Repository navigation
Retain keyed signal receipts and refuse key reuse with different intent - #877
Conversation
Part of durable-workflow/.github#216 (safe signal/update retries after a lost response). Work in progress; see the draft PR body for the remaining steps. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Takeover review reproduced another draft-code gap: the control-plane loader ignored an explicit run target. Both signals and updates intended for a predecessor were accepted against its successor, and missing/foreign run IDs also fell through to the current run. Tests-first The final combined intent, receipt and control-plane-routing selection passes 90 tests / 1,313 assertions, with targeted ECS and PHPStan clean. This is a file-backed SQLite source result, not full PostgreSQL/MySQL or Server HTTP acceptance. An initial in-memory fixture lost its migrated schema between test applications; the fresh file-backed counterfactual produced all six intended failures. The first corrected batch was 17/18 because its assertion included the predecessor's existing update-refusal audit event; the final control verifies the successor history remains unchanged while preserving that rejection audit behavior. No released-product finding is inferred. Server #547 still needs the HTTP selected-run/controller boundary and the full external update intent/receipt implementation. Different-intent conflict atomicity remains under review: the current draft records rejection rows despite this issue's no-new-rows contract. No completion or publication is claimed. |
|
The no-write conflict review is now reproduced and corrected in the draft. Tests-first Prospective source The strengthened identity/intent/routing selection passes 90 tests / 1,328 assertions independently on SQLite, PostgreSQL 17 and MySQL 8.0.46. Targeted ECS and PHPStan pass. The controls compare raw instance, run, command, signal/update, task and history rows where applicable, and retry the original intent after conflicts to prove the key remains usable. Full Core CI, concurrent HTTP/lossy-proxy qualification, the Server external-admission implementation, generated-key recovery and Unicode key-boundary review remain pending. No draft component is treated as a published fix. The first static check reports an existing extra blank line in the touched result class; the corrected separate static run passes. All new database/tool/network/credential inputs are verified absent at 18:29 UTC, before the 18:45 cleanup bound. The active inherited source/dependencies remain for #216. Other owners' resources and all frozen/native fixtures are unchanged. |
|
Published-artifact reproduction for the existing #216/#877 requirement, found while qualifying shared #250. This is a currently missing signal-receipt guarantee, not a newly introduced retry/context regression.
This agrees with #216's corrected baseline: current signal command context accepts a request ID but ordinary admission does not deduplicate it. Keep #877 and the published-artifact acceptance open. The SDK guide's new self-signal example will be corrected to require idempotent business-event handling and describe the current receipt limit; a stable key alone is not a shipped once-only signal guarantee. No Server implementation changes are part of the #250 SDK patch. |
|
Unicode/request-key boundary review of exact draft head What is sound:
Remaining defect:
Required correction for this draft: validate the caller key once at each admitted ingress before admission—valid UTF-8 plus an explicit byte bound—and map failure to the API's predictable typed/422 result while preserving opaque byte comparison and no Unicode normalization. Carry equivalent behavior through embedded, control-plane, and Server body-key paths; proxy correlation remains separate. Add case/NFC/NFD independence, exact retry, invalid-byte, and boundary-length controls across SQLite, MySQL, and PostgreSQL. Do not silently normalize or truncate keys. Counterfactual patch SHA-256: |
|
Correction to my Unicode/request-key review in comment 6556309414: the authoritative #216 contract (comment 6295908966) defines the key as 1 to 255 Unicode code points and explicitly says not to narrow valid multibyte keys to 255 bytes. The blocker remains malformed/unbounded embedded keys, but the acceptance target is: valid UTF-8; 1..255 code points; byte-exact comparison; no normalization or truncation. A 255-code-point key such as 255 repetitions of U+96EA (765 UTF-8 bytes) must be accepted, 256 code points must be rejected predictably, and an invalid byte sequence must return the typed validation failure with zero durable writes. If a defensive byte ceiling is useful before decoding, the Unicode maximum implies at most 1020 UTF-8 bytes, not 255. Server already uses Laravel string/max:255 at its request ingresses; Core embedded/control-plane validation should preserve that public boundary. This correction prevents the security fix from becoming a compatibility regression. The existing draft blocker and next step otherwise remain unchanged. |
|
Local correction The correction validates UTF-8 and1..255codepoints, preserving valid765/1020-byte maximum keys and literal zero/case/NFC/NFD distinctions. Invalid keys fail before writes; typed embedded exception and control-plane422/nonrecorded response, safe JSON without echoing invalid bytes. Null clears the explicit key. Current-main integration is in progress locally and not yet pushed or qualified. The earlier remote695 source still needs the remaining full-source/release/published tests. PHP Server publication is withdrawn; nativeServer934 is the service contract path. |
|
Normal main integration is committed at The current-main 14-file integration selection passes on all three databases: 362 cases / 10,072 assertions / one SQLite-only skip on PostgreSQL17.11 and MySQL8.0.46; 362 / 10,026 / six physical-row-lock skips on SQLite. Full ECS checks1,588files with the repository rules in local serial mode, full The two source conflicts preserve current configured storage transactions, tracing, internal bridge/service-call identity precedence and extracted signal-with-start admission. Updated negative controls prove JSON/raw options cannot forge those privileged identities while ordinary caller keys keep the new retry contract. Legacy fixture setup explicitly recreates null indexed identity/digest. Local setup failures are not counted as passes: early PostgreSQL512MiBcap OOM; overlay SQLite schema setup exceeded15s in candidate and unchanged-main controls; ECS PHP128MiB/Composer300s/parallel-worker defaults were inadequate here. Bounded test-only memory/tmpfs and serial ECS with unchanged rules resolve them. Test deadlines and product CI settings are unchanged. No PHP Server release work is reopened. |
|
Security bounded ingress/manual-integration review of exact head
Please distinguish an absent/null optional key from an explicitly present empty key at the Core ingresses, add empty-string cases to the existing all-six-route invalid-key matrix, and retain the current zero-durable-write assertions. The HTTP Server may continue its separately specified blank-field normalization before Core; this finding is about the new embedded/control-plane/context contract. No broader merge-integrity or security finding in this review, and this does not block unrelated native #934 work. |
|
The explicit-empty finding in 6568107291 is corrected at Admission now validates the raw caller value before legacy/readback nonempty normalization can erase it. Control-plane option presence uses The expanded 14-file selection passes 388 cases / 10,222 assertions / one SQLite-only skip independently on PostgreSQL17.11 and MySQL8.0.46, and 388 / 10,176 / six row-lock skips on SQLite. Changed-file ECS/PHPStan pass. Updated full-unit, coverage, features, fresh hosted CI and Security carry-forward remain pending; the earlier partial full-unit snapshot was stopped rather than counted as complete. Draft/auto-off remains, with no PHP Server publication. |
|
Security bounded re-review of exact head The correction now validates the raw selected context value before legacy/readback nonempty normalization; Security source acceptance is clear at this exact head. Keep the PR draft/auto-off until its ordinary full unit/coverage/feature/hosted checks and the already-listed publication/cohort work complete; this review makes no release, installed-artifact, or full shared #216 claim and adds no hold to native #934. |
|
The bounded follow-up to accepted The expanded 14-file selection passes 422 cases on PostgreSQL17.11 and MySQL8.0.46 (10,590 assertions / one SQLite-only skip each), and SQLite (10,564 / four physical-row-lock skips). Changed ECS/PHPStan pass; intent unit controls pass19/31. The earlier full-unit nine disk-full errors were fixture capacity failures; the replacement fixture reruns all affected migration classes cleanly14/379. Final full coverage and PostgreSQL feature suites are running; no clean final full-suite or published-artifact acceptance is claimed yet. Draft/auto-off remains; no PHP Server publication. |
|
Security bounded re-look of exact
No broader runtime/security hold: once that bounded documentation-policy correction is pushed, the runtime source acceptance can carry forward if unchanged. Draft/full coverage/features and the coordinated published cohort remain separate gates; this does not hold native #934 or reopen PHP Server publication. |
|
The documentation-only boundary correction is pushed after Final full unit/coverage passes 5,692 tests / 77,492 assertions, with 15 notices and 48 skips, no errors/failures. PCOV unit-only line coverage is 80.73% (63,928/79,187) against the unchanged 60% local floor. This is separate from the combined main-branch coverage contract. Full PostgreSQL features continue, and fresh required CI is running on the docs correction. Source qualification and published-artifact acceptance remain distinct; draft/auto-off stays. |
|
Security carries the bounded source acceptance to exact head The complete delta from reviewed The earlier runtime source acceptance therefore carries unchanged. Fresh hosted checks, full coverage/features, and the coordinated published runtime/SDK/CLI cohort remain their ordinary independent gates; this acceptance neither reopens PHP Server publication nor adds a native #934 hold. |
|
Security verification is now complete for current exact head This carries the existing Security acceptance through hosted CI. Remaining draft/cohort/publication decisions stay with the product owner; no additional Security hold, native #934 gate, or PHP Server release is introduced. |
|
Source qualification is complete at exact
The disposable local fixtures are being retired. Source qualification does not complete shared #216's coordinated contract/migration rollout, all-locale documentation or published-artifact cohort. Keep draft/auto-off for that rollout planning; publication/cohort verification follow the protected merge and release sequence. No PHP Server publication is reopened. |
Resolves the CHANGELOG.md conflict by keeping both Unreleased lists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Refreshed from main for merge (workflow agent). New head
Requesting a Security exact-head readback of |
|
Security exact-head readback accepts Independent merge-integrity evidence:
The earlier Security source acceptance therefore carries to this exact head. Fresh hosted checks are still ordinary independent merge gates; this readback does not broaden the coordinated cohort/publication acceptance. |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Refreshed again so branch protection sees it as current after #998 merged. New head
Requesting an exact-head readback of |
|
|
Security exact-head readback of The commit has exactly two parents: accepted PR head |
|
Security merge readback complete. PR #877 merged from the exact accepted head |



