proposed
An agent, an importer or the v1 migration saves a decision. It is captured and inert: it does not bind, and it is never packed as context.
varve decision pending Decision memory · local-first · MCP-native
varve is local-first decision memory for Claude Code, Cursor, Windsurf and any MCP agent. What an agent saves stays inert until a human accepts it, and every commit after that is recorded against it.
01 — The model
A varve is one year of lake sediment. Read the column and you read the record, in order, without asking anyone what happened. That is the whole idea behind the tool.
Governed. They declare which files they cover, carry evidence, and every transition lands in an append-only log.
An agent can propose one. It cannot accept one, cannot repeal one, and cannot delete one. Those are your commands, run from your terminal.
Ungoverned. Durable facts, session summaries, captured prompts.
Retrievable, never binding, and deleted outright when you ask. Most of what an agent learns belongs here, and that is fine.
The first call of a task returns what binds the files being touched, ranked, inside a token budget. Nothing is dropped in silence.
files: internal/auth/middleware.go budget: 2000 est-tokens · used: 1712 · omitted: 2 [1] DECISION 01J9W… · active · scope: internal/auth/** Refresh tokens rotate on every use. evidence: commit 4f2a91c, pr #87 [2] DECISION 01J8Q… · VIOLATED (2 unresolved) Session records are never written from a handler. -- proposed decisions touching these files: 2, not binding -- omitted (over budget): 2, named with their rank
02 — The lifecycle
It is a governed object with states, evidence and an append-only history. Here is every state it can reach.
An agent, an importer or the v1 migration saves a decision. It is captured and inert: it does not bind, and it is never packed as context.
varve decision pending A human accepts it, with at least one piece of evidence. Now it binds, and it is packed into every session that touches its scope.
varve decision accept 01KMDX --evidence commit:9f2c1ab A commit contradicted it. The rule still binds, and the report says how many unresolved places contradict it. This is not a repeal.
varve report --decision 01KMDX --raw Content is immutable once accepted. Changing what a rule says means a successor decision that replaces it, so the history keeps its meaning.
memory_save(topic_key: "decision/database") Repealed, terminally. Nothing is deleted: re-adopting the rule later means a new decision citing this one, never a resurrection.
varve decision revert 01KMDX Acceptance, rejection and repeal are CLI actions. There is no MCP tool for them, because an agent asserting that you approved something is exactly the assertion the quarantine exists to distrust.
03 — The record
Every link is an append-only event, and every figure in the report drills back down to the rows behind it. A number that cannot be traced is not printed.
coverage 3 of 5 agent sessions (60%) produced an
attributable decision to diff event
via pack: 3 · via recall: 0
follow-through 4 of 5 attributed changes conformed
observer 16 of 16 default-branch commits observed
ID packed matched conform violate
01J9WKQ2M4 7 4 3 0
01J8QF7RTB 5 2 1 1 Attribution is a traceable record, not a causal one. Conform means no violation signal was detected, not that compliance was verified. The report prints its own limits, every time, on the report.
04 — The surface
varve setup writes the MCP entry and the
instruction block your agent reads. Governance stays off this surface entirely.
05 — Install
One binary. No daemon, no container, no account. Your store is a SQLite file in the repository you are working in.
Homebrew 6 refuses any third-party tap until you trust it, so the first line is not optional. That is Homebrew policy, not something specific to this tap.