Files
dashboards/.agents/phases/todo/24_dev_mtls_rollout/04_verification.md
T
ducoterra f9b1565abb chore(agent): phase roadmap from TODO.md, 5 phases
Convert the 11 TODO items to phases 20-24 (masthead/nav polish,
page cleanups, /disks hiding unconfigured hosts, LLM rate window,
dev mTLS rollout). TODO.md cleared; items now live in
.agents/phases/todo/.

LLM-Generated: true
2026-10-20 18:06:46 -04:00

3.5 KiB

Task 04 — The fleet is mTLS: the end state, verified

Phase: 24_dev_mtls_rollout · Source: TODO.md:3 — "…so we never need non-mtls servers." Story: n/a

Objective

The end state is proven read-only, the way phase 15's task-05 final pass proved its composition: the dashboard dials all three agents with its client certificate, the issued-vs-deployed revisions agree, nothing non-mTLS is left in the config, and the things the bundle install must not have broken (driveripper's 16 SMART reads, deskwork's GPU row) still work. No live revocation is performed — the revocation wiring is phase 15's e2e proof (data/logs/verify-15-tls-e2e.py), and a live revoke of a working fleet is a change, not a check.

Work

  1. ./scripts/dev-server.sh status — the nine-source table ok (host:driveripper, host:deskwork, host:gateway, disks:driveripper, disks:deskwork, disks:gateway, nut, llm:gufo, llm:vllm); disks:gateway is ok with the page hiding gateway (phase 22's gate) — the job healthy, the page scoped.
  2. Signed-in GET /api/certs: all three rows status: "active", deployed_bundle_rev == bundle_rev (the "install the new bundle" sentence is gone for every host), agent block from the system payload: agent.tls: true + agent.bundle_rev present on all three (the task-03 passthrough — a token-mode snapshot grows nothing, so the fields' presence is the mTLS proof, rule 2's shape).
  3. Signed-in GET /api/system/snapshot + GET /api/disks/snapshot: the agent blocks on all three hosts; gateway's row absent from /disks (phase 22); driveripper's 16 drives with live SMART numbers (the --force unit rewrite is the gap-10 shape — a smart: null row here fails the task); deskwork's nvme0n1 row and its GPU card on /system (the 1.1.0 agent file's reads intact).
  4. The config: grep of .env.dev — no http:// in HOST_TARGETS, no @ userinfo in any target URL; data/env-backup/ holds the pre-flip copy (the rollback path exists on disk).
  5. The negative control, without touching the fleet: data/logs/verify-15-tls-e2e.py's transcript (phase 15) is the standing proof that a revoked serial is refused on /health too; this task re-runs none of it live — it names the transcript as the control and checks only that tests/test_collectors.py's revocation-before-dial pin and tests/test_api.py's build_hub wiring pin are green (they run in the suite).
  6. Screenshots (invariant 10) in data/logs/: /certs (the three active rows with matching revs), /disks (the two visible hosts, driveripper's 16 live rows), /system (deskwork's GPU card) — the "the dashboard says all three are mTLS" proof is a screenshot, not a curl.

Testing & Quality

  • Coverage: n/a (verification task)
  • The read-only rule: no POST to the fleet, no upsd command, no revocation, no unit change — the task reads the fleet and screenshots it

Completion Criteria

  • nine sources ok; deployed_bundle_rev == bundle_rev and agent.tls: true for all three hosts (pinned by the API checks, shown by the screenshots)
  • .env.dev has no http:// agent URL and no userinfo; the pre-flip backup exists
  • driveripper's 16 SMART reads and deskwork's GPU card are live in the served payloads
  • screenshots of /certs, /disks, /system in data/logs/
  • the revocation pins (tests/test_collectors.py, tests/test_api.py) green in the suite
  • the full suite + bash .agents/validate.sh green; AGENTS.md's fleet record and gap 11 updated by the phase's Documentation & Consistency pass to the mTLS end state