255 lines
16 KiB
Markdown
255 lines
16 KiB
Markdown
# Repeatable verification
|
||
|
||
Use the [development guide](DEVELOPMENT.md) to choose checks appropriate to the
|
||
change. These wrappers retain the existing test runner and simulation harness;
|
||
they do not replace rules, browser or release acceptance.
|
||
|
||
## Current verification priority
|
||
|
||
The 26 September 2026 amendment prioritizes remaining game content before
|
||
extensive saved-game polish. Keep focused current-feature playable continuation,
|
||
custody, privacy, authorization, no-reset and blocking save checks and required
|
||
checkpoint commands. Historical-save compatibility, exhaustive restore/seat
|
||
audits, backup refinement and routine whole-database comparisons wait until
|
||
final polish after game content; final recovery acceptance is still required.
|
||
The tools below remain available, not a mandate to run every preservation
|
||
command for each content checkpoint. See the
|
||
[OMP harness workflow](DEVELOPMENT.md#omp-harness-workflow) for execution mechanics.
|
||
|
||
## Verify the deployed application
|
||
|
||
The user requires testing the actual application at
|
||
**https://dune.procrastination.games**, added to the goal on 22 September 2026.
|
||
Local development, a local production build and container smoke tests do not
|
||
replace testing that deployed origin.
|
||
|
||
After relevant application changes are deployed, identify the running revision
|
||
or image digest and match it to the checkpoint under test. Record when testing
|
||
occurred, what revision actually ran, the routes/actions exercised, results and
|
||
remaining limitations. If the deployed revision is older, label the results for
|
||
that older revision; do not claim that new source passed deployed acceptance.
|
||
If access or deployment is unavailable, report the gap and keep acceptance open.
|
||
Each pushed application checkpoint also needs a separate live deployment; a
|
||
successful GitHub container publication alone is not a deployment. Follow
|
||
[the manual TrueNAS update](TRUENAS.md#applying-an-update) only after the image
|
||
passes CI, the persistent volume is backed up and play reaches a safe point.
|
||
If access, the backup or a safe point is missing, report the push as **not
|
||
deployed** and keep its production verification open rather than claiming the
|
||
Git revision label matches the pushed commit.
|
||
|
||
Use the production browser flow to verify relevant navigation and deep links,
|
||
bundled assets and rendering, HTTPS/proxy behavior, cookies and authentication,
|
||
room creation/join, rules selection, human/AI decisions, multiplayer updates,
|
||
private views and refresh/reconnection. Exercise changed gameplay and admin
|
||
operations through the real controls and server, with desktop/mobile coverage
|
||
where relevant. Do not rely solely on HTTP status codes or local test results.
|
||
Keep checks focused on the changed behavior and its dependencies; broad final
|
||
acceptance must cover the complete game and administration scope.
|
||
|
||
Create clearly identified QA rooms/seats and track their IDs privately. Protect
|
||
human games, private information, recovery credentials and logs. Admin tests
|
||
must use explicitly authorized admin access, with destructive or restoration
|
||
checks restricted to designated test records and appropriate recovery snapshots.
|
||
Do not reset production storage, interrupt live human play, weaken permissions
|
||
or restart the server merely to run a routine smoke test.
|
||
|
||
When a deployment or necessary restart occurs, verify saved-game and seat
|
||
continuity afterward, distinguishing legitimate gameplay changes from data loss.
|
||
Use the existing hosting/deployment procedure and additive migrations; testing
|
||
requirements do not authorize bypassing completion or publication gates.
|
||
Documentation-only checkpoints need documentation/link review, not an unrelated
|
||
production gameplay run. Record production evidence separately from the local
|
||
source-bound checks below, and repair runtime-specific failures before treating
|
||
the affected deployed feature as verified.
|
||
|
||
## Compact checks and source evidence
|
||
|
||
```sh
|
||
node --import tsx tools/verify.ts --out /tmp/dune-new-focused focused --focus guild-payment
|
||
node --import tsx tools/verify.ts --out /tmp/dune-new-check check
|
||
# Add build for app/build/dependency changes, integration for HTTP/auth/persistence.
|
||
node --import tsx tools/verify.ts --out /tmp/dune-new-release check build integration
|
||
# Only for relevant AI/gameplay work; the existing study covers Basic base factions.
|
||
node --import tsx tools/verify.ts --out /tmp/dune-new-study base-games --games 20 --seed 20260913
|
||
```
|
||
|
||
Each output must be a new directory outside the checkout, with an existing parent.
|
||
It is created with private permissions. Full command output stays in step logs;
|
||
`report.json` records commands, exit codes, timings, HEAD and a content fingerprint
|
||
of tracked and nonignored untracked files before and after the run. Ignored local
|
||
credentials, saved games and build caches are excluded. Do not supply secrets in
|
||
command arguments. A failed child stops subsequent steps. Changed source or HEAD
|
||
invalidates a successful run; finish all source/doc edits before broad checks.
|
||
This checks the two observed snapshots, not changes made and reverted between them,
|
||
nor the contents of dependencies, ignored files or an external HTTP server.
|
||
An interrupted or incomplete report is never evidence of success.
|
||
|
||
## Saved games and online backups
|
||
|
||
### Reusable base and faction sample games
|
||
|
||
```sh
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-faction-games
|
||
# Ten genuine base samples: Basic and Advanced at each player count.
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-base-games --profile base
|
||
# Basic Moritani with the full Leader Skills deck, two through six seats.
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-moritani-skills --profile moritani-skills
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-tleilaxu-skills --profile tleilaxu-skills
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-base-three --profile base --players 3 --rules advanced
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-combined --profile combined --rules advanced --seed 20260926
|
||
# Homeworld and Nexus with two through six base factions, Basic and Advanced.
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-homeworld --profile homeworld
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-nexus --profile nexus
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-homeworld-nexus --profile homeworld-nexus
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-choam-roster --profile choam-roster
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-ecaz-roster --profile ecaz-roster
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-nexus-three --profile nexus --players 3 --rules advanced
|
||
node --import tsx tools/faction-games.ts --out /tmp/dune-new-resume --resume /private/failed-combined-advanced.json
|
||
```
|
||
|
||
Default and `--profile all` retain the original six fixed CHOAM/Richese,
|
||
Ecaz/Moritani and combined Basic/Advanced samples. `--profile base` selects ten
|
||
additional samples: Basic and Advanced with two through six players.
|
||
`--players 2..6` narrows the base, Homeworld, Nexus, combined
|
||
`homeworld-nexus`, `choam-roster` or `ecaz-roster` profile; omission or `all`
|
||
retains all five counts. The fixed base roster adds Atreides, Harkonnen,
|
||
Fremen, Emperor, Guild and Bene Gesserit in that order. These are sample
|
||
rosters, not an assertion that they are the only rules-permitted player-count
|
||
configurations. Each optional module profile runs two through six base factions
|
||
under Basic and Advanced using the actual setup seams. The two expansion-roster
|
||
profiles also run Basic and Advanced with their respective physical expansion
|
||
enabled: CHOAM/Richese start with CHOAM then Richese, Ecaz/Moritani with
|
||
Moritani then Ecaz; subsequent seats extend each to six without changing
|
||
existing fixed four-seat samples. Their seed offsets are 68–77 and 78–87.
|
||
Output names include the player count. Homeworld's original four-seat seed
|
||
offsets remain 36–37; its other rosters use 48–51 and 54–57. Nexus's six-seat
|
||
offsets remain 38–39; its smaller rosters use 40–47. The combined module uses
|
||
offsets 58–67. These samples do not open public module or expansion starts or
|
||
assert complete interaction coverage.
|
||
|
||
All-AI Nexus samples now make public reciprocal offers as well as accepting
|
||
them, so an actual alliance can form without a human proposer. At the
|
||
20260927 seed, each six-seat sample made six alliance actions and completed;
|
||
no Nexus Card choice occurred at those tables. The two-to-six-seat matrix
|
||
completed without rejected actions and with JSON restores throughout; the
|
||
three-seat Advanced sample and five-seat Basic sample reached actual
|
||
`nexusCardChoice` actions. The focused Nexus alliance regression exercises
|
||
the subsequent draw when a seat remains unallied. These samples do not
|
||
establish complete card-effect coverage.
|
||
|
||
At the 20260927 seed, all ten Homeworld samples completed with no rejected
|
||
actions and repeated JSON restores. The six-seat Basic game reached actual
|
||
Junction offers/shipments and a Caladan reinforcement decision; these
|
||
observations do not certify every Homeworld occupation or expansion
|
||
interaction.
|
||
|
||
At the same seed, all ten combined Homeworld/Nexus samples completed without
|
||
rejected actions and with JSON restores. The five-seat Advanced game reached
|
||
three Nexus Card choices and eight Homeworld shipments in one physical game,
|
||
including 26 restores. This does not certify every interaction between the
|
||
two independent modules or either module's unfinished card effects.
|
||
|
||
`--profile moritani-skills` adds five Basic samples with Moritani, then Emperor,
|
||
Guild, Harkonnen, Fremen and Bene Gesserit. `--players` also narrows this profile;
|
||
Advanced requests fail before running. Its seed offsets are 16–20, leaving
|
||
existing samples unchanged. The full fourteen-card skill census and ordinary
|
||
Moritani/base Traitor census are checked throughout. `--resume` preserves this
|
||
explicit profile; other optional modules still fail its admission checks.
|
||
Homeworld, Nexus and combined snapshots resume only when their saved modules
|
||
and fixed rosters match a supported profile; other optional module
|
||
combinations remain excluded. An edited snapshot with a removed module can
|
||
match a different fixed profile, so verify its original private report
|
||
before relying on resumed provenance.
|
||
|
||
All samples use genuine setup and saved AI profiles, cycling Easy, Medium,
|
||
Hard and Brutal by seat. Smaller games necessarily contain fewer profiles;
|
||
the matrix collectively exercises all four. Filters retain each scenario's
|
||
seed offset: the original six use 0–5; base uses
|
||
`6 + 2 × (players − 2) + Advanced`, where Advanced is 0 or 1. `--seed` defaults to 20260926;
|
||
`--max-actions` defaults to 3500 accepted actions per game. Every action checks
|
||
physical card custody (including unsold auction cards), nonnegative integer
|
||
forces/spice, twenty-force totals and the distinct Fremen/Emperor/Ixian elite totals
|
||
and subsets. Base samples also check the exact Traitor inventory after dealing
|
||
has finished; expansion Traitor/Face Dancer zones are not certified by this
|
||
check. Every rejected candidate must leave its input unchanged. Every 37 actions
|
||
checks all private views after JSON restoration and absence of rival hand,
|
||
spice, Traitor and Face Dancer fields. Rejected candidates remain visible in private traces even when
|
||
a later candidate succeeds. The [ordinary AI arrival adapter](BOT_ARRIVAL_PREFLIGHT.md)
|
||
filters known supported-scope reaction conflicts before attempting an action;
|
||
remaining rejections are still reported, never hidden by the runner. Samples are development evidence, not calibration or
|
||
complete rules certification.
|
||
|
||
The output is a new private directory outside the checkout. It contains private
|
||
traces, incomplete-game snapshots, `results.json` and a source-bound `report.json`.
|
||
An incomplete game or changed source exits nonzero. Resume requires a matching
|
||
fixed base or expansion scenario snapshot with saved AI profiles and records its
|
||
SHA-256; it cannot be combined with profile/rules/player-count filters. Its action budget starts at the snapshot,
|
||
and its random stream restarts from the supplied seed plus scenario offset.
|
||
Check setup provenance against the original report: accepting a supplied snapshot
|
||
does not prove it came from genuine setup. No live room or database is accessed.
|
||
|
||
### Preservation commands
|
||
|
||
```sh
|
||
node --import tsx tools/saved-games.ts snapshot --db /absolute/games.sqlite --out /private/new-baseline --backup
|
||
node --import tsx tools/saved-games.ts compare --db /absolute/games.sqlite --baseline /private/new-baseline/snapshot.json
|
||
```
|
||
|
||
The source database is opened read-only. Snapshots store room versions and state
|
||
hashes, not private game state. New rooms are allowed; every changed or missing
|
||
original room fails comparison. Legitimate human play can change a room: investigate
|
||
and document it, never overwrite progress to make a comparison pass. When a
|
||
targeted storage-risk maintenance operation warrants a baseline, snapshot the
|
||
current set rather than reusing historical room counts; routine content-only
|
||
checkpoints do not require full-database comparisons.
|
||
Online backup includes WAL contents and requires Node 22.16 or newer; snapshot and
|
||
comparison retain the project's Node 22.13 minimum. Backup files contain private
|
||
state and session records, remain outside Git, and never overwrite an earlier run.
|
||
This tool does not delete, reset or restore the live database.
|
||
|
||
### Authorized reset, 13 September 2026
|
||
|
||
The user requested clearing all old local games and starting a new checkpoint.
|
||
With no development server running, a verified online backup preceded a single
|
||
transaction deleting **3,644 rooms** and cascading their seat/recovery/entry records.
|
||
Schema, migrations and Wrangler state files were preserved. All five application
|
||
tables were empty afterward; foreign-key validation passed.
|
||
|
||
Private archive: `/home/quintine/.local/share/dune/checkpoints/20260913-before-reset/`.
|
||
Fresh empty database backup and snapshot:
|
||
`/home/quintine/.local/share/dune/checkpoints/20260913-fresh-baseline/`.
|
||
These machine-local paths are operational records, not portable repo artifacts.
|
||
Old room IDs in historical browser evidence no longer identify active local games.
|
||
Future games must be preserved. This was a one-time user-authorized reset, not a
|
||
maintenance strategy or permission to clear future games.
|
||
|
||
The explicit `--profile choam-skills` runs Basic CHOAM and base opponents for
|
||
two through six players (ordinals 31–35), retaining the full skill module and
|
||
native 35-card Treachery deck; see [CHOAM integration](CHOAM_LEADER_SKILLS.md).
|
||
|
||
The explicit `--profile ix-skills` runs genuine Basic Ixian full-deck setup for
|
||
two through six players, with Tleilaxu and base opponents. It preserves ordinals
|
||
26–30 and full custody/private saved continuation; see [Ix integration](IX_LEADER_SKILLS.md).
|
||
|
||
## Private-seat restoration
|
||
|
||
Create a private JSON file (mode 0600) outside the checkout with this structure;
|
||
substitute credentials only in that private file, never in a command or tracked doc:
|
||
|
||
```json
|
||
{"baseUrl":"http://127.0.0.1:3000","isolatedQa":true,"seats":[{"code":"ABCDEFGH","playerId":"fixture-seat-id","version":4,"token":"fixture_session_token"}]}
|
||
```
|
||
|
||
```sh
|
||
node --import tsx tools/restore-seats.ts --config /private/qa-seats.json
|
||
```
|
||
|
||
Use deliberately isolated, stable human QA rooms. The server's GET route can resume
|
||
bots or automatic work, so this is not a generally side-effect-free read and must
|
||
not probe arbitrary human games. Requests use loopback origins only, reject redirects
|
||
and time out. Checks require the expected room, seat and version, the owning seat's
|
||
private fields, and absence of selected rival private fields. No session tokens,
|
||
response bodies or hands are printed. This is HTTP seat restoration, not recovery-key
|
||
rotation, exact hand-content proof, a complete privacy audit or browser rendering.
|
||
Pair it with saved-game comparison and feature-specific browser acceptance.
|