# How the ai-memory Handoff System Facilitates Cross-Agent Communication

> Learn how the ai-memory handoff system enables seamless cross-agent communication by persisting and retrieving structured context. Maintain workflow continuity effortlessly.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: how-to-guide
- Published: 2026-08-26

---

**The ai-memory handoff system persists structured context records through the `memory_handoff_begin` MCP tool at session end and automatically retrieves them via the `/handoff` endpoint at session start, injecting the context directly into the next agent's prompt to maintain workflow continuity.**

The `akitaonrails/ai-memory` repository provides a production-ready implementation for transferring unfinished work between AI agents. Unlike shared memory architectures, this system uses a **write-once-read-once** pipeline that eliminates race conditions and ensures deterministic context delivery across different agent runtimes.

## Creating Handoff Records at Session End

When an agent finishes its session, the **SessionEnd** hook triggers the `memory_handoff_begin` MCP tool. This action creates a structured record defined in [[`crates/ai-memory-core/src/handoff.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/handoff.rs)](crates/ai-memory-core/src/handoff.rs) (lines 60-66).

The `NewHandoff` struct captures:

- **Origin metadata**: agent identifier, workspace, project, and current working directory
- **Scope**: a `HandoffScope` tying the record to a specific directory path
- **Content**: a `HandoffContent` payload containing open questions or next steps

The system persists this data to the SQLite store (`ai-memory-store`) while simultaneously rendering a markdown representation under the wiki path `sessions/<id>.md`.

### Ownership and Sharing Configuration

By default, handoffs belong exclusively to their creator. However, the `shared: true` flag makes records visible to any operator within the same project, as documented in [[`docs/users.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/users.md)](docs/users.md) (lines 44-48). Administrators can override ownership restrictions using the `any_owner: true` flag on the `memory_handoff_accept` command.

## Retrieving Context at Session Start

Every agent configured with a **SessionStart** hook executes the `ai_memory_get_handoff` helper function defined in [[`hooks/_lib.sh`](https://github.com/akitaonrails/ai-memory/blob/main/hooks/_lib.sh)](hooks/_lib.sh) (lines 384-401). This function issues a GET request to the server's `/handoff` endpoint, passing the agent name and current session identifier.

The server implements precedence logic detailed in [[`docs/usage.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/usage.md)](docs/usage.md) (lines 16-26):

1. Manual handoffs take priority over automatic ones
2. Among automatic handoffs, the newest matching the current directory scope wins

Upon retrieval, the `session-start` script (e.g., [[`hooks/open-code/session-start.sh`](https://github.com/akitaonrails/ai-memory/blob/main/hooks/open-code/session-start.sh)](hooks/open-code/session-start.sh) at line 23) prints the handoff body to stdout, causing the agent runtime to prepend this text to the user prompt.

## Lifecycle Guarantees and Safety Mechanisms

### Single-Use Semantics for Automatic Handoffs

Automatic handoffs implement a **destructive read** pattern. When an agent fetches an automatic handoff, the operation atomically marks it as accepted via the `HandoffAcceptance` struct ([[`crates/ai-memory-core/src/handoff.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/handoff.rs)](crates/ai-memory-core/src/handoff.rs), lines 92-100). This ensures the context transfers exactly once and prevents duplicate processing.

Manual handoffs behave differently—they persist until explicitly cancelled using `memory_handoff_cancel`.

### Scope Resolution and Idempotency

The server enforces strict **scope resolution** through `ai_memory_store::ScopeResolver`, guaranteeing that handoffs never route to incorrect projects or workspaces. Additionally, the hook library prevents accidental double-consumption by tracking session state ([`_lib.sh`](https://github.com/akitaonrails/ai-memory/blob/main/_lib.sh) line 122), ensuring a single session never fetches the same handoff twice.

## Practical Implementation Examples

### Creating a Handoff in a SessionEnd Hook

```bash

# Example from hooks/open-code/session-end.sh

handoff_content=$(cat <<EOF
What remains to do:
- Verify JWT rotation
- Write unit tests for session-cookie fallback
EOF
)

ai_memory memory_handoff_begin \
  --agent=open-code \
  --content "$handoff_content" \
  --shared=false

```

### Automatic Retrieval in SessionStart Hooks

```bash

# From hooks/open-code/session-start.sh

HANDOFF=$(ai_memory_get_handoff "$SERVER/handoff?agent=open-code${QS}${SESSION_QS}" 2>/dev/null || true)

if [ -n "$HANDOFF" ]; then
  echo "$HANDOFF"
fi

```

### Manual Handoff Management

```bash

# List pending handoffs

ai_memory memory_handoff_list --project=my-project

# Accept a specific handoff

ai_memory memory_handoff_accept --handoff-id=123e4567-e89b-12d3-a456-426614174000

# Cancel a mistaken handoff

ai_memory memory_handoff_cancel --handoff-id=123e4567-e89b-12d3-a456-426614174000

```

## Summary

- The **ai-memory handoff system** uses MCP tools and SQLite to persist context between agent sessions without shared mutable state.
- The `memory_handoff_begin` tool creates structured records containing origin metadata, scope, and content, storing them in [`crates/ai-memory-core/src/handoff.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/handoff.rs) data structures.
- **Automatic handoffs** follow single-use semantics—consumed atomically on first fetch—while **manual handoffs** persist until cancelled.
- The `ai_memory_get_handoff` helper in [`hooks/_lib.sh`](https://github.com/akitaonrails/ai-memory/blob/main/hooks/_lib.sh) retrieves context via the `/handoff` endpoint, with scope resolution ensuring delivery only to matching projects and workspaces.
- Context injection occurs by piping handoff content into the agent's prompt at session start, enabling seamless workflow continuation across different AI agents.

## Frequently Asked Questions

### How does the ai-memory handoff system prevent duplicate context injection?

The system implements a **destructive read** pattern for automatic handoffs. When `ai_memory_get_handoff` fetches a record, the server atomically marks it as accepted through the `HandoffAcceptance` mechanism, preventing subsequent retrievals. Additionally, session hooks track consumption state to block double-fetching within the same session.

### What is the difference between automatic and manual handoffs?

**Automatic handoffs** are created by SessionEnd hooks and consumed automatically by the next compatible agent's SessionStart hook. They follow single-use semantics and disappear after acceptance. **Manual handoffs** are created explicitly by users or processes, persist indefinitely until cancelled, and can be accepted by any authorized operator through the `memory_handoff_accept` command.

### Can handoffs be shared between different operators?

Yes. While handoffs default to private ownership, setting the `shared: true` flag during creation makes the record visible to any operator within the same project. Administrators can further override ownership restrictions using the `any_owner: true` parameter when accepting handoffs created by other users.

### How does scope resolution prevent cross-project contamination?

The server uses the `ai_memory_store::ScopeResolver` to validate that a handoff's `HandoffScope` matches the requesting agent's current directory, workspace, and project. This ensures that a handoff created in one project path never injects context into an agent running in a different project, maintaining strict isolation boundaries.