Updated: 2026-04-25 (single-mode refactor)
Original decision date: 2026-04-23 — Option B chosen (same server, /live route + live.html).
There is one server, one database (audit.db), and one operating mode. The admin decides whether live audit progress is visible to the public by toggling broadcastLive.
admin.html ──POST /api/broadcast──► state.broadcastLive = true/false
│
┌───────────────────┘
▼
/api/public/events (SSE fan-out)
│
broadcastLive=false broadcastLive=true
──────────────────── ──────────────────
Public SSE is silent. Live progress events forwarded.
public.html + /live show /live upgrades from snapshot
last-completed snapshot. view to live progress view.
- Zero user-facing action buttons on any public surface.
- Public can watch live testing progress only when the admin has enabled broadcast.
- Public can search nodes (moniker, address, country, city).
- Admin controls start/stop and broadcast. Public never does.
- Share-friendly URL (
/live).
| Page | Role |
|---|---|
admin.html |
Full control panel. Start/stop audit. Toggle Broadcast Live. View all results. |
public.html |
Static node directory + search + filters + sort. No action buttons. Shows last-completed run snapshot. |
live.html |
Public live view. SSE-driven via /api/public/events. Shows live progress when broadcastLive=true; falls back to last-completed snapshot when broadcastLive=false. No action buttons. |
POST /api/broadcast(adminOnly) — flipsstate.broadcastLive. No request body required. Returns{ broadcastLive: boolean }.GET /api/broadcast— returns current value. Open (no auth).- When
broadcastLiveis set totrue:- Admin clicks "Broadcast Live" in
admin.html. state.broadcastLiveflips totrueon the server./api/public/eventsSSE begins forwarding livebatch:*andloop:*events to all connected public clients.live.htmlreceives the events and switches from snapshot view to live progress view (samecbCardwidget used in admin).
- Admin clicks "Broadcast Live" in
- When
broadcastLiveis set back tofalse:- SSE fan-out goes silent.
live.htmlreturns to showing the last-completed run snapshot.
One database: audit.db. All runs — live and dry — write to it.
- Normal audit run:
mode='live'(or absent/null for legacy rows). - Test-run (
?testRun=1on/api/start):mode='test'. Every node row getsactualMbps: null, errorCode: 'TEST_RUN_SKIP'. Visually distinguishable in the admin table but stored in the same file. audit-dry.dbno longer exists.
TEST RUN is not a mode — it is an optional parameter on the normal start endpoint.
POST /api/startwithtestRun: truein body, orPOST /api/start?testRun=1.- Pipeline skips: plan membership check, online scan, chain operations, payments.
- Every node row:
actualMbps: null, errorCode: 'TEST_RUN_SKIP'. - Run row:
mode='test'inaudit.db. - Useful for verifying the pipeline plumbing and UI without spending DVPN.
/api/public/events forwards events only when state.broadcastLive=true.
| Event | Payload |
|---|---|
batch:start |
{ batchId, snapshotSize, iteration } |
batch:node |
{ addr, moniker, countryCode, type, actualMbps, errorCode, ... } |
batch:end |
{ batchId, passed, failed, durationMs } |
batch:gap |
{ gapMs } |
loop:started |
{ iteration: 0 } |
loop:stopped |
{ iterations, reason } |
loop:error |
{ error, iteration } |
No wallet, plan ID, or fee-grant internals are forwarded on the public SSE stream.
/liveis publicly accessible (usesattachAdminFlagbut does NOT gate access).- All data consumed by
/livecomes from/api/public/*endpoints — already sanitized. POST /api/broadcastrequiresadminOnlymiddleware (signed cookie or Bearer token).- No
ALLOW_PUBLIC_TESTenv flag needed — admin triggers broadcast, public only views.
- Mode cookie (
server_mode) andrequireMode()middleware. _currentMode,_applyModeUI,selectMode,switchModeclient-side helpers.- Mode overlay UI in
admin.html. POST /api/admin/public-test/start,POST /api/admin/public-test/stop,GET /api/admin/public-test/status.POST /api/public/test/start,POST /api/public/test/stop,GET /api/public/test/status.audit-dry.db— superseded by themode='test'column inaudit.db.- Economy mode (deprecated earlier in the same session).