Memory That Ages Like Wood: Tree Ring Memory for Agent Zero

Tree Ring Memory is a local-first, Rust-native memory lifecycle layer that keeps fresh memory sharp, compresses old memory into rings, keeps hard lessons visible as scars, and promotes verified truths to heartwood. Here is why it is a strong complement, or a full alternative, to Agent Zero's built-in memory.

#agents #architecture #context

Tree Ring Memory for Agent Zero

Most agent memory systems are transcript dumps with a search box on top. They remember everything with equal weight, forget nothing on purpose, and cannot tell you why a result came back. That works until the store grows, the noise drowns the signal, and the agent starts confidently recalling a decision that was reversed three weeks ago.

Tree Ring Memory takes a different position. Memory should age. Fresh memory stays detailed. Older memory compresses into rings. Important failures stay visible as scars. Durable truths become heartwood. And every one of those transitions is explicit, testable, and local.

It also ships with a dedicated Agent Zero plugin that hooks into the agent's native lifecycle. This article looks at what the system does, how the integration works, and why it is a serious candidate for Agent Zero users who want memory they can reason about.


The idea in one picture

A tree does not store its history as a log. It stores it as structure. The cambium is where growth happens now. Behind it, each year compresses into a ring. Damage leaves a scar that never fully disappears. The core hardens into heartwood, the part that holds the tree up.

Tree Ring Memory maps agent memory onto exactly that structure.

Six rings, one store

Ring What lives there
cambium Fresh, active memory from recent work. Automatic capture writes here first.
outer Recent memory after summarization. Specific, but no longer noisy.
inner Older memory compressed by deterministic consolidation.
heartwood Durable truths promoted by evidence: verified decisions, project rules.
scar Important negative lessons. What failed, and why, kept visible on purpose.
seed Unresolved hypotheses waiting for evidence.

The unit of storage is a MemoryEvent, not a transcript line. Each event carries a ring, a scope, an event type, a source reference, confidence, salience, sensitivity, retention, and review state. That metadata is what makes recall explainable and lifecycle operations possible.


What makes it stand out

Local-first, Rust-native, no cloud dependency

The runtime is a single Rust CLI called tree-ring backed by SQLite with full-text search. There is no vector database to run, no embedding API to pay for, and no service to keep alive. The store lives in a .tree-ring/ directory next to your project.

The project publishes its own certification numbers rather than marketing claims. From the most recent run recorded in the repository:

Metric Result
Release binary 6.4 MB
Import throughput 10,000 memories in about 4 seconds
Recall at 10k memories 3.5 ms average, 6.2 ms max
Recall at 30k memories 7.5 ms average, 13.5 ms max
Recall quality fixture 4 queries, 4 pass, 0 fail

These are synthetic, same-host measurements, and the project says so. That honesty is part of the appeal.

Forgetting and supersession are first-class

Most memory layers treat deletion as an afterthought. Tree Ring treats it as a core operation. You can redact a memory (which leaves a tombstone so it cannot be resurrected by a replay or import), delete it outright, mark it superseded by a newer truth, or let it expire on a retention policy. Recall excludes superseded and sensitive memory by default.

The audit command reports stale expiry, sensitive retention, low-confidence durable memory, supersession integrity, and contradiction candidates, all deterministically and without an LLM in the loop.

Sensitive data fails closed

Secret-like content is blocked before it is stored. Sensitive but non-secret memory is hidden by default in recall, export, and the terminal UI. Consolidation summarizes sensitive memory without copying raw payload text. This is a memory system designed by someone who has watched an agent cheerfully memorize an API key.

An evidence loop, not a belief loop

The evidence command records evaluated outcomes with a required reference back to the thing that proves them: a test run, a PR, an issue, a log. Promoted outcomes become heartwood. Rejected outcomes become scars. Deferred hypotheses become seeds. Nothing becomes durable truth on assertion alone.

This maps cleanly onto how Agent Zero already thinks about verification. Memory is guidance. Source files, tests, and AGENTS.md contracts stay authoritative.

