Registers the fully-built-but-never-wired eval module into the CLI spine
and repairs its one real instrument bug. Three commits, RPI-shaped: wire
+ fix, drift guards + docs, fixture counts.
## What
- **`ao eval` joins the spine** (cmd/ao/eval_composition.go):
deterministic suite runs, run-record
compare/baseline/scorecard/coverage, locked Tasks, holdout scenarios,
suite A/B verdicts with power-derived n-required, and the holdout-safe
Outcomes projection. This is the operating contract's *Learn* seat — a
read/measure consumer of evidence. It reports numbers and owns no retry,
scheduling, promotion, or lifecycle authority. The retired Aliases/Bench
seats stay nil and their subcommands are omitted.
- **Instrument bug fixed**: both scenario-ab arms were corpus-denied at
runtime — the with-gold treatment was only a prompt injection through
the retired `ao lookup`, so the A/B silently guaranteed a zero delta.
Treatment is now environment-shaped: the with-gold arm runs with the
corpus readable, the control arm stays sandbox-confined (the fail-closed
empty-deny guard is untouched), and judges are always corpus-denied.
- **Schema drift guards**: a run record persisted by the production
writer must validate against eval-run.v1.schema.json (and the minimal
suite against eval-suite.v1.schema.json) — closing the same silent-fork
class the verdict.v2 golden corpus closed.
- **Hermetic test builds hardened**: keep the real HOME's Go caches
(TestMain isolation was forcing module re-downloads) and skip VCS
stamping.
- docs/architecture/go-cli.md gains the eval section; MIGRATION.md notes
`ao eval`'s return; COMMANDS.md, cli-surface, and surface counts
regenerated; new leaves carry honest allowlist reasons; new cmd/ao L2
tests drive eval run/compare/help through the full production wiring.
## Evidence
- Full cli suite 2,801 green; race green on cmd/ao + the eval island;
vet clean
- Full-tier gate: 65/66 on the penultimate commit; the single failure
(surface counts) is the final fixture commit, re-verified PASS
standalone — no other check reads those fixtures
- Fresh independent validation (Codex, frozen subject 86022a3c6, clean
tree at start and end): **OVERALL PASS**, 6/6 — including a live
end-to-end `ao eval run` producing a passing run record
- Rubric-relocation decision honored: true holdout rubrics live in the
external measurement register; the repo keeps only leak-guarded
projections
## Summary
- New `scripts/update-cli-surface-counts.sh` with `--check` (default)
and `--fix` modes to synchronize CLI heading counts across the smoke
script and canary matrix JSON
- Wires fast pre-flight count-check into contracts-sync CI (catches
drift in ms before the 180s canary build)
- Adding a new ao CLI command is now: add Go code →
`generate-cli-reference.sh` → `update-cli-surface-counts.sh --fix` →
push
## Test plan
- [x] Script passes in check mode with current counts (75/188/263)
- [x] Script detects simulated drift (exit 1 + clear error message)
- [x] `--fix` mode correctly updates smoke script and matrix JSON
- [x] Fixed files are byte-identical to originals (round-trip verified)
- [x] `bash -n` syntax check passes
- [x] Go build passes in worktree
- [ ] CI contracts-sync passes with new pre-flight step
Closes-scenario: ag-lkxx#cli-surface-regen
Bounded-context: BC5-Runtime
Evidence: scripts/update-cli-surface-counts.sh