git blame answers who and when. This answers why, for entities git has no concept of — a column, an environment variable, a dependency bump. The tool that pays for the whole thing is prior_attempts: called before an edit, it surfaces the approach that was already tried and reverted, which is exactly the failure mode of handing a codebase to a fresh agent every session. Everything is local SQLite with no model in the path, and it only works if your agent instructions tell it to log as it goes.
A local change ledger that coding agents write to as they work. Each event records the entity that changed, the diff, the reasoning behind it and the constraint it was made under, into a SQLite file beside the code — so the why survives long after the session and the prompt that produced it are gone.
- log_change records a change to an entity with its diff, reasoning, change type, constraint, git commit and session, and can mark what it supersedes and the condition that would make it stale
- blame returns the most recent change to an entity — what changed, when, by which agent and why — for things git blame has no line for: a database column, an environment variable, a dependency
- diff returns an entity's history newest first with prefix matching, so a table name also returns its columns
- history filters across every entity by date, project, entity path or changeset, and changeset reassembles all the events sharing an id, oldest first, to reconstruct a whole feature
- search runs full text across entity paths, diffs, reasoning and agent names
- prior_attempts is the one to call before editing: previous attempts on that entity with an inferred outcome, so an approach that was already tried and reverted is visible before it is tried again
- stale_decisions surfaces decisions past their revisit date or with a triggered stale condition, by two deterministic rules rather than a judgement call
- No model sits anywhere in that path — the reasoning stored is what the agent wrote at the time, not an interpretation of the diff produced afterwards
Published on PyPI as selvedge and launched over stdio as selvedge-server — with uvx the entry point differs from the package name, so it needs --from selvedge — and there is an npm wrapper published as selvedge-mcp. Data lives in a SQLite file at .selvedge/selvedge.db beside the codebase, relocatable with SELVEDGE_DB. None of it fills up unless the agent actually calls log_change as it edits, which is what the few lines the README has you add to CLAUDE.md are for.
One command — pip install selvedge