Multi-agent identity built in

Every event can carry a project, agent_profile, workflow_id, session_id, and operation_id. Scopes enforce partition invariants: agent-scoped memory requires an agent profile, workflow-scoped memory requires a workflow ID. The operation_id gives you idempotent writes, so a retried tool call returns the existing memory instead of a duplicate.

For fan-out and fan-in work, an optional Coordinated write policy lets ordinary workers write only to their own agent scope while a designated coordinator publishes shared conclusions. The coordinator capability is accepted only through an environment variable, stored only as a hash, and never appears in logs or event payloads.

DOX and Revolve aware

Tree Ring credits its design lineage openly: the spatial project-memory patterns in DOX and the evidence-driven loop in Revolve, both from the Agent Zero ecosystem. It ships read-only adapters for both. dox sync summarizes AGENTS.md files with source references and keeps the files authoritative. revolve sync imports promoted outcomes as heartwood and rejected ones as scars.


How the Agent Zero plugin works

The plugin is a bridge, not a second engine. The Rust CLI owns storage, validation, ranking, and lifecycle. The plugin owns Agent Zero context mapping, tools, API envelopes, the Web UI panel, and safe host paths. Current release 3.4.1 targets CLI 0.15.7 and bundles verified Linux binaries for both x86_64 and aarch64 Docker runtimes.

How it runs inside an Agent Zero turn

Two lifecycle extensions do the work:

  1. Before the prompt is assembled, a message_loop_prompts_after extension derives the agent profile, project, workflow, and session identity from Agent Zero's own context, runs a bounded receipt-backed preflight, and injects only accepted, size-limited recall into a tree_ring_memory prompt extra. It never passes the raw user prompt or chat history to Tree Ring. Zero results is a valid outcome.
  2. At monologue_end, a second extension removes the ephemeral lifecycle state and the injected extra. It reads nothing and persists nothing.

Between those two points, the agent sees a capture checkpoint. Before finishing a task, it selects zero to three concise, durable candidates and calls the strict capture tool for each. Core validates the event and ring pair, rejects non-normal sensitivity, and enforces idempotency through indexed operation IDs. Zero candidates is the expected result for a turn with nothing worth keeping. The prompt guidance is blunt about it: never pad, never invent, never claim capture succeeded unless the tool call did.

This is the part worth pausing on. Automatic capture is agent-mediated. There is no background recorder scraping transcripts. The agent decides what is durable, and the tool enforces the rules. That is the right division of labor.

Tools exposed to the agent

Tool Purpose
capture Strict automatic-checkpoint writes with server-derived identity
remember Manual concise memory, agent-scoped by default
evidence Evaluated outcomes with a required evidence reference
recall Rust-ranked recall with project, agent, workflow, session, and scope filters
forget Explicit-ID delete or redact
consolidate Daily, weekly, monthly, yearly, or manual consolidation
audit_memory Non-mutating quality, privacy, and integrity audit
maintain_memory Dry-run by default; explicit expiry, redaction, or FTS repair
sync_dox, sync_revolve Source adapters, dry-run by default
import_memory, export_memory Portable JSONL in and out
policy_status, policy_audit Read-only coordinated write policy visibility

Activation is proof, not a marker file

Installing the plugin does not make it active. You mount a project at /a0/usr/projects/<project>, select it in plugin settings, and choose Activate this project. The plugin runs tree-ring init from the mounted project with its own installed capability descriptor. Status reports configured-awaiting-proof until a real session completes a receipt-backed preflight. Only then does it read active.

That is more ceremony than most plugins ask for. It is also the reason a configured bridge can never silently pretend that memory is working when it is not.

Web UI

The plugin panel shows runtime and schema readiness, one-action project activation, write-policy status, search with ring and event filters, memory detail, delete and redact, consolidation, DOX and Revolve previews, audit, and JSONL export. A concentric ring visual lights each ring relative to the busiest one, with an exact ledger of counts beside it. Selecting a ring filters the live results.


Complement or replacement?

