fix(supervise): heal a released slot the sweep's process died before recording - #1265
Merged
Merged
Conversation
…recording A release sweep appends a retained child's environment-teardown receipt and then its terminal record. A process that died between the two left an open cursor slot beside a destroyed environment; the next resume treated the node as interrupted, tried to recover an executor whose environment was gone or left it open forever, and every reader charged the ceiling the pool had already refunded. The reconciled record now carries the settlement the driver received (reason, infra, trace, outRef, providerModel, harnessTranscript), the withheld overspend, the cancellation source, and settledSeq, the cursor seq next() stamped on the delivery, through the same field spread the terminal record uses. On the root resume, healReleasedSlots walks the journal forest and, for a spawned node with no terminal record whose receipts after that record all read destroyed: true and name the environment its last admission named, writes the released record with the sweep's own builder at settledSeq and the reconciled at, then emits the sweep's agent.child event. The node is never interrupted and no recovery is attempted. A destroyed: false receipt, an empty receipt set, a receipt for an unadmitted environment, or a reconciled record without settledSeq leaves the slot open as before. The resumed cursor starts past every open node's settledSeq; a journal that already closes that seq fails the resume and writes nothing. terminalDownEvent, settledNodeEvidence and the release payload move to supervise/terminal-record.ts so scope.ts and recover-executors.ts share one builder without a runtime import cycle. The refund at the reconcile is unchanged. Version 0.234.0: SpawnEvent's shape moved. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit c5b7b69c7f0dacbb805ce767e2a05598d117527e)
…q past the reserved floor Independent check of the heal found the recorded-result branch of prepareInterruptedExecutors seeding its seq one past the last CLOSED record only, while the resumed scope's cursor already folded open nodes' reserved settledSeq. A recorded result could therefore be journaled on the seq an open retained node had reserved, exactly the collision the heal refuses. One reservedCursorFloor(events) now seeds both; a test pins the shape (open node at settledSeq 1, recorded result settles at 2) and fails on the closed-only floor. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 00de2dd31a811330b2c9e700f2562b51ec81d8c4)
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Contributor
Author
|
Cutting v0.234.0 at the merge commit now (tip of |
Contributor
Author
|
Published: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes the window 0.233.0's CHANGELOG stated and did not try to heal: a release sweep appends a retained child's
environment-teardownreceipt and then its terminal record, and a process that died between the two left an open cursor slot beside a destroyed environment. The next resume treated the node as interrupted, tried to recover an executor whose environment was gone or left it open forever, and every reader charged the ceiling the pool had already refunded.Why a resume could not heal it before
The released record's
seqis the cursor seqnext()stamped on the delivery the driver saw, and it lived only in memory: no record for an open node carried it. A resume could invent one (and areason, and atrace), which would place the record where the driver never saw it and claim things that never happened. So:reconciledrecord now carries the settlement the driver received (reason, infra, trace, outRef, providerModel, harnessTranscript), the withheld overspend, the cancellation source, andsettledSeq, through the same field spread the terminal record uses.healReleasedSlotswalks the journal forest and, for a spawned node with no terminal record whose receipts after that record all readdestroyed: trueand name the environment its last admission named, writes the released record with the sweep's own builder atsettledSeqand the reconciledat, then emits the sweep'sagent.childevent. The node is never interrupted; no recovery is attempted.destroyed: falsereceipt, an empty receipt set, a receipt for an unadmitted environment, or areconciledrecord withoutsettledSeq(every one written by 0.230.0–0.233.1) leaves the slot open exactly as before. A journal that already closes that seq fails the resume and writes nothing.terminalDownEvent,settledNodeEvidenceand the release payload move tosupervise/terminal-record.tsso scope and resume share one builder without a runtime import cycle. The refund at the reconcile is unchanged.reservedCursorFloor(closed seqs and open nodes'settledSeq). The independent check found the recorded-result branch seeding past closed records only; a test pins the collision and fails on the old seed.Process
Two independent designs → judge (from source, the seq rule above) → implement → independent check (sound, one defect, fixed in the second commit with a mutation-verified test).
Evidence
typecheck,biome,build,api-surface,docs:api(0 warnings),docs:freshness,check:version-bump(1 export change → 0.234.0,release:prepareapplied),check:publish-workflowall exit 0.merge-treeclean againstmain.🤖 Generated with Claude Code