ADR-008: Canonical Redis Key Schemas #

Status: Accepted Date: 2026-04-09 Linear: TOD-552 (engram #552)

Context #

The reverie mesh uses Redis for real-time coordination: log streaming, event audit trails, observation queues, and (planned) coord session/lock state. Key names are currently scattered as string literals across Rust code (log_fanout.rs, meshctl-tui), shell scripts (log-sidecar, coord-with-fanout), and documentation (protocol-v0.md, coord.proto).

Without a single source of truth, key names drift, collisions go undetected, and TTL/type expectations are implicit. This ADR defines the canonical schema and points to the redis_schemas module that enforces it in Rust code.

Decision #

All Redis keys used by the mesh follow the schemas below. New keys MUST be added here and to reverie_store::redis_schemas before use.

Key Catalog #

Sessions (coord backend — planned) #

KeyTypeTTLDescription
sessions:{pid}HASH600s refreshPer-session state: task, status, last_heartbeat, blob
sessions:indexZSETScore = last_heartbeat epoch; member = pid

Fields in sessions:{pid}: task, status, last_heartbeat, blob, registered_at, capabilities.

Locks #

KeyTypeTTLDescription
locks:{resource}STRING300sSET NX EX — value = owner pid
locks:project:{project}:{area}STRING300sScoped project lock (file-lock)

Task Queues #

KeyTypeTTLDescription
tasks:queue:{priority}LISTLPUSH/RPOP work items; priority ∈ {high, normal, low}
tasks:inbox:{peer}LISTPer-peer message inbox (coord send)

Event Streams #

KeyTypeTTLDescription
events:allSTREAMMAXLEN ~10000Global event bus
events:audit:wakeSTREAMMAXLEN ~10000Wake audit events (pseudoagent triggers)
events:audit:pseudoagent_wakeSTREAMMAXLEN ~10000Pseudoagent-specific wake events

Observation Queues #

KeyTypeTTLDescription
observations:queue:pendingSTREAMMAXLEN ~10000Observations awaiting consolidation
observations:queue:deadSTREAMMAXLEN ~10000Failed/rejected observations

Log Streams #

KeyTypeTTLDescription
logs:stream:{service}STREAMMAXLEN ~10000Per-service structured log stream

Pubsub channels (not keys, but part of the schema):

ChannelDescription
logs.{service}.{level}Real-time log fan-out; level ∈ {info, warn, error}

Metrics #

KeyTypeTTLDescription
metrics:{counter}STRINGAtomic INCR counters

Deduplication #

KeyTypeTTLDescription
seen:{hash}ZSETScore = epoch seen; member = content hash. Prune scores < now - 86400

Mesh Internal #

KeyTypeTTLDescription
reverie:env:logSTREAMMAXLEN ~10000Environment/runtime log stream
meshctl:prom:auditSTREAMMAXLEN ~10000Prometheus audit scrape results

Naming Conventions #

  1. Namespace separator: colon (:)
  2. Hierarchy: <domain>:<entity>:<qualifier>
  3. Dynamic segments: {placeholder} — always lowercase, no spaces
  4. No trailing colons
  5. Stream MAXLEN: always approximate (~) to avoid blocking on exact trim

TTL Policy #

Consequences #