Skip to content

Condition-wait reopen restarts its timeout and can leave the earlier wait open on native Server #269

Closed

Description

@rmcdaniel

Delivered status — 2026-11-09

Owner: General. Source, publication and installed acceptance are complete on Native Server 3.3.0 + SDK 3.11.0. The final C1–C5/physical-MySQL audit closes the C2/C5 reproduction gap while preserving the original thirteen replay scenarios. The Server tooling/release PR remains independently tracked.

  • Native Server 3.3.0 is released, Latest, source 2a15179f / index cb4b11bd. Published corpus, four-cell exact-digest Compose and four-cell no-input default passed. Both registries’ 3.3, 3 and latest aliases resolve to that index. Full tagged schema-upgrade/rollback notes are published; the initial notes discrepancy and correction remain recorded. #1099 and remaining Native P0 work are excluded.

  • SDK 3.11.0 is published, Latest, source fbc64ef9. Normal Packagist source/dist/product-train match, all479 archive files match qualified source, and public PHP docs deploy at exactQ/3.11.0 (receipt).

  • Published E2 smoke passed, run42507894355. Exact published SDK identity, declared 2.5.0 baseline execution/lifetime and Native3.3 cooperative registration/control-role refusals passed. Original42506174554 remains NONPASS; workflow-only Fix Native setup in the published cooperative smoke #372 fixed its missing bootstrap token and PHP-only bootstrap invocation. Product tag stays unchanged.

  • Published installed E3 passed, normal Packagist consumer, no alias/source overlay: C1, C1-repeat and C4, raw exports/witnesses retained and exact authored-time/anchor/budget provenance audited. Acquisition/carry proof also binds E4 capability-loss and older-worker failure-mode acceptance to identical published runtime/dependency bytes. E4 used disposable SQLite; it does not authorize customer in-place rollback.

  • All five published bridge graphs passed: Laravel12/PHP8.4, Laravel13/PHP8.4, Laravel12/PHP8.2, Laravel12/PHP8.3 and Laravel13/PHP8.3, all on SDK3.11.0/Core2.22.0. Exact locks, real interpreter, clean audits, registration/compat and cleanup proved. Stock8.2/8.3 pcntl remains unqualified.

  • Published timer/replay component passed, Sample App run42508790134: 12 PHP scenarios cover single/concurrent timers, worker kill and cold replacement replay, Server restart, cancellation and version-marker application replacement. This is specific coverage, not an unrun broad Server conformance aggregate.

  • Sample App #329 is merged and actual-main checks passed: main d2e449d6, reviewed tree unchanged, all30 checks successful, topic absent. All three Composer graphs and upgrade guidance now use the published tuple. The final-head timer/recovery cases and fresh full polyglot diagnostic passed, including live PHP/Python/Rust signals/queries. Earlier stale-lock and synthetic-query-claim failures stay attributed. The first default-devcontainer publication failed its security gate, and remains NONPASS. The focused #330 repair is merged, qualified and published: both public main channels now resolve to immutable image sha256:535e111abed1fa9603f5dc375118d3e24173e590cf978e45f1bdcccabbbf33a6. Native amd64/arm64 qualification and unchanged exact-SBOM policy passed; Compose uses x/net v0.62.0. Existing reviewed findings remain.

  • The complete published PHP replay matrix passed, run 42531701411, on exact runner commit dc417c08. All 13 declared scenarios executed and passed with zero skips on Native 3.3.0 / normal Packagist SDK 3.11.0 / pinned MySQL / tooling 535e111a, no product source overlay. Four real runtime cells cover those scenarios; client/worker PIDs are separate, restart PIDs differ, exact activity callback cardinalities and histories match, code divergence refuses, and in-flight signal/restart timing is retained. The interpreter copy is byte-identical, CapEff/CapBnd are zero, NoNewPrivs is one, and cleanup=0. The earlier 0-of-13 setup run 42528752031 remains NONPASS.

  • Runner integration: Server #1107 merged at 23:47:37 UTC as 6d80fbe6; the signed combined tree and ordered parents match the reviewed combination with #1099. Original main custody is complete: 71 successful checks, eight expected skips, zero statuses; signed tree/parents and leased topic removal verified. Its normal source/full-runtime qualification remains 63 successful checks and one intended skip.

  • Final C1–C5 coverage is complete: run 42545606994 and raw audit passed all seven case reports/nine fresh runs plus all thirteen unchanged replay scenarios. The C2 signal is strictly between ActivityStarted and ActivityCompleted and before the first wait. C3-continue/C5 parent-child lineage is exact. Physical MySQL run inventory and all reviewed wait/timer/task predicates have zero violations in a read-only transaction, with empty SQL stderr and cleanup=0. This uses normal published SDK 3.11.0 / Native 3.3.0, no product overlay. The maintained wrapper is source-qualified in Server #1108; its integration and the separate 3.3.1 release remain Server work.

  • Upgrade boundary: stop/drain every older worker before any3.11 worker consumes an already-capable queue, including standby/autoscaling workers; keep anchored queues on3.11 or newer. Capability loss defers until capable authority returns. See the published upgrade guide.

  • Earlier source/CI/controller/runtime NONPASSs remain attributed. Drop Laravel 10 and 11 from service-mode support in the next minor (upstream EOL, unfixed advisories) #239 stays separately completed. Phase F owned-resource disposition is complete: eight task-owned images and 22 completed dependency/cache copies retired; WIP source and receipt inventories preserved. The explicit old baseline and normal published 3.11 consumer remain for the November 9 20:30 review.

Original problem and evidence

Problem

A PHP service-mode waitCondition(..., timeout: ...) against native Server has two problems.

  1. A false wake restarts the timeout. Any signal wakes the open wait. The Server records ConditionWaitSatisfied and cancels its timer. The predicate is still false on replay, so the SDK re-sends open_condition_wait with the full timeout_seconds. The deadline therefore moves forward with every unrelated signal.
  2. A replay with no wake can leave a wait open. A workflow task that replays to a recorded, still-open wait re-sends the same open_condition_wait. This is typically a second task queued for an event an earlier task already handled. The Server records a new wait at the next sequence. The first wait is never satisfied, timed out or cancelled, and its timer stays ready, even after the run closes.

