# Understanding the Capture-Consolidate-Recall-Handoff Loop in ai-memory

> Explore the capture-consolidate-recall-handoff loop in ai-memory. Learn how this architecture transforms agent runtime data into a searchable knowledge base for seamless information flow.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: deep-dive
- Published: 2026-09-12

---

**The capture-consolidate-recall-handoff loop is ai-memory's steady-state data-flow architecture that moves information from an agent's runtime into a durable, searchable knowledge base and makes it available to subsequent agents through atomic, asynchronous stages.**

The `akitaonrails/ai-memory` repository implements this four-stage pipeline to solve the persistent memory problem for AI agents. By treating markdown files as the source of truth and SQLite as a derived searchable index, the system ensures that observations captured during one session become queryable knowledge for the next, with handoffs guaranteeing at-least-once delivery between agents.

## The Four Stages of the Memory Loop

### Capture: Ingesting Agent Observations

The **Capture** stage serves as the only trusted entry point into the system. When an agent emits lifecycle-hook events such as `SessionStart`, `UserPrompt`, or `PostToolUse`, the `ai-memory hook` command posts a JSON payload to `POST /hook`. 

According to the implementation in [`crates/ai-memory-hooks/src/lib.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-hooks/src/lib.rs), the hook router sanitizes the payload, assigns an `ObservationKind`, and enqueues a `WriteCmd` to the single-writer SQLite actor. Simultaneously, the observation is appended to [`log.md`](https://github.com/akitaonrails/ai-memory/blob/main/log.md), establishing the markdown wiki as the immutable source of truth while the SQLite index remains a derived layer.

### Consolidate: Synthesizing Structured Knowledge

When a `SessionEnd` event triggers, the **Consolidate** stage transforms raw observations into structured wiki content. The system first synthesizes a summary page at `sessions/<id>.md`. If `AI_MEMORY_LLM_PROVIDER` is configured, the `memory_consolidate` tool (implemented in [`crates/ai-memory-consolidate/src/lib.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/lib.rs)) rewrites this summary into richer, multi-page documentation under directories like `concepts/`, `decisions/`, and `gotchas/`.

The consolidation prompts preserve the source language and instruct the LLM to link related pages, creating a navigable knowledge graph from ephemeral session logs.

### Recall: Retrieving Context Across Sessions

The **Recall** stage enables agents to query accumulated knowledge through the `memory_query` interface. As defined in [`crates/ai-memory-store/src/query.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/query.rs), retrieval runs a combined pipeline:

- **FTS5** full-text search
- **Entity-match** filtering
- **Link-neighbour** RRF (Reciprocal Rank Fusion)
- Optional **vector similarity** when an embedder is configured

Result sets undergo optional re-ranking when `AI_MEMORY_RERANKER=llm` is set, and matched pages update their access counters to track knowledge utilization.

### Handoff: Transferring State Between Agents

After `SessionEnd`, the **Handoff** stage creates a transfer record pointing to the next agent. Handoffs can be explicit via `memory_handoff_begin` or automatic (opened on the receiving agent's next `SessionStart`). 

Defined in [`crates/ai-memory-core/src/routing_skills/ai-memory-handoff/SKILL.md`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/routing_skills/ai-memory-handoff/SKILL.md), the receiving agent lists open handoffs via `memory_handoff_list` and claims one through `memory_handoff_accept`. This triggers the same write-path as normal observations, ensuring atomic recording without blocking the agent's hot path.

## Operational Workflow: Commands and Implementation

The loop operates asynchronously—capture events are fire-and-forget, consolidation runs in the background, recall is read-only, and handoffs use tiny transactional rows. Here is the complete workflow in practice:

```bash

# 1. Capture – emit a lifecycle event (CLI handles this automatically)

ai-memory hook --event session-start --payload '{"cwd":"/path/to/project"}'

# 2. Consolidate – trigger LLM rewriting of the session summary

ai-memory memory_consolidate --session-id $(ai-memory status --last-session-id)

# 3. Recall – search the knowledge base for specific concepts

ai-memory memory_query "how to retry failed HTTP calls"

# 4. Handoff – initiate transfer to the next agent

ai-memory memory_handoff_begin --session-id $(ai-memory status --last-session-id)

# On the receiving agent, list and accept pending handoffs

ai-memory memory_handoff_list
ai-memory memory_handoff_accept --handoff-id 42

```

## Core Source Files and Architecture

The following files implement the capture-consolidate-recall-handoff cycle:

| File | Role in the Loop |
|------|------------------|
| [`docs/ARCHITECTURE.md`](https://github.com/akitaonrails/ai-memory/blob/main/docs/ARCHITECTURE.md) | Master documentation describing the steady-state loop and phase interactions |
| [`crates/ai-memory-hooks/src/lib.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-hooks/src/lib.rs) | Implements the `/hook` endpoint, payload sanitization, and `WriteCmd` enqueuing |
| [`crates/ai-memory-consolidate/src/lib.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/lib.rs) | Core LLM logic that rewrites session summaries into structured wiki pages |
| [`crates/ai-memory-store/src/query.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-store/src/query.rs) | Retrieval pipeline using FTS5, entity matching, link-neighbour RRF, and optional vector search |
| [`crates/ai-memory-core/src/routing_skills/ai-memory-handoff/SKILL.md`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-core/src/routing_skills/ai-memory-handoff/SKILL.md) | MCP tool definitions for handoff operations |

## Summary

- The **capture-consolidate-recall-handoff loop** provides ai-memory's cross-session persistence through four distinct, asynchronous stages.
- **Capture** sanitizes and logs observations via `POST /hook`, writing simultaneously to [`log.md`](https://github.com/akitaonrails/ai-memory/blob/main/log.md) and the SQLite queue.
- **Consolidation** transforms raw logs into structured wiki pages under `sessions/`, `concepts/`, and `decisions/` when LLM providers are available.
- **Recall** combines FTS5, entity matching, and RRF ranking to retrieve relevant context through `memory_query`.
- **Handoffs** use transactional records (`memory_handoff_begin`, `memory_handoff_accept`) to ensure state transfers atomically between agents without blocking execution paths.

## Frequently Asked Questions

### What triggers the consolidation stage in ai-memory?

The consolidation stage triggers automatically when the system processes a `SessionEnd` event. At this point, ai-memory synthesizes a session summary page, and if `AI_MEMORY_LLM_PROVIDER` is configured, the `memory_consolidate` tool rewrites the content into structured wiki pages with cross-references.

### How does ai-memory ensure data consistency between the markdown wiki and SQLite index?

The architecture maintains the invariant that the markdown wiki is the source of truth while SQLite serves as a derived searchable layer. All write operations append to [`log.md`](https://github.com/akitaonrails/ai-memory/blob/main/log.md) first, then enqueue to the single-writer SQLite actor, ensuring the index never diverges from the underlying markdown files.

### Can agents query semantic meaning or only exact text matches?

Agents can query using both semantic and lexical methods. The `memory_query` implementation combines FTS5 full-text search with optional vector similarity when an embedder is configured, plus entity-matching and link-neighbour analysis using Reciprocal Rank Fusion (RRF) to blend multiple relevance signals.

### What happens if an agent crashes before accepting a handoff?

Handoffs are designed for at-least-once delivery durability. The handoff record persists as a transactional row in the database until explicitly claimed via `memory_handoff_accept`. If the receiving agent crashes, the handoff remains available in `memory_handoff_list` for the next connection attempt.