Skip to content

CI: admit a killed author's unsent poll in the corrected clock contract - #763

Merged
rmcdaniel merged 2 commits into
mainfrom
rust-325-ci-clock-unsent-poll
Oct 25, 2026
Merged

rmcdaniel merged 2 commits into
mainfrom
rust-325-ci-clock-unsent-poll

Conversation

@rmcdaniel

Copy link
Copy Markdown
Member

Fixes the corrected-cohort python-clock-genuine-one flake (false !== true after the published PHP portable record passes). It has occurred twice: run 40151134683, and run 40206210357 on #762. It's classified on #754 (comment 6399755214).

Cause

tests/Fixtures/ServerParityProfiles/corrected-markers/python-clock-genuine-one.json declares "cancel_unsent_original_polls": true: the SIGKILLed original Python author may have polls in flight that end before the observing proxy forwards them. Only corrected-marker-contract.mjs implemented that. corrected-clock-contract.mjs still required every client-cancelled poll to show request_body_complete=true and upstream_request_started=true.

In run 40206210357 the published PHP clock record's requests[34] POST /api/worker/activity-tasks/poll 0 client_cancelled=true had neither flag set. It sat between the original's registration ([15]), its durable admission ([29]) and its explicit retirement ([35] DELETE …workflow:original). The PHP server never received that request.

Change

  • scripts/conformance/server-parity/killed-author-poll.mjs (new): the corrected-marker contract's unsent-poll branch, moved unchanged into checkUnsentKilledAuthorPoll. An unsent poll is admitted only when all of these hold:
    • the fixture declares cancel_unsent_original_polls;
    • the author is Python, stopped by SIGKILL, with exit code -9;
    • the route is a declared no-result poll;
    • it carries no bytes, no response and no forwarding;
    • it falls after the original's real registration and recorded durable admission, and before its explicit retirement.
  • corrected-marker-contract.mjs calls it in place of the inline branch; its other checks are unchanged. corrected-clock-contract.mjs calls it for a cancelled poll that was never forwarded, and keeps its existing checks for every forwarded one.
  • corrected-markers/check-clock-readers.mjs gains the corrected-marker reader's unsent-cancellation counterexamples, plus one more ("after original retirement"). They run on any actual clock record that contains such a poll.
  • tests/Unit/ServerParityKilledAuthorPollTest.mjs (new; in the path filter and the comparator list): the failing record's shape passes for each poll route. Each of 19 counterexamples is refused, including a received body, invented bytes, forwarding or response, a missing or foreign registration, a missing or unrecorded admission, a missing or earlier retirement, an undeclared fixture, a graceful shutdown, another producer, a living author and an undeclared poll kind.

Qualification

  • New unit test 2/2 (19 refusals). Comparator node tests 2241/2241. All four changed modules pass node --check. Docker workflow isolation policy passes.
  • No native, shared or frozen implementation changes and no fixture changes. The corrected-marker contract's behavior is unchanged; only its code moved. CI runs the corrected-markers and clock profiles on every database.

🤖 Generated with Claude Code

rmcdaniel and others added 2 commits October 25, 2026 15:55
python-clock-genuine-one declares cancel_unsent_original_polls, but only
the corrected-marker contract implemented it. The clock contract required
every cancelled poll to have reached upstream, so a SIGKILLed original
author whose activity poll ended before the proxy forwarded it failed the
published PHP clock record (Server #754: runs 40151134683 and 40206210357,
request 34 of the latter).

Move the corrected-marker contract's unsent-poll branch, unchanged, into
killed-author-poll.mjs and call it from both contracts. An unsent poll is
admitted only for a declaring fixture, a SIGKILLed Python author, a
declared no-result poll route, no bytes and no response, between the
original's real registration and durable admission and its explicit
retirement. The clock reader controls gain the corrected-marker reader's
unsent-cancellation counterexamples, and a unit test covers the shared
check and each refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ock-unsent-poll

The path filter and the comparator node test list keep both sides' new
tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel
rmcdaniel merged commit be19bd9 into main Oct 25, 2026
62 checks passed
@rmcdaniel
rmcdaniel deleted the rust-325-ci-clock-unsent-poll branch October 25, 2026 16:39
rmcdaniel added a commit that referenced this pull request Oct 25, 2026
…dec-one-job

The comparator node test list keeps main's killed-author poll test and this
branch's codec deadline cell test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@rmcdaniel

Copy link
Copy Markdown
Member Author

Cloud bounded wrapper review of exact fecc5bf24cfc27626b906d3667bda29dcf8d6ac8 (now merged): no finding in the shared killed-author-poll.mjs, the two changed contract call sites, or the clock-reader mutation controls.

The unsent branch requires the declared Python/SIGKILL case, author exit -9, a declared no-result poll, no received request/response bytes or forwarding, preceding original-worker registration and recorded durable admission, and subsequent explicit retirement. It returns no request authority. The clock caller retains transport checks; forwarded polls keep their existing path.

Independent verification: both helper unit tests passed, including all 19 refusal cases, in an isolated Node 22.23.4 container. The clock-reader source was reviewed but was not executed against records. This review covers the outer wrapper and fake controls only; it makes no new runtime, payload, or publication claim.

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