# How `memory_consolidate` with `multi_page: true` Rewrites Sessions into Atomic Multi-Page Updates in ai-memory

> Learn how memory_consolidate with multi_page true transforms sessions into atomic multi-page updates in ai-memory via a single LLM request and SQLite transaction.

- Repository: [Fabio Akita/ai-memory](https://github.com/akitaonrails/ai-memory)
- Tags: internals
- Published: 2026-08-22

---

**Enabling `multi_page: true` switches the consolidator from a single-page rewrite to an atomic batch operation that updates multiple wiki pages simultaneously using one LLM request wrapped in a single SQLite transaction.**

When working with the `ai-memory` repository, the `memory_consolidate` function transforms raw session observations into a structured wiki. By default, the system performs a single-page rewrite (M7a), but activating `multi_page: true` (via the `--multipage` CLI flag or library argument) engages the **M7b multi-page atomic fan-out** mode. This architecture distributes session observations across concepts, decisions, gotchas, and other slots atomically, ensuring consistency across the entire knowledge base.

## What Changed in Multi-Page Mode?

The consolidation engine shifts from isolated page updates to a **batch-oriented workflow**. Instead of processing the session against a single target page, the system builds a comprehensive prompt that includes the session observations plus the current contents of all relevant slots. The LLM returns a structured `ConsolidatedBatch` containing individual updates for each affected page.

The key differences from single-page mode include:

- **Batch LLM requests** rather than individual prompts per page
- **Atomic writes** via `wiki.apply_batch` in one SQLite transaction
- **Per-user namespace routing** for slot updates based on identity
- **Dry-run capabilities** that preview the scope without consuming tokens

## Atomic Transaction Processing

All page updates execute within a single database transaction. In [`crates/ai-memory-consolidate/src/consolidator.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/consolidator.rs), the `consolidate_session_multi` function (lines 14-44) invokes `wiki.apply_batch` to write every update atomically. Either every page is created or updated successfully, or the entire transaction rolls back—preventing partial states if one update violates constraints.

This approach contrasts with sequential single-page updates that could leave the wiki in an inconsistent state if interrupted.

## Admission Checks and Slot Handling

Before invoking the LLM, the consolidator performs an admission pre-flight check using the session page as the anchor. This verifies the caller has authorization to modify the entire batch scope.

The system then gathers current slot states via `slot_snapshots` (lines 71-104 in [`consolidator.rs`](https://github.com/akitaonrails/ai-memory/blob/main/consolidator.rs)). If `per_user_slots` is enabled, each update undergoes `slot_placement` evaluation. Updates may be redirected to personal namespaces (e.g., `_slots/<identity>/...`) or discarded if they would write into another operator’s namespace, enforcing strict isolation boundaries.

## Dry-Run Preview Mode

When `dry_run` is set to `true`, the function returns a preview containing only the canonical session anchor (`sessions/<id>.md`) and skips the LLM call entirely. This allows callers to discover the resolved scope and affected pages without spending tokens, providing a safe way to validate permissions and routing logic before execution.

## Implementation Details

The M7b architecture is documented in the header comments of [`crates/ai-memory-consolidate/src/consolidator.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/consolidator.rs) (lines 9-10): "M7b extends this to multi-page atomic fan-out."

The transformation logic resides in the loop starting at line 78, which processes each LLM-produced update into a write request while handling per-user slots and invariants. The outcome is a `Vec<ConsolidationOutcome>`—one element per page—containing the new title, body, page ID, and tags.

**Key source files:**

- [`crates/ai-memory-consolidate/src/consolidator.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/consolidator.rs) - Core implementation of `consolidate_session_multi`
- [`crates/ai-memory-consolidate/src/types.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/types.rs) - Definitions for `ConsolidatedBatch` and `ConsolidatedPageUpdate`
- [`crates/ai-memory-mcp/src/server.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/server.rs) - HTTP request parsing for the `multipage` flag
- [`crates/ai-memory-mcp/src/admin.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-mcp/src/admin.rs) - Admin endpoint exposure for CLI integration

## Usage Examples

**Command Line Interface:**

```bash

# Consolidate session ID 123 into multiple pages atomically

ai-memory consolidate --session 123 --multipage

# Preview affected pages without invoking the LLM

ai-memory consolidate --session 123 --multipage --dry-run

```

**Rust Library:**

```rust
use ai_memory_consolidate::Consolidator;

async fn run_multi_page(consolidator: &Consolidator, session: SessionId) -> anyhow::Result<()> {
    // Execute real consolidation (dry_run = false)
    let outcomes = consolidator
        .consolidate_session_multi(
            session,
            false,                     // dry_run
            ActorContext::default(),
            None,                      // author
            None,                      // instructions
        )
        .await?;

    for outcome in outcomes {
        println!("Updated {} – title: {}", outcome.path, outcome.new_title);
    }
    Ok(())
}

```

## Summary

- **`memory_consolidate` with `multi_page: true`** triggers atomic multi-page fan-out instead of single-page rewrites
- **Single SQLite transaction** ensures all pages update together or fail together via `wiki.apply_batch`
- **Batch LLM architecture** sends session data plus slot snapshots in one request, receiving structured updates for multiple pages
- **Per-user slot routing** enforces namespace isolation through `slot_placement` checks
- **Dry-run mode** previews the consolidation scope without API costs
- **Source implementation** lives in [`crates/ai-memory-consolidate/src/consolidator.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/consolidator.rs) with core logic in `consolidate_session_multi`

## Frequently Asked Questions

### What is the difference between M7a and M7b consolidation modes?

M7a performs a single-page rewrite targeting one specific wiki page, while M7b (activated by `multi_page: true`) executes a multi-page atomic fan-out that updates all relevant slots simultaneously. According to the source code in [`consolidator.rs`](https://github.com/akitaonrails/ai-memory/blob/main/consolidator.rs), M7b uses a batch request containing the session observations and current slot contents, then applies all updates in one atomic transaction.

### How does `multi_page: true` handle errors during the batch write?

The system uses `wiki.apply_batch` to wrap all page updates in a single SQLite transaction. If any individual page update fails—whether due to constraint violations, namespace conflicts, or IO errors—the entire transaction rolls back. This guarantees that the wiki never contains partial consolidation results, maintaining referential integrity across concepts, decisions, and gotchas.

### Can I see which pages will be affected before running the LLM?

Yes. Set `dry_run = true` (or use the `--dry-run` CLI flag). In this mode, `consolidate_session_multi` returns a preview containing the canonical session anchor path without invoking the LLM. This lets you verify the resolved scope and authorization boundaries before spending tokens on the actual consolidation.

### Where does the multi-page consolidation logic live in the codebase?

The primary implementation resides in [`crates/ai-memory-consolidate/src/consolidator.rs`](https://github.com/akitaonrails/ai-memory/blob/main/crates/ai-memory-consolidate/src/consolidator.rs). The `consolidate_session_multi` function (lines 14-44) orchestrates the flow, while `slot_snapshots` (lines 71-104) gathers current slot states. The M7b design is documented in the header comments (lines 9-10) and the transformation loop begins at line 78.