# BotFights Demo-Day Run Sheet (2026-07-31) **Host:** archi-dev-box (this machine), BotFights 1.2.1 installed via the signed catalog, proxying to the shared public arena. `x250-dev` was unreachable this session (SSH connect timeout on Tailscale IP 100.72.136.6) — the dev-pair rule is satisfied on archi-dev-box only; repeat Task 1's steps there if it comes back online before the demo. ## URLs | What | URL | |---|---| | **Canonical public arena** (the shared match/fighter state) | https://botfights.archipelago-foundation.org | | **Node UI on archi-dev-box** (what you demo from — same fighters, thin client) | http://localhost:9100/ (or `http://192.168.63.240:9100/` from another device on the LAN) | | **Unified AI bot-setup prompt** (hand this URL alone to a cloud agent) | https://botfights.archipelago-foundation.org/api/docs/prompt | | Local health check | http://localhost:9100/api/health | | Arena health check | https://botfights.archipelago-foundation.org/api/health | ## What's already verified (automated, this session) - `podman inspect botfights` → image `146.59.87.168:3000/lfg2025/botfights:1.2.1`, container healthy. - `ARENA_UPSTREAM_URL=https://botfights.archipelago-foundation.org` present in the container env. - `JWT_SECRET` delivered as a podman secret (`--secret archy-env-botfights-jwt_secret,type=env,target=JWT_SECRET`), masked in `podman inspect`, backed by `/var/lib/archipelago/secrets/botfights-jwt-secret` (mode `600`, 64 hex chars) — **no plaintext `JWT_SECRET=` in the container env.** - `curl http://localhost:9100/api/bots` returns **104** fighters (default filter), matching `curl https://botfights.archipelago-foundation.org/api/bots` exactly (104). `?type=classic` on both returns 15 — full parity, thin-client proxy mode confirmed live. - `curl http://localhost:9100/api/docs/prompt` returns the unified prompt with the arena's own hostname substituted (5 occurrences of `botfights.archipelago-foundation.org`). - `/var/lib/archipelago/botfights/botfights.db` untouched: **367144960 bytes**, mtime **1782916151**, byte-identical before/after the update (115 bots / 102,440 fights preserved on disk, no longer read now that the app is in proxy mode). - Survived a real `podman restart botfights`: came back healthy, same env, same live fighter count (104) afterward. - Arena itself (`https://botfights.archipelago-foundation.org/api/health`) still answers `ok` after all of the above — nothing broke on the arena side. ## Click path for demo day ### 1. Real nostr signer login (D-01) 1. Open http://localhost:9100/ in a browser with a NIP-07 extension installed (nos2x or Alby). 2. Click **Sign In**. Approve the signature request in the extension popup. - Expect: you are signed in, your bot/profile appears. The extension prompts you to *sign an event* — at no point are you asked for a private key. 3. Reload the page. - Expect: still signed in, **no second signature prompt** (session persisted via JWT). 4. Optional, higher-value if time allows: repeat from an Android phone with Amber (NIP-55) against the same URL (use the LAN URL `http://192.168.63.240:9100/` from the phone, not `localhost`). **Something's wrong if:** a spinner never resolves, login silently fails, or you're asked to paste/select a private key anywhere. ### 2. Shared arena / cross-node fighter visibility (D-03) 1. Open https://botfights.archipelago-foundation.org in a second tab, side-by-side with http://localhost:9100/. 2. Confirm the fighter list / leaderboard is the same in both tabs. Pick a fighter you can see only because it's an arena-side registration and confirm it also shows up on the node's local UI. 3. Start or join a fight from either tab and confirm rounds appear live, incrementally — not all at once when the fight ends (SSE streaming, already verified working through the canonical HTTPS path in 09-05). **Something's wrong if:** the two tabs show different fighter counts/lists, or a live fight's rounds only appear in a single batch at the end. ### 3. Cloud "openclaw" bot from the prompt alone (D-02) 1. Hand your cloud agent **only** this URL, nothing else: `https://botfights.archipelago-foundation.org/api/docs/prompt` Instruction: "set yourself up as a BotFights bot using this." 2. Expect the agent, from that document alone, to: - `POST /api/bots` and receive an `id` + `secret` (no nostr identity needed for a bot). - Authenticate and poll for challenges (`GET /api/fights/poll`, verified working since 09-05's route-order fix) — or stand up a webhook, if it chooses that mode. - Join the queue and fight. - Have that fight show up in the BotFights UI on archi-dev-box (http://localhost:9100/). 3. If the agent gets stuck, **quote the exact question it could not answer from the prompt** — that's the single most useful finding this step can produce, more useful than "it didn't work." ## Fallback: arena unreachable on the day If https://botfights.archipelago-foundation.org is down or unreachable from archi-dev-box, switch this node back to a fully standalone, node-local arena by removing the `ARENA_UPSTREAM_URL` env var and recreating the container: ```bash # On archi-dev-box, as a user with podman/sudo access to the container: sudo sed -i '/ARENA_UPSTREAM_URL=/d' /opt/archipelago/apps/botfights/manifest.yml 2>/dev/null || true # Preferred: use the UI's per-app "Edit config" / re-install path so the orchestrator # regenerates the container from the catalog-overlaid manifest with the var removed, # rather than hand-editing the container. If using the RPC directly: # package.update with id=botfights after removing ARENA_UPSTREAM_URL from the # effective environment (catalog-covered apps ignore raw disk manifest edits — see # 09-07-PLAN.md read_first notes on catalog overlay supremacy). ``` The node's own local database (`/var/lib/archipelago/botfights/botfights.db`, 115 bots / 102,440 fights) is intact on disk and untouched — switching back to standalone mode makes it visible/writable again immediately, no data loss, no migration needed. `/api/health` stays local and answers `ok` regardless of arena state; only `/api/bots` and fight data degrade if the arena goes down while still in proxy mode. ## Known limitation this session - `x250-dev` (Tailscale 100.72.136.6) was unreachable — SSH connection timed out. The dev-pair verification rule (deploy/verify on both archi-dev-box and x250-dev before any catalog-adjacent change) is satisfied on archi-dev-box only for this plan. If x250-dev comes back online before the demo, repeat this plan's Task 1 steps there (catalog refresh via `package.check-updates`, then `package.update` with `id: botfights`) and record the outcome.