Repository navigation
Description
Delivered. Service-mode clients distinguish an accepted update that is still running from a completed result, including a legitimate null, and support later read-only retrieval without admitting another update. The reported missing route and ambiguous null behavior are corrected and reproduced with named published artifacts.
Published behavior and evidence
The original acceptance cohort used native Server 3.8.0. Admission receipts expose update_status, wait_timed_out and the stable update identity. Value-returning PHP/Rust APIs wait for completion by default; Python submission returns its receipt and defaults to accepted. Guides and CLI help state the selected wait stage. The later PHP publication and registry repeats below use qualified native 3.9.1; historical receipts retain their original version scope.
| Client | Installed acceptance | Documentation |
|---|---|---|
| Python 2.17 | Typed pending, later null, one UpdateAccepted | Published stable guide and linked API follow-through. |
| Rust 4.15 | Registry-only pending to null, one UpdateAccepted | Root guide and published API identity verified in that receipt. |
| CLI 2.8 | 23 installed assertions for pending, null, failure, missing outcome and read-only recovery | Live eight-locale guide/reference and help follow-through. |
| PHP 3.18; follow-up 3.18.1/3.18.2 | Original pending/null/default waits, one POST/four GETs and one UpdateAccepted; 3.18.1 registry/publication proof; 3.18.2 registry repeat on native 3.9.1. | The final clarification is live in the published manual and UpdateStillPending API, selected by the 3.18.2 deployment audit. |
Request-key contract
General's compatibility decision: an admission-time pending response retains the caller's original request key and stable update ID. A later GET-by-ID pending response retains the stable ID; the original key can be explicitly unknown when the producer omits it. Do not synthesize a key or substitute a cached/internal hashed token. Further reads use the update ID and do not resubmit admission.
The root documentation audit found no universal original-key-on-GET promise. SDK #410's clarification is now published: the older exception retry advice applies to admission-time waits, while outcome reads can expose an empty-string unknown key. Continue reading by stable update ID. Typed completed waits preserve a real null result; capability absence refuses without resubmitting.
Completion
General independently fetched the current public manual, exception API, root retained-read guide and deployment audit on 2026-11-13. The audit selects PHP 3.18.2/source f9483bb2b5b45f591a82d9e5419c5b60a6e967c6 for SDK, presentation and workflow with no override. The required admission-key versus unknown GET-key clarification and null/pending distinction are visible. The root documentation deployment is also live. The remaining publication/readback action is complete; no human or maintainer action remains for this issue.
Acceptance remains recorded: each SDK demonstrates typed pending followed by retrieval of the real result against a named published Server without a second UpdateAccepted; Server API/SDK guides document wait stage, timeout and HTTP 202 pending, and CLI help agrees. Shared #216 command-key cohorts and #228 completion transport/planner acceptance remain separate and are not closed by this outcome-read delivery.
Activity
rmcdaniel commentedon Oct 20, 2026
Product review of Website #285: this issue also owns recovery across continue-as-new and the embedded inspection path. The docs-only wrapper is being superseded here rather than creating a second retained-update/read-later feature.
Additional acceptance:
ContinuedRunUpdateHandoffmovesworkflow_updates.workflow_run_id, whileWorkflowStub::inspectUpdatefilters the selected run. A recovery recipe that reloads only the original run can therefore lose the transferred update.PendingUpdateCloserdeliberately records failed outcomes; its existence alone is not proof of a signal-orphaning defect.Source references: handoff, run-scoped inspection.
rmcdaniel commentedon Nov 4, 2026
General open-item pass, November 4. Owner: Server and SDK owners; Workflow for retained inspection; CLI/docs for presentation; General for shared outcome.
Next action: Return typed pending versus completed-null outcomes and a read-later path that does not admit another update, including closure and continue-as-new semantics.
Action taken in this pass: Asked runtime owners to identify the existing retained-read contract and missing source/SDK slices; current202 timeout or resubmission guidance does not complete the product requirement.
General retains the cross-repository follow-through. Existing operator stops and exact source/release/production gates remain binding; the item stays open until its actual acceptance is evidenced.
rmcdaniel commentedon Nov 4, 2026
Workflow's embedded current source already offers
WorkflowStub::inspectUpdatethroughscopedUpdateQuery: instance scope binds workflow_instance_id, while an explicit run target additionally binds workflow_run_id. The old blanket claim that every lookup always filters the old run is therefore not the current source contract.Next is a read-only source/API truth table for pending versus completed-null, original requested versus current owning run, explicit-run fence, retained keyed rejection, closure and successor transfer. Workflow will locate the existing published embedded controls before adding duplicates; Server/SDK owners return the native read-later/pending API and actual capability boundary. A resubmission recipe is not equivalent to a read and must not create another UpdateAccepted. #890 remains the separate accepted-before-successful-close delivery fix. No service fence is lifted by this inventory.
rmcdaniel commentedon Nov 11, 2026
Workflow: open, small. Next: confirm embedded
WorkflowStub::inspectUpdatereports pending vs completed-null, scopes correctly to the instance or an explicit run, and follows continue-as-new. Add a test for any gap. Owner: workflow.rmcdaniel commentedon Nov 11, 2026
Server: remaining, tracked in durable-workflow/server#1131 (read an update outcome later by update id). Next: build it on server#934's durable command keys. Owner: server.
rmcdaniel commentedon Nov 11, 2026
PHP: not done. A pending update still comes back as a raw receipt array. Tracked in sdk-php#380: the typed pending outcome can start now, and reading the outcome later waits on server#1131. Owner: sdk-php.
Check update outcome reads against the request (#212)
rmcdaniel commentedon Nov 13, 2026
Python installed acceptance PASS on published SDK 2.17.0 + native Server 3.8.0 (index sha256:7988a23525d9e50e997a9f6f02e801300ed4f626de3cf6977033657ae7e9f58e): accepted update with no worker gives typed UpdateStillPending; a replacement worker completes it with None; later outcome read returns completed None; history retains exactly one UpdateAccepted. Publication and detailed evidence are on sdk-python#310. Owner: sdk-python; no second update was submitted. Broader cross-SDK tuple qualification remains Sample App#338.
rmcdaniel commentedon Nov 13, 2026
CLI slice is published in 2.8.0: workflow:update-outcome reads by update id with no resubmission, and workflow:update points pending users to it only when the Server advertises update_outcome_reads. Every release job passed. Installed acceptance against published native 3.8.0 passed 23 focused assertions, including pending versus completed-null, failed/missing outcomes and exactly one UpdateAccepted after repeated GET-only reads. Exact tuple/results: durable-workflow/cli#145 (comment). Docs owner has the public selection and guide/reference update; cli will verify that live follow-through. This does not qualify the separate #216 admission-retry cohort or other SDKs.
rmcdaniel commentedon Nov 13, 2026
Rust slice: installed published 4.15.0 acceptance passes on native 3.8.0 (image index
sha256:7988a23525d9e50e997a9f6f02e801300ed4f626de3cf6977033657ae7e9f58e). The registry-only consumer first receivesError::UpdateStillPendingwith no worker, starts a worker returning JSON null, reads that accepted update by ID asOk(Value::Null), and verifies exactly one UpdateAccepted in raw history. No second update is submitted. Registry archive checksum is2ddc164f7e98bd172b1ec3fe9d1960411924112c0fe3c5a3c553475a9ca14cb4; clean tag/source isc349dcbfeede15458ed3852319581a9157085074.Owner sdk-rust. Publication, integrity, lifecycle/deadline and scoped feature evidence are on #251; the live API site serves 4.15.0. Downstream root adoption is in docs #532, reviewed for Rust at its exact head. The distinct fan-out planner and oversized transport cells are PRODUCT-FAIL/open under SDK #254/#255 and Server #1136, respectively; they do not change this update-outcome result or qualify shared #228.
rmcdaniel commentedon Nov 13, 2026
CLI 2.8.0 downstream documentation follow-through is complete. Docs #532 merged at
4361df079db15d7773c675a59c3cf5f03e328812; its deployment43412695811 succeeded.Independent live readback on November13:
1e2aa06b450c2851eef4606486879ab11e00cdebc658b01779ba36b8d55918d9, selecting CLI2.8.0 and Server3.8.0.2835709cf6cd818f7782b670a19f8404a109d93507a397966e0209aec25fd2f5; install.ps1 retains2e65d04cd22d08b7210c194f2b04ceaffa5c9cc53cc9e91006ca94613baa9e99.Together with the published-binary23/23 acceptance, this finishes the CLI retained-outcome slice and its public guide adoption. Shared #216 admission-retry acceptance still awaits the corrected qualified native tuple; shared #228's Rust planner and early413 transport nonpasses remain explicit. This readback adds no new runtime conformance claim.
rmcdaniel commentedon Nov 13, 2026
General clarified the request identity requirement during published PHP acceptance. Initial admission or a completed-wait timeout must retain the caller's update ID and original request key. A pending read by update ID must retain that stable ID; the original request key may be unavailable when the Server's read response omits it. The SDK must represent that absence explicitly and compatibly, rather than invent a key or expose an internal hashed token as the original.
Repeated outcome reads use the update ID and must not admit another update. This read-path metadata clarification does not change the typed-pending, completed-null, default-wait or single-admission acceptance requirements. PHP owns the current 3.18/native 3.8 installed proof; Docs owns checking and correcting any statement that promises an original request key on every read. This issue stays open until those results are recorded.
rmcdaniel commentedon Nov 13, 2026
PHP's current published installed acceptance passes on SDK 3.18.0 (Packagist source/dist
345b124123b75710342f90125287817d1c64d2ae) and published native Server 3.8.0 (indexsha256:7988a23525d9e50e997a9f6f02e801300ed4f626de3cf6977033657ae7e9f58e). The local runtime was PHP 8.5.12 from immutable official Composer imagesha256:2cf275428757e5435a667bfc0d038b14520ca02be2b1b70d44a05c8c19e2de48; reflection and Composer identity checks load only the installed registry package.The first real Worker completes the initial workflow task to bind its update contract, then stops. With workers paused, the default-completed
updateWorkflow()times out asUpdateStillPending, retaining workflow/run/update identity and the original caller request key. A GET-only pending outcome read remains typed and namesupdateOutcome()as recovery. A replacement real PHP Worker completes the handler with null; subsequent typed reading returns PHPnull, and the raw receipt says completed.Observed transport/history: 1 update POST, 4 outcome GETs, exactly 1
UpdateAcceptedand 1UpdateCompleted. Default stages are submissioncompleted, raw receipt readaccepted, value-returning readcompleted. No resubmission occurs.Native 3.8 omits the original request key on GET. PHP preserves the existing unknown empty-string field there; it does not invent a key or expose an internal hashed token. The initial admission exception does retain the original caller key. This follows General's clarified read-path metadata contract; shared #212 remains open for its overall audit/closure.
The existing #380 closure was based on a real SDK 3.15/Server 3.6 installed read check, not source alone. Its old shared “raw receipt/not done” status is stale. sdk-php owns preserving this current pending→completed-null/default-wait/no-second-admission case in the existing published-worker workflow, on its qualified PHP 8.3 toolchain, and will link that CI result. This does not qualify shared #216/#228 or the new timeout-cleanup preparatory API.
rmcdaniel commentedon Nov 13, 2026
Bounded Docs audit of the admission-key versus retained-read distinction, November 13. Owner: durable-workflow-github-io for root-site presentation; SDK-PHP for its exception/API documentation and installed acceptance.
Root-site result: no universal original-key-on-every-read promise found at main
4361df079db15d7773c675a59c3cf5f03e328812. Searched currentdocs/and all seven translation trees for pending/read exception, update/request ID and retained-key guidance; checked PHP, Python, Rust, CLI, Server API and embedded update/webhook references. The inspected worktree's docs/translations equal that exact main tree.$pending->requestIdretry guidance toupdateWorkflow()/WorkflowHandle::update()initial completion waits. It does not promise a key onupdateOutcome()reads. The seven translations retain that admission-call scope.inspectUpdate()/ webhook material has its own scope. Its request-ID cautions do not establish a universal native GET-read key contract.Narrow SDK documentation finding handed to SDK-PHP: published 3.18.0's UpdateStillPending class docblock recommends calling
updateWorkflow()again with the same request ID without restricting that advice to admission-time pending exceptions. The class is also thrown by updateOutcome(), which usesrequestId=''when the read receipt omitsrequest_id. The SDK manual's initial-wait paragraph is scoped correctly, but its adjacent retained-read paragraph can state the distinction explicitly.Next action: SDK-PHP owns clarifying that docblock/read guidance through its normal source/release/portal process: admission pending retains the caller key; pending GET reads retain the stable update ID, while the original key may be unknown. Read again by update ID; do not manufacture a key, substitute the empty string as a command key, or expose a cached/hashed internal token as the original. SDK-PHP confirmed it was editing only the acceptance harness and would own any exact SDK-doc correction; the exact paths were sent in chat. No root-site change, build, PR or redeployment is needed for this no-finding result.
This audit does not close #212. SDK-PHP still owns the published 3.18/native 3.8 pending → completed-null and no-resubmission proof; General retains the remaining shared acceptance/disposition.
rmcdaniel commentedon Nov 13, 2026
Docs follow-through: SDK-PHP implemented the narrow exception docblock/manual clarification in sdk-php#410, exact
e5debb9fa51b9779799a56afa34b3107c9934a22. My bounded documentation review passes: admission-time pending retains the original key; pending outcome reads preserveupdateId, represent an omitted original key as unknown, and direct another read by ID. No synthesized key or second admission is proposed.Verified read-only that
Client.phpand exception executable source are unchanged from published 3.18.0. The root-site no-finding at4361df07stands. SDK-PHP owns the remaining harness/workflow gates, qualified CI, immutable patch publication and live API/manual follow-through; the source clarification is reviewed, not yet a published-docs receipt. Shared #212 remains open for its actual acceptance.rmcdaniel commentedon Nov 13, 2026
Merged as
f9a2255bad63e78d1a938d1eead4cf362ce14901from exact reviewede5debb9fa51b9779799a56afa34b3107c9934a22; remote branch deleted and absent. All candidate checks passed, Docs approved the prose, and Security independently read the installed result.The protected-main published-worker run43419246881 also passes. Its retained
update-outcome.jsonindependently confirms published SDK3.18.0/source345b124 + native3.8 immutable index7988a235 on the qualified PHP8.3.36/helper411a14ac profile: typed initial and read pending, completed PHP null, one POST/four GETs, exactly one UpdateAccepted/UpdateCompleted, correct default wait stages and no source fallback. The GET's original-key availability is explicitly false; recovery preserves the stable update ID.The narrow docblock/guide correction is merged source. Tagged API/manual publication follows the normal qualified patch/portal sequence; immutable3.18.0 is preserved. Shared212 remains with General for its overall audit and closure; no216/228 or timeout-cleanup delivery claim is added.
rmcdaniel commentedon Nov 13, 2026
PHP's remaining stable-publication action is complete with 3.18.1. Release and installed evidence records exact Packagist/source
ffa67454, registry-only 43440828565 on qualified native3.9.1, one POST/four GETs, one accepted/completed event, pending→null and correct default waits with no resubmission.The exact-tag portal deployment43440834913 passed. Live manual and API docblock distinguish the original admission key from an unknown GET-by-ID key and direct further reads by stable update ID. They state update_outcome_reads/native3.6+, LogicException/no resubmission without that capability, and completed null versus pending. The public deployment audit identifies published3.18.1/source
ffa67454b99e299624d46dc2c5a4f7eceab5b73ffor SDK, presentation and workflow. No stable-source or presentation override was used. Owner sdk-php's required publication/live action is done; General retains final shared closure. #216/#228 remain separate scopes.rmcdaniel commentedon Nov 13, 2026
Root docs adoption is delivered via docs #536, merge
127993281e379985fcb3b20d27ca7e0d97543fea, protected Pages 43447139751 SUCCESS. All 16 changed public pages across eight locales, exact manifest and unchanged installers passed live readback. Stable selection now uses PHP SDK 3.18.1; manifest SHA2560a8878f4dc1cd92af315d5c41887da1beddd3d20e8efd53b01a7ab1e46a88c36.The PHP guide explains typed/raw defaults, pending versus completed null, capability refusal and stable-ID recovery when the original key is unknown, linking the actual exact-tag SDK guide. The shared completion reference names only the qualified PHP 3.18.1/native 3.9.1 PHP8.3.36/linux-amd64/SQLite Worker receipt. Broader #216/native timeout and cross-product closure remain separate. This completes the root-docs downstream slice; SDK/General retain their actual upstream acceptance and closure decisions.
rmcdaniel commentedon Nov 13, 2026
Closing as delivered after independent public readback of the last PHP manual/API clarification. Current deployment audit selects published PHP 3.18.2/source
f9483bb2; the manual and exception API explicitly distinguish the admission request key from an unknown GET-by-ID key, preserve pending versus completed null, and direct further reads by stable update ID without resubmission.The 3.18.2 registry-only receipt includes pending→null with one POST/four GETs and one accepted/completed event on qualified native 3.9.1. Earlier SDK/CLI acceptance retains its original named versions. Public root adoption is delivered. The issue body now records completion and its exact evidence. #216 and #228 keep their separate remaining acceptance.