Skip to content

Prepare native timer-redrive workflow clock checks - #323

Merged
rmcdaniel merged 2 commits into
mainfrom
sdk-python/980-redrive-timer-clock
Nov 13, 2026
Merged

rmcdaniel merged 2 commits into
mainfrom
sdk-python/980-redrive-timer-clock

Conversation

@rmcdaniel

@rmcdaniel rmcdaniel commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Prepare the Python workflow definition for Server #980's completed-activity, fired-timer and later-failed-activity cohort. The same definition retains the original timer clock across redrives, and disables automatic retries for the later activity so its failure boundary stays observable.

Six synthetic replay checks cover fresh reconstruction, repeated redrive with immediate-predecessor metadata, missing/foreign timer-clock refusal, fractional clock preservation and completion. The fractional case compares a whole-second producer-shaped reuse timestamp against an exact source timestamp with .654321: the published reader loses the fraction in the former prefix and preserves it in the latter. They reuse an existing immutable protocol sample without claiming native producer or actual-Worker acceptance. No SDK implementation or package version changes.

Validation: 269 focused tests and Ruff pass. The original five replay checks and the new fractional case also pass using the already-installed published Python 2.17.2 package. Actual-Worker/cold-process execution remains pending Server's immutable qualified producer receipt after its precision correction; no image was selected and no runtime launched.

Refs durable-workflow/server#980 and its selected qualification packet durable-workflow/server#980 (comment).

@rmcdaniel

Copy link
Copy Markdown
Member Author

Exact successor b17bae5f7b41379a3b67294aa0e211c828c4e57d adds the requested offline reader/fixture proof. With published registry-installed Python2.17.2, a source timer time 2026-11-03T00:00:06.654321+00:00 and a whole-second reused_recorded_at yield 2026-11-03T00:00:06.000000+00:00. The otherwise identical exact fractional reuse prefix yields the original .654321 clock. Keeping fractional fired_at in both prefixes does not repair the authoritative reuse timestamp. The histories remain unchanged by replay, and each produces only the later activity command.

The new case passes directly in the existing registry-installed2.17.2 environment with its package origin checked under that environment's site-packages. All269 focused source checks and Ruff pass. The workflow definition is byte-identical to the earlier preparation, SHA256 af24e69d5d4ed57e3cb56915a5e2febe535438e8bb2b33ecfd998098c1557b2b.

No actual Worker, cold process, native producer, image selection or runtime experiment ran. The installed cohort remains pending the precision-corrected producer's immutable qualification/publication receipt. This comparison identifies fixture-reader consequences and does not claim that an unpublished producer was installed or that a new SDK release is needed.

@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Bounded producer-contract source countercheck PASS at b17bae5f7b41379a3b67294aa0e211c828c4e57d.

The unchanged workflow definition captures replay_now() immediately after its plain timer and passes that clock to the later activity, whose retry budget is explicitly one. The successor controls reuse the completed first activity and timer without issuing them again, keep the first timer clock on repeated redrive, reject missing or foreign-predecessor reuse authority, and preserve the supplied history. The new nonzero-fraction comparison changes only the authoritative reuse timestamp between the two prefixes. Fractional fired_at remains present in both. That isolates the producer's rounding defect rather than teaching the reader to infer an alternate clock.

This agrees with the published reader's reuse-time precedence and the correction in Server #1215: copy the full original event time on first reuse, preserve existing reuse metadata on repeat, and retain the immediate predecessor relationship. No SDK production code changes here. I reviewed the two-file source delta; the registry-only execution is the separately attributed owner receipt above. No Worker, cold process, native producer execution, image selection or installed-cohort qualification is inferred. The actual unchanged-definition cold-worker cohort remains gated on the precision-corrected immutable producer receipt.

@rmcdaniel
rmcdaniel marked this pull request as ready for review November 13, 2026 21:14
@rmcdaniel
rmcdaniel merged commit dbb4311 into main Nov 13, 2026
20 checks passed
@rmcdaniel
rmcdaniel deleted the sdk-python/980-redrive-timer-clock branch November 13, 2026 21:15
@rmcdaniel

Copy link
Copy Markdown
Member Author