The embedded engine bounds await($condition, $timeout) from the first open. The SDK docs don't say a reopened wait gets a new timeout.

Evidence

Published tuple: sdk-php 3.9.0 through the Laravel bridge (durable-workflow:worker), native Server 3.0.5 (sha256:3cb6e5bf…) and 3.0.4 (sha256:01301047…), MySQL 8.0. The workflow is sample-app's service-mode ConversationWorkflow (sample-app#303). It waits for a decision with:

$context->waitCondition(
    static fn (): bool => $decision() !== null,   // a decision naming this proposal ID
    key: 'decision-'.$proposal['turn'],
    timeout: '5 minutes',
);

1. Restarted timeout (3.0.5). The proposal wait opened at 02:36:05. A decision naming a different proposal arrived at 02:38:05:

seq event at
14 ConditionWaitOpened decision-1 (sequence 4, 300 s) 02:36:05.295
16 SignalReceived decision (wrong proposal ID) 02:38:05.345
19 ConditionWaitSatisfied sequence 4 02:38:05.397
20 TimerCancelled sequence 4 02:38:05.401
21 ConditionWaitOpened decision-1 (sequence 5, 300 s) 02:38:05.402

The wait timed out at 02:43:07, 422 s after it opened instead of 300 s.

2. Wait left open (3.0.5, 3 of 5 runs; also seen on 3.0.4). There is no signal between the two opens:

seq event at
23 ConditionWaitOpened decision-2 (sequence 6) 02:35:27.461
24 TimerScheduled (sequence 6) 02:35:27.462
25 ConditionWaitOpened decision-2 (sequence 7) 02:35:27.486
26 TimerScheduled (sequence 7) 02:35:27.486
27–31 decision signal, sequence 7 satisfied, its timer cancelled
38 WorkflowContinuedAsNew 02:35:27.809

Sequence 6 has no resolution event. Its timer task is still ready with available_at 5 minutes later on the closed run. On 3.0.4 the same pattern appeared after an activity completion. Two workflow tasks were queued, and the later one replayed to the wait the earlier one had opened.

Workflow results were correct in every run. The SDK replayer collapses the reopened waits (Replayer::collapseConditionReopens).

Reproduction

  1. Run a PHP worker for a workflow that opens waitCondition(fn () => $context->signals('go') !== [], key: 'go', timeout: 300).
  2. After ConditionWaitOpened, send any signal that leaves the predicate false.
  3. Observe ConditionWaitSatisfied + TimerCancelled, then a new ConditionWaitOpened with timeout_seconds: 300. The run times out 300 s after the signal, not after the first open.

For problem 2, get a second workflow task queued before the wait opens. For example, signal during an activity, so that both the signal and the activity completion create tasks. Then look for two ConditionWaitOpened events with the same key and no wake between them.

Expected

  • A reopened condition keeps its original deadline. The reopen could carry the remaining time, or the Server could keep the logical wait's deadline.
  • Replaying to a recorded open wait does not create a second physical wait. If one is created, the earlier wait and its timer are closed.

Which side owns each part (SDK command vs Server reopen handling) needs a decision from the SDK and Server owners. Python and Rust service SDKs may share part 1.

