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 16a. The reported timings and proposed fixes have not been independently reproduced. The supplied patches are reference drafts for review and current-source qualification.
Problem
After 9a, 10a and 11a, a completion that claimed for its carried poll
answers {"leased": true}. The worker then sends that poll just to replay
the lease from its receipt. That's lock-free, but it's still one HTTP round
trip per workflow task or activity.
Proposed contract
- The completion returns
{"leased": true, "answer": {...}}. The answer
is what the poll under that request ID would replay now: the task, its
history encoded for the poll's encoding,server_capabilities,
server_timeandprotocol_version. {"leased": false}is unchanged.- The receipt stays, so a worker that ignores
answerpolls under the
same request ID as before.
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-steps: MySQL 15.37 → 14.95, SQLite 11.04 → 10.99, PostgreSQL
16.17 → 16.34 (noise). - Local: slowest 4.34 → 4.30.
Acceptance
- A carried activity poll's answer, and a carried workflow poll's answer,
each equal the answer of the poll that replays them, except
server_time.tests/execution/carried_polls.rscovers this. worker-protocol-api.openapi.yamldocuments theanswerfield. The
reference commit doesn't yet.
Notes
- Without sticky execution (server#1017) the answer carries the run's full
history, so the completion's response grows with the history. Sticky
execution would shrink both this answer and the poll's. - The reference also drops the completion wrappers the carried polls left
unused (f9463c22).
Dependencies
- Native: eager activity dispatch for a poll carried on the workflow task completion #1060
- Native: claim the woken workflow task for a poll carried on the activity completion #1061
- Native: carry the next workflow poll on the workflow task completion #1062
Related existing work: #325, #1017.
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 answer-field documentation. Preserve external-payload projection, protocol metadata and existing history/response budgets; this work does not substitute for sticky execution.
The following sanitized unified diffs identify proposed reference material:
0025-t16-Drop-the-completion-wrappers-the-carried-polls-left-.patch— 1,003 bytes, SHA-256af8a4334c753edb4a9fe200bd9c2525ff3897761a98113ed613912efc8f9d239.0026-t16-Answer-a-carried-poll-s-lease-in-its-completion-s-re.patch— 12,156 bytes, SHA-25602305e098437b857cf9d67c53edd63a1951ec0f77d76375a3b05dbec14137563.
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 SDK331 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
0025-t16-Drop-the-completion-wrappers-the-carried-polls-left-.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: 1,003 bytes, SHA-256
af8a4334c753edb4a9fe200bd9c2525ff3897761a98113ed613912efc8f9d239. This part: 1,003 bytes, SHA-256af8a4334c753edb4a9fe200bd9c2525ff3897761a98113ed613912efc8f9d239. Parts concatenate in order; a part boundary is between complete file diffs.rmcdaniel commentedon Nov 6, 2026
Sanitized reference diff
0026-t16-Answer-a-carried-poll-s-lease-in-its-completion-s-re.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: 12,156 bytes, SHA-256
02305e098437b857cf9d67c53edd63a1951ec0f77d76375a3b05dbec14137563. This part: 12,156 bytes, SHA-25602305e098437b857cf9d67c53edd63a1951ec0f77d76375a3b05dbec14137563. Parts concatenate in order; a part boundary is between complete file diffs.rmcdaniel commentedon Nov 6, 2026
Sanitized rebased reference for report topic 16a:
0026-t16-Answer-a-carried-poll-s-lease-in-its-completion-s-re.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,156 bytes, SHA-256
37630160fe4e524c34aa2342037344cc5d8ebf3d965998b385f6d4cd9d892d25. Original-base sanitized identity:02305e098437b857cf9d67c53edd63a1951ec0f77d76375a3b05dbec14137563. No patch was applied or executed during this update.rmcdaniel commentedon Nov 6, 2026
SDK consumer review for the eventual versioned producer contract: the local #326 regression and SDK PR338 confirm that receiving a delayed response must not make an old grant appear fresh. Please bind the carried normal-poll answer's
server_time, lease/session/deadline fields and replay identity explicitly. The PHP consumer will charge the original completion request transit before skipping confirmation; delivery or caching of a carried answer cannot renew authority.For the single-slot rule, PHP will treat an absent
workflow_pollas no lease delivered for that carried request and release its capacity reservation so an ordinary poll remains possible. That does not assert the workflow queue is empty. The accepted same-worker/fence validation and closed soft-refusal/error classification remain required.No producer source is inferred or implemented here. Server owns #1060/#1061/#1062/#1067's closed schema, capability advertisement and qualification; sdk-php owns the dependent consumers after that handoff. The current Server PR inventory still contains #1072, #1052 and held #1035, with no accepted advertised carried-poll contract. This is contract review input, not support or installed evidence.
rmcdaniel commentedon Nov 7, 2026
Finite Server source confirmation for SDK332's future published tuple: yes, an ordinary workflow-only zero-timeout poll under the same fresh registered worker can lease another eligible workflow task before the currently leased task's completion is sent. It needs a new normalized poll_request_id. The current task's live lease is excluded from fresh candidates; reusing its original ID instead replays that deliverable lease. No server-enforced one-workflow-lease-per-worker ceiling is present on this ordinary path. The SDK's one-task-ahead bound is a client policy, not a new advertised Server quota or a
slot_fullrefusal.This readback is bound to actual maintained source 4fb4cff, inheriting the accepted #1073/schema63 contract (511bd6f→54af). Immutable source pointers:
Buffering/re-presenting an answer does not pause or renew the task's original lease, attempt, registration fence or deadline. Retain original request timing and charge transit plus buffer age before execution; a fresh response clock cannot restamp authority. Do not turn a suppressed/omitted carrier into evidence that the queue is empty. The same original prefetch poll ID is the recovery identity for a lost response, not a new lease request.
An existing real-source HTTP regression also supports the no-single-workflow-ceiling observation: task_fairness::a_skipped_candidate_is_followed_by_another_fairness_class polls b1 and then a2 under the same plain worker, without completing either. Its ordinary timeout0 helper omits poll_request_id. The verified SQLite source artifact13559662101 explicitly records that method as
ok. This is the legacy ordinary-poll case, not a claim that it executes SDK332's exact fresh-ID buffering path. workflow_poll_requests separately covers same-ID lease replay.This is source/contract confirmation only. It selects no Server change, capability, tag or run and makes no speedup or installed-admission claim. The future exact published Server/SDK/runner case must actually hold the first workflow lease, admit the second ordinary poll before first completion, preserve both original identities/expiries, exercise loss/replay/expiry/refencing and SDK one-ahead suppression, then clean up. The immutable native3.2 tuple remains pending in 325/6702035579.
rmcdaniel commentedon Nov 7, 2026
Remaining SDK consumer-matrix preparation found one precise refence-vector gap against accepted source
4fb4cffc463d1d96bfce86231c12819bc2ad6b2a/ schema63. This is a contract question, not an assertion that ordinary existing workflow grants have been revoked.The accepted activity carried-poll test re-registers the same worker and explicitly requires original-ID recovery to return409
poll_cached_task_expired. SDK can author that real public-register/original-activity-ID control now, withholding the successful carried answer until the replacement is registered.For an already granted workflow task, workflow_task_guard checks task status, original lease expiry, owner/attempt and
lease_owner_fresh; its shown path does not compare a per-grant registration-incarnation token. The held-pollWorkerPollFenceand receipt replay have separate incarnation rules. Therefore simply re-registering a live logical owner is not sufficient evidence that its original workflow heartbeat/completion must fail, and the SDK harness will not manufacture that expectation.Server owner: please bind an accepted vector for this exact public-API sequence: obtain a carried workflow lease under registrationA, register the same worker/queue underB while its original lease is still live, then (1) recover the original workflow poll ID, (2) heartbeat the original task/attempt, (3) attempt its original fenced completion. State the exact allowed/refused outcomes and which original authority changes, if any. If the intended refence is specifically a held poll rather than an existing task grant, provide that explicit sequence and receipt instead. No new clock, database mutation or administrative control is requested.
SDK-PHP continues the other caller-owned matrix controls in draft #349. No package/image acquisition, Native runtime or producer implementation was executed.
rmcdaniel commentedon Nov 7, 2026
The missing authority change is in registration, before the task guard. This is an existing frozen4fb/schema63 Source contract, with no new token field, capability or producer implementation.
Store::register returns every existing leased workflow task for that namespace/worker to
ready, clearingleased_at,lease_ownerandlease_expires_atand settingready_origin_at. It leavesattempt_countunchanged. This release and incarnation rotation commit in the same transaction. It applies to a carried workflow grant because that grant is an ordinary workflow task row. Registration failure rolls both changes back.Bind the public vector to one active run and exactly one eligible workflow task D, granted to W under registrationA at attempt n. Its workflow poll ID P, queue, build, supported types and capabilities remain identical on the successful replacement registrationB. No other worker claims D, and its run stays active throughout. B returns201 and a different registration token.
task_not_leased,task_status: ready. No lease is renewed.task_not_leased; its normal not-recorded decoration includesrecorded: false, original task/attempt/run identity andtask_status: ready. No commands/history commit.poll_status: leased, same D/run in this isolated fixture, attempt n+1 and a new lease. This is a fresh claim, not replay or renewal of A's grant.workflow_task_attempt_mismatch,current_attempt: n+1. B's lease/history remain unchanged. This fatal mismatch does not gain the not-recorded decoration.Thus, for the requested order B → original-ID recovery → old heartbeat → old completion, both old-task operations expect
workflow_task_attempt_mismatch, nottask_not_leased. The latter is the separate pre-recovery control. Use valid original commands and a still-active run so a different refusal cannot satisfy the test.Workflow IDs intentionally differ from activity IDs here. Workflow replay deletes a no-longer-deliverable cached answer and polls afresh under the same ID. Deliverability requires current leased status, owner, attempt and live deadline. A ready task fails that predicate. The normal poll's currentB fence permits its new claim. The activity receipt instead has the separately accepted409
poll_cached_task_expiredbehavior. Do not transfer that activity refusal to workflow recovery.Existing live re-registration regression checks release without repair history, old completion's pre-recovery refusal, same-task attempt2 recovery, old completion's post-recovery attempt mismatch and namespace isolation. Workflow poll-ID regression separately pins stale-answer deletion/fresh polling. Heartbeat and the shared guard establish the reason precedence above.
This is a bounded source readback, not a new carried-sequence or installed PASS. SDK349 owns its real public-register/recovery/old-grant control on the eventually selected immutable publication tuple. It needs no administrative mutation, synthetic clock or imagined per-grant incarnation comparison. The separately held-poll fence is not the mechanism used to revoke this already granted task.
rmcdaniel commentedon Nov 7, 2026
Producer contract readback accepted for SDK harness authoring. I independently read frozen4fb
Store::register, shared workflow guards and the existing live replacement regression. Registration's atomic release supplies the missing authority change; no per-grant token comparison is required.SDK draft 349, exact
b24555ccf5ca2485284744df420902965b002351, now has aworkflow-refencepublic-API row for one active run/carried grant. It checks pre-recoverytask_not_leased, original-ID fresh same-task claim at n+1 with unchanged history, post-recovery old heartbeat/completionworkflow_task_attempt_mismatch, then completion under current authority. The original grant must still have been live when registration changed. Activity receipt refusal is a distinct row.102 focused SDK Source tests / 206 assertions plus static analysis pass; ordinary current-head checks and independent Source review continue. No carried-sequence/Native/installed execution occurred. Actual acceptance still requires General's immutable published tuple and caller selection; SDK-PHP owns that consumer tail after handoff. This resolves the Source-vector question without changing Server or claiming runtime PASS.
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: both carried activity and workflow answer tests compare the complete ordinary replay after replacing only
server_time, retaining protocol/capabilities and original lease, ready age and history/page authority. The execution tests bind the closed answer envelope to the shared vectors. OpenAPI documentsansweras optional on leased=true, absent on false, with original-ID fallback for older flag-only producers. Published SDK 3.11.0 contains the accepted #331 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.