4.4 KiB
REVIEW — phase kuma (uptime-kuma create-a-monitor functional test)
Adversary verdict log. Append-only. SSOT: cc-ci-plan/plan-phase-kuma-monitor.md.
Phase orientation (2026-06-11T18:03Z)
Builder clone: /srv/cc-ci/cc-ci; Adversary clone: /srv/cc-ci/cc-ci-adv.
Phase goal: add functional test that completes uptime-kuma's first-run setup wizard and exercises
its core function — create a monitor, see it probe a target, assert UP + real probe timestamp.
Negative test (monitor → dead target → DOWN) required if it fits the runtime budget.
Two gates:
- M1 — test implemented + green locally; approach justified; bounded waits; real assertions
- M2 — drone-path green (≥2 consecutive runs); flake check; DEFERRED closed
Pre-phase independent research notes:
- uptime-kuma uses Socket.IO for ALL management operations (setup wizard, login, monitor CRUD)
- Existing tests: Socket.IO handshake (EIO v4), SPA branding, health check — NONE exercise wizard/monitor
- Two viable approaches per plan: (a) python-socketio client speaking events; (b) Playwright UI
- Key verification concerns for M1:
- Probe reality: must confirm a real HTTP check occurred (timestamp advance + status from uptime-kuma's state, not echo of config)
- Secret safety: generated admin creds must not appear in logs or test output
- Budget: target ≤90s added to functional tier; must use bounded poll not sleep
- Negative teeth: dead-target monitor must go DOWN (proves probe isn't stub) — required unless runtime budget forces explicit justification
- Existing
tests/uptime-kuma/functional/dir has 3 files: health_check, socketio_handshake, spa_branding — all pass in CI (build #91 was green for uptime-kuma level 5) - Phase plan says new test goes in
tests/uptime-kuma/functional/(orplaywright/if option b)
Adversary pre-flight checks (2026-06-11T18:03Z)
uptime-kuma Socket.IO event map (from source / prior investigation):
- Setup wizard:
setupevent with{username, password}→ response{ok: true} - Login:
loginevent with{username, password, token: ""}→ response{ok: true, token: "..."} - Add monitor:
addevent with monitor config → response{ok: true, monitorID: N} - Heartbeat list:
heartbeatListevent oruptimeevent to check recent probe status - Monitor status:
getMonitorListor heartbeat events contain{status: 1}(UP) or{status: 0}(DOWN)
Adversary independent acceptance criteria (what I will cold-verify for M1):
- Test file in correct location per plan (tests/uptime-kuma/functional/ or playwright/)
- Setup wizard completed and login token obtained (not hardcoded)
- Monitor created pointing at a harness-controlled URL (not a stub/no-op)
- Wait loop is BOUNDED (deadline/max_wait, not open-ended sleep)
- Assertion is on ACTUAL probe data: at minimum one heartbeat with status=1 + timestamp > deploy time
- Admin credentials NOT printed/logged in test output
- Negative test included OR explicit runtime-budget justification in DECISIONS.md
- Runtime ≤ ~90s added (measure from CI timing)
Independent pre-flight findings (2026-06-11T18:05Z)
Critical: python-socketio NOT available on cc-ci.
cc-ci-run -c 'import socketio' # → ModuleNotFoundError: No module named 'socketio'
cc-ci-run -c 'from playwright.sync_api import sync_playwright; print("ok")' # → ok
Implication: option (a) python-socketio requires a harness.nix + nixos-rebuild change; option (b) Playwright works immediately from existing infrastructure. Builder must justify their choice in DECISIONS.md regardless.
uptime-kuma recipe pinned at 2.2.1 (image louislam/uptime-kuma:2.2.1).
Socket.IO port 3001, routed through Traefik web-secure entrypoint.
uptime-kuma Gitea mirror exists (recipe-maintainers/uptime-kuma), no open PRs yet. Builder will need to create a test PR.
Real probe evidence requirements I will enforce at M1 cold-verify:
- heartbeat data must contain entries with
statusfield (1=UP, 0=DOWN) - heartbeat timestamps must be AFTER test start (not from config echo)
- For uptime-kuma 2.x:
heartbeatListsocket event OR API poll at/api/status-page/heartbeat/...carries real probe results; eventuptimealso carries historical data - The monitor's first heartbeat entry is sufficient if it has:
status: 1,time> deploy timestamp
Builder has not yet started (no STATUS-kuma.md, no kuma commits). Waiting for M1 claim.