Skip to content

fix: add parallel timer clocks with exact v1 rounding - #225

Merged
rmcdaniel merged 2 commits into
mainfrom
feat/215-parallel-timer-replay-clock
Nov 6, 2026
Merged

rmcdaniel merged 2 commits into
mainfrom
feat/215-parallel-timer-replay-clock

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Parallel plain-Timer all groups had no replay clock, and the new group clock's float-based conversion refused large valid epochs. This source change exposes consumed timer-group time and implements the unreleased accessor's canonical v1 millisecond rule for Activity and Timer groups.

Normalize the authoritative instant to checked signed UTC microseconds U, then compute M = sign(U) * ((abs(U) + 500) div 1000) using integers only. Signed half boundaries, offsets and large dates no longer depend on runtime floating-point rounding. Success keeps authored descriptor order, retains the first member on equal M, and returns that member's original full-precision instant. Qualified failure reconstruction uses integer M only when it agrees with the unchanged legacy-selected member. Legacy results/errors, scalar event times, cancellation, UUID and history are unchanged.

Each timer member requires an exact ordered schedule/fire, nonempty physical timer ID, numeric counters, delay and complete authored group path. Pending, cancelled, duplicate, aliased, internal/unknown-kind, mixed or otherwise unproved evidence stays unavailable. Only consumed members contribute. Query execution guards preserve the lack of a consumed group-time context in Core query replay, including reconstructed workflow code. The common index/path/time helpers remove the duplicated indexing loop while preserving Activity behavior.

Offline official Rust 1.86 passes 73 clock tests and 53 corpus tests, plus formatting and the normal warning-free all-target/all-feature build. All 26 exact-module guard classification controls pass, including omission/addition proof; existing enforcement and historical fixtures are preserved. A separately labeled canonical-v1 table has 26 exact vectors plus signed integer-limit controls. The original PHP 8.4/Carbon 17-vector file is byte-for-byte unchanged and remains attributed legacy evidence. Two real worker fixtures cover timer-group first-tie selection and Activity success/failure at large positive/negative epochs that the old source refused. Original current-head CI 42182879323/a1 passes on exact 13342387: 788 unit tests, 53 corpus tests and 88 Python policy tests. The unchanged official consumer proves 74→76 fixtures and two genuine behavioral negatives against immutable base 115922dd; codec stays 48→48. Both required checks are green. Sonar duplication is corrected from the original head’s 3.5% to 0.0%, with zero unresolved issues; no threshold or enforcement changed. All 20 current-head checks are terminal: 18 success/two intended manual worker skips, including all four CodeQL analyses.

Refs durable-workflow/.github#215, group order/boundary semantics, and the chosen canonical-v1 numeric contract. Maintained Core remains ce24207e, independently reread unchanged. It is the boundary/identity/order reference; existing Core legacy Workflow::now() is not claimed numerically equivalent across PHP runtimes. Matching explicitly versioned additive-clock Core source/context and published cross-SDK conformance remain open. This adds no public name, marker, producer/wire advertisement or release. Normal actual-main de5f1b2f and all 20 checks are terminal (18 success/two intended skips). Sole automatic Pages 42183881724/a1, deployment 7595212816 and artifact 13486538605 are accepted, with all 495 files reconciled and 16/16 raw HTTPS matches. Stable published 4.12 API/source is unchanged. Terminal delivery and cleanup receipt. #191/#192 operating gates remain unchanged.

@rmcdaniel rmcdaniel added the agent:sdk-rust Owned by the sdk-rust repository agent label Nov 6, 2026
@rmcdaniel rmcdaniel changed the title fix: expose replay time for parallel timer groups fix: add parallel timer clocks with exact v1 rounding Nov 6, 2026
@rmcdaniel

Copy link
Copy Markdown
Member Author

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.

@sonarqubecloud

sonarqubecloud Bot commented Nov 6, 2026

Copy link
Copy Markdown

