English | 简体中文
Claims are cheap. Agents report "done", "fixed", "verified"; dashboards report green. Evidence is not cheap, and almost nothing forces a claim through it before the claim is believed.
ev is a small command-line closure engine for one person and the agents working alongside them.
An agent files a claim with a typed evidence pointer. The engine checks that the pointer
resolves — deterministically, never judging whether the work is good — and counts how far the
world has since moved under each anchor (drift). Only the
human closes a claim: with evidence, on hold, or declared dead. Nothing gates, nothing blocks —
a short daily pause is where the judgment happens, and a line of what closed with evidence is
what accumulates.
agent claims ─▶ evidence pointer ─▶ anchor resolves? (exists · matches — a fact, not a verdict)
│
drift: how far the world has
moved under the anchor since
│
the human closes ─▶ close with evidence
(nothing gates; a claim with no │ hold (grey)
evidence simply waits at the pause) └─ declare dead
│
the line: closed-with-evidence vs let-go
cargo install evolving # installs the `ev` binaryPrebuilt static binaries (including aarch64 musl for hosts without a toolchain) are attached to each GitHub Release.
ev init # enroll a repo
ev hook install # wire the session hooks: auto-capture + the brief
ev claim "fixed the parser" \ # an agent files a claim with a pointer
--by agent --evidence commit:<sha>
ev claim "the boundary is safe" # a bare claim — no pointer yet
ev reading <claim> --depth plain --lang en <ref> # an agent points a non-author's read at it
ev verify # re-check anchors; report status joined with drift
ev pause # the human's daily ritual: demand, attach, hold, ack, let go
ev ack <claim> --i-am-the-human # the human looked; the claim still stands
ev line # the work line: what closed with evidence
ev doctor # check the ledger's integritySessions also leave exhaust: your commits are captured automatically as self-evident claims, so you don't file one for every commit — you file one when you want to assert something a bare commit doesn't say, and back it with a pointer.
Evidence pointer types: commit:<sha> · test:<path>[::<text on the cited line>] ·
file:<path>[::<text on the cited line>] · artifact:<name>[::<text on the cited line>] ·
metric:<text> and url:<text> (recorded, not checked).
The :: payload is text to match, never a line number — ev anchors by content. file:src/x.rs:56
is refused; file:src/x.rs::fn parse( goes red when that line changes, while a bare file:src/x.rs
goes red only if the file is deleted.
Everything is an event in an append-only ledger (.evolving/ledger/, one JSONL file per machine,
committed with the repo). No database, no daemon: every invocation re-reads the events and folds
them into the current state — a claim moves bare → evidenced → anchored, or sits grey, or ends
closed or dead. History is never rewritten; corrections are new events beside the old ones.
An anchor is checked for exactly one thing: does the pointer resolve — the commit exists, the
file contains the named line. resolves is a fact about the pointer, never a verdict on the claim.
Evidence auto-derived from your own commits is marked ⊙ (self-evident); independently filed
anchors get ✓ — never the same mark, because evidence must not self-certify.
A filed anchor records the repo state it was filed against (its base). For path-bearing anchors
(test:, file:, artifact:), ev can then count drift: how many commits have touched the
cited path beyond that base. (Auto-captured commit exhaust carries no base — a commit is its own
fixed point.) Drift is measured in world movement, not clocks — an anchor can still resolve while
the claim it supported has gone stale underneath. The engine counts; what the count means is the
human's judgment.
status and drift, read side by side, are a cell: still (measured, and zero) ·
neighborhood-moved (the cited line stands, but code moved beside it) · anchor-changed ·
file-gone · legacy (a pre-0.2.3 status ev cannot classify without re-checking). No cell is shown
when drift could not be measured — an absent cell means ev asserts nothing. neighborhood-moved is
the anchor's blind spot made visible: most caller-visible defects are fixed by adding code beside
the cited line, which leaves a content anchor green. ev cannot tell anyone a claim was fixed —
only that the ground under it moved, which is a prompt to re-read, never a verdict.
A claim may also carry a reading: pointers an agent fills over comprehension depth
(maintainer — the claim itself; plain — a non-author's read; ground — assumes zero
background) and language (zh/en), so a claim written for a maintainer is not the only way in.
ev stores the pointer, never the explanation, and states which slots are empty — a fact, never a
grade. At the pause, > drills one depth deeper and ~ switches language; a cognitive-debt
line — "last understood N commits ago — re-read" — appears only on a claim whose anchored code has
moved since the human's last look.
That judgment happens at the pause: demand evidence, attach it, hold in grey, ack that it still
stands, or let a claim die. Closing is its own deliberate act — ev close <id>, on a claim that has
earned it. What accumulates is the line — two raw counts, never a score.
- Facts, not verdicts. The engine checks whether a pointer resolves and how far the world has drifted under it — never whether the work behind it is good, never by asking a model, never over the network. Whether the evidence covers the promise is the human's call at the pause.
- Nothing gates. Session hooks always succeed; the only refusals are on your own verbs — a claim closed without evidence is refused, because closed-anyway should not exist.
- No comprehension score. ev never generates, completes, or grades an explanation. A
readingstores only pointers; ev reports which slots are empty, never how good a filled one is. - Only the human closes. Agents may file claims and attach evidence. Closing is yours.
- No daemon. State refreshes when you invoke
ev, never in the background.
A repo running ev carries an AGENTS.md that tells any coding agent how to file
evidence-backed claims and answer a demand.
The internals — the append-only ledger, the fold, anchor resolution and drift, the sweep, and the
pause — are described in docs/design.md.
Apache-2.0.