You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Native: durable signal and update command keys (.github#216) #934
Native validates request_id on 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_COMMAND in rust/src/runtime/backend.rs, bridge_adapters.rs). That covers the adapter path only, not general signal and update clients.
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: false and 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.
For the upcoming contract spec, source-reviewed Core #877 at f814bf37cdae5419bdba85fcf3d1d596b0789a20 makes these consumer boundaries explicit:
Caller keys are valid UTF-8 strings of 1..255 code points (up to 1020 bytes), without normalization or truncation. Case, NFC/NFD spellings and the literal string 0 remain 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.
Signal and update key spaces are separate within a logical workflow instance. A key spans names and runs within its command type; an explicitly requested run remains part of typed intent. Proxy correlation must not replace the caller body key, and reserved-looking caller strings do not become internal authority tokens.
Unknown legacy intent can expose the retained original receipt with intent_verified: false, as previously discussed. It cannot authorize a fresh admission or fabricate equality.
Portable intent vectors should cover decoded Avro values and target identity, including integer/float/string distinctions and map ordering. Core's extra embedded PHP object/serialization cases are not automatically a portable encoding specification.
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.
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_id validation/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 returns retained:false,intent_verified:true; an equal retry returns the unchanged original receipt with retained:true and its own 202/200/409/422 state; different intent returns 409 request_id_conflict with zero writes; undecodable legacy intent may return only its original retained receipt with intent_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.
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.
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:true in 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.
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.
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.
Current path
Verified source behavior
Required receipt/vector boundary
Inline Avro signal/update arguments
The official Value codec decodes the payload. prepare_control_arguments accepts a list, or converts a nonempty outer map into argument values, then prepares the typed command.
Workflow must bind canonical argument-list normalization and exact typed intent. Map/list, bytes/text, integer/double and signed-zero cases must not be collapsed by JSON or PHP serialization. Automatic retries retain the same encoded artifact and key.
Runtime external_payload
The envelope must contain exactly codec + reference. The registered reference, codec, size, fetched snapshot integrity and official Avro datum are checked before use. Signals retain the registered reference; updates resolve the verified blob into their prepared arguments.
A URI alone is not intent. Retain the relationship between the verified artifact/reference and canonical typed intent; shared vectors must cover identical artifact retry, changed reference/datum, corruption, missing object and foreign namespace.
Provider external_storage
This native path explicitly refuses the provider reference.
Keep the refusal explicit. Do not silently accept it, infer plaintext equality or label it a legacy verified receipt.
Opaque/encrypted or PHP-specific values
No new transform is implemented by this specification. The native portable Value model has null, Boolean, signed long, double, bytes, string, array and map; PHP object/DateTime/Stringable serialization is not a native typed-Avro branch. Current native ingress also has an explicit non-finite-double refusal.
Workflow owns the inline/external/opaque transformation table, including embedded-only canonical cases versus admissible native input. Preserve existing codec refusals unless a separate reviewed protocol change intentionally alters them. No invented HMAC or inferred plaintext proof is needed for the unshipped encryption hook.
Concrete ordering gap: both signal preparation and update preparation call prepare_external before 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.json and resources/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.
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, MySQL workflow_commands.request_id is varchar(191) under inherited utf8mb4_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.
Authenticate and authorize the namespace/instance and requested read authority. Validate route, operation/key shape and envelope structure without fetching an external object. Look for the exact retained key before current-run/active/drain gates. A real legacy receipt may return only its own original outcome as intent-unverified; a missing key cannot create that state.
For a retained v1 row, compare supported intent. Inline values use Workflow's canonical typed-Avro vector authority. A repeated external artifact may use the retained binding between the original verified reference and canonical intent only after that binding is reviewed. The current reference includes schema, reference_id, codec, byte size and SHA-256; a URI alone is never sufficient. The original object becoming unavailable must not force fresh admission. The read-later route independently returns authorized retained state without resolving new command input.
Any needed fresh/changed artifact resolution and official Avro decoding occur outside the database transition transaction, using existing bounded transfer/snapshot capacity. Keep the verified snapshot alive until the final decision. Unsupported fresh opaque/transformed input refuses before admission; no guessed plaintext identity.
Re-enter the existing transition transaction, re-read the exact receipt key and retention authority, and decide against the current canonical row. A concurrent identical commit returns its original outcome; conflict makes zero command/history/task changes. If a row was pruned/reused during preparation, do not act on the stale earlier row or its artifact binding. For a genuinely absent key, apply current admission gates, claim external ownership, and commit the canonical command plus receipt/outcome together. A lost commit acknowledgement is recovered using that same key. No object fetch or unbounded codec work is added inside this transaction.
Retain the original admission HTTP status and canonical command/run identities, plus typed pending/completed state. An update's completed null must differ from pending. Store canonical intent/artifact identity in precision-preserving encoded/binary form; do not introduce JSON-number coercion into intent equality. No second receipt TTL is invented.
Retention is a real integration point. Current retention::PRUNED deletes 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 remains command_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.json and 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.
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.
Current native mapping for Workflow's canonical command-intent checkpoint, at accepted Server main d8eb3bc1a5368752be823784521a9a09ec44de71, native tree 131536cee548a04fd9784deb9611a7de485214e4. 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.
Boundary
Current native source
Mapping for the canonical artifact
Typed arguments
Value model has null, Boolean, signed long, finite binary64 double, bytes, string, array and string-keyed map. Bytes/text, integer/double and negative-zero bits remain distinct. Non-finite doubles refuse.
Preserve these portable distinctions and label Core-only object/DateTime/Stringable/protected-value conventions separately. A protected marker is not proof of plaintext equality. Do not turn an unsupported native value into a verified legacy intent.
Argument normalization
prepare_control_arguments accepts an Avro array, or a nonempty outer map whose BTreeMap values become the argument list. An empty map or a root of another type refuses; an empty array remains valid. Nested maps remain map values.
Include the explicit request-root normalization before canonical command comparison. In particular, a native outer map projects values in sorted key order, not arbitrary insertion order. Do not confuse that projection with nested-map canonical ordering or reorder argument lists.
Key and same-key conflict
Request rules validate the nullable body key and reserved bridge prefix. Ordinary signal rows do not persist a general receipt key. Update lookup checks an existing name/run after external claim and current-run selection, without full typed-intent equality.
The accepted v1 contract still requires exact namespace/instance/kind/key scope, full 255-code-point/1020-byte equality, typed conflict with zero writes, and retention of the original admission identity/outcome. MySQL's inherited 191-character, case/accent-folding command index still needs a narrow migration plan.
Closed and continued runs
Current update selection can reject a historical selected run before its existing row is consulted. Pruning deletes update/command rows tied to any applicable original/requested/resolved run.
Canonical vectors must keep closure distinct from detail pruning, preserve explicit selected-run intent and verified continuation handoff, and cover concurrent prepare/prune/key reuse. Pending command authority must neither disappear at handoff nor outlive its retained canonical authority. No second TTL is selected.
External/opaque input
Signal preparation and update preparation fetch the registered external snapshot before store lookup. The exact codec/reference envelope, registered binding, size/hash and official Avro datum are checked. Provider external_storage is explicitly unsupported.
Preserve a separate retained artifact-to-intent binding. A committed retry whose original object is later unavailable must not fetch or admit fresh input merely to recover its receipt. URI-only, changed/foreign/corrupt artifact and unavailable-transform cases cannot prove equality. The exact retained binding remains an implementation decision to review alongside the vectors.
Legacy and read-later
There is no native v1 intent field, independently authorized command-receipt route or advertised signal_update_request_receipts_v1 capability. Existing bridge deduplication is a separate authority.
For the proposed contract, a genuine historical receipt may return only its own original intent-unverified outcome. Missing/pruned is not legacy and never proves non-admission. Read-later is read-only, preserves authorization and distinguishes pending from completed-null. It must not trigger input preparation or admission.
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.
The canonical command-intent source-file dependency now exists on Workflow main through Workflow#1048: actual merge 78909284bbbd5cf9bc3b34c00a38a079ba35dbb5, tree b965189add3576b6b509df2a70bd5b3b12ea0b48, ordered parents [2de50a9e, dd64bf24].
I independently read resources/protocol/command-intent-v1-vectors.json from that exact merge using the GitHub contents object's base64 bytes, verified Git blob 5c8fcb73fe16f4dca4bae03e60da37f3919afa9c and SHA-256 445e5b4eef97e163fb459bc6662932b66e68c555e72ac0968d557767209d4092: 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.
Triage 2026-11-11: native validates request_id only; no durable dedupe key. Workflow#1048 vectors are merged. Next: server posts the schema/index plan; this is a schema change, so it should batch into the 3.5.0 bump with #1120 if ready. Owner: server.
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.
rmcdaniel commentedon Nov 11, 2026
Triage 2026-11-11: native validates request_id only; no durable dedupe key. Workflow#1048 vectors are merged. Next: server posts the schema/index plan; this is a schema change, so it should batch into the 3.5.0 bump with #1120 if ready. Owner: server.