Boundary enforcement for AI coding agents.
Declare each module's interface and dependencies in plain YAML. anma sync compiles that into the CLAUDE.md, hooks, and CI checks that keep an agent inside your architecture — author once, enforce everywhere.
ANMA's value depends on the model. We publish both halves.
A frontier model respects a documented architecture on its own. A cheaper or faster model doesn't — and that's exactly where ANMA earns its place.
Already inside the lines
Across the scenarios tested, Opus 4.8 never crossed the boundary on its own, and the ANMA arm used more turns. We don't claim ANMA makes a frontier model smarter, because the data says it doesn't.
Routinely steps over
On payments-boundary, Haiku violated the boundary in 13 of 19 control runs and 0 of 20 with ANMA. orders-inventory pointed the same way (2/5 → 0/5).
Contracts are the source of truth. Everything else is generated.
You maintain small YAML contracts. anma sync compiles them so the architecture the agent reads can never drift from the rules CI enforces.
GUIDANCE in-session steering
The generated root and per-module CLAUDE.md put your architecture in the agent's context. This drove the 68% → 0 result — the model was steered to the right design and never attempted a bad edit.
ENFORCEMENT the hard backstop
A PreToolUse hook judges the proposed edit and blocks any new disallowed import before it lands. The same check runs at pre-commit and in CI.
The same task, with and without ANMA.
An independent scorer counts disallowed cross-module imports in the agent's final code against each scenario's declared graph. Incomplete runs are flagged and excluded, so a blocked run can't read as a clean pass.
| Scenario · model | Arm | Trials | Violations | Mean | Hook blocks |
|---|---|---|---|---|---|
| payments-boundary · Haiku 4.5 | control | 20 (19 scored) | 13 | 0.68 | — |
| payments-boundary · Haiku 4.5 | anma | 20 | 0 | 0.00 | 0 |
| payments-boundary · Opus 4.8 | control | — | 0 | 0.00 | — |
| payments-boundary · Opus 4.8 | anma | — | 0 | 0.00 | 0 |
Why hook blocks read 0: guidance prevented the violations before the hook was needed. The enforcement hook is verified separately to fire (a forbidden edit returns exit 2). Both layers work — guidance does the work in practice, enforcement is the backstop. Limits: n=20 on one scenario, one model family, three hand-built scenarios. The raw per-trial data is committed in the repo.
Best where the agent isn't perfect.
Cheaper agent fleets
Cost-sensitive pipelines, bulk tasks, non-frontier or non-Claude models that don't reliably respect an architecture on their own. This is where ANMA's steering is decisive.
An enforced architecture
A guarantee in CI and pre-commit that module boundaries hold — regardless of which model, agent, or human authored the change.
Architecture as data
Declared interfaces, ownership compiled to CODEOWNERS, and docs that can't silently drift from the rules they describe.
One contract. Python, Go, and TypeScript.
The contract graph — names, dependencies, ownership — is language-neutral. Only the part that resolves imports and runs the check is per-language, behind a swappable adapter. Adding a language is an adapter, not a rewrite: the neutral layers stayed byte-for-byte identical when Go and TypeScript landed.
| Language | External backend | Zero-dep fallback | Enforces |
|---|---|---|---|
| Python | tach | ast scanner | depends_on + interface |
| Go | go-arch-lint | import scanner | depends_on (module→module) |
| TypeScript | dependency-cruiser | import scanner | depends_on (module→module) |
What's measured: the gauge above is Python (~68%→0). For Go and TypeScript we pre-registered a harder, neutral-prompt benchmark — with a fixed efficacy floor — before collecting data. TypeScript: where the bare model crosses the boundary 18 of 20 times, ANMA produces 0 of 20 violations — Fisher's exact p<0.00001. A measured second-language result, not extrapolated from Python. Go: directional and significant (10/30→0/30, p=0.0004), but the control rate (33%) fell below our pre-registered 0.40 floor — so we report Go as suggestive, not yet efficacy. The same task drew 90% violations in TypeScript but 33% in Go: explicit imports make a language more boundary-respecting on its own, and ANMA helps most where they don't. Interface-level (public:) enforcement is Python-only today; one language per project.
Install. Declare. Enforce.
pip install anma[tach] # tach backend recommended; works without it too anma init # python (default) · or --language go|typescript anma sync # generates CLAUDE.md, hooks, tach.toml, CI anma check ✓ boundaries respected