ui-coverage.test.ts fails the suite the moment an engine event has no client handling (allowlist entries require a written reason) or a cell/edge-targeting card is missing from the board's aim sets — the one-at-a-time bug reports become a red test instead. The wizwar-audits skill documents the three house audits (UI coverage, ledger inspection by room code, the determinism gate); .claude/skills/ joins the repo so they travel with it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2.8 KiB
name, description
| name | description |
|---|---|
| wizwar-audits | Run the Wiz-War health audits — UI coverage of engine events/cards (the "telepath audit"), live-game ledger inspection by room code, and the pre-deploy determinism gate. Use when asked to audit, when adding cards or events, or when a player reports "the engine did X but I never saw it". |
Wiz-War audits
Three recurring audits keep the maze honest. The first is self-enforcing; the other two are on-demand.
1. UI coverage — "the telepath audit" (automated)
packages/engine/test/ui-coverage.test.ts runs with every npm test and
fails when:
- a GameEvent type has no client handling (no
humanizecase innet.svelte.ts, no fx infx.ts, no modal check inApp.svelte) and is not in the test'sSILENT_BY_DESIGNallowlist — each allowlist entry needs a reason for why the player sees the information another way; - a card resolver demanding a cell/edge target is missing from App's
CELL_CARDS/EDGE_CARDSclick-targeting sets (an unaimable cast).
When adding an event: give it a humanize line at minimum. Private
info (visibleTo events carrying cards) deserves the cardReveal modal
in App.svelte — see handRevealedPrivate / cardsStolenPrivate /
handTakenPrivate for the pattern. When adding a card with a cell or
edge target, add it to the App targeting set; with params, wire the
named-card picker (NAMED_CARDS + suggestions) or a bespoke control.
The one axis the test cannot judge: whether a params-taking card's
input UI actually offers sensible choices. Check that by hand when adding
one (thief → target's steallables, deja-vu → discard contents, etc.).
2. Live-game audit by room code
Fetch and replay production ledgers (details in auto-memory
wizwar-fetch-game-files):
scp root@104.236.96.198:/var/lib/wizwar/rooms/<CODE>.jsonl <scratchpad>/
Replay with createGame({playerIds, seed, sets, colors, deckRev}) +
applyCommand per command line (see deploy/replay-verify.mjs). Stop at
any seq to inspect full state. To ask why a bot did something, rebuild
the state at its turn and call automatonCommand(viewFor(state, id), style, tier) — and if its choice differs from the ledger, the engine
refused it and the fallback burned the turn (the X2XN pattern).
For "which games are open/stalled" sweeps: fetch all *.jsonl, replay
each, and report phase / round / humans vs bots / last command's at.
3. Determinism gate (before deploying engine changes)
deploy/verify-ledgers.sh 104.236.96.198
Strict-replays every production ledger against the local engine; one
refused command fails. A room whose ledger no longer replays becomes
unreachable after restart. Rules changes while games are live need a
deckRev bump plus an engine gate (the convention survives the 2026-08
reset to rev 1).