Mental Model

Mental Model

How to think in CellState. Read this first if you’re new to the codebase.

For system internals, see ARCHITECTURE.md.

Core Philosophy

CellState is a hierarchical memory framework for AI agents. It models memory the way humans remember: some things are fleeting (what you had for breakfast), others persist (how to ride a bike).

The key insight: Turns are cheap and disposable. Artifacts and Notes are valuable and persist.

The Hierarchy

TENANT (isolation boundary — one per organization)
  └── TRAJECTORY (task/goal — like a project folder)
        ├── SCOPE (context window — like a conversation)
        │     ├── TURN (ephemeral — dies when scope closes)
        │     └── TURN
        ├── ARTIFACT (persists — important outputs)
        └── NOTE (cross-trajectory knowledge)

Entity Lifespans

EntityLifespanAnalogy
TenantPermanentYour organization
TrajectoryTask durationA project folder
ScopeSessionA conversation thread
TurnScope onlyIndividual messages (deleted when scope closes)
ArtifactConfigurable TTLSaved documents
NoteCross-trajectoryLearned knowledge

Memory Types

TypeMaps ToLifespanExample
EphemeralTurnsScope only”The user just asked about X”
WorkingActive scopeSession”We’re debugging the auth flow”
EpisodicArtifactsConfigurable”I fixed bug #123 yesterday”
SemanticNotesLong-term”TypeScript requires strict types”
ProceduralNotes (procedure type)Permanent”How to deploy to production”

What Survives When a Scope Closes?

  • Turns are deleted (ephemeral conversation)
  • Artifacts survive (extracted value)
  • Notes survive (learned knowledge)

Before closing a scope, extract valuable information into Artifacts or Notes.

Abstraction Levels (L0 → L1 → L2)

Information compresses upward as context fills:

LevelNameScopeExample
L0RawSingle turn/artifactDirect observations
L1SummaryWithin trajectorySynthesized from multiple L0s
L2PrincipleCross-trajectoryHigh-level abstractions
L0 (Raw):      "User asked about error handling in turn 3, wanted try/catch"
L1 (Summary):  "This trajectory focused on error handling patterns in TypeScript"
L2 (Principle): "Always validate at system boundaries, fail fast internally"

L2 principles survive with minimal tokens. “Always validate inputs” is cheaper than storing 50 examples of input validation.

Token Budget Flow

Each Scope tracks token usage against a budget:

Scope(token_budget=8000)
  ├─ Turn(500 tokens) → used: 500
  ├─ Turn(400 tokens) → used: 900
  ├─ Turn(600 tokens) → used: 1500
  ├─ ...
  └─ When 80% full → trigger summarization

Summarization triggers: token threshold exceeded, scope closing, turn count threshold, artifact count threshold, or manual API trigger.

TTL (Time-to-Live)

Persistent    — never expires
Session       — expires when session ends
Scope         — expires when scope closes
Ephemeral     — alias for Scope
ShortTerm     — ~1 hour
MediumTerm    — ~24 hours
LongTerm      — ~7 days
Permanent     — alias for Persistent
Duration(ms)  — custom milliseconds

Multi-Agent Coordination

Delegation (Sub-task)

Agent A needs specialist help → creates Delegation to Agent B → Agent B works in a child trajectory → returns artifacts and result to Agent A.

Handoff (Transfer Control)

Agent A transfers full context to Agent B → Agent B takes over the trajectory → Agent A steps back. Use for escalation.

Message (Async Communication)

Agent A sends a notification/query to Agent B → Agent B processes when ready. Non-blocking.

Lock (Exclusive Access)

Agent A acquires an exclusive or shared lock on a resource → other agents wait → release when done. Prevents conflicts.

Graph Relationships (Edges)

Entities can be linked with typed relationships:

Edge TypeMeaningExample
SupportsA backs up BArtifact supports Note
ContradictsA conflicts with BTwo conflicting facts
SupersedesA replaces BUpdated artifact
DerivedFromA came from BSummary from turns
RelatesToGeneric relationRelated topics
SynthesizedFromOutput from multiple inputsL1 from multiple L0s

Mutation Pipeline

All writes flow through a 4-stage pipeline (see ARCHITECTURE.md for details):

  1. Assemble — fetch context and policy config (I/O)
  2. Gates — run pure policy checks (no I/O)
  3. Commit — atomic database transaction
  4. Receipt — return proof, broadcast event

Gates are pure functions. They receive a frozen ValidationContext and return Pass or Reject. No async, no database calls. This makes policy enforcement deterministic and testable.

Common Patterns

Task Execution

1. Create Trajectory (name="Fix bug #123")
2. Create Scope (token_budget=8000)
3. Add Turns (conversation with user/tools)
4. Extract Artifacts (code changes, decisions)
5. Close Scope (turns deleted, artifacts persist)
6. Complete Trajectory (outcome recorded)

Knowledge Extraction

1. During work, identify reusable knowledge
2. Create Note with type:
   - Convention: "Always use async/await, not .then()"
   - Strategy: "Start with tests for complex features"
   - Gotcha: "The API returns 500 for auth failures, not 401"
3. Link to source artifacts/trajectories
4. Note persists across all future trajectories

Context Management

1. Check scope.tokens_used vs scope.token_budget
2. If approaching limit (>80%):
   a. Summarize old turns → create Summary artifact
   b. Create Note with L1/L2 abstractions
   c. Close scope, open new one
