Files
Eric WagonerandClaude Fable 5.1 33ac0ec808 The credibility pass on Hnefatafl, ported to the template: the ops scripts count traffic through one parser, the reports digest is one program, the plaintext-token fallback and its migration are gone, and the stylesheet holds each shared rule once
From the hnefatafl repo's pass of the same day, everything that touched a
kit-shared file. The visitors digest and the nightly rollup share
deploy/traffic.py, installed to /usr/local/lib/<slug>; the rollup writes
the finished-games count it computed behind "and False". pull-reports.sh
and the reports skill both use deploy/report-digest.ts. The seat line
requires its token hash and the start line its rules revision; the
migration for ledgers written before hashing goes with them. The route
table in server/src/index.ts lists every route; Report, ReportLine and
Tally are declared once in view.ts for both sides; exports nobody
imported are exports no more.

In the client: .small, the × that dismisses, and the frame of the
reading pages are in app.css once; the preferences panel shares the
report slip's modal shape; the room store gains seatEmpty and
seatUnheld, and the lobby and the join page read those instead of
three spellings of their own. The room's moved and awaiting fields
stay: the demo board reads them, and simultaneous rounds are the
contract.

The deploy README no longer describes a browser-only game; the visitors
skill no longer names a /play route; the reports skill's replay call
carries the room's options. The Slack channel id is passed in the
environment rather than filled in as a placeholder.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GwFKMuQnPAEHJ5yA1q4orh
2026-09-23 20:12:37 -04:00

37 lines
2.3 KiB
Bash
Executable File

#!/usr/bin/env bash
# The operations pulse, printed ON the droplet: the game server's health,
# errors in its journal, the last week of the rollup, the backup's last word,
# and the box's vitals. Read by the __SLUG__-pulse skill.
set -u
echo "as of $(date -u '+%F %H:%M') UTC on $(hostname); up $(uptime -p | sed 's/up //')"
echo "--- game server"
systemctl is-active __SLUG__ >/dev/null && echo "__SLUG__: active since $(systemctl show __SLUG__ -p ActiveEnterTimestamp --value)" || echo "__SLUG__: NOT ACTIVE"
systemctl is-active caddy >/dev/null && echo "caddy: active" || echo "caddy: NOT ACTIVE"
echo "restarts in 7 days: $(journalctl -u __SLUG__ --since '7 days ago' -o cat | grep -c 'Started __SLUG__')"
ERR=$(journalctl -u __SLUG__ --since '7 days ago' -p err -o cat | grep -vc '^$')
echo "journal errors in 7 days: $ERR"
journalctl -u __SLUG__ --since '7 days ago' -o cat | grep -iE "error|unhandled|exception" | tail -3 | sed 's/^/ /'
echo "--- rollup, last 7 days (people / requests / rooms opened / turns)"
if [ -s /var/lib/__SLUG__/rollup.jsonl ]; then
tail -7 /var/lib/__SLUG__/rollup.jsonl | python3 -c '
import json, sys
for l in sys.stdin:
r = json.loads(l); rm = r["rooms"]
print(" %s %3d people %4d requests %2d rooms (%d started, %d with turns) %3d turns bots %d addr refs %s" % (
r["day"], r["humanAddresses"], r["human"], rm["created"], rm["started"], rm["withTurns"], r["turns"], r["botAddresses"],
",".join(sorted(r["referrers"])) or "-"))'
else
echo " (no rollup yet)"
fi
echo "--- ledgers"
echo "rooms on disk: $(ls /var/lib/__SLUG__/rooms/*.jsonl 2>/dev/null | wc -l); touched in 24h: $(find /var/lib/__SLUG__/rooms -name '*.jsonl' -mmin -1440 2>/dev/null | wc -l); size $(du -sh /var/lib/__SLUG__/rooms 2>/dev/null | cut -f1)"
echo "--- backup"
if [ -f /var/log/__SLUG__/backup.log ]; then
grep -E "backup (start|done)|skipped|error|ERROR" /var/log/__SLUG__/backup.log | tail -2 | sed 's/^/ /'
else
echo " never run"
fi
echo "--- box"
echo "disk: $(df -h / | awk 'NR==2{print $5" used of "$2}'); memory: $(free -m | awk 'NR==2{print $7" MB available of "$2}'); load: $(cut -d' ' -f1-3 /proc/loadavg)"
echo "caddy access log: $(du -sh /var/lib/caddy/access.log 2>/dev/null | cut -f1) live, $(ls /var/lib/caddy/access*.log* 2>/dev/null | wc -l) files"