ADR-003
12-gate crate admission protocol
accepted · 2026-04-13 · L0 L0.5 L1 L2 L3 L4 L5 · cites 20
0ADR-003: 12-gate crate admission protocol #
Context #
The Diamond rewrite (ADR-001) is valuable only if the new crates don't accumulate the same debt as legacy (1,276 unwraps, 47 oversized files, silent rot). Code review alone failed in the legacy codebase — reviews happened, yet a P0 audit discovered 29 broken MCP aliases that had lived for months. The enforcement must be mechanical, not social.
Five crates have been admitted to date (nika-error, nika-catalog, nika-catalog-verify, nika-kernel, nika-kernel-mock). Each carries the commit body listing all 12 gate results. The process works under load.
Decision #
Every crate passes 12 sequential gates before its path is added to Cargo.toml members:
- # · Gate · Enforces
- 1 · SPEC doc · crate purpose + API surface documented in `docs/crate-specs/<name>.md`
- 2 · TDD red/green · failing tests written before implementation
- 3 · IMPL compiles · workspace builds with the new crate added
- 4 · Zero Clippy warnings · `cargo clippy -- -D warnings` clean
- 5 · Mutation ≥90% · `cargo-mutants` kills ≥90% of mutants (or documented exemption)
- 6 · Property tests · `proptest` on security/parser/boundary code
- 7 · Benchmarks · `criterion` on hot paths if applicable
- 8 · Zero `cargo doc` warnings · `RUSTDOCFLAGS="-D warnings" cargo doc --no-deps` clean
- 9 · Canary E2E · 1 real workflow exercises the crate end-to-end (or exempted for infra crates)
- 10 · Golden parity test · output matches legacy where applicable
- 11 · 3-agent review swarm · parallel review by fresh agents, all findings resolved
- 12 · Atomic commit · single commit with full admission body
Exemptions (e.g., Gate 9 N/A for nika-error) require written justification in the crate spec. No gate skipping without explicit record.
Admission commit body format is mandatory (see .claude/rules/commit-granularity.md).
Consequences #
Positive #
- Every admitted crate starts at a correctness floor legacy never achieved: 0 unwraps, 0 clippy warnings, ≥90% mutation killed, documented public API.
- Regression detection front-loaded, not retrofitted.
- Proven on 5 crates:
nika-error100% mutation,nika-kernel100% mutation,nika-kernel-mock95.7%. - Bisect-friendly history: one crate = one atomic commit.
Negative #
- Admission is expensive per crate (a full session per admission in some cases).
- Gate 5 (
cargo-mutants) is slow on larger crates — up to ~20 minutes onnika-catalog. - Gate 9 (E2E) is N/A for infrastructure crates, requiring explicit documented exemptions.
- Velocity-over-Safety tension: an under-pressure solo dev might rationalize skipping a gate. The process must be socially enforced via memory + reminders.
Neutral #
- Agent review (Gate 11) requires ~3 parallel sub-agents per admission — acceptable cost given error detection rate.
Evidence #
.claude/CLAUDE.md— 12-gates summary.claude/rules/commit-granularity.md— mandatory commit body formatCHANGELOG.mdlines 196–216 —nika-kerneladmission with all 12 gates confirmed, commitef8804371scripts/ci/— check scripts (≈one per Gate):check-clippy.sh,check-crate-size.sh,check-dead-code.sh,check-expect.sh,check-fn-length.sh,check-loc-limits.sh,check-no-default-features.sh,check-tests.sh,check-unwrap.sh,check-adr-coverage.sh(see ADR-009),check-mutation-floor.sh(the REAL Gate 5 executor, 2026-06-10).github/workflows/diamond-ci.yml— CI matrix running the gates- memory:
crate-admitskill +gate-checkskill — automation entrypoints
Alternatives considered #
Alt A — Code review only #
Rejected empirically — legacy had reviews, still accumulated 1,276 unwraps.
Alt B — 8-gate protocol #
Earlier draft. Rejected because mutation coverage, property tests, and the agent review swarm each caught real issues in admission sessions. Downgrading to 8 would re-open those failure modes.
Alt C — Gates as PR-level CI only (not admission commit) #
Rejected because CI failure on a PR that has already touched 6 crates is expensive to unwind. Gates run before admission commit lands on nika-diamond.
Related #
- ADR-001 — orphan rewrite (the reason this process exists)
- ADR-004 — context-window sizing (why we have ~40 admissions to run)
- ADR-009 — ADR process (Gate 12 invokes ADR check)
crate-admitskill — guided admission workflowgate-checkskill — run gates against an in-flight crate
Notes #
If a future gate proves redundant (e.g., Gate 10 golden parity becomes meaningless post-v0.95), revisit and supersede. Gate count is not sacred — enforcement floor is.
Amendment — 2026-06-10 · social → structural enforcement #
The Context section's thesis ("enforcement must be mechanical, not social")
and the Negative note ("an under-pressure solo dev might rationalize skipping a
gate · socially enforced via memory + reminders") had two residual honor-system
gaps. Both are now structurally closed (no decision change · additive per
cross-source-validation.md §2.7):
- Gate 5 (mutation ≥90%) was checked only by presence (the crate-spec
mentioning "Mutation"). Now
scripts/ci/check-mutation-floor.sh <crate> [floor]actually runscargo-mutants, parses the kill ratio (caught / viable, excluding unviable), and fails below the floor. Admission/CI-tier (minutes-slow — not pre-commit). - Gate 2 / ADR-081 guards for L1 computer-use crates (
nika-screen,nika-a11y,nika-input,nika-browser,nika-vision-local) were "MANDATORY-at-admission" in prose only. Now hygiene vector 35scripts/hygiene/check-adr-081-guards.shreads the ADR-081 ownership matrix and FAILS if a workspace guard-owner lacks its guard impl+test (binding inscripts/ci/adr-081-guard-manifest.tsv). Declarative/evolutive: a future guard-owner (e.g.nika-inputM2.4 Guards 1+2) goes RED at admission until the guard ships.
Companion supply-chain hardening (same arc): hygiene vectors 34
(check-cargo-deny.sh — bans/licenses/sources, superset of vector 15 advisories)
and 36 (check-unused-deps.sh — cargo-machete).
read at v0.107.0 · the decision record ships with the engine