Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased] #
Added #
- engram-backup.timer systemd user unit — runs
engram backupevery 6 hours with Persistent=true so missed triggers replay; installed viamake install-systemd
Fixed #
- mesh-spawn wrapper now supervises
claude -pwith quadratic backoff + 20-restart cap (TOD-724); sync installed copy with repo viamake install-mesh
[0.6.1] - 2026-04-16 #
Added #
- M12 complete — T64: Graceful degradation when engram DB is down.
/healthstays 200,/searchreturns empty, dream cycles retry with backoff. - meshctl dash: 3-line activity tail per worker (green tools / blue message types), git-tree column (
⚙ N ahead+ newest commit subject), blank separator between workers. JSON exposesactivity_tail[],commits_ahead_main,newest_commit.
Fixed #
- mesh-spawn queue drain loop now calls
coord heartbeatper iteration — fixes false-positive “Dead” status on queue workers that were still executing tools but not refreshinglast_heartbeat.
[0.6.0] - 2026-04-16 #
Added #
- M7 complete — Domain model & DDD migration
- T41:
EngramCompatStoreimplementsObservationReader,ObservationWriter,SearchBackend,TagStore,SessionRepositoryfrom reverie-domain - T42:
ChunkMetadatavalue object — neuroscience fields (strength, depth_score, session_spread, stability, consolidation_status) extracted from the domain Observation - T43:
ChunkKind,Layer,LayerRefmigrated to reverie-domain
- T41:
- M9 closed — Dream pipeline v2
- T52: Consolidation-status transitions (Staged→Consolidated→Archived) in the place phase
- T53:
DreamJournalstruct — structured markdown + JSON run reports
- M10 complete — Mesh coordination & file locking
- T54: File-lock integration tests (
scripts/file-lock-tests.sh) - T55: File-lock metrics — emit
lock.acquired/released/conflictto Redis fanout - T56:
file-lock detect-cycles <project>— wait-for graph deadlock detection - T57:
crates/reverie-lock— Rust port of the bash file-lock script
- T54: File-lock integration tests (
- M11 follow-ups
- T59: Structured span attributes on dream cycle phases (duration, candidates, counts)
- M12 partial — Production hardening
- T61: Chunk schema versioning enforced on deserialize with v1→v2 migration path
- T62:
reveried backup/reveried restoresubcommands + pre-dream auto-backup - T63: Dream-cycle rate limiting (30min min interval, queue-1, skip-if-running)
- Mesh automation
mesh-reapscript + systemd user timer — auto-reap dead sessions, orphan tmux, empty worktrees every 2 min (closes TOD-599)- Headless spawn by default in
mesh-spawn— workers run viasetsidinstead of tmux, only the anchor keeps a tmux session - Fan-out queue pool —
mesh-spawn --queuedrain-loop workers that pull tasks from the Redis mesh queue; one Claude session drains N tasks (saves ~50% cold starts) meshctl initexpands from 7→9 steps: adds auto-reaper enable (step 4) and fan-out pool spawn (step 6). Flags:--skip-reaper,--queue-workers <N>
- meshctl dash
- Per-session last-activity line (tool name + age from Claude jsonl logs) — surfaces false-positive “Dead” status on queue workers that haven’t heartbeated but are still working
- Respects
$COLUMNSenv for detached tmux sessions; clamps crossterm-reported width to [40, 160] Donehealth status (cyan) distinct fromDead— workers that markedblob.completed=truebut are idle post-task
- Automation agents
~/.claude/agents/mesh-fan-out/AGENT.md— dispatches backlog tickets to builder pool~/.claude/agents/reverie-deploy/AGENT.md— build → deploy → verify → optional push/release
- Tooling/CLI
- Dream CLI phases shipped (TOD-677):
reveried scan/classify/place/prune - Subagent-stop auto-capture hook shipped (TOD-405)
- Dream CLI phases shipped (TOD-677):
Fixed #
- coord register/heartbeat preserves top-level
rolefield on session rewrite (TOD-501) - meshctl dash task-phase extraction reads
current_task.phaseinstead of the missingtaskfield - meshctl dash
--jsonmode and non-TTY mode (piped output) — was crashing with ENXIO - Deploy path: scripts that copied to
~/.local/bin/engrammissed the actual systemd target~/.local/bin/reveried. Deploy agent now writes both. - reveried tests — serialize env-mutation tests behind a
Mutex(was flaky on parallel CI) - meshctl libc dep added (was calling
libc::killwithout declaring the crate)
Security #
- cargo-deny: bumped
bitstream-ioto drop yankedcore2transitive dep; bumpedrand0.8→0.9.4 (fixes RUSTSEC-2026-0097); bumpedopentelemetry0.27→0.31; allowedBSL-1.0for redis 1.2’sxxhash-rust - rustls-webpki 0.103.10→0.103.12 (RUSTSEC-2026-0098, RUSTSEC-2026-0099)
Changed #
- Dependencies:
redis0.27→1.2,toml0.8→1.1,procfs0.16→0.18, GitHub Actions bumps (checkout@6, upload-artifact@7) - CLAUDE.md: added knowledge-placement SOP, agent/worker lane rules, pre-commit discipline
- Milestone v0.5.0 (Linear) renamed to
v0.7.0 — Learned Intelligence Layerto free the label for the shipped v0.5.0 release
Reverted #
- Repo split into separate meshctl repo — both crates stay in the reverie workspace (cancels TOD-712, TOD-719)
[0.5.0] - 2026-04-15 #
Added #
- M8 complete — Multi-factor scoring engine
- T44: Strength as post-RRF multiplier in hybrid search
- T45: Depth weight (episodic 0.8x, consolidated 1.0x, semantic 1.2x)
- T46: Session spread weight
ln(1+spread)/ln(2)for cross-session signal - T47: Ebbinghaus stability decay in hybrid search ranking
- T48: Feature flags for all lifecycle scoring factors (strength/depth/spread/stability)
- M9 complete — Dream pipeline v2
- T49: SHY downscale phase (0.95x global scale, min_strength_floor pruning)
- T50: Ebbinghaus stability updates as StabilizePhase (SM-2 inspired formula)
- T51: Depth score promotion/demotion in place phase (1→2→3 with activity thresholds)
- T52: Consolidation status transitions (Staged→Consolidated→Archived)
- T53: DreamJournal structured output (markdown + JSON aggregated reports)
- M11 complete — Observability
- T58:
#[instrument]tracing spans on all async HTTP handlers - T59: Structured span attributes on dream cycle phases (duration, counts, candidates)
- T60: Prometheus metrics for scoring pipeline (search duration, factor counters, dream histograms)
- T58:
- M12 partial — Production hardening
- T62:
reveried backup/reveried restoresubcommands + pre-dream auto-backup - T63: Dream cycle rate limiting (30min min interval, queue-1, skip-if-running)
- T62:
- M7 partial — Domain model
- T43: Migrate ChunkKind, Layer, ConsolidationStatus to reverie-domain crate
Fixed #
- meshctl dash TUI: Terminal-width-aware rendering, ANSI-aware line truncation, non-TTY loop mode,
--jsonoutput,current_task.phaseextraction - CI: Updated bitstream-io 4.9→4.10 to drop yanked core2, removed stale license allowances from deny.toml
[0.4.1] - 2026-04-15 #
Added #
meshctl dash— Live terminal health dashboard polling coord sessions every 2s. Shows role, PID, health (Working/Idle/Dead with color), heartbeat age, dirty files, and task phase.- Auto-respawn CLI flag —
reveried serve --auto-respawnenables sleeper rebound for flatlined workers. ExpandedCANONICAL_ROLESto include memory, release, security, and research roles. - Hybrid search: depth_weight (T45) — Depth-based scoring in
ChunkStore::hybrid_search(): episodic (depth=1) → 0.8x, consolidated (depth=2) → 1.0x, semantic (depth=3) → 1.2x. - Hybrid search: spread_weight (T46) — Cross-session signal:
ln(1 + session_spread) / ln(2). Chunks accessed across many sessions rank higher.
Fixed #
- meshctl libc dependency — Added missing
libccrate dependency forpid_exists()function. - Clippy lints — Fixed
nonminimal_bool,write_literal,collapsible_ifin meshctl dash code.
Security #
- rustls-webpki — Updated 0.103.10 → 0.103.12 (RUSTSEC-2026-0098, RUSTSEC-2026-0099: URI name constraint and wildcard name constraint bypass).
[0.4.0] - 2026-04-10 #
Added #
- MeshState types + StateReducer — Typed graph state (
task_id,phase,outputs,checkpoint) with merge semantics.StateUpdatevariant inSleeperMessage. Foundation for all graph abstractions. (reverie-domain) - MeshNode trait + DispatchedNode — Async node interface for graph execution.
DispatchedNodewraps coord send/poll into typed node.PassthroughNodefor testing. (meshctl) - MeshGraph engine — Conditional edge routing with
EdgeConditionpredicates.MeshGraphBuilderwith fluent API and validation. Cycle guard (100 steps).single_node_graphbridge for backward compat. (meshctl) - Subgraph composition —
SubgraphNode(nested graph as node) +AggregateNode(parallel fan-out withmerge_union). Enables complex multi-role orchestration workflows. (meshctl) - Plan-and-execute —
meshctl execute --decomposedecomposes directives into subtask DAGs via heuristic planner.Plan/PlannedTasktypes with role routing per subtask. (meshctl) - Graph-aware checkpoints — Extended
Checkpointwithcurrent_node,edge_to,mesh_statefor graph resumption.GET /checkpoints/resume/:task_idendpoint. (reveried) - Coord protocol graph extensions —
--outputon reply (typedMeshState),--graphon request (graph context),--graph-stateon register (blob.graph_state). Backward-compatible. - Sleeper rebound activation —
on_health_eventwired totry_respawn. Agent watcher emits per-agentsleeper_flatlineevents. Rebound loads dream journal checkpoint and injects into respawned worker. - SleeperMessage into coord protocol —
coord send --typeflag (task/ping/reply/fault/checkpoint),coord recv --parseextracts type field. Executor uses typed dispatch. - Dream journal lifecycle hook —
PostToolUsehandler inworker-lifecycle-hook.shPOSTs checkpoints to reveried. Fire-and-forget via background curl.
Fixed #
- Mutex poison recovery — Replaced
.expect("state poisoned")with.unwrap_or_else(|e| e.into_inner())+ warning log in event handlers. Daemon no longer panics on recoverable state.
Security #
- HTTP input validation —
DefaultBodyLimit10MB globally. Session ID validation (128 chars, alphanumeric). Search query length limits. Returns 400 for invalid input.
[0.3.1] - 2026-04-10 #
Added #
- Sleeper abstraction — Renamed “pseudoagent” to “sleeper” across codebase, aligning with neuroscience theme. Added
SleeperWake/SleeperAckevent variants withWakeMethodenum. Newdocs/architecture/sleepers.mdspec with sleep-biology vocabulary. - SleeperMessage typed inbox —
SleeperMessageenum inreverie-domainwith 5 variants (Task, Ping, Reply, Fault, Checkpoint),Priority/TaskStatusenums, backward-compatibleparse()for legacy JSON. - Sleeper rebound infrastructure —
SleeperReboundhandler with per-role circuit breaker (max 3/hour), 30s grace period,SubToken::noop()for disabled state. Infrastructure-only —on_health_eventactivation deferred to v0.4.0. - Dream journal checkpointing —
POST/GET /checkpointsendpoints in reveried for persisting sleeper task progress. Keyed bysession_id, TTL-based expiry,by-rolelookup route. - Heartbeat semantics split — Split
last_heartbeatintolast_poked_at(anchor) +last_acked_at(sleeper). Backward-compatible dual-write. AgentWatcher preferslast_acked_atfor staleness. - Capability-based routing —
meshctl route <task>scores roles by keyword overlap with declared capabilities + idle-time bonus from coord sessions. - Executor semantics —
meshctl execute <directive>dispatches to best-fit sleeper via coord, polls for reply with exponential backoff retry (configurable timeout/retries). - Composable role specs — YAML
traits:section in mesh-roles config. Traits define reusable capability/tool sets; roles inherit viatraits: [...]with deduplication. - README overhaul — CI/license/MSRV badges, “Why Reverie?” section, grouped 15-crate workspace table (Core/Mesh/Observability/Benchmark), expanded quickstart.
Fixed #
- coord register/heartbeat role preservation (#61) — Re-register now uses read-modify-write to preserve
rolefield.blob_extradefaults to{}instead of empty string. - mem_save FK constraint (#60) — Lazy session creation via
INSERT OR IGNOREon first observation. Removed duplicate INSERT using rawp.session_id. - Rate-limit sharding (#62) — Rate limit key sharded by
project:session_id. Each mesh worker gets its own 10/min bucket. Empty session_id falls back to global bucket. - meshctl init layout — Replaced
tmux split-window -p(fails in non-TTY) with-labsolute sizing.
Changed #
- meshctl init cold-boot layout uses absolute pane sizes instead of percentage-based splits.
[0.3.0] - 2026-04-10 #
Added #
- 8-factor scoring engine — Multi-factor retrieval scoring replacing simple RRF + time-decay. Factors: semantic, lexical, recency, resonance (Ebbinghaus stability), importance (kind-weighted), session spread, hippocampal pattern separation, emotional valence. Configurable weights.
- Hippocampal encoding — DG sparse pattern separation (1024→4096-dim, 5% sparsity), CA1 novelty detection, CA3 pattern completion. Hamming distance for orthogonality checks.
- Emotional valence — 4D valence (urgency, certainty, blast_radius, relevance) on observations. Heuristic computation on ingest.
- Procedural memory — Learned workflows with steps, triggers, proficiency tracking. Domain entity + store variants + bench scenarios.
- Entity/relationship graph — Named entities (person/project/tool/concept) with aliases, entity links to observations, coreference resolution.
- Metacognitive audit — 7 health checks (recency bias, staleness,
duplication, layer misplacement, write churn, orphan rate, topic
concentration). CLI:
reveried audit [--fix]. - Token-budget search —
search_within_budget()greedy-fills results within a token budget. Engram-compat endpoint. - Time-decay in engram-compat — Port BM25 time-decay boost to the production search path (TOD-633/T37).
- Neuroscience fields on Observation — strength, stability, depth_score, session_spread, access_count, consolidation_status. Wired into sqlite-vec schema + scoring.
- Domain model extensions — ConsolidationStatus enum, Valence value object, Entity/EntityLink types, Procedure/Step/Trigger types, ScoringFactors/ScoredHit, 6 new repository trait ports.
- Dream cycle feedback loop — Consolidate phase persists strength deltas, place phase persists depth_score promotions, reconsolidation bumps stability on access.
- Ablation benchmarks — 8-config ablation matrix, CORTEX-style leaderboard table, regression gates per phase.
- meshctl status — Worker columns (type/dirty/commits/locks), MESH aggregate counters, COST line from mesh-cost, SESSION line (model/ context/tokens/turns), QUEUE line (pending/inflight/done/dead), TRACE section (eBPF kernel events from reverie-tracee), GPU VRAM usage, OpenRouter balance. Flicker-free pane rendering.
- meshctl sessions — Subcommands: clean (kill dead sessions, release orphan locks, remove empty worktrees), up (spawn canonical workers), down (teardown all workers).
- meshctl init — Rewritten to use mesh-spawn with deterministic registration. 5 canonical roles with worker types.
- Mesh tooling — mesh-spawn (worker lifecycle, —queue drain loop), mesh-enqueue (Redis stream XADD), mesh-drain (queue monitoring), mesh-cost (per-worker token tracking), mesh-heal (self-healing watchdog for 10 services), file-lock (file-level contention).
- Job queue — Redis STREAM-based task queue with consumer groups. Workers pull tasks via XREADGROUP, ACK on completion, dead letter on failure. Persistent drain loop mode.
- Kernel tracing — aquasec/tracee privileged container for eBPF events, reverie-tracee consumer aggregates per-process, wired into meshctl status.
- Self-healing — mesh-heal monitors reveried, redis, memcached, prometheus, grafana, tracee, ollama, coord-keeper. Auto-restart on failure, 60s loop.
- Worker lifecycle hooks — Stop hook auto-deregisters from coord and releases file locks. PreToolUse hook blocks edits on locked files.
- reverie-domain — New crate for pure DDD types and repository traits
(TOD-635). Hexagonal architecture: domain types (
Observation,ObservationId,TopicKey,Chunk,Tag), repository traits, and error types. No runtime dependencies — pure domain modeling. - reverie-discovery — New crate for shared service endpoint resolution. Layered chain: env var → systemd unit parsing → well-known defaults. Replaces hardcoded ports across meshctl, meshctl-tui, reverie-status-tui. 7 unit tests + 1 doctest.
- tracee start — New
startsubcommand for tracee with auto-start inrun. Simplifies daemon lifecycle management. - meshctl svc — Dynamic service reflection from systemd user units.
Subcommands: list, port, url, bind, status, health, env. JSON output
for scripting (
--json). - meshctl init step 3 — Auto-start reveried via systemd if not running. Health-check with 5s timeout, fail hard if unreachable.
- release.yml — CI/CD release pipeline with feature gate. Tag-triggered
(
v*or<crate>-v*), validates version against Cargo.toml, checks CHANGELOG entry, runs full CI, packages binaries, creates GitHub Release. - Independent crate versions — Tier A publishable crates (store, dream,
gate, sync, chunk, discovery, proto) get independent semver. Tier B internal
crates get
publish = false.
Changed #
- workspace deps — Converted all inter-crate dependencies to workspace references for consistent version management.
- meshctl init — Renumbered from 6 to 7 steps (new reveried ensure step). Ollama and reveried URLs resolved dynamically via reverie-discovery.
- meshctl init — Step 7 (was 6) sets up a canonical
reverie-anchortmux dashboard layout: 70% main pane, 30% right split for livemeshctl status -pand reveried log tail, plus a full-width heartbeat ticker bar at the bottom. New--attachflag execs into the anchor session after init completes.
Fixed #
- store: tag reads — Tags now returned on
GET /observations/:id;PATCHcorrectly replaces tags instead of appending (TOD-632). - store: search_by_tag — Added
supersedes/superseded_bycolumns to search_by_tag query, fixing column index 17 panic. - health endpoint — Use
CARGO_PKG_VERSIONinstead of hardcoded version string; addserde_yamlworkspace dependency. - meshctl-init.yml — Stale port 3031→7437 for reveried health check.
Documentation #
- ADR-005 — Search cutover plan + M6 backlog milestone (TOD-633, TOD-634).
- Backlog grooming — Mark T22/T23 done, T33 superseded, update T30 status.
Chore #
- MIT hygiene — NOTICE, DCO, SECURITY, CODEOWNERS, SPDX headers, publish guards across all crates.
[0.2.0] - 2026-04-09 #
Added #
- TOD-584 — Structured multi-tag system with faceted tag table. New
chunk_tagsSQLite table keyed on(chunk_id, facet, value)with indexes on facet+value and chunk_id. Store methods:add_tags,remove_tags,get_tags,search_by_tag. MCPmem_saveaccepts optionaltagsarray of{facet, value}objects. MCPmem_searchaccepts optionalfacetandtag_valueparameters for tag-filtered queries. Five standard facets (Domain, Project, Phase, Role, Severity) documented but not enforced. Fully backward compatible — existing observations work without tags. - TOD-486 —
/mem-distillskill (scripts/mem-distill.sh) for end-of-session reverie observation consolidation. Pulls recent observations via engram/context/smart, clusters by topic_key prefix (strips date/version suffixes), summarizes each cluster via~/.local/bin/llm-task summarize(gemma4:26b, zero cloud cost), and stages anchor observations as JSONL to/tmpfor operator review beforemem_save. Args:--since 6h --project reverie --dry-run --max-anchors 3. SKILL.md install to~/.claude/skills/requirescoord lock claude-config— defer to operator post-merge. - TOD-487 Phase 1 —
crates/reverie-llm-router/skeleton withLlmBackendtrait,CompletionRequest/CompletionResponse/Messagetypes, and aLocalLlamabackend that talks to any OpenAI-compatible local server. Defaults to the wizard’sreverie-ollamacontainer atlocalhost:11434runningqwen3-coder:30b(RTX 5090, GPU). Integration testtests/local_llama_smoke.rsverified end-to-end against the live ollama instance (~14s round-trip, model returnedPROXY OK). Phase 2 adds theRouter+RoutingPolicy; Phase 3 wraps it as an MCP server. - TOD-394 — Production-grade in-place upgrade infrastructure.
New
reveried upgradesubcommand orchestrates a graceful handoff: verifies a new binary, backs up the old one, atomically swaps it into place, SIGUSR2s the running daemon, polls/healthreading theX-Reveried-Pidresponse header until it reports the new PID, and rolls back on failure. Under the hood,serve_with_handoffreplaceshttp::serveon the hot path: binds the listener withSO_REUSEPORTso old and new daemons can co-bind the same port, writes a pidfile at~/.local/state/reveried/serve.pid, layers theX-Reveried-Pidheader onto every response viatower-http::set-header, and runs a SIGUSR2 handler that fork+execscurrent_exe()and triggers axum graceful shutdown. Engram had no upgrade pattern — this is greenfield. Complements the systemd supervisor + autoupgrade timer shipped under TOD-393 (PR #57): the systemd path handles crash recovery + scheduled upgrades, this path handles zero-downtime in-process upgrades for hot-deploys. - make dev — cargo-watch target that rebuilds reveried on every
source change (watching reveried, reverie-store, reverie-sync,
reverie-gate) and then invokes
scripts/dev-restart.shfor an atomic binary swap + health check. OverrideREVERIED_PORT/REVERIED_BINto run against a dev port without touching:7437. - scripts/dev-restart.sh — atomic dev-time daemon restart. Reads
PID from the pidfile, falls back to
pgrep, TERM-then-KILL, respawns via nohup, polls/healthfor up to 5s, reports elapsed time to healthy state. - TOD-455 — Operator dashboard scaffold (phase 1): SvelteKit app at
apps/dashboard/with Tailwind dark theme, 7 mock-data panels (peers, locks, work queues, event stream, alerts, metrics sparklines, reverie observations), and areveried serve --devflag that binds the HTTP daemon to port 7438 with permissive CORS forlocalhost:5173. Vite HMR round-trip measured at ~36ms. - TOD-456 —
coord register --role <name>and--blob '<json>'flags.--roleseedsblob.roleon the initial atomic write.--blobshallow- merges a JSON object onto the seeded blob; rejects arrays, scalars, and null with a clear error. Both apply on first register — no follow-upcoord updateround-trip needed. 9-test suite atscripts/coord_register_metadata_test.sh. - TOD-448 — Backfill
coord broadcast,coord project-lock, andcoord project-unlockindocs/coord/protocol-v0.md. Adds rows to the §5 operation table and a new §5a “Detailed subcommand reference” section documenting synopsis, semantics, error cases, and example usage for each. Unblocks the TOD-446coord-docs-syncCI check. Doc-only — noscripts/coordchanges. - TOD-431 —
coord updatesubcommand for mutating session state without re-registering. Supports--task <phase>,--status <pending|in_progress|blocked|done>,--blob '<json-obj>'(replace), and--blob '<json-obj>' --merge-blob(shallow merge). Refuses non-object blobs, lone--merge-blob, unknown flags, and missing session records. Writes are atomic via same-directorymktemp+mvso concurrent readers never see partial JSON. Tests inscripts/coord_update_test.sh(13 cases). - TOD-430 —
scripts/coordis now tracked in the repo (mirroring the installed~/.claude/bin/coordbinary) along withscripts/coord-tests.sh, a 33-case test suite covering strict-flag parsing across every subcommand. - TOD-441 — Coord audit log + observability.
scripts/coordnow appends a JSONL record to$COORD_ROOT/audit.logfor every mutating op (register,dereg,heartbeat,lock,unlock,steal,send,recv,project-lock,project-unlock), with atomic rename-based rotation at 10 MiB (3 files kept). Newcoord log tail|stats|locks|sessionquery subcommand andcoord metricsPrometheus endpoint (coord_sessions_live,coord_locks_held,coord_messages_sent_total,coord_messages_received_total). Full schema indocs/coord/observability.md; protocol doc updated with §9b. Pure bash + jq, no new deps. Tests inscripts/coord_audit_log_test.sh(13 cases, all passing).
Fixed #
- TOD-459 —
scripts/coordno longer collapses subagent sessions onto their parent’s record. The session-id resolver now honors aCOORD_SUBAGENT_IDenv var (suffixing derived ids asclaude-pid-<N>-sub-<tag>) and a newcoord register --as-subagent <name>flag, plus an explicitCOORD_SESSION_IDoverride at the top of the precedence chain. Previously, every subagent walked the same/proc/$$PPid chain to the parent Claude pid and stomped the parent’s task / heartbeat fields on everycoord registercall. New 6-case regression suite inscripts/coord_subagent_session_id_test.sh. Doc section “Subagent session ids” added todocs/coord/protocol-v0.md§11a. - TOD-430 —
coord dereg --session <peer>no longer silently deregisters the caller’s session. The dereg subcommand previously had no arg-parsing loop at all, so unknown flags were ignored and the command always acted on the caller. Allcoordsubcommands now hard-error on unknown flags and explicitly reject--sessionwith a pointer tocoord stealfor stale-lock recovery. Documented indocs/coord/protocol-v0.md§7 (“CLI flag handling (strict)”).
Changed #
- TOD-258 — Global SessionStart hook
(
~/.claude/hooks/engram-start.sh) now prefersGET /context/smartfor boot context with a transparent fallback toGET /contextwhen the route 404s, making the hook forward- and backward-compatible across reveried versions and the Go engram rollback binary. Updateddocs/operations.mdwith a “Boot context” section documenting the curl pattern.
Fixed #
- TOD-258 —
scripts/engram_compat_smoke.shpassed the port positionally (engram serve "$PORT"), which post-cutover reveried rejects. Switched to--port "$PORT"somake smokeworks against the Rust daemon.
Added #
-
TOD-447 — Schema versioning scaffold for coord session records. Froze the current schema as
scripts/coord-schema-v1.jsonwith a byte-identicalscripts/coord-schema-latest.jsonmirror, createdscripts/migrations/with an authoring contract and a runnable no-op template (0_to_1_example.sh), added a pure bash+jq drift CI at.github/workflows/coord-schema-drift.ymlthat guards the latest-vs-highest invariant and exercises every migration script, and documented the versioning + migration rules indocs/coord/schema.md.scripts/coorditself is untouched; thecoord migraterunner is deferred to a follow-up ticket to avoid collision with concurrent in-flight edits. -
TOD-406 —
reverie-dreamclassify phase: read-only second dream phase that re-infers thetypefield for each scan candidate via a deterministic heuristic chain (structured**What/Why/Where**blocks, prefix matches forFixed/Decided/etc., keyword markers forpattern/discovery/architecture) and records decisions into a newDreamContext.type_changes: HashMap<i64, String>for downstream phases to persist. Ships theClassifiertrait +MockClassifiertest double + a no-opLlmClassifierplaceholder so the dream cycle stays offline by default; the real Anthropic-backed classifier andREVERIED_CLASSIFY_MODELenv wiring land in a follow-up. Eight integration tests cover each heuristic branch, the mock-classifier fallback path for undecidedmanualobservations, and the empty-candidates noop. -
TOD-260 —
reverie-bench boot-tokenssubcommand andcrates/reverie-bench/src/boot_tokens.rsmodule: snapshots the live~/.engram/engram.dbto a tempfile, spawns an isolatedreveried serveon an ephemeral port (default 17437, refuses 7437), and measures the SessionStart context block across four configurations (baseline-parity,reveried-smart,reveried-smart-narrow,reveried-smart-scoped). Tokenizes responses withpython3 -m tiktoken(cl100k_base) when available, falling back to abytes / 4heuristic with a clear disclaimer in the rendered markdown report. Writesreports/boot-tokens-<ts>.mdwith bytes / est-tokens / observation count / session count plus a “reduction vs baseline” delta table. First live run against the user’s engram.db (projectctodie, 70 observations) measured baseline-parity at 7184 B / ~1796 tokens vs reveried-smart at 5053 B / ~1263 tokens (-30%) and reveried-smart-narrow at 3206 B / ~801 tokens (-55%). Seedocs/operations.md§ “Boot token measurement”. -
TOD-401 —
reverie-bench churnsubcommand andreverie_bench::churnmodule. Replays a synthetic stream of candidate observations through two passes (ungated baseline vsGatePipeline::default()) and renders a markdown report comparing churn ratios. At N=1000 with the spec’d fixture mix (40% valid / 30% dup / 15% oversized / 10% directive / 5% spam) the gate cuts churn from 60.0% to 0.0% — a 100% reduction, well above the 50% ship target. Sample report inreports/churn-bench-20260407T000000.md. -
TOD-400 —
reverie-dreamscan phase: real implementation of the first dream cycle phase. Walks every non-soft-deleted observation via the newEngramCompatStore::all_live_observations()helper, scores each row with the SWR-inspired priority formularecency * access * importance * novelty(1-week recency half-life, log-scaled access on revision+duplicate counts with a small floor so first-run observations still rank, static type-weight table mirroring the TOD-400 ticket, novelty as1 - max_jaccardagainst peers sharing the sametopic_key), and returns the top-N candidates on a newDreamContext. Adds a minimalrunnermodule (DreamContext,DreamPhasetrait,PhaseReport) as forward-compatible scaffolding for TOD-397’s full runner. Eight tests (2 unit + 6 integration viaEngramCompatStore::open_in_memory()) cover empty store,top_ntruncation,min_age_hoursfiltering, type-weight ordering, and the novelty penalty on topic-key twins.docs/operations.mdgains a “Dream cycle phases” section documenting the phase table, thescantunables (top_n,min_age_hours), and sample output from a real engram snapshot (96 observations scanned, 50 selected, 1.24ms). -
TOD-273 —
observations.discovery_tokenscolumn (INTEGER, nullable) is now tracked as a reveried-additive column.AddObservationParamsgains an optionaldiscovery_tokensfield so callers can record the approximate agent token cost of discovering a memory (search fan-out, tool churn). Migration is idempotent via the existingREVERIE_COLUMNS+add_column_if_not_existspath — old engram DBs ALTER-add the column on next open and pre-existing rows read back asNone. The fieldskip_serializing_if = "Option::is_none", so the wire shape for old observations is byte-identical to upstream engram. -
TOD-274 —
SearchResult.token_count(optional) carries an estimated token cost for thecontentfield (ceil(bytes / 4), min 1 — rough BPE average for English). Populated only when the newSearchOptions.include_tokensflag is set; the HTTP handler exposes this asGET /search?...&include_tokens=true. The default/searchresponse is byte-identical to upstream engram (parity lock preserved for TOD-368). Themem_searchMCP tool is intentionally unchanged — no token_count in MCP responses. -
TOD-257 —
GET /context/smart?project=<name>&limit=<n>route, project-aware tiered context loader. Composes three tiers into a single markdown blob: Tier A (recent in-project, 60% of budget), Tier B (high-signal project anchors whererevision_count + duplicate_count ≥ 3, 30%), Tier C (cross-cutting recentscope='personal'rows across all projects, 10%). Lives alongside the byte-parity/contexthandler without touching it. Four newReveriedConfigknobs (smart_context_tier_a_weight,_b_weight,_c_weight,smart_context_default_limit) expose the weights and default budget; Tier B and Tier C are floored and Tier A absorbs the rounding remainder so the total always matcheslimit. NewEngramCompatStore::high_signal_observationshelper powers Tier B. Seedocs/reveried-config.mdanddocs/operations.mdfor curl examples and worked budgets. -
TOD-399 —
reverie-gate::rules::PlacementRuleis the first concreteGateRule. It wraps the TOD-357 placement-linter logic so that directive- shaped content (R5) is hard-rejected with “directive belongs in CLAUDE.md” and oversized content (R2) is hard-rejected with “content belongs in Obsidian” before the write hits the store. Respects the existinglint:ignore:R2/lint:ignore:R5/lint:ignore:allmarkers. The cap is driven by the newgate_max_content_charsconfig knob (default 2000). -
TOD-403 —
reverie-gate::rules::DedupRuleadds two-phase write-time deduplication. Phase 1 looks up the engram-compatnormalized_hashin the candidate’stopic_keyfamily withingate_dedup_window(default 15 min) and rejects any exact-hash hit. Phase 2 is a Jaccard-over-bag-of-words fallback against the last 5 observations with the sametopic_key, with a configurablegate_similarity_threshold(default 0.85). Cosine-similarity over embeddings is deferred to TOD-255 and documented in the module. -
TOD-404 —
reverie-gate::rules::BudgetRuleenforces per-project admission limits: a rolling 60-second rate limit (gate_rate_limit_per_minute, default 10) and a hard project cap (gate_project_cap, default 10000). Usesctx.nowso every rule in a pipeline run observes a consistent wall-clock. -
TOD-399/403/404 —
GatePipeline::default()now wires placement → dedup → budget (cheapest-first so structural rejections never touch the DB). Five newReveriedConfigknobs:gate_max_content_chars,gate_dedup_window,gate_similarity_threshold,gate_rate_limit_per_minute,gate_project_cap. Four newEngramCompatStorehelpers back the rules:recent_by_topic_key,count_recent_observations_in_project,count_live_observations_in_project, andfind_by_content_hash. -
TOD-398 —
reveried gatesubcommand. Reads a candidate observation from stdin (engramAddObservationParamsJSON shape), runs it through aGatePipeline(currentlyGatePipeline::default()=AlwaysAcceptuntil TOD-399/403/404 ship real rules), and either persists the accepted candidate viaEngramCompatStore::add_observationor reports a rejection on stderr + exit 1. Supports--dry-run(no write) and--reject-log(append rejected candidates as JSONL, default~/.local/state/reveried/gate-rejects.jsonl). Gate logic lives incrates/reveried/src/gate_cmd.rsso the integration suite (crates/reveried/tests/gate_integration.rs) can drive it end-to-end via the compiled binary. -
TOD-402 — Research write-up skeleton at
docs/paper.md. Nine sections (abstract, motivation, placement taxonomy, architecture, dream cycle, evaluation, related work, anti-patterns, release notes) with placeholder prose, concrete sub-item bullets, and citations to engram observations #270, #272, #279, #280, #281, #283. Cross-references MVP-B tickets TOD-396/397 (architecture), TOD-400/406/407/408/409 (dream phases), and TOD-401/410/351/354 (evaluation). The Evaluation section carries aTODO(TOD-411)marker so real benchmark numbers land with that ticket. Linked fromREADME.mdas the project’s design paper. -
TOD-397 —
reveried dreamentry point. Newreverie_dream::runnermodule orchestrates a six-phase pipeline (scan → classify → place → consolidate → prune → sync) via aDreamPhasetrait, with all phases shipping as stubs (real implementations land in TOD-400/406/407/408/409). Successful non-dry-run cycles append a markdown entry to~/.local/state/reveried/journal.md(overridable viaREVERIED_STATE_DIR/XDG_STATE_HOME); the journal self-truncates to the last 100 runs once it crosses 1 MiB. CLI gains--dry-runand--phase <name>flags alongside the existing--now. 5 unit tests cover phase ordering,--phasefiltering, dry-run journal suppression, journal markdown format, and append-on-second-run. -
TOD-395 —
docs/mvp-b/auto-capture-triggers.md: design doc defining the three auto-capture triggers for MVP-B (subagent-stop,session-end,passive-save), theCandidateObservationJSON shape on stdin toreveried gate, the rejection log layout (~/.local/state/reveried/gate-rejects.jsonl), per-trigger test plans, and open questions about the harness hook contract.subagent-stopships first;session-endships in the same PR if test plan §5.2 passes;passive-saveis deferred. Cross-references TOD-396 (GatePipelinetrait), TOD-398 (reveried gatesubcommand), TOD-405 (subagent-stop hook wiring). Linked from the newdocs/operations.md. -
TOD-396 —
reverie-gate::pipelineintroduces the trait-based write-gate abstraction:GateRule,GatePipeline,CandidateObservation,GateContext,RuleResult, andGateDecision. The runner executes rules in order, short-circuits on the firstReject, and threadsModifyrewrites into the next rule’s input. Ships with anAlwaysAcceptno-op rule used byGatePipeline::default(); real rules (placement, dedup, budget) land via TOD-399/403/404.
Fixed #
- TOD-392 —
reveried serveandreveried mcpnow resolve--dbvia the same chain Go engram uses (cmd/engram/main.go:139,internal/store/store.go:255): CLI--dbflag →$ENGRAM_DATA_DIR/engram.db→$HOME/.engram/engram.db. Previously defaulted to a hardcoded XDG path (~/.local/share/engram/engram.db) that engram does not use, so migrating users would silently boot against an empty database — caught during the TOD-271 cutover. Both subcommands now log the resolved path at startup so any future drift is visible. New unit tests pin the resolution order. - TOD-379 (closes TOD-380) — MCP default-project resolution. Reveried now
detects a default project at daemon startup using engram’s chain (
--projectflag →REVERIED_PROJECTenv →git config --get remote.origin.url→ repo basename, normalized viaengram_quirks::normalize_project) and applies it to every MCP tool call whoseprojectfield is missing or empty. Mirrors engram’sMCPConfig.DefaultProject(internal/mcp/mcp.go:29) at the same 7 handler sites engram patches (mem_search,mem_save,mem_save_prompt,mem_context,mem_session_summary,mem_session_start,mem_capture_passive— engram lines 635, 692, 859, 890, 1038, 1072, 1106). Also bringsmem_searchempty-results text into engram parity (No memories found for: "<query>",internal/mcp/mcp.go:651), which the smoke test exposed once the default-project filter started narrowing reveried’s result set to match engram. Newdefault_projectknob inReveriedConfig(TOML) pins a value and bypasses detection.make smokenow reports 19/19 PASS (was 17/19), unblocking the TOD-271 cutover. - TOD-368 follow-up —
scripts/engram_compat_smoke.sh: isolated the engram MCP subprocess to the same snapshot DB as the engram HTTP server. Previously the harness only sandboxedHOMEforengram serve; the per-testengram mcpinvocations inherited the realHOMEand read the user’s live~/.engram/engram.db, poisoning every MCP diff with DB-state drift (mem_stats / mem_search / mem_context / sessions_recent all reported spurious failures). Fix exportsENGRAM_DATA_DIR(engram’s highest-priority override) so every child process — bothserveand everymcp— reads the same$SMOKE_DIR/engram-data/engram.dbsnapshot. Added a startup sandbox sanity check that aborts (exit 3) if the engram HTTP and engram MCP processes report differentmem_statssession counts, so the silent- lie failure mode is now impossible. - TOD-368 — Wire-format parity with Go engram across 8 divergences caught
by the differential smoke test:
- MCP
tools/callresponses no longer emitisError: falseon the success path (engram omits it via Goomitempty). mem_suggest_topic_keynow returnsSuggested topic_key: <key>instead of a bare slug, matchinginternal/mcp/mcp.go:778.mem_get_observationMCP error string is nowObservation #<id> not found(capitalised, with hash) — engram’s HTTP and MCP layers use different miss strings; both are now matched./statsJSON now uses engram’stotal_sessions/total_observations/total_promptsfield names plus aprojects: []stringslice (nullwhen empty), replacing reveried’s prior bespoke shape./exportenvelope now always emitsversion+exported_at(engram-formatYYYY-MM-DD HH:MM:SSUTC timestamp), and thesessions/observations/promptsslice fields serialise to JSONnullwhen empty (Go nil-slice encoding) instead of[]./sessions/recent,/prompts/recent,/prompts/search,/observations/recent, and/searchnow serialise an empty result set as bare JSONnullrather than[], matching engram’s nil-slice response body./sessions/recentnow returnsSessionSummaryrows (observation_count, nodirectory) instead ofSession, matching engram’sStore.RecentSessionsprojection./contextandmem_contextnow render the engram markdown layout byte-for-byte:## Memory from Previous Sessionsheader,### Recent Sessions/### Recent User Prompts/### Recent Observationssections in that order,**project** (started_at): summary [N observations]session bullets,[type] **title**: <preview>observation bullets, code-point-based truncation, and an empty string when there is nothing to render. Themem_contextMCP wrapper appends the engram stats footer and falls back toNo previous session memories found.when the context is empty.
- MCP
- New
crates/reverie-store/tests/wire_format.rsintegration suite pins every fix above against engram’s documented wire output so we can’t silently regress. - TOD-368 final — Two remaining wire-format divergences caught by the
post-ripple smoke:
/timelineHTTP route: the 404 error envelope now reads{"error":"timeline: observation #<id> not found: sql: no rows in result set"}(byte-identical to engram’s Go store error; matches the string the MCP dispatch layer already returned).recent_sessionsSQL: theORDER BYclause now readsMAX(COALESCE(o.created_at, s.started_at)) DESC, matchinginternal/store/store.go:840. The olddatetime(s.started_at) DESCsurfaced empty test-fixture sessions over the ones users were actively writing into; this restores engram’s “recent activity” semantics.
- TOD-368 follow-up — Reshape
TimelineResultto match upstream engram byte-for-byte: addTimelineEntrystruct, populatesession_infoandtotal_in_range, and switch the SQL to engram’s same-session/id </id >windowing (internal/store/store.go:1360-1458). Replace JSON pretty-print bodies formem_get_observationandmem_timelinewith the hand-formatted text engram returns (internal/mcp/mcp.go:953-1027). Match engram’sTimeline error: timeline: observation #N not found: sql: no rows in result seterror string verbatim.
Added #
- TOD-270 —
reverie-syncadapters for the MVP-A drop-in cutover.ObsidianAdapterports the upstreamengram-to-obsidianPython hook to Rust, reading observations directly fromEngramCompatStoreand writing one Obsidian note per observation with frontmatter (engram-id,engram-type,topic-key,project,scope,sync_id, tags) deduped bytopic_keyfirst, slug second. State is persisted to<vault>/_System/.engram-sync-state.jsonin the same JSON shape as the Python script so the two are mutually compatible.AutoMemoryAdapterandClaudeMdAdapterare intentional no-ops — auto-memory and CLAUDE.md are user-curated layers (see canceled TOD-261 / TOD-263).
Fixed #
- TOD-371 —
EngramCompatStore::get_observationnow hides soft-deleted rows (matching engram’sStore.GetObservation); the previous implementation surfaced tombstones to callers. - TOD-371 —
EngramCompatStore::passive_capturenow correctly extracts numbered learning lists, parses### Learningsheaders, enforces engram’s 20-char / 4-word minimum item length, strips markdown (**bold**,`code`,*italic*), and walks sections in reverse to prefer the most recent valid one — matching the engramExtractLearningssemantics. Previously only-/*bullets were recognized.
Added #
- TOD-352 — Closet/drawer pattern on
Chunk. Addssummary: Option<String>to the chunk model (lossless YAML frontmatter round-trip, omitted whenNone), a new lightweightChunkSummary“closet pointer” ({id, topic_key, title, summary}), andChunk::derived_summary/Chunk::as_summaryhelpers that fall back to a UTF-8-safe preview ofcontentwhen no explicit summary is set.SearchEngine(previously a stub) now exposes the closet/drawer surface:search()returnsVec<ChunkSummary>(no body shipped),search_full()returns fullVec<Chunk>, andget_chunk(id)opens a single drawer. Default search no longer materializes verbatim bodies — token cost on multi-hit queries drops by roughly the body/summary ratio (typically 5–20×). - TOD-372 —
reveriedconfig file at~/.config/reveried/config.tomlwith--config <path>override and engram-parity defaults formax_observation_length(50000),max_context_results(20),max_search_results(20), anddedupe_window(15 min). NewReveriedConfiginreverie-store::configandEngramCompatStore::open_with_config()plumbing. Documented indocs/reveried-config.md. - TOD-368 —
scripts/engram_compat_smoke.sh: differential smoke test harness comparingreveriedvs the upstream Goengramdaemon byte-for-byte on every HTTP route and MCP tool against COPIES of the same startingengram.db. Includes JSON normalization (sorted keys, redacted timestamps / UUIDs / ANSI / version / tmp paths), idempotent cleanup, optional--write-modefor mutating routes, and amake smoke/make smoke-writetarget. Pre-cutover gate — exit code is the FAIL count. Engram is sandboxed via a fake$HOMEso the user’s live DB is never touched. - TOD-357 —
reverie-lintCLI inreverie-gate: placement linter that scans an engram observation database and flags 5 placement-framework violations (R1 preference-not-in-auto-memory, R2 oversized-for-engram, R3 near-duplicate, R4 stale-session-summary, R5 directive-in-engram). Each rule has a configurable threshold and supports per-rule suppression via alint:ignore:RN(orlint:ignore:all) marker in the observation content. Text and--jsonoutput, optional--fail-on-findingsfor CI gating. - TOD-367 —
EngramCompatStore: drop-in compatible SQLite backend that reads/writes the upstreamengram.dbfile, including the full schema, FTS5 triggers, topic_key upsert, content-hash dedup,<private>tag stripping, and 8 reveried-additive columns. Gated behind the newbackend-engram-compatfeature onreverie-store. - TOD-268 — engram-compatible axum HTTP server in
reverie-store::httpexposing all 21 routes fromdocs/engram-api-surface.md§1, plusreveried servewiring with--db/--bind/--port/--logflags. - Initial project scaffold: Cargo workspace with
reveriedandreverie-benchcrates - CLI skeleton for both binaries (clap derive)
- Full project infrastructure: Makefile, CI/CD, pre-commit, lint configs
- Documentation: daemon spec, LoCoMo harness spec, backlog
Research #
- 10 neuroscience mechanisms mapped to implementation
- 9 competitive systems analyzed (SOTA survey)
- 13 empirical findings from memory audit (105 → 39 observations)
- 5 synthesized insights (gravitational collapse, 200-line ceiling, adaptive forgetting, content-addressed sync, metadata pollution)
- Placement decision tree formalized
- LoCoMo benchmark integration plan