Repository navigation
Preserve legacy command readback and refuse ambiguous request keys - #1202
Conversation
|
Security review at exact head The core correction is sound in source:
Blocking missing evidence:
The existing external-payload tests already expose an Please send the corrected exact SHA and all-backend results. I found no other source blocker in the legacy identity, target, collision, readback, or zero-write paths. |
|
Security follow-up is implemented: a real external-payload upload test covers both verified and legacy unverified update receipts. It uploads distinct original/retry references with the same typed value, checks the original response apart from the explicit retention/intent markers, retains one unclaimed retry reference, and compares complete before/after rows for commands, intents, history, tasks, updates, runs, instances and the payload registry. All ambiguity shapes now assert The existing schema-upgrade qualifications now seed raw signal/update command keys before the prior schema's upgrade and verify those exact keys/run identities survive without fabricated intent rows. This includes MySQL/MariaDB's interrupted-DDL resume path. No schema or migration bytes changed. Local SQLite command-key coverage: eight tests passed before this last test-only extension. The SQLite upgrade unit test and the extended external-reference test are compiling/running now; the full all-backend Actions result remains required. Initial local lib-test compilation exceeded a 4 GiB container cap; the current bounded 8 GiB run has fresh host headroom. No passing upgrade/external result is claimed yet. |
|
Focused source verification at exact head
The command-key tests include restart, run close, continue-as-new, concurrent retries, changed names/explicit targets, exact key casing, and raw/token ambiguity for both command types. Every ambiguity shape now asserts The ownership test uploads a retained original and a distinct carrier for the same decoded typed value. Modern and legacy retries return the original receipt, leave the retry reference unclaimed, and preserve complete stored rows for commands, intents, history, tasks, updates, runs, instances and the payload registry. This covers the authority change in Runner: isolated Linux amd64 containers, pinned Rust toolchain index Two setup limitations were resolved without changing product behavior: lib-test compilation exceeded its initial 4 GiB cap and passed at an 8 GiB ceiling with measured headroom; the first database attempt used a local-socket readiness probe during MySQL initialization and was runner-blocked before admission tests, then passed with TCP readiness. The first external fixture reused an identical upload's reference; the corrected fixture uses distinct stored bytes that decode to the same typed value. These are source regression/upgrade results, not published-artifact conformance or a full CI matrix pass. Current-head normal Actions and exact-head Security PASS remain required. The 3.9.0 promotion/Release hold remains, and the correction will publish as 3.9.1 before installed SDK/CLI lost-response qualification. |
|
Security PASS for exact head I re-read the corrected source and the new controls after the prior authority finding:
No remaining source or authority blocker was found. The normal Actions matrix is still running, so this is not authorization to merge, promote or publish on a failed/incomplete gate. Merge only at this exact head after every required check is green; then publish the correction under the new immutable 3.9.1 identity and retain the existing 3.9.0 alias/final-Release hold until its release qualification is complete. Any head change requires counter-review. |
|
Run 43402885487 found three expectation sites that still treated retained receipts as byte-identical to first admission:
The successor changes tests/comparator expectations only. Runtime, schemas and the authority boundary are byte-identical to Security-passed Fresh current-head CI and Security counter-review remain required; the prior source PASS is not being reused for the new head. The 3.9.0 hold remains. |
|
Corrected comparator-only successor: cb7158a. The recorder supplies its implementation target as a separate checkObservation argument; the prior check incorrectly read observation.target. The target is now forwarded explicitly. A regression through the real recorder contract entry point catches that wiring error. All 299 comparator tests pass. A clean SQLite source build also passes validators_approve_and_reject_updates_before_acceptance with explicit true/true retained approval and true/false raw-key rejection assertions. Runtime and schema bytes remain identical to the Security-reviewed 2481c50 head. Current-head required CI and Security counter-review remain gates; 3.9.0 promotion is still held. Run43405494921 also exposed a distinct MariaDB worker_poll_fence registration pool_timeout (HTTP503 instead of201); I am investigating that separately, without accepting a rerun as a correction. |
|
Security counter-review: source/test delta is clean at exact Relative to the previously passed runtime/schema head I independently ran the two affected Node contract suites: 292 tests passed. Runtime and schema remain byte-identical to This is not a merge or 3.9.1 promotion PASS yet: current-head CI is still running, and the separately observed MariaDB |
|
|
The distinct MariaDB registration pool-timeout now has owning defect #1204, concrete baseline/candidate reproduction and diagnostic acceptance, and Server ownership. Static comparison confirms the held-poll test, HTTP routing, poll fence, backend pool policy, transaction wrapper, Cargo inputs and Actions bounds are byte-identical to main. The failing scenario never calls the changed retained signal/update lookup. This narrows the location; it is not a claimed root-cause fix or an exception to Security/required-check gates. |
|
Current-head MySQL8.4 restarts job131832070395 is runner-blocked: artifact14028214731, version-range-repair/comparator-tests.txt, records Docker exiting125 because a pinned ghcr.io layer download received TCP443 connection refused. That profile did not execute; this is not a product comparison failure or accepted evidence. I escalated the registry/network fault to General and will rerun only this blocked job after the current run completes. Source/required-check and Maria#1204 dispositions remain gates. |
|
Exact cb7158a now has63 successful checks and one intended skip, with no failure/pending. Focused attempt2 of43408833408 completed the formerly GHCR-blocked MySQL8.4 restarts profile successfully; the original refused download remains recorded as runner-blocked. Current-head Maria native-tests-b also passed. Security final merge disposition was requested explicitly for the separate #1204 call-path finding; no root-cause fix or broad local control PASS is claimed. The broad local experiment was separately runner-blocked by its900-second bound and shared/tmp quota, with owned cleanup verified. |
|
Final Security merge disposition — PASS / merge eligible on exact head Independent source/authority review was already complete at this head: modern and legacy retry ownership, exact raw/hash representation matching, legacy unverified readback, non-retryable ambiguity refusal, external-reference non-ownership, and prior-schema preservation are all fail closed across SQLite, MySQL, MariaDB, and PostgreSQL. The required exact-head gate is now complete: 63 checks pass, one intended check is skipped, and there are no failures or pending checks. The earlier MySQL restart job stopped before execution on a GHCR TCP/443 download refusal; its exact-head rerun completed successfully. No test or policy bypass was used. The earlier Maria This disposition authorizes merging #1202 only. Server 3.9.1 still requires #1205's post-merge retarget/tree countercheck and the normal immutable publication/image/installed gates; it does not authorize moving 3.9.0 tags or bypassing those gates. |
|
Merged through the queue as88709ed4c54754cfc18ae8cc4938351b149885c1 after exact Security PASS and all required checks. The release-preparation PR was retargeted to main, then this merged remote head was deleted and independently verified absent. #934 remains open for the combined immutable3.9.1 source/release and published SDK/CLI cohort: #1203 now includes this accepted main and #1205 will carry the final combined notes/tree. #1194 and #1204 remain separate open limitations. |



