Skip to content

Attestrum/stalemaid

Repository files navigation

stalemaid

stalemaid

Your architecture diagrams can't silently lie.

stalemaid is a CI gate that fails a pull request when code a mermaid diagram claims to model changes, but the diagram doesn't change with it. It reads provenance frontmatter on your diagram files and enforces that code and its diagram co-change in the same PR.

$ stalemaid check
stalemaid: 5 checks run, 1 failure(s)
  FAIL [drift] docs/diagrams/billing.md: code file src/billing.ts changed but
       referencing diagram docs/diagrams/billing.md (source_of_truth: code) was
       not changed in the same PR/commit — update the diagram and bump last_verified

Why this exists

Diagrams-as-code rot the moment the code moves and the diagram doesn't — and a stale diagram is worse than none, because people trust it. Most documentation-freshness tooling flags staleness after a change has merged, or regenerates docs automatically. stalemaid instead makes co-change a pre-merge gate: if a pull request touches code a diagram declares it models, the diagram has to change in the same PR or the build fails. See docs/how-stalemaid-works.md for the full walkthrough.

How it works

Each diagram is a markdown file with mandatory frontmatter:

---
title: "Billing flow"
models: "src/billing.ts, src/lib/charge.ts"   # the code this diagram describes
source_of_truth: code                          # diagram | code | spec
last_verified: a1b2c3d 2026-06-15              # short SHA + date (or `bootstrap <date>`)
diagram_type: flowchart
---

stalemaid check runs five checks over every *.md under --root (default docs/diagrams):

Check Fails when
frontmatter any of title, models, source_of_truth, last_verified is missing
freshness last_verified SHA is outside the recent-commit window (bootstrap allowed only for diagram/spec)
mermaid a ```mermaid block doesn't parse
forward-ref a models: path on a source_of_truth: code diagram doesn't exist on disk
drift a models: code file changed in the PR but the diagram didn't

The source_of_truth lifecycle: diagram (the contract, before code exists) → code (derived view once built; now gated for drift) → spec (external authority; drift means your code is wrong). Only code diagrams are drift-gated.

Install & use

# one-off, no install
npx stalemaid check --root docs/diagrams

# or install
npm i -D stalemaid
stalemaid check [--root <dir>] [--strict] [--json] [--skip-mermaid]
  • STALEMAID_BASE — git ref for PR-mode drift (e.g. origin/main); uses <base>...HEAD. Unset → the staged set (git diff --cached), ideal for a pre-commit hook.
  • STALEMAID_MMDC — absolute path to an mmdc binary (overrides the resolver chain).
  • Exit codes: 0 pass, 1 findings, 2 usage error.

The mermaid-parse check shells out to mermaid-cli (mmdc), resolved from $STALEMAID_MMDC → local node_modules/.binPATHnpx @mermaid-js/mermaid-cli. It needs a headless browser; pass --skip-mermaid where one isn't available.

GitHub Action

# .github/workflows/diagrams.yml
on: pull_request
jobs:
  stalemaid:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0          # drift + freshness need git history
      - uses: your-org/stalemaid@v0
        with:
          root: docs/diagrams
          skip-mermaid: "true"    # mermaid parsing needs a browser; opt in if yours has one

fetch-depth: 0 is required — the drift and freshness checks read commit history. In PR runs the action defaults STALEMAID_BASE to origin/$GITHUB_BASE_REF.

Pre-commit hook

# .git/hooks/pre-commit
npx stalemaid check --root docs/diagrams || exit 1

With no STALEMAID_BASE, stalemaid uses the staged set — so it catches drift before the commit is even made.

Development

npm install
npm run build
npm test          # vitest
bash tools/render-diagrams.sh   # render docs/diagrams to gitignored PNGs, then eyeball them

stalemaid governs its own diagrams (docs/diagrams/engine/) — drawn before the code and gated by the tool itself.

License

Licensed under either of Apache License 2.0 or MIT license at your option.

About

CI gate that fails a PR when code a mermaid diagram models changes but the diagram doesn't. Your architecture diagrams can't silently lie.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages