Repository navigation
fix: create stops its host and names the session on every error of its readiness wait - #294
Conversation
…ait, and check the SIGTERM handler comes before the manifest wait
…sion id on create errors
|
@codex review |
|
@codex security review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e99260072e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
…s first manifest write
|
@codex review |
|
@codex security review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
🛡️ Codex Security ReviewSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
# Conflicts: # .agents/skills/verify-session-lifecycle/coverage.json
# Conflicts: # .agents/skills/verify-session-lifecycle/coverage.json
Why
ThomasK33 asked to work every deferred follow-up of the first autopilot round until none is left. This PR fixes items 2 to 5 of #264, the follow-ups after #247 (for #209). Item 1, the Windows stop channel, comes in a second PR, which closes #264.
On Linux and macOS, a
createthat gives up on its host stops that host since #247. Three gaps were left. Errors in the readiness loop other thanHOST_UNREACHABLEandHOST_TIMEOUTrethrew without the stop, so a host could still serve a session whosecreatehad failed, the #209 leak (item 4). The create error envelope did not name the session (item 4). USAGE did not describe a stopped host or the cleanup timing (items 2 and 3), and no test or check pinned the stop after the host exits or the order of the host's SIGTERM handler (item 5).What changed
src/cli/commands/create.tswaitForReadyHost. It returns the create result, or throws.runCreateCommandwraps it in onetry. Every error of the wait, the last failedinspectincluded, callshost.stop()and then rethrows. A failed first manifest write insideallocateSessionkeeps its old path:createremoves the folder, and the host exits without spawning oncecreateexits. Examples are a manifest that is gone after the host answered, a manifest read that throws, and an error that is not aCliError.createstops the host only once the manifest names the program. The catch reads the manifest again for that rule, and a read error counts as no program.withSessionIdaddsdetails.sessionIdto the rethrown error and keeps its code, message,retryableand other details. An error that is not aCliErrorbecomesINTERNAL_ERRORwith the same message, as the top-level handler printed it before..agents/skills/verify-session-lifecycle)facts.mjsreadsCreateStopsOnGiveUpfrom thetryaroundwaitForReadyHost: its only statement is the wait, and its catch ends with the invariant, the manifest read, the platformifwithhost.stop(), andthrow withSessionId(error, sessionId).runHostregisters its SIGTERM handler beforewaitForManifestFromCreate(item 5). A handler after the wait, a catch without the stop, and a plainthrow erroreach readCreateStopsOnGiveUpas FALSE (checked by hand on three mutated copies).waitForReadyHostjoins the covered functions.CreateStopsOnGiveUpsection and the Scope list name the stopped host (item 2).docs/USAGE.md(items 2, 3 and 4),src/cli/commands/README.md,src/host/README.md.createunit tests, a golden envelope for the shape of acreateerror withdetails.sessionId,details.sessionIdin the give-up integration test, and 2launchHostunit tests (stop()signals a running host, and sends nothing and does not throw once the host has exited).Behavior changes for CLI and JSON users (automation-facing)
createerror after the session was allocated carrieserror.details.sessionId. Error codes, exit codes and the other details keys do not change. The error envelope'sdetailsis a free-form record (CommandError.details: Record<string, unknown>insrc/protocol/envelope.ts), so no Zod schema or message type changes. Thecreateunit tests (test/unit/commands/create.test.ts) and the give-up integration test (test/integration/lifecycle.test.ts) pindetails.sessionIdon the error thatcreatethrows. The golden envelope test pins only the envelope shape with that key.createthat fails after the launch for a reason other than an unreachable host now stops its host too (Linux and macOS, and on Windows once the manifest names the program). Before, such a host kept serving the session.Validation
Red first. At the tests-only commit (
915de003, which I ran asce427270before the rebase onto307c0e99), 7createunit tests failed: no stop on the other errors, nodetails.sessionId, and a rawTypeErrorinstead ofINTERNAL_ERROR. All pass on the head.launchHosttests: withstop()changed toprocess.kill(pid, 'SIGTERM'), both tests fail (the stop after the exit throws ESRCH). They pass on the head.Live, with the CLI (
node --import tsx src/cli/main.ts), an isolatedAGENT_TTY_HOMEandXDG_STATE_HOME, and a preload that delays the host's listen by 9 s, socreategives up after about 6 s:50860e8d50860e8d, rerun on307c0e99)createexit code and error codeHOST_UNREACHABLEHOST_UNREACHABLEerror.details.sessionIdcreateexits, then time todestroyeddestroyed, 0.02 sdestroyed, 0.02 s (3 of 3)destroying, thendestroyedafter 2.03 to 2.06 sdestroying, thendestroyedafter 2.08 to 2.10 s (3 of 3)runningat the exit and 3 s later,destroyedabout 6 s after the exitdestroySESSION_ALREADY_DESTROYEDSESSION_ALREADY_DESTROYEDrunningafter the exit and 3 s later, plaindestroyexit 6HOST_UNREACHABLEwith the group alive,destroy --forceexit 0 with the group and the host goneThe issue estimated "about 2 to 6 s" for item 3. The measurements show 0 to 2 s with a responsive host, and longer only while the host's start-up write is slow, so USAGE says that.
Lifecycle check (
.agents/skills/verify-session-lifecycle/scripts/check.sh --update-coverage) on the head: all 66 runs as expected, coverage synced ine9926007. The TLC constants thatfacts.mjsreads are the same as on main, so only the fingerprints ofrunCreateCommand,waitForReadyHostandfacts.mjschange. The model does not change.Gates on the head: typecheck, lint and format pass. Unit 1882/1882.
lifecycleandcliintegration 138/138 (vitest run --maxWorkers=1 --retry=2). CI runs the full suite. Live receipts:timing.sh,stopped.shanddelay-listen.mjswith their results, in the trail folder of this autopilot round.Round 2 (Codex round 1 on
e9926007, security clean): the code review found that the docs promised a stop anddetails.sessionId"after the launch", but a failed first manifest write inallocateSessiongets neither. That path leaves nothing to stop or name: the folder is removed, and the host exits without spawning oncecreateexits. Live, with a preload that fails that rename:createexits 8 withSTORAGE_WRITE_ERROR, no folder is left, the_hostis gone within 3 s, and no program ran.17143437narrows the comment, USAGE and the READMEs to errors after the first manifest write.createunit 19/19.Round 3, no Codex round (Codex round 2 on
17143437was clean in both lanes; root's conditional GO): merge of main142f7793(fix(host): keep sockets under a per-uid root and remove a dead host socket #288,390ed0c2, onlycoverage.jsonconflicted),b03c9823(thefacts.mjscomment says "every error of the readiness wait"),36c2bae0(USAGE:HOST_UNREACHABLEexit 6 after about 6 s,HOST_TIMEOUTexit 5 after about 10 s; measured live at 6.0 s with a delayed listen and 10.0 s with a host that accepts but never answers).check.shon the head: all 66 runs as expected,current23,479,528 distinct states andcurrent-no-token22,893,820, the same as SKILL.md.facts.mjsdrift 0. Unit 1914/1914.lifecycleandcliintegration 138/138.Merges of main
374937f9and0024ddfe(fix(host): read a group out of the CLI's pid space as running #291, fix(release): raise the Communique response token limit so release notes are not cut off #295, fix(host): read a terminal session next to the destroy marker as destroyed #284; merge64edbfdd, coverage4365f221), no Codex round (root's GO for merge-only deltas). Onlycoverage.jsonconflicted.check.shon the head: all 71 runs as expected,current25,534,376 distinct states andcurrent-no-token24,675,744.facts.mjsdrift 0. Unit 1937/1937.lifecycleandcliintegration 139/139. Typecheck, lint and format pass.Refs #264
Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:xhigh