Automatic vs Manual Handoffs in ai-memory: Key Differences Explained
The primary difference between automatic and manual handoffs in ai-memory is that automatic handoffs are generated by the SessionEnd lifecycle hook at the directory level, while manual handoffs are explicitly created via the memory_handoff_begin MCP tool and apply project-wide with higher precedence.
Understanding how ai-memory manages context transfer between sessions requires familiarity with its dual handoff system. The akitaonrails/ai-memory repository implements two distinct mechanisms for preserving session state, each designed for specific workflow requirements and operating under different scoping and precedence rules.
How Automatic Handoffs Work
Automatic handoffs provide zero-friction context preservation when a session terminates. According to the source code in hooks/pool/session-end.sh, these handoffs trigger automatically through the SessionEnd lifecycle hook without requiring explicit user intervention.
Directory Scoping and Precedence
Automatic handoffs are strictly directory-scoped. When a session ends in a specific directory, the handoff is created for that exact path and does not affect sibling directories. The system implements a "newest wins" policy: when multiple automatic handoffs match the same directory, the most recent one takes precedence.
Expiration Rules for Automatic Handoffs
The expiration logic for automatic handoffs operates on two principles as documented in docs/usage.md:
- Creating a new automatic handoff for a specific directory immediately expires any previously open automatic handoffs for that exact directory
- Accepting a handoff expires older automatic handoffs that match the same path
- Manual handoffs remain unaffected by these automatic expiration rules
How Manual Handoffs Work
Manual handoffs serve as explicit, project-wide checkpoints created through deliberate user action. Unlike their automatic counterparts, these require invocation of the memory_handoff_begin MCP tool.
Project-Wide Scope and Higher Precedence
Manual handoffs operate at the project level rather than directory level. As stated in docs/usage.md, "Manual handoffs are project-wide and take precedence over automatic SessionEnd handoffs." This means any agent starting a session in any sub-directory of the project will see the manual handoff before any automatic ones.
Persistent Unlike Automatic Handoffs
Manual handoffs persist until explicitly cancelled. They are not removed by the creation of new automatic handoffs and remain active until:
- The creator explicitly cancels them using
memory_handoff_cancel - They are accepted by a receiving session
Ownership and Sharing
According to docs/users.md, manual handoffs support ownership semantics through the --shared flag. By default, handoffs belong only to the creator, but they can be made accessible to team members when needed.
Practical Code Examples
Creating a Manual Handoff
Explicitly create a project-wide handoff with specific briefing content:
# Create a manual handoff (project-wide)
ai-memory memory_handoff_begin \
--summary "Investigate session-cookies as an alternative" \
--next-steps "Check server logs for cookie validation errors" \
--shared false
Automatic Handoff Lifecycle
Automatic handoffs require no command—they are written automatically by the session-end hook. However, you can interact with them programmatically. The helper function in hooks/_lib.sh implements ai_memory_get_handoff, which session-start hooks use to retrieve pending handoffs:
# Fetch handoff (typically handled by session-start hooks)
HANDOFF=$(ai_memory_get_handoff "$SERVER/handoff?agent=open-code${QS}${SESSION_QS}" 2>/dev/null || true)
Managing Handoff State
Control the lifecycle of manual handoffs through explicit commands:
# Accept (consume) a handoff manually
ai-memory memory_handoff_accept --handoff-id <HANDOFF_ID>
# Cancel a mistakenly-created handoff
ai-memory memory_handoff_cancel --handoff-id <HANDOFF_ID>
Key Differences Summary
| Feature | Automatic Handoff | Manual Handoff |
|---|---|---|
| Creation mechanism | SessionEnd lifecycle hook (hooks/pool/session-end.sh) |
Explicit memory_handoff_begin command |
| Scope | Directory-specific | Project-wide |
| Precedence | Lower (overridden by manual) | Higher (takes precedence) |
| Expiration | Expired by newer automatic handoffs or acceptance | Persistent until cancelled or accepted |
| Sibling directory impact | None (isolated to creation directory) | Visible to all project sub-directories |
| Typical use case | Automatic context preservation between sessions | Specific briefing for next session with custom instructions |
Summary
- Automatic handoffs in ai-memory are lifecycle-driven, directory-scoped, and transient, created automatically by the SessionEnd hook without user intervention.
- Manual handoffs are explicit, project-wide, and persistent, offering higher precedence and surviving automatic expiration rules.
- The
memory_handoff_begintool creates manual handoffs with custom summaries and next-steps, while automatic handoffs provide terse, automated context preservation. - Manual handoffs remain active until explicitly cancelled via
memory_handoff_cancel, whereas automatic handoffs expire when superseded by newer automatic handoffs for the same directory.
Frequently Asked Questions
When should I use a manual handoff instead of relying on automatic handoffs?
Use a manual handoff when you need the next session to start with specific briefing content, custom next-steps, or instructions that the automatic SessionEnd handoff would not contain. According to the akitaonrails/ai-memory source code, manual handoffs are ideal when you require project-wide visibility rather than directory-specific context, or when you need the handoff to persist beyond the next automatic session end in that directory.
How do automatic handoffs handle multiple sessions in the same directory?
Automatic handoffs implement a "newest wins" policy scoped to the exact directory. When you create a new automatic handoff for a specific directory, it expires any previously open automatic handoffs for that exact path. Additionally, accepting a handoff expires older matching automatic handoffs without disturbing manual handoffs, as implemented in the expiration logic referenced in docs/usage.md.
Can manual handoffs be shared between team members?
Yes, manual handoffs support ownership semantics that allow sharing. As documented in docs/users.md, you can set the --shared flag when creating a handoff with memory_handoff_begin. By default, handoffs are private to the creator (--shared false), but enabling sharing makes them visible to other agents or team members working within the same project.
What happens if both automatic and manual handoffs exist for a project?
Manual handoffs always take precedence over automatic SessionEnd handoffs. When a new session starts, the system checks for manual handoffs first across the entire project scope. Only if no manual handoff exists will the system consider automatic handoffs for the specific directory. This precedence rule ensures that explicit user intentions (manual handoffs) override automated context preservation when both are present.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →