Skip to content

feat(tui/subagent): resume interrupted children from checkpoint via followup - #5242

Merged
Hmbown merged 1 commit into
Hmbown:mainfrom
SparkofSpike:codex/harness-checkpoint-resume
Aug 6, 2026
Merged

feat(tui/subagent): resume interrupted children from checkpoint via followup#5242
Hmbown merged 1 commit into
Hmbown:mainfrom
SparkofSpike:codex/harness-checkpoint-resume

Conversation

@SparkofSpike

Copy link
Copy Markdown
Contributor

Summary

agents/followup on an interrupted_continuable child used to queue a dead-letter: the checkpoint was preserved and its continuation_handle returned, but nothing could actually resume the run — long tasks (document review, multi-step search) interrupted mid-way had to be re-dispatched from scratch, wasting tokens and time. This change wires checkpoint-based continuation: followup now re-dispatches a fresh agent loop seeded with the original prompt plus the checkpoint message tail and the follow-up text, under a new agent id, while the prior terminal record stays immutable.

Process: necessity review (scout) confirmed no resume substrate existed on main; implementation went through two adversarial review rounds (3 majors fixed: duplicate-resume idempotency, cwd-claim double-namespacing, runtime-posture widening).

Changes

  • resume_from_checkpoint (SubAgentManager, mod.rs): re-dispatch via spawn_background_with_assignment_options with the interrupted child's agent_type/assignment/allowed_tools/model restored.
    • Idempotency: resume_targets map (old id → resumed id) — a repeated followup returns the existing target and forwards the message to it (never silently dropped).
    • Spawn-seam fidelity: child runtime via background_runtime() (depth +1, detached cancellation), depth ceiling checked before derivation; workspace restored to the interrupted child's directory; write claim restored from the coordination ledger (pre-namespaced, isolation flag preserved); runtime posture (read_only / denied tools / shell) preserved from the worker record instead of rebuilt from the caller's role.
  • checkpoint_messages_to_text / build_resume_prompt: serialize the checkpoint message tail into a resume prompt ([RESUMED SESSION — checkpoint …] + prior conversation tail + parent follow-up).
  • AgentsFollowupTool (coord.rs): optional SubAgentRuntime via with_runtime; execute routes interrupted_continuable children with a runtime attached to the resume path, keeping honest queue-only semantics otherwise. Both registration points (AgentTool followup action, register_coordination_tools) attach the runtime.
  • Tests: 5 manager tests (seeded resume, workspace restore, idempotency with message forwarding, reject non-interrupted, reject missing continuable checkpoint) + 2 coord tests (queue-only without runtime, resume with runtime). stub_runtime made pub(crate).

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Tests

Testing

  • cargo fmt --all -- --check
  • cargo clippy -p codewhale-tui --bin codewhale-tui (no new warnings; only the pre-existing mcp.rs:262 warning inside a #[cfg(windows)] block, invisible to the ubuntu CI runner)
  • cargo clippy --workspace --all-targets --all-features --locked (warning-free under the CI allow list) — not run locally; CI will run it
  • cargo test -p codewhale-tui resume_from_checkpoint (4/4 pass) and cargo test -p codewhale-tui followup_interrupted_continuable (2/2 pass)
  • cargo test -p codewhale-tui tools::subagent (392/392 pass)
  • cargo test --workspace --all-features --locked — not run locally (heavy); CI will run it

Checklist

  • Updated docs or comments as needed
  • Added or updated tests where relevant
  • Verified TUI behavior manually if UI changes (N/A — no UI change; resume path exercised via unit/coord tests)
  • Harvested/co-authored credit uses a GitHub numeric noreply address (no human co-authors; agent assistance noted in commit body)

Related Issues

No-Issue: harness improvement backlog item (sub-agent checkpoint resume), no public issue number. Necessity-review and two review rounds performed as part of the implementation workflow.

…ollowup

agents/followup now resumes an interrupted_continuable child from its
durable checkpoint instead of queueing a dead-letter: the fresh agent
loop is seeded with the original prompt plus the checkpoint message
tail and the follow-up text, running under a new agent id while the
prior terminal record stays immutable.

Manager seam (resume_from_checkpoint):
- Re-dispatch via spawn_background_with_assignment_options with the
  original agent_type/assignment/allowed_tools/model restored
- Idempotency map (resume_targets): a repeated followup returns the
  existing resumed target and forwards the message to it
- Child runtime derived via background_runtime() (depth +1, detached
  cancellation), depth ceiling checked before derivation like a fresh
  spawn
- Workspace restored to the interrupted child's directory
- Write claim restored from the coordination ledger (pre-namespaced,
  isolation flag preserved); runtime posture (read_only/denied tools/
  shell) preserved from the worker record instead of rebuilt from the
  caller's role

Tool layer (AgentsFollowupTool): optional SubAgentRuntime via
with_runtime; execute routes interrupted_continuable children with a
runtime attached to the resume path, keeping queue-only semantics
otherwise. Both registration points (AgentTool followup action and
register_coordination_tools) attach the runtime.

Tests: 5 manager tests (seeded resume, workspace restore, idempotency
with message forwarding, reject non-interrupted, reject missing
continuable checkpoint) + 2 coord tests (queue-only without runtime,
resume with runtime). 392 subagent tests pass; fmt clean; clippy no new
warnings.

Agent assistance: Codewhale.
@SparkofSpike
SparkofSpike marked this pull request as ready for review August 5, 2026 03:30
@SparkofSpike
SparkofSpike requested a review from Hmbown as a code owner August 5, 2026 03:30
@Hmbown

Hmbown commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Reviewed against the v0.9.4 candidate: checkpoint-resume is squarely in the child-lifecycle scope the candidate is hardening (persistent subagent visibility + recovery). When this leaves draft, we'll review it on the candidate branch — please keep the checkpoint format compatible with the current subagent checkpoint records.

@Hmbown
Hmbown merged commit 0ff0c4b into Hmbown:main Aug 6, 2026
18 of 20 checks passed
Hmbown pushed a commit that referenced this pull request Aug 6, 2026
Adds #5242 (sub-agent checkpoint resume), #5240 (real shell wait elapsed
time), #5234 (#5223 alternate-scroll under mouse capture), #5077
(progressive fresh-context disclosure), and #5238 (MCP Registry
discovery); credits @SparkofSpike and @bistack in Contributors. Root and
crates/tui CHANGELOGs kept byte-identical in the 0.9.4 section.
Hmbown pushed a commit that referenced this pull request Aug 6, 2026
- source-structure budget: fold the test-fix commit's 3 executor.rs lines
  (673293 -> 673296).
- docs/public-surface-facts.json: sourceCandidate toolCount 67 -> 69 to
  match the regenerated web facts (MCP-discovery surface).
- web/lib/release-credits.ts + docs/CONTRIBUTORS.md: add @bistack (#5238)
  and extend @SparkofSpike's v0.9.4 entries (#5242/#5240/#5234) — the
  changelog/credits/contributors parity test requires exact handle parity.
- core_command_surfaces.feature: the /rlm dispatch copy changed to
  'Loading that into a persistent working context...' in a50b653
  (pre-existing on main, hidden by the cancelled CI); align the step.
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.

2 participants