3. New scope starts fresh but artifacts/notes persist

Quick Reference

When to Create What

SituationCreate
Starting a new taskTrajectory
Beginning conversationScope
Each message exchangeTurn
Valuable output (code, decision)Artifact
Reusable knowledgeNote
Sub-task for specialistDelegation
Transfer control completelyHandoff
Async notificationMessage
Prevent conflictsLock

What Persists?

EntityAfter Scope CloseAfter Trajectory Complete
TurnDeletedDeleted
ArtifactPersistsPersists
NotePersistsPersists
ScopeRecord remainsRecord remains
TrajectoryRecord remains

API Endpoints

ResourceEndpoints
TrajectoriesPOST /trajectories, GET /:id, PATCH, DELETE
ScopesPOST /scopes, GET, PATCH, POST /:id/close
TurnsPOST /turns, GET /:id
ArtifactsPOST /artifacts, GET, PATCH, DELETE, POST /batch
NotesPOST /notes, GET, PATCH, DELETE, POST /batch
AgentsPOST /agents/register, POST /heartbeat, DELETE
LocksPOST /locks/acquire, DELETE /release, PATCH /extend
MessagesPOST /messages, GET, POST /:id/acknowledge
DelegationsPOST /delegations, POST /:id/accept, /:id/complete
HandoffsPOST /handoffs, POST /:id/accept, /:id/complete
ContextPOST /context/assemble
SearchPOST /search
Pack ConfigPOST /pack-config/validate, POST /pack-config/parse

Interactive API docs: build with --features openapi,swagger-ui and visit /docs.

Diagrams

%% Domain concept model -- the battery metaphor mapped to real types %% Dotted arrows indicate conceptual mapping, not code relationships graph LR classDef runtime fill:#7733cc,color:#fff,stroke:#8844dd,stroke-width:2px classDef state fill:#22b37a,color:#fff,stroke:#2ed198,stroke-width:2px classDef event fill:#e85a2a,color:#000,stroke:#cc4418,stroke-width:2px classDef storage fill:#1fad8f,color:#fff,stroke:#26d9b3,stroke-width:2px classDef default fill:#1a1a2e,color:#fff,stroke:#353548,stroke-width:1px subgraph Metaphor Cell[Cell
State Container] Pack[Pack
Module Bundle] Circuit[Circuit
Execution Flow] Receipt[Receipt
Mutation Proof] end subgraph System Types Scope[Scope] Trajectory[Trajectory] MutPipeline[MutationPipeline] ReceiptEnv[ReceiptEnvelope] PackManifest[PackManifest] CompiledConfig[CompiledConfig] EventDAG[Event DAG] CircuitBreaker[CircuitBreaker] end Cell -.-> Scope Cell -.-> Trajectory Pack -.-> PackManifest Pack -.-> CompiledConfig Circuit -.-> MutPipeline Circuit -.-> EventDAG Circuit -.-> CircuitBreaker Receipt -.-> ReceiptEnv
Concept Model
graph TD classDef runtime fill:#7733cc,color:#fff,stroke:#8844dd,stroke-width:2px classDef state fill:#22b37a,color:#fff,stroke:#2ed198,stroke-width:2px classDef event fill:#e85a2a,color:#000,stroke:#cc4418,stroke-width:2px classDef storage fill:#1fad8f,color:#fff,stroke:#26d9b3,stroke-width:2px classDef default fill:#1a1a2e,color:#fff,stroke:#353548,stroke-width:1px FBF[the/FBF
Research Lab] BP[batterypack.dev
Dev Tools + SDK] CS[CellState
Agent Memory Infrastructure] FBF --> BP FBF --> CS BP --> SDK[TypeScript SDK] BP --> PythonSDK[Python SDK] BP --> CLI[CLI Tools] CS --> Pipeline[Mutation Pipeline] CS --> EventDAG[Event DAG] CS --> PackCompiler[Pack Compiler] CS --> PGExt[PostgreSQL Extension]
Ecosystem
%% Crate dependency graph -- reflects actual Cargo.toml workspace deps graph TD classDef runtime fill:#7733cc,color:#fff,stroke:#8844dd,stroke-width:2px classDef state fill:#22b37a,color:#fff,stroke:#2ed198,stroke-width:2px classDef event fill:#e85a2a,color:#000,stroke:#cc4418,stroke-width:2px classDef storage fill:#1fad8f,color:#fff,stroke:#26d9b3,stroke-width:2px classDef default fill:#1a1a2e,color:#fff,stroke:#353548,stroke-width:1px core[cellstate-core
Domain Types + Event DAG] pcp[cellstate-pcp
Validation + Checkpointing] storage[cellstate-storage
LMDB Cache + Traits] pipeline[cellstate-pipeline
Pack Compiler] pg[cellstate-pg
PostgreSQL 18 Extension] api[cellstate-api
REST + WebSocket Server] cli[cellstate-cli
CLI Binary] test_utils[cellstate-test-utils
Proptest Generators] sdk[cellstate SDK
Rust Re-exports] fuzz[cellstate-fuzz
Fuzzing Harness] pcp --> core storage --> core pipeline --> core pipeline --> pcp pg --> core api --> core api --> pcp api --> storage api --> pipeline cli --> pipeline test_utils --> core test_utils --> pcp sdk --> core sdk --> pcp fuzz --> core fuzz --> pipeline
Workspace