# Headroom Memory Scope Levels: USER, SESSION, AGENT, and TURN Explained

> Explore Headroom memory scope levels: USER, SESSION, AGENT, and TURN. Understand how each level controls data persistence and visibility, from permanent user data to ephemeral turn context.

- Repository: [Tejas Chopra/headroom](https://github.com/chopratejas/headroom)
- Tags: deep-dive
- Published: 2026-06-12

---

**Headroom supports four hierarchical memory scope levels—USER, SESSION, AGENT, and TURN—that control persistence and visibility from permanent user data to ephemeral turn-level context.**

The `chopratejas/headroom` repository implements a sophisticated memory management system using distinct **memory scope levels** to determine exactly how long information persists and where it remains visible across the application. These hierarchical scopes ensure AI agents access appropriate context at the right time, balancing long-term user knowledge against temporary conversation state.

## The Four Memory Scope Levels

Headroom defines memory scope levels as an enum in [`headroom/memory/models.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py), with each level representing a different longevity and visibility boundary.

### USER Scope

The **USER** scope persists across all sessions for a given user. Memories at this level act as permanent user preferences or facts that should survive individual conversations. According to the source code, this is defined at [`ScopeLevel.USER`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py#L20) in [`headroom/memory/models.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py).

### SESSION Scope

The **SESSION** scope persists only within a single task or conversation, making it ideal for temporary context that should survive multiple turns but disappear when the user starts a new chat. This level is defined at [`ScopeLevel.SESSION`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py#L21).

### AGENT Scope

The **AGENT** scope persists for the lifetime of a particular agent instance. This allows specific agent configurations or learned behaviors to remain available throughout the session without polluting global user memory. The constant is defined at [`ScopeLevel.AGENT`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py#L22).

### TURN Scope

The **TURN** scope is ephemeral, living only for the duration of a single LLM call. This is perfect for temporary facts or intermediate computations that should not persist beyond the immediate response. This is defined at [`ScopeLevel.TURN`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py#L23).

## Creating Memories at Specific Scope Levels

When instantiating the `Memory` class from [`headroom/memory/models.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py), you define the scope implicitly by providing specific ID combinations. The system automatically determines the appropriate scope based on which IDs are present.

```python
from headroom.memory.models import Memory, ScopeLevel

# USER scope: visible across all sessions (no session/agent/turn IDs)

user_mem = Memory(
    content="User's favorite color is blue",
    user_id="alice",
)

# SESSION scope: only for this conversation

session_mem = Memory(
    content="Current task is summarizing a PDF",
    user_id="alice",
    session_id="sess-1234",
)

# AGENT scope: tied to a specific agent instance

agent_mem = Memory(
    content="Agent prefers concise responses",
    user_id="alice",
    session_id="sess-1234",
    agent_id="agent-xyz",
)

# TURN scope: ephemeral, disappears after the LLM call

turn_mem = Memory(
    content="Temporary fact for this turn only",
    user_id="alice",
    session_id="sess-1234",
    agent_id="agent-xyz",
    turn_id="turn-7",
)

```

## Querying Memories by Scope Level

The `MemoryStore` class in [`headroom/memory/core.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/core.py) uses `MemoryFilter` from [`headroom/memory/ports.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/ports.py) to retrieve memories filtered by specific scope levels. This allows precise context retrieval based on the current execution context.

```python
from headroom.memory.core import MemoryStore
from headroom.memory.ports import MemoryFilter
from headroom.memory.models import ScopeLevel

store = MemoryStore(...)  # concrete backend like SQLiteVectorIndex

# Retrieve only USER-level memories

user_memories = await store.query(
    MemoryFilter(user_id="alice", scope_levels=[ScopeLevel.USER])
)

# Retrieve SESSION-level memories for a specific conversation

session_memories = await store.query(
    MemoryFilter(
        user_id="alice", 
        session_id="sess-1234",
        scope_levels=[ScopeLevel.SESSION]
    )
)

```

## CLI Support for Memory Scopes

The command-line interface implemented in [`headroom/cli/memory.py`](https://github.com/chopratejas/headroom/blob/main/headroom/cli/memory.py) exposes scope level filtering through the `--scope` flag, allowing developers to inspect memories at different persistence levels directly from the terminal.

```bash

# List all USER-level memories for the current user

headroom memory list --scope user

# Show SESSION-level memories for a specific conversation

headroom memory list --scope session --session-id sess-1234

```

## Summary

- **Four hierarchical levels**: USER (permanent), SESSION (conversation), AGENT (instance), and TURN (ephemeral) provide fine-grained control over memory persistence.
- **Defined in [`headroom/memory/models.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py)**: The `ScopeLevel` enum at lines 20-23 establishes the contract used throughout the codebase.
- **Implicit scoping**: The `Memory` class automatically determines scope based on which ID fields (user_id, session_id, agent_id, turn_id) are populated.
- **Query filtering**: `MemoryFilter` in [`headroom/memory/ports.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/ports.py) accepts `scope_levels` parameters to retrieve contextually relevant memories.
- **Storage routing**: [`headroom/memory/storage_router.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/storage_router.py) resolves appropriate backends based on scope requirements and request context.

## Frequently Asked Questions

### What is the difference between SESSION and AGENT scope in Headroom?

SESSION scope persists for an entire conversation or task, while AGENT scope is tied to a specific agent instance that may span multiple sessions or be shorter than a full session. According to the implementation in [`headroom/memory/models.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py), SESSION requires a `session_id` whereas AGENT requires both `session_id` and `agent_id`.

### How does TURN scope improve performance in Headroom?

TURN scope prevents memory bloat by automatically discarding temporary facts after a single LLM call completes. As implemented in the storage layer, these ephemeral memories never reach persistent storage backends, reducing query overhead and storage costs for transient computational data.

### Can I query multiple memory scope levels simultaneously?

Yes, the `MemoryFilter` class accepts a list of `scope_levels`, allowing you to retrieve memories from multiple hierarchies in a single query. For example, you can query both USER and SESSION scopes together to get long-term preferences alongside current conversation context.

### Where is the ScopeLevel enum defined in the Headroom codebase?

The `ScopeLevel` enum is defined in [`headroom/memory/models.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/models.py) at lines 20-23, containing the four constants: USER, SESSION, AGENT, and TURN. This enum is imported throughout the codebase including [`headroom/memory/core.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/core.py) and [`headroom/memory/ports.py`](https://github.com/chopratejas/headroom/blob/main/headroom/memory/ports.py) to enforce type-safe scope handling.