Agent Zero already has a memory system: a vector store with semantic recall over fragments, solutions, and knowledge. It is good at what it does, which is fuzzy, associative retrieval. Ask it something loosely related to a past task and it will find the neighbors.

Tree Ring answers a different question.

Two kinds of remembering

Question Better served by
What have I seen that resembles this? Built-in vector memory
What did we decide about this, and is that decision still current? Tree Ring
What went wrong last time, and why? Tree Ring (scars)
What has been verified, not just asserted? Tree Ring (heartwood with evidence)
Which worker in this fan-out learned what? Tree Ring (agent and workflow scopes)
Free-form notes and solution snippets Built-in vector memory

As a complement, the two run side by side with no conflict. The built-in store handles breadth. Tree Ring handles decisions, lessons, evidence, and lifecycle. The plugin's lifecycle recall is bounded and advisory, so it adds context without crowding out the existing memory extension. This is the lowest-risk way to try it and probably the right default for most users.

As a full replacement, Tree Ring covers the essential operations: remember, recall, forget, export, import, consolidate. What you give up is embedding-based similarity search. What you gain is explainable ranking, typed events, aging, supersession, redaction with tombstones, privacy that fails closed, and multi-agent partitions. For teams running Agent Zero on real projects with real consequences, that trade can be worth making, especially where auditability matters more than recall-by-vibe.

The project itself does not oversell either path. Its README says plainly that it is framework-agnostic and does not replace DOX or Revolve, that the shared-store guarantee is same-host local SQLite only, and that it is in protocol-preview status. That restraint is a feature.


Getting started

Install the Agent Zero plugin from Plugins, then Install, choosing the Git repository option and pasting:

https://github.com/TerminallyLazy/tree-ring-memory-agent-zero

Restart the runtime, open plugin settings, select your mounted project, and choose Activate this project. Start a chat in that project. The first turn writes the activation receipt, and status flips to active.

For the standalone CLI outside Agent Zero, a verified prebuilt install for Linux x86_64 or macOS ARM64 is one line:

curl -fsSL https://raw.githubusercontent.com/TerminallyLazy/Tree-Ring-Memory/main/install.sh | sh -s -- --project --init --release latest

Then:

tree-ring remember "Use project-scoped recall before changing release behavior." --event-type lesson --scope project
tree-ring recall "release behavior"
tree-ring tui

The terminal UI is worth opening at least once. An animated ring face pulses with memory activity, and the slash command palette gives you /remember, /promote, /scar, /seed, /supersede, /consolidate, and /export without leaving the console.


Things to know before you commit

A fair assessment includes the edges.

  • Protocol preview. The version numbers are pre-1.0 and the schema has moved (v0.13 introduced a one-way schema-v3 upgrade). The project documents each migration carefully, but expect change.
  • Same-host only. Shared stores are supported for concurrent processes on one host and a local filesystem. No NFS, no cross-host coordination, no distributed locking. For multi-host work, keep per-host roots and fan in explicitly.
  • Write authorization, not read ACL. The Coordinated policy controls who can publish shared memory. Anyone with filesystem access to the SQLite file can still read it. This is stated repeatedly in the docs.
  • No embeddings. Recall is FTS plus scoring factors. If your workflow depends on semantic neighbors, keep the built-in vector memory alongside.
  • Activation takes a real session. Status will not say active until a chat in the mounted project completes a preflight. This is by design, and it can confuse a first-time user who expects install to mean ready.

Why this fits Agent Zero

Agent Zero's design leans on a few convictions: verify rather than assume, keep the human in control, keep project contracts authoritative, and make everything inspectable. Tree Ring Memory shares every one of them. It cites DOX and Revolve as ancestors. It treats recalled memory as guidance and AGENTS.md as law. It refuses to store secrets. It publishes its own benchmark numbers with their limits attached. And it hooks into the agent lifecycle through the same extension points any Agent Zero plugin uses, without touching core code.

Memory that ages, scars that stay visible, truths that have to earn their place. That is a memory model worth having in the toolbox, whether it sits beside the built-in store or takes its place.