Three blind reviews over the first-person arc, every finding verified against the source. History-narrating comments made timeless or cut; the stacked BUDDY comment collapsed to one voice. Dead code out: the orphaned FACE copy, the DIR_ANGLE duplicate, the dead loop-counter poke, the impossible-state sentinel. The never-produced "warp" hit kind resolved the right way — warp mouths now hang a translucent veil of the painted warp texture, so art that never rendered finally does. Types tightened (SlabStrike named once, ShareData rides CatchUpStep, botTier loses its casts), the gallery reads MATERIALS instead of a hand-copied list, the chronicle resets through one helper, a superseded share mint rejects instead of stranding, and the conjured safe gains the growth key its siblings had. Tests lose a triple assignment, a tautology, and two self-swallowing regex alternatives. The sprite spec — which still told the artist to paint for additive compositing the renderer no longer uses — now describes the renderer that exists. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
60 lines
2.8 KiB
Markdown
60 lines
2.8 KiB
Markdown
---
|
|
name: wizwar-audits
|
|
description: 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 `humanize` case in
|
|
`net.svelte.ts`, no fx in `fx.ts`, no modal check in `App.svelte`) and is
|
|
not in the test's `SILENT_BY_DESIGN` allowlist — 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_CARDS` click-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.
|
|
|
|
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. Production deckRev is currently 1,
|
|
so low numbers are not stale.
|