# ADR-0001: Two-Tier Memory Architecture

## Status

Accepted

## Context

Multi-agent orchestration systems need memory to maintain consistency across runs and allow agents to "learn" from past work. However, uncontrolled memory leads to:

1. **Drift**: Agents gradually diverge from intended behavior
2. **Bad assumptions**: Outdated or incorrect information persists
3. **Security leaks**: Secrets accidentally stored in memory

We need a memory architecture that:
- Keeps the system consistent across runs and restarts
- Allows agents to learn from past work without bloating context
- Prevents uncontrolled writes that could corrupt system state
- Provides auditability and reversibility

## Decision

Implement a **two-tier memory architecture** plus ephemeral working memory:

### Tier 1: Operational Memory (Authoritative, Deterministic)

**Purpose:** Keep the system consistent across runs and restarts.

**Storage:**
- SQLite database: tasks, runs, approvals, health samples, usage
- `/ops/` directory files: project_state.json, ADRs, policies

**Contents:**
- Current project state and constraints
- Task history: what ran, who ran it, outcome, artifacts
- Approvals: who approved what, why
- Failures + fixes: error patterns and resolutions
- Agent capabilities registry

**Access:** Read by control loop first. Writes go through Memory Write Gate.

### Tier 2: Knowledge Memory (Retrieval-Based, Agent-Friendly)

**Purpose:** Let agents "learn" from past work without bloating context.

**Storage:**
- RAG index over `/ops/` directory (local embeddings or pgvector)

**Contents:**
- "How we do X here" runbooks
- Architecture decisions (ADR entries)
- Known pitfalls + patterns
- Standard prompts for each agent role
- Summaries of completed tasks

**Access:** Read-only by agents. Writes proposed as patches through Memory Write Gate.

### Tier 3: Working Memory (Per-Task Scratch)

**Purpose:** Keep context during a single run without polluting long-term memory.

**Storage:**
- In-memory dictionary + temp files

**Contents:**
- Transient notes ("I tried A; it failed; next try B")
- Tool outputs (test logs, error traces)

**Lifecycle:** Discarded or summarized into Knowledge memory at task end.

### Memory Write Gate

Agents cannot freely rewrite long-term memory. Instead:

1. Agents propose memory updates as patches (ADD, UPDATE, TAG)
2. Orchestrator validates: no secrets, fits schema, has evidence, passes risk rules
3. Patch risk classification determines routing:
   - LOW (tag fixes, formatting) → auto-apply
   - MEDIUM (content merges) → apply with review
   - HIGH (ADR/policy changes) → require approval

### Memory Hierarchy

| Tier | Name | Retention | Write Access |
|------|------|-----------|--------------|
| 0 | Immutable Audit | Never deleted | Admin only |
| 1 | Authoritative | Changes require approval | Through Write Gate |
| 2 | Working Knowledge | Librarian can modify | Through Write Gate |
| 3 | Ephemeral Cache | Auto-expire | Agent-writable |

## Consequences

### Positive

- System state is predictable and auditable
- Agents can "remember" without context bloat
- All memory changes are reversible (patches tracked)
- Secrets cannot leak into persistent memory
- Different agents see consistent world state

### Negative

- More complex than simple conversation history
- Requires maintaining RAG index
- Patch approval adds latency for HIGH-risk changes

### Risks

- RAG retrieval quality depends on embedding model
- Patch backlog if too many require approval
- Index can become stale if maintenance jobs fail

## Alternatives Considered

### 1. Model Memory (Conversation History)

Let the LLM "remember" in its conversation context.

**Rejected because:**
- Context windows fill up
- Not auditable
- Easy to leak secrets
- Different providers behave differently

### 2. Single-Tier Memory (Everything in SQLite)

Store all memory in a single database.

**Rejected because:**
- No separation between authoritative and derived data
- RAG retrieval harder to implement
- Harder to reason about what agents can/cannot modify

### 3. No Memory (Stateless Agents)

Treat all agents as completely stateless.

**Rejected because:**
- Loses valuable learning from past tasks
- Every task starts from scratch
- No way to capture "how we do things here"

## References

- Research on multi-agent memory systems
- RAG (Retrieval-Augmented Generation) best practices
- Architecture Decision Records (ADR) pattern
