Repository navigation
Rust #325: activity cancellation acknowledgement like Server 2.11.1 - #745
Conversation
PHP's repair pass raises the task's repair count and projects the run in one transaction, then stamps the dispatch and projects the run again in a separate step. Operator metrics reads runs, tasks and backlog without a shared snapshot, so one response can straddle those steps. Model the four PHP states and accept reads that never go backwards in read order; native must still report one consistent state.
Appends, diagnostics, delivery as the runtime-reserved signal, worker cursor acknowledgements and waits on workflow task completions, and the hand-over of the cursor and unconsumed messages to a continued run, with the message-streams parity fixture recorded from published PHP 2.11.1. A signal consumed by a condition wait now records no SignalApplied unless it is declared, the instance cursor event carries its task snapshot, and a completion reports the next message task, as PHP does. Retention holds runs whose instance has inbound streams until stream cleanup is ported.
Published Workflow aca7928484 reads each operator metrics value with its own query, so one section can straddle a repair. The PHP-only model now matches eight state-dependent reads in their real order, including the timestamps read before their counts, and reads each health warning from its own field. Native stays strict.
Published PHP treats an open_condition_wait's condition_key and condition_definition_fingerprint as optional strings of any form, trimmed and left out when empty. Native required both and a sha256 fingerprint. The wait projection and run summary now read a keyless wait as PHP does.
Published PHP's WorkflowHistoryEvent::record adds the task's snapshot to each event it records with the task model. Native now adds it centrally for those event types, uses the full snapshot on TimerScheduled and the activity events, and leases a timer task to itself while it fires, as RunTimerTask does, so TimerFired carries the leased timer task.
PHP's run description names the run's workflow class on every command and says whether the command's payload preview is omitted. Native left both out. Only a stored external reference is read to decide the flag.
…ients worker.php already waits, inside the original 30 s budget, for the Worker's acknowledgement of its query result before it stops: the independent caller can see the committed result first. The Python and Rust clients stopped immediately, so a fast caller could end the Worker before its acknowledgement arrived (#708 attempt 1, MySQL 8.0, PHP target, timely). Both now wait the same bounded way. The submission and acknowledgement assertions are unchanged.
…nto rust-325-task-snapshots # Conflicts: # rust/tests/execution/worker_history_presentation.rs
In late-handler-sync mode the client stopped as soon as the handler returned, but the installed SDK logs the lost authority after that, so the expired-authority assertion could see none (#713 attempt 2, PHP target). worker.php waits for its Worker's refusal; every non-timely Python mode now also waits, inside the 30 s original budget, for the expired-authority evidence before stopping. Assertions are unchanged.
…fix; run-bound task snapshots Security review of #718: - oversized() reads native's external_payload envelope as well as PHP's external_storage, so a stored reference over the payload limit omits the preview (and the target name, as PHP does). Run input and output previews use the same check. - The described-command query reads a payload only when its first 30 characters equal native's stored prefix, compared case-sensitively on each backend (COLLATE BINARY, binary cast, PostgreSQL text). - record() reads a task snapshot only from a task of the event's own run. Tests: a real stored reference at the 2 MiB limit and one byte above, upper-case/v2/malformed/large-inline counterfactuals, the query itself on SQLite, and a mismatched-run event with no snapshot.
…s maintenance loop (#721) On SQLite the published PHP API server and its maintenance loop share one database file. A contended poll gets PHP's typed backend_lock_pressure refusal, and the published Python run_until helper ends its Worker on it (sdk-python #218). The cohort tests patch replacement, not writer contention: stop the loop for the PHP record, restart it right after, and record and assert its state. The observer still never retries a poll refusal; MySQL and PostgreSQL jobs are unchanged.
…t until a sustained restart (#721) Security review of #722: the restore trap was installed only after a successful stop and disarmed before the restart was checked. Move the window into published-sdk-patch/maintenance.sh: arm restoration before the stop, restart with up to three attempts that each require the loop to stay running across three checks, and disarm only after that. A failed restart records the observed state and fails with restoration still armed. tests/Unit/PatchCohortMaintenanceTest.mjs injects a stop that exits nonzero after taking effect, a failed PHP record, and a start that exits at once, with a fake docker. The previous ordering fails the first and the last.
Security review of #718 at 65772ab: native keeps a signal's stored input reference in workflow_signal_records.arguments; workflow_commands.payload holds the encoded command. Read the exact native sentinel from s.arguments for signals and from c.payload for starts only, case-sensitively per backend. The describe test now proves the real signal row is the source, mutates that row around the limit with the same counterfactuals, shows an oversized sentinel in a signal's command row does not count, and covers the start command's row.
…721) The Docker workflow isolation policy requires a stopped container's name to resolve to github.run_id, run_attempt and job in the same source. Name the SQLite job's maintenance container from GITHUB_RUN_ID, GITHUB_RUN_ATTEMPT and GITHUB_JOB, refuse to act unless it equals the job's $RESOURCE_SCOPE-php-maintenance, and add a control proving a container outside the job scope is never touched.
…st-325-train-oct24-b
…st-325-train-oct24-b
docs/rust-server-port.md lists the published Server 2.11.1 routes native does not serve yet, and that prose drifted from the code (it said 125 of 174). An execution test now sends every method of every published API route, from the embedded PHP route table, through the native router, and requires the routes that answer 501 rust_capability_not_implemented to equal rust/tests/fixtures/unserved-php-routes.v2.11.1.txt. A port that serves a route removes it from the list in the same change. At this tree native serves 126 of 175 route methods; 49 remain. The test fails, naming the route, when one is removed from the list.
…d from published 2.11.1
Fixture first for POST /api/worker/activity-tasks/{task}/acknowledge-
cancellation, the last activity-task route native does not serve.
- The probe follows the cooperative path over raw worker HTTP: request
cancellation, deliver it to the activity from the workflow task, then
acknowledge from the activity worker. It records every ownership,
protocol and validation refusal, the receipt on the status route, the
duplicate, a later outcome, a claim polled on 1.19, an immediate
cancel, a retried attempt and a run terminated after delivery.
- The contract pins the published 2.11.1 bodies and event. Identities
and times come from the observation; their relations are exact.
- One documented reference boundary: published 2.11.1 delivers a
retried activity's cancellation to the execution's first task
(Workflow #923), so that attempt's acknowledgement is refused as not
fenced. The contract accepts exactly that defect's signature or the
correct acknowledgement, nothing else.
- The unit test runs the contract on the recorded 2.11.1 observation,
on the corrected retry, and on 16 mutations it must refuse.
Published 2.11.1 passes 3/3 locally with its maintenance loop running.
Native still answers 501 here; this branch adds the native route next.
…livery to activities
Native now serves POST /api/worker/activity-tasks/{task}/acknowledge-
cancellation like published Server 2.11.1, and the cooperative path
that leads to it:
- deliver-cancellation accepts call_kind activity with the default
try_cancel policy. It cancels the open execution, its current
attempt and that attempt's own task, and records ActivityCancelled
under the request with PHP's attempt and task snapshots. Published
2.11.1 picks the execution's first task instead, which breaks a
retried activity (Workflow #923); native cancels the live task.
- request-cancellation no longer refuses a run with open activities.
- Activity polls bind the immutable claim, as workflow polls do, so a
claim polled on protocol 1.19 cannot acknowledge.
- The heartbeat reports a delivered stop as PHP does (200,
cancel_requested, attempt_closed), and the status route carries the
cancellation_acknowledgement receipt.
- The acknowledgement follows PHP's order: protocol, validation,
ownership guard, claim, then the fence, request, recorded
cancellation, snapshot, context and duplicate checks. It records one
ActivityCancellationAcknowledged event with the stop's evidence and
the cancelled task's snapshot, and never changes the attempt.
- server_capabilities advertises activity_cancellation_acknowledgement,
and named namespaces admit deliver-cancellation and the new route.
Smaller parity fixes found by the fixture: the status route and task
snapshots format times with microseconds, and stale activity outcome
receipts carry the worker protocol fields.
Explicit wait_cancellation_completed and abandon activity policies stay
unported: native does not record an activity's policy, so every
delivery is try_cancel.
The activity-cancellation-acknowledgement fixture passes 3/3 against
native on SQLite locally, taking the correct retried-attempt branch.
…cknowledgement test - The workflow and activity polls report lease_expires_at with microseconds, as PHP does; the status route already does. - Native's stale outcome receipts now carry the worker protocol fields, so the execution tests that pinned the older receipt expect PHP's. - A native execution test requires that a retried activity's cooperative cancellation cancels the live attempt's task, keeps the earlier task completed, fences the earlier attempt and acknowledges the live one once. The shared fixture accepts published 2.11.1's defect (Workflow #923) here; native is held to the correct outcome. Full native SQLite suite: 257 library and 457 execution tests pass. The acknowledgement, lease renewal, one-activity and cancel-leased- activity fixtures pass against native locally.
…into rust-325-train-oct24-c
…st-325-train-oct24-c
…into rust-325-train-oct24-c
…ust-325-train-oct24-c # Conflicts: # .github/workflows/server-parity.yml # rust/src/runtime/store.rs # rust/tests/execution.rs
#709 serves the three message-stream routes, which the route coverage test reported as now served. Native serves 129 of 175 route methods at this tree; 46 remain.
heartbeat_renews_only_progress_deadline_and_cannot_resurrect_elapsed_authority compared two lease_expires_at strings. Native times are whole milliseconds and serialize without a fraction on a whole second, so a claim lease of ...:26Z sorted after a renewal of ...:26.045Z and the assertion failed about one run in a thousand (train #729, PostgreSQL 17 job 120852521096). The test now parses both and reports the values.
…activity or timer Security's R2 finding on #745: native recorded a cooperative cancellation delivery for call_kind activity even when no open activity was at the sequence. That pinned the wrong delivery sequence, and the duplicate path then refused the correct delivery. Native now runs published Workflow 2.11.1's validateCallBoundary for activity and timer deliveries before cancelling anything: - Every typed step at the sequence must have the call's shape, and an authored sequence must have typed history. Either fault is cancellation_delivery_shape_mismatch. A wait's timeout timer belongs to the wait, not to a timer call. - A call that resolved before the request is cancellation_delivery_not_eligible, including a member of a cancelled selection operation. One that resolved after the request still takes the delivery as it is. - The next sequence may be a call not yet authored. - Each validation refusal answers 409 with the bridge's undelivered body in the worker envelope, as Server 2.11.1 does, and records nothing. The activity acknowledgement probe adds a run whose activity completed before the request, with a timer at sequence 2. The contract pins both refusals, the unchanged history, the still-undelivered request and the timer's delivery. Published 2.11.1 passes it 4/4 and the pr1 recording replaces the expected observation. Native passes 3/3. The previous head fails it with a 200 delivery at the completed activity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t stack Conflicts were in two workflows. The fixtures workflow drops its old pull_request path list, as main does; the push path list it now classifies pull requests with already carries this stack's two contract tests. Its comparator step runs main's list plus those two tests. The PHPUnit workflow keeps the stack's patch cohort step beside main's merge queue and fixtures result steps. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Rust Server: fixed in Fix. Native runs published Workflow 2.11.1's
Evidence (all local).
Ready for your R2 recheck on |
|
Rust Server: hosted CI is terminal and green on the exact head
Ready for Security's R2 recheck. After acceptance I'll retarget #744 to |
|
Rust Server: The merge is clean. It adds only main's PHP and CI files; native code and this unit's fix ( Security's R2 recheck can target |
|
Rust Server: hosted CI is terminal and green on the exact head
This unit is ready to merge on Security's R2 acceptance of this exact head. Then #744 retargets to |
|
Second-round Security review accepts the fix for the prior call-boundary finding at exact current head The fix commit Coverage specifically proves that a completed activity is ineligible, an activity delivery at a timer is a shape mismatch, a timer delivery at an activity is a shape mismatch, a timed-wait timeout is not a pure timer boundary, refusals change no history or consumer state, the real pending timer remains deliverable afterward, and a timer that resolves after the request may still take delivery. The recorded probe and contract now carry those observations, and mutation cases reject the original incorrect acceptance and partial-state outcomes. Current hosted checks on This accepts the exact fix for the cited finding, not an unreviewed future merge result. The branch is behind current |
|
The MySQL and PostgreSQL corpus steps start native-a and native-b together, wait up to 30 seconds for native-a, then check native-b once. On run 40156433545 (#745, mysql-execution mariadb-10.11 corpus), native-b was still binding its port: that single check exited 7 ("Failed to connect to parity-native-b port 8080"), and the step failed before recording anything. native-b now gets the same bounded readiness loop. The survivor check after native-a is killed stays a single check, since native-b has been serving for the whole corpus by then. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Security final recheck accepts the previously reviewed cooperative-cancellation fix at exact current head The delta from accepted head The Security hold on #745 is released for this exact head. GitHub cannot record a formal approval from the shared maintainer identity on its own PR, so this comment is the durable acceptance receipt. Any future head requires revalidation. |
|
Rust Server: exact-head evidence for Security's re-acknowledgement of Hosted CI on this head
Merge structure
The merge adds only
Local qualification on this exact head: the full native shared fixture suite on SQLite, and the SQLite all-targets suite (264 unit, 466 execution). Holding the final merge for Security's re-acknowledgement of this head. |
…ust-325-worker-sessions Conflicts resolved as unions. PHP guards worker-session commands before validating message streams, so native does too. Capabilities advertise both worker sessions and message streams. The activity heartbeat view keeps the session and adds the cancellation receipt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The unserved-route list arrived with #745 and still named the five worker-session routes this branch serves, so route_coverage failed after the merge. Native now serves 138 of the 175 published route methods. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-activity Conflicts with #745 resolved as unions. Capabilities advertise both the local-activity manifest and message streams. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…workflow-import Both sides described omitted command previews. Main reads native stored references (a start's payload and a signal's arguments) through per-backend exact-prefix comparisons. This branch also recognised PHP's own external references, which an imported history keeps. The merged query keeps main's comparisons and adds two columns in the same style: php_payload_reference (exact 23-byte PHP prefix) and reason_payload for commandReason(), which never reads either kind of reference. A preview is omitted when either reference is oversized. The query test now pins both new comparisons and still refuses LIKE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cancellation-scopes The port log's route count is corrected to this branch's state: 133 of 175 served, 42 unserved as the route list records. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The unserved-route list arrived with #745 and still named it, so route_coverage failed after the merge. Native serves 131 of the 175 published route methods on this branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>



Part of #325. Security class: R2 (worker protocol surface). Stacked on #744 (base
rust-325-train-oct24-c), so it also takes its route off the unserved list; it merges after #744.Ports
POST /api/worker/activity-tasks/{task}/acknowledge-cancellation, the last activity-task route native did not serve, with its cooperative delivery path. Fixture first.Fixture (recorded from published 2.11.1)
activity-cancellation-acknowledgementfollows the cooperative path over raw worker HTTP:It records every ownership, protocol and validation refusal, the receipt on the status route, the duplicate, a later outcome, a claim polled on 1.19, an immediate cancel, a retried attempt and a run terminated after delivery. The contract pins the published bodies and the
ActivityCancellationAcknowledgedevent. Identities and times come from the observation, and their relations are exact. A unit test runs the contract on the recorded 2.11.1 observation, on the corrected retry, and on 16 mutations it must refuse.Reference boundary (Workflow #923). Published 2.11.1 delivers a retried activity's cancellation to the execution's first task, which has already completed, instead of the live attempt's task. The live task stays leased, and its acknowledgement is refused as
activity_cancellation_not_fenced. The contract accepts exactly that defect's signature, or the correct acknowledgement, and nothing else. Native gives the correct outcome, and a native execution test requires it.Native
deliver-cancellationacceptscall_kind: activityunder the defaulttry_cancelpolicy. It cancels the open execution, its current attempt and that attempt's own task. It recordsActivityCancelledunder the request, with PHP's attempt and task snapshots.request-cancellationno longer refuses a run with open activities.cancel_requested,attempt_closed). The status route carries thecancellation_acknowledgementreceipt.server_capabilities.activity_cancellation_acknowledgementis advertised. Named namespaces admitdeliver-cancellationand the new route.Smaller parity fixes the fixture exposed:
The execution tests that pinned native's older receipt now expect PHP's.
Not ported. Explicit
wait_cancellation_completedandabandonactivity policies. Native does not record an activity's policy, so every delivery istry_cancel. This is logged in the port log as a remaining gap.Evidence
activity_cancellation_ackandroute_coveragepass on SQLite.