What must always remain true — in one file, in plain language.
Not a framework. Not SaaS. A .invariants dotfile you commit like .gitignore.
Optional starter kit: multi-repo cascade, vecs code index (no markdown in the corpus),
GitHub triage via gh, and a conformance agent that pattern-matches severity to
BLOCKED, PROCEED TO TRIAGE, PROCEED, or CLOSE.
The dotfile is the law; the agent is the clerk.
When a system spans many repositories, no one holds the full picture. A change in one repo
breaks an assumption in another. Tests pass. Builds succeed. Architecture quietly becomes
something else. .invariants makes non-negotiable conditions explicit — for humans
in PR review and for agents with codebase access.
Claims in plain language — not a rules engine, not ArchUnit, not linter config.
Apex constitution plus per-repo files with inherits. One repo is the degenerate case.
Verdicts come from threatened severity — FROZEN, VERSIONED, ADDITIVE — not from chat mood.
Incompatible sub-repo claims may be an intentional fork. Say so in the review. Never store fork status, issue numbers, or “currently failing” in the dotfile.
.invariants sits at the intersection of ADRs and architectural fitness functions —
and fills the gap neither covers alone.
ADRs capture why a decision was made. The why: field in each assertion is an ADR in miniature.
ADRs document the past. They do not tell an agent what to do when a proposal threatens them.
Automated checks on structure and dependencies. severity and the verdict table are fitness-function logic.
They need executable rules. They cannot express “every consumer hashes identity identically” without bespoke code.
With an LLM evaluator, assertions are executable. Load the cascade, read real source, match severity. The dotfile is the enforcement surface.
fills: semantic invariants static analysis cannot check.
Ship .invariants in any repo (Level 1). Use the reference workspace when you want
the full loop: code index, issue triage, agent reports (Level 3).
cp .invariants.example .invariants in your repo. No vecs, no agent required.
Apex + per-repo files with inherits and cascades_to. Your own agent rule or review checklist.
bash setup.sh — submodules, Qdrant, index, needs_triage issues, conformance agent in Cursor.
Apex /.invariants plus {repo}/.invariants. Claims, severity, optional verify hints. Maintainers only — agents never edit dotfiles.
Starter kit rebuilds a code-only Qdrant collection via vecs query. Markdown on disk orients the agent; it is not embedded — avoids “what we wrote” masquerading as “what runs.”
Fetch needs_triage issues into issues/. Agent writes reports/, posts comments, flips in_triage. Ground truth: code in vecs + label state on GitHub.
Long-lived .md files declare edit mode on line 1: <!-- ·NAV:M --> (map paths), S (sync facts). IMPLEMENTATION_MAP.md is meant to be agent-curated after code discovery.
Source in product repos — .ts, .js, .sol, .cs by default. PASS / FAIL / UNKNOWN from files you read after vecs query.
CONTRACT.md, map, issues, reports. Wildcard when untagged. Constitution stays in .invariants only.
On forks: Incompatible apex vs sub-repo claims may be an intentional fork.
State that in the conformance report. Operators decide. Do not add fork metadata,
waivers, or PASS/FAIL notes inside .invariants.
The agent pattern-matches threatened severity. Audit PASS/FAIL is per-run output — never written back into the dotfile.
Batteries-included reference workspace: vendor/vecs submodule, Qdrant (Docker by default),
optional macOS daemon for power users, gh for triage. Then open the conformance agent in Cursor.
Host this page on GitHub Pages from /docs.
Convention only? Copy .invariants.example into any repo — no starter kit required.
File format ↓
.invariants file looks likeDeliberately simple. Maintainer-edited YAML. No “currently failing”, no issue numbers, no fork flags in the file.
Tools describe what was built. .invariants defines what the system is allowed to remain.
Navigational markdown may drift and be repaired; the dotfile is governance.
Take the convention into any repo. Use the starter kit when you want the full agent loop on your machine.