Files
felhom.eu/REPORT-day3-2026-10-08.md
T

8.6 KiB
Raw Blame History

REPORT — 2026-10-08 (evening): the operator's ten answers (D1–D10) built — code and tests, no delivery

(REPORT-day3-… because other sessions write in this clone today.) Rulings recorded first: 09 §3 decisions 185–194 (commit 4510dd7d), and in each row.

Part Result
A — operator actions (D1; R-314, R-279) Done on main. Controller internal/report/opactions.go + scheduler.RunNow; hub table operator_actions, four buttons, reply field operator_actions, result field operator_action_results. Closed list both sides (TestOpActions_ClosedList, TestOperatorActions_ClosedList); unknown → refused, nothing called; once per id; cross-customer result ignored. Fixed on the way: ExtendAbandon could move a deletion earlier or edit the box date in the hub phase; StopAbandon reported success while the hub's deletion stayed pending; reply read limit 4 → 64 KiB. Review fix: a run_job „done" says it ran, not what it found.
B — delete a switched-off box at once (D2; R-30) Done on hub main. Presence from the wait channel (connected / not connected since T / unknown), shown on the host page; the delete goes ahead at once only with the tick AND ≥ 360 s not connected, re-checked at the POST. 7 mutations red-proved.
C — health mail + dashboard (D3; R-79) Done on main, both halves. Hub: the household's health mail drops the raw note and points to the dashboard (operator mail unchanged). Controller: the last six health producers carry a key; wire text unchanged.
D — signed in across a restart (D4; R-35) Done on controller main. Only sha256(cookie) on disk (0600). Review fixes: rows written under another password are dropped at load; a failed revoking save removes the file. 8 tests.
E — Cloudflare key check (D6; R-138) Done on hub main. Fake Cloudflare in tests only; the token is never logged. Review fixes: the token's one zone must BE the customer's domain (a parent zone was accepted, and checking it against today's customers was order-dependent). Limit filed: R-913 (read scope ≠ write scope).
F — one lost off-site copy is an error (D7; R-435) Done on hub main. Review fixes: each window explains at most its hub-set cap; each window explains one fall only; a window stuck open explains nothing; unreadable windows fall back to the half-rule. 08 §6.5 written (count from the box, net count).
G — failed restore keeps the app stopped (D8; R-893) Done on controller main. Review fixes: the hold now covers every failure after the definition or a volume moved (not only a failed replay); the hold is persisted before the stop. R-893 stays open, NARROWED to the second half („put back exactly as it was") — no new row needed.
H — D5, D10 R-717 closed (D5). wger mem_request 256M pushed (catalog 31e9651, CI 1559 success), after a hub read showed no box runs wger (app-telemetry page 12:22 UTC: wger 0; controls paperless, bentopdf present).
R-554, R-462 Not done. R-554 is still stopped on a customer promise (decision 2 below). R-462 not started (no time left after the review fixes).

Rows: 132 before → 136 after. Opened 1 (R-913). Closed 1 (R-717). The other +4 are another session's (R-909, R-910, R-911, R-912: dashboard layout and logos). State changes: R-314, R-279, R-30, R-79, R-35, R-138, R-435 → VERIFY (built, ships tomorrow, closes after the live proof); R-893 → NARROWED.

Commits. Controller: ee8a526…d3e17e9 (cherry-picked from the helper branches onto main), 3f84f82 (review fixes). Hub/felhom.eu: 4510dd7d (rulings), then the integration push (this report's commit). Catalog: 31e9651.

Security review — what it found and what happened

Automatic commit reviews plus two read-only review helpers. Fixed and red-proved the same evening (10): Cloudflare parent zone; order-dependence of the zone check; R-435 fail-open on unreadable windows; a box's count_after widening a window; one window explaining several falls; a stale open window; D4 revocation lost on a failed save (two shapes); D8 earlier failure branches started the app on a mix; the hold written after the stop; run_job „done" read as a pass. Written as limits, not fixed: D2 — presence is the guest controller's, so a live host with a stopped guest reads „not connected" (the cost accepted with decision 186; noted on R-30); D8 — placed files alone still restart after a successful rollback (option C as ruled; option A is next); D6 — tokens saved before the check were never checked (R-138 closes only after each is checked once); D6 — read scope ≠ write scope (R-913).

Waits for tomorrow's releases

  • hub: the morning's items (R-243, R-901 one-year deletion, R-304 mail, R-415 guard) + D1 hub half, D2, D3 mail, D6, D7.
  • controller: the morning's R-899/R-304 + the afternoon's R-304 mail, R-298 button + another session's dashboard layout fixes + D1, D3 dashboard, D4, D8. MinAgent unchanged (0.131.0). Release the hub and the controller the same day (D1's wire fields; an older hub sends no actions, an older controller ignores them and the rows expire).
  • agent: the morning's R-899 + ring label + R-304 424 (nothing new tonight).
  • catalog: already pushed (wger 256M; reaches a box at its next sync).
  • DooPlex: the ep0-copy clean-up job (D9) — dry run, then daily — after the releases are read back.

Live proofs tomorrow's session must run (scratch 9202 only, after the releases)

  1. D1: from the hub's host page, run_job fill-watch → the hub's result row; control from another channel: the controller log pull's „checked N filesystem(s)" line. offsite_backup_now → result; control: the off-site snapshot list on 9202's backup page. abandon_stop / abandon_extend only if 9202 has a countdown.
  2. D2: stop guest 9202; time until the host page says „not connected"; control: the ingress log's last /api/v1/wait line from 9202. Do NOT tick-delete demo-hp — the fast delete removes the Proxmox host; prove it only through GET /hosts/<id>/delete-impact (off_tick_required). Evidence off before 9202 starts again.
  3. D3: a health_critical on 9202 → the household mail in the catch-all has no {, has the dashboard line; the operator mail still has the note. The dashboard banner in English for an English household.
  4. D4: sign in on 9202, restart the controller, the next page needs no login; then change the password → the old cookie is refused after the next restart.
  5. D6: re-save each customer's config once with its current token (operator present): each must pass; a refusal keeps the old token. Then close R-138.
  6. D7: a hand-granted window on 9202 removes N → no alarm; control: the hub's own window row.
  7. D8: design slice 0 on 9202 with a throwaway app (version N snapshot, update to N+1, restore with a truncated dump) → the app held, the page sentence, the operator line. Evidence off before teardown.
  8. D9: install the DooPlex job, dry run first, then daily.

Machines

demo-hp, demo-felhom, Tester 1: not touched. 9202 and the bench: not touched. Hub: read only (three page reads with the operator password: /apps, /hosts, /configs). DooPlex: no change (helper work ran in git worktrees under /mnt/5_hdd/felhom.eu/worktrees/; no Docker command). No release, no deploy, no reboot, no prune. Provisioned nothing.

Small fixes without a row

scripts/test_gate_decoys.py crashed in a linked git worktree (lock path); controller TestR650_NoBareDockerExec raced a vanishing temp file; the three D1 abandon fixes above.

Instruction files: no edit.

Decisions for the operator

  1. R-913 — how sure must the Cloudflare key check be? The hub can see what a pasted key may READ, not what it may CHANGE. A key made by hand with „read one zone, change all zones" would pass. Pick: (a) you always make the key with the one recipe („Edit zone DNS", Zone Resources: Include → Specific zone); it costs nothing. (b) The hub makes the key itself: safest, but the hub then holds a key that can make keys. If you do nothing: the check stays as built, and the limit stays written down.
  2. R-554 — what should the household's recovery note say once the old setup wizard is deleted? Today the note on the box tells the household to run a setup script on port 8081 to restore. Pick: the note says „Call Felhom; we restore your box from its backup", and CC deletes the wizard. If you do nothing: the wizard stays, unused, and a box whose first start cannot reach the hub shows it to the household.