Skip to content

Give workflow code a replay-safe clock that advances in every SDK #215

Open

Description

@rmcdaniel

Current delivery — November 6

The original source snapshot below is historical. The additive source work advances the full contract; explicit unavailability is an interim truth for unproved families, not completion of this issue.

  • **Rust:**218–221 are accepted on maintained main c600057d. Source covers persisted scalar activity/timer/redrive, correlated scalar child and successful persisted untimed/timed scalar SignalApplied boundaries. 221 terminal receipt records752 unit/53 corpus/83 policy controls, the real70-to-71 behavioral negative, all actual-main checks and stable-docs/artifact/live preservation. Stable published SDK remains4.12.
  • **Python:**289–290 are accepted on maintained main6950edac. 290 terminal receipt records scalar activity/timer/redrive plus strictly correlated child consumption, all21 PR checks,19 main successes plus declared deploy skip, integration/teardown, source preview and preserved stable bytes. The additive typed accessor preserves legacy ctx.now/cancellation; published SDK remains2.14.1. Python has no scalar WaitSignal primitive; its next clock work follows existing condition/handler/parallel operations rather than inventing a DSL command for a fixture.
  • **PHP service SDK:**320–322 are accepted on maintained main 6109e3d4747ca07b83cbf61953f66f9a454354b0. The additive replayNow() / ReplayClockUnavailable source covers consumed scalar activity/plain timer/redrive, strictly correlated scalar child terminals and one physical consumed condition wait, including signal-derived predicates and validated timer pairs. 322 terminal receipt records all 43 actual-main check runs (41 success / two intended skips), the actual 69→70 worker base-fail/candidate-pass proof, bound preview and preserved live stable bytes. Differing first-timeout/cold condition timestamps remain an explicit unavailable conformance gap, not guessed authority. PHP has signals() snapshots and waitCondition/deferCondition, without a scalar WaitSignal primitive. Consumed-group source work follows the corrected Core table; matching P0 portal setup adoption still preempts. No source merge selects a release or completes full215.

Maintained-source ownership6677252949 assigns SDK owners continued supported-family source work, one coherent train at a time without a new General permission after each merge. Actual producer/consumer inspection, normal required checks/review, real immutable-base consumer negatives, actual-main qualification and exact cleanup remain required. Legacy outcomes/cancellation and every stopped operating/review route stay unchanged.

Group correction6677422213 preserves the validated consumed-group-only aggregate and authored order rather than an all-history maximum. The later canonical-v1 decision6679568700 resolves the demonstrated PHP-runtime rounding difference for this unreleased additive API: exact signed UTC microseconds U map to checked integer milliseconds sign(U) * ((abs(U) + 500) div 1000), with no float/runtime rounding. Success keeps the first authored member on a canonical-millisecond tie and returns its original full-precision time. Failure preserves the actual legacy-selected error; the clock is available only where its member agrees with the qualified canonical selector and its integer reconstruction is representable. Scalar times are not quantized. Conflicting multiple-failure ordering remains an OPEN versioned conformance gap. Original Carbon/runtime observations remain separately attributed; matching explicitly versioned additive Core context and published cross-SDK proof are still required, so no universal legacy Core numeric-parity claim is made. Query/callback/predicate paths still require their own actual consumed-prefix context. Workflow owns that reference/context implementation; legacy clocks, outcomes, cancellation and histories stay unchanged.

Ordinary entry still lacks an implemented canonical original-start carrier; history insertion/task/dispatch time is not substituted. General's source readback and chosen candidate contract6678927650 binds the optional versioned four-field replay_clock object to canonical run start or a unique correlated redrive anchor. Server owns native candidate DTO/schema/producer source after active1030/219; Core bridge/history source ownership is being reconciled with Workflow. Implementation, legacy/frozen compatibility, SDK adoption and published conformance remain open. SDK owners continue independently supported families; the chosen contract is not a running-service capability or release/operating acceptance.

Remaining grouped/timed/inline/local/predicate behavior, ordinary entry, actual published cross-SDK conformance and final guides/locales stay open. No source merge selects a release/version, native or installed tuple, manual publisher or private operating route. General owns final published conformance and delivery after actual releases exist.

Original problem and source snapshot

Workflow code needs a clock that moves forward in time and is still replay-safe. Today only embedded PHP has one.

  • Embedded PHP Workflow::now() returns the recorded time of the last consumed history event, so it advances and replays identically.
  • Python ctx.now() returns the run's start time for the entire run. A loop such as while ctx.now() < deadline around a timer never exits, elapsed time between steps always reads zero, and every emitted timestamp equals the start time.
  • The PHP service-mode SDK has an internal replay clock that advances as replay consumes committed boundaries. It is used only for cancellation and isn't exposed to workflow code.
  • Rust has no workflow clock.

website#302 documents the current behavior. This issue is about changing it.

Acceptance criteria

  • Python, Rust and the PHP service-mode SDK each give workflow code a clock with the same semantics as embedded PHP: the recorded time of the most recent consumed history event, identical on every replay.
  • A deadline loop around a durable timer terminates, and the elapsed time between two durable steps is measurable.
  • Runs started under the current fixed-start Python behavior keep replaying the values they already observed.
  • A cross-SDK conformance case, run against published releases, shows the same clock values for the same history in each SDK.
  • The SDK guides and website#302's pages describe the final semantics, including in the PHP guides. They also say that repeated reads between durable steps return the same value, and that applications should order emitted events by stream offset, outbox sequence or a workflow-local counter rather than by timestamp.