Preparation delivered through the normal merge path at dbb4311b7e71050e4ddc552c8a775224ecba429b (2026-11-13 21:14:56 UTC). All20 exact-head checks passed, including Python3.10–3.15, integration, corpus, package, Sonar, CodeQL, action policy and target-branch qualification. The bounded producer-contract countercheck binds reviewed b17bae5f.

Accepted main equals the merge commit and its tree 00b11a82a9df3e7743e825f71ac2e9afbe311fbd exactly matches that reviewed head. The merged remote branch was deleted after an exact-head check, and absence was verified.

The prepared workflow's SHA256 remains af24e69d5d4ed57e3cb56915a5e2febe535438e8bb2b33ecfd998098c1557b2b. Published Python2.17.2 offline fixture/reader observations retain their recorded scope. Actual Worker/cold-process and repeated-redrive qualification still require the precision-corrected immutable producer/platform/source receipt on Server980. No image was selected, no runtime ran and no SDK release is needed for this test-only preparation.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The corrected native producer dependency is now available: Server's qualified 3.11 cohort handoff binds source da38c0ede9b15046fcab2bb0f25412c85a3e3404, index sha256:39d218fc5f251a3e7c4ff1dcda06d9cc53f66c034f0c6d0f67e8371fd0cc97d6, amd64 child sha256:8bc8400c4ff203c1e4d5c7f82028cfa1d429ab00a47a6e698453d8345ae4bcfc and config sha256:1f72415d494737c9ae4b5f7d2a18cc8d152de07d1279513ff3dd7ab7d586cfef.

Python's existing offline reader proof and unchanged workflow definition remain the preparation authority from this PR. Next is the independently reviewed published-package actual Worker/cold-replacement adapter, after the ordinary consumer profile in #324 clears its current exact-source review. It must preserve the observed nonzero-fraction source TimerFired and original history, compare parsed full-precision instants after first and repeated redrive, and show only the failed activity executes again with no timer work. No runtime was launched, no installed timer result is claimed, and no unchanged SDK release is needed for version alignment.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The ordinary published consumer profile prerequisite is now resolved: exact installed activity-identity cell and independent retained-evidence PASS. It used the normally installed 2.17.2 wheel, a complete hash-locked private environment, retained SDK inventory, captured runtime/consumer/network authority and independent full-ID/label cleanup. That result's Server 3.9.2 tuple is unchanged and supplies no timer-redrive evidence.

The qualified native 3.11 producer handoff is also current. The next Python action is therefore to freeze the actual cold-Worker first/repeated-redrive adapter using that exact 3.11 index/platform/source and the unchanged definition already accepted here. It must preserve original published history, observe a nonzero fractional TimerFired, compare parsed full-precision instants, prove reuse/lineage and failed-activity-only callbacks, and keep each Worker in a fresh process. The adapter/changed tuple still need their own source, normal checks and runner review before any timer cell; no runtime selection or launch occurred in this preparation update. The remaining SDK211 portal prose correction is currently in SDK326 and is independent of this runtime profile.

@rmcdaniel

Copy link
Copy Markdown
Member Author

The actual cold-Worker adapter is now concrete in draft SDK327, frozen 830ae6b38d318c42e5051abaa0d22fc465cf981a / tree 3003952b2171cbb75d7c58dc9bf0beef3f711b3a. It uses the unchanged definition accepted here and the qualified published SDK 2.17.2 / native 3.11 tuple, with three fresh Worker processes for source, first redrive and repeated redrive. The existing closed installed consumer profile supplies complete hash-locked wheels, retained SDK inventory, the same two owned internal-network containers and independent ID/label cleanup.

184 offline contract/ownership/inventory controls and Ruff pass, including exact fractional clock versus truncation, immediate predecessor/new timer pair, original-start/result/history scope, no extra emitted timer command or callback, and pre-child source binding. The real case only collects outside manual admission. Current Python matrix, package, corpus, CodeQL and Sonar checks pass; normal integration and exact Security/Server contract reviews are pending. No local SDK/native runtime launched and no installed timer result is claimed. SDK327 holds the complete source/runner review and later ordinary manual execution; database timer/task invariants remain explicitly with the qualified producer instead of being inferred from public history.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant