---
name: respawn-failed-subagent-with-context
description: Add a "retry/respawn" action for a failed long-running subagent run that resumes with a context preamble built from its recorded progress updates, instead of restarting from scratch.
---
# Respawn Failed Subagent With Context Preamble

## When to use
- User asks for a "retry", "resume", "respawn", or "pick up where it left off" action on a failed subagent / coder run in InfiniBot.
- Activity / kanban / sessions UI shows FAILED runs and needs a one-click way to relaunch them without losing the work the prior attempt completed.
- Any long-running task pipeline where progress updates / checkpoints already exist in a registry but there's no way to feed that history back into a new attempt.

## How to apply
1. **Persist lineage in the registry first.** In `src/agents/subagent-registry.ts` add an optional `respawnOfRunId` to `SubagentRunRecord` and to `registerSubagentRunForCoder` params. This must survive gateway restarts (live store + archive), so chained respawns are traceable.
2. **Thread `respawnOfRunId` through the coder tool schema.** In `src/agents/tools/claude-coder-tool.ts` add it as an optional zod arg, read from `params`, forward into `registerSubagentRunForCoder`. Do NOT invent a new spawn path — caller-supplied `systemPrompt` already cascades into the spawn preamble via `composeSpawnSystemPrompt`, so the respawn handler just sets `systemPrompt` to the built preamble.
3. **Build the preamble from existing telemetry, not from the failure stack alone.** In `src/gateway/server-methods/subagents.handlers.ts` add `buildRespawnPreamble(runId)` that pulls from the `subagent-progress` updates (status + progress% + checkpoint + message + timestamp), the checkpoints list, last fine-grained activity row, and (when live record is gone) the archived `filesTouchedSample`. Order chronologically. Cap at ~12K chars so it can't blow the child's context budget.
4. **Add a `subagents.respawn` RPC.** Load the original run with **live → archive fallback**, verify `ERROR_STATUSES` or `outcome.status === 'error'` (refuse to respawn non-failed runs), build the preamble, then call `createClaudeCoderTool(...).execute({ mode: "detach", systemPrompt: preamble, respawnOfRunId, task, workdir, backend, label })` reusing the original `task` verbatim. Register it in `WRITE_METHODS` in `src/gateway/server-methods.ts`. Return `{ runId, sessionKey }`.
5. **Surface lineage in detail/status responses.** Extend `mergeRunAndProgress` and `subagents.detail` to include `respawnOfRunId` so the UI can render the chip on both the new run and any descendant.
6. **Wire the mobile UI** (`mobile/src/screens/TaskActivityScreen.js`):
   - Fetch `subagents.status` + `subagents.detail` when the focus modal opens; reset on visibility change.
   - Add a failure banner with `outcome.error`.
   - Add an **Activity Feed** panel rendering `updates[]` chronologically, color-coded by status.
   - Add a **Respawn Agent** action button gated on `ERROR_STATUSES` or `outcome.status === 'error'`. Confirm via `Alert`, call `sendReq('subagents.respawn', { runId })`, show the new runId, close the modal.
   - Add a "Respawn of #xxxxxxxx" chip in the header when `respawnOfRunId` is set, plus a compact inline chip on `ActivityRow` lineage rows.
7. **Validate before reporting done.** `npx tsc --noEmit -p tsconfig.json` AND `@babel/parser` JSX parse on the modified mobile screen. Then call out the manual gateway smoke test as TODO — never claim UI is verified just because types pass.

## Rules
- Never restart a failed run from scratch when progress updates exist — always inject the chronological preamble so the child knows what was already done, what files were touched, and where the last checkpoint landed.
- Never invent a parallel spawn pipeline for "respawn". Reuse `createClaudeCoderTool(...).execute({ mode: "detach", systemPrompt })` so future changes to spawn semantics apply automatically.
- Never let the preamble grow unbounded — cap it (≈12K chars) so the child still has room for the real task.
- Never trust the live registry alone; always fall back to the archive when loading the original run, otherwise respawn breaks after gateway restarts.
- Always persist `respawnOfRunId` lineage on the new record (live + archive) so chained respawns are traceable in the UI.
- Always gate the Respawn button on actual failure (`ERROR_STATUSES` or `outcome.status === 'error'`); refuse to respawn running/succeeded runs server-side too.
- Always reuse the original `task`/`workdir`/`backend`/`label` verbatim — the preamble carries the delta, not a rewritten task.
- Always reset modal-fetched state (`updates`, `detail`) on visibility change so a previously-opened run's data doesn't leak into the next modal.