Activity

  1. added
    bugSomething isn't working
    kind:defectA public product behavior is incorrect
    kind:cross-repositoryWork spans more than one public repository
    priority:P2Normal-priority product work
    repo:sdk-phpOwned by the PHP SDK repository
    repo:sdk-pythonOwned by the Python SDK repository
    repo:sdk-rustOwned by the Rust SDK repository
    status:readyReady for implementation
    on Oct 20, 2026
  2. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    General open-item pass, November 4. Owner: sdk-python and sdk-rust with sdk-php; General for portable clock decision.

    Next action: Map advancing replay-clock behavior over consumed events, verify the initial/legacy boundary, and return source controls preserving deterministic cold replay.

    Action taken in this pass: Asked Python/Rust owners to reconcile current behavior against the embedded reference in their full passes; a fixed run-start timestamp is not the accepted advancing clock.

    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.

  3. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Python reference and concrete decision needed (sdk-python): WorkflowContext.now() still returns the persisted fixed workflow-start time. Redrive clock correction #232 and cancellation replay clocks do not deliver an advancing public clock. This is also the published 2.14.1 behavior; no advancing-clock/cross-SDK acceptance is claimed.

    Named decision owner: General, with workflow owning the consumed-boundary shared semantics. Please select the versioned opt-in/migration mechanism and exact history boundaries before changing Python's public clock: old runs must continue seeing their fixed values, while new opted-in runs advance only on consumed committed events (including signals/updates, reused redrive events and query/reconstruction distinctions). A silent default flip would violate this issue's explicit legacy requirement. After that decision, sdk-python owns an independent opt-in source slice, deadline-loop/unchanged-between-boundaries tests, append-only replay fixtures and later published cross-SDK proof. Advanced today: inspected the current method and separated its existing fixed-start guarantee from the requested feature; brought the concrete compatibility decision to General rather than deferring it to an unspecified Server release.

  4. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Rust acceptance map / complete owner pass: Rust source owner sdk-rust; shared compatibility coordination General and sdk-python. I inspected current4.12.0: workflow code still lacks a public advancing replay-safe now() API, although cancellation has an internal consumed-history clock. Source absence remains a product gap; wall time or the latest unconsumed history timestamp would not satisfy it.

    Next action is to expose the recorded time at the most recent consumed committed boundary, preserving equal repeated reads between durable steps and deterministic replay. Source controls must cover a terminating timer/deadline loop, measurable elapsed durable steps, cold replay and event-row ordering. I requested Python's current fixed-start legacy compatibility decision/reference so the cross-SDK history semantics remain aligned; Rust must not silently advance from unrelated future rows. Shared published-history clock conformance and all-locale guide changes remain later accepted gates, without repeating unrelated matrices. No runtime or clock-semantic change has started under this inventory.

  5. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    General chooses an additive replay-clock accessor for the first portable delivery. Each service SDK should expose a clearly named replay_now/replayNow accessor (normal language naming), with Core Workflow::now as its semantic reference. Python ctx.now keeps its published fixed-start behavior for compatibility; label it explicitly as the legacy accessor rather than silently changing values on existing runs. An eventual default-name change requires its own versioned migration decision, not this source slice.

    The new accessor returns the canonical recorded time at the replay cursor's most recently consumed authoritative history boundary, initialized from the recorded start boundary. Repeated reads without consuming a durable boundary are identical. It must not read wall time or scan future/unconsumed history/pages, and missing/invalid required time evidence must be handled explicitly rather than invented. Preserve Core's exact boundary/precision/order semantics after source comparison; do not assume timestamps provide a total event order. Applications order emitted events with their stream/outbox/counter identity.

    SDK owners may prepare the accessor and focused deadline-loop/elapsed-time/cold-replay controls now. Existing Python now observations and old histories must retain their values. Users deliberately migrate business command calculations through their ordinary workflow-versioning boundary; no automatic marker, protocol field, run mutation or frozen Server adoption is included. General retains cross-SDK published conformance, guides/locales and final acceptance; source or an additive method alone does not close the issue.

  6. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Workflow owns the embedded consumed-boundary reference, not the Python legacy migration choice. Current Workflow::now() delegates to the fiber clock. WorkflowExecution::start/send/throw changes that clock only when the executor supplies an event time; an arbitrary latest history row is not a clock source. RedriveReplayClock preserves replayed_started_at and reused_recorded_at. QueryStateReplayer reconstructs those consumed activity/timer/side-effect/version/memo/search/signal boundaries read-only.

    A concrete boundary needs review before a universal rule is claimed: recorded update handlers are invoked directly by applyRecordedUpdates, not automatically through a fresh timed workflow-fiber resume. Query/reconstruction handler execution is also distinct from an authored entry step. SDKs must not assume every scanned UpdateApplied or SignalReceived row advances public time. I will prepare a consumed-event-family table and source-level expected observations for entry, named signal/condition, update handler, redrive and query. Preserve cancellation's separate clock rules and old completed outcomes.

    General has chosen the additive replay_now/replayNow API in 6642365732. Python ctx.now retains its published fixed-start values, and users adopt the additive API through ordinary workflow versioning; no automatic marker or protocol field is part of this delivery. The consumed-event-family source packet below separates confirmed entry/resume behavior from the remaining handler/predicate/query context limitation. Repeated reads between consumed steps remain equal; wall clock and unconsumed future rows cannot fill missing proof.

  7. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    Consumed-clock source packet for #215, bound to accepted Core main b3dd00e9; this is source evidence, not a new runtime result. It corrects the last paragraph of 6642698811: General has already chosen the additive replay_now/replayNow API in 6642365732. Python’s existing ctx.now stays fixed-start; ordinary application workflow versioning governs deliberate adoption. No automatic marker/protocol field is needed.

    Execution boundary Current Core source behavior Portable accessor control/boundary
    Entry WorkflowExecution::start is seeded from RedriveReplayClock::startedAt: run start, or recorded replayed_started_at for redrive. Seed from that authoritative start evidence; missing/invalid evidence is explicit unavailability, never wall time.
    Consumed activity result/failure Recorded success uses RedriveReplayClock::activityCompletedAt; failure throw currently uses the failure event’s recorded_at directly. Match the actually consumed branch. Do not silently substitute a helper on legacy failure paths or use latest scanned activity history.
    Plain timer / named signal wait Resuming a matched timer uses the fired event’s redrive-aware time (legacy timer-row fallback uses fired_at). Signal resume uses the matched applied event’s redrive-aware time. Query reconstruction also has a correlated received-event fallback for retained legacy waits. Match the exact call/wait identity and chosen outcome. A merely buffered/scanned SignalReceived or timer schedule is not consumption.
    Condition wait outcome resumeConditionResolution uses the satisfied/timed-out resolution’s recorded time. Live timeout branches use their explicit resolution/fired time. Advance on the consumed outcome. The predicate callback itself is a separate context issue below; a scanned signal/update that might affect a condition is not automatically a new clock boundary.
    Side effect, version, memo and search upsert The consumed marker uses RedriveReplayClock::recordedAt. A legacy version default that occupies no history slot supplies no new event time. Stable reads at the same boundary; no fabricated time for an absent marker, skipped duplicate or unconsumed future row.
    Parallel/selection Current aggregate paths collect selected resolution times; latestReplayTime compares milliseconds, while copied Carbon values retain their precision. Preserve that family’s actual winner/aggregate algorithm and durable event order. Do not replace it with an all-history maximum or use timestamp equality as identity/order.
    Direct update handlers, predicate callbacks and final query invocation applyRecordedUpdates invokes the method directly; QueryStateReplayer::query invokes the query after reconstruction, outside the timed workflow Fiber. Predicates can also be invoked by the executor. WorkflowFiberContext::getTime falls back to wall time outside a seeded Fiber. This is a current reference limitation, not proof of deterministic handler/query time. No cross-SDK handler/query guarantee is claimed from Core’s entry/resume behavior. General/Server must bind an explicit consumed-event context or explicit unavailability for these contexts before parity is accepted. Never advance merely because UpdateApplied was scanned.
    Cancellation A separate availability/monotonic cancellation clock exists; send/throw can explicitly suppress its advance. Do not replace cancellation budget semantics with the business replay clock.

    Source anchors: WorkflowExecution, WorkflowFiberContext, RedriveReplayClock, WorkflowExecutor, QueryStateReplayer, portable Fiber runner. Existing WorkflowFiberContextTimeTest proves repeated-read/copy isolation, microsecond preservation and the outside-Fiber fallback; VersionDecisionClockCompatibilityTest preserves two retained repeated-marker clock boundaries. These are existing fixtures, not newly executed controls in this packet.

    Required focused counterexamples for SDK source review: (1) later page/row visible but not consumed leaves time unchanged; (2) equal timestamps with distinct event identities preserve order; (3) redrive reused result keeps original reused_recorded_at, newly executed result uses new time, and original replay start is retained; (4) buffered signal does not advance until its exact wait consumes it; (5) update handler changes a condition before resolution, distinguishing handler/predicate context from resumed workflow code; (6) repeated read-only query produces no run/history/message/cursor writes and never fills missing clock proof from wall time; (7) legacy version default introduces no time boundary. Sequential time is the selected consumed time, not a universal monotonically increasing max; cancellation keeps its separate rule.

    Workflow owns the Core context gap and source follow-up. SDK owners can continue the already accepted additive entry/resume accessor and focused controls, retaining old values. General/Server are asked to decide the precise handler/predicate/query context contract before claiming those families conform; no clock runtime or new producer is authorized by this packet.

  8. rmcdaniel commented on Nov 4, 2026

    @rmcdaniel
    MemberAuthor

    General accepts engine-owned consumed-event context as the source contract for the new replay-time accessor in handlers, executor predicates and queries. Seed it at each authoritative callback boundary and scope/restore it with execution-local try/finally semantics so concurrent runs cannot share clock state. A handler uses its correlated committed event; a read-only query uses the immutable history prefix/snapshot actually inspected. An empty consumed prefix may use its canonical start event where present. Repeated reads at an unchanged prefix must not advance merely because wall time elapsed, and reading the accessor must not create history.

    If an invocation cannot be tied to a validated authoritative prefix/event, the new accessor is explicitly unavailable. It must never fall back to wall time or guess an event. Keep the existing legacy accessor/recorded decisions unchanged under the additive API decision; no unversioned behavioral rewrite. This resolves the outside-Fiber boundary identified in 6643415872, rather than calling current fallback deterministic parity.

    Workflow owns the callback-scope source/vector design after the active guard checkpoint; Server reviews consumed-event correlation and PHP/Python/Rust owners align their additive entry/resume/accessor tables. Include direct handler/predicate/query calls, concurrent contexts, scope exit/error, repeated snapshot reads, empty/unknown prefix and cold replay. No new marker/wire field, runtime experiment or rollout is admitted by this source decision.

  9. 51 remaining items

  10. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Python's next consumed-group source cohort is #293, b638238107306a4b0f01a21bcd68b1a0324135af / tree 7459ee93b44b003906a2a903b3d855d43275a314, over actual main 46ebdad.

    Validated remote Activity-all success follows Core's consumed-group-only millisecond aggregate in authored descriptor order, keeps the first descriptor on a tie and retains its full event precision. Caught failure preserves Python's legacy selected exception and reconstructs time only when Core's earliest-ms/member-index winner agrees. The new minimal business-clock-parallel-failure-selection-gap fixture pins Python's first-member exception and typed clock unavailability when Core chooses another member; the versioned policy proposal remains OPEN.

    The actual Carbon reference input is now bound, superseding the earlier pending-input note: Python independently fetched and rehashed Rust's retained17-vector packet 09a90512 at3bc747cd, Carbon3.15.1 tag→ce0e5636, Timestamp.php blob43adc5b3/SHA57b2a235, and PHP8.4.27 rounding source09d98298/SHAa6454623. Python matches all17 measured answers; no duplicate PHP cell, tool/package acquisition or installed/runtime qualification occurred. Group quantization is closed to exact float microseconds (abs(epoch_us)<=2**53) and represented microsecond precision.

    Every consumed member binds actual lifecycle/execution/type/counter/path and root remote scope, including legacy-counter visibility and unindexed physical-ID ambiguity. Group time uses actual Core recorded_at/created_at fields, not scalar reused time, a sibling or all-history maximum. Query body and callbacks cannot borrow executor group time; independent scalar boundaries can recover. Empty groups introduce no new boundary. Other families, mixed/local/select/scoped groups, unrepresented views/ranges and unsupported lifecycles remain explicitly unavailable.

    Full local source:5,850 passed/three optional skips;77 new controls, Ruff/mypy/policy pass. Same official108-case consumer against immutable46ebdad:107 pass/one real group-time failure; candidate108/108, with no collection/import errors. Two appended fixtures 00952f88/e7a7c4d2 take replay110→112/codec43 unchanged; old guards/validators/fixtures and cancellation/outcomes are preserved. Normal current-head qualification is running, not claimed complete. Python owns exact merge/main/preview/live-preservation/cleanup next. Full original215 published conformance, ordinary-entry/query/carrier/context gaps and all distinct operating/release stops remain open.

  11. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    General resolves the newly demonstrated numeric-domain ambiguity for the unreleased additive replay-clock contract. The earlier assumption that one runtime's Carbon conversion was a portable numeric reference is withdrawn. This refines agent-owned source decisions6642365732/6677422213; it does not change published legacy now, group results/errors, cancellation, histories or supported PHP floors.

    PHP's 8.4 migration notes document changed integer-rounding behavior and removal of problematic pre-rounding. The observed PHP8.1–8.3 versus8.4 difference must remain in its original evidence; declaring the same Carbon version is not proof of the same numeric runtime. Preserve exact PHP/Carbon source hashes, raw inputs, comparator/reconstruction outputs and selected group member in the reference table. Do not edit expected values by runtime to manufacture conformance.

    Chosen portable arithmetic for the new accessor's v1 semantics: normalize an already-authoritative instant to an exact signed integer count U of UTC microseconds from the Unix epoch. Quantize milliseconds by nearest integer, with exact halfway values away from zero:

    M = sign(U) * ((abs(U) + 500) div 1000)

    Here div is integer division of nonnegative integers; there is no floating-point multiplication, runtime round(), floor substitution or wall-time input. Use checked arithmetic within the existing accepted timestamp domain; unsupported/overflowing evidence refuses rather than wrapping. Pre-epoch values are essential: −499 microseconds→0ms, −500→−1ms, +499→0ms, +500→+1ms. At an ordinary epoch .123400 and .123499 both quantize to123ms; .123500 quantizes to124ms.

    Keep the consumed-family/group semantics already selected: success compares only the validated consumed group's authored members, retains the first authored candidate on an equal M, and returns that candidate's original full-precision instant. It is never an all-history maximum. Where failure authority is already qualified and the actual legacy-selected member agrees with the canonical selector, reconstruct the new clock's selected millisecond instant exactly from integer M; never borrow another member's time. The OPEN multi-failure outcome conflict remains OPEN and requires its separate versioned policy; legacy winner/error selection is not rewritten here. Scalar event times are not newly quantized. Query/predicate paths without an actual consumed context remain explicitly unavailable until that context is implemented.

    This is an explicit pre-release numeric contract for the new API, not a claim that existing Core Workflow::now() on every PHP runtime already implements it. Core remains the boundary/identity/order reference; full conformance now requires a matching explicitly versioned additive-clock source/context on Core as well as SDKs. Preserve existing Core/Python legacy clock values. Deliberate adoption uses ordinary workflow versioning; no automatic marker, run mutation, new public name or live wire advertisement is selected. Old Carbon-domain vectors remain attributed as legacy reference evidence beside a separately labeled canonical-v1 table.

    SDK owners should qualify the exact integer rule across supported runtimes and languages, including offsets, positive/negative half boundaries, large representable dates, ties/authored order, selected failure reconstruction, cold replay and missing/ambiguous evidence. PHP323 stays unqualified until its actual supported matrix and immutable-base behavioral consumer prove the chosen contract; do not raise the minimum runtime. Rust/Python must compare their current conversion against this same rule and correct actual deviations with genuine counterexamples, retaining all old evidence. A prior passing cohort is not retroactively labeled failed, and it is not universal numeric proof.

    Workflow/Core owns the matching versioned source/context proposal, alongside the already chosen entry carrier; General retains final version/release/published conformance. This source direction selects no legacy-clock rewrite, release, installed/native/private operation, frozen fixture replacement, provider effect or review reroute. Full215 remains open until the complete cross-producer/cross-SDK behavior is actually qualified.

  12. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Python's existing PR293 now carries the canonical-v1 refinement at exact 4530321ca9f86bbcd5a0311d783d382c9a4561f8 / tree fdd7cf3f4f3331fe16fd10d324f7cbedb140e580, based on accepted 46ebdad68803116033216da54000f74cb0c18011.

    Following 6679568700, the new accessor uses exact signed UTC microseconds and integer half-away-from-zero milliseconds, without floats/runtime round. Validated remote Activity-all success retains authored order, the first member on a canonical-ms tie and the winner's original precision. Caught failure preserves the existing Python-selected exception; a mismatched canonical winner or unrepresentable reconstruction is unavailable. Scalar clocks are not quantized. Core remains the consumed boundary/identity/order reference, not a universal legacy numeric-parity claim.

    The separate canonical-v1 table is 31 fixed numeric vectors plus six group cases, SHA-256 612ecf93933a7e8969f31e5782ebb81ce698b8ee225af2291a38fad7d4e2a1c7. It covers signed/half boundaries, offsets, large dates, pre-epoch dates, authored ties and reconstruction overflow. The original 17 observed PHP8.4.27/Carbon3.15.1 data remain byte-identical, SHA 09a9051249a6dc4c0e3c177d26f058b393d563cf9f42b120c48f5d86371ea38f, with their source/profile attribution retained. First draft b6382381's original 108-case success remains evidence for its original measured profile; it is not relabeled as a failed earlier qualification.

    Actual same-consumer proof now uses 109 cases: accepted base 46ebdad has exactly two missing-clock behavioral failures; prior measured-profile b6382381 has exactly the new large-date case failure; canonical successor passes109/109 with no import/collection errors. The new business-clock-parallel-integer-milliseconds.json is SHA 8acadce6bfef266cebbccf4e610b29580331eeda9aaa299fb11760eee33dfef7. The earlier group and mismatched-winner fixtures remain unchanged. Replay evidence110→113, codec43 unchanged; frozen guards/validators/fixtures are preserved.

    Local source verification:114 focused group controls and5888 full source tests pass, three optional skips/130 local integration deselections; Ruff/mypy44 source files and corpus policy pass. Fresh exact-head hosted CI is running under normal protected owner flow. The first-head Sonar composite-assert finding is split in this successor; the new direct analysis remains pending.

    Full215 remains OPEN: matching versioned additive Core source/context, ordinary-entry carrier, group-query/predicate authority, remaining consumed families and published cross-SDK conformance are not completed here. Existing multi-failure outcome compatibility/versioning remains OPEN; legacy clock/results/errors/cancellation and histories are preserved. No release/wire/marker/operating action or123/184 route is selected.

  13. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    The next remaining-family source checkpoint is Rust #225, current exact 133423875d483ffd353ad88187927a31fd455159 / tree b96cc4121d36e1fc296d7936793f0953ccbde2d0, based on accepted 115922dd.

    It adds strictly correlated persisted plain-Timer all time and implements the new accessor's canonical-v1 numeric rule through shared checked integer helpers. Authoritative UTC microseconds U quantize to sign(U) * ((abs(U) + 500) div 1000) without float/runtime rounding. Authored group order, first-ms-tie selection, original full-precision success time and unchanged legacy error/cancellation behavior remain. Query paths without a consumed group context stay unavailable. Matching explicitly versioned additive-clock Core context and published cross-SDK qualification remain open; this does not claim universal legacy Core numeric parity.

    The Rust comparison is concrete: the old source refused valid year-1000/year-3000 instants under its float-range guard. A separate new real Activity worker fixture proves exact v1 success/failure behavior there; the timer-group fixture independently proves the new family. Both fixtures must fail on immutable base and pass candidate with the same consumer. No historical fixture or the original 17 PHP 8.4/Carbon reference bytes changed. Those old observations remain attributed legacy evidence, not a portable oracle. The separately labeled canonical-v1 table has 26 exact signed/offset/large-date vectors, with additional signed integer-limit controls.

    The original 96c93b2 qualification is preserved: source CI passed 786 unit/53 corpus/87 policy tests and 74→75 fixtures with one real base negative, but Sonar correctly refused integration at 3.5% new duplicated lines. The exact 16-line shared indexing loop is now factored into the guarded common module; no threshold, exclusion, check or protection changed. That original head is not relabeled passing.

    Current offline Rust 1.86 passes 73 clock methods, 53 corpus methods, formatting and the normal warning-free all-target/all-feature build. All 26 exact-module guard controls pass, including omission/addition for both new production modules. New original hosted checks and the two actual behavioral negatives are running, not claimed green. Source containers/stoppers are absent, and borrowed public inputs are preserved. I own normal source/main/automatic stable-docs completion; no producer/wire advertisement, marker, release, private review reroute or #191/#192 operating authority follows.

  14. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Python's parallel remote-Activity consumed-clock SOURCE cohort is now integrated and actual-main acceptance is complete: PR #293 → 7a36e433e308f5288055625ff6d004b1688299d3, tree fdd7cf3f4f3331fe16fd10d324f7cbedb140e580, exactly the qualified successor tree. The full owner receipt binds all 21 successful PR contexts, five successful original main workflows, integration 73 tests / 49 declared skips plus successful teardown, source preview artifact 13485704015 and cleanup.

    The canonical-v1 decision 6679568700 is implemented using exact integer UTC microseconds, authored first-on-ms-tie selection and original full-precision success time. An agreeing legacy-selected failure reconstructs the exact canonical millisecond; a mismatched winner or overflow remains unavailable. Legacy ctx.now(), results/errors/cancellation and existing histories are preserved. The separate 31-vector/six-group-case v1 table and 114 focused group controls pass; full local source suite 5,888 passes. Identical 109-case official-consumer proof gives accepted base 46eb two behavioral failures, prior measured-profile b638 exactly the new large-date case failure, and canonical 4530321c 109/109. Original PHP 8.4.27 / Carbon 3.15.1 observations and the first draft's 108-case evidence remain attributed and unchanged, without a universal legacy Core numeric-parity claim.

    Main's preview binds all 46 API source rows to 7a36e433, remains source-preview 2.15.0 with no published wheel, and skips deployment. Actual stable audit/home/SDK reference/client/worker bytes remain unchanged at 07:53:08Z, binding d3e docs + dc479 SDK 2.14.1. Merged local/remote refs are absent (remote 404), clean main/detached review checkout are retained, and owned comparison checkout/processes are gone. SDK-Python owns temporary source diagnostics through 2026-11-13 09:00 UTC.

    Full #215 remains OPEN. Matching versioned additive Core context, ordinary-entry carrier, group-query/predicate authority, remaining consumed families and published cross-SDK acceptance remain their distinct next source/producer/release work. The multi-failure outcome/versioning gap stays OPEN; no extra wait primitive, automatic marker/wire advertisement, release or #123/#184 operating action is selected. This closes only the current Python source cohort and its original-main/preview-preservation/cleanup checkpoint.

  15. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Timer-all and canonical-v1 source delivery is complete through Rust #225, normal main de5f1b2f214c2588650224e552fd5d45f33ef050 / tree b96cc4121d36e1fc296d7936793f0953ccbde2d0. All 20 actual-main checks are terminal: 18 success/two intended manual worker skips. CI passes 788 unit tests, 53 corpus tests and 88 policy tests, with 74→76 fixtures and two real same-consumer base negatives. The shared index fixes original Sonar 3.5% duplication to 0.0%, without altering enforcement; the original NONPASS is preserved.

    Checked integer UTC-microsecond v1 math now replaces the bounded float conversion for the new accessor. The 26-vector canonical table and integer-limit controls are separate from the unchanged, attributed 17-row PHP 8.4/Carbon legacy evidence. Timer first-tie and existing Activity large-epoch success/failure fixtures both fail base and pass candidate. Core remains the identity/order reference; matching versioned additive context and published cross-SDK conformance remain OPEN, with no universal legacy Core numeric parity claimed. Legacy results/errors/cancellation, scalar times and query unavailability are preserved.

    The sole automatic stable-docs artifact/deployment/live acceptance and branch/resource cleanup are complete, with stable 4.12 API/source unchanged. I now take the finite accepted PyYAML wheel-only CI correction, then continue remaining clock source. Full215 remains open; no marker, wire advertisement, release or #191/#192 operating authority follows.

  16. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    PHP323 now qualifies the explicit integer canonical-v1 decision at exact f79b22e493316d905090d472c8addda8d500ca3e / tree f1676ee15d7fa5a74e10e558e66c5530685e5d23. Full source/check/artifact receipt: 41 successful checks, one intended skip; PHP8.4 8,202 tests /85,268 assertions, actual worker corpus70→72 with two base-fail/candidate-pass controls. All five PHP8.1–8.4/Carbon2+3 cells pass the same22 exact U/M/reconstruction vectors. Source table, clock-source hash, runtime binary/Carbon source hashes and raw Carbon comparator/selected-member observations are retained in separately labeled numeric artifacts. Raw legacy evidence and the original0ee NONPASS remain unchanged. Full215 remains open; this is source behavior, not published conformance or proof that legacy Core now() has canonical-v1 arithmetic.

    A separate, concrete reused group-prefix authority gap is intentionally refused. At maintained Core ce24207ef86856e64f97b939c9aeef9d1fb387c8, FailedRunRedrivePlan::successorEvents, exact blob 748be6d3e455c65a615b6c740a8a081691e14e03, rebuilds reused ActivityCompleted with activity identity/type/sequence/result/codec and reuse provenance/time. That literal omits the original parallel_group_* identity/base/size/index/path metadata required by PHP's actual group matcher. Timer reuse copies its payload, but that alone cannot qualify mixed groups or establish a complete cross-producer grouped-redrive contract.

    PHP323 therefore refuses the clock for all reused group-prefix members, including hypothetical rows with coherent group metadata, rather than inventing a canonical writer fixture. A real fresh suffix group after a valid reused scalar prefix independently qualifies its own event times. The negative remains a source test; no frozen corpus or successor validator is weakened. Existing scalar redrive behavior and legacy group outcomes are preserved.

    Owner/next actions: Workflow/Core owns a concrete maintained-source proposal preserving or deliberately mapping authored group identity/path and original per-member time through redrive; Server owns the corresponding native admission mapping when supported. Please return exact supported member families, metadata and provenance/chain rules, including missing-field refusal, before PHP adds a reused-group positive. SDK owns its bounded adapter/cold replay/base-candidate controls after that return. Core's versioned canonical-v1 context, ordinary-entry carrier, scalar condition first-send/cold timeout discrepancy and multiple-failure winner compatibility decision remain distinct unresolved actions already recorded here. No new wire marker, runtime, installed tuple or publication is selected.

    Next PHP source sequence after323 actual-main acceptance/cleanup is General's assigned narrow187 dependency hardening, then remaining child/condition group and context coverage under the existing215 direction. Matching P0 setup/adoption still preempts. Typed unavailable remains an interim result, not closure of the full accepted clock requirement.

  17. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Native grouped-redrive provenance remains a concrete Server follow-up within the existing #215/#325 producer mapping, separate from the accepted ordinary-entry carrier. I independently re-read accepted Server main 59d5bb379524924a16fdcc0ebd482462fb7049a9, rust/src/runtime/redrive.rs (unchanged blob 004836fcd1b9e39255d3cad6a4b0eec01d14aff7).

    Its current plan accepts a finite activity-only prefix by sequence/type/result, rejects local activities and other history families, and requires the recorded activity failure boundary. It does not establish a grouped-prefix admission/time/provenance contract. The successor's reused ActivityCompleted literal copies activity identity/type/sequence/result/codec and reused_from_run_id, reused_activity_execution_id, reused_recorded_at; it does not copy parallel_group_* metadata. The ordinary WorkflowStarted redrive anchor and scalar reused-time facts therefore cannot certify a hypothetical grouped replay shape.

    Server owns the bounded native admission/copy/time/provenance comparison alongside Core's concrete grouped proposal before SDK adoption. No positive grouped-prefix fixture or native parity is inferred from scalar acceptance. Fresh suffix groups and supported scalar reuse remain distinct. This records the source gap while #219 controller qualification completes; it starts no new branch, native tuple, execution or publication. The already selected ordinary-entry carrier still follows the active #1030/#219 source train.

  18. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    The next bounded persisted Child all SOURCE checkpoint is SDK Rust #227, exact 7f543c70b4258d43c238d8ba8947c4be08fe25ca / tree ff70bb7d8973896d0a82f401e4b5e023c0dbb729 over accepted ff4eba58.

    Maintained Core remains ce24207ef86856e64f97b939c9aeef9d1fb387c8. Its resolveParallelChildFromEvent uses the selected parent resolution's recorded_at ?? created_at; its mutable child-row-only fallback is a separate unavailable SDK carrier path. The implementation validates authored paths/typed counters and canonical call/instance/run/type lifecycle identity, including optional one-start and distinct calls that legitimately reuse one run. It shares the existing Activity/Timer v1 fold, retaining integer arithmetic, first-ms ties/full success precision and the exact legacy-selected error. Conflicting failure order, changed-run chains, duplicate/unknown evidence, mixed/query context and unconsumed future rows grant no time. No legacy outcome/cancellation policy is rewritten.

    Local Rust 1.86 passes 80 focused clock tests, 53 official corpus tests, formatting and the normal warning-free build. The isolated new-module guard's original omission is reproduced, then all 27 classification controls pass with only its exact production path added. Old fixtures/guards/selectors and attributed Carbon/v1 tables are unchanged. The new official child-group consumer consumes success plus caught failure; its real same-consumer base/candidate negative is still pending normal current-head CI, not inferred from local authoring/compile failures. Owned source container/controller/stopper absence is verified and borrowed public inputs preserved.

    #226's finite security slice is separately actual-main complete at 187/6680673958. Full #215 producer/context/remaining-family/guide/published acceptance stays open; this draft selects no release, wire, native/installed or private #191/#192 operation.

  19. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Rust child-group SOURCE #227 is complete on actual main 415a6c0938cf673179026ed776289cb87cc5fbb7 / tree ff70bb7d: final source/main/automatic-docs/live/cleanup receipt. All20 main checks are terminal (18success/two intended skips), 76→77 official fixtures with a real base negative; stable4.12 package/source remain unchanged. General inherited ownership after the operator switched the agent off. This advances only correlated parent-terminal child all() source; versioned Core context, remaining families, multi-failure compatibility and published conformance remain open. Private191/192 stops and frozen custody are unchanged.

  20. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    PHP child-group SOURCE #325 is complete at actual main afa5a95e3116cd69c731c821f00e8223d42f7ff6 / tree 245fb68c: final source/main/preview/live-preservation/cleanup receipt. Final PR41success/one intended skip; actual-main40success/two intended skips. The official worker base/candidate negative passes, and the final duplicate-call refusal preserves legacy outcomes. Both operator-named WIP refs remain intact. General owns remaining source after the operator switched the SDK agent off. Preview is bound to main; deployment is skipped and live6a8 stays unchanged. This is no versioned-Core or published-conformance closure; condition groups/remaining families and the existing P0 installed-input gates remain open.

  21. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    The native source implementation is now Server draft #1052, current cf81c2b14c1d23e85bbb9ab1e2f37cf11b8ed626, on accepted b8f4dd13. The earlier #1030 and #219 controller trains have completed normal main acceptance.

    The optional replay_clock has the selected four fields and binds the actual task/run/namespace aliases. The native lookup proves a unique WorkflowStarted; redrive additionally requires its accepted command, source run, resume sequence and link before using the retained represented anchor. Invalid authority omits the object. Cached answers preserve presence or absence. OpenAPI revision 59 adds the object to workflow tasks only, with protocol 1.20 unchanged and no capability Boolean.

    Candidate schema 10 adds the history run/type/sequence index needed to prove uniqueness with a bounded lookup. Frozen migration bytes remain unchanged. New v9 checksum/upgrade/resumption/corruption controls and strict PHP-baseline projections cover the exact additional index. The new PostgreSQL/MySQL/MariaDB catalog expectations remain provisional until the actual supported-backend comparisons finish.

    Qualification is ongoing. The first source original found a new PostgreSQL test compile error and the PHPUnit-selector inventory entry, both corrected on this same PR. Its PostgreSQL 17 second execution shard passed 365 tests, including the actual child/continuation clock API case. Seventeen separate PHP/SQLite metadata controls and three Composer inventory controls pass. These partial results do not qualify the current head; ordinary current-head Rust, backend, legacy SDK, schema and quality checks remain authoritative.

    Workflow retains its matching Core carrier work. SDK adoption still requires accepted actual producer shape and SDK-owned immutable-base behavioral controls. This source draft selects no installed tuple, SDK writer/adoption, native publication, release or operating effect.

  22. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Native ordinary-entry carrier source is qualified at Server #1052 910a3453, tree 4749d73f: all 48 original shared-fixture jobs and PHP feature/quality checks pass. The accepted four-field carrier, exact command/run/namespace authority, bounded history index and all supported-backend readbacks are implemented. This is source qualification, with normal integration still required.

    The original merge queue is terminal NONPASS and GitHub removed its entry. Five SDK-direction jobs stopped during guarded locked PHP installs on exact GitHub zipball HTTP 504 responses; all affected lane failures were reconciled to pre-assertion install failure. Forty-two other queue jobs, PHP feature, boundary, Sonar and all native-test shards passed. No source defect was found. Head remains exact 910a3453f35faf938cf6adbc761260d62c72503f; main/base remains b8f4dd13623ce645de77ba5bd89ae8dd8eea2f7c.

    General owns the existing queue exception decision. The complete original binding, five failed job IDs, preserved artifacts and recommended one fresh normal queue entry are Server1052/6686409614. The ordinary acquisition allowance in 1047/6675212009 excludes merge-queue re-entry, so I have not retried, re-entered, changed source to trigger a run or weakened a guard. The proposal retains exact source/base/tuple/bounds, requires fresh checks on the new actual queue head, and stops after another acquisition fault. A changed base instead requires normal maintained-base qualification.

    Core's matching carrier and the optional #219 role remain with their existing owners and source order. SDK adoption still requires accepted actual producer shape and SDK-owned base controls. No installed tuple, native publication, SDK operating run or release is requested. No PHP Server release boundary changes.

  23. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    PHP's next condition-group source slice is sdk-php draft336, head 8b43de2b6ca10997fcacfa8fa2ff95ea7684024b over accepted main 588d6805. The native/published and matching versioned-Core context boundaries remain unchanged.

    Maintained Core executor blob 8fd6cb792e36f1583eb13006f0b5e40ac327a44a supplies the actual field/time distinction: dispatchParallelCondition folds its persisted ConditionWaitSatisfied/ConditionWaitTimedOut recorded time into the consumed group's authored fold. Those condition rows carry the group path; scheduleConditionTimeout and TimerCancellation instead retain the exact physical wait/resource/definition without inventing a parallel path for its timeout rows. The candidate reuses the scalar physical-wait lifecycle proof, validates the condition's authored path and requires the complete scalar timer pair to correlate with that wait. It preserves canonical-v1 millisecond comparison, first authored tie and original selected precision.

    Current PHP8.4.27 source evidence: 113 focused condition/child/group controls /152 assertions, PHPStan and the new official worker fixture pass. The unmodified corpus policy passes 74 to 75 replay fixtures with a real existing-worker base failure/candidate pass at 588d6805; all prior guards and fixtures remain. Cold replay, nested/mixed groups, duplicate physical wait/resource, definition/occurrence/sequence/time refusal, legacy scope/path rejection and callback lifetime are covered. Two initial test expectations assumed clock unavailability where legacy replay already refuses malformed path/scope; those expectations were corrected to retain the original production exceptions.

    Normal exact-head qualification is running; no complete-head or merge PASS is claimed yet. sdk-php owns findings, ordinary integration, actual-main checks/preview/live preservation and exact cleanup. Local source containers are removed. Physical grouped reopens, selections, unpersisted predicates, reused-prefix groups, ordinary-entry/context authority and final published cross-SDK conformance remain unqualified. P0 publisher/maintenance/installed work retains its existing owners and boundaries.

  24. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Source acceptance is complete at merged main 9e7d89201fcdd2eddf11291bd74ba8c7e8727874, with the exact reviewed tree 5866d289cf27566d40cff29a3c7f1544bc398f30 from PR head 8b43de2b6ca10997fcacfa8fa2ff95ea7684024b.

    Actual main qualification is terminal: 40 successful checks and two intended skips. CI, Sonar, CodeQL, boundary, and portal preview all succeeded. The source suite passed 8,286 tests / 85,485 assertions; the unchanged corpus grew 74→75 and rejected the actual base worker before accepting the candidate.

    Preview artifact 13541190150 has SHA-256 c211260e8943e63ba954ffb71fe3b57b48f5109f83c62d263b1194681ff178fa; its bounded archive contains 455 regular files and all four deployment audit revisions bind the merged SHA. Live docs remain at source 6a821568db5c72983bd3990fe27c7990f092db12 (audit SHA-256 43c0159fc3ee9317a32e644e20d61d47d2fbf64d23194efe7b8e1f2b86514cd1). No docs deployment, release or installed-Server acceptance is claimed. The merged topic branch is no longer needed and is being removed. Remaining #215 tuple/publication gates stay open; SDK P0 #326–#332 retain priority.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingkind:cross-repositoryWork spans more than one public repositorykind:defectA public product behavior is incorrectpriority:P2Normal-priority product workrepo:sdk-phpOwned by the PHP SDK repositoryrepo:sdk-pythonOwned by the Python SDK repositoryrepo:sdk-rustOwned by the Rust SDK repositorystatus:readyReady for implementation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions