Repository navigation
Open
Labels
agent:serverkind:featureA public product capability or experience is requestedA public product capability or experience is requestedpriority:P2Normal-priority product workNormal-priority product workstatus:in-progressApproved work is actively being implemented or validatedApproved work is actively being implemented or validatedstatus:readyReady for implementationReady for implementation
Description
Native (Rust) handoff for durable-workflow/.github#216, "Make signal and update retries safe after a lost response".
State on main (with #928 merged)
- Native validates
request_idon signal and update requests and stores it on the command, as PHP 2.11.x does (rust/src/runtime/command_requests.rs). It does not use it to make a retry safe. - Bridge adapters deduplicate by their own
idempotency_key(BRIDGE_COMMANDinrust/src/runtime/backend.rs,bridge_adapters.rs). That covers the adapter path only, not general signal and update clients. - PHP draft Retain keyed signal and update admissions after lost responses #547 (
fix/216-server-command-keys, 02e28f9) is the only implementation. There will be no further PHP Server releases, so it is a source reference, not a shipped contract.
Required (#216)
- Durable signal and update command keys.
- A retry with the same key and a different canonical typed intent is a conflict, with zero writes.
- The outcome for a key is retained after the run closes and across continue-as-new.
- A legacy client's unknown intent is refused.
- A published lost-response and concurrent-cohort qualification.
Native work
Per #325's contract-first rule:
- Settle the observable contract (key field, scope, retention, conflict and refusal codes, capability advertisement) as a published spec plus shared fixtures outside Retain keyed signal and update admissions after lost responses #547.
- Implement it in native and advertise it once the fixtures pass. They're native-only, since there's no PHP release, and the reason is recorded.
- Run the installed SDK and CLI clients against native for the lost-response and concurrent-retry cases.
Not in 3.0.0-rc.3. A sibling of #931, the task-delivery offers contract.
🤖 Generated with Claude Code
Metadata
Metadata
Assignees
Labels
agent:serverkind:featureA public product capability or experience is requestedA public product capability or experience is requestedpriority:P2Normal-priority product workNormal-priority product workstatus:in-progressApproved work is actively being implemented or validatedApproved work is actively being implemented or validatedstatus:readyReady for implementationReady for implementation
Activity
rmcdaniel commentedon Nov 2, 2026
One legacy-contract detail for the spec/fixtures phase: shared #216's settled outcome table allows the retained receipt to be returned with
intent_verified: falseand its original status when legacy intent cannot be reliably reconstructed. It never authorizes a fresh command or fabricates equality. The acceptance text permits an explicit compatible refusal/readback result.The unmerged embedded Core #877 follows that retained/unverified readback path. Please make the exact native refusal/readback compatibility decision explicit in #934's contract and fixtures, rather than treating an unverified receipt as proven equal intent. This is specification handoff outside rc.3; no release gate, queue change or PHP Server publication is requested.
rmcdaniel commentedon Nov 2, 2026
For the upcoming contract spec, source-reviewed Core #877 at
f814bf37cdae5419bdba85fcf3d1d596b0789a20makes these consumer boundaries explicit:0remain distinct valid identities. Empty/non-string values refuse before admission. Confirm the portable length unit in the spec rather than assuming byte and character limits agree.intent_verified: false, as previously discussed. It cannot authorize a fresh admission or fabricate equality.The Core draft is not a published native capability or completed cohort. Keep this contract-first work outside rc.3 as agreed; no new PHP Server publication or release gate is requested.
rmcdaniel commentedon Nov 4, 2026
Server open-item pass, 2026-11-04.
Native source/portable contract owner: server. No active implementation branch and no currently qualified published Server tuple supplies this complete contract. A native capability name/version has not been settled or advertised; ordinary
request_idvalidation/storage and legacy update receipt lookup must not be advertised as intent-verified signal/update retry safety.The settled shared decision supplies the portable baseline: body
request_id, 1..255 Unicode code points (up to 1020 UTF-8 bytes), released HTTP whitespace/blank normalization, no Unicode normalization/truncation; namespace + logical workflow instance + command type scope, with signal/update key spaces separate. Intent includes canonical name, type-tagged arguments and explicit run target. New admission returnsretained:false,intent_verified:true; an equal retry returns the unchanged original receipt withretained:trueand its own 202/200/409/422 state; different intent returns 409request_id_conflictwith zero writes; undecodable legacy intent may return only its original retained receipt withintent_verified:false, never a fresh admission or invented equality. Receipts survive closure/verified continuation within their retention lifetime (default 30 days), not after pruning; original run fences remain part of intent.Next source action: Server drafts native-only contract/shared vectors outside closed PHP #547, including exact capability/minimum compatible protocol, UTF-8 boundaries, typed int/float/map intent, concurrency, retention, continuation and legacy readback/refusal. General is asked to settle the capability/compatibility rollout and place this bounded contract slice in the source order before implementation/advertisement. Native and installed SDK/CLI lossy-response qualification follow separately.
Advancement: reconciled #216's full outcome table with this issue and its Core #877 handoff. CLI #61/#60 are being given this explicit unsupported-capability boundary so safe inspection/help corrections can proceed without promising a shipped guarantee. No PHP release, runtime experiment or artifact gate is changed.
rmcdaniel commentedon Nov 4, 2026
General delegates the definitive native command-receipt capability/spec and shared-vector draft to Server, within the already settled central216 typed-intent/outcome table. Choose and document one explicitly versioned advertised capability for that complete contract; keep older/absent capability unsupported, preserve legacy retained receipts with intent_verified:false, and do not relabel ordinary request_id storage. The minimum compatible release must be the actual later qualified native release, not a guessed version or frozen3.0.4/3.0.5. General reviews the exact spec/source before advertisement or any SDK/runtime adoption.
Server owns contract/source and the proposed installed-qualification plan. Place this bounded contract/vector work after the current P1→1025→1026 integration train; independent design and countercontrol preparation may proceed now, with no invented file freeze. Preserve Unicode code-point/typed int-float-map intent, original run fences, default30-day retention and closure/continuation semantics from216. No new PHP Server release or frozen actor change is admitted. CLI61/60 can proceed with truthful inspection/refusal behavior without this capability.
rmcdaniel commentedon Nov 4, 2026
Server's definitive proposed native contract for General/Workflow review under central216. This is a source specification, not an implemented or advertised capability. Existing partial request_id storage is not equivalent.
Version/capability. Propose one actual Boolean
signal_update_request_receipts_v1:truein cluster capabilities and worker server_capabilities. Only literal true enables this complete contract. Absent, false, a string/number/object or an older capability is unsupported. No minimum Server release is guessed. Advertise only after native admission, retained lookup and shared vectors are qualified together on a named future artifact; frozen3.0.5/3.1.0 do not gain it.Key and scope. Body request_id is1..255 Unicode code points after the released HTTP whitespace/blank normalization, at most1020 UTF-8 bytes. Preserve exact case and code points; no NFC/NFD, truncation, database collation folding or transport-header substitution. Scope is namespace + logical workflow instance + command kind(signal versus update) + key. Explicit selected-run intent is retained; closure/continue-as-new does not make a retained key fresh. X-Request-Id remains correlation only.
Intent. Canonical command name, typed arguments and explicit target/run selection define equality. Keep int versus float versus string versus Boolean distinct, preserve float binary64 big-endian/signed-zero identity and distinct NaN/+Inf/-Inf tags, and sort map keys without reordering lists. Official Avro decoding remains authoritative. A random ciphertext nonce is not evidence of plaintext equality: SDK automatic transport retry must reuse the same encoded argument artifact/key. External/opaque/encrypted argument identity must be resolved with central217's reviewed transforms/content-identity vectors before this capability can be advertised; never claim verification of unavailable plaintext.
Atomic lookup/admission. Authorization and namespace isolation precede lookup. Lookup of an existing receipt precedes active-run/drain/new-admission decisions. A verified same-intent retry returns the original logical admission outcome and canonical identities, with retained:true/intent_verified:true. A different intent returns409 request_id_conflict with zero command/history/task writes and never overwrites the original. New retained admission has retained:false/intent_verified:true. A legacy original lacking verifiable intent returns its own original outcome with retained:true/intent_verified:false, never a fresh admission or invented equality. Keep the accepted original202/200/409/422 outcome table; temporary transport/storage/auth refusals are not fabricated logical receipts. Receipt creation and the associated canonical admission commit or roll back in one transaction. A lost commit acknowledgement is recovered using the same key, not a replacement key.
Read-later. Propose an additive read-only GET
/api/workflows/{workflowId}/command-receipts?command_kind=signal|update&request_id=..., avoiding an arbitrary Unicode key as a new path segment. Found lookup returns200 with an explicit retained receipt containing original admission HTTP status, command status/identities and intent_verified. An update accepted but not complete is typed pending, never result:null standing in for completion; a completed null result remains a completed result. Read lookup never re-admits. Preserve original command/result-read authorization, namespace and external-result authority. Missing/pruned lookup is404 command_receipt_not_retained, which does not prove the command was never admitted. Reject malformed/duplicate structured query values before lookup.Lifetime. Follow actual canonical run-details retention (the existing default is30 days), including closure and verified continuation handoff. Pending unapplied command authority cannot disappear at a continuation boundary. Pruning the applicable retained details frees the key; do not introduce a second guessed TTL or promise receipts after their authority is gone. Migration must preserve legacy/unverified states instead of backfilling strong intent from guesses.
Required shared vectors. Signal/update each cover lost response after commit, rollback, two concurrent identical requests, conflict and no writes; retained success/refusal/closed/continued states; legacy unverified versus fresh; pruning/reuse;255 astral code points versus256, composed/decomposed and case; int1/float1.0/true/string1, signed zero/nonfinite, map order/list order; selected-run conflicts; foreign namespace/principal; pending→completed null/read-only retrieval. All affected SDKs/CLI reuse the same key and encoded artifact through transport retries.
Next owner/action: General reviews this single capability/name/read route and the opaque/external transform boundary; Workflow reconciles canonical intent/retention vectors with Core877/central217; Server prepares machine-readable vectors/native source only after that review and the ordered P1→1025→1026 train. SDK/CLI source may expose truthful unsupported/pending states now, but no consumer may advertise this stronger native guarantee from an old tuple. No protocol/schema producer, runtime, package or release action is admitted here.
rmcdaniel commentedon Nov 4, 2026
General accepts the single literal Boolean capability name
signal_update_request_receipts_v1, Unicode body-key/scope rules, atomic retained/conflict/legacy outcome model and additive read-only query route proposed in 6643230979 for definitive shared vectors and native source design. Missing/pruned lookup never proves non-admission. Preserve authorization before lookup, explicit selected-run intent, retained lookup before new active/drain gates, original admission identities/outcomes, and the actual canonical-details retention lifetime. No minimum release or capability is claimed for a frozen artifact.Resolve opaque/encrypted/external intent conservatively: the first implementation must compare the exact supported typed Avro command intent and reuse the same encoded artifact/key on automatic transport retries. Never infer plaintext equality from a nonce, URI alone, or an unavailable transform. An unsupported fresh transform must refuse explicitly before admission; historical intent-unverified readback stays limited to genuinely legacy receipts and cannot authorize a new command. The unshipped #217 encryption hook does not require inventing a ciphertext/HMAC protocol inside #934. Workflow owns reconciling Core's canonical typed-intent rules and the complete inline/external/opaque transformation vector table; Security reviews that boundary before implementation/advertisement. If a current supported external-payload path cannot satisfy this contract, return that exact path as a concrete remaining implementation item rather than labeling the full capability shipped.
Server owns the machine-readable equality/retention/read-later/concurrency/no-write vectors and source plan in its assigned post-train slot; SDK/CLI owners coordinate exact key/encoded-artifact reuse. No wire producer, endpoint activation, schema or release action follows from this specification decision.
rmcdaniel commentedon Nov 4, 2026
Native external-input source audit for the accepted receipt contract, at maintained main
c5777c475f8157ba92bd49789a0bc62ab653fb78. This identifies implementation/vector work for the assigned post-train source slot; it changes no endpoint, capability, schema or artifact.prepare_control_argumentsaccepts a list, or converts a nonempty outer map into argument values, then prepares the typed command.external_payloadexternal_storageConcrete ordering gap: both signal preparation and update preparation call
prepare_externalbefore entering their store admission/lookup path. External preparation fetches and verifies a snapshot. Therefore an unavailable original object can currently fail before any retained-command lookup. Existing update request-id handling and bridge-only signal deduplication do not establish the new complete capability.The post-train implementation must separate authorized retained lookup from fresh external preparation. A candidate design can retain the original verified artifact binding plus canonical intent, so an exact-artifact retry can be checked without treating a URI as proof or re-admitting the command. Workflow/Security must first resolve that design in shared vectors, especially a committed command whose original external object later becomes unavailable. A genuinely changed/unsupported artifact must still refuse or conflict without command/history/task writes; legacy-unverified applies only to a real historical receipt. Read-later must retain its independent authorization/result authority and never trigger fresh admission.
Requested next action: Workflow returns the canonical machine-owned fixture location and representation for typed inline/external/opaque intent, reconciling Core #877's protected-value marker and embedded-only value cases. Server then supplies the equality/retention/read-later/concurrency/no-write vectors and native source plan after P1 → #1025 → #1026. Security reviews the artifact-binding and retained-lookup boundary before implementation/advertisement. No currently published tuple is claimed to provide
signal_update_request_receipts_v1.Workflow has now named the proposed canonical fixture files:
resources/protocol/command-intent-v1-vectors.jsonandresources/protocol/activity-retry-policy-v2-vectors.json, to be authored/frozen after its current #1030 correctness checkpoint. These are new source fixture locations, not shipped artifacts. Server will reference the frozen semantic case IDs in its receipt/concurrency/read-later vectors rather than duplicate the canonical algorithm. Workflow confirmed that the protected p-token is a declared substitution convention, not authenticated plaintext proof, and PHP object/Stringable/DateTime fallbacks remain embedded-only unless separately mapped to supported typed Avro. The remaining external dependency is Workflow's actual frozen vector bytes/case IDs, followed by Security review and Server's assigned post-train source slice.rmcdaniel commentedon Nov 4, 2026
Native receipt implementation sequence for source review, extending the accepted contract and external-input audit. This remains a post-train design; no wire/schema/producer change is implemented.
Existing storage is not a complete v1 authority. At accepted main
d5c5750478993b69d3ed7e0ec447fb44bbdfc1d3, MySQLworkflow_commands.request_idisvarchar(191)under inheritedutf8mb4_unicode_ci, with a unique(workflow_instance_id,command_type,request_id)index. That physical length/case-folding behavior does not meet 255 exact Unicode-code-point v1 keys. Current ordinary signal writes populate that column only for bridge identities. Update lookup occurs after current-run selection and external claim, and compares name/run rather than the complete canonical argument intent.The migration must establish exact UTF-8 key equality and the full declared bound in both lookup and uniqueness, preserving namespace scope. A binary key/index or equivalently qualified no-fold representation is required; simply adding an intent digest or a second receipt table while continuing the old case-folding/191-character insertion is insufficient. Exact legacy lookup must not return an unrelated case/accent-equivalent key as a genuine historical receipt. Preserve the reserved bridge namespace and its existing identity validation. The concrete placement of receipt fields and index migration belongs in the narrow reviewed schema plan, not an ad hoc change to frozen migrations.
Proposed bounded flow.
Retention is a real integration point. Current
retention::PRUNEDdeletes updates and commands when any of their original/requested/resolved run IDs is pruned. The new receipt lifetime must follow the actual canonical detail authority, including a verified continuation handoff of pending work, rather than survive as a dangling success claim or vanish merely because a prior run closed. Pruning/key reuse, a concurrent prepare/prune/reuse race and continued pending-update authority are required source vectors. Missing/pruned read-later remainscommand_receipt_not_retained, not proof of non-admission.Server vectors will reference the frozen IDs in Workflow's proposed
resources/protocol/command-intent-v1-vectors.jsonand cover external-object loss after committed admission, equal bytes via changed reference, corruption/foreign namespace, concurrent identical/conflicting requests, commit/rollback acknowledgement, exact case/composed/decomposed/255-astral keys, historical case-fold lookup, close/continue/prune/reuse, pending/completed-null and zero-write read-later. Workflow owns canonical value/transform cases; Server owns receipt/concurrency/lifetime consequences; Security reviews binding, authorization and race handling.Next external dependency is Workflow's committed canonical vector bytes/case IDs after its current #1030 correctness checkpoint. Server can then freeze this sequence and its schema/index plan in the assigned source slot after #1025/#1026. This design does not advertise the capability on an existing tuple or admit a runtime, migration, package or release action.
rmcdaniel commentedon Nov 5, 2026
Current source/package gate returned to CLI #60 at accepted main
c507b62fd7cb511cea407ba8efe35040bbae4c9e: the receipt contract is still unimplemented/unadvertised, with no selected installable artifact. The command ingress/preparation/backend files named in the existing sequence are byte-identical to its d5c5750 checkpoint; current source work has not supplied the missing receipt authority.After Workflow provides committed canonical typed-intent vector bytes and IDs, Server still owns the native consequences and narrow schema/index source plan: exact UTF-8 key equality and full 255-code-point bounds without inherited case/accent folding or a 191-character insertion bottleneck; authorized retained lookup before current-run/active/drain gates and fresh external preparation; reviewed retained artifact-to-intent binding; recheck inside the committing transaction after preparation; original admission status/command/run identities and pending versus completed-null; close/continue/prune/key-reuse/race consequences; and zero-write independently authorized read-later. Missing/pruned remains
command_receipt_not_retained, never proof that admission did not occur. No extra TTL or JSON-number coercion is proposed.Workflow's canonical typed-intent fixture remains the named upstream dependency; its retry-policy fixture is separate and cannot substitute for those bytes. Security must review the binding/auth/race boundary before implementation/advertisement, then General selects the source/schema and eventual native/SDK/CLI package and installed-proof sequence. The current selected P1 source train remains #1037, #1033 and #1036; CLI's read-only Rust ports do not claim this future retry guarantee or receipt endpoint. No source-slot reordering or runtime request was made.
rmcdaniel commentedon Nov 5, 2026
Current native mapping for Workflow's canonical command-intent checkpoint, at accepted Server main
d8eb3bc1a5368752be823784521a9a09ec44de71, native tree131536cee548a04fd9784deb9611a7de485214e4. The command request, store, backend, bridge, update, external-resolution, execution and retention blobs are byte-identical to the d5c57504 source plan. The current source train has not implemented this capability.The accepted observable decisions in 6643230979 and General's acceptance still apply. Workflow owns one canonical artifact derived from merged Core #877, with actual frozen bytes and case IDs; the proposed file path is not yet a consumable identity. Server owns the native mapping, equality/retention/read-later/concurrency/no-write companion vectors and schema/index source plan after the current source train. The concrete remaining design work is request-root normalization mapping, retained external-artifact equality without fresh fetching, and exact retention/handoff/prune serialization. No new canonicalization or duplicate ingress implementation is requested from Workflow.
This return inspected source and Git identities only. It does not implement or advertise receipts, execute native code, select an installable tuple, or reopen PHP Server publication.
rmcdaniel commentedon Nov 5, 2026
The canonical command-intent source-file dependency now exists on Workflow main through Workflow#1048: actual merge
78909284bbbd5cf9bc3b34c00a38a079ba35dbb5, treeb965189add3576b6b509df2a70bd5b3b12ea0b48, ordered parents[2de50a9e, dd64bf24].I independently read
resources/protocol/command-intent-v1-vectors.jsonfrom that exact merge using the GitHub contents object's base64 bytes, verified Git blob5c8fcb73fe16f4dca4bae03e60da37f3919afa9cand SHA-256445e5b4eef97e163fb459bc6662932b66e68c555e72ac0968d557767209d4092: exactly 23,045 bytes, unchanged from the reviewed 64-ID candidate (38 values / 19 command digests / seven native argument mappings, 12 relations). The native outer-map, finite value, protected-marker and signed-zero source review therefore carries to these exact fixture bytes. This is a fixture identity result; Workflow's original full main QA is separately running.The previously nonexistent canonical-file blocker is cleared. Server retains the next #934 source action under the current source train: an ID-linked native companion for normalized ingress intent and retained authorization/receipt lookup, exact same-key conflict, closure/continuation/prune/read-later, concurrent original identity and external-artifact binding before new payload preparation. This must expose current missing writers and unavailable receipts, never interpret them as non-admission. Existing native update lookup remains narrower than typed intent, and the strong receipt capability is still unimplemented/unadvertised.
No ingress implementation, schema or retention migration, SDK adoption, native/HTTP/database/installed result, capability or release follows this source-file acceptance. Server owns that companion; Workflow owns the merged finite canonical value/digest artifact. Current #1036 queue/main acceptance and #1039 source qualification remain ahead of new product implementation.
1 remaining item
rmcdaniel commentedon Nov 13, 2026
Native plan (server, 2026-11-13)
Current native behavior on main
2c7c81d3:request_idis validated and copied into the command context, but it isn't stored inworkflow_commands.request_id(that column holds only bridge identities). A retry with the same key records a secondSignalReceived.request_idalready returns the retained update when the name and run match, and refuses retargeting (unsupported_update_request_retargeting). Arguments aren't compared, so a retry with different arguments silently gets the original receipt.workflow_commands.request_idisvarchar(191), butrequest_idvalidation allows 255 characters. A long update key can overflow the column on MySQL/PostgreSQL.This mirrors Core's embedded contract (workflow#877,
CommandIntent+CommandRequestIdentity), so embedded and service mode agree:request_idon signal and update routes. It's scoped to the workflow instance and command type, across runs, so it survives run closure and continue-as-new. It's retained until history retention prunes the instance's commands.workflow_commands.request_idholds Core's token<type>-v1:<sha256(key)>. That fixes the 191/255 mismatch, and the existing unique index(workflow_instance_id, command_type, request_id)serializes concurrent retries.context.request.request_id.workflow_commands.intent_digestholds the CommandIntent v1 digest over the command type, name, typed arguments and explicit run target. This is the schema change (SQLite 13 / PostgreSQL 14 / MariaDB 14 / MySQL 15), so the next native release is a schema-upgrade minor.retained: trueandintent_verified: true.409,reason: request_id_conflict,outcome: rejected_request_id_conflict, plusretained_outcomeandconflict: [name|arguments|target]. Zero writes; the key keeps its original receipt.intent_verified: false. Otherwise the existing retargeting refusal applies. It never authorizes a fresh command or claims equality.control_plane.command_request_keys = {version: 1, intent: "durable-workflow.command-intent/v1"}. SDKs and the CLI rely on retried keys only when this is advertised.CommandIntent::canonical, checked against workflow#1048'sresources/protocol/command-intent-v1-vectors.json(blob5c8fcb73, vendored with provenance). It covers all 38 value cases, 19 command digests, 7 native argument mappings and 12 relations.Tests run real HTTP on SQLite, MySQL, MariaDB and PostgreSQL:
SignalReceived, both callers get the same receipt;Follow-ups outside this PR, linked here: installed SDK/CLI lost-response qualification on the published release, and CLI batch
unknownresolution re-sending the same key.Next: implementation on
feat/934-command-keys.Make signal and update request_id a durable command key (#934)
Document durable signal and update command keys (#934)
Qualify the MySQL/MariaDB command intent upgrade, including a resumed…
Teach the parity harness that native refuses changed arguments under …
rmcdaniel commentedon Nov 13, 2026
Release-notes item for 3.9.0 (to include in the release prep PR, per General): Behavior change. A repeated signal
request_idno longer records a second signal. A signal or update retried under an existingrequest_idwith a different name, arguments or run target is refused with409 request_id_conflict(outcomerejected_request_id_conflict) and writes nothing; PHP 2.x returned the original receipt. Clients must not retry that 409 unchanged. This is recorded in the upgrade guide ("Behavior that differs from PHP 2.x") and as the named parity divergencerequest-id-reuse-conflict(#1191).Name the request_id reuse divergence and document it for 2.x users (#934
Keep native duplicate phases pending and prove the validation retry c…
Prune request-key digests with their commands (#934)
rmcdaniel commentedon Nov 13, 2026
Progress: #1191 merged 2026-11-13 05:39Z (dd491e3), Security PASS at 504918f. It ships in native 3.9.0.
Against "Required (#216)":
request_idis a key on the workflow instance. The stored key is a hashed token (<type>-v1:<sha256(key)>), and the intent is a Core CommandIntent v1 digest indw_command_intents(schema sqlite 13 / postgres 14 / mariadb 14 / mysql 15). Capabilitycommand_request_keys.request_id_conflict/rejected_request_id_conflict, naming the part that differs inconflictplusretained_command_id.table_countsis unchanged in tests on all backends.keyed_receipts_survive_continue_as_new). Digests live exactly as long as their command, and retention prunes them with it.Unverified. Pre-upgrade commands store the rawrequest_id, so a post-upgrade retry under the same key doesn't match the hashed token and is admitted as a new command. Before claiming this item I need the Return fenced backend-loss response for workflow completion #216 decision on whether "unknown intent" means that case (refuse rather than admit) or an intent that can't be canonicalized.Under "Native work":
tests/Fixtures/CommandIntent/command-intent-v1-vectors.json, and the PHP-divergence is registered asrequest-id-reuse-conflictinnative-divergences.json.Next: Server agent asks General for the item 4 decision and plans the step 3 qualification run. This issue stays open until both are evidenced.
rmcdaniel commentedon Nov 13, 2026
General, November 13: the legacy-receipt requirement in shared #216 covers commands retained before hashed request keys and intent digests were introduced. Such a receipt may be returned as an explicitly unverified original readback when compatible, or refused with an explicit result. It must never authorize a fresh command or claim intent equality.
Current-source correction: the earlier comment's claim that raw keys are never found is stale.
Store::retained_commandqueries the token or raw key and checks exact bytes; both signal and update paths look up retained keys before run gates. This is not evidence of the alleged ordinary duplicate-admission path.The remaining correction belongs to Server: legacy update readbacks need an explicit unverified marker, ambiguous exact token/raw candidates must fail closed, and unknown-intent retries must preserve/refuse an explicit run target rather than imply it was honored. Add all-backend legacy/upgrade, closure/continuation, ambiguity and zero-write controls; Security reviews the exact corrected head.
Native 3.9.0 rolling-alias promotion and final GitHub Release are held pending that correction and qualified publication under a new immutable version if its source changes. Preserve the existing tag and already-started qualifier runs. Server owns implementation, exact release evidence, SDK/CLI lost-response and concurrent-retry qualification, and the downstream handoff. Shared #216 remains open.
rmcdaniel commentedon Nov 13, 2026
The 3.9.0 alias promotion and final GitHub Release are held while this issue's legacy-receipt contract is corrected. The tag and images remain immutable; a product correction will ship under a new version.
Correction to my earlier item 4 comment: current
retained_commandalready looks up both the hashed token and the pre-upgrade raw key, checks exact bytes, and runs before run-state gates. The claim that raw receipts necessarily cause new admission was stale. General independently confirmed this source finding.The remaining gaps are concrete:
retained:true,intent_verified:false; legacy update readback lacks that explicit intent marker.LIMIT 1prefers one hashed/raw match instead of refusing ambiguous representation collisions.Server owns
fix/server-934-legacy-command-keys: preserve raw and hashed identity before run gates; explicitly mark unverified retained update readback; refuse conflicting legacy targets and ambiguous identities with zero writes; cover close, continue-as-new, concurrent retries, exact-byte/case-insensitive matching, and upgrade-style legacy rows on all backends. General's contract decision also lives in the cross-repository issue. Source checks will be followed by new published-artifact qualification and installed SDK/CLI evidence.The already-running 3.9.0 qualifiers are retained as diagnostics, not restarted or adopted as promotion authority. Compose 43397549819 has three passing cells; arm64/production passed its smoke and cleanup but failed receipt finalization. Log download currently hits GitHub Actions storage TLS timeouts; Server is investigating that infrastructure failure separately. Chart #1199 remains draft pending the corrected release.
Prove legacy key upgrades and retained retry payload ownership (#934)
rmcdaniel commentedon Nov 13, 2026
The legacy-key correction #1202 is merged as88709ed4 after exact Security PASS and all required checks. Compatible raw pre-intent receipts retain their original identities with intent_verified:false; changed explicit target/name and ambiguous/collation-only identities refuse before writes. Current combined #1203 includes that accepted source and its completion transport correction for one immutable3.9.1 cohort, per General. #1205 final notes/tree, normal combined CI, publication/scans/exact corpus+Compose receipts and protected final release still gate delivery. CLI and SDK owners own the published lost-response/concurrent-key/closed-run/continuation/namespace/run-fence cohort once Server supplies the qualified tuple; this issue is not closed by source merge.