feat(babysitter): resume the previous wake's agent session on a reused box (F4)
Rebased on main after #635 and #636 merged; the diff is the Babysitter part only: examples/babysitter/{fix,fixer}.ts, the tests, FIXER.md, the rebuilt fixer artifact and the evidence.
This is the last piece of Khaliq's ask: on a wake for new PR feedback, the same sandbox, the same checkout and dependencies, and now the same agent session, so the agent keeps the earlier wake's reading of the code on top of the original intent.
Behaviour
- Recording:
stashCheckoutwrites the agent'ssessionIdbeside the PR checkout cache, or removes it when the agent reported none, so a stale session is never kept. - Restoring:
restoreCheckoutreturns that session only when it restored the checkout on this box. - Resuming: the fixer resumes the session when it belongs to the origin's CLI, and never resumes another CLI's session.
- Fallback: a session the CLI no longer has fails that step (Claude: "No conversation found"). The run then continues with a fresh
babysitter-fix-freshagent, which carries the origin context in its task either way. A stale session can't fail a run. - Audit: the cli/model pairs stay literal.
resumeis a plain property, becausef.agenttreatsundefinedas absent, so the unmodified shipped-source audit resolves every call.- My first attempt used a conditional spread, which the audit refused as unprovable. That capture is
evidence/f4-fixer-resume/05a.
- My first attempt used a conditional spread, which the audit refused as unprovable. That capture is
Evidence (examples/babysitter/evidence/f4-fixer-resume/)
Red, before the adoption:
✖ a restored PR checkout brings back its session, and a stash records the new one (1.970079ms)
✖ a session the CLI no longer has falls back to a fresh agent with the origin context (0.599917ms)
✖ a wake on a reused box resumes the previous agent session and records the new one (0.856034ms)
✖ failing tests:
ℹ fail 3
ℹ pass 26
02: 145 tests, 138 pass, 0 fail, 7 todo.03: digests reproduce. Standalone is unchanged at580bab1d…; fixer is23ad283edac047a601f40f62da3f82baf6466ccd834dae7806e5b002da8b5e5b.04:flows checkpasses, run with #636's SDK build because this worktree's build predates the option.05: shipped-source audit 2/2, file unmodified.06:filtered-count=0.
Rollout notes
- The fixer runs on the sandbox's installed SDK. An SDK without #636 drops
resume(it builds the step spec from an explicit list), so that wake simply starts fresh. Resume takes effect once a release with #636 is in the sandbox image. - cloud#4348 (merged) already pins this fixer digest,
23ad283edac047a601f40f62da3f82baf6466ccd834dae7806e5b002da8b5e5b;node examples/babysitter/build-standalone.mjs --checkreproduces it at this head.
🤖 Generated with Claude Code
Summary by cubic
Makes the Babysitter fixer resume the previous wake's agent session when it restores the PR checkout in a reused sandbox, so a later step continues the CLI session an earlier step recorded instead of starting cold.
Babysitter fixer adoption
stashCheckoutrecords the run'ssessionIdbeside the PR checkout cache and removes it when the agent reported none;restoreCheckoutreturns it only when it restored the checkout on that box.- The fixer resumes the session only when it belongs to the origin's CLI; a session the CLI no longer has falls back to a fresh agent that still carries the origin context, so a stale session can't fail a run.
- On a sandbox whose SDK lacks
resume, that wake simply starts fresh.
Agent Relay sessions
claudesession497569fc· opened viagh pr create· last active 2026-10-09
[!NOTE]
Medium Risk
Changes cross-run agent dispatch and persists session IDs on the sandbox filesystem; behavior depends on SDK resume support (#636) but falls back to a fresh agent when resume fails or the CLI mismatches.
Overview
On a reused sandbox, the Babysitter fixer now continues the previous wake’s agent session alongside the cached PR checkout, so follow-up fixes keep the earlier code context plus the original task intent.
Checkout cache: stashCheckout writes checkout.session.json with { cli, sessionId } (or deletes it when the agent reports no session). restoreCheckout returns that session only when it successfully restores the cached checkout. restore / stash wrappers pass session data through the journaled f.run steps.
Fixer flow: After restore, the fixer calls f.agent('babysitter-fix', …, resume) when the cached CLI matches the origin source; otherwise it starts cold. If resume throws, it logs and retries with babysitter-fix-fresh (same task/origin context, no resume). The run’s new sessionId is stashed in finally for the next wake.
Docs, tests, artifact: FIXER.md documents session resume; fixer.test.ts adds restore/stash/resume/fallback cases; the bundled fixer artifact and manifest digest are updated; evidence/f4-fixer-resume/ captures red→green test output.
Reviewed by Cursor Bugbot for commit 5b5f5a02830e94d8e41521c72d0f768e1611e702. Bugbot is set up for automated code reviews on this repo. Configure here.