Skip to content

Dashboards report drift. Repository guards can stop structural drift from merging.

Codee3 turns structural repository-knowledge rules into local CI gates instead of remote dashboard scores. The checks are zero-dependency Node scripts. They run on your machine, exit non-zero on violation, and can be placed in any CI system that respects an exit code.

Scope, stated first. These checks read the governed .ai/ directory and check its structure. They do not read your source tree, do not evaluate whether a sentence is true, and do not observe anything at runtime.

01 · The event

A structural violation, from commit to green

Five steps at your pace. The change is reasonable, the failure is specific, the correction is named rather than guessed, and the record of what happened ends up in the ledger instead of in a filename.

Everything shown is the real output shape of check:no-versioning and its real remedy line — rendered as text, never as a screenshot.

feat/payments-rearchitecturediff
  • .ai/domains/payments/architecture-v2.md
  • .ai/domains/payments/00_INDEX.md
  •  
  • A new architecture document lands beside the existing one. The index is updated to point at it. Reviewed, approved, entirely reasonable.

Step 1 of 5

02 · The instruments

5 checks, each enforcing one invariant

Each guard is a zero-dependency Node script wired into package.json. It runs locally, prints what it found, and exits non-zero when the invariant is violated — which is what lets any CI system fail the build on it.

Checks
Governed document and reference names for version-suffix patterns — `v2`, `mk2`, `FooV2`, `api-v2` and equivalents.
Exits non-zero when
A versioned name appears anywhere inside the governed brain.
Scope · will not look outside this
The governed `.ai/` directory only. It will not fail your build over `apiV2Client.ts` in application source — Codee3 imposes no naming policy on your code.
Why it is worth a gate
A version suffix declares a successor and forks truth. Once two documents both claim to describe the same concept, every reference becomes ambiguous and every reader has to work out which one governs.

Implements: Every concept has exactly one timeless identity

What the reference registry is for

Given a canonical fact, returns every governed document that references it. Run it before a rename so the whole fan-out is fixed in one pass, rather than discovering the stragglers when the reference guard fails.

$ npm run brain:refs:radius -- payments-provider
brain:check:referencescanonical fact payments-provider
Reference graph for one canonical factFive governed documents reference the canonical fact payments-provider, declared in DECISIONS-LEDGER.md. Four references resolve. One, in domains/checkout/00_INDEX.md, still uses the retired name payments-provider-v2, so the reference guard fails.DECISIONS-LEDGER.mdCANONICAL · declares payments-providerdomains/payments/00_INDEX.mddomains/payments/01_OVERVIEW.mdCURRENT-REALITY.mdEXECUTION-QUEUE.mddomains/checkout/00_INDEX.md✗ still references payments-provider-v2

A rename that misses one document leaves a reference that no longer resolves. Running brain:refs:radius before the rename lists the whole fan-out; brain:check:references fails the build if one is missed.

check:no-versioning FAILED — 3 versioned reference(s) in .ai:  .ai/domains/payments/00_INDEX.md:1  [v<n>]  v2  .ai/domains/payments/00_INDEX.md:5  [<name>-v<n>]  i-v2  .ai/domains/payments/00_INDEX.md:5  [<name>-v<n>]  s-v2 The brain owns change — rename to a timeless name; record evolution in the changelog.Legit external pin? add `no-versioning:allow-line` on that line, or `no-versioning:allow` to the file.

A clean result says where it stops

Every guard reports the ground it did not examine — version-control internals, vendored dependency trees, anything it could not read — and says so in the same breath as the pass. The wording is deliberate: “this guard’s verdict does not extend to them.” A check that skipped something silently and still printed a green result would be worse than no check, because you would trust it.

NOTE 1 path(s) were deliberately not scanned for references (declared-exclusion): .git — this guard’s verdict does not extend to them.

03 · The boundary

What these guards do not prove

The guards establish that the knowledge layer has not structurally broken. That is a narrower claim than it first sounds, and the difference is the whole reason to trust the rest of this page.