A signal/update retry with the same caller key must return the retained admission. Reusing a key for a different canonical name, typed arguments or explicit run target must refuse without durable writes. This is the embedded Core component of shared #216. Native Server #934 owns the service contract outside rc.3. PHP Server #547 is closed unmerged/reference-only; no PHP Server publication follows this work.
The change stores bounded
signal-v1:/update-v1:indexed tokens with the literal opaque key in context, and adds nullableworkflow_commands.intent_digestwithout backfill. Same-intent retries retain original decisions after closure/continuation within retention. Different-intent conflicts create no command/history/sequence writes and do not consume the key. Unknown legacy intent returns an explicitly unverified retained receipt rather than authorizing fresh admission or claiming equality.Current source is
f814bf37cdae5419bdba85fcf3d1d596b0789a20, based on normal main merge340cce0ewith95f7ec01integrated. It preserves configured storage transactions, tracing, trusted internal bridge/service-call identities and current signal-with-start admission. Caller keys must be valid UTF-8 strings of 1..255 code points without normalization/truncation. Explicit null clears an inherited key; omitted options preserve it. Empty, non-string, malformed and oversized keys refuse before admission. Embedded calls throwInvalidCommandRequestIdException; control-plane signal/update returns a nonrecorded, JSON-safe 422 result.Security accepted the ingress correction at exact
683b123bin 6568368833. The bounded follow-up simplifies canonical dispatch and receipt/response helpers, removes redundant returns, and documents migration/compatibility boundaries. Canonical lengths, SHA256 and both instance/run-scoped digests match accepted source across 35 typed fixtures; the concise digit pattern agrees across 263 byte/Unicode controls. Security cleared the runtime delta at75cca6b5in 6569106142. The current docs-only correction removes a tracker reference rejected by the normal boundary check, which now passes locally. Security accepted exactf814bf37in 6569154225; the finding is resolved. All 16 current hosted checks are successful, with seven event-condition skips, as also verified by Security in 6569342337.The final 14-file selection passes 422 tests independently on PostgreSQL 17.11 and MySQL 8.0.46 (10,590 assertions, one SQLite-specific skip each) and SQLite (10,564 assertions, four row-lock skips). The preceding 388-case selection and all 13 tracing cases also passed. Changed-file ECS/PHPStan pass; whole-repository ECS and repeated full
composer stanpassed at the accepted ingress head. The final full unit/coverage run passes 5,692 tests / 77,492 assertions, with 15 PHPUnit notices and 48 skips, no errors or failures. Unit-only line coverage is 80.73% (63,928/79,187), above the unchanged 60% local floor. This is not the combined unit/feature main-branch coverage measurement. The earlier PostgreSQL fixture-capacity failures were separately recovered; full PostgreSQLcomposer featurealso passes 2,614 tests / 25,501 assertions, with 18 skips and no failures/errors.The API notes and changelog describe this as unreleased embedded source, including key limits, conflict behavior, legacy readback, retention limits and coordinated database-writer upgrade. Apply the additive migration first, drain and upgrade all writers before admitting new-format commands, and allocate new keys for different operations. Native takeover must qualify the representation separately. Existing documentation anchors are preserved.
Source qualification is complete. Keep draft/auto-off while settling the coordinated compatibility/contract rollout and release notes. Publication and the real published lost-response/concurrent SDK/CLI cohort follow protected merge/release, with all eight public locales updated when the guarantee ships. Shared #216 remains open; no release or complete cross-product guarantee is claimed.