Wiz-War lives on the shared hall host: its scripts, skills and docs name it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
This commit is contained in:
Eric Wagoner
2026-09-29 12:52:36 -04:00
co-authored by Claude Opus 5.5
parent 56ea593e07
commit 397c68a1c8
8 changed files with 18 additions and 16 deletions
+2 -2
View File
@@ -36,7 +36,7 @@ one (thief → target's steallables, deja-vu → discard contents, etc.).
Fetch and replay production ledgers (details in auto-memory Fetch and replay production ledgers (details in auto-memory
`wizwar-fetch-game-files`): `wizwar-fetch-game-files`):
scp root@104.236.96.198:/var/lib/wizwar/rooms/<CODE>.jsonl <scratchpad>/ scp root@159.203.115.252:/var/lib/wizwar/rooms/<CODE>.jsonl <scratchpad>/
Replay with `createGame({playerIds, seed, sets, colors, deckRev})` + Replay with `createGame({playerIds, seed, sets, colors, deckRev})` +
`applyCommand` per command line (see `deploy/replay-verify.mjs`). Stop at `applyCommand` per command line (see `deploy/replay-verify.mjs`). Stop at
@@ -50,7 +50,7 @@ each, and report phase / round / humans vs bots / last command's `at`.
## 3. Determinism gate (before deploying engine changes) ## 3. Determinism gate (before deploying engine changes)
deploy/verify-ledgers.sh 104.236.96.198 deploy/verify-ledgers.sh 159.203.115.252
Strict-replays every production ledger against the local engine; one Strict-replays every production ledger against the local engine; one
refused command fails. A room whose ledger no longer replays becomes refused command fails. A room whose ledger no longer replays becomes
+1 -1
View File
@@ -12,7 +12,7 @@ quiet, say so in one line before the details.
## Gather ## Gather
1. **Box health** (one ssh to root@104.236.96.198): 1. **Box health** (one ssh to root@159.203.115.252):
- `systemctl is-active wizwar caddy` — both must be active - `systemctl is-active wizwar caddy` — both must be active
- `systemctl status wizwar` Memory line — the cap is 700M; worry - `systemctl status wizwar` Memory line — the cap is 700M; worry
past ~500M steady-state past ~500M steady-state
+5 -5
View File
@@ -6,7 +6,7 @@ description: Work the Wiz-War player-feedback desk — fetch new bug reports, sh
# The Wiz-War reports desk # The Wiz-War reports desk
Players file surprise reports from the in-game 🐞 button. Each lands in Players file surprise reports from the in-game 🐞 button. Each lands in
`/var/lib/wizwar/feedback.jsonl` on the droplet (104.236.96.198) pinned `/var/lib/wizwar/feedback.jsonl` on the droplet (159.203.115.252) pinned
with `roomId`, `seq`, `round`, and `deckRev` — enough to replay the game with `roomId`, `seq`, `round`, and `deckRev` — enough to replay the game
to the exact moment. Replies live in the same file and appear under the to the exact moment. Replies live in the same file and appear under the
report in the player's lobby ledger. This desk fetches, displays, and report in the player's lobby ledger. This desk fetches, displays, and
@@ -32,7 +32,7 @@ One JSONL line per entry:
screenshot; the file is `/var/lib/wizwar/feedback-images/<id>.<ext>`. screenshot; the file is `/var/lib/wizwar/feedback-images/<id>.<ext>`.
`scp` it to the scratchpad and Read it: it is usually the whole story. `scp` it to the scratchpad and Read it: it is usually the whole story.
Fetch: `ssh root@104.236.96.198 'cat /var/lib/wizwar/feedback.jsonl'` Fetch: `ssh root@159.203.115.252 'cat /var/lib/wizwar/feedback.jsonl'`
## a) Fetch and b) display ## a) Fetch and b) display
@@ -49,7 +49,7 @@ players' voices — never compress their words, or your replies, into a table.
For each unanswered report, in order: For each unanswered report, in order:
1. **Replay to the pin.** Fetch the ledger 1. **Replay to the pin.** Fetch the ledger
(`scp root@104.236.96.198:/var/lib/wizwar/rooms/<roomId>.jsonl <scratchpad>/`) (`scp root@159.203.115.252:/var/lib/wizwar/rooms/<roomId>.jsonl <scratchpad>/`)
and replay it to the report's `seq` with the engine and replay it to the report's `seq` with the engine
(`createGame` + `applyCommand` per command line, printing the events (`createGame` + `applyCommand` per command line, printing the events
around the pinned moment). CRITICAL replay details: around the pinned moment). CRITICAL replay details:
@@ -80,10 +80,10 @@ For each unanswered report, in order:
- Chronicle-only changes (event names, humanize lines) ship ungated. - Chronicle-only changes (event names, humanize lines) ship ungated.
- Before deploying: full engine suite passes AND - Before deploying: full engine suite passes AND
`bash deploy/verify-ledgers.sh` replays every production ledger `bash deploy/verify-ledgers.sh` replays every production ledger
clean. Deploy with `bash deploy/deploy.sh 104.236.96.198` from the clean. Deploy with `bash deploy/deploy.sh 159.203.115.252` from the
repo root. The deploy restarts the server; live games survive. repo root. The deploy restarts the server; live games survive.
5. **Reply.** From the repo root: 5. **Reply.** From the repo root:
`bash deploy/feedback-reply.sh 104.236.96.198 <reportId> <status> "text"` `bash deploy/feedback-reply.sh 159.203.115.252 <reportId> <status> "text"`
- `<reportId>` is the report's `id`, or its `at` timestamp for - `<reportId>` is the report's `id`, or its `at` timestamp for
legacy reports. Pass it as ONE clean argument — a stray newline in legacy reports. Pass it as ONE clean argument — a stray newline in
the id silently orphans the reply (it happened; the bad line had the id silently orphans the reply (it happened; the bad line had
+1 -1
View File
@@ -10,7 +10,7 @@ Eric like a host glancing over the tavern.
## Gather ## Gather
ssh root@104.236.96.198 /usr/local/bin/wizwar-visitors.sh [YYYY-MM-DD] ssh root@159.203.115.252 /usr/local/bin/wizwar-visitors.sh [YYYY-MM-DD]
Default is today, UTC. The script rolls today's partial rollup row Default is today, UTC. The script rolls today's partial rollup row
first, so the traffic line is current to the minute. Its output: first, so the traffic line is current to the minute. Its output:
+6 -4
View File
@@ -7,16 +7,18 @@ survive deploys and reboots.
## Current production ## Current production
- Droplet: `wizwar` (nyc3, s-1vcpu-1gb, tag `wizwar`), IP 104.236.96.198 - Host: `hall` (nyc3, tag `kestrels-hall`), IP 159.203.115.252, shared with
the other games of Kestrel's Hall since 2026-09-29; Wiz-War keeps its own
service user, port 8787, site file and access log there.
- URLs: https://wizwar.kestrelsnest.social - URLs: https://wizwar.kestrelsnest.social
and https://wizwar.104.236.96.198.sslip.io (always works, zero DNS). and https://wizwar.159.203.115.252.sslip.io (always works, zero DNS).
Caddy serves both; NOTE: kestrelsnest.social's authoritative DNS is at Caddy serves both; NOTE: kestrelsnest.social's authoritative DNS is at
HOVER (ns1/ns2.hover.com), not DigitalOcean — records must be added there. HOVER (ns1/ns2.hover.com), not DigitalOcean — records must be added there.
A matching record also sits in the DO zone in case nameservers ever move. A matching record also sits in the DO zone in case nameservers ever move.
## Everyday deploys ## Everyday deploys
deploy/deploy.sh 104.236.96.198 deploy/deploy.sh 159.203.115.252
Builds the client locally, rsyncs the repo (minus node_modules, data/, .git, Builds the client locally, rsyncs the repo (minus node_modules, data/, .git,
research), installs dependencies on the droplet, and restarts the service. research), installs dependencies on the droplet, and restarts the service.
@@ -25,7 +27,7 @@ automatically.
Before any deploy that touches the engine, run the determinism gate: Before any deploy that touches the engine, run the determinism gate:
deploy/verify-ledgers.sh 104.236.96.198 deploy/verify-ledgers.sh 159.203.115.252
It fetches every production ledger and strictly replays it against the local It fetches every production ledger and strictly replays it against the local
engine; a single refused command fails the check. A room whose ledger no engine; a single refused command fails the check. A room whose ledger no
+1 -1
View File
@@ -3,7 +3,7 @@
# to a local folder, and write a digest beside them for reading. # to a local folder, and write a digest beside them for reading.
# deploy/pull-feedback.sh [host] [folder] (default ~/Desktop/wizwar-reports) # deploy/pull-feedback.sh [host] [folder] (default ~/Desktop/wizwar-reports)
set -euo pipefail set -euo pipefail
HOST="${1:-104.236.96.198}" HOST="${1:-159.203.115.252}"
OUT="${2:-$HOME/Desktop/wizwar-reports}" OUT="${2:-$HOME/Desktop/wizwar-reports}"
mkdir -p "$OUT/images" mkdir -p "$OUT/images"
scp -q "root@$HOST:/var/lib/wizwar/feedback.jsonl" "$OUT/feedback.jsonl" scp -q "root@$HOST:/var/lib/wizwar/feedback.jsonl" "$OUT/feedback.jsonl"
+1 -1
View File
@@ -3,7 +3,7 @@
# replay it against the LOCAL engine. Any refused command is a hard failure. # replay it against the LOCAL engine. Any refused command is a hard failure.
# Run from the repo root before deploying any engine change. # Run from the repo root before deploying any engine change.
set -euo pipefail set -euo pipefail
HOST="${1:-104.236.96.198}" HOST="${1:-159.203.115.252}"
TMP=$(mktemp -d) TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT trap 'rm -rf "$TMP"' EXIT
scp -q "root@$HOST:/var/lib/wizwar/rooms/*.jsonl" "$TMP/" scp -q "root@$HOST:/var/lib/wizwar/rooms/*.jsonl" "$TMP/"
+1 -1
View File
@@ -74,7 +74,7 @@ for f in sorted(glob.glob("/var/lib/caddy/wizwar-access*.log*")):
ref = " ".join(h.get("Referer", [""])) ref = " ".join(h.get("Referer", [""]))
m = re.match(r"https?://([^/]+)", ref) m = re.match(r"https?://([^/]+)", ref)
host = m.group(1) if m else "" host = m.group(1) if m else ""
ours = host.endswith("kestrelsnest.social") or "104.236.96.198" in host ours = host.endswith("kestrelsnest.social") or "159.203.115.252" in host
# Scanners forge referrers on paths like /.env, and the app answers # Scanners forge referrers on paths like /.env, and the app answers
# unknown paths with the page itself, so the status cannot tell a # unknown paths with the page itself, so the status cannot tell a
# probe from a reader. Only the pages count. # probe from a reader. Only the pages count.