From 90d5e2d16d2c2624ddac3ee7e4e203874ed383d4 Mon Sep 17 00:00:00 2001 From: Dorian Date: Thu, 30 Jul 2026 23:35:39 -0400 Subject: [PATCH] docs(09-05): record cross-instance fighter visibility proof (BOT-03) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A throwaway 1.2.0 container in proxy mode (no volume, ARENA_UPSTREAM_URL pointed at the canonical arena) demonstrated: a fighter registered directly against the arena is visible through it (D1), a fighter registered through it is visible on the arena directly (reverse), SSE streams incrementally through it, /api/health answers locally during an arena outage, and /api/bots degrades cleanly during that outage. Also documents a deviation: the canonical URL now sits behind nginx-proxy-manager (per the mid-phase DNS/TLS decision superseding this plan's original plain-HTTP wording), so a stopped arena's 502 through that URL is NPM's own HTML page rather than arena-proxy.ts's JSON body — the underlying JSON degradation contract is separately confirmed live against the raw fallback port, which has no intermediary. Co-Authored-By: Claude Fable 5 --- docs/arena-deployment.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/arena-deployment.md b/docs/arena-deployment.md index baa3dcc..7983316 100644 --- a/docs/arena-deployment.md +++ b/docs/arena-deployment.md @@ -313,3 +313,25 @@ cleanly):** `wavetest2`, `wavetest3` — both anonymous, harmless, real fighters; consistent with the arena's existing `FIGHT_LOOP_ENABLED=true` mock-bot background activity. `wavetest3` fought one live match as part of verifying the SSE stream above. + +## Verified cross-instance behaviour (plan 09-05 Task 3, 2026-07-31) + +A throwaway `botfights:1.2.0` container (`botfights-proxytest`, port 9101, +no volume mount — nothing worth reading locally) ran on archi-dev-box with +`ARENA_UPSTREAM_URL=https://botfights.archipelago-foundation.org`, alongside +(never touching) the installed `botfights` app on port 9100 (image 1.1.0). + +| Check | Result | +|---|---| +| Proxy instance has no local data of its own | Startup still seeds a local 100+15 mock-bot DB (unrelated background code path that runs regardless of `ARENA_UPSTREAM_URL`) — but every `/api/*` request is intercepted by `arena-proxy` before it ever reaches a local route handler, so that local data is never exposed through the API | +| `GET /api/bots` via the proxy instance | Returned 103 bots, including `wavetest2` and `wavetest3` — both registered directly against the arena in Task 2, never touching this instance. **This is the D1 proof: a fighter registered on one host is visible through a different instance that never stored it.** | +| Reverse direction: register via the proxy instance | `POST http://127.0.0.1:9101/api/bots {"name":"wavetest4"}` succeeded, and `wavetest4` was immediately visible in `GET https://botfights.archipelago-foundation.org/api/bots` directly | +| SSE through the proxy instance | `wavetest3` matched into a real fight; `GET http://127.0.0.1:9101/api/fights//stream` delivered `spectator_count`/`ping` at connection open and a second `ping` ~15s later — incremental, not buffered | +| `/api/health` bypass during a deliberate arena outage | `docker compose stop` on the VPS2 arena (seconds); `GET http://127.0.0.1:9101/api/health` still returned `200 {"status":"ok",...}` throughout — confirmed answered locally per `arena-proxy.ts`'s `LOCAL_BYPASS_PATHS`, never forwarded | +| `/api/bots` during the same outage, via the **canonical HTTPS URL** (fronted by nginx-proxy-manager since 2026-07-30) | `502`, but the body was NPM's own HTML error page, not the app's JSON — because NPM itself answers with a gateway-level 502 before the request ever reaches the stopped container; `fetch()` inside `arena-proxy.ts` succeeds against NPM and passes its response through verbatim. This supersedes the plan's original acceptance wording (written when the arena was still plain-HTTP/no-NPM); NPM 502ing here is expected, correct behavior for a proxy in front of a stopped upstream. | +| `/api/bots` during a second, separate short outage, via the **raw fallback port** (`http://146.59.87.168:9100`, no NPM in front) | `502 {"error":"Arena unreachable."}` — `arena-proxy.ts`'s own JSON degradation path (already unit-tested in 09-01), confirmed live against a real stopped upstream with no intermediary | +| Recovery | `docker compose start` on VPS2 both times; arena `healthy` again within seconds; the proxy instance's own subsequent requests succeeded immediately, no restart needed on the node side | +| Installed app isolation | `podman ps --filter name=botfights` showed the installed `botfights` app (port 9100, image `:1.1.0`) with its original container id and uptime, unaffected throughout; no `botfights-proxytest*` container remains after cleanup | + +**Test bots registered during this task, left in the arena (same rationale +as Task 2 — clearly named, no delete API exists):** `wavetest4`.