Agent Handoff
When multiple agent profiles run on the same issue — for example a research profile followed by an implementer followed by a reviewer — they can share structured deliverables via a per-issue handoff directory on the worktree branch. This guide walks through the convention and a three-profile worked example.
The convention
Section titled “The convention”Each worker run leaves a Markdown deliverable at:
.itervox/handoff/<ISO8601-timestamp>_<profile-name>.mdThe ISO8601 timestamp is generated by the orchestrator at dispatch time, with : replaced by - so it is filename-safe. Lexicographic order equals chronological order, so a plain ls of the directory is also the timeline.
Before dispatching any worker, the orchestrator:
- Reads every
.mdfile in the directory. - Sorts by filename (chronological).
- Concatenates them, applying a 30 KB budget — oldest files are dropped first with a
[earlier handoffs truncated]marker. - Inlines the result as a
## Prior Agent Handoffsblock in the worker’s prompt. - Adds a
## Run Contextblock withrun.timestampandrun.handoff_pathso the agent knows where to write its own deliverable.
The profile’s INSTRUCTIONS.md is responsible for telling the agent to read the prior handoffs and write its own — the orchestrator does not interpret the content.
Git policy
Section titled “Git policy”.itervox/handoff/** is committable. itervox init and itervox init --update --workflow WORKFLOW.md patch the root .gitignore to whitelist it alongside .itervox/agents/**:
.itervox/!.itervox/!.itervox/agents/!.itervox/agents/**!.itervox/handoff/!.itervox/handoff/**Commit the handoff files into PRs so reviewers can read the chain. The pipeline trail becomes part of the PR’s documentation: research notes, design briefs, implementation summaries, and review findings all live alongside the code.
Partial deliverables
Section titled “Partial deliverables”If a worker exits with TerminalFailed (process crash, render error) or TerminalStalled (the orchestrator’s stall watchdog cancelled the worker context), the orchestrator finds the most recent <timestamp>_<profile>.md file authored by that worker and renames it to <timestamp>_<profile>.partial.md. Subsequent agents still see the partial in their handoff context but with an explicit marker:
### 2026-05-26T15-12-00Z_implementer.partial.md (partial — prior agent exited before completing this deliverable)TerminalInputRequired does NOT mark partial — the agent intentionally paused and will resume; its in-progress file remains as-is and can be extended on resume.
Worked example: research → implement → review
Section titled “Worked example: research → implement → review”This example uses three profiles wired through issue_entered_state automations. As the orchestrator moves an issue between tracker states, each new state fires a different profile, and each profile reads the prior handoffs from .itervox/handoff/.
WORKFLOW.md
Section titled “WORKFLOW.md”---itervox_schema_version: 2tracker: kind: linear api_key: ${LINEAR_API_KEY} project_slug: my-project active_states: ["Todo", "Researching", "Implementing", "Reviewing"] completion_state: "Done" failed_state: "Won't Do"
workspace: root: ~/.itervox/workspaces/my-project worktree: true base_branch: main auto_clear: true # clears when issue reaches Done or Won't Do
agent: max_concurrent_agents: 3 reviewer_profile: reviewer auto_review: false # we drive the reviewer via automation instead
profiles: researcher: command: claude soul_file: .itervox/agents/researcher/SOUL.md instructions_file: .itervox/agents/researcher/INSTRUCTIONS.md allowed_actions: ["move_state", "comment"]
implementer: command: claude soul_file: .itervox/agents/implementer/SOUL.md instructions_file: .itervox/agents/implementer/INSTRUCTIONS.md allowed_actions: ["move_state", "comment"]
reviewer: command: claude soul_file: .itervox/agents/reviewer/SOUL.md instructions_file: .itervox/agents/reviewer/INSTRUCTIONS.md allowed_actions: ["move_state", "comment"]
automations: - id: kick-off-research trigger: type: issue_entered_state states: ["Todo"] profile: researcher policy: move_to_state: "Researching"
- id: kick-off-implementation trigger: type: issue_entered_state states: ["Researching"] profile: implementer policy: move_to_state: "Implementing"
- id: kick-off-review trigger: type: issue_entered_state states: ["Implementing"] profile: reviewer policy: move_to_state: "Reviewing"---
Implement issue {{ issue.identifier }}: {{ issue.title }}.
{{ issue.description }}Profile INSTRUCTIONS.md files
Section titled “Profile INSTRUCTIONS.md files”Each profile’s INSTRUCTIONS.md includes a Handoff Protocol section. itervox init scaffolds this automatically; here are the relevant excerpts.
.itervox/agents/researcher/INSTRUCTIONS.md:
# researcher INSTRUCTIONS
## Workflow- Map the parts of the codebase relevant to this issue.- Identify existing patterns to follow.- Flag risks: timezones, multi-tenant data, retry semantics, schema drift.- Do NOT edit code or run state-changing commands.
## Done Criteria- Findings cover relevant files, existing patterns, and risks.- The handoff file ends with an explicit next-step recommendation.- Move the issue to "Researching" via the daemon action.
## Handoff Protocol- The orchestrator prepends a "## Prior Agent Handoffs" block to your prompt with every prior agent's deliverable on this issue's branch.- Before exiting, write a concise Markdown deliverable to `run.handoff_path` (see the "## Run Context" block).- Do not edit handoff files authored by prior agents..itervox/agents/implementer/INSTRUCTIONS.md:
# implementer INSTRUCTIONS
## Workflow- Read the researcher's handoff for context — do not re-explore.- Implement the smallest complete change.- Match existing patterns flagged by the researcher.- Write or update tests alongside the implementation.
## Done Criteria- The change addresses the issue's intent.- Tests pass (capture command output in the handoff).- Move the issue to "Implementing" via the daemon action.
## Handoff Protocol- Read the prior "## Prior Agent Handoffs" block in your prompt.- Write your deliverable to `run.handoff_path` — list files changed, tests added, commands run, and any risks the reviewer should focus on..itervox/agents/reviewer/INSTRUCTIONS.md:
# reviewer INSTRUCTIONS
## Workflow- Read every prior handoff: the researcher's brief, the implementer's summary.- Inspect the diff against the brief — verify the implementation actually does what was scoped.- Look for: real bugs, regressions, race conditions, missing tests, security issues, scope creep.
## Done Criteria- Findings are specific (file path + line number) and grouped by severity (Critical / Important / Minor).- If no findings, say so plainly — do NOT invent issues to look thorough.- Move the issue to "Done" if clean; back to "Implementing" with critical findings if not.
## Handoff Protocol- Read all prior handoffs to understand intent before evaluating the diff.- Write your review to `run.handoff_path` grouped by severity.What you see after a run
Section titled “What you see after a run”Working on ENG-42, after all three profiles have run:
$ ls .itervox/handoff/2026-05-26T14-30-45Z_researcher.md2026-05-26T14-58-12Z_implementer.md2026-05-26T15-22-08Z_reviewer.mdEach agent’s prompt contained everything that came before it. The implementer saw the researcher’s brief; the reviewer saw both. The full reasoning trail lives in the PR alongside the code changes.
Re-runs and the .partial.md case
Section titled “Re-runs and the .partial.md case”If the implementer crashes mid-run (e.g. the model hits a transient API error and exhausts retries), the file it had started writing is renamed:
$ ls .itervox/handoff/2026-05-26T14-30-45Z_researcher.md2026-05-26T14-58-12Z_implementer.partial.md # crash hereWhen the next implementer attempt fires (either via retry or via an operator manually moving the issue back through state), it reads the partial in its prior-handoffs context and can decide whether to start fresh or build on the partial work. The partial marker makes the distinction unambiguous; you do not need a separate “this run failed” flag.
Budget management
Section titled “Budget management”The 30 KB token budget on the prior-handoffs section is a default chosen to leave ample room for the rest of the prompt (issue body, profile content, sub-agent roster, PR context). Issues that accumulate many handoffs — for example after several retry attempts or a long-running multi-profile pipeline — will see the oldest files dropped first with:
_[N earlier handoffs truncated to fit budget — see `.itervox/handoff/` for full history]_When this happens, the dropped files still exist on disk. The agent can read them directly with the Read tool if it needs detail; the prerender is just the default convenience.
When NOT to use handoff
Section titled “When NOT to use handoff”The handoff convention shines when:
- Multiple profiles run sequentially on the same issue.
- The work splits into distinguishable phases (research, design, build, verify, review).
- You want the pipeline reasoning trail to commit into PRs.
It is unnecessary when:
- A single profile handles the whole issue end-to-end.
- The profile’s own output is already captured in code commits and tracker comments.
- The team’s review tradition is “read the diff” rather than “read the design brief.”
In those cases, skip the chain and use a single profile with auto_review for the post-implementation reviewer pass. The handoff convention is opt-in — agents that do not write to run.handoff_path simply leave no trail.
Related
Section titled “Related”- Agent Profiles guide — defining SOUL/INSTRUCTIONS files
- Automations guide — triggering profile chains from tracker state transitions
- Configuration reference —
workspace.auto_clearsemantics under the handoff model