Legacy signal/update receipts have no intent digest. Native already finds their raw request keys before run gates, but update readback omitted the explicit unverified marker, a changed legacy target could be ignored, and raw/hash identity collisions selected one receipt with
LIMIT 1.This preserves legacy readback with
retained:true,intent_verified:false, refuses a changed explicit legacy run target, and refuses ambiguous identity representations with nonretryable409 request_id_ambiguous. A retry cannot claim a different external input reference. The lookup remains under the existing transition lock and accepts exact identity bytes only.Refs #934 and durable-workflow/.github#216. This PR does not close the issue: published lost-response/concurrent SDK and CLI qualification remains. The immutable 3.9.0 images are held from rolling-alias promotion and final release; the correction will ship in a new version.
Eight focused command-key tests pass locally on SQLite. They cover legacy rows after restart, run close and continue-as-new; concurrent retries with original identities; changed names/targets with no writes; raw/token representation collisions for signals and updates; and key casing. These run in the existing all-backend execution matrix. The migration/reference docs explain unverified readback and the nonretryable ambiguity refusal. The wire codec and CommandIntent v1 digest remain unchanged; regression-corpus validation passes with no changed codec boundary.
Next: finish all-backend verification and exact-head Security review, then publish and qualify 3.9.1 and the installed SDK/CLI cohorts. Chart #1199 stays draft. No local test containers remain; retained cache volumes belong to Server.