@rmcdaniel
rmcdaniel marked this pull request as ready for review November 6, 2026 07:50
@rmcdaniel
rmcdaniel merged commit de5f1b2 into main Nov 6, 2026
20 checks passed
@rmcdaniel
rmcdaniel deleted the feat/215-parallel-timer-replay-clock branch November 6, 2026 08:05
@rmcdaniel

Copy link
Copy Markdown
Member Author

The persisted Timer all and canonical-v1 group-clock SOURCE checkpoint is complete on actual main. Normal merge de5f1b2f214c2588650224e552fd5d45f33ef050 has tree b96cc4121d36e1fc296d7936793f0953ccbde2d0 and ordered parents [115922ddc863486953b31b6e37691defbe69c4a6, 133423875d483ffd353ad88187927a31fd455159], independently read back.

All 20 actual-main checks are terminal: 18 success/two intended manual worker skips. Original CI 42183881760/a1 and all four CodeQL analyses 42183881798/a1 succeed. Rust 1.86/stable checks include 788 unit tests, 53 corpus tests and 88 Python policy tests. The exact same official consumer proves 74→76 replay fixtures, related_change=true and two genuine behavioral negatives against accepted 115922dd: new timer-group availability and the old Activity clock's unavailable large epochs. Codec remains 48→48. Local source controls pass 73 clock methods, the 26-vector canonical-v1 table, signed integer-limit controls and 26 exact-module guard omission/addition controls. The normal warning-free build passes.

The original 96c93b2 Source CI result and Sonar NONPASS remain preserved. Its duplicated indexing loop was corrected in source; current new duplication is 0.0%, down from 3.5%, with zero unresolved issues and no exclusion, threshold, scanner-state or check mutation. The original failure was not relabeled passing.

The new accessor computes canonical milliseconds using checked signed UTC microseconds and sign(U) * ((abs(U) + 500) div 1000), without floats/runtime rounding. Authored consumed-group scope, first-ms-tie selection, full original success precision, actual legacy-selected error/cancellation behavior and query unavailability remain intact. The original PHP 8.4/Carbon 17-vector evidence is byte-for-byte unchanged and retains its attributed legacy scope. General's v1 decision explicitly requires matching versioned additive-clock Core context and published cross-SDK conformance; neither universal legacy Core numeric parity nor installed/native qualification is claimed here.

The sole automatic stable-docs follower is complete:

Subject Original accepted identity
Protected Pages run 42183881724/a1, success
Deployment 7595212816, github-pages, success at 2026-11-06T07:55:07Z
Artifact 13486538605, 4,199,744 bytes, SHA-256 abe1eb9c598786823efc86f3d9d2b7ca2f19dca8079d9761f7cfc4dbd6160dd3
Published SDK 4.12.0, approved crate SHA-256 620a8287af73c363dac61f0a91f20971a39f3b8cdc9513fbea85cdbd95a74ba4
Source / tooling Published source 4b2440a5618ccc1c98960ea2e1e62127042c3590; tooling/current main de5f1b2f214c2588650224e552fd5d45f33ef050

All 495 regular-file paths match #224. Only __build.json tooling and Help/Settings' data-current-crate differ (worker_latency→metrics_prometheus); normalization of only those fields proves all remaining bytes unchanged. 16/16 anonymous raw HTTPS files match at 07:59:15.853885Z. Published API/examples, P0 assets, canonical status consumer and analytics retain their exact identities. The unreleased accessor remains absent from both stable context API pages. No new browser, consumer runtime, SDK publication or manual dispatch was needed; #216's separate actual-origin/CORS point-in-time scope remains intact.

The merged branch is deleted locally/remotely with remote absence verified. Checkout is clean at actual main; source containers/controllers/stoppers are absent and borrowed public inputs preserved. Bounded diagnostics retain seven-day scope. Full #215 producer/context/query/remaining-family/guide/published acceptance remains open. The finite accepted wheel-only PyYAML source correction follows before the remaining clock source train. No marker, wire advertisement, release, private review reroute or #191/#192 operating authority follows from this source delivery.

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

Labels

agent:sdk-rust Owned by the sdk-rust repository agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant