Knowledge Audits

Tests that verify what agents in a box actually know — by prompting a real box agent, watching its tool use, and checking its response. Periodic execution catches knowledge drift as schemas, prompts, and conventions evolve.

The harness lives in src/dev/:

When to run

docs/maintenance.md lists this alongside the other periodic tasks.

See docs/reports/knowledge-audit-rerun-2026-07-03.md for the latest full-corpus rerun record.

Running

npx tsx src/dev/knowledge-audit.ts run --box ~/src/boxes/test1 [--filter <tag-or-id>] [--engine claude|codex]
npx tsx src/dev/knowledge-audit.ts list

--box takes the box root (~/src/boxes/test1) — there is only the one root to pass, and the context-history ledger keys off its basename (src/dev/lib/audit-box.ts). Pass an absolute path (or ~/…), never a bare name like test1, which would resolve inside the monorepo and be refused by the nested-box guard.

By default the runner uses the box's configured engine. --engine overrides that choice for the audit only, so the same definitions can be exercised against Claude and Codex without editing _config/box.json. Reports include the engine and use engine-qualified default filenames. Codex behavior is captured from the validated live app-server event stream; private rollout files are not parsed. Codex does not expose Claude-equivalent per-turn context snapshots on that surface, so Codex reports deliberately omit the context baseline rather than presenting incomparable usage as parity.

Recording results

After running audits, update the status comments in knowledge-audits.yaml with the date and results. Each test section (e.g., # === Don't Drop Important Information ===) should have a # Status (YYYY-MM-DD): comment noting:

The status comment is the durable record. Reports in reports/ are gitignored and ephemeral — they're a working artifact, not a result log.

Context size

Each report entry shows a Context line — the loaded-context size the box agent carried during that audit, read from the session log's per-turn usage (summed across input + cache_creation + cache_read, since prompt caching leaves raw input_tokens tiny). The initial number is the always-on baseline the box pays every turn (system prompt + agent-guide + box CLAUDE.md + tool schemas); peak and added show how much answering grew it. A knows_directly / 0-read audit doubles as a baseline gauge: trim a box's always-on context, re- run, watch initial drop. Logic lives in lib/context-usage.ts.

Every run also appends these numbers to src/dev/context-history.yaml — a committed ledger keyed by box → audit id → entries, each stamped with the date, the box's HEAD, and the monorepo's HEAD. The file's git history is the trend line: a CLAUDE.md trim that drops the baseline shows up as a diff. (boxCommit is the box's HEAD before the harness regenerates docs — stable for a current box, but the throwaway worktree box clone is behind upstream templates, so its hash moves each run.) Logic lives in lib/context-history.ts.

Test structure

Each entry in knowledge-audits.yaml has these fields:

Interpreting failures

Common failure patterns and what they mean:

When fixing failures, prefer changing docs/prompts to changing the test — the test is asserting an expectation about agent behavior, and silently weakening it defeats the point.