Builder crash-restart resumes the pinned session instead of respawning fresh (PIR #1233) - #1356
Open
amrmelsayed wants to merge 21 commits into
Open
Builder crash-restart resumes the pinned session instead of respawning fresh (PIR #1233)#1356amrmelsayed wants to merge 21 commits into
amrmelsayed wants to merge 21 commits into
Conversation
…ions in both trees
…grade/re-mint behavior
…ware launcher names
… record consult outcome in review
Collaborator
Author
Architect ReviewAPPROVE (pr gate). Medium-high risk (every future Claude builder's launch path) — reviewed the full production diff, verified the post-consult worktree-mode test (06e8a9e), and independently ran the launch-loop suites: 107/107 green. What stands out:
With this, the jetsam-kill → builder-amnesia path reported on 2026-07-23 is closed end-to-end: a killed builder now costs 2 seconds and a nudge, not its memory. Architect review |
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.
PIR Review: Builder crash-restart resumes the session instead of respawning fresh
Fixes #1233
Summary
Builder
.builder-start.shwrappers previously handled any claude crash (notably the #1227 jetsam-SIGKILL class) by respawning a brand-new session with the original spawn prompt — total conversation amnesia, two seconds after every kill. This PR expresses the architect resume pattern (#832/#1264) in the generated bash: a session UUID is minted and pinned at spawn (--session-id), unnatural exits resume that conversation (--resumeplus a re-orientation nudge so the unattended builder acts instead of idling), three consecutive fast failures degrade to the historical prompt-replay under a re-minted id, and #1267's clean-exit-stays-fresh semantics are preserved but now crash-protected under a new id. Session-less harnesses (codex/gemini/opencode/custom) generate byte-identical scripts to before.Files Changed
packages/codev/src/agent-farm/commands/spawn-worktree.ts(+238 / -23) —buildSessionLaunchLoopstate machine,scriptSessionForms,CRASH_RESUME_NUDGE;startBuilderSession/buildWorktreeLaunchScriptwiringpackages/codev/src/agent-farm/utils/harness.ts(+20 / -0) — optionalnewSessionScriptFragment/resumeScriptFragmenton thesessionseam; Claude implementationpackages/codev/src/agent-farm/__tests__/pir-1233-session-launch-loop.test.ts(+241 / -0) — new executed-bash suitepackages/codev/src/agent-farm/__tests__/spawn-worktree.test.ts(+27 / -15) — Supportcodexas an architect #929/Builder launch loop: clean-exit relaunch should rerun the harness fresh (no --resume), matching architect semantics from #1264 #1267 assertions updated to the session-aware launcher names (intents preserved)packages/codev/src/agent-farm/__tests__/launch-loop-exit-code.test.ts(+4 / -2) — crash-branch message wordingcodev/protocols/pir/{builder-prompt,protocol}.md+codev-skeleton/protocols/pir/{builder-prompt,protocol}.md(+2 / -2 each) — crash-relaunch wording now describes resume semantics; both trees byte-identicalcodev/projects/1280-prompt-surface-judgment-not-ru/manifests/pir-1233-crash-resume.md(+17) — T16 manifest rows for the four prompt-bearing doc touchescodev/resources/arch.md,codev/resources/lessons-learned.md— routed updates (see below)codev/plans/1233-builder-crash-restart-loses-al.md,codev/state/pir-1233_thread.md— plan and thread artifactsCommits
8e4156c2[PIR Builder crash-restart loses all context: .builder-start.sh loop respawns fresh instead of resuming the session #1233] Crash restarts resume the pinned session instead of respawning fresh11e788c8[PIR Builder crash-restart loses all context: .builder-start.sh loop respawns fresh instead of resuming the session #1233] docs: crash-restart now resumes; update PIR loop descriptions in both treesd158f2fd[PIR Builder crash-restart loses all context: .builder-start.sh loop respawns fresh instead of resuming the session #1233] Test: execute the session-aware loop and assert resume/degrade/re-mint behavior05184d2e[PIR Builder crash-restart loses all context: .builder-start.sh loop respawns fresh instead of resuming the session #1233] thread: implement-phase notes6c020959[PIR Builder crash-restart loses all context: .builder-start.sh loop respawns fresh instead of resuming the session #1233] Test: update Supportcodexas an architect #929/shellper/launch loops: auto-restart should only trigger on unnatural exits — a deliberate quit should end cleanly #1241/Builder launch loop: clean-exit relaunch should rerun the harness fresh (no --resume), matching architect semantics from #1264 #1267 assertions to the session-aware launcher namesb4cdd57f[PIR Builder crash-restart loses all context: .builder-start.sh loop respawns fresh instead of resuming the session #1233] Manifest: register prompt-bearing doc touches for T16 (Spec 1280)Test Results
pnpm build: ✓ passpnpm test: ✓ pass (4,406 passed / 48 skipped; 13 new executed-bash tests)claude -p --session-id <uuid>thenclaude -p --resume <uuid> "<prompt>"— context restored (codeword round-trip) and the positional nudge prompt processed as the next turndev-approvalgate (code + generated-script walkthrough; live kill -9 test procedure provided)Architecture Updates
Routed COLD (
codev/resources/arch.md, Agent Farm Internals): a new paragraph "Builder crash restarts resume the pinned conversation (#1233)" alongside the existing #832/#1145 architect-resume paragraph — covering the pin-at-spawn/resume-on-crash state machine, the nudge rationale, the fast-fail degrade,.builder-session-idwith bash as sole writer (consumption deferred to #1112), session-less byte-identity, and why the machinery lives in generated bash (builder PTYs outlive Tower). Not HOT: this is subsystem mechanics to consult when touching spawn/recovery, not a fact that should steer every decision; the hot cap is better spent on its current entries.Lessons Learned Updates
Routed COLD (
codev/resources/lessons-learned.md, Protocol Orchestration):--resumerestores the transcript, not the momentum — unattended agents need a turn trigger (the nudge prompt) or a context-loss fix silently becomes a stalled-lane incident. Not HOT: narrow to agent-resume design, below the cross-cutting bar.Things to Look At During PR Review
buildSessionLaunchLoop,spawn-worktree.ts) is the subtle core: the degrade path must never--resumea stale id after falling back to an unpinned launch (guarded by the launcher-name check), and the clean-exit re-mint must happen after thereadso a vanished terminal (EOF) never mutates state on the way out. The executed-bash tests pin both.{exitCode: 0, signal}. All new tests execute real bash and assert wrapper-layer codes only..builder-session-idat spawn; the bash script is the sole writer (runscodev_persist_session_idbefore the first launch). One writer beats two writers of the same value..builder-prompt.txt/.builder-role.md(edits land only on a clean-exit relaunch), and crashes no longer accidentally "solve" a near-full context window (useafx resetfor that)..builder-session-idjoins the existing untracked.builder-*family (a.builder-*gitignore is a candidate follow-up for Unify builder conversation resume onto persisted session IDs (harness.session), retiring the jsonl-discovery heuristic #1112); the degrade message wording is imprecise when the pinned-fresh launcher is itself the fast-failing one (behavior correct, wording only).How to Test Locally
pir-1233→ View Diffcd .builders/pir-1233/packages/codev && pnpm exec vitest run src/agent-farm/__tests__/pir-1233-session-launch-loop.test.tspnpm build && pnpm -w run local-installfrom the worktree):.builder-start.shcontainscodev_launch_resume()and.builder-session-idholds its UUIDkill -9its claude pid → "Resuming the conversation in 2 seconds…" → ask for the codeword back.builder-session-id~/.claude/projects/<encoded-worktree>/,kill -9→ three fast resume attempts, then fresh prompt-replay relaunchNotes
.builder-session-idformat (one lowercase UUID + newline) becomes a soft contract for Unify builder conversation resume onto persisted session IDs (harness.session), retiring the jsonl-discovery heuristic #1112, which owns making--resume/recover consume it in place of mtime discovery.