Skip to content

Releases: frankbesch/memvet

v0.12.0

Choose a tag to compare

@github-actions github-actions released this 17 Sep 05:19

Changelog

  • 1279734 action: empty-array-safe expansion in the check step (bash 3.2 under set -u)
  • 3f984b7 rename: memlint becomes memvet (v0.12.0; D-### at wrap, ruled 2026-09-17)

Install with go install github.com/frankbesch/memvet@v0.12.0, or
download a binary above and verify it against checksums.txt.

v0.11.1

Choose a tag to compare

@github-actions github-actions released this 17 Sep 04:04

Changelog

  • 4bbaf60 docs: pin the Action and pre-commit snippets to v0.11.1
  • b3e56cc docs: retire the [secrets] entropy detector from the roadmap (D-### at wrap, 2026-09-11)
  • 7eca25b init: infer a flat memory folder from MEMORY.md alone (v0.11.1)

Install with go install github.com/frankbesch/memlint@v0.11.1, or
download a binary above and verify it against checksums.txt.

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 19:35

What's new

This release is about the first five minutes: memlint now does something useful before you have written a config, checks the memory folder Claude Code keeps outside your repo, and runs as a GitHub Action or a pre-commit hook.

check runs without a config, and says so. With no .memlint.toml at the target, check runs the config init would have written and reports that first:

config    YELLOW  .memlint.toml  not found; ran the inferred config (pointers); memlint init to keep it [config/inferred]
    an inferred run checks only what the tree shows; declare the invariants you rely on
pointers  RED     MEMORY.md:3    dead reference: memory/gone.md does not exist [pointers/dead-ref]
memlint: 1 red, 1 yellow (tree eec04fc40977)

Nothing is written. The YELLOW fails the run under --strict, so a CI job that forgot its config is loud rather than clean. An invalid config is still exit 2; only absence infers. Try it on any repo without installing anything:

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

Flat memory folders. Claude Code's auto-memory is MEMORY.md beside its notes, indexed as [Title](note.md), with no folder to name as a root. The new [pointers] root "." checks slash-less link destinations against the file's own folder. Only link destinations count; a.md in prose is a word, not a claim. init infers it when MEMORY.md sits beside two or more notes and no markdown folder exists, which means this now works with no config at all:

memlint check ~/.claude/projects/<project-slug>/memory

Wider discovery. init and inference enable pointers on whichever of GEMINI.md, COPILOT.md, .github/copilot-instructions.md, .cursorrules, and CONVENTIONS.md exist, alongside MEMORY.md, CLAUDE.md, and AGENTS.md. The mirrors suggestion list is unchanged and still closed.

GitHub Action. Fetches the released binary, verifies it against checksums.txt, and runs check --format github:

- uses: frankbesch/memlint@v0.11.0
  with:
    strict: true
    base: ${{ github.event.pull_request.base.sha }}

pre-commit hook. Builds memlint at the pinned release with go install and runs check --changed on what you are about to commit:

- repo: https://github.com/frankbesch/memlint
  rev: v0.11.0
  hooks:
    - id: memlint

Compatibility

  • memlint check on a directory with no .memlint.toml used to exit 2 with a one-line refusal. It now runs and exits 0 or 1 like any other run, with the config/inferred YELLOW as its first line. Scripts that relied on the refusal (none known) should pass --strict, which turns the YELLOW into exit 1.
  • roots = ["."] used to be a config error. It now enables the sibling pass. No existing valid config changes meaning.
  • One new finding code, config/inferred. No code was renamed or removed, and the JSON schema_version stays 1.
  • Fixture counts, examples, the tree receipt, and all other output are byte-for-byte unchanged.

Install

brew upgrade memlint
go install github.com/frankbesch/memlint@v0.11.0

Binaries for macOS and Linux are attached; verify against checksums.txt.

Engineering notes

Commit b7733b0. SPEC.md v0.11 addendum parts 1–5 with gates; the post-push CI run 34639081021 is green on ubuntu, macos, and the new action job, which runs this repo's action.yml against examples/broken and asserts it fails. The addendum header records a competitor read of agents-lint, ctxlint, and claude-healthcheck, cross-checked the same day; the parts here close the first-run gaps only, and check still has no fix mode.

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 11 Sep 18:48

What's new

This release changes how memlint feels, not what it checks. No rule, finding code, or exit code changed.

Flags work before or after the path.

memlint check . --strict        # now works
memlint check --strict .        # still works

An unknown flag anywhere, a flag without its value, or a second path is still a usage error (exit 2), printed with that command's help. Nothing is ignored silently.

Each command has its own help. memlint --help is one screen: the three commands and where to go next. memlint check --help, memlint init --help, and memlint fingerprint --help each carry only what that command needs. memlint help <command> does the same.

init tells you what it inferred. It reports three tiers:

Enabled
  pointers      MEMORY.md, CLAUDE.md -> roots memory, docs
  junk          .DS_Store seen in the tree
Suggested (written as commented sections; uncomment to enable)
  append_only   memory/decisions.md exists
  mirrors       CLAUDE.md and AGENTS.md both present
Not inferred (needs a decision only you can make)
  human_brief   authorship is a policy choice
  tokens        a budget is a choice
  ...

The generated .memlint.toml is now short: a four-line header, the enabled sections, and commented sections only for the suggested rules. The full rule reference lives in docs/rules.md, not in every generated file. The suggestion list is closed: a decisions.md by name suggests append_only, two of CLAUDE.md, AGENTS.md, GEMINI.md at the root suggest mirrors, and nothing else is ever guessed.

init --dry-run prints the config it would write to stdout and the report to stderr, and writes nothing. It works when a .memlint.toml already exists, so you can rerun discovery on a configured repo. init still never overwrites, and there is no --force.

Also in this release

The README is now a landing page, with the reference material under docs/. docs/recipes.md gives copy-and-paste configs for a basic memory repo, a decision log, and shared instructions; each is a directory under examples/ that CI runs on every commit, and a test keeps the README's quoted output identical to the real run. A complete pull-request workflow is at .github/examples/memlint.yml.

Compatibility

  • memlint check <path> --flag used to exit 2. It now runs. Scripts that relied on the refusal (none known) would see a real result instead.
  • init no longer prints N rules enabled. Scripts that grepped for it should read the Enabled tier.
  • The generated config no longer carries commented examples for every rule. Existing configs are untouched.
  • Everything else, including JSON output, GitHub annotations, and the tree receipt, is byte-for-byte unchanged.

Install

brew upgrade memlint
go install github.com/frankbesch/memlint@v0.10.0

Binaries for macOS and Linux are attached; verify against checksums.txt.

Engineering notes

Commit c3d3314. SPEC.md v0.10 addendum parts 1–4 with gates G1–G6 (G6 is the post-push CI run, 34635112173, green on ubuntu and macos). Ruling D-143. No new rule ships until the next minor; new invariants face the admission bar in CONTRIBUTING.md.

v0.9.1

Choose a tag to compare

@github-actions github-actions released this 08 Sep 21:18

What's new

Anchored markdown references are now validated.

Before v0.9.1, memory/setup.md#install passed as long as memory/setup.md existed. Now the anchor must resolve too: #install has to match a heading slug, a {#custom-id} attribute, or an <a id>/<a name> tag in the target file. A miss is RED pointers/dead-anchor, and the finding lists the anchors the file does expose so the fix is a copy-and-paste.

Why it matters

A renamed heading used to leave agent memory pointing at a section that no longer exists, and nothing failed. It fails now.

Compatibility

Repositories with [pointers] enabled may report new pointers/dead-anchor findings on the first run. Each one is a real broken link. No config change is needed; anchored references were already extracted, only the anchor half was unchecked.

Install

brew upgrade memlint
go install github.com/frankbesch/memlint@v0.9.1

Binaries for macOS and Linux are attached; verify against checksums.txt.

Engineering notes

Commit 4bb6135. SPEC.md v0.9 addendum part 2, gates G1–G5. The planted-defect fixture is now 10 red, 4 yellow.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 08 Sep 21:00

Changelog

  • 8a9af9c docs: v0.9 futures — pointers/dead-anchor, secrets entropy
  • b816eaf v0.9: tree fingerprint — memlint fingerprint, tree receipt in every check summary and summary.tree, --expect-tree turns a moved tree into RED tree/moved (Frank ruled 2026-09-08; gates G1–G5 in SPEC.md)

Install with go install github.com/frankbesch/memlint@v0.9.0, or
download a binary above and verify it against checksums.txt.

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 05 Sep 16:54

Changelog

  • 4bd9197 check --changed: findings narrowed to files changed since HEAD (modified, staged, untracked); config-level findings survive; git-per-file rules skip the rest; exit 2 without git
  • 594cbe4 docs: v0.8 roadmap state
  • 8b0dc1c globs: recursive ** as a whole-segment wildcard in every glob-taking key (junk, tokens, pointers, ids); one translator for matching and validation
  • 9c5a887 ids: cited_in (dead citations are RED ids/dead-cite) and ordered = true (mid-log paste is RED ids/out-of-order)
  • 8e60827 v0.8: [blocks] mirror=true content mirroring; [append_only] per-file headers; [human_brief] follow_renames
  • 8a09cc2 v0.8: [stamps] last-verified dates vs the file's last change; [secrets] credential-shaped text (value never echoed)

Install with go install github.com/frankbesch/memlint@v0.8.0, or
download a binary above and verify it against checksums.txt.

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 05 Sep 16:42

Changelog

  • 4a00ae6 Add PreToolUse output-filter hook: noisy commands (go test/build/vet, make, npm/pip install) return only failures + summary + log path; fails open, unlisted commands untouched
  • 2151a8f append_only: rotation allowance — a cut span found verbatim in a new listed file is INFO append_only/rotated, not RED; header_lines marks the only mutable span
  • 4682712 docs: two-register findings entries — plain-English lead, expert detail after
  • df26d84 ids: known = [...] — reconciled collisions report as INFO ids/known-duplicate; a known id that never collides is YELLOW ids/known-unused
  • 5ad2a4c ids: new [ids] rule — every id opening a line must be unique across the listed files; duplicate = RED ids/duplicate citing the first occurrence
  • 4ca76b9 ids: the delimiter form "^(D-\d{3}) |" is the default pattern (Frank ruled 2026-09-05)
  • 2d2ef9f tokens: optional two-tier budget — limit=M adds a RED tokens/over-limit tier

Install with go install github.com/frankbesch/memlint@v0.7.0, or
download a binary above and verify it against checksums.txt.

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 11 Aug 16:45

Changelog

  • f3f3edd feat: pointers grow up — anchor-aware checking + glob support in files
  • 0e29ed3 feat: self-describing findings — docs/findings.md, doc_url, codes in text

Install with go install github.com/frankbesch/memlint@v0.6.0, or
download a binary above and verify it against checksums.txt.

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 11 Aug 16:18

Changelog

  • 441196f docs: roadmap reordered post-critique — pointers grow up, self-describing findings
  • 4030971 feat: --base turns [append_only] into a pull-request gate

Install with go install github.com/frankbesch/memlint@v0.5.0, or
download a binary above and verify it against checksums.txt.