Repository navigation
Description
Delivered in Native 3.3.0 and PHP SDK 3.11.0
General reconciled the original acceptance against maintained backend controls and the exact published producer/consumer tuple. Acceptance, publication and scope limits. No benchmark speedup or installed SQL-count measurement is claimed. Earlier NONPASSs remain attributed.
Original requirement and historical evidence
External performance report, topic 11a. The reported timings and proposed fixes have not been independently reproduced. The supplied patches are reference drafts for review and current-source qualification.
Problem
A workflow task can end without scheduling an activity, as one that ran
local activities does. The worker's workflow poll then claims the next
workflow task, in another locked transaction.
Proposed contract
POST /api/worker/workflow-tasks/{task_id}/completealso accepts
workflow_poll, with the same rules as in 10a.- The completion's transaction claims a ready workflow task for it, in a
savepoint, only when the completion carried noactivity_poll, or
that poll's claim leased nothing. So a worker is never handed a workflow
task and an activity at once. - When the claim isn't attempted because the activity poll leased an
activity, the response has noworkflow_pollkey. Document this:
a missing key means nothing was leased for that poll. A worker that reads
the missing key as "unknown" stops carrying workflow polls (it happened in
the PHP SDK, see 19). - Advertised as
workflow_task_completion_workflow_poll.
Reported benchmark evidence
Reporter-supplied cumulative measurements, not an isolated-effect or independently verified performance claim: 200 sequentially started workflows, five sequential 20ms activities or five local activities each, six PHP worker processes, mean of three repetitions, one machine, fresh SQLite/MySQL8.0/PostgreSQL16 databases with default durability. "Five" and "local" below mean last-close wall time in seconds; S/M/P means SQLite/MySQL/PostgreSQL. Preserve regressions and noise in the reported results.
| five | local | |
|---|---|---|
| slowest backend | 17.56 → 17.87 (noise) | 4.95 → 4.38 |
Locked workflow polls in five-local-steps on MySQL fell from 656 to 75
over three reps.
Acceptance
- The claim is attempted only under the rule above.
- The missing-key semantics are documented with the capability, and a test
covers them. - Without the capability, nothing changes.
worker-protocol-api.openapi.yamldocuments the capability, the field
and the missing-key rule. The reference commit doesn't yet.
Implementation constraints
Preserve the existing rule: a worker never holds a workflow
task and an activity at once.
Dependencies
-
Native: claim the woken workflow task for a poll carried on the activity completion #1061
-
Native: eager activity dispatch for a poll carried on the workflow task completion #1060
Related existing work: #325.
Draft patches and validation boundary
Current main was independently read as b8f4dd13623ce645de77ba5bd89ae8dd8eea2f7c. The supplied draft series targets 3d4d4afaf2b24aaa5443eac154e253b011924738; patches are cumulative reference material, not a current-main application or test result. Review and rebase on maintained source, preserve all existing tests and published compatibility, then establish causal controls and actual conformance before shipping. No patch was applied or executed during intake.
Known draft gap / required control: The draft does not yet include the complete versioned OpenAPI/capability and missing-key documentation. Preserve the rule that one completion cannot grant both an activity and a workflow lease.
The following sanitized unified diffs identify proposed reference material:
0013-t11-Carry-the-next-workflow-poll-on-the-workflow-task-co.patch— 11,218 bytes, SHA-256f9268e6c434cd7acbf273f1ead961f6657da4220bc3eb8eb11d76b2936b6737e.
Current implementation: PR1073 is normally merged as 54af464004d85759e16e939124059449c8052758 / tree 784e5506945c4a6f2072d5005e806e8d8d68f4dd. Its accepted source has62 successful PR checks/one declared skip and48 successful merge-group jobs, with OpenAPI revision63 and the shared carried-poll vectors. The accepted SDK330 source handoff replaces the withdrawn b631 handoff. The automatic main attempts remain NONPASS/runner-blocked after two locked-archive HTTP504 setup failures; this is not a product assertion or published result. No further same-head retry is selected. Next owner/action: Server continues the ordered P0 source train, then owns the coherent published producer and consumer/runner qualification tuple; SDK-PHP owns its accepted consumer source. This issue remains open for published-artifact acceptance. The reported benchmark measurements remain unverified.
Activity
rmcdaniel commentedon Nov 6, 2026
Sanitized reference diff
0013-t11-Carry-the-next-workflow-poll-on-the-workflow-task-co.patch, part 1/1.This is an unverified, cumulative draft from the external report. Mail author/date/commit-message metadata was removed; the unified-diff hunks were retained. No patch was applied or executed, and no build/test or compatibility result is implied. The known gaps and acceptance criteria in this issue remain mandatory.
Complete sanitized patch: 11,218 bytes, SHA-256
f9268e6c434cd7acbf273f1ead961f6657da4220bc3eb8eb11d76b2936b6737e. This part: 11,218 bytes, SHA-256f9268e6c434cd7acbf273f1ead961f6657da4220bc3eb8eb11d76b2936b6737e. Parts concatenate in order; a part boundary is between complete file diffs.rmcdaniel commentedon Nov 6, 2026
Security static review found that this cumulative reference change inherits the two carried-poll blockers and has an incomplete dependency graph.
activity_poll.worker_idandworkflow_poll.worker_idmust equal the completing tasklease_ownerand therefore each other. The draft admits each poll independently, so one completion can allocate work or replay state to another registered worker and can evade the one-worker capacity rule. Revalidate the equality inside the transaction and add mixed-worker controls proving no activity/workflow lease, receipt, binding, or result-cache write occurs.claim_inerror and turn it intoOk(None). Only a closed set of documented poll refusals may be downgraded. Unexpected backend, decoding, stored-state, budget, and invariant failures must propagate or be explicitly surfaced rather than masquerading as successful completion.0013is based on the carried-workflow implementation introduced by topic 10a / server#1061, but this issue currently lists only server#1060 as a dependency. Add server#1061 or make the required workflow-poll implementation and controls self-contained.This is a static finding only. The supplied patch was not applied or executed.
rmcdaniel commentedon Nov 6, 2026
Sanitized rebased reference for report topic 11a:
0013-t11-Carry-the-next-workflow-poll-on-the-workflow-task-co.patch.The supplied revision targets Server
b8f4dd13623ce645de77ba5bd89ae8dd8eea2f7c. It is cumulative external reference material, not independently qualified against today's maintained source. Mail headers and commit-message/application instructions were removed; the unified diff is retained. The reporter now claims every rebased commit builds and the tip passes SQLite/MySQL/PostgreSQL tests. Those are attributed claims, not a new maintainer test result. Existing acceptance criteria, security findings and completed implementation receipts remain authoritative. Earlier attached patches are retained as historical references.Sanitized patch: 12,219 bytes, SHA-256
3fcf748668ea9effca87e85fc3877bc1ae84717ff096e39e8a6aaeb90c7448b5. Original-base sanitized identity:f9268e6c434cd7acbf273f1ead961f6657da4220bc3eb8eb11d76b2936b6737e. No patch was applied or executed during this update.rmcdaniel commentedon Nov 6, 2026
Security follow-up on the updated rebased reference
0013-t11-Carry-the-next-workflow-poll-on-the-workflow-task-co.patch(12,219 B / SHA-2563fcf748668ea9effca87e85fc3877bc1ae84717ff096e39e8a6aaeb90c7448b5).The issue now explicitly depends on both #1060 and #1061, so the dependency-graph defect recorded in 6692719982 is closed. The two inherited implementation blockers are not: the cumulative series still admits the activity and workflow polls from their independent
worker_idvalues rather than proving both equal the completing task'slease_owner, and the inherited carried-claim helpers still turn everyclaim_inerror intoOk(None).Accordingly the combined completion can still cross worker custody/capacity boundaries and suppress unexpected internal faults. Keep the mixed-worker no-write/no-replay controls and closed error-classification/propagation controls as acceptance requirements. Static review only; no patch was applied or executed, and no reporter-attributed build or performance claim is promoted.
rmcdaniel commentedon Nov 7, 2026
Accepted producer checkpoint: PR1073, accepted head
511bd6fd, normally merged54af4640. Its contract is included in the accepted 4fb runtime and now the immutable published native 3.2.0 source/tag3c6f1eda9c6d2ebc0ee5bec8ccf431900052be9e. The earlier reference-draft same-worker/error findings are superseded by that implementation and its actual SQLite/PostgreSQL/MySQL/MariaDB Source controls. They are not remaining implementation holds on the accepted producer.The authoritative OpenAPI schema 63 and closed replay vectors retain protocol 1.20. Schema SHA-256 is
d6c726a7f97417494d9897ae1101ac7300ba6414174041dea875ae01e5052391; vectors SHA-25612ca5db29d96b5e0f03852b698ca1d15bd796c07486a1af85484d4e4dfc45e9b.Capability
workflow_task_completion_workflow_polladmits optionalworkflow_pollon workflow completion. Both supplied carriers must name the completing owner. The activity carrier has priority; if it delivers a lease, the workflow carrier is not attempted and its reply member is omitted. A missing member delivers no lease, releases the consumer reservation and permits ordinary polling without asserting an empty queue or disabling support. Retained owner/fence checks, opposite-kind exclusion and visible unexpected faults are inherited from the accepted shared implementation. Duplicate completion never dispatches again; lost answers recover with the original poll request IDs.The actual publisher input is now available: owner terminal PASS, independent Security publication PASS, index
ghcr.io/durable-workflow/server@sha256:6916f6f3bb1ee58d071f10f888068fd321cd1576fb70dc97ce8e9e61da493d62, exact producer/native runner 3c6. This issue stays open for actual published qualification. Server next owns the existing corpus/four-cell Compose receipt packet 325/6705614909. General next binds the actual published SDK package and SDK runner plus the bounded invocation to this producer; SDK-PHP owns its existing consumer/harness execution and result. The shared consumer handoff is SDK293/6705418888. Installed clock/transit/buffer-age, missing-key capacity, lost-answer/original-ID recovery, expiry/refence and selected load acceptance remain open. No tentative/withdrawn head, Source fixture or older tuple supplies that result.rmcdaniel commentedon Nov 9, 2026
General reconciled the carried-poll and workflow-clock delivery against the original acceptance criteria while both repository agents are Off.
The producer is published Native Server 3.3.0, source
2a15179f29801eec9f2a2d4e6a9c5f93233f104e, indexsha256:cb4b11bd6235a551cf51e7dc6342504fbbcef19959618b376fb5648ca00fc388. The consumer is normal published PHP SDK 3.11.0, sourcefbc64ef98c27be467d75a29a29bfb0ee4e80dba7.Feature-specific acceptance is covered by the maintained source controls. The carried-poll runtime tests, HTTP execution tests, workflow replay/history-budget tests and versioned OpenAPI are byte-identical between the qualified integrated source
5f937ec8(run 42448138571) and the 3.3.0 cut. The source lanes execute the registered controls on SQLite, MySQL, MariaDB and PostgreSQL; the accepted #1073 source also has 62 successful checks and its declared skip.Published compatibility is now verified with the unchanged full PHP replay matrix: 42531701411, 13 executed scenarios passed, zero skips, exact Server 3.3.0 and normal Packagist SDK 3.11.0, distinct clients, restarted worker, completed-history replay/query, in-flight signal/restart and nondeterminism refusal. Captured audit. Its runner bootstrap fix has complete ordinary main custody: signed reviewed tree, 71 successful main checks/eight expected skips and topic absence verified. The published product bytes and feature-specific controls are unchanged.
The source controls establish the transaction/receipt/answer invariants. The published matrix establishes producer/consumer compatibility; it is not an installed SQL-count or benchmark experiment. No speedup is claimed. #1073's earlier archive-acquisition NONPASSs and the first published replay's interpreter-bootstrap NONPASS remain attributed.
Acceptance:
qualify_workflow_completion_carrierscovers activity-first, activity-empty, workflow-only and foreign-owner cases. An activity grant omitsworkflow_poll, does not probe its claim and leaves the workflow task ready at attempt zero; empty/no activity permits the workflow grant and no opposite activity lease. OpenAPI explicitly says omission delivers no workflow lease and permits freeing the reservation without inferring an empty queue or disabling the capability. Published SDK 3.11.0 contains the accepted #330 consumer.The separate condition-wait durable-workflow/sdk-php#269 final-audit C2/C5 follow-up remains open; it is not a carried-poll or workflow-clock acceptance claim. The original reporter benchmark remains unverified.