The keeper can say a word at a table through the keeper's door, signed as the keeper and heard whether or not the gallery may talk, so a call answered too late, after the game began, can still be answered; <slug>-say.sh sends it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0141G6xqLeNRYEtviLWSB5Up
This commit is contained in:
Eric WagonerandClaude Opus 5.5 committed 2026-10-20 13:21:24 -04:00
1 parent 21de94869d
commit 82107f73eb
10 files changed
+50 -3

No files matched your search

+3
View File
@@ -55,6 +55,9 @@ deploy, so the live copies are the repo copies:
- `hnefatafl-visitors.sh [day]`: who is here now and who came that day.
- `hnefatafl-reseat.sh ROOM [SEAT]`: who sits at a table; with a seat, a new
token for a player locked out of it, as a link to send them.
- `hnefatafl-say.sh ROOM "text"`: a word from the keeper in a table's talk,
signed as the keeper, through the same door; it is heard whether or not
the gallery may talk, so a call that came too late can be answered.
- `hnefatafl-pulse.sh`: the weekly health check (service, errors, rollup
trend, backup, box).
- `hnefatafl-rollup.sh [day]`: one JSON line per day of counts, run
+1
View File
@@ -43,6 +43,7 @@ ssh "root@$HOST" '
install -m 755 /opt/hnefatafl/app/deploy/hnefatafl-rollup.sh /usr/local/bin/hnefatafl-rollup.sh
install -m 755 /opt/hnefatafl/app/deploy/hnefatafl-backup.sh /usr/local/bin/hnefatafl-backup.sh
install -m 755 /opt/hnefatafl/app/deploy/hnefatafl-reseat.sh /usr/local/bin/hnefatafl-reseat.sh
install -m 755 /opt/hnefatafl/app/deploy/hnefatafl-say.sh /usr/local/bin/hnefatafl-say.sh
# The key to the keeper door: made once, readable by root (the reseat script) and the game user (the server) alone.
if [ ! -s /etc/hnefatafl/keeper.key ]; then
install -d -m 750 -o root -g hnefatafl /etc/hnefatafl
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/env bash
# A word from the keeper in a table's talk, signed as the keeper, whether or
# not the host lets the gallery talk: the answer to a call that came too late,
# or anything else the table should hear from the keeper. Runs ON the droplet,
# through the game server's keeper door.
# hnefatafl-say.sh ROOM "text"
set -euo pipefail
ROOM="${1:?usage: hnefatafl-say.sh ROOM \"text\"}"
TEXT="${2:?usage: hnefatafl-say.sh ROOM \"text\"}"
DOOR="http://127.0.0.1:8789/keeper/rooms/${ROOM^^}"
[ -s /etc/hnefatafl/keeper.key ] || { echo "No keeper's key at /etc/hnefatafl/keeper.key; a deploy makes it." >&2; exit 1; }
# The key goes as a header read from a file descriptor, never on a command line another user could see.
KEY="@/dev/fd/3"
exec 3< <(printf 'x-keeper-key: %s\n' "$(cat /etc/hnefatafl/keeper.key)")
BODY=$(TEXT="$TEXT" python3 -c 'import json, os; print(json.dumps({"text": os.environ["TEXT"]}))')
CODE=$(curl -s -o /tmp/hnefatafl-say.$$ -w '%{http_code}' -X POST -H "$KEY" -H 'content-type: application/json' -d "$BODY" "$DOOR/say")
if [ "$CODE" = 204 ]; then echo "said at ${ROOM^^}"; else cat /tmp/hnefatafl-say.$$ >&2; echo >&2; rm -f /tmp/hnefatafl-say.$$; exit 1; fi
rm -f /tmp/hnefatafl-say.$$