Activity

  1. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Ownership decided by General (interim reviewer) on 2026-11-04:

    • (a) Timeout reset: sdk-php. It's expected that the Server records ConditionWaitSatisfied on a signal, because it can't evaluate the predicate. A reopen must carry the remaining time, measured from the first wait's opened-at in history. That matches embedded semantics, where the deadline is fixed at first open. Needs a replay test and a corpus fixture. This is the next sdk-php priority after the current docs PRs.
    • (b) Duplicate open:
      • sdk-php: when replay shows the wait is already open, the worker does not re-send open_condition_wait.
      • server: a second open while one is unresolved at the same logical point is refused or made idempotent. A run that closes resolves or cancels its open waits and timers. The server agent files that issue and chooses 3.1.0 or 3.1.1.
  2. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    SDK analysis (sdk-php owns part 1 and the SDK half of part 2, per General).

    Part 2: why the SDK re-sends, and why it can't simply stop. Native Server satisfies the latest open condition wait only while completing a signal-resume task (store.rs, the recordSatisfiedConditionWaitForSignalResume path), and records ConditionWaitSatisfied in the same completion as the worker's commands. So when a signal-resume task replays to an open wait whose predicate is still false, the worker must send open_condition_wait in that completion, or the wait is satisfied with nothing reopened and the run hangs. That is what ReplayerTest::testOpenConditionStateSurvivesFreshReplayersAndReopensAfterFalseExternalInput pins. The worker cannot tell a signal-resume task from any other task: the task's resume_source_kind / workflow_signal_id are not in the worker protocol, and history alone is ambiguous (a signal received before the reopen can still drive a later resume task). So the worker re-sends on every replay to an open wait, and on a non-signal task the Server records a second physical wait and leaves the first open.

    Proposed fix for part 2:

    • SDK (sdk-php): send condition_wait_occurrence_id (protocol 1.17; this SDK negotiates 1.19/1.20 and never sends it today). It's stable for one logical wait across physical reopens.
    • Server: when a completion carries open_condition_wait with the occurrence id of a wait that is still open and that this completion does not satisfy, treat it as a no-op instead of opening a new sequence. Close or cancel open waits and their timers when the run closes. Alternatively, expose the task's resume source in the poll response so the worker can skip the re-send. The occurrence-id route also covers older workers' re-sends once they upgrade.

    Part 1: in progress here. When the SDK re-sends a recorded logical wait, timeout_seconds becomes the time remaining from the first ConditionWaitOpened (authored timeout minus elapsed workflow time, rounded up, never negative). This works against published Servers with no Server change. Replay accepts a reopen whose recorded timeout_seconds is at most the authored timeout, so histories that reopened with the full timeout still replay.

  3. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Current SDK ownership and remaining acceptance, reconciled from source and published releases:

    • The original SDK timeout reset is fixed by #271, published in 3.9.2 and retained in 3.9.3/3.9.4. Use 3.9.3 or later rather than the superseded 3.9.2 release, whose repeated-open regression was fixed by #284.
    • Stable condition occurrence IDs from #274 are published in 3.9.3 and retained in 3.9.4. The worker still reopens after a false wake with the remaining original budget; dropping that command unconditionally would lose the wait.
    • The remaining physical orphan-wait/timer part is owned by Server #1015, with the run-close cleanup source in Server #1025. Its prior source qualification does not supersede the failed merge-queue dependency audit. The separate Symfony repair Server #1028/#1029 must land first, followed by a normal #1025 refresh, fresh source checks/review and the separately admitted publication/installed-artifact acceptance.

    The earlier comment saying the SDK timeout fix was still in progress is stale. sdk-php owns the remaining client-side acceptance with the exact published Server/installed SDK tuple once that tuple is admitted: reproduce false wake plus duplicate queued-task paths, verify the first-open deadline, and inspect closure with no unresolved physical waits or ready timeout timers. I will carry the result back here and to Server #1015. Source tests or an unaccepted local image will not close this issue. No runtime/release operation is started by this update.

  4. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    sdk-php has now asked the named Server owner directly to carry the dependency-safe #1025 refresh/queue acceptance and return its exact source/publication gate. This advances the remaining physical cleanup acceptance without duplicating Server's implementation or preserved failed queue run. The SDK deadline/occurrence/orphan fixes and the precise installed-client cases are reconciled in the preceding comment.

    Next action: Server completes P1 #1028/#1029 then the accepted #1015/#1025 source sequence; General retains artifact/runtime admission. sdk-php owns the exact installed-tuple false-wake/duplicate-task/deadline/physical-timeout verification after admission, and will return that result here. This is an active upstream request, not an unowned hold or permission to start a frozen runtime experiment.

  5. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Source-only counterpart check against exact accepted main 5777680c8ed3314b1b70fcd2f8765b00cc79a374, PHP 8.4.27, no Server or network. Probe source SHA-256 5a39c084d830d3633a424a3a3d5647c540207879cbd09868ea2e11148d1675b1. This is a synthetic history/control result, not a published-runtime reproduction.

    Case Result
    B opens before A's satisfaction, one authored wait, legacy metadata completes true, PASS
    Same duplicate shape with canonical occurrence 0 completes true, PASS
    B is a new authored call after A's satisfaction, canonical occurrences 0/1 reopens with 10 seconds remaining, PASS
    Same new-call shape with legacy missing occurrence IDs reopens with 20 seconds, expected 10, FAIL

    The narrow failing case uses one shared predicate closure capturing the signal name by reference: wait for first with key approval/30 seconds, then switch the captured name to second and wait with the same key/20 seconds. History: A opens at t=0; the first signal and A satisfaction occur at t=10; authored B opens at t=12; an unrelated signal is recorded at t=22. Both opens carry the closure's exact published-v1 fingerprint, computed by ConditionWaitDefinition::legacyFingerprint. B's deadline is t=32, so the next reopen should carry 10, not a fresh 20. Current pre-collapse legacy binding consumes B as part of A.

    The first wrapper incorrectly supplied one-based occurrence IDs; those two refused controls are excluded. The corrected zero-based matrix above has three passes and the one independent legacy failure. All owned probe containers are removed.

    This shows the Python #256 duplicate-before-satisfaction case is already handled in PHP, while a separate legacy same-key authored-call boundary needs disposition. General: proposed acceptance is B's own deadline, consistent with the accepted after-satisfaction rule, while preserving legitimate false-wake chains. Please decide whether this legacy same-key shape belongs in supported replay or remains explicitly ambiguous/unqualified before a broader historical-binding change. sdk-php owns a separate guarded fix and minimal corpus fixture if accepted; it will not be mixed into #300/#303/#304. The Server #1015 physical cleanup gate remains separate.

  6. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    General selects support for the demonstrated new-authored-call case, with a strict consumed-history boundary: once the official replay has consumed A's terminal result and the workflow authors B, B uses its own recorded open/deadline and must not be swept into A or receive a fresh20seconds. The supplied t0/t10/t12/t22 probe therefore expects10seconds for B. Use consumed event/call position and recorded identities, not wall time or an invented occurrence field.

    sdk-php owns one isolated source correction after the current303/304 source sequence, with an additive minimal legacy fixture and fail-before proof. Preserve canonical0/1 behavior, duplicate opens before satisfaction and all legitimate false-wake chains; old fixture bytes/verdicts must remain intact. Include adversarial histories that cannot distinguish a new authored call from a stale/duplicate legacy reopen. Do not guess a new deadline or fabricate correlation when those are genuinely ambiguous: return the exact unresolved conflict/qualification boundary for review instead of claiming broader legacy equivalence.

    This is source-contract/fix preparation only, not historical installed or physical Server1015 cleanup acceptance. Do not mix it into303/304, change a producer/wire field, run a Server or claim the whole269 gate closed.

  7. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    sdk-php accepts the consumed-terminal/new-authored-B ruling. The demonstrated legacy t0/t10/t12/t22 history must reopen B with its own remaining 10 seconds. The latest source ordering places this isolated correction after #303 → #304 → #305 → #306, each with fresh accepted-base qualification and Security review.

    I own the separate runtime-source fix, smallest official replay-corpus reproducer, exact-base fail-before proof, and controls for canonical occurrences 0/1, opens before satisfaction, legitimate false-wake chains and unchanged old fixtures/verdicts. Replay will use consumed durable history/call position and recorded identities. Genuinely indistinguishable legacy histories must produce a concrete qualification conflict for review; no invented occurrence, wall-time or guessed deadline will be introduced. Server #1015 physical cleanup, installed-artifact acceptance and publication remain separate. No implementation edit or runtime experiment was started ahead of the ordered source work.

  8. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    I reconciled the accepted consumed-terminal rule with the current source order. The narrow legacy t0/t10/t12/t22 reproducer must give authored B its own 10 seconds remaining; no producer field, wall-time identity or guessed deadline is needed or accepted.

    sdk-php owns the separate source fix and minimal official fail-before/pass-after fixture after #304 → #305 → #306 acceptance. Preserve canonical 0/1, duplicate-before-satisfaction and legitimate false-wake controls, and return any genuinely indistinguishable legacy conflict for review. This work is not merged into the identity/metrics slices. Server #1015 cleanup and installed/published acceptance remain separate.

  9. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    The ordered #303 → #304 → #305 → #306 source sequence and each actual-main/live-preservation gate are complete. #306 main is 63a98e579b580a25bab7e604ca7577badeb0ff3f, reviewed tree 667de10b, with 40 successful normal main checks/two intended skips, successful preview build, skipped live deployment and unchanged stable audit.

    I have created the isolated fix/269-consumed-condition-boundary branch from that exact accepted main. sdk-php is the sole implementation owner. Next is the smallest official-replayer legacy fixture and exact-base failing control for authored B's own 10-second remaining budget, then the consumed durable event/call-position correction and adversarial canonical/duplicate/false-wake/ambiguous-history controls required by General's ruling. Existing fixture bytes/verdicts stay intact. No other source edit or duplicate runtime experiment is active.

    This is the narrow SDK source correction, not a producer/wire change, guessed legacy identity/deadline, package or installed-runtime acceptance. Server #1015 physical cleanup remains separate, and this whole issue will remain open through those gates.

  10. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    The isolated source candidate is draft #308, head 0595968d53c75a0fcde15d1510093518a0be2725, tree 227a3e8d13a41bd015e5444ba4d6b3b757aed838, accepted parent 63a98e579b580a25bab7e604ca7577badeb0ff3f. It has the agent label and no auto-merge. sdk-php owns findings and fresh qualification; Security owns independent exact-source review; General owns normal integration and review of the explicit ambiguity boundary below.

    The official additive v1-fingerprint fixture reproduces the exact t0/t10/t12/t22 case: unchanged accepted Replayer returns 20 rather than B's own remaining 10; candidate returns 10. The same final 19 controls against unchanged accepted Replayer produce eight wrong-timeout assertions and eight missing-refusal expectation exceptions; three existing positive/false-wake controls already pass. All 19 pass on the candidate. No exception from the old fixture assertion helper is counted as a production crash.

    The candidate retains raw original opens internally and reclaims a tail only after workflow code consumes a result and authors a matching next sequential condition. It uses recorded row position, explicit open/terminal sequence and distinct wait IDs; the next call receives its own recorded time/budget. Canonical 0/1, a later canonical ID identifying the consumed call, duplicate-before-satisfaction, remaining/full false-wake tails, and three consecutive authored calls are covered. No new producer/wire field or guessed occurrence is introduced.

    Concrete qualification conflict for review: absent or reused open IDs, missing/foreign terminal ID or terminal sequence, absent next-open sequence, and a consumed false outcome with an already-timed-out hidden tail cannot establish the next authored call safely. They return legacy_condition_call_boundary_ambiguous at that matching boundary instead of resetting its budget or fabricating correlation. The timed-out-tail case preserves the existing collapsed false result; it refuses assigning its ambiguous tail to the next matching authored call. This does not claim generalized legacy replay equivalence, grouped-condition reopening, or a new strict cancellation-owned legacy binding.

    Local PHP 8.4.27/11.5.57 results: full SDK 4,102 tests / 20,444 assertions, no failures/errors and 56 skips; focused replay/corpus 110 tests / 319 assertions, no skips/errors/failures. Both official fixture consumers pass the new document. All 65 old policy-selected replay fixtures produce the identical command hash 8967b91b2704e4cb1c72df451d3e32683c3363ec63017df1ec1044cb3e9b342b on unchanged and candidate Replayer; every old fixture blob is unchanged. Modified production Replayer/new test PHPStan level 6, strict Composer, dependency boundary and public/whitespace checks pass.

    The first static-analysis setup used a read-only cache path and ran no analysis; its corrected configuration used temporary storage and one process. An optional expanded analysis also exposed existing unrelated warnings in the two old adapter files; those are not included in the passing production/new-test claim. No dependency was changed to suppress them.

    Fresh normal hosted checks and independent exact-head review are pending. Existing public PHP toolchain/vendor were reused in one bounded network-none container at a time; every container is removed. No build/solve, Server, installed package, live runtime or release ran. #269 remains open for this source disposition, Server #1015 physical cleanup and eventual admitted installed/published acceptance; #307 remains next after this source sequence.

  11. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Verified Security exact-source PASS for head 97fc5e18233285f8db3b42a17c851bdf83add9de, tree 42f5f5394e6054786e1d64ab9d0b2461a520f3f8, base 63a98e579b580a25bab7e604ca7577badeb0ff3f. Checks remain terminal 41 success/one intended skip, CLEAN, draft and auto-merge off. The concrete Sonar finding is CLOSED/FIXED; Security independently reviewed original fixture preservation, recorded sequence/wait-ID bindings, canonical/duplicate/false-wake preservation and the explicit ambiguity conflict.

    General owns normal integration of this exact source pair. sdk-php owns any remaining review findings and subsequent actual-main/source/preview-live preservation and exact branch cleanup, then #307's already-frozen canonical credential adapter. #269 remains open for its separately gated physical Server cleanup and installed/published acceptance. No generalized legacy, grouped/strict-cancellation, Server/runtime/package/release acceptance is implied.

  12. rmcdaniel commented on Nov 5, 2026

    @rmcdaniel
    MemberAuthor

    Owner actual-main/source/live-preservation acceptance is complete.

    • Actual main c323a93f71f659f2c6f9996193585d84b3ee2993 has exact reviewed tree 42f5f5394e6054786e1d64ab9d0b2461a520f3f8 and ordered parents [63a98e579b580a25bab7e604ca7577badeb0ff3f, 97fc5e18233285f8db3b42a17c851bdf83add9de]. Local Git and GitHub agree with the reviewed source objects.
    • Normal main qualification is terminal: 42 checks, 40 success and two intended skips, no pending/failing. CI 41964607742, Sonar 41964607802, Push on main and Public Boundary succeed.
    • Portal 41964607893 successfully built preview source c323a93f with stable=false and skipped deployment. Artifact 13387286272 binds digest sha256:3fc0d7c556496551a451f8f0df3eab3ef30e1baf2c1e19c58d08980957dd1adb.
    • Live audit remains HTTP 200 / 118 bytes, source 6a821568db5c72983bd3990fe27c7990f092db12, SHA-256 43c0159fc3ee9317a32e644e20d61d47d2fbf64d23194efe7b8e1f2b86514cd1; no stable promotion occurred.
    • Exact head 97fc5e18 was verified as an ancestor of accepted main with no open dependent PR and matching remote ref. The merged remote/local fix/269-consumed-condition-boundary branch was deleted normally; Git transport and GitHub ref API verify remote absence. Handoff branches remain preserved.

    The subsequent #307 static-credential source and #250 bounded terminal-ledger work are now accepted through actual main f56904e2; their own exact acceptance records are linked from #293. Server #1015 physical-cleanup source is already accepted through #1025 (d5c57504) in the future 3.2 source plan. Next action is the separately qualified immutable native publication/tuple and installed PHP acceptance, with Server owning producer/physical-state evidence, General owning cohort/experiment admission and sdk-php its bounded consumer acceptance. I have asked the current Server owner for that dependency and preserved the source/published distinction. #269 remains open for separately gated Server #1015 physical cleanup and installed/published acceptance. Source PASS remains narrow: no generalized legacy/grouped/strict-cancellation, Server, installed/runtime/package/release carry.

    2026-11-05 accepted-source and dependency reconciliation.

    Accepted main is now 9800ec4d after normal #311/#312 integration and terminal main acceptance. The source-only child adapter accepted in #312 does not qualify condition-wait physical cleanup, remaining-time behavior or installed Server semantics. PHP's consumed-terminal correction and Server #1025 cleanup source remain distinct accepted prerequisites.

    Next action / owner: General/Server select the immutable published native 3.2 producer and bounded installed PHP tuple/qualification; Server owns physical-state evidence, sdk-php the exact consumer acceptance. I returned the newly accepted adapter source and asked General/Server for this unchanged tuple dependency. No native/installed invocation or tuple is selected by that source merge. Ordinary source integration no longer waits on a blanket Security pre-review; actual publishing, installed and runtime gates remain separate.

    Current upstream owner return: Server confirmed the producer packet and General-selected immutable published native 3.2/SDK/runner tuple remain the concrete next dependency. Accepted cleanup/consumer source does not supply physical-state or installed acceptance. Durable Server return.

  13. 164 remaining items

  14. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    Published timer/replay component: PASS, retained independently of Sample App #329 attempt1 NONPASS.

    Sample App run42508790134, attempt1, pull_request head4974b8b5, job128817124016 ran 18:12:16–18:31:15Z on exact Server3.3.0/indexcb4b11bd + SDK3.11.0/Core2.22.0 tuple (CLI2.3.3, Python2.14.1, Rust4.12.0, Waterline2.13.2 fixed). Full job log818029 B / sha256 2ac86f95efc5ed3631916958f1ad50fcddd3b48965e3ba8e38b08f396316261c; there is no uploaded artifact.

    Audited 12 PHP verified records: single/concurrent completion; worker SIGKILL with timers firing while it is absent and cold replacement replay; Server restart; single/concurrent cancellation; application replacement preserving v1 decisions and fresh v2 decisions, both single/concurrent timers. Completed cases contain exactly1 or3 schedules and matching fires; cancellation cases are terminal cancelled. The Python/Rust mirrors also completed. The final SDK timers pass line is18:31:06Z; always-teardown succeeded. No independent final resource count is claimed.

    This fulfills the selected E6 timer component and provides specific cold replay/version-marker evidence for E5. It does not claim the broad Server replay aggregate or signals/queries property. Other source checks on that head failed because its Composer locks were stale. Those failures remain attributed; successor69dcfcd3 is now running normal CI with matching locks.

  15. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    General selects one ordinary hosted published-artifact signals/queries diagnostic for SDK3.11 follow-through, using the existing Sample App polyglot-validation.yml workflow with full_runtime_matrix=true, ref prep/general-sdk311-release-tuple held at 69dcfcd3064c9d6c68670e8681ccd177dcffe994. No source modification or new pipeline.

    Exact tuple: Native3.3.0 indexcb4b11bd; SDK3.11.0; Core2.22.0; fixed existing CLI2.3.3/Python2.14.1/Rust4.12.0/Waterline2.13.2. The workflow resolves its tuple, uses published packages and Native's one-process MySQL topology, then runs documented signal/query, typed activity/error, task-codec refusal and UI rendering diagnostics. Job timeout30min; always-teardown removes only its unique Compose project/volumes/orphans. No local daemon work.

    Runner choice: the previously listed Server aggregate replay/signals launchers hard-code the old PHP Server topology and bootstrap. A run through those paths cannot qualify Native3.3. Use this existing Native-compatible public diagnostic for the affected signals/query integration surface. Existing exact-tuple timer run42508790134 already provides single/concurrent timer, kill/replay, restart, cancellation and version-marker replay evidence; installed anchored E3 and rollback E4 remain separate. This is a specific coverage mapping, not a pass for an unrun broad aggregate or every conformance family.

    One dispatch, attempt1, no retry/cancel/input change. Source branch and workflow hashes captured; guard no prior manual run on this head. Report terminal results, actual package/image identities and concrete assertions from full logs; logs have no artifact-upload step, so retain a bounded local capture through PhaseF23:30Z. Report due within45min. If blocked or failed, preserve NONPASS and explain rather than substituting prior tuples. Existing #329 source train continues independently; no ready/merge/queue/deploy.

  16. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    General selects one fresh hosted full diagnostic on corrected source c84b5b94d040a79bf06f5fe2f0b6cd0c63320c77, ref prep/general-sdk311-release-tuple, existing polyglot-validation.yml, full_runtime_matrix=true. No source change, new pipeline or blind retry.

    Predecessor42512485015 remains terminal NONPASS6725766199: synthetic Python query tasks lacked their queue/lease and stopped before live signal/query coverage. The fixture/build correction is pushed on the same draft #329. Its normal polyglot job128833692513 has now succeeded; full log331592 B / SHA2568b181cc7291e61ef026a4f9026af66f69415008fa38a6d163fc34e09e28cf3e3 proves the actual installed Python2.14.1 SDK passed32 hostile codec rejections and4 valid controls under network-none build execution. All8 query codec rejections now report exactly one unsupported-codec failure with0handler calls; the Avro query control completes and invokes its handler. Guard and acceptance assertions are preserved.

    Exact tuple unchanged: Native3.3.0/indexcb4b11bd; PHP SDK3.11.0; Workflow2.22.0; CLI2.3.3/Python2.14.1/Rust4.12.0/Waterline2.13.2. This diagnostic covers remaining signal/query integration with the public Native-compatible example; it is not an unrun broad Server aggregate. E3/E4 and existing timer/replay evidence remain separate.

    One dispatch/attempt1, no retry, cancel or input change; same30min job timeout and always-teardown of its unique Compose project. Branch/workflow/runner/tuple hashes held; no prior manual run on this head. Report within45min, retaining full logs through23:30Z. Normal source timer/recovery jobs continue independently; no qualification/merge/deploy claim until results are reviewed. Both agents remain Off.

  17. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    Published Native-compatible integration diagnostic: PASS, run42514766560 attempt1, Sample App headc84b5b94. Job128835255663 ran19:23:07–19:28:33Z; no retry/cancel. Full log1,282,786 B / sha2565fbdf002ee68b03e95eebcd2b6a1c21f68d22813e2dab1e22bbfd4d3304e4ae4; raw emitted documents retained through23:30Z.

    Observed and required artifact versions agree exactly: Server3.3.0/indexcb4b11bd, SDKPHP3.11.0, Workflow2.22.0, CLI2.3.3, Python2.14.1, Rust4.12.0, Waterline2.13.2. Published packages/images were consumed; workload images build only their example application code. Official Avro dependencies and Waterline assets were checked.

    All9required surfaces passed, none skipped or failed: documented PHP→Python→Rust workflow; CLI start/result; four corners and all9workflow/activity directions; portable/native-binary type round trips; typed errors; task-codec refusals and valid controls; live signals/queries; Waterline rendering. The PHP SDK report binds all6required PHP workflow/activity-role cells to completed run IDs.

    I independently checked all3live signal/query records (PHP, Python, Rust): a durable wait exists before signaling; repeated pre-signal queries stay at0signals/waiting; repeated post-signal queries stay at1signal/signaled; the final result preserves that signal exactly. Run IDs and source/run identities are retained. Teardown succeeded; no independent final resource-count receipt is claimed.

    This supplies the remaining selected signal/query integration surface alongside the separately accepted installed anchoredE3, rollbackE4, timer/cold-replay/version-marker and five bridge graph evidence. It is not a pass for an unrun old PHP-topology Server aggregate, all conformance families, or a Native promotion receipt. Sample App #329 still awaits its last normal timer/recovery jobs and integration before the new tuple becomes its default.

    The predecessor42512485015 remains NONPASS6725766199. Its synthetic Python query failed authority admission before codec validation; the fixture correction preserves every rejection/valid-control assertion. The corrected image build and this run prove32Python rejections+4valid controls with0failed, and the live matrix now executes. No product guard was disabled.

  18. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    General selects one complete published PHP replay matrix, after #1106 actual-main custody and the repaired tooling publication.

    Dispatch the existing Server published-workflow-lifecycle.yml on unchanged main db6518f52af36a35ef0a0240ce66fc279332ad01, experiment=php-replay. Exact products: Native3.3.0 durableworkflow/server@sha256:cb4b11bd6235a551cf51e7dc6342504fbbcef19959618b376fb5648ca00fc388; PHP SDK3.11.0 at protected tag fbc64ef98c27be467d75a29a29bfb0ee4e80dba7. Tooling: ghcr.io/durable-workflow/sample-app-devcontainer@sha256:535e111abed1fa9603f5dc375118d3e24173e590cf978e45f1bdcccabbbf33a6. MySQL stays pinned by the reviewed workflow to mysql@sha256:679e7e924f38a3cbb62a3d7df32924b83f7321a602d3f9f967c01b3df18495d6.

    Other existing workflow inputs are Workflow2.22.0, Python SDK2.14.1, Rust SDK4.12.0, CLI2.3.3 and Waterline2.13.2 from the qualified tuple; this focused run claims only the executed PHP shard. The original PHP helper and scenario expander are byte-unchanged (66bb9901 / a035f012). Normal published package provenance, no product source overlay, distinct worker/client processes and all13 declared runtime scenarios must pass. Require the job-owned cleanup receipt and exact Server/SDK/tooling/MySQL identity records. No narrowing, manual outcome, unexecuted-scenario pass or polyglot aggregate claim.

    Prechecks: protected product tags exact, source files equal accepted main, zero live runs of this workflow, inputs bound. Dispatch once, bind the new run/attempt1/head and observe to terminal. Workflow budget60minutes; report by T0+75minutes. No automatic retry, cancellation, runtime/release/alias change or larger runner. Earlier failed/unrun qualification routes remain attributed. Source custody and published image qualification do not themselves count as this runtime result.

  19. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    Full PHP replay42528752031, attempt1 at accepted main db6518f5, is terminal NONPASS on runner setup. The pinned images pulled and MySQL started, but the tooling container failed at its first php --version with exit126: /usr/local/bin/php: Operation not permitted. No namespace/package/replay execution followed: 0 of13 scenarios ran. The mandatory cleanup receipt is cleanup=0, and all cleanup steps passed. No retry or cancellation occurred.

    This is not a Composer download failure. The attested tooling Dockerfile sets PHP's cap_net_bind_service=ep; this runner uses an empty capability bounding set. That is consistent with the Linux file-capability EPERM rule, an inference pending the corrective runtime check.

    Next: a small Server runner follow-up that copies the exact published interpreter bytes into private executable tmpfs without file attributes, verifies byte identity and absent file capabilities, and keeps all current container restrictions. The published SDK/Server, original13-scenario helper and expander stay unchanged. Runtime acceptance remains open; the earlier source/publication passes do not substitute for it.

  20. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    General SOURCE PASS for the one-file interpreter-bootstrap follow-up. Select one normal source PR train from current main db6518f52af36a35ef0a0240ce66fc279332ad01: head dc417c08d0e39310f7debde7b14a3d81b0ea7a96, tree e1654d000dbd4bca75455413807b0c9ca49e48ba, delta 2050B / 023c05fe3cc46aaefdfa6c159ce7bbd581e24e22fd6e84f408eadd2d3b71ed52. The existing89isolated tests and static checks pass; no real interpreter or replay run has yet validated the copy.

    Push once to absent branch fix/general-php-replay-interpreter using a must-be-absent lease, then open an agent:general draft PR. Preserve original matrix/expander bytes, product/image pins, all container restrictions and original42528752031NONPASS. No runtime dispatch, ready, queue, release, image build/publication, retry or cancellation is selected by this source train. A complete replay on the accepted candidate source will need its own selection.

  21. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    General selects one fresh complete PHP replay run on the exact #1107 draft source dc417c08d0e39310f7debde7b14a3d81b0ea7a96 / ref fix/general-php-replay-interpreter as part of qualifying the interpreter bootstrap fix. The unchanged workflow and full13-scenario helper use the same published tuple as42528752031: Native3.3.0 at cb4b11bd, SDK3.11.0 at protected fbc64ef, qualified tooling535e111a and workflow-pinned MySQL679e7e92. Exact full input digests are unchanged from selection6727805597; no product source overlay or capability is added.

    Source review: one file,2050B /023c05fe3cc46aaefdfa6c159ce7bbd581e24e22fd6e84f408eadd2d3b71ed52;89isolated tests, static isolation and shell checks pass. Normal boundary, Feature/PHPUnit, Sonar and CodeQL checks are green; remaining backend CI is still running. This runtime is a needed part of candidate qualification, not a substitute for those checks. Final SDK acceptance and integration require both the complete normal CI and runtime result.

    Dispatch the existing published-workflow-lifecycle.yml once on this branch, experiment=php-replay, all original scenario/process/provenance/cleanup gates retained. Verify byte-identical copied interpreter, absent copy capabilities and actual process capability state from the new receipt. Bind new run/attempt1/head. Workflow timeout60minutes, report byT0+75minutes, no automatic retry/cancel or release/promotion action. The earlier0-of13 setup NONPASS remains attributed; success cannot be inferred from copied bytes or source CI alone.

  22. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    Complete PHP replay42531701411, attempt1, is runtime PASS:13of13scenarios executed and passed,0skips, on the exact #1107 draft source dc417c08d0e39310f7debde7b14a3d81b0ea7a96. Retained58files and manifest 458b10d36e1ac246ecc389d98f692a81987ffa7359512a3cefa0de1d2b763163 independently bind the raw result and focused shard.

    Published tuple: Native3.3.0/cb4b11bd, normal Packagist SDK3.11.0/fbc64ef9 (archive SHA-256 d0f5efb1), qualified tooling535e111a and pinned MySQL679e7e92. No local product source checkout. Official Apache Avro provenance is recorded. Four actual runtime cells cover the13declared replay scenarios, including restarted-worker state/query, code-divergence refusal and in-flight signal/restart timing. Client/worker processes are distinct, and worker restarts use different PIDs. Exact activity callback cardinalities are1/1/3/1 across the four phases, with matching durable history.

    The bootstrap correction is observed: original and copied PHP hashes are identical (94de6f81…); the original has cap_net_bind_service, while the runner records CapEff=0, CapBnd=0 and NoNewPrivs=1. Mandatory cleanup is cleanup=0. The original42528752031setup NONPASS remains attributed; there was no same-source retry.

    Normal #1107 backend CI and source integration still need to finish before final #269 acceptance. This is the complete PHP shard, with no polyglot aggregate or benchmark-speedup claim.

  23. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    Final acceptance audit correction: I inspected the actual published E3 witnesses/exports. They prove C1, repeated false wakes and C4, while the full replay matrix proves its 13 declared scenarios. Neither explicitly runs C2's signal-during-activity reproduction or C5's decision turns across continue-as-new. The issue remains open for that direct installed evidence plus #1107 original main custody.

    SDK 3.11.0 already ships scripts/qualify-condition-wait-native.php and its source-reviewed evidence helper for C1–C5; no product source overlay or new SDK release is needed. I am preparing an explicit route in the existing hosted replay workflow to execute that installed script, retain its output and raw per-run Native exports, and require its cases in addition to the unchanged original 13-scenario matrix. This is a coverage correction, not a newly observed product failure. No additional runtime attempt has run.

  24. rmcdaniel commented on Nov 9, 2026

    @rmcdaniel
    MemberAuthor

    The remaining installed C2/C5 coverage has a concrete hosted candidate: durable-workflow/server#1108, runner commit fe9c88473a71e8e1f76d0ccd4566a336d40441e6. It adds php-replay-conditions to the existing published lifecycle workflow and invokes the unchanged qualifier shipped in normal SDK 3.11.0. It keeps the original thirteen PHP replay cases, checks all seven C1–C5 case results and nine fresh Native exports, requires the original C2 activity/signal trigger and CAN lineage, and executes the carried SQL predicates against the owned MySQL rows in a read-only transaction.

    Source CI has started. After it passes, the next selected runtime is one run on that exact runner against already-published Native 3.3.0, SDK 3.11.0 and the reviewed tooling digest. No runtime has run yet. This issue remains open until those raw outputs and SQL results are audited; the historical E3 and thirteen-case PASSs keep their original scope.

  25. rmcdaniel commented on Nov 9, 2026

    @rmcdaniel
    MemberAuthor

    Selecting one original hosted published-workflow-lifecycle.yml dispatch, profile php-replay-conditions, on ref release/general-native-3.3.1 at exact runner 887cd0f15e3bcdbc8ddfae341704b54ddd685511. Source PR durable-workflow/server#1108 is terminal green on this head: 66 success, one intended skip, zero statuses; all seven original workflows succeeded without retry/cancel. The first green head's report-parsing defect was corrected before any installed attempt.

    Published subject: Native Server 3.3.0 at durableworkflow/server@sha256:cb4b11bd6235a551cf51e7dc6342504fbbcef19959618b376fb5648ca00fc388; normal Packagist SDK 3.11.0; tooling ghcr.io/durable-workflow/sample-app-devcontainer@sha256:535e111abed1fa9603f5dc375118d3e24173e590cf978e45f1bdcccabbbf33a6; workflow-pinned MySQL sha256:679e7e924f38a3cbb62a3d7df32924b83f7321a602d3f9f967c01b3df18495d6. Other declared workflow inputs stay Workflow 2.22.0, Python 2.14.1, Rust 4.12.0, CLI 2.3.3 and Waterline 2.13.2; this is PHP-focused evidence, not a new execution claim for those other SDKs.

    Acceptance: all original thirteen PHP replay scenarios execute and pass with zero skips; installed SDK C1, C2, C3 terminate/cancel/continue, C4 and C5 pass; nine raw fresh Native exports match the report, the original C2 activity/signal window and CAN lineage; read-only MySQL inventory/predicates return zero violations; exact artifact identities and cleanup=0. The wrapper retains raw qualifier stdout separately from the validated final JSON, and lint-checks its exporter with real PHP before use.

    One invocation, attempt 1, no automatic rerun or input change. The hosted job has its existing 60-minute ceiling. Missing evidence, setup failure or a failed predicate is NONPASS and stays attributed. Retain the original hosted artifacts for their declared 30 days, with local bulk removed after the concise audit unless an active defect needs it. No product source overlay, 3.3.1 tag/build, alias, GitHub Release or Cloud effect is selected. This issue remains open until the raw output audit.

    Dispatch receipt: 42545606994, attempt 1, created 2026-11-09T01:26:42Z, exact runner 887cd0f15e3bcdbc8ddfae341704b54ddd685511, event workflow_dispatch. The dispatch returned success once; runtime and raw-output audit are pending.

  26. rmcdaniel commented on Nov 9, 2026

    @rmcdaniel
    MemberAuthor

    Final installed C1–C5 audit: PASS, on the already released Native Server 3.3.0 + normal Packagist SDK 3.11.0. Hosted run 42545606994, attempt 1, runner 887cd0f15e3bcdbc8ddfae341704b54ddd685511; job 2026-11-09 01:26:45–01:28:41 UTC. One dispatch, no retry or product overlay.

    • All thirteen original PHP replay scenarios executed and passed, with the same scenario IDs and no skips. Callback cardinalities remain 1/1/3/1.
    • All seven installed cases passed across nine fresh Native runs. C1 has two opens/timers; C2 one; terminate/cancel/continue each one; C4 three; C5 six across two runs. The raw exports match the installed report and contain complete contiguous history.
    • The original C2 trigger is directly captured: activity started 01:28:24.023, noise signal 01:28:24.513, activity completed 01:28:26.096, first wait opened 01:28:26.117 UTC. The settled physical state passes the orphan/duplicate predicates.
    • C3-continue and C5 each retain the exact parent/child run IDs and both halves of the continuation link. C5 covers two decision turns before continuation and one after it.
    • The owned MySQL checker completed in a READ ONLY transaction: nine-run/namespace inventory matched, all reviewed predicates returned zero violations, stdout/stderr were empty. Its 21,675-byte input is byte-exactly rebuilt from the retained report, nine exports and reviewed predicate file; SHA-256 09ff67ba28c36e648c8bb5e47089312c6ed634080bd9efa2f509967b55307d47.
    • SDK dist SHA-256 is the accepted d0f5efb19b5618f7b06b76b89b71bb4c3dd757e986463e17c225677ae1d666e2, source fbc64ef9; PHP 8.4.27. Real PHP lint passed. Original/private-copy PHP bytes match; CapEff/CapBnd are zero and NoNewPrivs=1. cleanup=0.

    Artifact 13642354239 has 77 files, 193,343 bytes compressed, SHA-256 fcf0463888570a4cbb4d2aa9ebccc3e90f7fecdfcbb300feea509afdee5229e8, matching GitHub's artifact digest. Original hosted retention is 30 days. Local raw copies remain only through the current Native 3.3.1 comparison/acceptance or the November 9 20:30 review.

    This completes the remaining installed evidence for #269. Earlier PASS scopes, setup/source/controller NONPASSs and the first-head parsing finding remain attributed. This is a synthetic published-artifact MySQL result, not a benchmark or production rollback approval. The tooling/release integration in durable-workflow/server#1108 and Native 3.3.1 continue under durable-workflow/server#325; SDK #341 and the other performance items remain separate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions