🤝 handoff — Bidirectional Handoff, Resumption & Ambient Continuity Engine
Aliases: agent-handoff | subagent-handoff | context-packet | resume | where-were-we
handoff provides context continuity across agent lifecycles in three modes:
- Inbound Resumption: Resumes previous agent sessions with boundary-safe directory matching, leading with any unanswered open questions.
- Outbound Dispatch: Generates lean, bounded context packets before dispatching subagents or stepping away.
- Ambient Continuity (v2.1.0): Passively maintains a live state file and probes for it on every workspace entry, so work continues across conversations, agents, and runtimes — even after abrupt endings and even when no one asked for a handoff.
When to Use
Mode A: Inbound Session Resumption
- User asks: "where were we", "resume", "pick up where I left off", "what was I doing", or begins a session with no fresh prompt.
- Restoring state after an interruption or machine restart.
Mode B: Outbound Subagent Dispatch
- Before dispatching any subagent for backend, frontend, testing, or refactoring.
- Before spawning multi-agent teams or worker processes.
- Before stepping away from a long-running session (>30 minutes).
- Whenever a task prompt to another agent exceeds 3 sentences.
Mode C: Ambient Continuity (Default-On)
- Every workspace entry: probe for prior state before doing anything else.
- Every checkpoint: a milestone completes, a decision is made, a correction lands, a task is abandoned mid-flight.
- End of any working turn with work incomplete: session ending normally, crash imminent, or user walking away — no explicit handoff request required.
- A brand-new conversation opens in a working directory where prior work happened: the agent resumes context automatically instead of starting blind.
Quick Reference
Mode Comparison
| Capability |
Inbound Resumption (A) |
Outbound Dispatch (B) |
Ambient Continuity (C) |
| Trigger |
"where were we", "resume" |
"dispatch worker", "handoff to subagent" |
Workspace entry; checkpoints; incomplete end-of-turn |
| Matching Rule |
Strict directory-boundary matching (=== or startsWith(cwd + sep)) |
Explicit destination file and line range scope |
Current working directory, always |
| First Output |
Unanswered user question (if any) |
Single 1-sentence actionable objective |
≤5-line resumption block, then first productive action |
| Persistence |
Session memory / .agents/artifacts/ |
.agents/artifacts/handoff-<timestamp>.md |
.agents/artifacts/HANDOFF.md (overwritten, never appended) |
| Closing Token |
Concrete atomic next-step pointer |
Deterministic verification command |
Refreshed live file + optional memory write |
Token Budgets (hard limits)
| Phase |
Budget |
Rule |
| Entry probe |
1 command |
test -f .agents/artifacts/HANDOFF.md — zero analysis before this |
| Resumption output |
≤5 lines |
State summary + next step only; no narrative, no history retelling |
| Detail loading |
On demand |
Full packet, references, and memory recall load only when the 5-line block is insufficient or the user asks |
| Live-file write |
≤30 lines |
HANDOFF.md is a pointer, not a journal |
The State-Source Ladder (cold-start continuity)
On workspace entry, resolve prior state by climbing the ladder; stop at the first rung that yields state:
- Live Handoff file —
.agents/artifacts/HANDOFF.md exists → resume from it directly.
- Memory recall — query the runtime's session-memory tool (e.g.
memory_sessions / memory_recall), strictly filtered to this directory boundary.
- Project context —
.agents/context/current.md and .agents/context/index.md (maintained by updateagents conventions).
- Git forensics — reconstruct from the repository itself (recipe in references/resumption-protocol.md); after reconstructing, write HANDOFF.md immediately so the next agent never digs again.
- Cold start — declare honestly:
No prior session history found for this project directory. Never invent history. Offer the ai-ready audit.
The Live Handoff File (.agents/artifacts/HANDOFF.md)
One fixed-name file, ≤30 lines, overwritten on every state change — the bridge from any session to any future conversation:
# HANDOFF — <ISO timestamp>
branch: <branch> | phase: <one-line state>
## Next Step
<Single atomic action: file + what to do>
## In-Flight
- <Unfinished item, if any>
## Ruled Out
- <Approach>: <why it failed — one line>
## Decisions
- <Durable choice made, not to be re-litigated>
## Verify
`<exact command>`
## Open Questions
- <Unanswered user question, if any — leads resumption>
Omit empty sections. Full schema and write-trigger contract: references/ambient-handoff.md.
Procedures
🔄 Mode A: Inbound Session Resumption Procedure
- Resolve Workspace Directory:
Normalize the current working directory. If a directory override argument is provided, resolve to an absolute path.
- Retrieve Prior Session (via the State-Source Ladder above):
Query session history (memory tools,
.agents/artifacts/, .agents/context/current.md), enforcing directory-boundary isolation:// Prohibit raw prefix matching to prevent sibling repo bleed:
session.cwd === projectPath || session.cwd.startsWith(projectPath + path.sep)
- Surface Unanswered Questions FIRST:
If the prior session ended on an unanswered user question (
?), highlight it at the very top of your response. Do not guess the answer.
- Format Resumption Summary (≤5 lines before the first productive action):
Resuming [session_id] "[session_title]".
❓ Open Question from Last Session:
[Unanswered question, if present]
📌 State: [key decisions & modified files · active roadblocks]
👉 Immediate Next Step:
[Single concrete atomic action]
📦 Mode B: Outbound Subagent Dispatch Procedure
- Extract Operational Facts:
- Objective: Exact 1-sentence goal starting with an imperative verb.
- Decisions Made: Irreversible choices not to be re-litigated.
- Ruled-Out Paths: Approaches tried and eliminated with failure reasons.
- Target Scope: Exact files to touch.
- Hard Constraints: Forbidden files, libraries, or credentials (
MUST NOT).
- Deterministic Verification: Exact test or build command.
- If Blocked: Escalation fallback.
- Write Handoff Packet to
.agents/artifacts/handoff-<timestamp>.md (structure in README and worked example in examples/sample-handoff.md).
- Lease hand-off to workers (shared checkouts): if the packet's Target Scope includes git mutations (branch switches, stashes, commits to shared surfaces), embed the worktree-lease instruction in the dispatch prompt — the worker probes
.agents/artifacts/WORKTREE-LEASE.md before its first git mutation and inherits or acquires per the lease protocol (coupling-router Step 0). Never dispatch two workers whose scopes overlap on one checkout.
- Echo & Dispatch: Embed the packet directly into the subagent invocation prompt.
- Refresh the live file: update HANDOFF.md to point at the dispatched task so an interrupting conversation still lands correctly.
🌊 Mode C: Ambient Continuity Procedure
Write side (passive, silent — no prose, no user interruption):
| Trigger |
Action |
| Checkpoint completed (milestone, passing gate, landed change) |
Overwrite HANDOFF.md with new Next Step |
| User decision or correction received |
Record under Decisions; refresh timestamp |
| End of turn with work incomplete |
Overwrite HANDOFF.md (Next Step = exactly what you would do next) |
| Ending signal ("close", "wrap up", session end) |
Full flush: HANDOFF.md + timestamped packet if the state is rich + memory hook |
| Task blocked or abandoned |
Next Step = escalation path; route the failure to dead-letter |
Read side:
- Workspace entry always probes for HANDOFF.md before any other work. If present and fresh (same branch, plausible timestamp), emit the ≤5-line resumption block and continue — even though nobody said "resume".
- If the user's first message is a fresh instruction, treat the resumption block as silent context: proceed with the instruction, informed by state.
- Lease check on entry (shared checkouts): if
.agents/artifacts/WORKTREE-LEASE.md exists with a fresh heartbeat, another session is live — the ≤5-line resumption block notes this, and the entry session takes a separate worktree or stays read-only until the lease releases (decision rules: coupling-router Step 0).
Anti-noise guardrails:
- One file, overwritten — never append, never accumulate.
- Refresh only on real state change (checkpoint, decision, reversal); not on every tool call.
- Silent writes: ambient handoff never narrates itself.
🧠 Memory System Hooks
Handoff integrates with whatever memory system the runtime provides (e.g. musememory's write/recall tools), without ever touching .memory/** directly — that path is owned exclusively by musememory:
- On outbound handoff or full flush: push durable decisions only (not the file dump) through the runtime's memory-write tool call when one exists. Ephemeral state stays in HANDOFF.md; durable rules and decisions go to memory.
- On workspace entry (ladder rung 2): memory recall is a lookup, filtered strictly to the current directory boundary.
- When no memory tool exists: durable findings are reported in the output and recorded in
.agents/context/ via updateagents conventions — never written to .memory/ by hand.
Neighboring Skill Boundaries
context-anchor → manual mid-session drift stop within one conversation. Ambient handoff → session-boundary continuity across conversations; the live file doubles as a rolling anchor.
coupling-router → owns the shared-worktree lease. Handoff routes to it: dispatches embed the lease instruction (Mode B step 3) and workspace entry respects an active lease (Mode C read side). A session that died holding the lease is exactly the case handoff's ladder reconstructs — check its notes for preserved WIP.
dead-letter → failure-path escape hatch. A blocked task lands in both: HANDOFF.md Next Step (continuity) + dead-letter packet (diagnosis).
updateagents → owns durable .agents/context/ truth; ambient handoff reads it (ladder rung 3) and routes durable changes to it rather than editing governed context directly.
Pitfalls
- Raw Prefix Collisions: Never match session directories using raw
startsWith(path); sibling directories like /project-staging will falsely match /project.
- Hiding Open Questions: Never bury an unanswered user question under a wall of status logs.
- Compound Objectives: Never combine multiple decoupled tasks into one outbound packet.
- Omitted Ruled-Out Paths: Subagents re-explore failed attempts unless explicitly forbidden.
- Journal Bloat: HANDOFF.md is a pointer, not a diary. If it exceeds ~30 lines it has become a session log — prune or demote detail to a timestamped packet.
- Ladder Skipping: Do not run deep analysis before the entry probe; the cheapest rung that yields state wins.
- Silent Cold Starts: Never invent prior context when the ladder returns nothing — say "cold start" and move.
Verification
References
- 🔄 Inbound Resumption & Boundary Protection Protocol
- 🌊 Ambient Continuity & Live Handoff File Contract
- 📄 Sample Handoff Packet
- 📄 Sample Live Handoff File
1---2name: handoff-23description: Bidirectional agent handoff and session resumption engine with ambient continuity. Generates lean, bounded context packets before dispatching subagents, resumes previous sessions with boundary-safe directory matching and unanswered questions leading, and maintains an always-current HANDOFF.md live-state file with a state-source ladder (live file, memory recall, project context, git forensics) probed on every workspace entry so any new conversation or agent continues prior work at lowest token cost — even after abrupt endings, with no explicit handoff requested. Dispatches embed the worktree-lease gate for shared checkouts.4license: MIT5---67# 🤝 handoff — Bidirectional Handoff, Resumption & Ambient Continuity Engine89> **Aliases**: `agent-handoff` | `subagent-handoff` | `context-packet` | `resume` | `where-were-we`1011`handoff` provides context continuity across agent lifecycles in three modes:121. **Inbound Resumption**: Resumes previous agent sessions with boundary-safe directory matching, leading with any unanswered open questions.132. **Outbound Dispatch**: Generates lean, bounded context packets before dispatching subagents or stepping away.143. **Ambient Continuity** (v2.1.0): Passively maintains a live state file and probes for it on every workspace entry, so work continues across conversations, agents, and runtimes — even after abrupt endings and even when no one asked for a handoff.1516---1718## When to Use1920### Mode A: Inbound Session Resumption21- User asks: *"where were we"*, *"resume"*, *"pick up where I left off"*, *"what was I doing"*, or begins a session with no fresh prompt.22- Restoring state after an interruption or machine restart.2324### Mode B: Outbound Subagent Dispatch25- Before dispatching any subagent for backend, frontend, testing, or refactoring.26- Before spawning multi-agent teams or worker processes.27- Before stepping away from a long-running session (>30 minutes).28- Whenever a task prompt to another agent exceeds 3 sentences.2930### Mode C: Ambient Continuity (Default-On)31- **Every workspace entry**: probe for prior state before doing anything else.32- **Every checkpoint**: a milestone completes, a decision is made, a correction lands, a task is abandoned mid-flight.33- **End of any working turn with work incomplete**: session ending normally, crash imminent, or user walking away — no explicit handoff request required.34- A brand-new conversation opens in a working directory where prior work happened: the agent resumes context automatically instead of starting blind.3536---3738## Quick Reference3940### Mode Comparison4142| Capability | Inbound Resumption (A) | Outbound Dispatch (B) | Ambient Continuity (C) |43|:---|:---|:---|:---|44| **Trigger** | *"where were we"*, *"resume"* | *"dispatch worker"*, *"handoff to subagent"* | Workspace entry; checkpoints; incomplete end-of-turn |45| **Matching Rule** | Strict directory-boundary matching (`===` or `startsWith(cwd + sep)`) | Explicit destination file and line range scope | Current working directory, always |46| **First Output** | Unanswered user question (if any) | Single 1-sentence actionable objective | ≤5-line resumption block, then first productive action |47| **Persistence** | Session memory / `.agents/artifacts/` | `.agents/artifacts/handoff-<timestamp>.md` | `.agents/artifacts/HANDOFF.md` (overwritten, never appended) |48| **Closing Token** | Concrete atomic next-step pointer | Deterministic verification command | Refreshed live file + optional memory write |4950### Token Budgets (hard limits)5152| Phase | Budget | Rule |53|:---|:---|:---|54| Entry probe | 1 command | `test -f .agents/artifacts/HANDOFF.md` — zero analysis before this |55| Resumption output | ≤5 lines | State summary + next step only; no narrative, no history retelling |56| Detail loading | On demand | Full packet, references, and memory recall load **only** when the 5-line block is insufficient or the user asks |57| Live-file write | ≤30 lines | HANDOFF.md is a pointer, not a journal |5859### The State-Source Ladder (cold-start continuity)6061On workspace entry, resolve prior state by climbing the ladder; stop at the first rung that yields state:62631. **Live Handoff file** — `.agents/artifacts/HANDOFF.md` exists → resume from it directly.642. **Memory recall** — query the runtime's session-memory tool (e.g. `memory_sessions` / `memory_recall`), strictly filtered to this directory boundary.653. **Project context** — `.agents/context/current.md` and `.agents/context/index.md` (maintained by `updateagents` conventions).664. **Git forensics** — reconstruct from the repository itself (recipe in [references/resumption-protocol.md](references/resumption-protocol.md)); after reconstructing, **write HANDOFF.md immediately** so the next agent never digs again.675. **Cold start** — declare honestly: `No prior session history found for this project directory.` Never invent history. Offer the `ai-ready` audit.6869### The Live Handoff File (`.agents/artifacts/HANDOFF.md`)7071One fixed-name file, ≤30 lines, overwritten on every state change — the bridge from any session to any future conversation:7273```markdown74# HANDOFF — <ISO timestamp>75branch: <branch> | phase: <one-line state>7677## Next Step78<Single atomic action: file + what to do>7980## In-Flight81- <Unfinished item, if any>8283## Ruled Out84- <Approach>: <why it failed — one line>8586## Decisions87- <Durable choice made, not to be re-litigated>8889## Verify90`<exact command>`9192## Open Questions93- <Unanswered user question, if any — leads resumption>94```9596Omit empty sections. Full schema and write-trigger contract: [references/ambient-handoff.md](references/ambient-handoff.md).9798---99100## Procedures101102### 🔄 Mode A: Inbound Session Resumption Procedure1031041. **Resolve Workspace Directory**:105 Normalize the current working directory. If a directory override argument is provided, resolve to an absolute path.1062. **Retrieve Prior Session** (via the State-Source Ladder above):107 Query session history (memory tools, `.agents/artifacts/`, `.agents/context/current.md`), enforcing directory-boundary isolation:108 ```ts109 // Prohibit raw prefix matching to prevent sibling repo bleed:110 session.cwd === projectPath || session.cwd.startsWith(projectPath + path.sep)111 ```1123. **Surface Unanswered Questions FIRST**:113 If the prior session ended on an unanswered user question (`?`), highlight it at the very top of your response. Do not guess the answer.1144. **Format Resumption Summary** (≤5 lines before the first productive action):115 ```text116 Resuming [session_id] "[session_title]".117118 ❓ Open Question from Last Session:119 [Unanswered question, if present]120121 📌 State: [key decisions & modified files · active roadblocks]122123 👉 Immediate Next Step:124 [Single concrete atomic action]125 ```126127### 📦 Mode B: Outbound Subagent Dispatch Procedure1281291. **Extract Operational Facts**:130 - **Objective**: Exact 1-sentence goal starting with an imperative verb.131 - **Decisions Made**: Irreversible choices not to be re-litigated.132 - **Ruled-Out Paths**: Approaches tried and eliminated with failure reasons.133 - **Target Scope**: Exact files to touch.134 - **Hard Constraints**: Forbidden files, libraries, or credentials (`MUST NOT`).135 - **Deterministic Verification**: Exact test or build command.136 - **If Blocked**: Escalation fallback.1372. **Write Handoff Packet** to `.agents/artifacts/handoff-<timestamp>.md` (structure in [README](README.md#-packet-structure) and worked example in [examples/sample-handoff.md](examples/sample-handoff.md)).1383. **Lease hand-off to workers** (shared checkouts): if the packet's Target Scope includes git mutations (branch switches, stashes, commits to shared surfaces), embed the worktree-lease instruction in the dispatch prompt — the worker probes `.agents/artifacts/WORKTREE-LEASE.md` before its first git mutation and inherits or acquires per the lease protocol (`coupling-router` Step 0). Never dispatch two workers whose scopes overlap on one checkout.1394. **Echo & Dispatch**: Embed the packet directly into the subagent invocation prompt.1405. **Refresh the live file**: update HANDOFF.md to point at the dispatched task so an interrupting conversation still lands correctly.141142### 🌊 Mode C: Ambient Continuity Procedure143144**Write side (passive, silent — no prose, no user interruption):**145146| Trigger | Action |147|:---|:---|148| Checkpoint completed (milestone, passing gate, landed change) | Overwrite HANDOFF.md with new Next Step |149| User decision or correction received | Record under Decisions; refresh timestamp |150| End of turn with work incomplete | Overwrite HANDOFF.md (Next Step = exactly what you would do next) |151| Ending signal ("close", "wrap up", session end) | Full flush: HANDOFF.md + timestamped packet if the state is rich + memory hook |152| Task blocked or abandoned | Next Step = escalation path; route the failure to `dead-letter` |153154**Read side:**155- **Workspace entry always probes** for HANDOFF.md before any other work. If present and fresh (same branch, plausible timestamp), emit the ≤5-line resumption block and continue — even though nobody said "resume".156- If the user's first message is a fresh instruction, treat the resumption block as silent context: proceed with the instruction, informed by state.157- **Lease check on entry** (shared checkouts): if `.agents/artifacts/WORKTREE-LEASE.md` exists with a fresh heartbeat, another session is live — the ≤5-line resumption block notes this, and the entry session takes a separate worktree or stays read-only until the lease releases (decision rules: `coupling-router` Step 0).158159**Anti-noise guardrails:**160- One file, overwritten — never append, never accumulate.161- Refresh only on real state change (checkpoint, decision, reversal); not on every tool call.162- Silent writes: ambient handoff never narrates itself.163164### 🧠 Memory System Hooks165166Handoff integrates with whatever memory system the runtime provides (e.g. musememory's write/recall tools), without ever touching `.memory/**` directly — that path is owned exclusively by `musememory`:1671681. **On outbound handoff or full flush**: push *durable decisions only* (not the file dump) through the runtime's memory-write tool call when one exists. Ephemeral state stays in HANDOFF.md; durable rules and decisions go to memory.1692. **On workspace entry (ladder rung 2)**: memory recall is a lookup, filtered strictly to the current directory boundary.1703. **When no memory tool exists**: durable findings are reported in the output and recorded in `.agents/context/` via `updateagents` conventions — never written to `.memory/` by hand.171172### Neighboring Skill Boundaries173174- `context-anchor` → manual mid-session drift stop within one conversation. Ambient `handoff` → session-boundary continuity across conversations; the live file doubles as a rolling anchor.175- `coupling-router` → owns the shared-worktree lease. Handoff routes to it: dispatches embed the lease instruction (Mode B step 3) and workspace entry respects an active lease (Mode C read side). A session that died holding the lease is exactly the case handoff's ladder reconstructs — check its `notes` for preserved WIP.176- `dead-letter` → failure-path escape hatch. A blocked task lands in both: HANDOFF.md Next Step (continuity) + dead-letter packet (diagnosis).177- `updateagents` → owns durable `.agents/context/` truth; ambient handoff reads it (ladder rung 3) and routes durable changes to it rather than editing governed context directly.178179---180181## Pitfalls182183- **Raw Prefix Collisions**: Never match session directories using raw `startsWith(path)`; sibling directories like `/project-staging` will falsely match `/project`.184- **Hiding Open Questions**: Never bury an unanswered user question under a wall of status logs.185- **Compound Objectives**: Never combine multiple decoupled tasks into one outbound packet.186- **Omitted Ruled-Out Paths**: Subagents re-explore failed attempts unless explicitly forbidden.187- **Journal Bloat**: HANDOFF.md is a pointer, not a diary. If it exceeds ~30 lines it has become a session log — prune or demote detail to a timestamped packet.188- **Ladder Skipping**: Do not run deep analysis before the entry probe; the cheapest rung that yields state wins.189- **Silent Cold Starts**: Never invent prior context when the ladder returns nothing — say "cold start" and move.190191---192193## Verification194195- [ ] Inbound resumption surfaces any unanswered question before status text.196- [ ] Session matching strictly validates directory boundaries.197- [ ] Outbound handoff packet is written to `.agents/artifacts/handoff-<timestamp>.md`.198- [ ] Workspace entry performed the HANDOFF.md probe before other work.199- [ ] HANDOFF.md is ≤30 lines, overwritten (not appended), and carries an atomic Next Step.200- [ ] Resumption output stayed within the ≤5-line budget before the first productive action.201- [ ] Memory integration used the runtime's tool API (or reported the durable fact) — `.memory/**` never touched by hand.202- [ ] All 7 outbound packet sections are populated with zero placeholder text.203- [ ] In shared checkouts, dispatched workers carry the worktree-lease instruction, and entry respected any active lease before mutating.204205---206207## References208209- 🔄 [Inbound Resumption & Boundary Protection Protocol](references/resumption-protocol.md)210- 🌊 [Ambient Continuity & Live Handoff File Contract](references/ambient-handoff.md)211- 📄 [Sample Handoff Packet](examples/sample-handoff.md)212- 📄 [Sample Live Handoff File](examples/sample-HANDOFF.md)