Factual inaccuracy in prose
The guards do not read a sentence and decide whether it is true. A governed document can pass every check and be entirely wrong.
Semantic divergence between documentation and code
Nothing compares the content of a document against the implementation it describes. Codee3 reads the governed Markdown, not your source tree.
Runtime behaviour
No part of the product observes a running system. These are file-structure checks executed at merge time.
Production correctness or safety
Passing guards do not indicate that a release is safe. They indicate that the knowledge layer has not structurally broken.

A passing brain:check means the structure holds: nothing is versioned, every folder is indexed, every reference resolves, routing is valid. It does not mean the contents are correct. Somebody still has to be right about the system, and write it down.

04Tested to break

The guards were tested until a round found nothing.

Before release, every guard had to survive isolated adversarial testing against a blinded release artefact — commissioned fresh each round, forbidden from reading anything but the tarball itself. A round that finds something real closes it and the artefact is re-qualified before the next round starts. Release happens on the round that finds nothing.

Self-administered, not third-party — isolated AI-agent instances attacking a blinded release artefact, not a security firm's signature. Stated as exactly that, because the difference is checkable.

Adversarial test record21 rounds · 6 classes closed
Found
Under simulated crashing writers, an early version silently lost governed records — 23 out of 17,142 (0.096%) in the reproduction that found it — a race in the lock-and-swap path that let two writers both believe they held it.
Closed
The ledger swap became atomic independent of the advisory lock, via a per-write commit claim keyed to the exact bytes being replaced.
Held under re-attack
Re-attacked with escalating load across seven further rounds — up to 211 real process kills against 17,600+ writes in a single round. Zero losses since the fix.
And then, separately

Qualification rounds are not the last word. A release candidate then faces a separate gate: readers who have seen none of the development, given only the tarball, the digest it is expected to match, the boundary a customer is promised, and an instruction to break it. Their verdict is on the artefact that would actually ship — and the digest they audited has to be the digest that gets delivered, or the verdict does not transfer.

Twenty-one rounds is not a claim that nothing else is findable — and it is deliberately not the number of rounds that found nothing. It is a record of what was found, that every round which found something real closed it, and that the artefact was re-qualified before the next round began. The count is high because the standard is a clean round, not a good one.

05Architecture

Local gate, not remote score

Codee3 turns structural repository-knowledge rules into local CI gates instead of remote dashboard scores. The difference is where the check runs and what happens when it fails.

Comparison of remote scheduled reporting and local repository guards across five dimensions
DimensionRemote scheduled reportingLocal repository guards
Where the check runsA vendor backend, on the vendor’s scheduleYour machine and your CI runner, on your commit
When you find outWhen the dashboard next refreshesBefore the merge completes
What happens on violationA score drops; a notification may be sentA non-zero exit code, which fails the build if you wire it to
What the check needsAn account, an integration, and your repository contents transmittedNode 18 or newer, and the files already in your working tree
Who owns the resultThe vendor stores itIt is stdout and an exit code; nothing is transmitted

This is a difference in architecture, not a claim that other products cannot fail a build. Plenty can — linters, static analysis, policy engines and PR gates all block merges every day. The distinction is what is being gated: those tools gate the code. These gate the structure of the repository’s own knowledge layer.

Wiring it in

# .github/workflows/brain.yml
name: brain
on: [push, pull_request]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      # Non-zero exit fails the job. No account, no token, no network call.
      - run: npm run brain:check
06Rollout

Turning it on without a big bang

The first run on an existing corpus usually finds things. A gate that blocks everybody on day one is a gate that gets removed in week two, so adoption is staged.

  1. Run it locally

    Run `brain:check` on the repository as it stands. The first run on an existing corpus usually finds things; none of it is blocking anyone yet.

  2. Run it in CI, non-blocking

    Add the job but let it report. The team sees what the guards catch before the guards can stop anyone merging.

  3. Make it required

    Once the corpus is clean and the team recognises the failures as fair, promote the job to a required check.