ADR-0195shipped

Mandatory Memory Participation Contract

Status: accepted Date: 2026-03-02 Deciders: Joel Hooks, Panda Related: ADR-0021, ADR-0068, ADR-0077, ADR-0082, ADR-0094

Context

The memory system exists (ADR-0021, ADR-0082) but participation is opt-in. Skills can remind agents to use recall/observe, but nothing enforces it. In practice:

  • Sessions start cold when the agent forgets to recall
  • Compactions and session ends often skip observation
  • There’s no telemetry proving memory is actually being used
  • Silent memory failures are invisible — the agent just operates without context

Opt-in memory is no memory. The system has the pipeline but no enforcement.

Reference spec: https://joelclaw.com/the-memory-system.md

Decision

1. Gateway Role Hard Rules

Add to gateway ROLE.md / system prompt as non-negotiable:

  • Every session MUST retrieve memory on start. No cold-start sessions. Recall fires automatically.
  • Every session MUST observe on compaction and end. No silent sessions. Observations are extracted from every session.
  • Recall before responding to any non-trivial human question. Trivial = greetings, acks, heartbeats. Everything else gets a recall check.
  • Memory write failures are first-response priority. Same severity as deploy failures. If observe/store fails, fix it before other work.

2. Pi Extension Enforcement

Implement memory hooks in the pi-tools extension (packages/pi-extensions/):

HookAction
session_startAuto-fire recall with session context seed query
agent_startInject recall results into first-turn context
compaction eventAuto-fire observe on compacted content
session_shutdownAuto-fire observe on session transcript
tool_call (recall)Wrap with OTEL span, log query + params
tool_result (recall)Tag results with retrieval metadata (count, latency, budget)
observe failureEmit error OTEL event, log to gateway

The extension makes memory participation involuntary. The agent doesn’t choose to remember — the harness ensures it.

3. OTEL Instrumentation

Every memory operation emits structured telemetry to the otel_events collection:

Recall events:

  • memory.recall.started — query, budget profile
  • memory.recall.completed — result count, latency_ms, top categories
  • memory.recall.failed — error, query

Observe events:

  • memory.observe.started — session_id, trigger (compaction/shutdown)
  • memory.observe.completed — facts extracted, allow/hold/discard counts, duration_ms
  • memory.observe.failed — error, session_id

Write gate events:

  • memory.gate.decision — observation hash, verdict, confidence

Health targets (enforced via o11y triage):

  • Sessions without recall: 0
  • Sessions without observe: 0
  • Observe failure rate: < 5%
  • Recall p95 latency: < 3s

Consequences

Good

  • Memory becomes structural, not behavioral — can’t be forgotten
  • OTEL proves actual usage, not just capability
  • Extension hooks are the enforcement layer — no prompt compliance needed
  • Health targets make memory regressions visible in o11y triage (ADR-0090)

Tradeoffs

  • Extension complexity increases — more hooks, more failure modes
  • Recall on every session start adds latency (~1-3s)
  • Observe on every compaction adds inference cost
  • If the memory pipeline is down, sessions may be blocked or degraded

Mitigations

  • Recall has hard timeout (3s) — degrade to no-memory rather than block
  • Observe is async — doesn’t block session end, fires as background Inngest function
  • Circuit breaker: if memory pipeline has >3 consecutive failures, degrade gracefully and emit alert

Implementation Sequence

  1. ADR-0195 accepted ← here
  2. Update gateway ROLE.md with hard rules
  3. Implement extension hooks in pi-tools (session_start recall, shutdown observe)
  4. Add OTEL spans to recall/observe tool calls
  5. Add health targets to o11y triage patterns
  6. Verify with joelclaw otel search "memory." — all events flowing
  7. Monitor for 7 days, tune timeouts and circuit breaker thresholds

2026-03-04 Reality Check

Status updated to shipped.

What’s running

  • ~/.pi/agent/extensions/memory-enforcer/index.ts — pi extension in production
  • session_start hook: fires joelclaw recall with seed query, injects results into first turn
  • session_shutdown hook: fires memory/observe.requested via joelclaw send
  • before_agent_start hook: queries system_knowledge via joelclaw knowledge search
  • OTEL events emitted: memory.recall.started/completed/failed, memory.observe.requested/failed, system_knowledge.retrieval.started/completed/failed

Gap: no automated verification of hook success rate

  • OTEL events exist but no scheduled check compares “sessions started” vs “recalls fired”
  • knowledge-watchdog (every 4h) checks retrieval events in window but not session-level coverage
  • Next step: add session coverage check to knowledge-watchdog (ADR-0200 F/E/V verify layer)