Tree Ring Memory is a framework-agnostic, local-first memory lifecycle layer for AI agents. It helps agents remember useful decisions, warnings, preferences, and lessons without turning memory into a transcript dump. Fresh memory stays detailed, older memory compresses into rings, important scars remain visible, and durable truths become heartwood.
Tree Ring Memory is inspired by the spatial project-memory patterns in DOX and the evidence-driven improvement loop in Revolve, with a deliberate nod to their original creator, Jan Tomášek. This project is framework-agnostic and does not replace either protocol.
Tree Ring Memory is in protocol-preview status. Current launch links:
- Launch page: https://terminallylazy.github.io/Tree-Ring-Memory/
- Launch release: https://github.com/TerminallyLazy/Tree-Ring-Memory/releases/tag/v0.11.0
- Launch discussion: #27
- Rust-native CLI article: https://terminallylazy.github.io/Tree-Ring-Memory/launch/rust-native-agent-memory-cli.md
- Feedback issue: #26
- Homebrew tap: https://github.com/TerminallyLazy/homebrew-tree-ring
Protocol preview history
- v0.1 provided the initial local reference implementation with SQLite storage and no required cloud services.
- v0.2 moved durable behavior into a Rust core.
- v0.3 explored host bindings during the Rust migration.
- v0.4 added Rust-owned JSONL import/export with privacy-preserving defaults across the CLI.
- v0.5 added Rust-owned audit checks for stale, sensitive, low-confidence, supersession, and contradiction candidates.
- v0.6 added Rust-owned deterministic consolidation with idempotent summary records and cautious sensitive-memory handling.
- v0.7 made the public facade Rust-native only and added Rust-owned maintenance for expiry, secret redaction, and FTS repair.
- v0.8 removed Python-owned runtime behavior.
- v0.9 removed tracked Python source, tests, smoke scripts, and the optional CPython extension from the canonical repo.
- v0.10 added a one-line installer plus Rust-native terminal onboarding with animated terminal tree rings.
- v0.11 made the repo fully Rust-native, wired TUI export/consolidation actions, added DOX/Revolve sync adapters, and added agent-framework discovery.
- Explicit local recall with SQLite/FTS storage and no required cloud service.
- Source-linked memories for decisions, scars, lessons, evidence, and durable project truths.
- Rust-native import/export, audit, consolidation, maintenance, DOX/Revolve adapters, harness discovery, and terminal UI.
- Evidence artifacts for install size, recall speed, harness readiness, and recall quality.
- Privacy defaults that block secret-like memory, hide sensitive details, and keep transcript capture out of scope.
The Rust workspace currently includes:
crates/tree-ring-memory-core: models, validation, sensitivity checks, and recall scoring.crates/tree-ring-memory-sqlite: schema-compatible SQLite/FTS storage and recall filtering.crates/tree-ring-memory-cli: nativetree-ringCLI.
The public runtime is Rust-native. The Rust CLI and Rust crates own storage, recall, import/export, audit, consolidation, maintenance, and terminal UI behavior. There is no tracked root Python package, Python wrapper layer, pytest suite, Python smoke script, PyO3 crate, or CPython extension.
These are captured from the actual tree-ring tui app running against a local
.tree-ring store populated through the public CLI with 47 memories across
all rings, plus the current certification artifacts.
Dashboard view with populated cambium, outer, inner, heartwood, scar, and seed rings. Ambient layers are duller at lower relative fullness and lighter as their share of stored memories grows; activity pulses are temporary.
Search mode with ranked recall results and selected-memory details.
Evidence browser with install size, recall speed, harness records, and
recall-quality checks loaded from target/tree-ring-certification/.
Integrations view showing detected local agent framework markers and next-step guidance.
Global user install:
curl -fsSL https://raw.githubusercontent.com/TerminallyLazy/Tree-Ring-Memory/main/install.sh | shmacOS ARM64 install with Homebrew:
brew tap TerminallyLazy/tree-ring
brew install tree-ringProject-local install with first-run initialization:
curl -fsSL https://raw.githubusercontent.com/TerminallyLazy/Tree-Ring-Memory/main/install.sh | sh -s -- --project --initStore the first project memory:
tree-ring init
tree-ring remember "Use project-scoped recall before changing release behavior." \
--event-type lesson \
--scope project \
--project example-service \
--tag release \
--tag workflow
tree-ring recall "release behavior" --project example-serviceOpen the terminal console:
tree-ring tuiThe installer builds the Rust CLI with cargo, installs tree-ring, then shows
one stable terminal onboarding screen with a branded terminal ring and the next
useful commands. For global installs, it also adds the install bin directory to your
shell profile when that directory is not already on PATH. It does not
initialize memory unless --init is passed.
The installer command streams only the installer script into sh. It does not
put memory in a temporary location and it does not remove .tree-ring,
installed binaries, Cargo caches, source checkouts, or shell profiles.
Persistent memory lives in the configured memory root, normally .tree-ring
for project-local use or whatever path you pass with --root.
Initialization creates the SQLite store and non-destructive agent-awareness files in the memory root:
.tree-ring/AGENTS.md: DOX-style Tree Ring Memory guidance and rootAGENTS.mdmerge notes..tree-ring/SKILL.md: portable skill instructions for agent runtimes..tree-ring/CLI.md: quick command reference for recall, remember, evidence, DOX/Revolve sync, import/export, audit, maintenance, and TUI usage.
Existing awareness files are left untouched. Tree Ring Memory does not modify a
project's root AGENTS.md; merge the generated guidance manually when you want
DOX-aware agents to see it before entering .tree-ring/.
Useful installer options:
sh install.sh --help
sh install.sh --project --init
sh install.sh --global --install-dir "$HOME/.local"
sh install.sh --no-animation # stable output; kept for explicit script usage
sh install.sh --no-path-update
sh install.sh --archive-url https://example/tree-ring-memory-0.11.0-macos-arm64.tar.gz --archive-sha256 <sha256>After install, rerun onboarding anytime:
tree-ring welcome
tree-ring welcome --init
tree-ringBy default, the installer uses cargo install from the Git repository or a
local --source checkout. Release builds can use --archive-url plus
--archive-sha256 to install a prebuilt tree-ring binary archive.
Open the terminal console after a global install:
tree-ring tuiIf your shell cannot find tree-ring after a global install, run it directly or
add the install bin directory to the current terminal. The installer can update
future shell sessions through your shell profile, but a child installer process
cannot rewrite the already-running parent shell environment:
$HOME/.local/bin/tree-ring tui
export PATH="$HOME/.local/bin:$PATH"Open the terminal console after a project-local install:
.tree-ring/bin/tree-ring --root .tree-ring tuiThe tree-ring command is the Rust CLI.
tree-ring init
tree-ring remember "Use protocol-first design." --event-type decision --tag architecture
tree-ring evidence "Snapshot invalidation fixed stale unread chat state." --outcome promoted --evidence-ref evals/chat-state/run-042 --score 0.91
tree-ring recall "protocol design"
tree-ring forget mem_example --mode delete --reason "example cleanup"
tree-ring export --output memories.jsonl
tree-ring import memories.jsonl --dry-run
tree-ring import memories.jsonl
tree-ring audit --audit-type sensitive
tree-ring consolidate --period-type manual --dry-run
tree-ring maintain
tree-ring maintain --apply-expired --repair-fts
tree-ring dox sync --source-root . --dry-run
tree-ring revolve sync --source-root revolve --dry-run
tree-ring integrations scan --source-root .The CLI stores memory in .tree-ring/ by default.
Command ownership is Rust-native:
initcreates the SQLite store plus.tree-ring/AGENTS.md,.tree-ring/SKILL.md, and.tree-ring/CLI.mdwithout overwriting existing files.remember,recall, andforgetcover direct memory capture, retrieval, redaction, and deletion.evidenceis the Revolve-inspired improvement-loop entry point for evaluated outcomes.dox syncandrevolve syncare read-only source adapters that summarize and point back to authoritative files.integrations scandiscovers nearby agent-framework markers and suggests setup paths without changing their config.export,import,audit,consolidate, andmaintainare local maintenance surfaces over the same SQLite store.welcomeandtuiare the terminal onboarding and operator-console surfaces.
The Revolve-inspired loop is exposed through tree-ring evidence. It records
evaluated outcomes as memory with an evidence reference instead of treating
claims as durable truth without support.
tree-ring evidence "Snapshot invalidation fixed stale unread chat state." \
--outcome promoted \
--evidence-ref evals/chat-state/run-042 \
--project agent-ui \
--score 0.91
tree-ring evidence "Aggressive caching caused stale multi-chat state." \
--outcome rejected \
--evidence-ref evals/cache-branch/run-013 \
--project agent-uiOutcome mapping:
promoted->heartwood, durableevaluation_promotionrejected->scar, durableevaluation_rejectiondeferred->seed,evaluation_hypothesisobserved->outer,evaluation_result
This is not a replacement for Revolve records. Use source refs that point back to real evaluations, checkpoints, PRs, issues, logs, or run artifacts.
Tree Ring Memory includes Rust-native source adapters. They produce concise, source-linked memory events and then persist through the same SQLite store as manual memories.
tree-ring dox sync --source-root . --dry-run
tree-ring dox sync --source-root . --project example-service
tree-ring revolve sync --source-root revolve --dry-run
tree-ring revolve sync --source-root revolve --project example-serviceDOX sync discovers AGENTS.md files, stores summaries and source refs, and
keeps the source files authoritative. It can scan a project root or a single
AGENTS.md file. It does not copy entire project-contract trees into memory,
does not weaken child contracts, and does not let memory replace fresh DOX
traversal before edits.
Revolve sync scans a Revolve root or an evidence file. It imports promoted outcomes as heartwood, rejected outcomes as scars, deferred hypotheses as seeds, and observed results as outer-ring evidence. It keeps source refs back to the Revolve/evaluation record and does not treat incomparable or outcome-free files as durable truth.
For both adapters, run --dry-run first. Imported memory is a concise recall
aid; the source AGENTS.md, Revolve record, evaluation artifact, PR, issue,
test, or run log remains authoritative.
Framework discovery is read-only:
tree-ring integrations scan --source-root .
tree-ring integrations certify --source-root .integrations certifywrites non-mutating harness evidence undertarget/tree-ring-certification/harness/and updatestarget/tree-ring-certification/evidence-index.json. Pass, fail, and skip states are evidence records, not broad compatibility claims.recall-qualitywrites non-private recall diagnostics undertarget/tree-ring-certification/recall-quality/default-fixture-v1.jsonand merges the result intotarget/tree-ring-certification/evidence-index.json. It uses deterministic safe fixture memories, records returned ids, rank positions, score factors, and latency, and marks each query aspass,fail, orneeds_review.
tree-ring recall-quality --source-root .It looks for local markers for DOX, Revolve, Codex, Claude Code, Agent Zero/A0, Goose, OpenCode, Hermes, and Pi, then suggests next steps without editing those tools' configuration. JSON output records whether each marker came from the project or from the user's home configuration, so harness readiness is not overstated when only global config exists.
Agent-mediated bridge linking is the planned next step after read-only
discovery. The design keeps .tree-ring as the canonical memory root while
adding small project-level bridge files that tell the active agent to read
.tree-ring/SKILL.md and .tree-ring/CLI.md. Project bridges are preferred
because they travel with the repo; global bridges affect every project and must
remain explicit opt-in. Until tree-ring integrations link is implemented, add
those references manually in the harness startup context or project instruction
file instead of expecting tree-ring init to modify Codex, Claude, Pi,
OpenCode, or other agent configuration.
tree-ring export writes newline-delimited JSON. The first line is a
tree_ring_memory_export header with schema and plugin version metadata; each
remaining line is a memory_event envelope. The command excludes sensitive and
superseded memories unless --include-sensitive or --include-superseded is
set. Import validates all events, batches writes through SQLite, skips duplicate
ids by default, and replaces existing ids only with --replace-existing.
tree-ring audit is non-mutating. It reports deterministic local findings for
stale expiry, sensitive retention, low-confidence durable memory, supersession
integrity, and conservative contradiction candidates.
tree-ring consolidate creates deterministic local summary memories without an
LLM. Dry-run mode writes nothing. Persisted consolidation is idempotent for the
same period and source-memory set unless --force is provided. Sensitive
non-secret memories are summarized without copying raw payload text and require
review; secret-like memories are excluded from consolidation.
tree-ring maintain is safe by default. Without apply flags it is a dry-run
report, including on a missing root. It can apply eligible temporary-memory
expiry, redact secret-like memories, and rebuild SQLite FTS only when explicitly
asked through --apply-expired, --apply-secret-redactions, or --repair-fts.
The Rust CLI includes a framework-agnostic Ratatui console for humans and agent operators working from a terminal:
tree-ring tui
tree-ring --root .tree-ring tui --event-stream ./tree-ring-events.jsonl --tick-ms 150From a source checkout without installing:
cargo run -p tree-ring-memory-cli -- --root .tree-ring welcome --init --no-animation
cargo run -p tree-ring-memory-cli -- --root .tree-ring remember "Try the TUI with a first memory." --event-type lesson --scope project
cargo run -p tree-ring-memory-cli -- --root .tree-ring tuiThe console keeps an animated straight-on tree-ring face visible at all times. The visual layer generates a backend-independent ring frame first, then rasterizes that frame into high-resolution terminal cells for the ambient HUD. Individual rings carry clockwise or counter-clockwise highlights, pulse with matching memory activity, and shimmer through scar marks on each tick. That keeps the always-on animation cheap and portable while leaving room for richer Kitty/iTerm2 image-protocol rendering in welcome or expanded views later. Store-watch polling updates persisted counts from SQLite, while the optional event stream lights rings in real time without treating stream events as durable truth.
Useful keys and commands:
sfocuses search,/opens the slash command palette,ropens exploded ring view,qquits.itoggles sensitive-memory visibility,utoggles superseded-memory visibility.- Slash commands include
/rings,/search <query>,/remember <summary>,/forget,/redact,/promote,/scar,/seed,/supersede <old_id>,/consolidate,/export <file>,/sync,/integrations,/stream, and/watch.
Destructive or authority-changing operations are confirmation-gated. Sensitive details stay hidden by default, and secret-like memory is blocked before storage.
Event stream lines are local JSONL objects. They are display signals only:
{"event":"remembered","ring":"cambium","label":"Stored project lesson"}
{"event":"policy_blocked","ring":"scar","label":"Secret-like memory blocked"}cargo test --locked
sh install.sh --help
cargo run -p tree-ring-memory-cli -- --help
cargo run -p tree-ring-memory-cli -- welcome --no-animation
cargo run -p tree-ring-memory-cli -- tui --help
cargo run -p tree-ring-memory-cli -- export --help
cargo run -p tree-ring-memory-cli -- import --help
cargo run -p tree-ring-memory-cli -- audit --help
cargo run -p tree-ring-memory-cli -- consolidate --help
cargo run -p tree-ring-memory-cli -- maintain --help
cargo run -p tree-ring-memory-cli -- dox sync --help
cargo run -p tree-ring-memory-cli -- revolve sync --help
cargo run -p tree-ring-memory-cli -- integrations scan --help
cargo run --release -p tree-ring-memory-sqlite --example performance_smoke -- 1000
sh scripts/certify-tree-ring.sh
sh scripts/package-release.shThe Rust CLI writes the canonical SQLite/raw JSON shape. The performance smoke
asserts nonempty recalls, emits a METRICS_JSON= line, and uses conservative
local thresholds of at least 500 inserts/sec and max recall latency of 250 ms
for the synthetic workload.
scripts/certify-tree-ring.sh runs the fuller local certification suite:
formatting, tests, Clippy, release build, isolated project/global installs, CLI
JSON smokes, DOX/Revolve adapter smokes, integration-scan origin checks,
install-size, recall-speed, recall-quality diagnostics, CLI, adapter, and
harness checks, import throughput, and 10k/30k recall timing. It writes
target/tree-ring-certification/summary.md,
target/tree-ring-certification/metrics.json, and
target/tree-ring-certification/evidence-index.json.
Most recent branch-local certification run, generated at
2026-07-09T15:34:52Z:
- Release binary: 6,352,528 bytes.
- Project install with init: 6,272 KB.
- Global install: 6,228 KB.
- CLI import: 10,000 memories in 5 seconds, about 2,000/sec.
- 10k recall: 3.643 ms average, 6.499 ms max.
- 30k recall: 7.608 ms average, 13.634 ms max.
- Harness matrix: 5 pass, 1 skip. Codex, Claude Code, OpenCode, Goose, and Agent Zero/A0 passed; Pi was skipped because only a user-home marker was present in the fixture.
- Recall quality: 4 queries, 4 pass, 0 fail, 0 needs review; average latency 0.118 ms, max latency 0.370 ms.
- Agent Zero plugin smoke: skipped because
TREE_RING_AGENT_ZERO_ROOTwas not set.
Certification also runs the default memory quality scenario pack under
fixtures/quality/. Those scenarios prove recall gates, spam rejection,
stale-truth suppression, evidence requirements, and behavior-proof outcomes.
The quality report is written to
target/tree-ring-certification/quality/quality-report.json with a readable
summary at target/tree-ring-certification/quality/quality-summary.md.
scripts/package-release.sh builds the Rust CLI in release mode, creates a
platform tarball under dist/, and writes a SHA-256 checksum file. Tag pushes
run the release artifact workflow for Linux and macOS.
docs/architecture/rust-core-roadmap.mddocs/architecture/rust-core-status.mddocs/integrations/agent-skill.mddocs/protocol/memory-event.md
Historical migration and planning documents are retained under docs/superpowers/
and docs/feature/. Some of those records describe earlier Python prototype or
binding options that have since been superseded by the Rust-native runtime.
The current bridge-linking design is tracked in
docs/superpowers/specs/2026-07-06-tree-ring-agent-mediated-bridges-design.md.
skills/tree-ring-memory/SKILL.mdgives agents portable guidance for when to recall, remember, redact, forget, or avoid memory capture.templates/dox/AGENTS.mdis a DOX-style project contract template for repos that want Tree Ring Memory rules alongside source code.docs/integrations/agent-skill.mdexplains how to use both without making memory more authoritative than local project docs.tree-ring initandtree-ring welcome --initcopy local guidance into.tree-ring/AGENTS.md,.tree-ring/SKILL.md, and.tree-ring/CLI.mdwithout overwriting existing files.
For DOX-style project awareness, merge the relevant generated .tree-ring/AGENTS.md
sections into the project root AGENTS.md. The CLI intentionally does not
rewrite root project contracts automatically.
For agent harnesses that support local skills or instruction packs, point them
at .tree-ring/SKILL.md or the repository copy under skills/. For
DOX-aware agents, make sure the project root AGENTS.md tells the agent to read
Tree Ring Memory guidance when memory is initialized. For CLI-driven agents,
include .tree-ring/CLI.md in the harness prompt or startup context so the
agent knows the exact local commands.
Bridge files should be short discovery pointers, not duplicate memory stores.
Recommended project-level bridge targets are .agents/skills/tree-ring-memory/SKILL.md
for Codex/Gemini-style skill loaders, .claude/skills/tree-ring-memory/SKILL.md
plus CLAUDE.md references for Claude Code, root AGENTS.md references for
OpenCode/DOX-style agents, and .pi/settings.json resource references for Pi.
Global bridge files under home directories are useful only when the user wants
Tree Ring visible in every project.
Memory updates are agent-mediated. Bridge files tell the active agent when to
call tree-ring recall, tree-ring remember, tree-ring evidence,
tree-ring forget, tree-ring consolidate --dry-run, or tree-ring maintain.
Tree Ring does not scrape transcripts, run a hidden recorder, or turn TUI
event-stream pulses into durable memory without an explicit write command.
assets/tree-ring-memory-logo.pngassets/tree-ring-memory-banner.png
- Local-first by default.
- Protocol before adapters.
- Explainable recall.
- Sensitive data fails closed.
- Forgetting and supersession are first-class.
- Memory quality should be testable.




