memvet

command module
v0.12.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2026 License: MIT Imports: 2 Imported by: 0

README

memvet

CI

Integrity checks for file-based AI agent state: memory, instructions, decisions, and contracts.

Think go vet or fsck, not ESLint. memvet verifies properties you declare must stay true across a repo of markdown that an agent runtime reads as memory. It does not judge prose, and it is not a memory store or retrieval system.

check is read-only. It never edits, creates, moves, or deletes a file, and there is no --fix. The one write in the whole tool is memvet init, which creates a starter config once and refuses to overwrite it.

The failure mode

Runtimes like Claude Code and Codex load CLAUDE.md, MEMORY.md, and a folder of notes into context on every run. Those files drift silently:

  • MEMORY.md still points at a note that was renamed last week.
  • An append-only decision log was quietly rewritten.
  • CLAUDE.md and AGENTS.md are supposed to be identical and no longer are.

Nothing fails. The agent just starts working from something that is no longer true. memvet turns each of those into a RED finding with a file, a line, and a stable code.

60-second example

examples/broken is a three-file memory repo with two defects. Its config:

[pointers]
files = ["MEMORY.md"]
roots = ["memory"]

[tokens]
watch = ["MEMORY.md", "memory/*.md"]
budget = 400

memvet check examples/broken prints:

pointers  RED     MEMORY.md:6     dead reference: memory/preferences.md does not exist [pointers/dead-ref]
tokens    YELLOW  memory/acme.md  794 estimated tokens exceeds budget of 400 [tokens/over-budget]
docs: https://github.com/frankbesch/memvet/blob/main/docs/findings.md
memvet: 1 red, 1 yellow (tree a5e8a264f658)

RED means a declared invariant is broken and the run exits 1. YELLOW means something needs attention but does not fail the run unless you pass --strict. Every code links to a plain-English entry in docs/findings.md.

Install

brew install frankbesch/tap/memvet
go install github.com/frankbesch/memvet@latest

Or try it once without installing anything, on the repo you are in:

go run github.com/frankbesch/memvet@latest check .

With no .memvet.toml yet, check runs what it can infer from the tree and says so in its first line.

Or download a binary for macOS or Linux from the releases page and verify it against checksums.txt. memvet --version tells you what you got.

Quick start

From the root of the repo your agent uses as memory:

memvet init
memvet check

init inspects the repo, writes a .memvet.toml that enables only the rules it found evidence for, and reports what it enabled, what it only suggests, and what it refused to guess. memvet init --dry-run shows the config without writing it. Review it, then add rules from the table below as your repo accumulates invariants worth declaring. Ready-made configs for common layouts are in docs/recipes.md.

What can it protect?

I need to make sure that… Rule
references between memory files still resolve pointers
the decision log was only ever appended to append_only
copies of the agent instructions stay identical mirrors
an agent-owned block keeps its start and end markers blocks
a human-written brief was never written by an agent human_brief
decision ids are unique, cited, and in order ids
memory files stay within a token budget tokens
"last verified" stamps keep up with edits stamps
scratch files do not creep into the repo junk
credential-shaped strings never land in memory secrets

Ten rules, five ideas:

Family Rules Protects against
Referential integrity pointers, ids dangling or ambiguous references
Mutation and provenance append_only, human_brief rewritten history, wrong author
Replication and ownership mirrors, blocks copies that disagree, unsafe shared regions
Freshness and capacity stamps, tokens stale or bloated context
Hygiene tripwires junk, secrets things that should not be in the tree

A section's presence in .memvet.toml is what enables its rule. Full key reference: docs/rules.md.

In CI

The shortest form is the action, which fetches the released binary and runs check --format github:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0
- uses: frankbesch/memvet@v0.12.0
  with:
    strict: true
    base: ${{ github.event.pull_request.base.sha }}

A complete pull-request workflow using go install instead is in .github/examples/memvet.yml. The core of it:

- uses: actions/checkout@v4
  with:
    fetch-depth: 0
- uses: actions/setup-go@v5
  with:
    go-version: stable
- run: go install github.com/frankbesch/memvet@latest
- run: memvet check --format github --strict --base "${{ github.event.pull_request.base.sha }}" .

--format github renders each finding as an inline annotation on the diff. --base matters for append_only: a fresh checkout equals its own HEAD, so without a base the log has nothing to be compared against. fetch-depth: 0 makes that base reachable.

Tree receipts

Every check summary ends with a fingerprint of the exact tree it judged. A later run can be held to it with --expect-tree, which turns a tree that changed in between into one RED finding. memvet stores nothing; the caller keeps the receipt. Details in docs/tree-receipts.md.

Documentation

  • Configuration: the .memvet.toml format and what it rejects.
  • Rules: every rule, its keys, what it proves and what it cannot.
  • Recipes: copy-and-paste configs for common memory layouts, each a runnable example.
  • Command line: flags, exit codes, JSON and GitHub output.
  • Finding codes: what each code means and what to do.
  • Tree receipts: fingerprints and --expect-tree.
  • Development: tests, fixtures, releases, roadmap.
  • SPEC.md: the versioned build log, for design provenance.

What memvet does not do

  • Judge whether a memory is correct, useful, or well written.
  • Decide what an agent should remember.
  • Prove agent authorship when git metadata does not identify the agent.
  • Replace a full secret scanner; [secrets] is a last-mile tripwire on the working tree.
  • Repair anything. check never writes, and init only creates a config that did not exist.
  • Watch mode, HTML output, or a hosted service.

Contributing

Behavior changes start as a SPEC.md addendum with gates; see CONTRIBUTING.md. Bug reports and proposed invariants are welcome as issues.

License

MIT. See LICENSE.

Documentation

Overview

Command memvet checks mechanical invariants in file-based agent memory repositories. check is read-only: it never modifies, creates, or repairs files. The one exception in the whole tool is init, which creates a starter .memvet.toml and refuses to overwrite an existing one.

Directories

Path Synopsis
internal
cli
Package cli implements memvet's command line: argument parsing, exit codes, and output selection.
Package cli implements memvet's command line: argument parsing, exit codes, and output selection.
config
Package config loads and validates .memvet.toml.
Package config loads and validates .memvet.toml.
lint
Package lint evaluates memvet's rules against a repository root.
Package lint evaluates memvet's rules against a repository root.
report
Package report renders lint results as text or JSON.
Package report renders lint results as text or JSON.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL