Author SHA1 Message Date
admin d8752de9e3 Night 2026-10-28 (part): R-1338 — the memory mark reads the live anon (decision 22 refined; bench 27.7 %, 9202 25.1 %, catalog patch prepared, not pushed); claim fault.already-paired walked on Tester 1's console (33 -> 32 not walked); evidence
gates / gates (push) Successful in 1m48s
2026-10-29 00:14:46 +01:00
admin 8a3df79fda Night 2026-10-28 (part): design notes R-1255/R-1254 (03), R-528 (08, live on Tester 1 + the operator's mail); capability map E8/E9 PROVEN-LIVE, B2 re-checked; 2 claims walked (35 -> 33 not walked); evidence + red-proofs
gates / gates (push) Successful in 1m49s
2026-10-29 00:00:44 +01:00
admin 1ee6d5a507 hub: R-1255 escrow edges (HUNT-3 H3/H4) — the carry takes the package with a hash; set-aside names unique per run; the purge never takes a reused path's package
gates / gates (push) Successful in 1m52s
Tests red before the fix: TestR1255_TheCarryTakesTheNewestPackageThatHasAHash,
TestR1255_APurgeNeverDeletesAPackageAReusedPathStillNeeds, TestR1255_TwoSetAsidesOnOneDayGetTwoNames.
Commit only; rides the next hub release.
2026-10-28 22:40:01 +01:00
admin 05595ecff6 Gitea 28.2.0 live (R-1315 closed; D57 -> decision 280: imports only from GitHub/Codeberg/GitLab); R-1338: the Meilisearch cap helps on the bench, not on 9202 — measured, not pushed; STATUS, CONTEXT, evidence
gates / gates (push) Successful in 1m52s
2026-10-28 21:35:56 +01:00
admin 1be7aa87dc Big steps close-out: Wanderer, Termix, Homepage, Seerr live (bench + box + undo); R-1335/R-1311/R-1320/R-1317 closed, R-1338 opened, R-1334 VERIFY (0 refused in two dry runs, no login); 09 decision 279 + [DESIGN] path rule; STATUS, CONTEXT, evidence
gates / gates (push) Successful in 2m53s
2026-10-28 18:23:33 +01:00
admin 3c0a33c1a0 R-1334 evidence: dry run 2459 log
gates / gates (push) Successful in 3m50s
2026-10-28 13:08:41 +01:00
admin 8644450db2 image reader waits out a registry 429 and tries again (3 tries); 08 + changelog: the dry-run measurement of the Docker Hub change (0 refused), two runners = two tag caches (R-1334) 2026-10-28 13:08:33 +01:00
admin fe677bae94 security watch: Docker Hub requests spaced, a 429 retried (NOT CHECKED only after the last try), tag lists cached 24 h per registry path on the runner (R-1334); W14
gates / gates (push) Successful in 4m14s
2026-10-28 12:43:38 +01:00
admin 1c8f9ef924 Runtime fixes 2026-10-28 close-out: lane batches 3+4 live (papra, dawarich, adventurelog), R-1332 closed (10 live / 4 big step / 6 no fix), TABLE final, AdventureLog runs 2-4 evidence, 9202 back on the live catalog; CONTEXT, STATUS, REPORT
gates / gates (push) Successful in 3m37s
2026-10-28 12:04:26 +01:00
admin ac95ca4fc3 STATUS 2026-10-28 (day): the steps live, the waiting apps in one line; D61 ruled and moved to history
gates / gates (push) Successful in 3m33s
2026-10-28 10:49:00 +01:00
admin e381172846 register: section counts after the runtime-fixes rows 2026-10-28 10:40:43 +01:00
admin 47e1ef062b Runtime fixes 2026-10-28: TABLE of the 20 apps (calibre-web loads Brotli — corrected; file manager does not, 3 boxes), lane batches 1+2 evidence; 09 decisions 277 (D61, operator) + 278 and the lane batch; R-1313/R-1322/R-1327 closed; R-1334..R-1337 opened; app rows updated 2026-10-28 10:40:31 +01:00
admin 29e9cd36a6 security watch: remember a notice per group — a catalog pin and a DooPlex pin of one image no longer share one memory entry (old entries copied once, no re-mail); W13 2026-10-28 10:39:41 +01:00
admin 73c91eacce security watch: the RUNTIME line names the zstd decoder in words, not the module repr (R-1327) 2026-10-28 10:33:39 +01:00
admin a3247d9f44 security watch reads zstd layers in CI by itself (R-1327): pinned zstandard 0.25.0 wheel, sha256-checked; RUNTIME log line; HA 2026.9.4 and RomM 5.4.1 dropped from the cache for the CI fill proof; Immich v3.3.5 power-cut repair evidence
gates / gates (push) Successful in 4m12s
2026-10-28 07:59:34 +01:00
felhom security watch 9b4b5fe5e7 security-watch: memory of 2026-10-28 (R-1303). Docs only. 2026-10-28 03:42:17 +00:00
admin 3d3cd3ad7c Night 2026-10-27/28: Immich and Home Assistant lane walks proven (drill), Wanderer hidden in the drill, R-1322/R-1313 updated; STATUS (D61 RomM, the morning list), CONTEXT with the unattended decisions
gates / gates (push) Successful in 2m0s
2026-10-27 23:36:25 +01:00
admin f5a4995da5 security watch sees runtimes (R-1327) and DooPlex (R-1328); HTTP2Shell rows R-1329–R-1332; R-1326 closed
gates / gates (push) Successful in 3m27s
- scripts/image_runtime.py: Node / Python Brotli / brotlicffi / apk / dpkg read from an image's registry config and
  layers (no pull; HEAD for the nightly digest; zstd via the zstd program where present; quay.io, index.docker.io).
- security_watch.py: a „runtime" source (security_watch_runtimes.json), cached by digest in state.json (154 images,
  filled on DooPlex tonight); ghcr.io tag lists are paged; the DooPlex group (own block, homelab next-step).
- dooplex_inventory.py + documentation/security-watch/dooplex-workloads.txt (89 images, homelab-manifests 5aeec8d).
- Tests W10–W12 (58 checks) + test_image_runtime.py (13), each red-proved.
- audits/http2shell-2026-10-27: the Home Assistant lane walk (proven), HOMELAB-LIST.md (19 to update), the run log.
- 08 §11 design line; 09 §3 decision 276 (HA monthly = same main version; decided by CC unattended).
2026-10-27 23:23:02 +01:00
admin 503692a1da D60 (CC never deletes from the secret store) and D56–D59 recorded: 09 §3 decisions 271–275, rows R-785/R-1311/R-1313/R-1315, the decide table cleared; D60 in workspace CLAUDE, 12, secrets runbook
gates / gates (push) Successful in 1m59s
2026-10-27 22:31:44 +01:00
admin a69ddbde56 hub manifest (R-1326): a startupProbe gives the hub up to 180 s to start (measured 31–36 s); liveness unchanged after start
gates / gates (push) Successful in 1m57s
2026-10-27 21:45:58 +01:00
admin f633d48bab R-1299 CLOSED: the clean-up window button (hub 0.174.0/0.174.1, live grant + cancel on tester-1); R-1326 filed (hub start-up vs liveness); R-1237 updated (46 dead names removed with sec rm); 07/05 design lines; secrets runbook: sec rm
gates / gates (push) Successful in 1m59s
2026-10-27 21:16:48 +01:00
admin 714ee236b2 hub v0.174.1: manifest bump (R-1299 event row + Backup & DR tab) — on the operator's yes 2026-10-27
gates / gates (push) Successful in 2m1s
2026-10-27 20:22:46 +01:00
admin de57c090bf hub(R-1299): the window grant/cancel event is really stored (0.174.0 wrote no row); the block moves to the Backup & DR tab
gates / gates (push) Successful in 1m59s
2026-10-27 20:12:43 +01:00
admin 1796112508 Security app updates 2026-10-27, close-out: Jellyfin 12.4 live (catalog 540f185; bench + box + the undo proven, R-1314 filed and closed); per-box floors cleared after a clean 30-min watch; TRIAGE states; STATUS (four picks D56-D59); teardown; REPORT-security-app-updates-2026-10-27.md
gates / gates (push) Successful in 2m4s
2026-10-27 19:26:39 +01:00
admin 33f3cd7af0 hub v0.174.0: manifest bump (R-1299, the clean-up window button) — on the operator's yes 2026-10-27
gates / gates (push) Successful in 1m54s
2026-10-27 19:22:20 +01:00
admin d85198b835 hub(R-1299): the one-time clean-up window gets a button on the customer page
gates / gates (push) Successful in 1m51s
The Backup card's off-site part shows the window state (weekly switch, the normal cap, a waiting grant, the last
window) and a form: optional limit -> a confirm step that names the customer and the limit -> the SAME route and
rule as the script address (POST /offsite/window-grant/<customer>, wr(grpOffsite), the page's CSRF). A waiting grant
can be cancelled. A raised limit above the store's measured snapshot count is refused (the 500 ceiling stays). Every
grant and cancel: a log line and an operator-only info event offsite_window_grant (who, customer, limit).
Tests TestR1299_* (five), red-proved by five mutations.
2026-10-27 17:23:37 +01:00
admin 7610f69e7c Security app updates 2026-10-27: 14 security-fix steps + 2 normal steps live (catalog 06e603e, 7b0071e, 65a6b11); controller v0.346.1 (traefik, file manager, cloudflared) floor set; R-1304 and R-1306 CLOSED, R-1305 NARROWED; R-1313, R-1315–R-1325 filed (big steps left, three observations); 09 decision 255 and B23: the batch use of the lane; evidence 2026-10-27 17:22:02 +01:00
admin 7c75162a18 REPORT-release-2026-10-27: the night's fixes, the line test, the release block; the floor watch and the per-box clear (evidence)
gates / gates (push) Successful in 1m56s
2026-10-27 16:13:40 +01:00
admin acd79a78cc Release block 2026-10-27: hub 0.173.0, agent 0.167.0, controller 0.346.0 released; R-1250 fixed the same day and proven; ten rows closed, R-1312 opened
gates / gates (push) Successful in 2m29s
- audits/linetest-2026-10-27/: the hold failed four times as built (qBittorrent drains ~14 s), the fix 710ceac, the test
  through the hold on 0.346.0-rc.1 (94.5 Mbit/s, the limit back exactly), teardown.
- audits/release-2026-10-27/: builds, agent release + signed updates, per-box and global floors, box walk.
- 09 §3 decisions 269 (R-1250 fix the same day) and 270 (R-1218 live proof waived); D55's window result in 268.
- 08 §: the drain-wait design line. STATUS, CONTEXT, register (223 -> 214).
2026-10-27 15:45:59 +01:00
admin 708a34512e Security app updates 2026-10-27: evidence of batch 1 (box walks rallly, romm, code-server, outline, vikunja; wishlist + bookstack bench and box; jellyfin bench; the walk's negative control). Docs only.
gates / gates (push) Successful in 1m58s
2026-10-27 15:08:44 +01:00
admin bbc3acb817 hub v0.173.0: manifest bump (D53 held apps, R-1218 hub half, Go 1.27.3) — on the operator's yes 2026-10-27
gates / gates (push) Successful in 1m56s
2026-10-27 09:31:45 +01:00
admin 29134c52c2 security_watch: a GitHub Actions advisory is not listed; an empty fix with a closed range reads 'after X' (R-1310 part; test W9, red first)
gates / gates (push) Successful in 3m36s
2026-10-27 09:16:58 +01:00
admin ba06b873b9 Security app updates, Part 1: the triage of 38 flagged pins (TRIAGE.md, per-app notes, PICKS.md); R-1306 triaged; R-1310 (watch classifier) and R-1311 (Termix X-Forwarded-For) filed
gates / gates (push) Successful in 2m0s
2026-10-27 09:06:38 +01:00
admin c6248dbfc5 R-1303: the GitHub key is in place (CI dry job 2415 read every repo in one night); first real night (job 2413) mailed nothing, as designed; STATUS do-item removed
gates / gates (push) Successful in 2m0s
2026-10-27 07:55:04 +01:00
admin 8744eab80d R-1174 CLOSED: the status gate refuses from 2026-10-27 (hand run: clean copy rc 0, a copy citing a closed row rc 1); R-1250's due check moves one day (the line test runs today, from 10:00 CET)
gates / gates (push) Successful in 2m4s
The nightly CI job 2412 convicted both due checks, as designed.
2026-10-27 05:16:43 +01:00
felhom security watch 3c8c1ded1f security-watch: memory of 2026-10-27 (R-1303). Docs only. 2026-10-27 03:41:31 +00:00
admin 626275b187 R-1303 built and live-proven (test mail arrived, seed run committed its memory); R-1305–R-1309 filed (file manager, 27 apps, image packages, floating tags, mail-only notices); docs 08 §11, B23, monthly §4a; STATUS
gates / gates (push) Successful in 2m21s
2026-10-26 23:51:45 +01:00
felhom security watch ed843da788 security-watch: memory of 2026-10-26 (R-1303). Docs only. 2026-10-26 22:44:04 +00:00
admin 6ee23a3b8f R-1303: watch — abandoned templates are GAP, a seed's unread pins stay pending (no storm after a seed); 38 checks
gates / gates (push) Successful in 4m5s
2026-10-26 23:34:29 +01:00
admin 1f62d62915 R-1303: the nightly security watch — security_watch.py, the shared pin list + upstream gate, 35 tests, the CI job (03:40 UTC)
gates / gates (push) Successful in 3m53s
2026-10-26 23:20:06 +01:00
admin 97ae7086c0 R-1303 (P2): the security watch — spike: which notice sources catch the controls; R-1304 (P3): traefik v3.7.13 inside 12 October advisories
gates / gates (push) Successful in 1m55s
2026-10-26 22:57:07 +01:00
admin ae3db89ab3 night fixes 2026-10-26: live proofs (R-1220, R-1232, R-1187, R-1298), register states, design lines; R-1300 filed; R-528 design
gates / gates (push) Successful in 1m56s
Evidence audits/night-fixes-2026-10-26/ (scanned: 0 secret hits).
2026-10-26 22:17:36 +01:00
admin cc0fb962f3 R-1300 CLOSED: controller 0.345.1 (cloudflared 2026.10.3) on every box; R-1301 filed (N100 host clock, chrony fails at boot); 01: cloudflared follows Cloudflare's security notices
gates / gates (push) Successful in 2m27s
2026-10-26 21:41:05 +01:00
admin f680720ecd STATUS: R-1300 (P1) — the tunnel's bad-certificate trust, until 0.345.1 reaches each box
gates / gates (push) Successful in 2m35s
2026-10-26 20:58:42 +01:00
admin ffb91d89e7 R-1300 (P1, Security): cloudflared 2026.9.3 trusts the eMudhra weak-key intermediates — the list, the origin check (not affected), evidence 2026-10-26 20:50:39 +01:00
admin 3720bd1f03 audits: R-972 govulncheck before/after (Go 1.27.3)
gates / gates (push) Successful in 2m16s
2026-10-26 20:42:41 +01:00
admin d625a1437d hub build(R-972): Go 1.27.3 + golang:1.27.3-alpine3.24 builder (GO-2026-6809) — govulncheck 1 → 0 called 2026-10-26 20:42:35 +01:00
admin 09b5f02fc3 hub(R-1218): never replace a recovery package that seals the off-site key with one that seals none (409)
gates / gates (push) Successful in 1m54s
SaveHostEscrowWithIdentity refuses (ErrEscrowWouldDropRepoKey); the PUT answers 409. Red-proved (store: superseded=true;
API: 500). Two older tests pinned the old demotion and are updated. Commit only.
2026-10-26 20:21:08 +01:00
admin 99c0f5e310 D55 = 260 recorded (09 §3 decision 268); the grant set and read back; R-1299 filed (no grant button)
gates / gates (push) Successful in 1m56s
2026-10-26 20:11:22 +01:00
admin 3ca9b71c73 R-435 read and closed: the 2026-10-26 windows (hub records + mailbox; box logs lost to restarts, said plainly)
gates / gates (push) Successful in 2m5s
2026-10-26 19:17:19 +01:00
admin 4955744462 docs: STATUS D55 (the D54 grant needs the operator: CC's token lacks offsite:write; the cap), R-1294/R-1297 rows, CONTEXT
gates / gates (push) Successful in 1m57s
2026-10-26 19:06:41 +01:00
admin e33ec8210a D53 built + live-proven (08 §10 [DESIGN — built]); R-1297 decoys: register-shape decoys assert the script's exit
gates / gates (push) Successful in 3m25s
- 08 §10: built (controller 5bd03ad, hub 7e57e824, commit only); putback_pending as on the wire; as-built notes
- audits/d53-held-apps-2026-10-26: live proof on 9202 against a test hub (3-min grace), red-proofs, teardown
- R-1291 BUILT (not released); R-1298 filed (9202's orphan holds + PrivateBin leftover)
- test_gate_decoys.py: the register-shape cases also run the script and assert its exit code — R-1297's decoy 2
  showed an inert main() passed every case (9 cases red with it now)
- audits/r1297-ci-trim-2026-10-26: runners, times, decoys
2026-10-26 19:03:07 +01:00
admin 7e57e824a2 hub(D53): held apps reach the operator — mirror, Held apps list (host + Hosts page), reminder after the grace
gates / gates (push) Successful in 1m58s
app_held / app_hold_cleared allow-listed and operator-only; handleEvent mirrors them in held_apps; HeldAppsChecker
sends ONE app_held_reminder (warning, operator-only, per-app cooldown) after the grace per reason (6 h / 1 d / 3 d),
then weekly; recorded before sending; stale rows not reminded; the hub never clears a hold. Test-only
alerting.held_app_grace_override. TestD53_* in api/monitor/notify/web, red-proved by six mutations. Commit only.
2026-10-26 18:25:00 +01:00
admin ecd82abab8 ci(R-1297 A): heavy suites by path on a branch push, all on a tag and nightly; no second full gate run
gates / gates (push) Successful in 3m23s
- script_tests_gate.py: test_gate_decoys / test_due_checks_gate / dooplex-offsite run on a CI branch push only
  when one of their paths changed (FELHOM_CHANGED_FILES); no list, an empty or unreadable list = every suite
- gates.yml: nightly schedule 03:20 UTC; the list is set only for push:refs/heads/*; a trimmed commits array
  (total_commits > listed) is an unknown list
- test_repo_gates.py and test_due_checks_gate.py group G drive the real runner with GATES narrowed to their
  labels, instead of the whole gate set a second time (130 s each in CI)
- red-proved: filter cases, workflow pins (old gates.yml), inert run_gate, unregistered due-checks
2026-10-26 18:14:23 +01:00
admin 8143a2c872 docs: record D53, D54 and R-1297 (B) (09 §3 decisions 265-267); STATUS moves the two picks to history
gates / gates (push) Successful in 5m51s
2026-10-26 18:07:22 +01:00
admin 2354b9084c 2026-10-26 afternoon: R-1295 and R-1292 closed (hub 0.172.0 + tenantsync v1.4.0 on ep0; controller 0.345.0, floor 13:27:04Z); R-1297 filed (CI speed, operator: both); STATUS (D53, D54), CONTEXT, the run's report.
gates / gates (push) Successful in 13m30s
2026-10-26 14:33:48 +01:00
admin 69443d3c4e hub v0.172.0 RELEASED (13:08 UTC); felhom-tenantsync v1.4.0 INSTALLED on ep0 (operator yes); R-1292 live on Tester 1 (PASS; run 1 was an instrument failure, kept).
gates / gates (push) Successful in 13m17s
2026-10-26 14:17:07 +01:00
admin a90a9745a8 hub: image 0.172.0 (R-1295; operator yes 2026-10-26)
gates / gates (push) Successful in 13m1s
2026-10-26 14:04:22 +01:00
admin 232f42d21e R-1295 live on hub rc.1 (a fresh Tester4 install set up its whole-guest off-site tier; the box consumed the credential and made its first copy); R-1294 read: an honest plan the cap can never catch up with (D54); R-1291 design (08 §10, D53); design lines for R-1295, R-1285, R-1292, R-1294; R-1296 filed; STATUS.
gates / gates (push) Successful in 13m41s
2026-10-26 13:42:47 +01:00
admin ee38dee2c9 hub: image 0.172.0-rc.1 (R-1295 live proof; operator yes 2026-10-26)
gates / gates (push) Successful in 13m30s
2026-10-26 12:45:52 +01:00
admin 722013da90 R-1295: the PBS DR set-up waits out PBS's 5-s permission cache. Cause measured on a throwaway PBS 4.2.5 under load (v1.3.0 failed 11/30, v1.4.0 0/30): tenantsync v1.4.0 re-checks the same token (and the admin token) up to 15 s; hub v0.172.0 retries a self_check_failed rollback 3x, 7 s apart, and a final failure mails the operator (pbsdr_provision_failed, operator-only). Red-proved. Commit only; ep0 unchanged.
gates / gates (push) Successful in 13m24s
2026-10-26 12:27:28 +01:00
admin c69f53055d 2026-10-26 release run: hub 0.171.0, agent 0.166.0 (vouched), controller 0.344.0 (global floor 09:07:47 UTC), catalog 73c165d, golden 0.344.0 (baked, vouched; a fresh install came up on 0.344.0); the golden waiver removed — the gate is green on the golden. Rows: 9 closed (R-1278, R-1280–R-1283, R-1286–R-1289), R-1285 back to OPEN, R-1294 and R-1295 filed; STATUS, CONTEXT, evidence (scanned, 0 hits).
gates / gates (push) Successful in 13m35s
2026-10-26 10:42:54 +01:00
admin 6efb47607f hub: image 0.171.0 (R-1287, R-1289; operator yes 2026-10-26)
gates / gates (push) Successful in 13m7s
2026-10-26 08:53:49 +01:00
admin 7ad7c99684 D52: the golden waiver renewed for 2026-10-26 only (expires 2026-10-27) — the Sunday bake was missed; the golden is baked today on v0.344.0 and the waiver goes after the vouch. D51 (Start) and D52 recorded (09 §3 263, 264; CONTEXT; STATUS-HISTORY).
gates / gates (push) Successful in 12m56s
2026-10-26 08:37:12 +01:00
admin 1550b1da5a R-1183 CLOSED (measured 2026-10-26, two channels: the hub log and DooPlex's push journal — each daily job once, on its CET hour; the morning of 10-25's hub log is gone, named). R-1293 filed (P4): on the fall-back night the 02:30 push runs before the hub's second 02:00, so that copy never reaches ep0; dated check 2027-03-29. 2026-10-26 08:23:31 +01:00
admin b00d5c6107 D51 ruled by the operator: Start. Kimai's crash-loop hold lifted 2026-10-26 06:57:03Z, both containers healthy, 0 restarts; R-1286 to VERIFY (install_id at the next controller start; holdWhy rides v0.344.0); D51 off STATUS. 2026-10-26 08:08:01 +01:00
admin 9258cdd11c Night 2026-10-25 Part 4–5: each fix's [DESIGN] line (04, 05, 07, 08, 11, 13, 15), the register (R-1261, R-1281, R-1282, R-1288, R-1280, R-1285, R-1283, R-1287, R-1289, R-1278 to VERIFY; R-1286 waiting on the operator; R-1291 and R-1292 opened), STATUS (D51 Kimai, the Monday list), the night report with its three-layer teardown, and the rig evidence (scanned: 0 known-secret hits)
gates / gates (push) Successful in 13m42s
2026-10-25 23:47:13 +01:00
admin f63284861e hub v0.171.0 (unreleased): a set-aside-only backup digest mails as a warning that says nothing failed (R-1287); a test build is never the fleet's newest (R-1289). Red-proved. Commit only.
gates / gates (push) Successful in 13m21s
2026-10-25 21:21:18 +01:00
admin 68ee667a83 Night 2026-10-25 Parts 1–3: every named artifact still downloads; installer 1.36.1 published (operator yes) and its three refusal sentences seen live; D50 = A recorded (09 §3 262, CONTEXT, build skill); R-1284 and R-1290 closed; R-1261 rig evidence so far
gates / gates (push) Successful in 12m56s
2026-10-25 20:52:56 +01:00
admin b841192670 webpage: the installer git-sync (sidecar + init) follows installer-v1.36.1 (R-1284; operator yes 2026-10-25)
gates / gates (push) Successful in 13m19s
2026-10-25 20:11:34 +01:00
903 changed files with 144636 additions and 194 deletions

No files matched your search

+26
View File
@@ -18,8 +18,13 @@
name: gates
# R-1129: `workflow_dispatch` is the manual PROOF that the failure mail can be sent. A push run is
# unchanged by it: the proof step below is skipped on a push, and `force_alarm` is then empty.
# R-1297 (A, 2026-10-26): the nightly schedule is the run that still executes the three path-filtered suites when no
# push touched their files (scripts/script_tests_gate.py PATH_FILTERED). It sets no file list, so every suite runs —
# like a release tag (a tag push) and a manual dispatch. 03:20 UTC: after the 01:40 release copy and the night chain.
on:
push:
schedule:
- cron: "20 3 * * *"
workflow_dispatch:
inputs:
force_alarm:
@@ -149,6 +154,12 @@ jobs:
if not commits:
sys.stderr.write("the payload carries no commits array - unknown\n")
raise SystemExit(0)
# R-1297: Gitea trims the payload's commits array (the newest few only); a push of more commits than it
# lists has files nobody named here. That list is UNKNOWN, never short - so nothing is printed.
total = ev.get("total_commits")
if isinstance(total, int) and total > len(commits):
sys.stderr.write("the payload lists %d of %d commits - the file list is unknown\n" % (len(commits), total))
raise SystemExit(0)
seen = []
for c in commits:
for key in ("added", "modified", "removed"):
@@ -172,6 +183,18 @@ jobs:
[ "$SCOPE" = "docs" ] || SCOPE=code
echo "PUSH_SCOPE=$SCOPE" >> "$GITHUB_ENV"
echo "scope: $SCOPE"
# R-1297 (A): the heavy suites read this list and skip themselves when none of their paths changed. ONLY a
# branch push with a known list sets it; a tag, the nightly schedule and a dispatch run every suite.
case "${GITHUB_EVENT_NAME:-}:${GITHUB_REF:-}" in
push:refs/heads/*)
if [ -s /tmp/pushed-files.txt ]; then
echo "FELHOM_CHANGED_FILES=/tmp/pushed-files.txt" >> "$GITHUB_ENV"
echo "suite filter: ON (a branch push with a known file list)"
else
echo "suite filter: OFF (no usable file list) - every suite runs"
fi ;;
*) echo "suite filter: OFF (${GITHUB_EVENT_NAME:-?} ${GITHUB_REF:-?}) - every suite runs" ;;
esac
- name: Run the gate entry point
# The ONLY thing CI runs. No go build, no go test, no linting, no deploy — those are either
@@ -188,6 +211,9 @@ jobs:
# R-986: the security-scan gate fetches the PINNED gitleaks here (sha256-checked); no Go, so govulncheck says
# NOT CHECKED in CI, out loud. Warn-first either way: the scan lists, it never fails this job.
FELHOM_SCAN_FETCH: "1"
# R-1327: test_image_runtime.py reads a zstd layer with the PINNED zstandard wheel (sha256-checked); with this
# set, a missing decoder FAILS the suite instead of saying NOT CHECKED.
FELHOM_WHEEL_FETCH: "1"
run: python3 scripts/repo_gates.py --fast --scope="${PUSH_SCOPE:-code}"
- name: Manual proof - alarm key present, optional forced failure (dispatch only, R-1129)
+128
View File
@@ -0,0 +1,128 @@
# security-watch — every night, read the security notices of everything Felhom ships, and mail the operator
# (admin@felhom.eu, never a household) what affects a pinned version (R-1303). The logic, its classes and its mails:
# scripts/security_watch.py; the list of pins: scripts/security_watch_inventory.py; why these sources:
# documentation/audits/security-watch-2026-10-26/SPIKE.md.
#
# THE MEMORY is documentation/security-watch/state.json on `main`, committed back by this job with its own Actions
# token. Why there and not elsewhere (2026-10-26): the two runners each have their OWN disk (act-runner-data,
# act-runner-2-data — a job lands on either), so a runner file would be two memories; Actions cache needs a node
# `uses:` step, which this python-and-git runner cannot run; anything on the DooPlex host is a host change. A file in
# the repo is one memory, readable by a person, and its history says when each advisory was first mailed.
# If the push of the memory fails, the job fails and the alarm below mails — the next night may then mail an advisory
# twice, which is the safe direction.
#
# Manual run (`workflow_dispatch`, mode):
# run a normal night, now
# seed record every advisory open now as known and mail nothing new (the first run; prints what it WOULD mail)
# dry no mail, no memory change — read the result table in the log
# test-mail send ONE clearly marked test advisory to the operator; touches nothing else
name: security-watch
on:
schedule:
- cron: "40 3 * * *" # 03:40 UTC: after the 03:20 gates run
workflow_dispatch:
inputs:
mode:
description: "run | seed | dry | test-mail"
default: "dry"
jobs:
watch:
runs-on: felhom-gates
timeout-minutes: 20
permissions:
contents: write
steps:
- name: Fetch main (latest, for the memory) and the two sibling repos
run: |
echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
base=http://gitea.gitea-system.svc.cluster.local:3000/admin
git init -q . && git remote add origin $base/felhom.eu.git
git fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD
echo "felhom.eu main at $(git rev-parse --short=12 HEAD)"
for r in felhom-controller app-catalog-felhom.eu; do
git init -q ../$r && git -C ../$r remote add origin $base/$r.git
git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD
echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"
done
- name: Run the watch
env:
RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
GH_ADVISORY_TOKEN: ${{ secrets.GH_ADVISORY_TOKEN }}
MODE: ${{ github.event.inputs.mode }}
# R-1327: zstd layers (Home Assistant and others) are read with the PINNED zstandard wheel, sha256-checked
# (scripts/image_runtime.py); without it they are NOT CHECKED, out loud.
FELHOM_WHEEL_FETCH: "1"
run: |
set -u
mkdir -p documentation/security-watch
mode="${MODE:-run}"
[ "${GITHUB_EVENT_NAME:-}" = "schedule" ] && mode=run
echo "mode: $mode"
case "$mode" in
test-mail) python3 scripts/security_watch.py --test-mail; exit $? ;;
dry) extra="--no-mail" ; state=/tmp/state-dry.json
cp documentation/security-watch/state.json "$state" 2>/dev/null || true ;;
seed) extra="--seed" ; state=documentation/security-watch/state.json ;;
run) extra="" ; state=documentation/security-watch/state.json ;;
*) echo "unknown mode $mode"; exit 2 ;;
esac
python3 scripts/security_watch.py --state="$state" --catalog=../app-catalog-felhom.eu \
--controller=../felhom-controller --json=/tmp/watch-results.json $extra
- name: Commit the memory (only when it changed)
if: github.event.inputs.mode != 'dry' && github.event.inputs.mode != 'test-mail'
env:
PUSH_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -u
f=documentation/security-watch/state.json
if [ ! -f "$f" ]; then
echo "no memory file was written - nothing to commit"; exit 0
fi
if git ls-files --error-unmatch "$f" >/dev/null 2>&1 && git diff --quiet -- "$f"; then
echo "memory unchanged - nothing to commit"; exit 0
fi
cp "$f" /tmp/state.json
auth=$(python3 -c 'import base64,os;print(base64.b64encode(("x:"+os.environ["PUSH_TOKEN"]).encode()).decode())')
for attempt in 1 2 3; do
git fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD
mkdir -p "$(dirname "$f")" && cp /tmp/state.json "$f"
git add "$f"
git -c user.name="felhom security watch" -c user.email=monitoring@felhom.eu \
commit -q -m "security-watch: memory of $(date -u +%F) (R-1303). Docs only." || { echo "nothing to commit"; exit 0; }
if git -c http.extraHeader="Authorization: Basic $auth" push -q origin HEAD:main; then
echo "memory pushed: $(git rev-parse --short=12 HEAD)"; exit 0
fi
echo "push refused (attempt $attempt) - re-fetching main"
sleep 5
done
echo "MEMORY NOT SAVED after 3 attempts"; exit 1
- name: Alarm on failure
if: failure()
env:
RESEND_API_KEY: ${{ secrets.RESEND_API_KEY }}
run: |
python3 - <<'PY'
import json, os, sys, time, urllib.request
key = os.environ.get("RESEND_API_KEY", "")
if not key:
sys.exit("ALARM FAILED: RESEND_API_KEY is empty")
run = os.environ.get("GITHUB_RUN_ID", "?")
link = "https://gitea.dooplex.hu/%s/actions/runs/%s" % (os.environ.get("GITHUB_REPOSITORY", "?"), run)
started = os.environ.get("WATCH_STARTED_AT", "")
elapsed = "%d s" % (int(time.time()) - int(started)) if started.isdigit() else "unknown"
print("ALARM-LINK " + link)
body = json.dumps({"from": "Felhom CI <monitoring@felhom.eu>", "to": ["admin@felhom.eu"],
"subject": "[felhom CI] security watch FAILED",
"text": ("The nightly security watch did not finish (R-1303).\n\nRun : %s\nElapsed : %s\n\n"
"Until it runs again, silence from the watch does NOT mean that nothing affects us.\n"
"The run log names the step: the watch itself, a mail it could not send, or its memory "
"it could not save.\n") % (link, elapsed)}).encode()
req = urllib.request.Request("https://api.resend.com/emails", data=body, method="POST", headers={
"Authorization": "Bearer %s" % key, "Content-Type": "application/json", "User-Agent": "felhom-ci/1.0"})
with urllib.request.urlopen(req, timeout=30) as r:
print("RESEND-ACCEPTED id=%s" % json.load(r)["id"])
PY
+156
View File
@@ -16,6 +16,162 @@
> and holds nothing of its own; this file does hold its own content, namely the standing rulings below.
> **2026-10-28 (evening, attended) — Gitea 28.2.0; Wanderer's search memory measured, not changed.** Gitea 1.27.3 → 28.2.0
> live `0baf8f9` (bench + box + undo; 1.27.3 refuses a 28-migrated database, the undo copy restores it). D57 → decision
> 280: imports only from github.com/codeberg.org/gitlab.com (`[migrations] EGRESS_MODE=strict` + `ALLOWED_HOST_LIST`, the
> 28.x names — 1.x's ALLOWED_DOMAINS is gone; the security review's „wrong key" notice is pre-28). The Gitea fixture posts
> every installer field (28 renamed the form). R-1338: `MEILI_MAX_INDEXING_MEMORY`=128 MiB helped on the bench (17.7 %)
> but NOT on 9202 (95.7 %, steady) → not pushed; the ladder has no entry type for a same-digest re-measure.
> **2026-10-28 (afternoon, attended at the STOPs) — Docker Hub stops refusing the watch; the four big steps.** R-1334:
> measured first — the 429s were the BURST (211 tag-list requests in ~2 min from six workers), not the count; `fe677bae`
> spaces Docker Hub requests (1/s), retries a 429 (Retry-After; NOT CHECKED after the 4th try) and caches tag lists 24 h
> per registry path on the runner (two runners = two caches); `8644450d` retries a registry 429 in the image reader. Dry
> runs 2458/2459: 0 refused — **no Docker Hub login needed** (the operator's key was not asked for). Big steps, each a
> NORMAL ladder step (`09` §3 [DESIGN] of today: no pin move without a step, also when no box runs the app), each with
> bench + box 9202 + the UNDO proven on 9202 (`audits/dockerhub-bigsteps-2026-10-28/undo_proof2.py`, probe on port 1):
> Wanderer v0.21.2 `1825247` (PocketBase internal, no `SUBDOMAIN_DB`, inbound federation off — no
> `POCKETBASE_PROXY_SECRET`; Meilisearch 384M, still `memory_tight` → R-1338; offered again, D59 ended, decision 279);
> Termix 2.8.0 → 2.9.2 `e0b9594` → 26.10.5 `589c957` (two pushes: `check-test-record-move` judges the whole push range
> as ONE move); Homepage v2.7.0 `1a254d4` (fixture reads its first-start config). New tools: `box_walk.py
> --to-definition`, fixtures Wanderer/Homepage/Seerr (Seerr brings a throwaway Jellyfin, `felhom-drill-jellyfin`).
> Termix X-Forwarded-For on 9202: the 6th wrong login is 429 on 2.8.0, 2.9.2 and 26.10.5 from the LAN (traefik
> replaces the header) and through the tunnel's address with Cloudflare's appended real address.
> **2026-10-28 (day, attended at the STOPs) — HTTP2Shell lane batches; the runtime cache fills itself in CI.** **Operator:**
> D61 = keep RomM offered (`09` §3 decision 277; the first RomM with Node ≥ 24.22.1 is a lane step). **Decided by CC (the
> brief's choice):** zstd in CI by a hash-pinned `zstandard` 0.25.0 wheel, not `zstd` in the runner image (decision 278) —
> this REPLACES the 10-27 night's „cache filled on DooPlex" (2) above. **Live on the operator's yes, CI green by hash:**
> catalog `b5b78f6` (HA 2026.10.4, Wanderer hidden), `0158b50` (Immich v3.3.5, repair re-proven), `abf3db3` (ghost,
> metube, zipline), `71e3fdf` (karakeep, tandoor), `651a991` (papra, dawarich), `0829994` (adventurelog v0.13.1 + health
> `start_period` 300 s — its backend needs ~2 min 45 s after an update). Box-walk tool fixes (catalog `box_walk.py`):
> `move_images` moves two services sharing one image; the walk loads the drill into the box mirror before the install.
> felhom.eu: `a3247d9f` (zstd), `73c91eac` (decoder named in words), `29e9cd36` (the watch's memory keyed per group —
> `dooplex:<image>|<id>`, old keys copied once; W13). Corrected: Calibre-Web DOES load Brotli (`/proc/<pid>/maps` from the
> guest; in-container maps were unreadable). Rows: R-1313, R-1322, R-1327, R-1332 closed; R-1334–R-1337 opened (229 → 229).
> 9202 ends on the LIVE catalog; the drill is back at FROM for all lane apps (`5c51ddc`). Trap: a `git pull --autostash`
> in felhom.eu emptied a walk's `walk.txt` that was being written in the clone — walk output goes to the scratchpad now.
> **2026-10-27 night (attended to 22:40, then alone) — D60, the runtime watch, HTTP2Shell.** **Decided by CC unattended
> — operator may reverse:** (1) Home Assistant's monthly release is the same main version (one comparator) → a LANE step
> with CVE-2026-111497 (`09` §3 decision 276); (2) the watch's runtime cache is filled on DooPlex (zstd, the stored Docker
> Hub login through `sec run`) and committed in `state.json`, instead of a zstd dependency in CI (`08` §11); (3) no
> Paperless step (it decodes only replies to its own calls, R-1331); (4) RomM kept (STATUS D61, R-1330); (5) the live
> catalog changes stay PATCHES/drill commits at night — the push waits for the operator. **Done:** D60 enforced
> (cc-secrets 0.4.0 `092e282` + two review hardenings `27fd806`/`e99f937`; proven in two new CC sessions); D56–D59
> recorded (decisions 271–275); hub `startupProbe` 180 s live on the operator's yes (`a69ddbde`, one start, 0 restarts;
> R-1326 closed); `scripts/image_runtime.py` + the watch's „runtime" source and „dooplex" group (`f5a4995d`; 154 images
> cached; positive controls HA + RomM, negative audiobookshelf); ghcr.io tag paging fixed; lane walks PROVEN on 9202 and
> written to the DRILL: Home Assistant 2026.9.4 → 2026.10.4 (`3c8ebb5`), Immich v3.2.4 → v3.3.5 (`34b14d5`); Wanderer
> hidden in the drill (`ee18bff`). Rows R-1327–R-1332 opened, R-1326 closed. Morning: the catalog push (writer on the
> live catalog), the homelab list to the homelab session.
> **2026-10-27 evening — R-1299 the clean-up window button (hub v0.174.0 + v0.174.1); cc-secrets 0.3.0 `sec rm`.** The
> customer page's „Backup & DR" tab has the „Off-site clean-up window" card (`internal/web/offsite_window.go`): the
> one-shot grant through a confirm step, same route and rule (`/offsite/window-grant/<id>`, `wr(grpOffsite)`), cancel,
> a limit bounded by the store's snapshot count (ceiling 500). Every grant/cancel is a STORED operator-only info event
> `offsite_window_grant` — 0.174.0 only called the dispatcher (which writes no row) and its test asserted the call; the
> operator's live click exposed it, 0.174.1 writes the row (`store.SaveEvent`) and the test reads rows. Hub builds came
> from a clean clone (`FELHOM_HUB_REPO_DIR`) — the shared clone held another session's uncommitted installer edit.
> Start-up 31–36 s vs a liveness kill at ~65 s: R-1326. `sec rm NAME` (cc-secrets `dc82cf9`); 46 dead names removed on
> the operator's yes (92 → 46). Agent 0.167.0 vouched by the operator; `pinned.day0_agent` = 0.167.0 (agent `3055bc5`).
> **2026-10-27 (attended release block) — RELEASED: hub v0.173.0, agent v0.167.0, controller v0.346.0.** Hub 0.173.0
> deployed 09:35 CET (image `sha256:458bfb03…`, from `29134c52`, ArgoCD sync of Deployment/hub only, 30-min watch clean).
> Agent 0.167.0 by `release-agent.sh` from a clean clone (agent `28bdd282…`, bundle `9d034416…`; tag `v0.167.0`), signed
> `agent_update` to the three test boxes (configs/ unchanged → no bundle job); **NOT vouched yet** — after the vouch set
> `pinned.day0_agent` in `felhom-agent/scripts/retention-policy.json` (D50). Controller 0.346.0 from `b1b9be3` (image
> `sha256:3d910b03…`, CI 2423): per-box floors 15:09 CET, box walk green, held-apps lists match (0 = 0), global floor
> 15:37 CET (MinAgent 0.158.1). **R-1250 fixed the same day (`09` §3 decision 269):** the hold failed four times
> („not quiet" — qBittorrent sends ~14 s after its limit falls; the agent reads 5–15 s after the call); `710ceac`
> `upwatch.waitDrained` asks only after the held app reports its own upload near zero; live on `0.346.0-rc.1` on 9201:
> 94.5 Mbit/s, the limit back exactly (`audits/linetest-2026-10-27/`). **R-1218's live proof waived (decision 270):** the
> hub page's off-site switch did not reach Tester 1's saved target (R-1312). demo-hp's slot is minute 95 (11:35 CET),
> Tester 1's 213, demo-felhom's 20 — each host's own. D55's window ran 03:18Z: 223 removed, 373 → 150. R-1174 closed
> (the status gate refuses since today). Closed 11 rows; opened R-1312.
> **2026-10-26 night (alone) — the data-safety fixes, on `main`, NOT released.** Controller: R-1220 `7e15a37`
> (`liveDriveBinds(drives)`: an unreadable app.yaml = installed), R-1218/R-1219 `1170b48` (stage when the password FILE
> exists; no ceremony during a recovery offer), R-1187 `dfd0f8e`…`90a2530` (.fab: links as links, FIFO refused, `os.Root`
> writes, downward-only links, owners/modes, busy and bad-path refusals; the import's compose gets `USERDATA_PATH`/
> `IMPORT_PATH`; the DB loads through `appbackup.ImportDump` — the import's `mysqladmin`/`mysql` broke every MariaDB 11+
> import), R-1298 `b156e45`, Go 1.27.3 `2560cf1`. Agent: R-1232 `3911cc6` (own-key archives only in the due-check),
> Go 1.27.3 `fbbb168`. Hub: R-1218 `09b5f02f` (409 on a key-less package over a keyed one), Go 1.27.3 `d625a143`.
> Live: `audits/night-fixes-2026-10-26/` (R-1220, R-1187, R-1298 on 9202 with local test images; R-1232 on a BYO Tester4
> VM, uninstalled and destroyed). R-1218's live shape needs the operator (off-site off on Tester 1) — else reverted
> before the release. R-528: design in the row, not built. New: R-1299, R-1302.
> **2026-10-26 (night) — D55 = 260 (`09` §3 decision 268); the grant is SET.** CC used the operator's one-purpose token
> `HUB_TOKEN_D55_WINDOW` („cc-d55-window", Off-site write only) once: `POST /offsite/window-grant/demo-hp` `max_remove=260`
> → 200, 19:10:31Z; read back `offsite_window_grant:demo-hp = max:260` (hub DB with WAL) and the hub log line „granted ONE
> clean-up window … 260". The grant is consumed at demo-hp's next window request (after its next nightly off-site run).
> The token is the operator's to revoke after that. The hub has no page button for the grant (R-1299).
> **2026-10-26 (evening run) — R-1297 A built (`ecd82aba`, `e33ec821`); D53 built, commit only (controller `5bd03ad`, hub
> `7e57e824`); D54 blocked on a scope.** CI: `script_tests_gate.py` `PATH_FILTERED` (decoys / due-checks / dooplex-offsite
> run on a branch push only when their paths change; `FELHOM_CHANGED_FILES` set only for `push:refs/heads/*` in
> `gates.yml`; nightly 03:20 UTC + tags run all); `test_repo_gates.py` / due-checks group G narrow `repo_gates.GATES` by
> label (the wiring, not a second full run). The decoy suite's register-shape cases now assert the script's exit code
> (an inert `main()` passed them). D53: `internal/holdreport` (controller) → `app_held` / `app_hold_cleared` (info) →
> hub `held_apps` + `HeldAppsChecker` (`app_held_reminder`, operator-only, per-app cooldown; grace 6 h / 1 d / 3 d, then
> weekly; `alerting.held_app_grace_override` test-only). Live on 9202 against a TEST hub process (no hub deploy):
> `audits/d53-held-apps-2026-10-26/`. D54: CC's hub token lacks `offsite:write` (403) — STATUS D55 (the cap: the plan
> grows ~14 a night, 220 would be refused). New R-1298 (9202's orphan holds would be reminded weekly after D53 ships).
> **2026-10-26 (evening) — operator rulings by starting the evening brief: D53 = operator-only held-app reminders first
> (`09` §3 decision 265; build `08` §10); D54 = one clean-up window for demo-hp with cap 220 through the hub's one-shot
> grant `POST /offsite/window-grant/<customer>` (decision 266; the cap rule unchanged); R-1297 (B) DONE by the operator — a
> second CI runner, both runners 2 CPUs (decision 267). CI trim (R-1297 A) is CC's: every removed run keeps a path filter,
> a tag run or a nightly run.
> **2026-10-26 (afternoon run) — R-1295 fixed at the cause and released; R-1292 released; R-1294 read; R-1285 committed;
> R-1291 designed.** R-1295's cause, measured on a throwaway PBS 4.2.5: the PBS proxy caches permissions up to 5 s and an
> ACL-only change does not clear it, so under concurrent requests a new token is refused for ~5 s (v1.3.0 11/30 failed,
> v1.4.0 0/30). Fixed: felhom-tenantsync v1.4.0 INSTALLED on ep0 (operator yes), hub v0.172.0 RELEASED (retry + operator
> mail `pbsdr_provision_failed`); live: a fresh Tester4 install made its first whole-guest copy. Controller v0.345.0
> RELEASED (global floor 13:27:04Z): the 50 % rule owns qBittorrent's NORMAL slot (live on Tester 1). R-1294: demo-hp's
> plan is honest but can never catch up with the cap (D54). R-1285: agent `b1bc63d`, the pass after the commit, not
> released (live needs a box from 0.164.0). R-1291: `08` §10 design (D53). New R-1296, R-1297 (CI speed: operator „both").
> **2026-10-26 (attended release run) — released: hub 0.171.0, agent 0.166.0 (vouched 10:04:55 CET), controller 0.344.0
> (global floor 09:07:47 UTC, MinAgent 0.158.1), catalog `73c165d`; golden 0.344.0 baked and vouched (10:26:23 CET).**
> Live on the release builds (`audits/release-monday-2026-10-26/`): R-1287 (the set-aside mails „⚠️ … nothing failed"),
> R-1289 (the vouch line names 0.344.0), R-1280 (a 25 h job REJECTED on demo-hp, a 30 min one ran), R-1281 (forged header
> 000 with a working control; the household's files 200; OnlyOffice fetches the document over `felhom-files`), R-1282,
> R-1278, R-1286, R-1283 — closed. **R-1285 back to OPEN:** in the normal two-job delivery the bundle runs in the OLD
> agent process, so the policy pass waits for the next bundle. R-1261 stays VERIFY until Tuesday's live line test (R-1250).
> New: R-1294 (demo-hp's weekly off-site clean-up refused by its own cap, 209 > 179). The golden waiver file is removed —
> the gate is green on the new golden alone. D50 pin `day0_agent` → 0.166.0.
> **2026-10-26 (attended release run) — D51 = Start; D52 = bake the golden today on v0.344.0.** (`09` §3 decisions 263,
> 264.) D51: the operator pressed Start on demo-hp's Kimai (07:57 local); the crash-loop hold lifted, both containers
> healthy, 0 restarts (R-1286). D52: the Sunday 2026-10-25 bake was missed (not in that night's brief); the golden waiver
> is renewed for 2026-10-26 only (`expires: 2026-10-27`) so the release commits can be pushed; the golden is baked on
> v0.344.0 the same day and the waiver is removed after the vouch. The weekly Sunday bake stays the rule; every
> Sunday-night brief names it.
> **2026-10-25 night (unattended, commit only) — the night's fixes, each red-proved; proven live on a BYO test VM (demo-hp
> VM 9372, customer Tester4, agent 0.165.0, controller rc.1–rc.3).** Controller (`a79a292`…`7ea942a`, rides v0.344.0):
> R-1261 the line hold holds EVERY running seeder, drops a removed app's record, names qBittorrent's slot (`up_limit` /
> `alt_up_limit` via `app/preferences` — `transfer/uploadLimit` follows the current speed mode, measured); R-1288 the
> restore of a set-aside unit sets the replaced unit aside AT the restore, no alarm (the brief's safest reading, `07`
> §8.2d changed); R-1282 the „later" media restart stored and resumed; R-1281 FileBrowser served on its own
> `felhom-files` network (traefik + OnlyOffice while linked), off traefik-public — the forged header from an app went
> 200 → no answer; R-1286 every hold reason says what it is (Kimai's was a crash-loop stop, not a failed restore). Hub
> (`f6328486`, v0.171.0): R-1287 a set-aside-only digest is a warning „nothing failed"; R-1289 suffixed versions never
> „the fleet's newest". Agent (`d912307`, `abcc1e6`, next agent release + vouch): R-1280 a signed window ≤ 24 h; R-1285
> the agent runs the wrapper's `bundle-policy` pass after every bundle install. Drill catalog `6733764`: R-1283 MeTube
> `optional` (a named ruling in the download-binds gate). New rows R-1291 (a held app has no lasting signal), R-1292
> (the 50 % rule follows the speed mode).
> **2026-10-25 (evening, attended) — D50 = A; installer 1.36.1 published.** (`09` §3 decision 262.) The registry keeps the
> newest 5 agent versions + the MinAgent floor + the day-0 agent; the agent CI asserts exactly these
> (`retention-policy.json` `pinned`, copied from hub state by the vouching session — CI holds no hub secret). The operator
> also pruned controller, golden and hub images by hand; every artifact still named (manifest agent/bundle/golden, the
> floor agent, tags v0.158.1+, controller 0.343.0/0.342.0/0.331.0, samba 1.2.0, the ISO) downloads
> (`audits/night-2026-10-25/part1-artifacts.txt`). Installer 1.36.1 (`installer-v1.36.1` → `79ee3e33`, served sha256
> `e18cdd17…`): the preflight words 401/404/409 again (R-1284).
> **2026-10-25 (attended release run) — D49 = A, D44/D45 = all picks, D46 = yes; released: hub 0.170.0, agent 0.165.0,
> controller 0.343.0, catalog `ebbf1f4`** (`09` §3 decisions 258–261; `REPORT-release-2026-10-26.md`). **D49 = A:** a
> restore whose app does not start keeps both copies and never pours back by itself (`07` §8.2e). **Fix A** (controller
+72
View File
@@ -0,0 +1,72 @@
# REPORT — 2026-10-26 afternoon: R-1295 fixed at the cause, R-1294 read, R-1285 / R-1292, R-1291 designed, releases
**Plain words first.**
1. **R-1295 cause:** PBS's proxy keeps permissions in a 5-second cache, and a new access key's grant does not clear it.
When other boxes are talking to ep0 at that moment, the new key is refused for a few seconds, and the old script
gave up after one quick retry. **Fixed at the cause on ep0** (the script now waits up to 15 s) **and in the hub**
(retries, and **a failure now mails you** — yes). Live: a fresh Tester4 install set up its whole-box off-site copy.
2. **Tester 2's reinstall is safe** from this failure: the fix is on ep0 and in the hub, and if anything still fails you
get a mail that says what to do.
3. **R-1294:** demo-hp's clean-up plan is **honest** (old copies only, every app keeps its copies), but it can never get
back under the safety cap by itself. **Your pick D54:** a one-time window with a raised cap (my pick).
4. **R-1292 fixed and released; R-1285 fixed, not released** (its live proof needs a box coming from 0.164.0).
5. **Released:** hub 0.172.0, controller 0.345.0 (every live box), felhom-tenantsync v1.4.0 on ep0. Not released: agent.
Safest readings taken alone (said first): R-1292's live test ran on Tester 1, not 9202 (9202 has no tested line, so the
rule never acts there); R-1285 has no live test today (a box coming from 0.164.0 needs a signed downgrade chain); the
fresh-install proof ran after the hub rc deploy, both on your yes.
## Each fix, before → after
- **R-1295 (hub v0.172.0 + tenantsync v1.4.0):** a new access key refused by the PBS cache → rolled back, no off-site copy,
only a log line → the script waits up to 15 s (the admin key too); the hub retries 3×, 7 s apart; a final failure mails
you („… could not be set up — save the customer config to retry"). Measured 11/30 → 0/30 under load; red-proved.
- **R-1292 (controller v0.345.0):** with alternative speed on, the 50 % rule changed the alternative limit or gave up →
it sets only the normal limit. Live on Tester 1; red-proved.
- **R-1285 (agent `b1bc63d`, not released):** the old agent installed the bundle, so the new policy pass waited a release
→ the new agent runs it once after its update commits. Tested in the real order; red-proved.
- **R-1294 (read only):** no change; D54.
- **R-1291 (design only):** `08` §10; D53.
## Versions, CI by commit
| What | Version / digest | Commit → CI |
|---|---|---|
| hub | 0.172.0, `sha256:7c8d129a…` (rc.1 `f6cb8f57…` for the proof) | `722013da` 2362 ✓, `232f42d2` 2366 ✓; manifests `ee38dee2` 2364 ✓ |
| ep0 | felhom-tenantsync v1.4.0, sha256 `751b3c26…` (v1.3.0 kept beside it) | `722013da` |
| controller | 0.345.0, `sha256:2dc2c0a5…` (rc.1 `1378e4e2…`) | `2619191` 2365 ✓, `6bfb784` 2368 ✓ |
| agent | — (not released) | `b1bc63d` 2363 ✓ |
Global floor 0.345.0 at 13:27:04Z (MinAgent 0.158.1), read back from the hub DB with its WAL and the hub log; the
per-box floors cleared. Every live box reports 0.345.0.
## Rows
Before **212**, after **212**; opened **2** (R-1296 the hub drops ep0's refusal reason; R-1297 CI speed — your „both"),
closed **2** (R-1295, R-1292). R-1285 VERIFY; R-1294 and R-1291 wait for D54 / D53.
## Observations
- FILED: R-1296 — PBS's real refusal reason never reaches the hub log (found only by reading ep0's journal).
- FILED: R-1297 — felhom.eu CI ~13 min, one runner; ruled „both".
- NOT-A-FINDING: the `backup_tier_skipped` 6 min after the fresh install — before the box applied its descriptor; the hub
held the mail by design (box enrolled < 1 h); 15 min later the box took its key and made its first copy.
- NOT-A-FINDING: 9202's FileBrowser WARN on the move from 0.343.0 (twice now) — healed in 3 s, log only, every live box is
past that move.
- NOT-A-FINDING: R-1292 run 1 „FAIL" — my probe's quoting broke its reads (kept as evidence); run 2 with a fail-fast
instrument check passed.
- My mistake, fixed: removing Tester 1's test record the first time raced a path unit that restarted the controller; the
second time I stopped the path unit first.
## Teardown
- **Machines:** VM 9373 (the R-1295 fresh install) and LXC 9374 (the throwaway PBS) destroyed with their disks; Tester 1's
two throwaway qBittorrents removed through the product, its rule record removed (it had none before), helper files
gone; 9202 back on 0.343.0 exactly as found (FileBrowser on `traefik-public`, no `felhom-files` network, the rc image
deleted — 9202 is not bound to the hub, so no floor moves it). Nothing of mine runs on demo-hp into Tuesday 10:00.
- **Product uninstall of VM 9373: not run** — tried root SSH with the original password (refused: day-0 replaced it with
the vaulted one) and DooPlex's key (never installed); the vault read is yours. The VM was destroyed instead.
- **Hub:** delete host `Tester4-b5ec39` (STATUS). Its first whole-guest copy stays in Tester4's ep0 namespace (a host
delete keeps the tenancy, by design).
- **ep0:** only the script swap you approved; v1.3.0 kept as `/usr/local/bin/felhom-tenantsync.v1.3.0`.
- **Secrets:** evidence scanned (the sec values + the bind token and pairing code): 0 hits.
+76
View File
@@ -0,0 +1,76 @@
# REPORT — cloudflared 2026.10.3 on every box (R-1300), 2026-10-26 evening, attended
> A sibling of `REPORT.md`: the night session (`TASK-night-burndown-and-tuesday-2026-10-26.md`) owns `REPORT.md`
> tonight.
## In plain words
1. **We run 3 cloudflared, one in each box's guest** (Tester 1, demo-hp, demo-felhom). None on DooPlex. Tester4 has no
tunnel; Tester 2 has no box.
2. **The https-origin trap does not apply.** Each tunnel sends to `https://traefik` with „No TLS Verify" on, and traefik
shows its own self-signed certificate — not an eMudhra one.
3. **0.345.1 is on every box: 4 of 4 reporting controllers** (the three above + Tester4); none left behind.
4. **Longest tunnel gap: about 11 seconds** (demo-hp). Tester 1 about 2 s, demo-felhom about 4 s.
Decisions: the operator said yes to the build-gate exception (build from a pushed tag) and to the global floor.
## Versions, digests, CI
| What | Value |
|---|---|
| controller tag `v0.345.1` | commit `f3204024` = v0.345.0 `6bfb784` + one commit; CI job 2393 success (attempt 1) |
| controller `main` | `a1c65b3d` (same bump + `build.sh` tag path); CI job 2392 success (attempt 1) |
| controller image `0.345.1` / `:latest` | `sha256:7cfdf7e1f835628de9c7d536e0a60c06bad5bbe19e8133765cc0a6bb732dbff6` |
| cloudflared | `cloudflare/cloudflared:2026.10.3`, index `sha256:faa8e0a1475f137c910be6025f43c8e4092fdd35461b31e19fd1390657a1ff39` |
| MinAgent | 0.158.1 (unchanged, declared with the floor) |
| global floor | 0.345.1 at 20:08:39Z (`303 floor_set`; read back from the running hub: „Effective floor: v0.345.1 — source: DB") |
| per-box floors | set 20:05:08Z (Tester 1), 20:06:04Z (demo-hp, demo-felhom); cleared 20:39:54Z |
Tests and gates: controller gates `--fast` green on both commits; `go test ./...` green on the tag commit; the new
reconcile test and the four build-gate cases red-proved. felhom.eu gates green on push. **Methods:** box state by
`docker ps`/`docker logs` in each guest; tunnel state by the hub's Hosts page and by a public name with no app
(`cfprobe.<domain>`: 404 = tunnel up, 530 = down), probed every 0.5–1 s from DooPlex.
## Register
Rows before **213**, after **214**, opened **2** (R-1300, R-1301), closed **1** (R-1300).
## Observations
- The N100 host's clock is 14 s slow; chrony fails at every boot — **FILED: R-1301** (and `lived-in/n100.md`).
- I put a test run and a commit in one command on the detached tag clone (standing rule 1). The commit was local; the
test result was then read on its own (green) before anything was pushed — **NOT-A-FINDING: my slip, caught before
push, recorded here.**
- `noTLSVerify` on every tunnel route (R-510) — **NOT-A-FINDING: a leg that never leaves the guest** (cloudflared and
traefik alone on the /29 tunnel network); now written in `01` as a recorded exception, with the rule „never turn off
a certificate check to make an update work".
- cloudflared 2026.10.4 (today, VULN-176088: metrics debug endpoints allowlist) — **NOT-A-FINDING: our metrics bind to
the container's own loopback**; not taken because it is under a day old and the notice names 2026.10.3.
- 0.345.1 is built with 0.345.0's Go builder; `main` moved to Go 1.27.3 tonight (R-972) — **NOT-A-FINDING: R-972 owns
it; the next release from `main` carries it.**
- Single-sample `000` answers at 20:13:37 (both Tester 1 probes at once) and 20:17:13 (demo-hp) — **NOT-A-FINDING: a
client-side timeout, no 530; the hub and the boxes showed the tunnel up throughout.**
- `internal/stacks` tests took 450 s under the night session's load (each R-442 remove test 26 s) — **NOT-A-FINDING: CI
green; slow only under load.**
- Tester4's agent reads `0.167.0-night1 floor held` on the Hosts page — the night session's agent; not touched.
## What changed in documents
- `architecture/01-topology-and-trust.md` „Tunnel placement": the version, the rule, the recorded exception.
- `architecture/11-os-updates.md` C8: the new pin.
- `STATUS.md`: one line (released; `main` and Sunday's golden carry it). The golden 0.344.0 still has 2026.9.3; a new
box moves to the floor in its first minutes. No extra bake (operator did not ask).
- System poster: none of the three needed — no fact on the poster changed (cloudflared still runs in the guest).
- Controller: `build.sh` may push from the pushed tag `v<VERSION>` (operator's yes). Controller report:
`felhom-controller/REPORT-cloudflared-0.345.1.md`.
## For the operator
- **Nothing to do.** If you want a second look: Cloudflare dashboard → Networking → Tunnels shows each connector's
version (CC holds no Cloudflare token).
## Teardown
Machine: the image pulled on scratch guest 9202 for the version check was removed. Host: nothing. Hub: the three
per-box floors cleared; the global floor stays at 0.345.1 by design. Clones `felhom-controller-sec`,
`felhom-controller-mainsec` and `felhom.eu-cfsec` on DooPlex are my work copies (all pushed); removed at the end.
+162
View File
@@ -0,0 +1,162 @@
# REPORT — 2026-10-28 (from midday, attended at the STOPs): the watch and Docker Hub; the four big security updates
Architecture read: `08-alarm-ladder.md` §11 (the watch); `09-update-architecture.md` §3 (decisions 255, 274, 275) and
§6.4 (the ladder); the catalog's `CLAUDE.md` (the test record) and its move gates.
## In plain words
1. **Why Docker Hub refused the watch:** speed, not volume. The night run asked 211 times in about 2 minutes from six
workers and got 15 refusals. Now the requests are spaced, and a refusal is retried. **No Docker Hub login was needed.**
2. **One CI night with 0 refusals:** not yet. Two daytime test runs had 0 refusals. Tonight's 03:40 run is the check
(R-1334 stays open until then).
3. **The four apps — all live, each a normal ladder step** (bench + box + undo proven):
- Wanderer v0.21.2
- Termix 26.10.5 (two steps: 2.8.0 → 2.9.2 → 26.10.5)
- Homepage v2.7.0
- Seerr v3.5.1 (a definition step: new image name, new start command)
4. **Wanderer is offered again: yes** (your word; D59 ended). Federation from other servers stays off (your word).
5. **What you do:** nothing today. Tomorrow morning I check that the night run had 0 Docker Hub refusals and then
close R-1334.
## Decisions (yours, at the STOPs)
- **Pushed, one STOP each:** Wanderer, Termix, Homepage, Seerr.
- **Wanderer offered again**, and **its inbound federation stays off** (`09` §3 decision 279).
- **The Docker Hub key was not asked for.** The fix without a login measured clean.
## Part 1 — R-1334 (evidence: `documentation/audits/dockerhub-bigsteps-2026-10-28/part1/`)
**The cause, measured.** Docker Hub's tag-list API (`hub.docker.com`) refused requests that came in a burst:
| Run | Requests | Time | Refused |
|---|---|---|---|
| Night 2446 | 211 | ~2 min | 15 |
| Dry 2450 | 224 | ~3.5 min | 0 |
No scheduled job on DooPlex calls Docker Hub at that hour (k3s cron jobs and CI schedules, read only: Renovate runs
on Saturdays; the others are Longhorn backups and Postgres dumps). Other traffic from the same address was not measured.
**The fix.**
- `fe677bae`:
- Docker Hub requests are spaced: one per second across the workers.
- A 429 is retried after its `Retry-After`. The image is NOT CHECKED only after the 4th try.
- Tag lists are kept for 24 hours per registry path, on the CI runner. Two names of one image fetch once.
- Test W14: 7 checks, red first.
- `8644450d`: the image reader also retries a registry 429. ghcr.io had refused two blob reads when two dry runs came
15 minutes apart. Its retry checks were red first.
**Measured after.** Dry runs 2458 and 2459:
- 0 Docker Hub 429s and 0 retries. 210 requests over about 7 minutes.
- The only NOT CHECKED images are 6 private DooPlex ones (by design) and `minio/minio:latest`, which Docker Hub no
longer serves (noted on R-1328 for the homelab session).
- The two CI runners each keep their own tag cache. So the cache helps a re-run on the same runner. The spacing is
what fixes the night.
## Part 2 — the four big steps (evidence: `documentation/audits/dockerhub-bigsteps-2026-10-28/<app>/`)
**The path, by the rules.** No box runs any of the four apps (checked on all three boxes and on 9202). There is still
no pin move without a step: the catalog's test record and its move gates require it. `09` did not say so, so it now
has a `[DESIGN]` note. So each app is a normal ladder step. In every case below the undo was proven on 9202: the new
version, with its checks broken on purpose, ended `undone`, and the data read back on the old version.
### Wanderer v0.20.0 → v0.21.2 — catalog `1825247`
- **Template, changed at v0.20.0 first:**
- PocketBase is internal (no public address, no database-subdomain question at install). Upstream says the db must
not be reachable from outside.
- The sign-up lock now also covers `PUT /api/v1/user`. v0.20.0 already had that route, and the old lock missed it.
- No `POCKETBASE_PROXY_SECRET`, so inbound federation is rejected. There is no federation switch, and this is the
only way to close it.
- **Fixture:** a user and a private list.
- **Proof:**
- Bench: `proven`.
- Box 9202: update in 78 s.
- Undo: back to v0.20.0 in 28 s.
- **Memory:** Meilisearch fills whatever limit it gets: 256 → 384 MB, still 88.8 %. That is filed as R-1338.
### Termix 2.8.0 → 2.9.2 → 26.10.5 — catalog `e0b9594`, `589c957`
- **Two pushes**, because 2.9 must start once before 26.x.
- **Fixture:** the existing one.
- **Proof, per hop:** bench, box and undo all proven.
- **D58, measured on 9202.** Seven wrong logins, each with a different forged `X-Forwarded-For`:
- **From the LAN:** Traefik replaces the header. The 6th try got HTTP 429 on 2.8.0, 2.9.2 and 26.10.5.
- **Through the tunnel's own address** (a test container at cloudflared's address, with the chain Cloudflare
delivers): the 6th try got 429 on all three.
- So the bypass was not reachable on our boxes, before the update either. 26.10.5 adds the app's own guard
(`trust proxy: loopback`).
- **A loopback-only login route in 26.10.5:** off in our image. `NODE_ENV=production`, and nginx sets `X-Real-IP` on
every request.
### Homepage v1.13.2 → v2.7.0 — catalog `1a254d4`
- **Fixture:** a new one. It reads the dashboard's own services and bookmarks (written at first start) and plants
nothing.
- **Proof:** bench, box and undo all proven. The family gate still answers 302.
### Seerr: Jellyseerr 2.7.3 → Seerr v3.5.1 — catalog `9ef06a7`
- **A definition step:**
- The new image, plus `init: true`.
- The container starts as root only to hand `/app/config` to UID 1000. Then it runs Seerr as `node` (smoke-tested
first).
- **Fixture:** a new one. It brings a throwaway Jellyfin for Seerr's first sign-in and stores an application title.
- **Proof:**
- Bench: `proven`. Its bare abort loses the seed on the converted data, as Jellyfin did yesterday.
- Box 9202: `proven`.
- Undo: Seerr ran its migration, failed its check, and the box's undo copy brought the data back.
**Tools added in the catalog.**
- `box_walk.py --to-definition`, with 8 checks in `test_box_walk_drill_move.py`.
- The Wanderer, Homepage and Seerr fixtures.
- The bench's Wanderer override was removed, because the template does it now.
- The undo tool: `audits/dockerhub-bigsteps-2026-10-28/undo_proof2.py`. Its broken probe now uses port 1, because a
single-page app answers 200 on any path.
## Commits and CI (all green by hash)
| Repo | Commit | What | CI job |
|---|---|---|---|
| felhom.eu | `fe677bae` | Docker Hub spacing, retry, tag cache | gates 2457; dry runs 2458 and 2459 |
| felhom.eu | `8644450d`, `3c0a33c1` | image-reader retry; evidence | 2460 |
| catalog | `1825247` | Wanderer | 2461 |
| catalog | `e0b9594` | Termix hop 1 | 2462 |
| catalog | `589c957` | Termix hop 2 | 2463 |
| catalog | `1a254d4` | Homepage | 2464 |
| catalog | `9ef06a7` | Seerr | 2467 |
| felhom.eu | this close-out | docs, register, evidence | in the final check |
## Register — 229 before, 226 after
| Opened (1) | Closed (4) |
|---|---|
| R-1338 — Meilisearch memory | R-1335 — Wanderer |
| | R-1311 — Termix |
| | R-1320 — Homepage |
| | R-1317 — Seerr |
R-1334 is VERIFY; it closes after tonight. R-1328 has a note added (minio).
## Observations
| Observation | Result |
|---|---|
| Meilisearch fills its memory limit | FILED: R-1338 |
| `minio/minio:latest` gives 401 on Docker Hub | FILED: noted on R-1328 (the homelab list) |
| Three security-review notices: „image downgrade" in the drill | NOT-A-FINDING: the drill is the test copy and must stand at FROM before a walk; the live catalog is at the new versions |
| The update accepts a container whose Docker check is still „starting" | NOT-A-FINDING: by design the declared probe decides (`09` §3); the undo tool now breaks the probe on port 1 |
| `test-record-move` judges a whole push as one move, so two hops refused together | NOT-A-FINDING: the rule works as built; Termix went out as two pushes |
| The `memory_tight` mark needs a raised limit and a new measurement | NOT-A-FINDING: the gate did its job; done for Wanderer |
| The Termix header test, first try: no gate cookie, and the shell expanded `$x` too early | NOT-A-FINDING: my test tool; fixed and re-run, and every try is kept |
| The Termix header test with a forged-only chain skipped the limit on every version | NOT-A-FINDING: Cloudflare always appends the real address; with the real chain every version locks |
| Termix 2.9.2's route dropped for a while right after the first install (502, then 404) | NOT-A-FINDING: the test now waits for health; 2.9.2 is only a stop on the way to 26.10.5 |
| Termix 26.10.5's loopback auto-login route | NOT-A-FINDING: off in production, and nginx sets `X-Real-IP` |
| Secret scan of the evidence found `"password": "wrong-"` | NOT-A-FINDING: the deliberately wrong test password, a code literal |
## Teardown
- **Machine:** 9202 is on the LIVE catalog (`repoint-9202-live.txt`, cache `9ef06a7`). It runs only its standing apps.
Every test app was removed through the product. The throwaway Jellyfin containers were removed on the bench and
on 9202.
- **Bench:** 9401 is stopped, with 0 containers.
- **Host and hub:** nothing provisioned, no change.
+49
View File
@@ -0,0 +1,49 @@
# REPORT — installer 1.36.1 published; the night's fixes (2026-10-25 evening → 2026-10-26 morning)
**Plain words first.**
1. **Every package that is still named is there.** You pruned old controller, agent and golden packages by hand; nothing a
box or the installer can still ask for is missing (the agent 0.165.0 + bundle, the 0.158.1 floor agent, golden
0.331.0, the agent tags from 0.158.1 up, controller 0.343.0 / 0.342.0 / 0.331.0, samba 1.2.0, the ISO).
2. **Installer 1.36.1 is live, and its three messages were seen:** a wrong customer → „not found (404)", a wrong
passphrase → „passphrase REJECTED (401)", a customer whose box is live → „already has a live box (409)" (R-1167's
sentence, which could never show before).
3. **The agent CI is green with D50 = A** (the newest 5 versions + the MinAgent floor + the day-0 agent).
4. **R-1261 is fixed and proven before Tuesday** — on a test VM with two seeders: both held, 94.8 Mbit/s measured, both
limits back; a speed-mode switch mid-test never left 1 KiB/s. It reaches households with Monday's controller release.
5. **You decide:** Kimai on demo-hp — press Start, or remove it (STATUS, D51). And the Monday release list (STATUS).
## Each fix, before → after
- **R-1261 (controller `a79a292`):** one seeder held, a removed app's record kept forever, qBittorrent's limit put back
in whatever slot its mode showed → every seeder held, the record dropped, the held slot named. Live on the rig.
- **R-1287 (hub `f6328486`, v0.171.0):** a set-aside mailed „🔴 1 of 1 apps failed to back up" → „⚠️ … a backup of an
earlier install was set aside — nothing failed", a warning. Test on the real dispatch path.
- **R-1288 (controller `b5863a9`):** a set-aside restore's replaced unit was set aside at the NEXT backup, with a second
alarm → set aside at the restore, no alarm. Live on the rig (one set-aside mail only).
- **R-1281 (controller `7ea942a`):** an app container signed in to FileBrowser with a forged header (200) → no answer;
the household's file manager still 200; a FileBrowser left on traefik-public is moved off by the next round. Live.
- **R-1289 (hub `f6328486`):** a dev build no box ran was „the fleet's newest" → test builds never count.
- **R-1282 (controller `b5863a9`):** the 03:30 media restart was forgotten by a controller restart → stored, resumed once.
- **R-1280 (agent `d912307`):** a signed window of any length → at most 24 h (verifier, root wrapper, felhom-opsign).
- **R-1285 (agent `abcc1e6`):** a BYO host lost our SSH file one update late → the agent runs the new wrapper's policy
pass after every bundle install.
- **R-1283 (drill catalog `6733764`):** MeTube's downloads `excluded` → `optional` (a named ruling in the gate).
- **R-1286 (controller `838c834`):** Kimai's crash-loop hold read „a failed restore whose rollback also failed" → every
hold reason says what it is. The cause: the crash-loop guard during the 10-14 power drill.
## Teardown — three layers
- **Machine (rig VM 9372 on demo-hp):** the product's own `--uninstall` ran first (rc 0, „UNINSTALL complete — removed:
guest 9201, the felhom-agent …", `audits/night-2026-10-25/rig/uninstall-console.txt`); the host journal was copied off
before (`rig/rig-host-journal.txt`). Then `qm destroy 9372 --purge 1`: `qm list` shows no 9372, its folder on
`nvme-scratch` is gone, the plain-PVE ISO is removed from demo-hp, the ISO work folder on DooPlex is removed, the old
host key is removed from `known_hosts`.
- **Host (demo-hp):** guest 9202's test tracker, downloader container, test files and image are removed (0 containers,
0 files, port 6969 closed). `nvme-scratch` is a standing storage (it holds 341, 9202, 9401) — this session did not add
it, so it stays. `local-lvm` (the thin pool) was never used: 48 %.
- **Hub:** host `Tester4-84bbe7` stays on the Hosts page — a host delete is the operator's (STATUS, „Also Monday"). The
R-1285 test package was deleted from the registry (204, then 404).
- **Secrets:** the scratch session, CSRF and header files, the dashboard password file, the rig root password file, the
test bundle and the test agent build are shredded. The evidence was scanned against the four known values (through
`sec`) and four token shapes: 0 hits (one shape hit is code that reads a file). The `sec` entries
`RIG_2026_10_25_DASH_PW` and `RIG_2026_10_25_SETUP_CODE` remain; `sec` has no delete, and the box they opened is gone.
+70
View File
@@ -0,0 +1,70 @@
# REPORT — 2026-10-26 night → 2026-10-27 afternoon: the night's fixes, the line test, one release block
**Safest reading taken alone:** none needed today — every release step had the operator's yes in the session.
## Plain words first
1. **The night's fixes:** all released today. Proven live: kept data (R-1220), the reinstalled box's off-site tier
(R-1232), app-file export/import (R-1187 a, b, g), held-app reports (R-1298, D53). Not live: R-1219 (handler test, as
the brief allowed) and R-1218 (the operator waived its live proof — no product path reaches the case on a hub box).
2. **The line test:** ran — but only after a same-day fix. As built, the hold was refused four times (qBittorrent keeps
sending ~14 s after it is slowed). With the fix: **94.5 Mbit/s**, the seeder's own limit back **exactly**.
3. **Released:** hub 0.173.0, agent 0.167.0 (not vouched yet), controller 0.346.0 (global floor 15:37 CET).
4. **D55 grant seen:** yes — the window ran 03:18 UTC, 223 of 223 removed (373 → 150), no alarm.
5. **The operator still does:** vouch agent 0.167.0; revoke the token `cc-d55-window`; delete hub host
`Tester4-b5dbbd`.
## Versions, digests, CI by commit
| | Version | Image / sha256 | From | CI |
|---|---|---|---|---|
| hub | 0.173.0 | `sha256:458bfb03e614db4b7abd6442e6af15c652ba4b9b4509fe2b0efe00ac979b8f52` | `29134c52` (manifest `bbc3acb8`) | 2418, 2419 ✓ |
| agent | 0.167.0 | agent `28bdd2826f45f3767880fcff4d3105afb7247c09c0ced99d78b3a978d8d826f0`, bundle `9d0344164b22634159984bfbcdaf77c53e6d2423812973ed8b4f2135a7ed1268` | `54d3a10` (tag `v0.167.0`) | 2400, 2420 ✓ |
| controller | 0.346.0 | `sha256:3d910b039fc52f08366c657774d9664320d6913fdebdd3deb2bbbb01d7eb9dd3` | `b1b9be3` (fix `710ceac`) | 2421, 2423 ✓ |
| controller rc | 0.346.0-rc.1 | `sha256:bfa091e9…` | `710ceac` | 2421 ✓ |
## Each fix, before → after
- **R-1250** (`710ceac`): four holds refused „not quiet" (4.0–4.2 Mbit/s) → held, slowed after 22 s, 94.5 Mbit/s, limit
5898240 back exactly; the 50 % rule kept the normal slot (0.15 % move). `audits/linetest-2026-10-27/`.
- **R-1232**: `due:false` (a foreign archive counted) → `due:true / absent`, first whole-box copy at once (night).
- **R-1220 / R-1187 / R-1298**: see `audits/night-fixes-2026-10-26/`.
- **R-1218** hub: a key-less upload over a keyed package → 409 (red-proved); controller: stage when the FILE exists
(red-proved). Live proof waived (`09` §3 decision 270).
- **R-1285**: the bundle pass now runs right after the commit in the normal delivery (all three boxes) — the BYO removal
itself is still unproven (stays VERIFY).
- **R-1174** (dated check): the status gate refuses since today — a hand run convicted a copy, rc 1.
## Release steps
Hub: yes 09:30 CET → build, manifest, sync of Deployment/hub only, Synced/Healthy, the digest matches, the „Held apps"
list renders, 30 min: 0 events, 0 WARN, reports flowing, no alarm mail. Agent: yes → release-agent.sh from a clean clone,
signed updates (demo-felhom 10:26, Tester 1 10:32, demo-hp 13:49 after its test). Controller: rc.1 on 9201 and Tester 1
(9202 was session 2's) → 0.346.0 → per-box floors 15:09 → all three „update successful" → box walk green (start logs 0
errors, every app healthy, https-only green, held apps 0 = 0) → yes → global floor 15:37 → 30-min watch clean → per-box
floors cleared 16:09 (DB reads empty). `audits/release-2026-10-27/`.
## Teardown
Machine: the throwaway qBittorrent on 9201 removed through the product (shared library folder and older backups kept —
older than the test), forwarder and seed gone. Host: nothing provisioned on demo-hp today. DooPlex: the test torrent,
its data and folder removed, 326 torrents as before. Hub: per-box floors cleared; `Tester4-b5dbbd` (last night) waits for
the operator. Tester 1's off-site switch: the operator switched it off and on again; the box never saw it (R-1312).
## Register
Before 223 open → after 214. Closed 11 (R-1174 and R-1250, R-1261, R-1218, R-1219, R-1220, R-1232, R-1187, R-1298,
R-972, R-1291). Opened 1: R-1312 (the hub's off-site switch did not reach the box).
## Observations
- FILED R-1312 — the hub page's off-site switch does not change the box's saved target.
- NOT-A-FINDING: the line-test slot is not 10:00 — each host has its own slot minute (demo-hp 95, Tester 1 213,
demo-felhom 20), by design; the brief's 09:25 start was early, not wrong.
- NOT-A-FINDING: the off-site push WARNs „radarr/sonarr/prowlarr/qbittorrent: not deployed — unit-only" on demo-hp —
designed (`offbox_capture.go`, decision §2.4: kept units of removed apps).
- NOT-A-FINDING: the 50 % rule did not re-set qBittorrent after the new test — the line moved 0.15 %, inside its 20 % band.
- The 0.345.1 container's log was dropped when the rc replaced it; the four refusal lines were recovered from this
session's earlier reads, and the agent journal holds them independently (said in the evidence).
- The nightly CI run 2412 failed on the two due checks, by design; one operator mail at 03:24 UTC.
- A pushed commit message (`ae3db89a`) names the new row „R-1300"; the register uses R-1302 (the number was taken).
+75
View File
@@ -0,0 +1,75 @@
# REPORT — the 2026-10-26 release: hub 0.171.0, agent 0.166.0, controller 0.344.0, catalog, golden 0.344.0
**Plain words first.**
1. **The push is unblocked.** The waiver covered one day; the three waiting felhom.eu commits went out (CI 2352 ✓ on
`7ad7c996`, which carries `b00d5c61` and `1550b1da`). The waiver is now removed: the golden gate is green on the new
golden alone.
2. **Hub 0.171.0 is live.** A set-aside now mails „⚠️ … nothing failed" as a warning (seen in your mailbox), and the
vouch line names a release version as „the fleet's newest".
3. **Agent 0.166.0 is vouched** (10:04:55 CET) and runs on the three test boxes; a 25-hour signed job is refused on a box.
4. **Controller 0.344.0 runs on every live box** (3 of 3; the global floor 09:07:47 UTC). Tester-2 has no box (R-862).
5. **Golden 0.344.0 is baked and vouched** (10:26:23 CET); a fresh install from the public ISO came up on 0.344.0 with no
update step.
## The release-build checks (one line each)
- **R-1287** — Tester 1 set-aside → mail „⚠️ tester-1: a backup of an earlier install was set aside — nothing failed",
warning (hub log + mailbox; the 10-25 mails of the same event read 🔴 „failed"). Closed.
- **R-1289** — the agent vouch logged „behind the fleet's 0.344.0" while `0.344.0-rc.3` reports sit in the same table. Closed.
- **R-1280** — demo-hp: 25 h job REJECTED, 30 min job ran; `felhom-opsign -ttl 25h` refuses. Closed.
- **R-1285** — the policy pass is wired (seen under 0.166.0), but in the normal delivery the bundle runs in the OLD agent
process, so a BYO host still loses our drop-in one release late. **Back to OPEN.**
- **R-1281** — FileBrowser only on its own networks on all three boxes; forged header from four apps → 000 (control 404/301);
household files 200, no cookie 401; OnlyOffice linked: joins `felhom-files`, editor config 200, the document fetched 200.
The file manager restarted once at the update. Closed.
- **R-1261 / R-1250** — the line hold is in 0.344.0; the live test is Tuesday 10:00–16:00 (dated check stays). R-1261 VERIFY.
- **R-1282** — „Később" survives a controller restart (start-up line + settings.json). Closed.
- **R-1278** — the install page shows the kept-backup hint and link; none before or after (Tester 1). Closed.
- **R-1286** — Kimai has its install id (07:01:55Z); the hold sentences are released. Closed.
- **R-1288** — released (proven on the night's rig). Closed.
- **R-1283** — catalog `73c165d` pushed; Tester 1 synced at once, MeTube's folder `optional`. Closed.
- **D47** — 0 set aside after the update; every app has an install id.
## Versions, digests, CI by commit
| What | Version / digest | Commit → CI job |
|---|---|---|
| hub | 0.171.0, `sha256:742d2e69ce75d0d96598e8ee9a9acb11e677a3663348571e34abbd3819c7c46e` | `7ad7c996` → 2352 ✓ (code `f6328486` → 2342 ✓); manifest `6efb4760` |
| agent | 0.166.0, binary `3f22c65b…bfea9c5c`, bundle `093772c1…5156003a3` | `aa69114` → 2351 ✓; record `b890b57` → 2356 ✓ |
| controller | 0.344.0, `sha256:9435165dab85b1200d94157ec49d8be065889139e1831a5476dc68f4b9474b8a` | `0a59044` → 2355 ✓ |
| catalog | `73c165d` | gates green locally (catalog CI runs on push) |
| golden | 0.344.0, `767a90fe07ed47c85a3e08a16b85926e30531b65608f9856aa25855b4dd53210` (637,293,448 bytes) | `documentation/tests/golden-0.344.0-2026-10-26/` |
## Rows
Before **219**, after **212**; opened **2** (R-1294 demo-hp's off-site clean-up refused by its own cap; R-1295 PBS DR
provisioning rolled back at a re-enrolled install, log only); closed **9** (R-1278, R-1280, R-1281, R-1282, R-1283, R-1286,
R-1287, R-1288, R-1289). R-1285 back to OPEN.
## Observations
- FILED: R-1294 — demo-hp's weekly off-site clean-up refused (209 > 179) at 03:17Z; each refused week grows the next plan.
- FILED: R-1295 — at the fresh install the PBS DR auto-provision for Tester4 rolled back (`self_check_failed`); no mail.
- R-1285 reopened (delivery order), see above.
- NOT-A-FINDING: the vouch's `wrapper_sha=false` — the PBS-DR wrapper was never vouched (empty before and after).
- NOT-A-FINDING: 9202's rc start logged one WARN while FileBrowser was re-created in the same second; joined 2 s later, log
only; the release boxes logged none.
- NOT-A-FINDING: the 07:23Z self-bind mail to tester4@ — the operator's delete of `Tester4-84bbe7`, as designed.
- NOT-A-FINDING: the 02:57Z DooPlex sweep found `RIG_2026_10_25_SETUP_CODE` in last night's session record — that box is
destroyed, so the code opens nothing; the sweep worked as designed.
- NOT-A-FINDING: R-1282's status API read „LOST" on Tester 1 — the API shows `later_at` only on a box with media apps;
the stored value and the start-up line both kept it (instrument, recorded in the evidence).
- Deviation from the brief, said once: the fresh-install proof ran AFTER the golden vouch, because an install refuses any
golden but the vouched one (R-297); the vouch was reversible and the proof passed.
## Teardown
- **Machines:** fresh-install VM 9373 on demo-hp destroyed with its disks (nvme-scratch); Tester 1's throwaway Tandoor (×2)
and OnlyOffice (×2) removed through the product, nothing left; 9202 back on 0.343.0 with FileBrowser on `traefik-public`
and no `felhom-files` network, the rc image deleted; the drill VM back to `virgin` (CT 9100 purged).
- **Host:** demo-hp's thin pool never used; `nvme-scratch` (standing) untouched otherwise.
- **Hub:** host `Tester4-eb7371` (the fresh-install VM) stays for the operator to delete (STATUS); per-box floors cleared.
- **Secrets:** bake token/user, bind token, pairing code shredded; the pairing code blacked out in the committed
screenshot; evidence scanned (6 sec values + the 3 one-time values: 0 hits). New sec entry `REL_2026_10_26_ROOTPW`
(the test VM's typed root password, replaced at day-0; the VM is gone).
- One test side effect: at 2026-10-27 03:30 the „Később" timer fires on Tester 1, which has no media app — it restarts nothing.
+120
View File
@@ -0,0 +1,120 @@
# REPORT — 2026-10-28 (day, attended at the STOPs): HTTP2Shell steps live, the runtime cache fills itself, the 20 apps
Architecture read: `09-update-architecture.md` §3 (decisions 255, 275–278) and §6.4 (the security-fix lane);
`08-alarm-ladder.md` §11 (the watch).
## In plain words
1. Last night's three steps are live: **yes** — Home Assistant 2026.10.4 and Wanderer hidden (`b5b78f6`), Immich v3.3.5
(`0158b50`). demo-hp (9201) read the new commit and listed Home Assistant's step as due.
2. The runtime cache fills itself in CI: **yes** — no DooPlex change. With two entries taken out of the cache, a CI run
read Home Assistant 2026.10.4 (zstd) in 87 s and RomM 5.4.1 (gzip) in 25 s, and took audiobookshelf from the cache.
The whole job took 3 min 34 s.
3. Of the 20 apps: **10 are live** as tested security steps. **4 need a big step.** **6 have no fixed release yet.**
4. The operator: give the homelab session its list (unchanged since the morning). Nothing else is waiting on you.
## Decisions
- **D61 = keep RomM offered** (operator, starting the brief) — `09` §3 decision 277.
- **zstd in CI through a hash-pinned `zstandard` wheel, not `zstd` in the runner image** (the brief's „say which and
why") — decision 278. The runner image would be a homelab change, a rebuild and a k3s rollout on DooPlex, which the
brief forbids. A wrong or missing wheel gives NOT CHECKED, never a pass.
## The 20 apps — `documentation/audits/runtime-fixes-2026-10-28/TABLE.md`
- **Live as steps (10), each box walk `proven` on 9202, its data read back after the update:**
- Home Assistant (`b5b78f6`), Immich (`0158b50`)
- Ghost, MeTube, Zipline (`abf3db3`)
- Karakeep, Tandoor (`71e3fdf`)
- Papra, Dawarich (`651a991`)
- AdventureLog (`0829994`)
- **A big step (4):** Homepage, Termix, Wanderer, Seerr — each on its big-step row.
- **No fix (6):** ActualBudget, cal.com, Calibre-Web, Paperless, RomM, SparkyFitness — each on its row, with its exposure.
- **No bench test ran:** none of these apps has a bench fixture.
- **AdventureLog failed twice before it passed:**
- After an update its backend needs about 2 min 45 s to start. With a 30 s start time, Docker marked it unhealthy
for about a minute.
- A record every 10 seconds shows this. With 300 s the services go from „starting" straight to „healthy".
- The step carries that change. Run 2 was inconclusive: 9202's copy of the drill was old.
## Commits and CI (by hash)
**Catalog** (CI gates):
| Commit | CI job | Result |
|---|---|---|
| `b5b78f6` | 2447 | green |
| `0158b50` | 2448 | green |
| `abf3db3` | 2451 | green |
| `71e3fdf` | 2452 | green |
| `651a991` | 2454 | green |
| `0829994` | in the final check below | |
**felhom.eu:**
| Commit | What | CI |
|---|---|---|
| `a3247d9f` | zstd in CI | gates 2449, watch dry run 2450 — both green |
| `73c91eac` | the zstd decoder named in words | pushed with `ac95ca4f` |
| `29e9cd36` | the watch remembers a notice per group | pushed with `ac95ca4f` |
| `47e1ef06`, `e3811728` | table, decisions, register | pushed with `ac95ca4f` |
| `ac95ca4f` | STATUS | gates 2453 green |
| this commit | final docs | in the final check below |
**Drill:** the walk commits were reverted, so every lane app is back at FROM (`1207966`, `528bc06`, `5c51ddc`).
## Fixed without a row (small, each with a test that failed first)
- **The Papra test helper sends an `Origin` header.**
- Papra 26.x refuses a sign-up without one (`MISSING_OR_NULL_ORIGIN`).
- Proven live: the sign-up was refused (403) before the fix and works (200) after.
- **The box-walk drill mover moves two services that share one image.**
- Dawarich's app and its worker use the same image. The walk stopped with „FROM ref not found".
- Test: `test_box_walk_drill_move.py`. Proven live on Dawarich.
- **The walk loads the drill into the box before it installs the old version.**
- My revert of the drill never reached 9202. The walk's own check stopped the run as inconclusive.
- **The nightly watch remembers a notice per group** (`dooplex:<image>|<id>`).
- Before, the catalog's RomM and DooPlex's RomM shared one memory entry. A new notice on both reached only one of
them.
- Old entries are copied once, so the change sends no repeat mails. Test W13: 4 of 5 checks failed before the fix.
- **The RUNTIME log line names the zstd decoder in words**, not as a Python module object.
- **Two code comments** no longer say the cache is filled on DooPlex.
## Corrected
- **Calibre-Web does load Brotli.** This morning's table said it does not.
- The morning check used the process list. Inside the container, the app's memory map could not be read.
- Read from the guest instead (`/proc/<pid>/maps`): the app maps Python Brotli 1.2.0, Pillow's libbrotlidec 1.2.0
and Debian's 1.1.0. It now has its own row (R-1337).
- **The file manager does not load Brotli on any of the three boxes.** Measured: `ldd` and the maps of every process.
## Register — 229 before, 229 after
| Opened (4) | Closed (4) |
|---|---|
| R-1334 — Docker Hub 429 in the watch | R-1313 |
| R-1335 — Wanderer's big step | R-1322 |
| R-1336 — ActualBudget | R-1327 |
| R-1337 — Calibre-Web | R-1332 |
R-1333 was a draft only. Its fix landed in the session (the watch's memory per group), so it was never filed.
## Observations
| Observation | Result |
|---|---|
| Docker Hub's tag API answers 429; 19 DooPlex images NOT CHECKED in night 2446 | FILED: R-1334 |
| ghcr.io answered one blob with 429 during the dry run, while this session read images from the same address | NOT-A-FINDING: caused by this session's own parallel reads; R-1334 carries the rate-limit work |
| The security review flagged „version rollback" in the drill revert commits | NOT-A-FINDING: the drill is the test copy and must stand at FROM before a walk; the live catalog keeps the new versions |
| The evidence scan matched `Drill-1a37bb84e421` | NOT-A-FINDING: a seeded Ghost site title, not a secret |
| The evidence scan matched `"password": mpw` in `immich_repair.py` | NOT-A-FINDING: a variable name in code, not a value |
| A `git pull --autostash` in the shared felhom.eu clone emptied Dawarich's `walk.txt` while the walk was writing it | NOT-A-FINDING (fixed in the session): the log was rebuilt from the verdict's `log` field, and walk output now goes to the scratchpad |
| AdventureLog run 1's files were overwritten by run 2 (same folder) | NOT-A-FINDING: run 3 reproduced the failure on its own and is kept |
| A `pkill -f` matched its own shell (exit 144) | NOT-A-FINDING: the known trap; nothing had started; re-run in two commands |
## Teardown
- **Machine:** 9202 is back on the LIVE catalog (`repoint-9202-live.txt`, cache HEAD `0829994`). Every walk app was
removed through the product and verified gone: no container, no `app.yaml`, no volume.
- **Host:** nothing was provisioned. The bench (9401) was not started.
- **Hub:** no change.
+53
View File
@@ -0,0 +1,53 @@
# REPORT — security app updates, 2026-10-27 (day, attended)
> A sibling of `REPORT.md` (the release session of the same day owns that file).
## In plain words
- **Real notices:** the security watch flagged 38 pins. Read by hand: 33 real, in 32 apps plus 3 box programs; 5 apps
were false alarms (`audits/security-app-updates-2026-10-27/TRIAGE.md`).
- **Out tonight by the quick lane:** 14 apps, in three batches, each on your yes — Rallly, RomM, code-server, Outline,
Vikunja; n8n, PrivateBin, Docmost, Grafana; Homebox, Mealie, Audiobookshelf, BentoPDF, Uptime Kuma. Wishlist and
Bookstack had no notice id and went as normal steps. Immich (the lowest item) was not done.
- **Big steps:** Jellyfin 10.11 → 12.4 is done (bench, box, and the undo proven). Ten are left, a row each.
- **No-fix picks:** four questions for you (STATUS D56–D59); none changed a template.
- **Box programs released:** yes — controller 0.346.1 (Traefik v3.7.16, file manager 1.5.8-stable, cloudflared
2026.10.4), global floor 15:50:15Z on your yes.
## Catalog commits (app-catalog-felhom.eu) and CI by commit
| Commit | What | CI job |
|---|---|---|
| `06e603e` | batch 1 + wishlist; Rallly/Jellyfin fixtures; the privileges gate skips `steps/*.felhom.yml` | 2422 success |
| `7b0071e` | batch 2 + bookstack | 2425 success |
| `65a6b11` | batch 3; Homebox/Mealie fixtures | 2432 (see the final report for the read-back) |
| `540f185` | Jellyfin 10.11.11 → 12.4 | (see the final report) |
## Controller
`v0.346.1` = the release commit `b1b9be3` (v0.346.0) + one commit `5ba1b86` (tag `v0.346.1`; the same commit is on
`main`). CI 2427/2428 success. Image `gitea.dooplex.hu/admin/felhom-controller:0.346.1`
`sha256:b6b1e5488d31cb0b6596228fd6bf50900692ab0798d5da858159db67e8440190`, built from `ed3927f` (= `5ba1b86` + the
release session's REPORT.md only). MinAgent 0.158.1.
## Proofs
- The lane: a negative control first (busybox as TO → `failed`, undone). 14 walks `proven`, 12 with the seed read back.
- Part 5: 9202 (rc.1) and Tester 1, demo-hp, demo-felhom (per-box floors 15:41Z): all 29 public names redirect to
https; the file manager signs in (Tester 1, 9202: listing 200, 401 without a cookie); an app container cannot reach
it on any box (R-1281 probe with a control); the tunnel gap 4–5 s per box, the Traefik restart 7–20 s; a 30-minute
watch after the global floor was clean; the per-box floors cleared.
- Part 3: Jellyfin's undo — 12.4 migrated the database, failed on purpose, the box undid it, 10.11 signed the user in.
## Register
Rows at the task's start 221; now 224. This task opened 15 (R-1310, R-1311, R-1313–R-1325, R-1314 closed the same day)
and closed 3 (R-1304, R-1306, R-1314); R-1305 NARROWED. The release session closed ten and opened one in the same time.
## Teardown
Machine: 9202 back on the live catalog, controller 0.346.1, its saved config copy removed (identical); the walks
removed every app they installed; the drill mirror in 9202's volume stays (harmless, as after B23). Bench 9401
stopped (as found). Host: nothing. Hub: per-box floors cleared; the global floor 0.346.1 stays (intended).
Evidence: `documentation/audits/security-app-updates-2026-10-27/`.
+86
View File
@@ -0,0 +1,86 @@
# REPORT — the nightly security watch (R-1303), 2026-10-26 night
> A sibling of `REPORT.md`: the night session owns `REPORT.md` tonight. Readings taken alone (the brief's „safest
> reading", stated first):
> 1. **The key:** the operator said yes; the token did not exist by the end, so the watch runs in no-key mode (box
> programs nightly, apps' advisory lists every second night) and switches by itself when `GH_ADVISORY_TOKEN` exists.
> The name is `GH_…`, not `GITHUB_…`: Gitea reserves the `GITHUB_` and `GITEA_` prefixes for Actions secrets.
> 2. **The memory:** a file the CI job commits to `main` itself (`documentation/security-watch/state.json`), not the
> runner's disk (two runners, two disks), not the Actions cache (needs a node step), not DooPlex (a host change).
> 3. **A seed that could not read everything** (no key) leaves those pins pending; their first real read is recorded
> silently. Otherwise the first nights after the seed would have been the mail storm the brief forbids.
## In plain words
1. **Sources picked:** GitHub's per-repo security advisories (the main source), GitHub release notes, the Cloudflare
blog plus cloudflared's own `VULN-` notes, OSV for our Go builders, and the registries for „newer version". **They
cannot see:** a fix told only by mail, forum or a blog we do not read; a security fix nobody calls one; packages inside
our own images (Debian, Alpine, Samba); closed-source apps (Plex, Emby); floating tags like `redis:7-alpine`.
2. **Watched:** 108 pins — 11 box programs and build bases, 97 catalog images (21 of them with a stated „no source").
3. **First real run (the seed, CI job 2408):** ADVISORY on **30 pins (142 notices)**: 3 box programs (traefik, the file
manager, cloudflared) and 27 apps; BEHIND on 17; 0 NOT CHECKED. Nothing was mailed — the seed records them.
4. **The test mail arrived:** yes — „[Felhom security] TEST — not a real advisory …" in the admin@felhom.eu mailbox
(Resend id `01a17a5d-…`, CI job 2407).
5. **The operator does:** make the GitHub key and store it as `GH_ADVISORY_TOKEN` (CC's store and Gitea Actions). Then
decide the order of triage for the advisory list (R-1305, R-1306).
## The ADVISORY list today (box programs first; full list `audits/security-watch-2026-10-26/ADVISORIES-2026-10-26.md`)
| Program | Our version | Fixed in (notices) |
|---|---|---|
| traefik | v3.7.13 | v3.7.14–v3.7.16 (15; triage: none seems to apply to our config — R-1304) |
| file manager (FileBrowser Quantum) | 1.5.6-stable | 1.5.7-stable for 2 of 36 (GHSA-qx86, needs the password; GHSA-3846); the rest on 2.x (R-1305) |
| cloudflared | 2026.10.3 | 2026.10.4 (VULN-176088, metrics allowlist; our metrics are on the container's own loopback) + the eMudhra blog post (already fixed, R-1300) |
| 27 apps | — | e.g. Jellyfin 10.11.11 → 12.0; Gokapi 1.9.6 → 2.2.4; Seerr 2.7.3 → 3.5.0; Wanderer v0.20.0 → v0.21.2; Rallly 4.15.3 → 4.15.4; Immich v3.2.4 → v3.3.5 (notes); SparkyFitness: no fix yet (R-1306) |
## Commits and CI (by commit)
| Repo | Commit | What | CI |
|---|---|---|---|
| felhom.eu | `97ae7086` | spike + rows R-1303, R-1304 | job 2401 success |
| felhom.eu | `1f62d629` | the watch, the shared list + gate, tests, workflow | job 2402 success |
| felhom.eu | `6ee23a3b` | abandoned = GAP; seed-pending | (see below) |
| app catalog | `f61800a` | `upstream:` in 65 templates, gate + decoys, checklist 1.10 | job 2403 success |
| controller | `e01eb64b` | `upstream.txt`, `# upstream:` comments, gate + decoys | job 2404 success |
| felhom.eu | `ed843da7` | the memory, committed by the CI job itself | — |
| felhom.eu | (this commit) | docs, rows R-1305–R-1309, STATUS, this report | read at the end |
Live runs in CI: job 2405 (dry: every host reached; 30 NOT CHECKED because DooPlex's shared GitHub quota was at 0 —
printed and counted, the reason for the key), 2407 (test mail), 2408 (seed; memory pushed). Tests: 38 checks, no
network; red-proved five ways (dedupe, streak, the 30-day window, a swallowed source error, the seed-pending set); the
two gates' decoys red-proved with a reader that reads comments.
## Rows
Before **215**, after **222**; opened **7** (R-1303 – R-1309), closed **0**.
## Observations
- traefik v3.7.13 inside 12 October advisories — **FILED: R-1304**.
- The file manager 1.5.6-stable inside 36 notices, 2 fixed in its own channel — **FILED: R-1305**.
- 27 app pins with published notices — **FILED: R-1306** (one row; the list is the file).
- Packages inside our own images not watched — **FILED: R-1307**. Floating tags — **FILED: R-1308**. Mail-only and
silent fixes, closed-source apps — **FILED: R-1309**.
- Three upstream repos renamed (cal.com → `calcom/cal.diy`, jellyseerr → `seerr-team/seerr`, wanderer →
`open-wanderer/wanderer`) — **NOT-A-FINDING: the mapping uses the new names; the images still pull.**
- plant-it's image name points nowhere — **NOT-A-FINDING: known and stated in its template (abandoned); the watch lists
it as GAP and never looks it up.**
- The hub's Dockerfile lines are not gated in felhom.eu's own runner (only the catalog's and the controller's are) —
**NOT-A-FINDING: the watch reads them nightly and reports a missing line as NOT CHECKED; a gate there would need its
own decoy suite for two lines.**
- nginx's channel test treats 1.31 (mainline) as the same channel as 1.30 (stable) — **NOT-A-FINDING: BEHIND is a weekly
hint; the notice match does not depend on it.**
- Without a key, the dry run spent DooPlex's whole GitHub quota (shared with every DooPlex client) — **NOT-A-FINDING:
that is R-1303's „blocked on"; the watch reported it as NOT CHECKED, as designed.**
## Documents changed
`runbooks/monthly-floating-retest.md` §4a (the BEHIND check is nightly; the monthly run keeps the same-name re-test);
`architecture/capability-map-detail/B.md` B23 (a watch mail starts the lane); `architecture/08-alarm-ladder.md` §11 (the
three signals, `[DESIGN]`); `scripts/CHANGELOG.md`; `REUSE.md`; the catalog's `NEW-APP-CHECKLIST.md` 1.10. System
poster: none of the three needed — no machine, path, backup tier or key changed (a CI job reads public sources).
## Teardown
Machine and host: nothing provisioned. Hub: nothing. CI: three manual runs, no lasting change but the memory file. Work
copies `felhom.eu-cfsec`, `app-catalog-cfsec`, `felhom-controller-cfsec` on DooPlex: removed at the end, all pushed.
+55
View File
@@ -0,0 +1,55 @@
# REPORT — 2026-10-27 evening: the clean-up window button (R-1299) and `sec rm`
## Plain words first
1. **The button is live** on the hub: customer page → **Backup & DR** tab → „Off-site clean-up window". You granted a
window on Tester 1 and cancelled it again; nothing was removed.
2. **`sec rm NAME` works** (cc-secrets 0.3.0): one name per call, saved in git, undo by `git revert`.
3. **46 store entries removed** on your yes (names in `documentation/audits/r1299-window-button-2026-10-27/sec-rm.txt`):
the two D55 token copies, 20 of the 10-20 rehearsal box, 14 of the night/fixes test boxes, 3 of the rig and the
release BYO box, 5 of the 10-24 sweep box, `R_C11_REWALK`, `R_PART4`. The store went from 92 to 46.
4. **You still do:** nothing from this run. (Today's three do-items are done: agent 0.167.0 vouched, the D55 token
revoked, `Tester4-b5dbbd` deleted.)
**A defect of my own, found by your click and fixed:** hub 0.174.0 logged each grant but stored NO event row (my code
called only the dispatcher, which writes no row, and my test checked the call, not the row). Hub 0.174.1 stores the row;
the test now reads the stored rows and fails on 0.174.0's shape. 0.174.1 also moved the card to Backup & DR, where you
looked for it first.
## Versions, digests, CI
| | Version | Digest | From | CI |
|---|---|---|---|---|
| hub | 0.174.0 | `sha256:4f9ee04a9ff7c108a37a411be3c3de521b6acccb431c9e550c3567f7211e2e94` | `d85198b8` | 2433 ✓ |
| hub | 0.174.1 | `sha256:bb43f88acd59b8b20914381932eb2d9f779d44c190c34d3349eed91d37ce71fb` | `de57c090` (manifest `714ee236`) | 2437 ✓ |
| cc-secrets | 0.3.0 | — | `dc82cf9` | no CI in that repo; local suite 72 OK, red-proofs 28/28 |
| agent pin | day0_agent 0.167.0 | — | `3055bc5` | (end-of-run check) |
Live: 0.174.0 at 19:25 CET, 0.174.1 at 20:26 CET; both Synced/Healthy, 0 restarts, hub-only ArgoCD sync, built from a
clean clone (the shared clone held another session's uncommitted installer edit). 30-minute watch after 0.174.1
(to 21:13 CET): 0 warning-or-worse events, 0 WARN/ERROR lines, 10 box reports in the last 20 minutes, 0 restarts, no
new alarm mail.
## Tests
Hub `TestR1299_*` (five): the page per branch (and in the Backup & DR tab), a grant through the form stores one grant with
its limit and one stored row, refusals store nothing (above the count, not a number, no confirm, no CSRF), the ceiling
when no count is known (260 passes, 501 refused), cancel. Red-proofs: seven mutations, all caught
(`redproof-0174.0.txt`, `redproof-0174.1.txt`). **The tests were written after the code in Part 1** — so each was then
seen failing by a mutation; Part 2's `sec rm` tests were written first and seen failing before the code existed.
## Rows
Before 224 open → after 224. Closed: R-1299. Opened: R-1326 (the hub's start-up, 31–36 s, eats half its liveness margin
of ~65 s). Updated: R-1237 (its dead names are gone from the store; the sweep no longer watches those values; the
transcripts are unchanged).
## Observations
- FILED R-1326 — hub start-up vs the liveness probe.
- FIXED in-session — the window event wrote no row (0.174.0 → 0.174.1).
- FIXED in-session — the card's place (Backup & DR).
- NOT-A-FINDING: CC cannot press the button — its token has no `offsite:write` and CC holds no hub password, by design
(`09` §3 decision 251); the live click was the operator's.
- NOT-A-FINDING: the `sec doctor` sweep line still lists the removed names — it reports the LAST night's sweep (03:40 UTC),
before the removal.
+7
View File
@@ -124,6 +124,7 @@
| `offsite.DeliveryStateFor` (+ `DeliveryStatus`) | hub/internal/offsite/delivery.go | `(st, customerID) (DeliveryStatus, error)` | THE R-70 offsite last-mile detector — one implementation for every consumer (customer card `deliveryViewFor`, `monitor.OffsiteDeliveryChecker` event + R-71c heal) | Precedence: `applied` (latest report has offsite) wins over every secret-row shape; applied+unconsumed-staged = applied + `StaleStagedSince` flag (demo-felhom's live specimen). Never add a sibling derivation — consumers read THIS. |
| `(*Store).GetOneTimeSecretInfo` / `LastEventAt` / `LatestReportOffsitePresence` / `CountReportsOffsiteSince` | hub/internal/store/store.go | `(customerID) (*OneTimeSecretInfo, error)` / `(customerID, eventType) (time.Time, error)` / … | Detector inputs + DURABLE event-cooldown source (events table survives restarts — prefer over in-memory maps for hub-emitted checker events) | `GetOneTimeSecretInfo` never selects the value column — keep it that way. `SetOneTimeSecretTimesForTest` is the back-dating seam (PBSDR pattern). |
| `monitor.OffsiteDeliveryChecker` + `OffsiteReissuer` | hub/internal/monitor/offsite_delivery.go | `NewOffsiteDeliveryChecker(st, reissuer, onEvent, logger)` | R-70 stuck event + R-71c self-heal on the shared 60 s ticker | THE R-39(a) GUARD lives in `maybeHeal`: re-reads the secret row at act time and refuses over an UNCONSUMED row — `SaveOneTimeSecret` clobbers by design (Re-issue depends on supersede); never "fix" the store, never bypass the guard. reissuer nil = heal disabled (no provisioner) — required, else a heal-event fires for a silent no-op. |
| `monitor.HeldAppsChecker` + `store.UpsertHeldApp`/`ClearHeldApp`/`ListHeldApps` + `HeldAppGrace`/`HeldAppWhoClears` (D53, unreleased) | hub/internal/monitor/held_apps.go · hub/internal/store/held_apps.go · hub/internal/web/held_apps.go | `NewHeldAppsChecker(st, graceOverride, onEvent, logger)`; `.Check()` on the 60 s sweep | `08` §10: the boxes' held apps — the mirror (fed by `app_held`/`app_hold_cleared` in `handleEvent`), the „Held apps" list on the host page and the Hosts page, one operator reminder after the grace per reason, then weekly | **The hub never clears a hold** — a row goes only on the box's `app_hold_cleared`. The reminder is recorded BEFORE it is sent (a restart cannot mail twice); a row the box stopped repeating (> 50 h) is listed, never reminded. `app_held_reminder` is operator-only and per-app cooldown. `graceOverride` is a TEST configuration only (`alerting.held_app_grace_override`). Pinned by `TestD53_*` (monitor, api, web, notify) |
| `monitor.RestoreTestChecker` + `assessRestoreProven` | hub/internal/monitor/restoretest.go | `NewRestoreTestChecker(st, onEvent, logger)`; `.Check()` | R-85: turns a restore-test result into a SIGNAL — it was a `[WARN]` log line and nothing else, even for the tier already being tested | **TWO event types, never merged**: `restore_test_failed` (broken now, error) vs `restore_test_stale` (unverified — *not* known-broken, warning). Merging collapses the second into the first, and the second is what quietly becomes the first. **Anchored on R-81** (`assessRestoreProven` reuses `backupAssessment`/`verdict*`): a never-proven tier on a newborn box is UNKNOWN, not FAILED. Per-tier proof comes from the hub's RETAINED WINDOW — the agent reports only its latest run, so the latest report alone cannot answer "when was the OTHER tier last proven?". Operator-tier only: **no `customerMessages` entry** — do not add one without copy review. **R-86 (2026-08-03): the window is PER TIER, not one constant.** `restoreProvenWindow(tier, observed, ok)` = `clamp(4 × max(observed, declared), floor 7d, cap 12d)`, where `declared` is that tier's own backup-freshness threshold (`backupStaleAfter` 26 h / `offsiteBackupStaleAfter` 8 d — reuse those, never a second opinion) and `observed` comes from `observedArchiveIntervals` over the retained window. **Observation may only WIDEN**: a gap shorter than the declared rhythm is routine (a retry, a heal, a catch-up) and a live box proved it — demo-felhom's two PBS snapshots sit 8 h 54 m apart, which would read a WEEKLY tier as nine-hourly and re-create the false alarm. The cap keeps the window strictly inside offsite retention. `assessRestoreProven` takes the window as an argument and **every reason string names it** (R-100's corollary). |
| `(*Server).applyPBSDR` + `mergePBSDR`/`readPBSDR` | hub/internal/web/pbsdr.go | `(ctx, r, cfg) error` | The config form's DR-tier section → HOST desired_json `pbs_dr` descriptor + generation bump | Descriptor lives in the host desired_json, NOT ConfigJSON (buildConfigJSON drops foreign keys on re-save). v0.51.0: driven by `cfg.DRTier` (set from the form BEFORE applyOffsite/applyPBSDR); UNMET preconditions are honest waiting stages (save succeeds), REAL failures stay fail-closed; already-provisioned = success-no-op (red-proofed); disable keeps the ep0 tenancy. |
| `(*Server).pbsdrProvisionAtom` + `PBSDRAutoProvision` | hub/internal/web/pbsdr.go | `(ctx, customerID, host, storageID) (blocked string, err error)` / `(ctx, customerID)` | The shared fresh-provision cascade atom; the WG-registration hook target (api `SetWGRegisteredHook`, wired in hub/cmd/hub/main.go when tenantsync is on) | `blocked != ""` = waiting stage (never an error); the hook runs in a detached goroutine and must never fail registration. Scenario-A e2e test: TestPBSDR_AutoProvisionOnWGRegistration. |
@@ -158,6 +159,12 @@
| `scheduleDaily` | hub/cmd/hub/main.go (~L449) | `(ctx, name, "HH:MM", fn, logger)` | Daily jobs in Europe/Budapest (prune etc.) | Blocking — run as goroutine. `parseHM` returns 0,0 (midnight) on bad input. |
| `hu_grep.py` | scripts/hu_grep.py | `PATTERN --anchor ASCII [--negative TEXT] PATH…` | ANY search for Hungarian (accented) text in files — prints file:line hits, and refuses to report a zero unless an ASCII anchor hits and a negative control misses (R-364) | Reads bytes in Python, never via a shell; refuses a pattern that arrived transformed (octal escapes, U+FFFD). Exit 0 found · 1 tested zero · 2 refused |
### The list of everything we ship, with its upstream (R-1303, scripts/)
- `scripts/security_watch_inventory.py` — THE reader of every pin (catalog `image:` + `.felhom.yml` `upstream:`,
controller `infra.go` + `upstream.txt`, every Dockerfile `FROM` with its `# upstream:` comment) and of the source
grammar. The nightly `scripts/security_watch.py` and the catalog's and controller's `upstream` gates all import or call
it — never copy its parser.
## 2. Canonical patterns (copy structure from THE named file)
| Pattern | Canonical file | Key traits |
+17 -17
View File
@@ -2,7 +2,7 @@
**Ready for Tester 2? Yes — tell the friend go (hand-over list: `documentation/pilot/TESTER2-handover.md`).**
**Updated 2026-10-25 (evening, attended release).** Every box runs the new controller: a restore that does not start says so and keeps both copies (D49), a reinstall never touches the old backup, a restore downloads first. The hub stores the recovery package in one step; the new agent is vouched; the catalog has three fixes.
**Updated 2026-10-28 (evening).** On your yes, the four big updates are live with their undo tested: Wanderer v0.21.2 (offered again, D59 ended; federation from other servers stays off), Termix 26.10.5 (D58 ended), Homepage v2.7.0 and Seerr v3.5.1. Gitea 28.2.0 too (imports only from GitHub, Codeberg, GitLab); Docker Hub no longer refuses the watch in test runs — tonight's run is the check.
## What works
- **The Plex attack (10-17 → 10-23) did not reach Felhom's secrets** (R-1241).
@@ -19,11 +19,12 @@
## What is broken
- **P1:** any hacked app on DooPlex can read the hub's nightly backups, and maybe the signing keys (R-1241, homelab session); about 12 homelab logins still use a password that was public, and the public Gitea repo is not decided (R-925, yours).
- Tester 2 is off since 2026-10-04: old emergency password, no off-site check, no bootstrap (R-1139, R-1104, R-862). The scratch box cannot use agent features (R-1083).
- Tester 2 off since 10-04: old emergency password, no off-site check, no bootstrap (R-1139, R-1104, R-862). Scratch box: no agent features (R-1083).
- DooPlex: something sets the shared checkout to „bare" (R-935).
## What we work on
- Dated checks, run by CC. 2026-10-26: each hub daily job ran once on the clock-change day (R-1183). 2026-10-27: the qBittorrent line test on a seeding box, with DooPlex's qBittorrent as the peer (R-1250, your yes); the weekly clean-up window (R-435; the logs of the last one were lost to restarts). 2026-10-30: D35, website and installer to Cloudflare, starts (R-1228, ruled yes).
- Apps still waiting for the HTTP2Shell fix: 6 — ActualBudget, cal.com, Calibre-Web, Paperless, RomM and SparkyFitness have no fixed release yet.
- Dated checks, run by CC. 2026-10-30: D35, website and installer to Cloudflare, starts (R-1228, ruled yes).
## Waiting on you — decide
@@ -39,23 +40,22 @@ Newest first. CC's pick is in the „Pick" column. Each row also has its full te
## Waiting on you — do
**Still needed? (yes/no)** — CC could not check these. Answer yes or no per line.
1. Look at `roms/roms/` on the N100's drive in the file manager (R-1099). Since 2026-10-16.
2. The N100 sheet, about 30 minutes: Plex, the admins in Prowlarr, Sonarr and Radarr, your download sources (`documentation/audits/n100-lived-in-2026-10-15/SHEET.md`). Since 2026-10-15.
3. Look at these demo-hp pages when you have time: Calibre-Web, the file manager, AdventureLog, Plex, the app page, the Plex and Sonarr guides. Since 2026-10-16.
4. Remove the test server „plex-k6" from your Plex account (plex.tv → Settings → Authorized Devices). Since 2026-10-15.
5. Ask Google to index `https://felhom.eu/sajat-felho-tarhely` in Search Console (R-1035). Since 2026-10-14.
6. BIOS: on the N100, read „After Power Loss"; on the HP, set „Bypass F1 Prompt on Configuration Changes" to Enable. Since 2026-10-14.
7. Pin the first Facebook post (R-917), and look at the new cover in the Facebook phone app (R-919). Since 2026-10-12.
1. Look at `roms/roms/` on the N100's drive in the file manager (R-1099). (since 10-16)
2. The N100 sheet, about 30 minutes: Plex, the admins in Prowlarr, Sonarr and Radarr, your download sources (`documentation/audits/n100-lived-in-2026-10-15/SHEET.md`). (since 10-15)
3. Look at these demo-hp pages when you have time: Calibre-Web, the file manager, AdventureLog, Plex, the app page, the Plex and Sonarr guides. (since 10-16)
4. Remove the test server „plex-k6" from your Plex account (plex.tv → Settings → Authorized Devices). (since 10-15)
5. Ask Google to index `https://felhom.eu/sajat-felho-tarhely` in Search Console (R-1035). (since 10-14)
6. BIOS: on the N100, read „After Power Loss"; on the HP, set „Bypass F1 Prompt on Configuration Changes" to Enable. (since 10-14)
7. Pin the first Facebook post (R-917), and look at the new cover in the Facebook phone app (R-919). (since 10-12)
**Day, 2026-10-23 — your do list.**
**2026-10-28 day.** 1. Give the homelab session `audits/http2shell-2026-10-27/HOMELAB-LIST.md` (19 images, R-1328). If not: DooPlex keeps the bad runtimes.
**2026-10-23 do list.**
1. Print the break-glass sheet (`documentation/runbooks/break-glass-sheet.md`, the part from „The sheet”, one A4), fill it by hand, keep it outside the home (D32; R-923, R-924). If not: after a DooPlex loss no off-site copy opens.
2. On the hub's Hosts page: Discard appliance 49, and delete host Tester4-f967d4 (the BYO test host, removed 2026-10-25). If not: dead entries alarm.
2. On the hub's Hosts page: Discard appliance 49. If not: a dead entry alarms.
3. Give the homelab session R-1241, R-1242, the lists at the end of `documentation/audits/plex2shell-felhom-impact-2026-10-23/README.md` and `documentation/audits/dooplex-alarms-2026-10-24/README.md`, and an upload alarm on DooPlex's `eno1` (~100 Mbit/s line; the flood peaked at 905). If not: the next hacked app on DooPlex can read the hub's backups.
**The rest**
- System poster needs a refresh: the new 01:40 „release copy” arrow from DooPlex to ep0 (D33); the hub-database label already says every 6 hours. If not: the drawing misses one copy.
- Tell CC what removed four old agent packages from Gitea on 2026-10-25 (a clean-up rule?): the agent's CI is red until the gate and the rule agree (R-1290).
- Publish installer 1.36.1 (tag + webpage sync): a wrong passphrase then reads „passphrase REJECTED", not a doubled code (R-1284).
- Rotate the reused homelab logins and decide the Gitea repo's visibility (R-925, P1). Since 2026-10-09.
- Two DooPlex leftovers: `leftovers/2026-10-14/first-post/` (keep or delete); the `deny`-list edit in homelab-manifests' `.claude/settings.json` (commit or drop). Since 2026-10-14.
- Rotate the reused homelab logins and decide the Gitea repo's visibility (R-925, P1). (since 10-09)
- Two DooPlex leftovers: `leftovers/2026-10-14/first-post/` (keep or delete); the `deny`-list edit in homelab-manifests' `.claude/settings.json` (commit or drop). (since 10-14)
- Before the first paying customer: Tandoor's permission (R-789); a lawyer for the licence list and the terms (R-802, R-813); SparkyFitness by e-mail (R-784).
- Later (yours, not urgent): R-1250 (a seeding qBittorrent is never tested), R-1248 (a hard upload cap per app), R-1229 (ArgoCD's sync settings into git), R-862 (Tester 2's bootstrap, when it is back), R-504, R-1071, R-1073, R-1077, R-1042, R-132, R-908, R-779, R-904, R-232, R-433, R-933, R-213, R-832, R-388, R-882, R-883, R-814, R-1056, R-1164, R-930, R-920, R-902.
- Later (yours, not urgent): R-1248 (a hard upload cap per app), R-1229 (ArgoCD's sync settings into git), R-862 (Tester 2's bootstrap, when it is back), R-504, R-1071, R-1073, R-1077, R-1042, R-132, R-908, R-779, R-904, R-232, R-433, R-933, R-213, R-832, R-388, R-882, R-883, R-814, R-1056, R-1164, R-930, R-920, R-902.
@@ -103,7 +103,7 @@
| ID | Capability | Component | Status | Scope | Evidence |
|---|---|---|---|---|---|
| <a id="b1"></a>[B1](capability-map-detail/B.md#b1) | Deploy an app from the catalog (env config, memory guard, health-aware progress) | controller, catalog (65 apps, images pinned) | **PROVEN-LIVE** | **re-checked 2026-10-24** on controller 0.342.0 (after 6d90374 + 2fe6341): all 65 apps through the deploy request on a fresh box — 62 installed and answered, Wanderer installed but cannot run without DNS (R-739), 2 not offered by lifecycle; the memory guard did not fire (one app at a time) | `audits/catalog-sweep-2026-10-24/README.md` (2026-10-24); `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07); `audits/RERUN-p1p3-2026-07-06.md` (2026-07-06) |
| <a id="b2"></a>[B2](capability-map-detail/B.md#b2) | App lifecycle: start/stop/restart/update/logs/remove/redeploy | controller | **PROVEN-LIVE** | the actions; remove-with-data re-proven 2026-09-13; **re-check (2026-10-24):** mechanism changed after its evidence — 8ae9178 (removal deletes labelled volumes, R-1117) | `audits/R442-2026-09-13/` (2026-09-13); `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07) |
| <a id="b2"></a>[B2](capability-map-detail/B.md#b2) | App lifecycle: start/stop/restart/update/logs/remove/redeploy | controller | **PROVEN-LIVE** | the actions; remove-with-data re-proven 2026-09-13; **re-checked 2026-10-28 night on 9202** after 8ae9178 (removal deletes labelled volumes, R-1117): install, stop, start, restart, logs, the protected stacks refuse a stop (403), remove with data → its labelled volume and container gone (`audits/night-2026-10-28/part5-claims/lifecycle-walk.*`) | `audits/R442-2026-09-13/` (2026-09-13); `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07) |
| <a id="b3"></a>[B3](capability-map-detail/B.md#b3) | Update is GUARDED: it refuses without a restorable backup, backs up first when the copy is stale, and HOLDS an app that does not come up — on ANY backup tier, and the release itself arrives by the managed floor | controller v0.237.0 + v0.238.0 + v0.238.1 + v0.239.0, hub v0.112.0 | **PROVEN-LIVE** | — | `audits/slice4-2026-09-13/` (2026-09-13); `audits/rulings-r472-r475-2026-09-13/` (2026-09-13) |
| <a id="b4"></a>[B4](capability-map-detail/B.md#b4) | A failed update is UNDONE by the box itself — the previous version back with its data from seconds before the update; the app is held only if that undo fails too | controller v0.263.2 (the undo), v0.264.0 + hub v0.120.0 (the mail) | **PROVEN-LIVE** | scratch 9202 | `audits/undo-live-2026-09-23/README.md` (2026-09-23) |
| <a id="b5"></a>[B5](capability-map-detail/B.md#b5) | The catalog holds only TESTED steps — an image move without a proven test record (bench + box, digests the registry still serves) is refused at push time | catalog `6db08a5` (test-record gate, `ladder.py`) | **PROVEN-LIVE** | written PROVEN: the catalog gate against the live registry | `audits/DRILL-night-2026-09-23.md` (2026-09-23) |
@@ -124,7 +124,7 @@
| <a id="b20"></a>[B20](capability-map-detail/B.md#b20) | App crashes → customer notified (one event per transition, no flapping spam) | controller v0.120, hub v0.48 | **IMPLEMENTED** | crash→customer mail never live-confirmed | `audits/CAMPAIGN-3-2026-07-11.md` (2026-07-11) |
| <a id="b21"></a>[B21](capability-map-detail/B.md#b21) | Post-deploy optional config (API keys etc.) with restart | controller, catalog `.felhom.yml` | **IMPLEMENTED** | config-save + restart in no campaign | `tests/CAMPAIGN-2-2026-07-07.md` (2026-07-07) |
| <a id="b22"></a>[B22](capability-map-detail/B.md#b22) | Backup classification: 13 bind-bearing apps carry mandatory/optional/excluded classes | catalog, controller v0.132–133 | **PROVEN-LIVE** | — | `audits/SPIKE-backup-classification-2026-07-14.md` (2026-07-14); `audits/CAMPAIGN-6D-2026-07-15.md` (2026-07-15) |
| <a id="b23"></a>[B23](capability-map-detail/B.md#b23) | An urgent security fix reaches the boxes at night — a `security_fix` ladder step (box walk required, bench optional, a CVE/GHSA notice), taken by the night update (`09` §3 decision 255, D39 = B) | catalog `3898593`, controller v0.341.0 | **PROVEN-LIVE** | scratch 9202 (drill catalog), Plex 1.43.4 → 1.43.5; an app with no box fixture is checked by health, version and a soak only (`seed: none`) | `audits/security-lane-2026-10-23/` (2026-10-23) |
| <a id="b23"></a>[B23](capability-map-detail/B.md#b23) | An urgent security fix reaches the boxes at night — a `security_fix` ladder step (box walk required, bench optional, a CVE/GHSA notice), taken by the night update (`09` §3 decision 255, D39 = B) | catalog `3898593`, controller v0.341.0 | **PROVEN-LIVE** | scratch 9202 (drill catalog), Plex 1.43.4 → 1.43.5; an app with no box fixture is checked by health, version and a soak only (`seed: none`) | `audits/security-lane-2026-10-23/` (2026-10-23); batch use: `audits/security-app-updates-2026-10-27/` (2026-10-27, 14 steps live) |
## C. Protection & recovery (the product promise)
@@ -195,8 +195,8 @@
| <a id="e5"></a>[E5](capability-map-detail/E.md#e5) | Files from Windows Explorer / Mac Finder (SMB server) | controller v0.145.0 + `felhom-samba:1.0.0` | **PROVEN-LIVE** | — | *(evidence not on file — not re-verifiable)*: the row cites `felhom-controller` REPORT.md (v0.144.0, outside `documentation/`), the design `controller/sharing.md` and the transport verdict `audits/SPIKE-lan-discovery-2026-07-18.md` — none is a run of the shipped server |
| <a id="e6"></a>[E6](capability-map-detail/E.md#e6) | Media to TV via DLNA | — | **MISSING** | — | R-6; R-8 |
| <a id="e7"></a>[E7](capability-map-detail/E.md#e7) | File access via browser | FileBrowser (infra app, auto-mount sync) | **IMPLEMENTED** | browse/download through FileBrowser in no doc | `audits/storage-lifecycle-acceptance-2026-06-15.md` (2026-06-15); R-75 |
| <a id="e8"></a>[E8](capability-map-detail/E.md#e8) | Indítópult (app launcher) — one-tap grid of the household's openable apps | controller v0.163.0 | **IMPLEMENTED** | live click-through pending | R-72 |
| <a id="e9"></a>[E9](capability-map-detail/E.md#e9) | Indítópult megosztás (vendég link) — capability URL `/s/<token>` serves a standalone read-only guest launcher (no account, no admin session); optional per-share password; QR | controller v0.165.0 | **IMPLEMENTED** | — | R-15 |
| <a id="e8"></a>[E8](capability-map-detail/E.md#e8) | Indítópult (app launcher) — one-tap grid of the household's openable apps | controller v0.163.0 | **PROVEN-LIVE** (2026-10-28 night, 9202, endpoint-level — the household's page lists a tile per openable app, each linking to its public address) | `audits/night-2026-10-28/part5-claims/launcher-walk.*` | R-72 |
| <a id="e9"></a>[E9](capability-map-detail/E.md#e9) | Indítópult megosztás (vendég link) — capability URL `/s/<token>` serves a standalone read-only guest launcher (no account, no admin session); optional per-share password; QR | controller v0.165.0 | **PROVEN-LIVE** (2026-10-28 night, 9202, endpoint-level: switched on, opened with NO session — the apps, no admin link; a wrong token 404; rotate → the old link 404, the new 200; switched off → 404; the box left as found) | `audits/night-2026-10-28/part5-claims/launcher-walk.*` | R-15 |
| <a id="e10"></a>[E10](capability-map-detail/E.md#e10) | Forgot dashboard password → instant reset code | controller v0.123, hub | **PROVEN-LIVE** | — | `audits/DRILL-day0-take2-2026-07-12.md` (2026-07-12) |
| <a id="e11"></a>[E11](capability-map-detail/E.md#e11) | The dashboard in English — the household picks its language; Hungarian unchanged | controller v0.247.0 (spike) → v0.250.0 (slice 1, R-556 CLOSED) | **PARTIAL** | every dashboard template live; other surfaces open | `audits/i18n-slice1-2026-09-17/C/live/` (2026-09-17); `audits/i18n-2026-09-17/live/` (2026-09-17) |
| <a id="e12"></a>[E12](capability-map-detail/E.md#e12) | The box tells visitors apart — a stranger's wrong passwords lock only the stranger (dashboard, setup gate, apps that read the visitor from the right) | controller v0.286.1, catalog router resets | **PARTIAL** | — | `audits/visitors-2026-10-01/A/L2-demo-hp-real-tunnel.txt` (2026-10-01); R-779 |
@@ -281,6 +281,13 @@ app. Controller down → the gated app answers an error, never the app. Measured
tunnel. Since controller v0.286.0 it sits ALONE on the `felhom-tunnel` network at the fixed address `172.16.253.2`
(traefik at `.3`), so traefik can believe forwarded headers from it and from nothing else (§5). Geo-restriction WAF
is **hub-enforced** (the hub holds the CF API token; the controller only reports geo desired-state).
**Version and rule (2026-10-26, R-1300):** the image is `cloudflare/cloudflared:2026.10.3` since controller v0.345.1
(`infra.CloudflaredImage`). **cloudflared follows Cloudflare's security notices** — a notice is a patch release of
the controller, and a controller update recreates the container on the new image by itself
(`TestEnsureCloudflared_ANewImageRecreatesTheTunnel`). **Never turn off a certificate check to make an update
work.** The one check that is off today is the route's own: `*.<domain>` → `https://traefik` with `noTLSVerify`
(R-510; traefik shows its self-signed default certificate on a leg that never leaves the guest) — a recorded
exception, not a pattern to copy.
- **[DESIGN] The website's content comes from Gitea IN-CLUSTER** (2026-10-19). The `felhom-webpage` pod pulls
`website/` (from `main`) and `scripts/` (from the `installer-v…` tag, R-110) with four git-syncs that read
`http://gitea.gitea-system.svc.cluster.local:3000/admin/felhom.eu.git` — plain HTTP, safe only because it never
+20 -1
View File
@@ -510,7 +510,7 @@ per Part 1: **snapshot** (LVM-thin, transient, whole-guest rollback — not a ba
backup is due (`GET /backup/due`, §6) → **quiesces** (stops its app stacks) → `POST /backup` →
polls `GET /backup/status` to `done` → **unquiesces** (restarts exactly the stacks it stopped).
Implemented in `felhom-controller` v0.36.0 (`internal/quiesce`) + `felhom-agent` v0.11.0 (the
`/backup/due` cadence policy + `/backup/status` phases). **An agent-initiated vzdump is
`/backup/due` cadence policy + `/backup/status` phases). *[DESIGN] R-1232 (2026-10-26 night, agent main `3911cc6`, next agent release): on an encrypted tier the due-check counts only archives written with THIS storage's key (the R-727 discriminator — an archive carries no host id), so a reinstalled box does not read the old box's archive as its own last backup.* **An agent-initiated vzdump is
crash-consistent only** (there is no inbound-to-guest channel to trigger a quiesce — §3/§5); the
controller stopping its stacks first is what makes the captured state **clean-shutdown-consistent**
(validated live: a quiesced postgres restore comes up clean — "database system was shut down" — vs
@@ -569,6 +569,16 @@ never opens, re-seals or logs it; the audit (`escrow_carried`) carries host ids
hosts → no carry, `escrow_carry_refused` to the operator. The box then sees „identity present", its mint guard (R-241)
holds, and it offers the recovery screen. Proven live 2026-10-21 (`audits/fixes-2026-10-21/P1-live/`: the right code
opened the household's history, Nextcloud's 3 031 files came back byte-identical, the next off-site run appended).
**[DESIGN] 2026-10-28 night — WHICH retained row is carried (R-1255 H3; felhom.eu `1ee6d5a5`, rides the next hub
release):** the newest retained row that has an identity blob AND a repository-password hash; only when no row has a
hash, the newest row as before (a legacy package whose hash was never recorded may still seal the password — never fewer
ways back). Before, the newest row alone was taken: a newer package without the password was carried while the
household's real one stayed under the deleted host. **And the set-aside purge (R-1255 H4):** a set-aside is named
`<repo>.orphaned-<YYYYMMDDTHHMMSSZ>` (unique per run; was the date, which a same-day abandonment freed for the next
set-aside), and a retained row is purged only when it was tagged with the deleted path no later than that path's
deletion (`repo_tagged_at`; a row tagged before the column existed uses `superseded_at`) — a reused path's later copy is
still stored, and its packages stay. Store tests `TestR1255_*`, red before the fix; no live proof (a hub deploy is not
tonight's).
#### The separation principle (the rule that governs every posture)
Reading customer data needs **BOTH** the encrypted chunks **AND** a usable key. **Zero-knowledge
@@ -652,6 +662,15 @@ nothing waiting 404, hub failure 502 (still waiting). A controller that has not
R-978 order. Proven on demo-hp 2026-10-19: ceremony 1 typed back → code 1 opens the hub's package, code 0 is a kept
earlier one (422); ceremony 2 shown and abandoned → code 1 still opens it, code 2 opens nothing
(`audits/day-2026-10-19/P1/escrow-*.txt`).
**[DESIGN] 2026-10-28 night — a lost or late answer (R-1254 H2; agent `5ddd124` + controller `e33cffa`, unreleased):**
the upload at the claim or the confirm can lose its answer AFTER the hub stored the package, and the household was then
told „the previous code still works" — false. Now, after a failed upload, the agent asks the hub which package it holds
(`GET /api/v1/hosts/<id>/escrow`, the identity blob compared byte for byte, ciphertext only, 15 s): THIS package → a
success; another package → 502, the old sentence (now true); no answer → **504**, a sentence that promises nothing about
either code, the wait goes on. The controller words 504 and its own failed call as „Nem tudjuk biztosan… Őrizd meg
mindkét kódot…" (`api.escrow.confirm_store_unknown`), and waits up to 60 s for the claim and the confirm (was the
client's 15 s — shorter than the agent's 30 s upload, so an abandoned claim could store a package whose code reached
nobody). Tests `TestR1254_*` in both repos, red first. Live proof with the agent release (the vouch).
#### Custody across generations — what the hub retains when a blob is superseded (hub v0.60.0; **contract corrected hub v0.93.0, R-198**)
@@ -80,7 +80,9 @@ nonce (DoS-safe). Each layer is mandatory and was proven to reject independently
the root wrapper (`configs/felhom-os-apply`) alike (corrected 2026-10-24). **[DESIGN — the operator picked a code change
2026-10-25 (D44); row R-1280]:** neither caps the window's LENGTH (`expires_at − issued_at`); `felhom-opsign` defaults to 30 min
(`cmd/felhom-opsign/main.go:57`), and the nonce store keeps a record until its expiry. The pick: the agent and the
root wrapper refuse a window longer than 24 h. Not built yet;
root wrapper refuse a window longer than 24 h. **Built 2026-10-25 night (agent `d912307`, unreleased — rides the next
agent release):** `authz.MaxWindow = 24h` (`ErrWindowTooLong`), the wrapper's `MAX_WINDOW_S`, and `felhom-opsign -ttl`
refuses more; exactly 24 h is accepted;
- **nonce** — unseen within the window (the nonce store **must be persistent across agent restarts**
and expiry-pruned; a non-persistent store reopens the replay window after a restart).
@@ -139,7 +139,9 @@ walk is green; the golden is baked weekly and vouched by the operator; a new box
itself to the floor (R-1052: not yet proven end to end). Setting the global floor today needs the operator page with the
operator's password — there is no scoped route for CC (R-1051). **An agent can be vouched mid-week; the golden stays
weekly** (hub v0.158.0): the R-120 golden guard judges only a CHANGED golden selection, so a Day-0 save that keeps the
vouched golden (same version and sha) saves a new agent even while that golden is behind the fleet. **The agent list
vouched golden (same version and sha) saves a new agent even while that golden is behind the fleet. **„The fleet" is the
newest RELEASED controller any box reported** — a test build (`-rc.N`, `-dev…`) never counts (R-1289, hub v0.171.0,
unreleased: the semver compare could not read a suffix and kept a dev build no box ran as the fleet's newest). **The agent list
offers real agent packages only (R-1011, hub 0.162.0, deployed since; corrected 2026-10-24):** the sha lookup asks for exactly the
`felhom-agent` file (the golden: `golden.tar.zst`) and never falls back to another file, so a step bundle
(`0.156.1-step1`, only the config bundle) is left out of the list, and a vouch of one is refused
@@ -298,7 +300,7 @@ What remains:
**`host_escrow.blob`** (and the identity blob beside it).
**[DESIGN] 2026-10-24 (R-1254; committed felhom.eu `dcf4f84c`, hub next v0.170.0 — NOT deployed):** the escrow PUT
stores the blob, its sealed-password hash and the identity blob in ONE transaction (`Store.SaveHostEscrowWithIdentity`;
the superseded copy is made inside it). A failure leaves all of the old package or all of the new — never the new hash
the superseded copy is made inside it). *[DESIGN] R-1218 (2026-10-26 night, hub main `09b5f02f`, next hub release): a package that seals the off-site repository password is never replaced by one that seals none — the PUT answers 409 and the good package stays current (it used to be demoted to operator-only custody, so the household's code no longer opened its off-site copy).* A failure leaves all of the old package or all of the new — never the new hash
beside the old identity package, which a box would read as „escrowed" while the written code opened nothing. A
malformed identity blob is refused before anything is stored. (The agent ceremony's „the previous code still works"
after a lost answer, R-1254's other half, stays open.)
@@ -389,6 +391,17 @@ the explicit Re-issue action") and the re-issue itself then refused with 400 —
tier. **Not built:** releasing ONLY the token on host delete. The endpoint's only removal op
(`deprovision`) destroys the backups too, so a token-only release needs a new endpoint operation.
**[DESIGN — R-1295, hub v0.172.0 (rc.1 deployed for the proof) + tenantsync v1.4.0 (committed, not on ep0)] A new
token's self-check waits out PBS's permission cache, and a failure is never silent.** PBS's proxy caches permissions for
up to 5 s and an ACL-only change does not clear that cache; a request from another client between the token create and
its grant leaves the token refused (403) for up to ~5 s, and the script's one quick retry fell inside the window
(Tester4, 2026-10-26: rolled back, the box got no whole-guest off-site tier, only a log line). Measured on a throwaway PBS
4.2.5 under load: v1.3.0 failed 11 of 30, v1.4.0 0 of 30 (`audits/r1295-pbsdr-selfcheck-2026-10-26/`). The endpoint now
re-checks the same token (and its own admin token) for up to 15 s; the hub repeats a `self_check_failed` rollback (3
attempts, 7 s apart, a log line each) in the provision and the F-14 re-issue paths; a final failure of the WG hook raises
the operator-only `pbsdr_provision_failed` („… save the customer config to retry"). Live 2026-10-26 on hub rc.1: a fresh
Tester4 install provisioned the tier on the first try.
## 15. Customer e-mails — what the hub writes to a household [hub v0.118.0, R-558]
**The section this document did not have.** The hub composes every sentence a household reads before
@@ -746,7 +759,7 @@ method (405), so a token gets 403.
| `/configs/{id}/edit` | `customers:read` | **session only** | Edit can change the household's e-mail — and a new e-mail auto-mails the self-bind link (ruling 13:20). |
| `/offsite/remove-unpinned/{id}` | — | **session only** | |
| `/offsite/abandon-cancel/{id}` | — | **session only** | Cancelling a pending set-aside deletion: no group names it; until the operator places it, session only. |
| `/offsite/window-grant/{id}` | — | `offsite:write` | |
| `/offsite/window-grant/{id}` | — | `offsite:write` | The one-shot clean-up window: the script address AND the customer page's „Backup & DR" card (R-1299, hub v0.174.0): `from=page` + `confirm=1` from the form; `cancel=1` removes a waiting grant; a limit above the store's snapshot count is refused. |
| `/offsite/windows-enabled` | — | `offsite:write` | |
| `/os/{id}` | `os:read` | `os:write` | |
| `/offsite/key-audit` | — | `offsite:read` | Runs the daily key check now: it reads keys and reports, it changes none. |
@@ -255,6 +255,21 @@ the identity bundle's shape is `{tunnel_token, pbs_token, wg_private_key, restic
**[DESIGN] Off-site deletion custody (decisions 68–69, 2026-10-03) — BUILT hub v0.127.0 / controller v0.289.1, live on both demo boxes.** The restic repository password stays on the box only. The box's off-site key is append-only (pinned in `authorized_keys`, written by the hub — the key registrar); the box never receives the sub-account password, which the hub stores encrypted at rest. Old snapshots are pruned by the box itself, only in a weekly window the hub opens, behind a fake-snapshot guard (R-822); the window has run live on both demo boxes since 2026-10-05 (R-95, closed). The guard's residual — past-dated fakes steering the keeps, and a window check that trusts the box's own counts — is R-822 and R-895. **Hub v0.158.0 (built 2026-10-18; deployed the same day on the operator's yes — corrected 2026-10-24) adds the hub's own check:** the 07:10 key audit compares the repository's `snapshots/` listing, over the hub's own login, with yesterday's — files gone that no clean-up window explains raise `offsite_snapshots_vanished` (error), files no reported box run explains raise `offsite_snapshots_unexplained` (warning); both operator-only (R-895 slice 2). A Felhom-side pruner holding repository passwords is rejected.
**[FINDING — R-1294, 2026-10-26, read only; a rule change waits for the operator (STATUS D54)] A store that once goes
over the window's cap never comes back by itself.** The cap is half the store (hub `offsitekeys.MaxRemove`); each refused
window adds a week of snapshots and removes none, so the plan grows faster than the cap. demo-hp: one test day
(2026-10-16, 152 snapshots) aged past 7 days and the 10-26 window refused 209 > 179 — an HONEST plan (every removal 7–30
days old, every app keeps ≥ 9 or its last copies; `audits/r1294-offsite-cap-2026-10-26/`). The existing way out is the
operator's one-shot raised cap (R-833, `GrantOffsiteWindowOnceMax`).
**[DESIGN — R-1299, built hub v0.174.0/v0.174.1 2026-10-27, `d85198b8` + `de57c090`] The one-shot window has a button.**
The customer page's „Backup & DR" tab carries the „Off-site clean-up window" card: the weekly switch, the normal cap,
a waiting grant and the last window; an optional limit, a confirm step that names the customer and the limit, then the
same route and rule as before (`POST /offsite/window-grant/<customer>`, `offsite:write` or a session). A raised limit
above the store's measured snapshot count is refused (a window cannot remove more than exist; the 500 ceiling stays). A
waiting grant can be cancelled before the box uses it. Every grant and cancel is a stored operator-only info event
`offsite_window_grant` (who, customer, limit). Live: granted and cancelled on tester-1 by the operator, nothing removed
(`audits/r1299-window-button-2026-10-27/`).
**[DESIGN, built hub 2026-10-07 — R-32 option A, `09` §3 decision 167] What RESET does to the household's off-site
copy.** On the shared pool box a sub-account is a LOGIN, not the data: deleting it leaves its folder (measured
2026-07-21: 1.4 GB in two `.orphaned-*` folders after a RESET), and a re-enabled customer lands on the same folder
@@ -396,6 +411,8 @@ never moved by an update or an undo, and the unit restore accepts it.
> copy protected the app's files. Since v0.245.0 every dashboard page carries the reminder (the R-241
> bar, second instance) and the Tier-1 sentence renders by state — „védené … szünetel" while paused.
> Measured on a fresh box 2026-09-16: zero snapshots, and the page said the files were protected.
>
> *[DESIGN] R-1219 / R-1218 (2026-10-26 night, controller main `1170b48`, next release): during a recovery offer the bar does NOT urge the ceremony (a new code would replace the key that opens the old off-site copy) and the start answers 409; a ceremony stages the off-site password whenever its FILE is on the box, also with off-site switched off or cleared.*
> **R-191 (2026-08-04) — this row was RIGHT and the configuration disagreed with it, weekly, for as long as R-89 has been in force.** The contract has not changed: offsite retention is ep0's, the box's token is write-only, and the box cannot delete its own history. What had not followed was the installer's `keep_last: 2` on the offsite tier, so every weekly run uploaded its snapshot successfully and then failed the whole JOB on a prune the token is refused — `whole_guest_backup_failed` in the operator's inbox about a backup that had already succeeded. Fixed in installer **1.25.0** (`keep_last: 0`) and on both live boxes; a gate now asserts it. **Verified before changing it:** ep0's two prune jobs have run every day since 2026-07-27, 18 tasks, all OK. A doc that states the contract does not enforce it — the gate does.
@@ -916,6 +933,8 @@ run makes it longer.
*Second-drive copies that are KEPT (D25) and the rule that a rejected backup block never deletes one: §8.2a (R-1252, 2026-10-24).*
*[DESIGN] R-1220 (2026-10-26 night, controller main `7e15a37`, ships with the next controller release): an app whose `app.yaml` EXISTS but does not parse counts as INSTALLED — every folder its compose binds, on every registered drive, is live and never listed as kept data (fail closed; one WARN names the app).*
**What it is.** "Remove the app, keep my data" leaves the app's drive folder (`<drive>/appdata/<app>`, or the folder
its definition binds through `${HDD_PATH}`) in place. A reinstall over it no longer runs silently into the old files
(R-657): the install asks „A megőrzött adataimat használom" / "Use my kept data" (the database from the newest copy of
@@ -1073,6 +1092,8 @@ second drive's whole restore (its `CheckOnly` pass carries the pull, so its file
load from a unit and from off-site, and a set-aside unit (D47) — the off-site restore, the second drive's file restore
and the no-unit fallback. Not covered: the `.fab` import — it removes the running app's volumes before its definition is pulled (R-1279).
*[DESIGN] The `.fab` route, R-1187 (2026-10-26 night, controller main, next release): the export carries a symlink AS A LINK and stops on a FIFO, socket or device naming its path; a drive folder that cannot be packed fails the export (never left out). The import writes only through `os.Root`, keeps owners and modes, restores a link only when it points DOWNWARD inside the folder (no absolute target, no „..”, no link on the way — others refused and listed), refuses while another operation holds the box and refuses an empty or relative `HDD_PATH`; its compose runs get the controller's own `USERDATA_PATH`/`IMPORT_PATH`; the database loads through the backup side (`appbackup.ImportDump`: mariadb / mariadb-admin, psql ON_ERROR_STOP) — the import's own `mysqladmin`/`mysql` calls failed on every MariaDB 11+ image. Live: `audits/night-fixes-2026-10-26/`.*
### 6.7 Why an off-site run failed — the failure classifier (R-571)
**[FACT, read from source 2026-10-05, felhom-controller `114ff27`]** When an off-site (restic) run fails, the
@@ -1720,7 +1741,7 @@ names the app and both identities). Nothing moves a unit while that app is being
telepítés mentése") with **„Visszaállítás"** — the one unit-restore body, with the unit's own database password — and
„Eltávolítás". Only those two, and the app's remove with „delete its backups too", ever remove it (the §8.2a / R-1252 H9
rule). After a restore from it, the app is that unit's install; the app's own unit of the install it replaced is then
set aside at the next backup — never lost.
set aside ~~at the next backup~~ **at the restore itself** — never lost. **[DESIGN — R-1288, 2026-10-25 night, the brief's safest reading; controller `b5863a9`, unreleased]:** the restore of a set-aside unit moves the replaced install's unit aside whole right after it (success, or „not started yet" — the data stays, D49 = A), one log line „replaced by the restored install", **no operator alarm** — the household chose this restore; before, the next backup's writer set it aside with a second alarm and a second kept copy (measured on Tester 1, 0.343.0). **[FACT]** on the night's rig (rc.2): the line, the account back, the next backup set nothing aside, one set-aside mail only (`audits/night-2026-10-25/rig/r1288-live.txt`). A set-aside's operator mail (R-1287, hub v0.171.0, unreleased) reads „⚠️ … a backup of an earlier install was set aside — nothing failed", a warning.
**Known limit, stated.** A box that reinstalled and refreshed BEFORE this release already holds a rewritten unit; its
old password is gone and nothing can bring it back. A unit from before D47 of an app with no carried secret has no
@@ -1728,7 +1749,7 @@ signal: it is treated as this install's (the old behaviour) and gets the identit
**Why a volume app's reinstall asks no kept-data question:** the question (§6.5, decision 36) is about the app's drive
FOLDER (`${HDD_PATH}` binds under `appdata/`); a volume app keeps nothing there — „remove, keep my data" removes its named
volumes and keeps only its backups — so the install starts empty, and the kept backup is now the set-aside unit on the
restore page. (The missing offer at install is its own row, R-1278.)
restore page. **[DESIGN — R-1278, controller `fbec5cb`, unreleased]:** the install page now says so for an app not installed — „the new install starts empty; load the backup afterwards on the Restore page" — with a link (set-aside and removed-app units counted).
### 8.2e A restore whose app does not start is never „success" [DESIGN, R-1270, 2026-10-25 — controller `b680db8` + fix A; D49 = A (operator 2026-10-25); released in controller 0.343.0]
@@ -251,6 +251,19 @@ today's engine, and its build (read the counter of every container; „probably
before any code, by the brief's measure-first rule — `09` §3 decision 155 stands for the operator to confirm or drop.
Cost measured for the record: one `docker exec … cat memory.events` across demo-hp's 21 containers takes 1.6 s wall
(0.47 s user, 0.44 s sys); cloudflared has no `cat` and reads as unknown. `audits/design-build-2026-10-06/C/`.
**[DESIGN] 2026-10-28 night — the host's counter beside Docker's flag (R-528, as designed in the row 2026-10-26; agent
`6f933d6` + controller `eed23e7`, unreleased):** the agent serves `GET /guest/oom-kills` — the kernel's `oom_kill` of
each of the asking guest's containers, read on the host from `/sys/fs/cgroup/lxc/<vmid>/ns/system.slice/docker-<id>.scope/memory.events`
(0444; the non-root agent reads it — no sudo); the 30-s scan asks once per pass (5 s cap; an agent without the route
404s and is asked again after 10 minutes; no agent = Docker's flag only). A running container whose CURRENT run counts a
kill (its scope is new at each start) raises the same `app_oom` (once per run), whatever Docker's flag says; the
event's details carry `source` (`docker`, `cgroup` or both) and the host's count is the run's kill count — so a
container with a false flag now also reaches the storm rung. **[FACT] live 2026-10-28 23:27 on Tester 1** (test builds
of both, put back afterwards): a throwaway Radicale capped at 128 MB, `tail /dev/zero` inside it → the hog killed
(exit 137), the container kept running, the host counter 0 → 1; the controller logged the OOM line naming Radicale,
„seen by docker,cgroup", and pushed ONE `app_oom` (none in the next two minutes); the operator's mailbox (a second
channel) held exactly one mail, details `"source":"docker,cgroup"`. Docker 29.8.2 reported this kill too, so the
cgroup-only path is proven by the tests, not live. `audits/night-2026-10-28/r528-oom/`.
**The box STOPS a crash loop or an out-of-memory storm (decision 28 of `09` §3, R-667, controller v0.269.0 /
hub v0.123.0, 2026-09-24).** Alarming was not enough: gokapi crash-looped for hours at 385 → 546 restarts
@@ -591,6 +604,22 @@ normal use; work it does not explain is the sign of a hacked app. Numbers and me
start-up check puts it back; the 50 % rule waits while a record exists. Measured on demo-hp with a real seed (10
Mbit/s to DooPlex's qBittorrent): refused `not-quiet` without the hold; with it the uplink fell to 0.02–0.16 Mbit/s,
94.2 Mbit/s measured, the app held 56.8 s and back to 1 249 280 B/s exactly (`audits/dooplex-alarms-2026-10-24/`).
**[DESIGN — R-1250 drain wait, 2026-10-27; controller `710ceac`, released v0.346.0]:** between the hold and the call
the controller waits until every held app REPORTS its own upload ≤ 16 KiB/s on two readings 2 s apart (at most 90 s;
an unreadable speed waits 20 s) — qBittorrent 5.2.4 kept sending at full speed ~14 s after its limit fell, inside the
agent's 5–15 s quiet read, and four tries in an hour were refused; with the wait the test ran (94.5 Mbit/s, the limit
back exactly; `audits/linetest-2026-10-27/`; `09` §3 decision 269).
**[DESIGN — R-1261, 2026-10-25 night; controller `a79a292`, unreleased]:** EVERY running seeder is held (qBittorrent
and Transmission — one left seeding kept the test refused `not-quiet` every time); all records first
(`upwatch.line_test_holds`), then the apps; a record whose app was removed while held is dropped (it used to stop the
50 % rule for good); qBittorrent's hold names its slot (`up_limit` / `alt_up_limit` through `app/preferences` —
`transfer/uploadLimit` follows the CURRENT speed mode, measured on 5.2.4), so the household's switch to the
alternative speed during the test never leaves 1 KiB/s behind. **[DESIGN — R-1292, controller `2619191`, unreleased]:**
the 50 % rule owns the NORMAL slot only (`up_limit` through `app/preferences`); the household's alternative limit is
never read or written by it, and a mode switch never reads as „the household changed it". **[FACT]** the night's rig (BYO VM, agent 0.165.0,
rc.1, two seeders to 9202's qBittorrent): with a mode switch mid-test both limits came back, the test refused
(the switch let qBittorrent upload); without, both held (qBittorrent in its alternative slot), 94.8 Mbit/s measured,
both limits back exactly (`audits/night-2026-10-25/rig/hold-watch*.txt`).
While the box owns it, qBittorrent's page says: „A qBittorrent
feltöltése legfeljebb N Mbit/s, hogy a családi internet gyors maradjon. A qBittorrentben átállíthatod."
6. **Limits, stated:** *(added 2026-10-24, review round 2: ANY viewer explains any amount of upload, so a hacked app can send freely while one real playback runs — `upwatch/watch.go:275,299`; R-1262)*; an attacker who knows the check can make the app's API lie — a per-container ceiling (`tc` from
@@ -598,3 +627,100 @@ normal use; work it does not explain is the sign of a hacked app. Numbers and me
whatever the API says; not built. The box cannot tell LAN from internet bytes per app; a host-network container
(Samba) has no counter; the push floor is a lower bound, the weekly test is close to the line.
7. **Release:** released 2026-10-24 on the operator's yes (controller v0.342.0, hub v0.169.0; R-1244) — corrected 2026-10-24.
## 10. A held app the operator can see [DESIGN — built 2026-10-26 (commit only): controller `5bd03ad`, hub `7e57e824`; D53 = operator-only, `09` §3 decision 265; R-1291]
**Why.** A held app is stopped on purpose and stays stopped until a person acts — and today nobody is told after the
first minute. demo-hp's Kimai sat held for 11 days (2026-10-14 → 10-26) and was found by accident (R-1286). The
controller sends one event when the crash-loop guard stops an app (`app_stopped_unhealthy`); no other hold sends
anything, and the hub has no held-app state at all. On a household box the same silence would hide a failed restore.
**The holds that exist** (controller `settings.RestoreHold.Reason`, the sentences of `holdWhy`, R-1286):
| Reason | What put it there | Who may clear it |
|---|---|---|
| `restore_failed` | a restore whose rollback also failed | **a person only** (R-379: support, `--clear-restore-hold`) |
| `restore_mixed` | an off-site restore whose database replay failed | a person (the same) |
| `update_failed` | a failed update | the household, by restoring the app from its backup |
| `unhealthy_stop` | the crash-loop guard | the household's Start (one more try, `09` §3 decision 28) |
| `putback_pending` | a restore waiting for its pre-restore copy | nobody — it clears itself when the drive comes back |
**What the controller reports.** The legacy report is frozen (hub rule), so the event channel carries it:
`app_held` when a hold is written (stack, reason, since — the hold's own `At`) and `app_hold_cleared` when it goes.
Because an event can be lost, the controller re-sends `app_held` for every hold still in place **once a day**; the hub
treats it as idempotent. Both types enter `allowedEventTypes` AND `customerMessages` (hu + en) in the same hub commit
(the coupling rule); `app_held` is operator-only in v1.
**Where the hub shows it.** The host page (and the customer page) get a „Held apps" list: app, reason in one line
(the `holdWhy` sentence), since, and who may clear it. Built from the open `app_held` events per customer and stack.
**When it mails.** One operator mail per hold after a grace that follows the reason: `putback_pending` 6 hours (it
should have cleared itself — if not, something is stuck); `restore_failed` / `restore_mixed` 1 day (only a person can
act); `update_failed` and `unhealthy_stop` 3 days (the household can act first). Then one reminder a week while it
lasts, through the dispatcher's existing per-type cooldown (§6.2). A cleared hold sends nothing.
**Who clears it.** Unchanged: R-379 holds only a person; the household's Start or restore for its own two. **The hub
never clears a hold** — it only shows and reminds.
**Cost.** One controller release (the two events + the daily re-send, ~½ day with tests) and one hub release (allow-list,
the i18n keys, the list on two pages, a reminder checker; ~1 day). No agent change.
**Ruled (D53, operator 2026-10-26, `09` §3 decision 265):** v1 is operator-only. Household mails for the two holds it can
clear itself may follow once the operator list has run.
**As built (2026-10-26, commit only — releases ride an attended run).** The wire reason is the controller's own constant:
`putback_pending` (one word), and the empty legacy reason is sent as `restore_failed`. The controller's reporter is ONE
observer of the hold store, ticked every minute (`internal/holdreport`), never a send inside a hold writer; the set it
last reported is kept in settings, so a hold cleared while the controller was down is still reported cleared. The hub
mirrors the events in `held_apps`, sends `app_held_reminder` (warning, operator-only, per-app cooldown, the subject
names the app) once after the grace and then weekly, records the reminder before it sends it, and does not remind about
a row the box stopped repeating for 50 h (the list still shows it, marked). `alerting.held_app_grace_override` replaces
every grace — a test configuration only. Live proof: `audits/d53-held-apps-2026-10-26/` (a crash-looped throwaway app on
9202 against a test hub with a 3-minute grace: listed on both pages, one operator mail, Start cleared it, the row went,
every household leg `skipped operator_only`).
*[DESIGN] R-1298 (2026-10-26 night, controller main `b156e45`): an install's hold (`unhealthy_stop`, `update_failed`, `putback_pending`) of an app that is NOT installed (no `app.yaml`) is not reported — it would remind weekly about an app that does not exist; a restore hold is always reported (R-379, a person clears it).*
## 11. The security watch — three operator-only signals [DESIGN — built 2026-10-26: felhom.eu `1f62d629`, `6ee23a3b`; R-1303]
The nightly CI job `security-watch` (03:40 UTC, `scripts/security_watch.py`) reads where each shipped program publishes
its security notices (sources and their limits: `audits/security-watch-2026-10-26/SPIKE.md`) and mails **admin@felhom.eu
only** — no household, no hub event:
| Signal | When | Once? |
|---|---|---|
| **ADVISORY** — „[Felhom security] <programs, box first> — N new advisories" | a notice affects the version we pin | once per (program, notice); a reminder every 7 days while it stays open; a vendor-blog notice never repeats |
| **BEHIND** — „[Felhom security] weekly: …" | Monday (or the last summary is 8+ days old) | one summary; it also lists GAP, FLOATING and tonight's NOT CHECKED |
| **NOT CHECKED** — „[Felhom security] the watch could not check …" | the same source failed two nights in a row | once per streak; a good night resets it |
The memory is `documentation/security-watch/state.json`, committed by the job itself; a missing memory re-seeds AND mails
that it did. A job that does not finish mails „[felhom CI] security watch FAILED". The mail starts the security-fix lane
(capability map B23).
**[DESIGN — R-1327/R-1328, built 2026-10-27 night, commit only] A fourth source, „runtime", and a third group,
„DooPlex".** HTTP2Shell (CVE-2026-111497) sat in the Node.js and Python Brotli INSIDE app images, where no app notice
mentions it. The watch now reads each pin's image (`scripts/image_runtime.py`: the registry config, then only where
needed the layers — Alpine/Debian package databases, Node's `node_version.h`, Python `.dist-info` — never a pull) and
matches it against `scripts/security_watch_runtimes.json`; a hit is an ADVISORY with source „runtime", a read that
fails is NOT CHECKED. Results are cached by the tag's digest in `state.json` (`runtime_cache`) and the nightly lookup is
a HEAD request (Docker Hub does not count it against the anonymous pull limit — the first run's GETs hit HTTP 429).
**The cache fills itself in CI (2026-10-28, R-1327; replaces the 2026-10-27 night's DooPlex filling run).** Images with
zstd layers (Home Assistant) are read with the `zstandard` package, version 0.25.0, as a wheel pinned by the sha256 PyPI
publishes and checked every time it is opened; the workflows fetch it (`FELHOM_WHEEL_FETCH=1`) into the runner's cache.
Not the `zstd` program in the CI runner image: that image is built in the homelab repo, and changing it is a DooPlex
change. A missing or wrong wheel makes the zstd layers NOT CHECKED, said in the log's `RUNTIME` line — never a pass. A
new image is read on the night its tag first appears; the log's `RUNTIME read=… (… s) from-cache=…` line says how much
was read and how long it took. The DooPlex group (`documentation/security-watch/dooplex-workloads.txt`,
from homelab-manifests) is read the same way and mailed in its own block; Felhom changes nothing on DooPlex.
**Docker Hub's tag API is asked gently (2026-10-28, R-1334).** The 2026-10-28 night run was refused 15 times (HTTP 429)
when it sent 211 tag-list requests to `hub.docker.com` in about 2 minutes from six workers; a 3.5-minute dry run that
morning sent 224 and was refused none. So: the requests to Docker Hub are spaced (one per second across the workers);
a 429 waits (its `Retry-After`, else 10/30/60 s) and tries again, and the image is NOT CHECKED only after the fourth
try; a tag list is kept for 24 hours per registry path in the CI runner's cache (`~/.cache/felhom-watch-tags.json`, not
committed), so two names of one path (`lscr.io/linuxserver/x`, `linuxserver/x`) and a same-day re-run fetch nothing.
The log's `TAGS fetched=… from-cache=… retried-429=…` line counts it. No Docker Hub login is used. Two CI runners take turns, each with its own
cache, so the cache helps a same-day re-run on one runner, not the nightly; the spacing is what fixes the night (two
dry runs 2026-10-28: 0 refused). The image reader (`image_runtime.py`) also waits out a 429 and tries again (3 tries):
ghcr.io refused two blob reads when two dry runs read the same 14 new images 15 minutes apart.
@@ -370,6 +370,17 @@ builds them (`audits/update-rulings-2026-09-23/`).
both options. **Why (b):** decision 13's mark exists for "does not fit the memory" (RomM, R-635), and
only the app's own memory decides that. The cgroup peak stays in every record (`memory_cgroup_peak_pct`
in the ladder entry). R-652.
**Refined 2026-10-28 night (R-1338, the night brief's „fix the measurement — the gate reads the right figure"):** the
mark reads the LIVE anon — `anon` without the pages the app already gave back. An allocator that frees with
MADV_FREE leaves the pages mapped (`anon` keeps counting them) on the INACTIVE FILE list, and the kernel takes them
back first. Measured: Wanderer's Meilisearch read `anon` 83–96 % of its 384 MiB limit on the bench AND on 9202 (with
or without swap, with or without `MEILI_MAX_INDEXING_MEMORY`), 0 kills, while `file` was ~1 MB and `inactive_file`
~290 MB; it used ~100 MB. Figure (one home: catalog `scripts/memfigure.py`): the larger of `anon − max(0,
active_file + inactive_file − file)` and `active_anon + inactive_anon − shmem`, capped at `anon` — it errs high.
Wanderer v0.20.0 → v0.21.2 re-run on the bench: `proven`, no marks (search 83.3 % anon, **27.7 % live**); 9202:
95.2 % anon, **25.1 % live**. The evening's „17.7 % with the cap" was a different container (the one after the
swap, started over existing data), not the cap's effect. The catalog change (and Wanderer's entry without
`memory_tight`) is prepared, not pushed — the morning list. `audits/night-2026-10-28/r1338-meili/`.
23. **The push-time test-record gate asks the registry — for moved refs only** — *decided by CC
unattended 2026-09-23 night — operator may reverse.* *One sentence:* may a `--fast` (hook) gate use
@@ -1098,6 +1109,171 @@ its length, and both fixes cost something the household would notice — operato
night leg logged `plex: skipped — not_proven` and a hand press took the step; on 0.341.0-rc.1 the night leg logged
`plex: security fix CVE-2026-96652,CVE-2026-96654,CVE-2026-96655,CVE-2026-96656 taken` and ended `done` in 30.1 s
after the update's second-drive copy and undo copy. Released as controller 0.341.0, global floor 11:24 UTC.
**Batch use, 2026-10-27 (the lane's first live use, `audits/security-app-updates-2026-10-27/`):** the security
watch (R-1303) flagged 38 pins; a hand triage put 15 apps in the lane. One negative control first (TO
`busybox:1.36.1` → `failed`, undone), then walks on 9202 three at a time, each written to the drill, then **a STOP
per batch of about five** before the live catalog: batch 1 `06e603e` (rallly, romm, code-server, outline, vikunja),
batch 2 `7b0071e` (n8n, privatebin, docmost, grafana), batch 3 `65a6b11` (homebox, mealie, audiobookshelf,
bentopdf, uptime-kuma) — 14 steps, 12 with the seed read back after the update, 2 `seed: none` (code-server: no
script route; bentopdf: no data). Two notices with no CVE/GHSA id (wishlist's critical account takeover,
bookstack's two leaks) could not use the lane and went as NORMAL steps (bench 9401 + box) in the same batches.
**What the batch use taught:** (a) a walk can be `inconclusive` because the FIXTURE is stale, not the step — four
were (Rallly 4.15's code-only sign-in, Jellyfin 10.11's wizard, Homebox 0.26's entities API, Mealie's generated
admin password); each was fixed and the walk run again; (b) three walks at a time on 9202 (25 GiB) kept every soak
clean; (c) a one-step-per-app lane stops below a fix that needs a NEW main version — those stay big steps with a
row each (R-1311, R-1313–R-1322).
### 2026-10-26 (night brief) — D55: demo-hp's one clean-up window gets a cap of 260
268. **demo-hp's one-shot clean-up window is granted with a raised cap of 260, not 220 (D55 = 260).** *Operator,
2026-10-26 night.* Options: A) 260 — cost: one window may remove up to 260 old copies on a test box (the box still
removes only what its normal keep rule selects, and the fake-copy guard still runs); B) 220 as first ruled — cost:
the plan grows ~14 a night (209 on 2026-10-26, ~223 at the next run), so it is refused again. Why A: the cap must sit
above the honest plan on the night it is used. CC's token lacks `offsite:write`, so the operator made a one-purpose
token `cc-d55-window` (Off-site write only); CC used it once, 2026-10-26 19:10:31Z (`max:260` stored, read back).
**The window ran** 2026-10-27 03:18:15–03:18:41Z (window 17): 223 of 223 planned removed, 373 → 150, closed by the
box, no alarm (hub row + the box's own log agree). The operator revokes the token.
### 2026-10-27 (evening, operator 21:33) — D60: CC never deletes from the secret store; D56–D59 = CC's picks
271. **CC never deletes from the `sec` store, with or without the operator's yes (D60).** *Operator, 2026-10-27 21:33.*
`sec rm` is the operator's command, run in his own terminal. Why: one purpose of the store is that CC cannot delete
by mistake (the old credentials file was wiped once). Made mechanical the same evening: cc-secrets 0.4.0 (`092e282`,
hardened `27fd806`) refuses `sec rm` in every form and any removal or overwrite of the store file or the age key
(Bash and Write/Edit guards), proven in a new CC session. The 46 names removed earlier that day by CC (on the
operator's yes, before this ruling) can come back by `git revert` of their `rm NAME` commits — the operator's act.
272. **D56 = keep SparkyFitness offered** (R-785) while its two flaws have no fix — both need a family account or a leaked
photo link; the fix rides its big step. *Operator, 2026-10-27 21:33 (CC's pick).*
273. **D57 = keep Gitea's repository import on** (R-1315) — sign-up is closed; judged again in its big step. *Operator,
2026-10-27 21:33 (CC's pick).*
274. **D58 = Termix waits for its big step** (R-1311); the forged-address header is NOT stripped now — stripping it lets
a stranger lock the family out (R-775). *Operator, 2026-10-27 21:33 (CC's pick).*
275. **D59 = hide Wanderer from new installs until its big step is done** (R-1313) — any server on the internet can
overwrite its records with no login; no box runs it; an installed copy is not touched. *Operator, 2026-10-27 21:33
(CC's pick).*
276. **A Home Assistant monthly release (2026.9 → 2026.10) is the SAME main version for the ladder, so a security fix
may ride the lane.** *Decided by CC unattended 2026-10-27 — operator may reverse.* Options: A) the lane — the one
comparator (`stacks.CompareImageRefs`, Q3) parses „2026" as the major, a notice id exists (CVE-2026-111497, Python
Brotli 1.2.0 → 1.2.1 inside the image); cost: a monthly HA release carries feature changes into the night lane;
B) a normal step — cost: a second rule beside the comparator for one app's version shape (Q3 warns that is how a
major gets automated by accident). Why A: the brief („a normal step if it counts as a main version in our ladder
rules, else the lane") and the one-comparator rule; the box walk + soak is the guard either way.
### 2026-10-28 (evening, attended) — D57 judged again in Gitea's big step: imports from three hosts only
280. **Gitea's repository import is limited to github.com, codeberg.org and gitlab.com** (`[migrations] EGRESS_MODE=strict`,
`ALLOWED_HOST_LIST`, Gitea 28's own egress rules) — this replaces D57's „keep import on, unrestricted" (decision 273).
Measured on 9202 with 28.2.0: the default (`lax`) already refuses home-network and Docker addresses (422); the
allow-list also refuses every other public host (gitea.com 422) and lets GitHub import (201). Options: the allow-list
(cost: an import from a self-hosted forge or Bitbucket is refused) or 28's default (cost: the box fetches any public
address a family member names). *Operator, 2026-10-28, at the Gitea STOP; CC's pick.*
### 2026-10-28 (afternoon, attended) — the four big steps; D59 ends; Wanderer's inbound federation stays off
279. **D59 ends: Wanderer is offered again** after its big step v0.20.0 → v0.21.2 went live (catalog `1825247`), and
**its inbound federation stays OFF** — the template sets no `POCKETBASE_PROXY_SECRET`, so v0.21 rejects every
inbound ActivityPub delivery (fail closed, upstream's docs). Options: off (a family instance takes nothing from
strangers' servers; the route GHSA-fprh abused stays shut) or on (a generated shared secret; other servers deliver
follows, comments, updates). *Operator, 2026-10-28, at the Wanderer STOP; CC's pick both times.*
**[DESIGN] A pin move needs its step — also when no box runs the app (2026-10-28, stated here because the brief asked
for „the rule for a pin change when no box runs the old version" and this document did not say it).** The rule lives in
the catalog: `app-catalog-felhom.eu/CLAUDE.md` („An `image:` move needs its TEST RECORD") and its gates —
`check-test-record.py` (the newest ladder entry IS the compose) and `check-test-record-move.py` (a moved ref must add a
proven entry). There is no exception for an app no box runs: the writer (`upgrade-test.py --write-ladder`) refuses
unless the bench AND the box walk say `proven`, so every big step is a normal ladder step. A big step's UNDO is proven
on 9202 as well (the 2026-10-27 Jellyfin method, generalised in `audits/dockerhub-bigsteps-2026-10-28/undo_proof2.py`):
TO with failing checks must end `undone` and the seed must read back on FROM. **The broken probe must fail on any app:**
a single-page app answers 200 on every path, so a „no such path" probe passed and Termix's update ended `done`; the
tool now probes port 1. `test-record-move` also refuses a `memory_tight` step whose range does not raise the limit —
Wanderer's Meilisearch went 256 → 384 MB and was measured again (it sizes itself to its limit: 88.8 %).
### 2026-10-28 (day, attended) — RomM kept; the runtime cache fills itself in CI
277. **D61 = keep RomM offered** (R-1330) while no RomM release carries Node ≥ 24.22.1; the first one that does is taken
as a lane step (CVE-2026-111497). No Node process runs in RomM (gunicorn, rq and nginx — `ps` on demo-hp 9201) and the
setup gate is in front; the watch flags it every night until then. *Operator, 2026-10-28 (starting the day brief),
CC's pick.*
278. **The watch reads zstd layers in CI with a hash-pinned `zstandard` wheel, not with `zstd` in the CI runner image.**
*CC, 2026-10-28, the brief's choice („say which and why").* Options: A) the wheel (0.25.0, PyPI's sha256 per
Python/libc, checked on every open, fetched into the runner's cache) — cost: a download from PyPI when the cache is
empty, and a pin to renew when the runner's Python moves; B) `zstd` in `felhom-act-runner` — cost: a homelab-repo
change, an image rebuild and a k3s rollout on DooPlex, which the brief forbids, and every CI job depends on that
image. Why A: no DooPlex change, and a wrong or missing wheel is NOT CHECKED out loud, never a pass (`08` §11).
**The lane batch of 2026-10-28 (R-1332), how it ran — the method, not a new rule.** Twenty apps carried a bad runtime
(the watch's first full read). For each pin the registry's tags in the pinned tag's own shape were listed, and the newest
one in the same main version and the newest overall were READ FROM THE IMAGE (`image_runtime.py`), never from release
notes (`audits/runtime-fixes-2026-10-28/TABLE.md`). Three states: a fixed release in the same main version → a
security-fix step; a fix only in a new main version → the app's big-step row carries it; no fixed release → a row with
the exposure. The main version is the tag's first number, and for a `0.x` app the minor (Homebox 0.26 → 0.27 on
2026-10-27; Karakeep 0.33 → 0.34 today). Batches of about five, each walked on 9202 (`box_walk.py --security`, soak
600 s, the seeded data read back), the writer run on the live catalog, `catalog_gates.py --fast`, and a STOP before each
push. None of the eight apps has a bench fixture, so no bench ran (§6.4, the lane's stated trade). Two tool gaps found
on the way were fixed in the session: the drill mover moved two services that share one image only half (Dawarich), and
a drill commit made outside a walk (the revert to FROM) never reached the box's mirror before the install.
### 2026-10-27 (attended release block) — the line-test hold is fixed the same day; R-1218's live proof is waived
269. **The line-test hold waits until the held app has really slowed down — fixed in the controller the same day.**
*Operator, 2026-10-27 12:30 CET.* Options: A) fix in the controller now, prove it on an rc on demo-hp's 9201 while the
seed runs, ride today's 0.346.0 — cost: ~1.5 h, the release later in the afternoon; B) file it and fix later — cost:
a box that seeds all day keeps getting no weekly test. Why A: measured four refusals in an hour (qBittorrent sends
~14 s after its limit falls; the agent reads 5–15 s after the call). Built `710ceac`; live on `0.346.0-rc.1`: 94.5
Mbit/s, the limit back exactly (`audits/linetest-2026-10-27/`).
270. **R-1218 is released without its live proof (rule 2 waived for this row).** *Operator, 2026-10-27 15:15 CET.*
Options: A) keep both halves, waive the live proof — cost: released key code proven by red tests only; a box that
lost its key file entirely now gets a 409 on its ceremony instead of a silent demotion; B) revert both halves — cost:
a hub 0.173.1 and a second deploy, and the demotion bug stays. Why A: no product path makes the box's saved off-site
target „off" on a hub box (the hub page's switch did not reach Tester 1's target; the household's clear is refused on
a hub tier), so no live run can tell the old code from the new; the change only widens a safety step and adds a
refusal. R-1312 asks what the hub switch does on the box.
### 2026-10-26 (evening brief) — D53: held apps reach the operator; D54: demo-hp's stuck clean-up; R-1297 (B): a second CI runner
265. **A held app reaches the OPERATOR first, never the household (D53 = operator-only reminders first).** *Operator,
2026-10-26 evening (starting the brief is the yes).* Options: A) operator only — cost: a household whose app is held
still learns only from the app's page; B) the operator and, for the two holds a household can clear, the household
too — cost: two more customer mails to write and translate, about a stop they may not understand. Why A: the
operator can act on every reason; household mails can follow once the operator list has run. Built from `08` §10.
266. **demo-hp's off-site store gets ONE clean-up window with a raised cap of 220, through the hub's existing one-shot
grant; the cap rule itself is unchanged (D54 = prune once).** *Operator, 2026-10-26 evening.* Options: A) a one-shot
grant — cost: one window prunes 209 snapshots at once on a test box (the plan was read honest, R-1294); B) change the
cap rule — cost: hub and controller code, and a weaker guard against a mass deletion on every box. Why A: the guard
stays as strong as it is; the grant expires after one use.
267. **CI gets a second runner on DooPlex; both runners have 2 CPUs (R-1297 B).** *Done by the operator, 2026-10-26.*
Options: A) a second runner — cost: DooPlex CPU while two jobs run; B) only trim the suites — cost: every repo's job
still queues behind felhom.eu's run. Why both (the operator's „both"): the trim makes one run short, the runner stops
the queue. The trim (A) is CC's and keeps every check (path filters, a tag run and a nightly run).
### 2026-10-26 (attended release run) — D51: Kimai's hold; D52: the missed weekly golden
263. **demo-hp's Kimai, held by the crash-loop guard since the 2026-10-14 power drill, is started again, not removed
(D51 = Start).** *Operator, 2026-10-26 07:57.* Options: A) Start — cost: if it crash-loops again it is held again;
B) remove it through the product — cost: the test app and its data are gone. Why A: the household's Start is the
designed way to lift this kind of hold (decision 28), and it is a test box. Result: hold lifted, healthy (R-1286).
264. **The missed Sunday bake is made up the same day, on the new controller, and the waiver covers that one day only
(D52 = bake today on v0.344.0).** *Operator, 2026-10-26.* Options: A) renew the waiver to the next Sunday — cost: a
week of new installs on a golden 13 releases behind; B) bake today — cost: about an hour of the release day. Why B:
the gate goes green by a fresh golden, not by a waiver. The weekly Sunday bake (`runbooks/nightly-rotation.md`)
stays the rule; every Sunday-night brief names it.
### 2026-10-25 (evening, attended) — D50: which agent packages the registry keeps
262. **The registry keeps the newest 5 released agent versions, plus the hub's MinAgent floor, plus the version the hub's
day-0 manifest names; CI asserts exactly these (D50 = A).** *Operator ruling 2026-10-25 evening.* Options: A) this
— cost: a box on a version outside the set cannot fetch its own binary again (none is, on the day); B) the newest 10,
never pruned by hand — cost: today's four are gone, so CI stays red until ten new versions exist. Why A: it is what
the operator prunes to, and the two pinned versions are the only old ones anything still asks for. Built: agent
`scripts/retention-policy.json` (`generic_versions_kept` 5, `pinned`) + `check-published-versions.py`; the pins are
copies of hub state, updated by the session that records a vouch or a new MinAgent (R-1290).
### 2026-10-25 (attended release run) — D49: a restore that does not start keeps both copies; D44–D46: the review picks
+10 -2
View File
@@ -79,11 +79,19 @@ boxes installed. Nobody keeps a hand-written list.
**[DESIGN, operator ruling D43 = A, 2026-10-24 — committed agent `c8d3c17`, unreleased]** The host's root-key-only sshd
drop-in (D4, R-982) is an APPLIANCE-only file of the config bundle: written only when the root-owned install record
says `appliance`; on a `byo` record nothing is written and a copy the bundle wrote earlier (this path, our first line)
is removed; a box whose record proves nothing is left as it is (R-1257).
is removed; a box whose record proves nothing is left as it is (R-1257). **[FACT] 2026-10-25 (BYO test host, agent
0.164.0 → 0.165.0):** the removal came one bundle LATE — the bundle that brings the new wrapper is planned by the OLD
one (R-1285). **[DESIGN — R-1285, agent `abcc1e6`, unreleased]:** right after every bundle install the agent asks the
wrapper now on disk for a policy pass (`mode: "bundle-policy"`), which removes our appliance-only files from a BYO
record (no signature: it only removes a file we wrote; a failing `sshd -t` puts it back).
**[DESIGN — R-1285 follow-up, agent `b1bc63d`, unreleased]:** in the normal delivery the bundle job runs in the OLD
process (measured on demo-hp 2026-10-26: the bundle 09:03:07–09:03:09, the restart into 0.166.0 at 09:03:10), so the
new agent also runs the pass once right after its self-update commits (`selfupdate.Manager.SetOnCommitted`). Only a
box coming from 0.164.0 can show it: 0.165.0's wrapper already applies D43 at plan time.
- **The Proxmox MAJOR upgrade** (PVE 9 → 10). It is a later step of its own, drilled first (R-808 item 5).
- **`cloudflared` and the other infrastructure images** (traefik, filebrowser). **[FACT] (C8)** They are containers in
the guest, pinned in the controller (`internal/infra/infra.go:26`: `cloudflare/cloudflared:2026.6.0`, since
2026-06-11 — *`2026.9.3` today, corrected 2026-10-24*) and baked into the golden; upstream was `2026.9.3` on 2026-10-04. They move only by a controller release
2026-06-11 — *`2026.9.3` from 2026-10-24; `2026.10.3` since controller v0.345.1, 2026-10-26 — Cloudflare's eMudhra notice, R-1300*) and baked into the golden; upstream was `2026.9.3` on 2026-10-04. They move only by a controller release
— the app-image question (`09`), not an OS package. The gap is R-838.
---
@@ -72,4 +72,7 @@ secret rule or a review step, or remove a rule — that is the operator's. The f
that uses a value by NAME and never prints it, and Claude Code hooks in `~/.claude/settings.json` — so every CC
session on DooPlex — that refuse the known leak shapes, mask stored values in tool output, and a nightly sweep of old
session records that mails NAMES only. Built 2026-10-17 (R-1118); evidence `audits/cc-creds-build-2026-10-17/`.
**D60 (operator 2026-10-27 21:33, `09` §3 decision 271): CC never deletes from the store.** `sec rm` is the operator's
command; the hooks refuse it in every form, and any removal or overwrite of the store file or the age key (Bash and a
`pre-write` Write/Edit hook, cc-secrets ≥ 0.4.0).
`runbooks/secrets.md` stays the home of the CLUSTER Secrets.
@@ -84,7 +84,13 @@ directly; the only guard is that the header NAME is a per-box secret, which trae
client request and sets only for a browser holding the dashboard's files pass
(`felhom-controller/controller/internal/infra/filebrowser_sso.go:15-22`, `internal/web/files_sso.go`). The name file's
creation race was fixed by review round 2 (controller `b01bb4b`). The pick: FileBrowser joins only the network traefik uses, so no app
container reaches it directly. Not built yet.
container reaches it directly. **Built 2026-10-25 night (controller `7ea942a`, unreleased):** a network of its own for
the route, `felhom-files` — traefik is on it, the CHECKED FileBrowser joins it by id after R-1126's default-login check,
and FileBrowser leaves traefik-public; OnlyOffice joins it while — and only while — its FileBrowser link is on (it
fetches and saves documents at `http://filebrowser:80`), the one stated exception. **[FACT] measured on the night's rig:**
before, from the qBittorrent and Transmission containers the forged header as the household user got the drive's
listing (200); after, no answer (`000`); the household's „Fájlok ↗" walk still gets 200 through traefik
(`audits/night-2026-10-25/rig/r1281-*.txt`).
## 6. What we accept (do not re-report)
@@ -169,8 +169,10 @@ download (R-1019). *(Fixed since: catalog `c50adfc` marks the download and watch
`app-catalog-felhom.eu/templates/transmission/.felhom.yml:46-51`; noted 2026-10-24.)* **[DESIGN — the operator picked a code change 2026-10-25 (D44); row R-1283]:** the same commit also
marks the download folders of NZBGet, SABnzbd and MeTube `excluded` (`templates/{nzbget,sabnzbd,metube}/.felhom.yml`).
NZBGet and SABnzbd stay excluded (their files can be fetched again). The pick for MeTube: `optional`, so the
second-drive copy carries it and the off-site copy does not — a MeTube video can be gone from its source site. Not
built yet. **[DESIGN]** The per-drive media bind is declared `excluded` for every media app — the family's
second-drive copy carries it and the off-site copy does not — a MeTube video can be gone from its source site.
**Built in the DRILL catalog 2026-10-25 night (`app-catalog-drill` `6733764`, not live):** `class: optional`, and the
download-binds gate allows `optional` only for an app named with its ruling (`OPTIONAL_BY_RULING`); mandatory and
unlisted stay refused. The live push is the operator's (the Monday list). **[DESIGN]** The per-drive media bind is declared `excluded` for every media app — the family's
media is no single app's data; whether the library gets its own household-level backup is a separate decision.
## 8. Removal and export assume one drive per app
@@ -275,7 +277,9 @@ returns** (G7f).
**[DESIGN — the operator picked a code change 2026-10-25 (D44); row R-1282]:** the „Később"
03:30 media restart is an IN-MEMORY timer — a controller restart forgets it and only the notice stays
(`internal/web/media_events.go` `handleMediaRestart`, `time.AfterFunc`). The pick: the controller stores the due
time and runs the restart after a restart of its own. Not built yet.
time and runs the restart after a restart of its own. **Built 2026-10-25 night (controller `b5863a9`, unreleased):**
`settings.media_restart_later_at`; at start `ResumeMediaLater` re-arms it, runs it at once when it passed while the
controller was down, and clears it once it ran.
**[DESIGN — confirmed by the operator 2026-10-25 (D44 = all picks, R-1265)]:** the Sonarr/Radarr API key is READ from
`/config/config.xml`; the „set at install" option §6 calls cleaner was not built (`internal/mediawire/mediawire.go:336-345`).
@@ -392,6 +392,10 @@ four version observables at TO, a 600 s memory soak), and the only writer turns
ladder step. Every box on controller >= 0.341.0 takes it at night with the usual guards (backup first, undo on a
failed health check, held / stopped / needs_person / W+5h respected).
**Trigger (2026-10-26, R-1303):** a mail from the nightly security watch („[Felhom security] …", `08` §11) starts the
lane: it names the program, our version and the fixed version. An app notice goes this lane; a box program's (traefik,
cloudflared, the file manager) is a controller release — the cloudflared 2026.10.3 run (R-1300) is the worked example.
**Components:** catalog `3898593` (`ladder.py check_security`, the two test-record gates, `upgrade-test.py --write-ladder
--security`, `box_walk.py --security`); controller v0.341.0 (`legCandidate`).
@@ -405,4 +409,10 @@ a hand press took the step; on 0.341.0-rc.1 the night leg logged `plex: security
**Gap:** an app with no box fixture (Plex today, R-1238) is checked only by health, version and the soak — no data is
read back. `files_may_change` is a bench measurement and reads `false` when no bench ran (decision 255 item 7).
**Batch use (2026-10-27, `audits/security-app-updates-2026-10-27/`):** 14 security-fix steps in three batches, each
pushed live after the operator's yes at a batch STOP (catalog `06e603e`, `7b0071e`, `65a6b11`); 12 read the seed back
after the update, 2 are `seed: none`. demo-hp's 9201 read `06e603e` at once and holds RomM's step for its night leg
(`live-readback-batch1-9201.txt`). Notices with no CVE/GHSA id go as normal steps in the same batches (wishlist,
bookstack). Four stale fixtures were found and fixed by the walks' `inconclusive` C1 (`09` decision 255, batch note).
---
@@ -142,7 +142,9 @@
**Evidence (as written):** New FIRST sidebar page `/launcher`: colored tiles (deterministic slug color or `.felhom.yml` `brand_color`) + white glyph/monogram, one per openable app (tile ⟺ „Megnyitás" — subdomain presence is the single criterion; controller excluded). Operational → `<a target=_blank>` to the public URL; stopped → greyed + state badge, no link. `/` stays the Vezérlőpult. Endpoint-level + render-test verified; `felhom-controller/REPORT.md` (2026-07-24)
**Gap / roadmap (as written):** Live operator click-through of a real tile → app pending (browser automation not available on DooPlex). Follow-up: curate `brand_color` for top catalog apps (R-72). Sharing the launcher outside the household is now the capability-URL guest link — see the row below
**Walked 2026-10-28 night (9202, endpoint-level — the page and links the browser receives):** `/launcher` answered 200 with one tile per openable app (`hike`, `paperless`, `tasks`), each a link to the app's public address; the controller has no tile. `audits/night-2026-10-28/part5-claims/launcher-walk.*`.
**Gap / roadmap (as written):** Live operator click-through of a real tile → app pending (browser automation not available on DooPlex; the endpoint walk above stands in). Follow-up: curate `brand_color` for top catalog apps (R-72). Sharing the launcher outside the household is now the capability-URL guest link — see the row below
---
@@ -157,7 +159,7 @@
**Status (as written):** **IMPLEMENTED**
**Evidence and gap (as written — this row's text carries a `|` outside code, so its last cells are kept together as they stood):** 160-bit `crypto/rand` token, constant-time match (empty stored = disabled = byte-identical to the mux default 404); guest headers `noindex`/`no-referrer`/`no-store`; optional SEPARATE bcrypt share password + its own per-IP attempt map; signed cookie `HMAC(token`\ | `passwordHash)` keyed with `session_secret` (rotate-token OR change-password invalidates all cookies); token redacted in logs (`/s/<redacted>`). Groups A–G (14 tests) + 3 red-proofs; **§13 endpoint-level live validation on 9201 all-pass** (`felhom-controller/REPORT.md` 2026-07-24). **Design ruling: member accounts SUPERSEDED by this capability-URL model; per-member tile visibility parked under the SSO arc (R-15).** | Full operator browser click-through + a validation doc pending → then PROVEN-LIVE. Accepted residuals: link-preview crawlers fetch once (noindex prevents indexing); reverse-proxy/CF access logs hold the path (ops-tier); the modal link carries the request Host (LAN-IP admin ⇒ LAN-IP link)
**Evidence and gap (as written — this row's text carries a `|` outside code, so its last cells are kept together as they stood):** 160-bit `crypto/rand` token, constant-time match (empty stored = disabled = byte-identical to the mux default 404); guest headers `noindex`/`no-referrer`/`no-store`; optional SEPARATE bcrypt share password + its own per-IP attempt map; signed cookie `HMAC(token`\ | `passwordHash)` keyed with `session_secret` (rotate-token OR change-password invalidates all cookies); token redacted in logs (`/s/<redacted>`). Groups A–G (14 tests) + 3 red-proofs; **§13 endpoint-level live validation on 9201 all-pass** (`felhom-controller/REPORT.md` 2026-07-24). **Design ruling: member accounts SUPERSEDED by this capability-URL model; per-member tile visibility parked under the SSO arc (R-15).** | **Walked 2026-10-28 night on 9202 (endpoint-level, `audits/night-2026-10-28/part5-claims/launcher-walk.*`):** switched on from the launcher (303 `flash.share.enabled`); the link opened with NO session → 200, the household's app tiles, no admin link; a wrong token → 404; rotate → the old link 404, the new one 200; switched off → 404 (it was off before the walk). NOT-A-FINDING: an unknown non-`/s/` route answers an anonymous visitor 302 to the login page, so a wrong token is told apart from an unknown ROUTE (404 vs 302) — what the design hides is a wrong token from a disabled one, which both answer 404. → PROVEN-LIVE. Accepted residuals: link-preview crawlers fetch once (noindex prevents indexing); reverse-proxy/CF access logs hold the path (ops-tier); the modal link carries the request Host (LAN-IP admin ⇒ LAN-IP link)
---
@@ -6,17 +6,17 @@
</style></head><body><div class="wrap">
<h1>Where Felhom stands</h1>
<div style="color:#8fa0b8;font-size:12.5px;margin:7px 0 4px;max-width:1100px;line-height:1.5">What we built, what happens when things go wrong, and what is still missing. <b style="color:#cbd7e8">Generated from <code>where-felhom-stands.yaml</code></b>, which cites the capability map, register row or evidence document behind every claim — and which is checked by <code>scripts/check_stands.py</code>.</div>
<div style="color:#6b7a91;font-size:11.5px;margin-bottom:16px">Verified 2026-08-22 against felhom-agent <code>40d857b527</code>, felhom-controller <code>2da259af38</code>, hub <code>877fcd2a38</code>. <b style="color:#fbbf24">15 claim(s) carry a recorded status move</b> (8 re-checked in this pass) — each is marked on the page.</div>
<div style="display:flex;gap:22px;flex-wrap:wrap;background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:11px 14px;margin-bottom:18px"><div style="display:flex;gap:8px;align-items:flex-start"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:11.5px"><b>Walked</b> <span style="color:#7c8aa3">(20)</span><span style="display:block;color:#6b7a91;font-size:10.5px">done end to end on real hardware, evidence on file</span></span></div><div style="display:flex;gap:8px;align-items:flex-start"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:11.5px"><b>Built</b> <span style="color:#7c8aa3">(15)</span><span style="display:block;color:#6b7a91;font-size:10.5px">shipped and tested, the real path never walked</span></span></div><div style="display:flex;gap:8px;align-items:flex-start"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:11.5px"><b>Partial</b> <span style="color:#7c8aa3">(16)</span><span style="display:block;color:#6b7a91;font-size:10.5px">some walked, some not — the note says which</span></span></div><div style="display:flex;gap:8px;align-items:flex-start"><span style="width:8px;height:8px;border-radius:50%;background:#64748b;flex:0 0 8px;margin-top:5px"></span><span style="font-size:11.5px"><b>Missing</b> <span style="color:#7c8aa3">(4)</span><span style="display:block;color:#6b7a91;font-size:10.5px">does not exist</span></span></div><div style="display:flex;gap:8px;align-items:flex-start"><span style="font-size:11.5px"><b style="color:#7dd3fc">needs-hardware</b><span style="display:block;color:#6b7a91;font-size:10.5px">only a running box could settle it</span></span></div></div>
<div style="color:#6b7a91;font-size:11.5px;margin-bottom:16px">Verified 2026-08-22 against felhom-agent <code>40d857b527</code>, felhom-controller <code>2da259af38</code>, hub <code>877fcd2a38</code>. <b style="color:#fbbf24">17 claim(s) carry a recorded status move</b> (8 re-checked in this pass) — each is marked on the page.</div>
<div style="display:flex;gap:22px;flex-wrap:wrap;background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:11px 14px;margin-bottom:18px"><div style="display:flex;gap:8px;align-items:flex-start"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:11.5px"><b>Walked</b> <span style="color:#7c8aa3">(23)</span><span style="display:block;color:#6b7a91;font-size:10.5px">done end to end on real hardware, evidence on file</span></span></div><div style="display:flex;gap:8px;align-items:flex-start"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:11.5px"><b>Built</b> <span style="color:#7c8aa3">(13)</span><span style="display:block;color:#6b7a91;font-size:10.5px">shipped and tested, the real path never walked</span></span></div><div style="display:flex;gap:8px;align-items:flex-start"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:11.5px"><b>Partial</b> <span style="color:#7c8aa3">(15)</span><span style="display:block;color:#6b7a91;font-size:10.5px">some walked, some not — the note says which</span></span></div><div style="display:flex;gap:8px;align-items:flex-start"><span style="width:8px;height:8px;border-radius:50%;background:#64748b;flex:0 0 8px;margin-top:5px"></span><span style="font-size:11.5px"><b>Missing</b> <span style="color:#7c8aa3">(4)</span><span style="display:block;color:#6b7a91;font-size:10.5px">does not exist</span></span></div><div style="display:flex;gap:8px;align-items:flex-start"><span style="font-size:11.5px"><b style="color:#7dd3fc">needs-hardware</b><span style="display:block;color:#6b7a91;font-size:10.5px">only a running box could settle it</span></span></div></div>
<div style="font-size:15px;font-weight:600;margin:0 0 9px">The journey</div>
<div style="color:#6b7a91;font-size:11.5px;margin-bottom:10px">Seven stages, left to right, as they happen to a person.</div>
<div class="grid7">
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">1</span> &nbsp;Getting a box</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">A blank machine installs itself from our own boot image and registers itself as unclaimed — proven on two different boards<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Two boards: N100 2026-07-18, HP t740 2026-07-21.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Bare-metal Felhom ISO (blank hardware → zero-touch auto-ins… · evidence tests/VALIDATION-n100-rehearsal-2026-07-18.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">The installer is published rather than pushed: rolling it back is one act<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Gate 6 of hostinstall_gates asserts the manifest names an installer-v tag; ran green tonight.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: gate 6 asserts the manifest names an installer tag, but no walk of a rollback is on file</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map The installer is PUBLISHED, not pushed · register R-110</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Installing onto hardware the customer already owns — the path exists, the first real one has not happened<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">UPGRADED: a real --mode byo install completed on demo-hp 2026-08-09 (Day-0 provision SUCCESS, 3m49s). Still not a customer's own hardware, so not 'walked' — but 'has not happened' is now false.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">A machine that ends up on the wrong network port explains itself on screen and finds its way back — proven in a virtual drill, never on metal<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Map says the same: PROVEN-LIVE (nested drill — nested != metal).</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Box survives a wrong-NIC install · evidence audits/SPIKE-firstboot-nic-sweep-2026-07-22.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Reinstalling a machine we previously installed refuses, because our own removal leaves a name service holding the port our own installer checks<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Warning card. Confirmed live 2026-08-09; dnsmasq restarted by --uninstall seizes :53.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-272 · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div></div>
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">2</span> &nbsp;Making it theirs</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">An emailed one-time code; the customer sets their own password and the operator never sees it<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Exercised live 2026-08-09: reset code accepted at /claim, 302 + session.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Customer claim: one-time emailed code → customer sets own p… · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">The customer can bind their own machine from a link, with no operator present — done once, for real<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">attempts=0, locked=0, source customer_selfbind, 2026-07-18.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Customer binds their own appliance (self-service) · evidence tests/VALIDATION-n100-rehearsal-2026-07-18.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">It has never been done by a person who is not the operator<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Map records MISSING (as evidence). Still true after 2026-08-09.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map A customer (not the operator) performs a restore via UI alone</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Each of the two secrets has one name on every surface, and the re-enrol mail points at a page a rebuilt machine shows<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Shipped (controller v0.211.0, hub v0.104.0/v0.105.0); no customer has typed the passphrase yet. Operator ruling 2026-10-12 (S13). The old defect cost a real code on 2026-08-09.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-282 · register R-295 · register R-323 · register R-327</span></span></div></div>
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">3</span> &nbsp;Using it</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Apps installed from a catalog of about 52, with a memory guard and health-aware progress<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">53 templates listed on the rebuilt box 2026-08-09; deploy driven live.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Deploy an app from the catalog (env config, memory guard, h… · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Start, stop, restart, update, logs, remove — and the parts that must not be stopped cannot be<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: no walk document cited by the map row or anywhere else</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map App lifecycle: start/stop/restart/update/logs/remove/redeploy · register R-108</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Reachable from anywhere through a tunnel, per-app addresses<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Verified tonight: the rebuilt box answered on its public URL from outside.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Remote access via Cloudflare Tunnel + Traefik (per-app subd… · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Reachable on the home network when the internet is down<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#1b2740;color:#7dd3fc;font-size:10px;white-space:nowrap">needs-hardware</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Only an observation on a running box with WAN pulled could settle it. Boxes are off.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map LAN access when internet is down (lan_resolver)</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Phone photos, documents with text recognition, files from Windows Explorer or a Mac<span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Files from Windows Explorer / Mac Finder (SMB server) · evidence audits/SPIKE-lan-discovery-2026-07-18.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">A one-tap launcher, and a read-only guest link for visitors<span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Indítópult (app launcher) — one-tap grid of the household's…</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#64748b;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-heigLine truncated
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">3</span> &nbsp;Using it</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Apps installed from a catalog of about 52, with a memory guard and health-aware progress<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">53 templates listed on the rebuilt box 2026-08-09; deploy driven live.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Deploy an app from the catalog (env config, memory guard, h… · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Start, stop, restart, update, logs, remove — and the parts that must not be stopped cannot be<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was built</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Walked 2026-10-28 night on scratch 9202: install, stop, start, restart, logs; traefik and cloudflared refuse a stop (403); remove with data leaves no volume and no container. The update half: the same day's guarded updates on 9202 (bench + box + undo walks).</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: a walk document is now cited (2026-10-28 night)</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map App lifecycle: start/stop/restart/update/logs/remove/redeploy · register R-108 · evidence audits/night-2026-10-28/part5-claims/lifecycle-walk.log · evidence audits/dockerhub-bigsteps-2026-10-28</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Reachable from anywhere through a tunnel, per-app addresses<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Verified tonight: the rebuilt box answered on its public URL from outside.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Remote access via Cloudflare Tunnel + Traefik (per-app subd… · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Reachable on the home network when the internet is down<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#1b2740;color:#7dd3fc;font-size:10px;white-space:nowrap">needs-hardware</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Only an observation on a running box with WAN pulled could settle it. Boxes are off.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map LAN access when internet is down (lan_resolver)</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Phone photos, documents with text recognition, files from Windows Explorer or a Mac<span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Files from Windows Explorer / Mac Finder (SMB server) · evidence audits/SPIKE-lan-discovery-2026-07-18.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">A one-tap launcher, and a read-only guest link for visitors<sLine truncated
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">4</span> &nbsp;Drives</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">A new drive is found, offered, formatted, mounted and enrolled — including on awkward older boot layouts<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">moved twice: 2026-08-09 walked -&gt; built, then 2026-08-10 back to walked</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Applies to a NEW drive. Re-attaching an existing one after a reinstall is R-280 and fails.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: receipt found 2026-08-10: a live throwaway drive on felhom-pve walked scan -&gt; format -&gt; mount -&gt; PVE dir storage -&gt; one-click Regisztralas, with the resulting storage.cfg entry and systemd mount unit recorded. The map already read PROVEN-LIVE; the dataset was behind it. Scope unchanged: this is a NEW drive. Re-attaching an existing one after a reinstall is R-280 and still fails.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Drive wizard: scan/format/mount/enroll, incl. legacy-boot L… · register R-220 · evidence audits/SPIKE-raw-drive-enroll-2026-06-15.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Moving data between drives, crash-safe; removing a drive safely; unplug detected<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: no walk document cited</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Data migration between drives (all / per-app), crash-safe</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">A network drive can be browsed and hold bulk media, but may not hold an app's data — enforced<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">RefuseAsAppNamespace is the fail-closed predicate.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Network storage (NAS) is browse + bulk-media only · register R-108 · evidence audits/R108-network-app-namespace-2026-07-30.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">After a reinstall the data drive cannot be re-attached through any dashboard route<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Warning card. /api/disks/candidates returns empty; the restore page promises two clicks.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-280 · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div></div>
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">5</span> &nbsp;Backing up</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">App data on the machine, nightly database dumps, a copy on a second drive<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">moved twice: 2026-08-09 walked -&gt; built, then 2026-08-10 back to walked</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">True for every app but one, and that one was found on 2026-08-21: paperless-ngx's 72-table PostgreSQL was dumped nightly and written into a folder named after an app that does not exist, so it never entered the recovery unit, the second-drive copy or the off-site copy. Fixed and proven live 2026-08-22 (R-355) — the dump is now in the app's own unit and in the off-site snapshot for the first time. A catalogue-wide sweep, itself proven able to convict a planted case, says 1 of 53 was affected.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: receipt found 2026-08-10: an adversarial, destructive, unattended overnight campaign across both boxes and ep0, with A2 (one quiesce, two tiers) proven end to end. Map already read PROVEN-LIVE.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Tier-2 secondary-drive copy: class-driven legs · register R-355 · evidence audits/CAMPAIGN-8-backup-restore-2026-07-27.md · evidence audits/DRILL-backup-truth-2026-08-21/evidence/phase4-paperl…</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">A whole-machine archive that lands off the guest's own disk — a single-drive machine is recorded as degraded rather than pretending<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: no walk document cited</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Whole-guest backup lands OFF the guest's own physical device · register R-165</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">An encrypted off-site copy, sealed with a key the operator cannot read<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">The COPY is real and the key is still unreadable to us — what failed is DAILY and UNBROKEN. The 2026-08-09 note said '18 snapshots, daily, unbroken'; the next snapshot after 2026-08-09 08:30 was 2026-08-21 22:17, put there by hand during the drill. Twelve days, no alarm. Two causes in series: the 2026-08-21 rebuild lost the off-box target (R-193's shape), and after the self-heal restored it EVERY per-app switch was still off, so the first run logged 'backup OK: 0 app(s) backed up, 14s'.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: the claim is about a CONTINUING daily copy; a 12-day silent gap was found on 2026-08-21 and nothing reported it</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Offsite (restic → Hetzner Storage Box) · register R-199 · register R-193 · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md · evidence audits/REPORT-DRILL-backup-truth-2026-08-21.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">The backups prove themselves: a restore is actually performed, uLine truncated
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">6</span> &nbsp;When something goes wrong</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">The machine watches itself and repairs some faults without telling anyone it had to<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">R-264 records that the self-heal counters reach the hub and are decoded nowhere.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: no walk document cited</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Box survives an unattended app or guest-network failure · register R-264</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Failures reach the operator by email, one mail per run, every failing app named<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">CONFIRMED against source: backup_run_failures digest is allowlisted (api/handler.go:1837), operator-only (dispatcher.go:423), templated (templates.go:48); recovery_unit_capture_failed is record-only (dispatcher.go:376). NOTE: R-182's register row still describes the PRE-FIX behaviour — see R-289.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: the digest is wired and source-verified, but no run of it has been observed delivering</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map A failed per-app Tier-1 backup reaches the OPERATOR — EVERY… · register R-182</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Failures reach the customer<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">The customer leg is built; today's log shows customer-channel rows skipped as operator_only.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map App crashes → customer notified (one event per transition, …</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">An already-paired box is still told to pair itself<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Warning card.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-214 · register R-235</span></span></div></div>
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">6</span> &nbsp;When something goes wrong</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">The machine watches itself and repairs some faults without telling anyone it had to<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">R-264 records that the self-heal counters reach the hub and are decoded nowhere.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: no walk document cited</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map Box survives an unattended app or guest-network failure · register R-264</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Failures reach the operator by email, one mail per run, every failing app named<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was walked</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">CONFIRMED against source: backup_run_failures digest is allowlisted (api/handler.go:1837), operator-only (dispatcher.go:423), templated (templates.go:48); recovery_unit_capture_failed is record-only (dispatcher.go:376). NOTE: R-182's register row still describes the PRE-FIX behaviour — see R-289.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: the digest is wired and source-verified, but no run of it has been observed delivering</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map A failed per-app Tier-1 backup reaches the OPERATOR — EVERY… · register R-182</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#60a5fa;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Failures reach the customer<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">The customer leg is built; today's log shows customer-channel rows skipped as operator_only.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">capability-map App crashes → customer notified (one event per transition, …</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">An already-paired box no longer tells anyone to pair it — its console says there is nothing to do<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#3a2a12;color:#fbbf24;font-size:10px;white-space:nowrap">changed 2026-08-09, was partial</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Was a warning card (the console kept showing the pairing code). Fixed by ISO 1.28.0 (R-535; R-214, R-235 closed). Walked 2026-10-29 00:04 on Tester 1 (paired, claimed): the console reads, in Hungarian and English, that there is nothing to do on this machine and no need to log in — no pairing code.</span><span style="display:block;color:#9a7b3a;font-size:11px;margin-top:2px">why it moved: the defect is closed and the console was read live on a paired box (2026-10-29)</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-214 · register R-235 · evidence audits/night-2026-10-28/part5-claims/tester1-console-2026-1…</span></span></div></div>
<div style="background:#121b2c;border:1px solid #1f2c44;border-radius:6px;padding:14px 13px"><div style="font-size:14px;font-weight:500;padding-bottom:9px;margin-bottom:10px;border-bottom:1px solid #1f2c44"><span style="color:#4b5b76;font-family:ui-monospace,monospace">7</span> &nbsp;Getting everything back</div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">A rebuilt machine shows a full-page recovery screen without anyone looking for it, and says plainly that nobody can replace a lost recovery code<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Seen unsought on the rebuilt demo-hp 2026-08-09, seal date matching host_escrow.created_at.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-193 · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">The customer's code opens the sealed package and the data returns byte for byte — including accented Hungarian filenames, verified as raw bytes<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Still true, and re-proven 2026-08-22 (5/5 byte-identical, both accented names as raw bytes) — but the SCOPE is narrower than the sentence sounds and was silently narrower still until v0.218.0. The drill found the off-site restore had NO named-volume leg at all: the archive sat in the unit, the snapshot and the checking folder and was never replayed, under a success message (R-354, fixed and proven 2026-08-22). AND 40 of the 53 catalogue apps STILL cannot run this route at all — it refuses first, saying a running app is not installed (R-356, open). So: proven for an app that declares a data drive; unproven and currently unreachable for the class whose entire dataset is a named volume.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-201 · register R-354 · register R-356 · evidence tests/walk5-r201-2026-08-07/journal.md · evidence audits/REHEARSAL-byo-reinstall-2026-08-09.md · evidence audits/REPORT-DRILL-backup-truth-2026-08-21.md</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Walked end to end with no command line inside the machine (2026-08-07)<span style="display:inline-block;margin-left:6px;padding:1px 5px;border-radius:3px;background:#1b2740;color:#a78bfa;font-size:10px;white-space:nowrap">contested</span><span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">CONTESTED-RESOLVED: not a contradiction. The walk proves the ROUTE needs no guest shell; the map's MISSING row is about a NON-OPERATOR doing it, which has still never happened. Two questions, one word 'customer'.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-201 · evidence tests/walk5-r201-2026-08-07/journal.md · capability-map A customer (not the operator) performs a restore via UI alone</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#fbbf24;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">Putting restored files back where they belong is still manual<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">Warning card. Confirmed 2026-08-09: the restore lands in a verification folder and says so.</span><span style="display:block;color:#4b5b76;font-size:10px;margin-top:3px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace">register R-213</span></span></div><div style="display:flex;gap:8px;align-items:flex-start;margin-bottom:9px"><span style="width:8px;height:8px;border-radius:50%;background:#34d399;flex:0 0 8px;margin-top:5px"></span><span style="font-size:12px;line-height:1.45;color:#b8c4d6;text-wrap:pretty">The tripwire that says someone is opening this customer's backups does fire<span style="display:block;color:#7c8aa3;font-size:11px;margin-top:3px">CONFIRMED tonight from the hub store: escrow_blob_served 2026-08-09 10:19:41Z = 12:19 CEST in the operator's mailbox. R-281's original claim of silence is WITHDRAWN.</span><span style="display:block;color:#4b5bLine truncated
</div>
<div style="font-size:15px;font-weight:600;margin:22px 0 9px">When things go wrong</div>
@@ -155,17 +155,20 @@ claims:
band: journey
stage: 3
title: "Start, stop, restart, update, logs, remove — and the parts that must not be stopped cannot be"
status: built
status: walked
note: "Walked 2026-10-28 night on scratch 9202: install, stop, start, restart, logs; traefik and cloudflared refuse a stop (403); remove with data leaves no volume and no container. The update half: the same day's guarded updates on 9202 (bench + box + undo walks)."
sources:
- capability-map: "App lifecycle: start/stop/restart/update/logs/remove/redeploy"
- register: "R-108"
- evidence: "audits/night-2026-10-28/part5-claims/lifecycle-walk.log"
- evidence: "audits/dockerhub-bigsteps-2026-10-28"
changed:
from: walked
reason: "no walk document cited by the map row or anywhere else"
from: built
reason: "a walk document is now cited (2026-10-28 night)"
verified:
date: 2026-08-09
verdict: downgraded
depth: register+map
date: 2026-10-28
verdict: upgraded
depth: source-read
- id: use.tunnel
band: journey
stage: 3
@@ -207,13 +210,18 @@ claims:
band: journey
stage: 3
title: "A one-tap launcher, and a read-only guest link for visitors"
status: built
status: walked
note: "Walked 2026-10-28 night on scratch 9202 through the pages the browser receives: the launcher lists each openable app; the guest link opens with no login and no admin link, a wrong token is 404, rotate and switch-off kill the old link."
sources:
- capability-map: "Indítópult (app launcher) — one-tap grid of the household's openable apps"
- evidence: "audits/night-2026-10-28/part5-claims/launcher-walk.log"
changed:
from: built
reason: "walked live 2026-10-28 night (map E8, E9 → PROVEN-LIVE)"
verified:
date: 2026-08-09
verdict: confirmed
depth: register+map
date: 2026-10-28
verdict: upgraded
depth: source-read
- id: use.dlna
band: journey
stage: 3
@@ -453,16 +461,20 @@ claims:
- id: fault.already-paired
band: journey
stage: 6
title: "An already-paired box is still told to pair itself"
status: partial
note: "Warning card."
title: "An already-paired box no longer tells anyone to pair it — its console says there is nothing to do"
status: walked
note: "Was a warning card (the console kept showing the pairing code). Fixed by ISO 1.28.0 (R-535; R-214, R-235 closed). Walked 2026-10-29 00:04 on Tester 1 (paired, claimed): the console reads, in Hungarian and English, that there is nothing to do on this machine and no need to log in — no pairing code."
sources:
- register: "R-214"
- register: "R-235"
- evidence: "audits/night-2026-10-28/part5-claims/tester1-console-2026-10-29.png"
changed:
from: partial
reason: "the defect is closed and the console was read live on a paired box (2026-10-29)"
verified:
date: 2026-08-09
verdict: confirmed
depth: register+map
date: 2026-10-29
verdict: upgraded
depth: source-read
- id: recover.screen
band: journey
stage: 7
@@ -0,0 +1,27 @@
# cloudflared 2026.10.3 — the eMudhra notice (R-1300), 2026-10-26 evening
**The notice.** Cloudflare, 2026-10-20 (blog „8 eMudhra certificates are compromised"): eight eMudhra (emSign)
intermediate CA keys were weak (recoverable from the public certificates; six TLS, two code-signing). cloudflared
before 2026.10.2 trusts them. Docker users take the fixed image. Cloudflare: „do not resolve these errors by disabling
verification". Release notes: 2026.10.2 = Go 1.27.3 + new distroless base (the trust store); 2026.10.3 = newer
debian base + Go bump. 2026.10.4 (2026-10-26, today) adds a metrics-endpoint allowlist (VULN-176088) — not taken:
under a day old, and the notice names 2026.10.3.
**Image.** `cloudflare/cloudflared:2026.10.3` index digest
`sha256:faa8e0a1475f137c910be6025f43c8e4092fdd35461b31e19fd1390657a1ff39` (Docker Hub API and a pull on 9202 agree;
amd64 `sha256:c3f24df7…`); `--version` = `cloudflared version 2026.10.3 (built 2026-10-21-13:24 UTC)`.
(`part3-image-check.txt`)
**Part 1 — the list.** Three boxes report to the hub (demo-felhom, demo-hp, Tester 1); each guest 9201 runs
`cloudflare/cloudflared:2026.9.3` (`part1-boxes.txt`, `part1-hub-hosts.txt`). 9202 (scratch) has no tunnel. Tester 2: no box.
DooPlex: no cloudflared in k3s, Docker, systemd, dpkg or processes; the same queries find traefik/the hub (control)
(`part1-dooplex.txt`). Cloudflare account: CC holds no Cloudflare token (`sec list`); the connector versions are the
operator's look in Networking → Tunnels.
**Part 2 — the https-origin trap.** Every tunnel's remote route (cloudflared's own „Updated to new configuration" log
line, all three boxes): `*.<domain>` → `https://traefik`, `originRequest.noTLSVerify: true`, then `http_status:404`
(`part2-remote-config.txt`). traefik answers SNI `traefik` with `CN=TRAEFIK DEFAULT CERT`, self-signed
(`part2-origin-cert.txt`). No eMudhra chain → the new trust store refuses nothing on the origin leg: **the trap does
not apply.** The `noTLSVerify` is the day-0 recipe (R-510) for a leg that never leaves the guest (cloudflared and
traefik alone on the /29 `felhom-tunnel`); not changed tonight (the brief forbids touching certificate checks, and
turning verification ON needs traefik to present a cert cloudflared can verify — a design question, not tonight).
@@ -0,0 +1,57 @@
System clock synchronized: no
NTP service: inactive
failed
inactive
× chrony.service - chrony, an NTP client/server
Loaded: loaded (/usr/lib/systemd/system/chrony.service; enabled; preset: enabled)
Active: failed (Result: exit-code) since Wed 2026-10-21 05:23:50 CEST; 5 days ago
Invocation: 135c8cdc305140c8ac2bf943db811094
Docs: man:chronyd(8)
man:chronyc(1)
Oct 16 05:09:25 demo-felhom systemd[1]: Failed to start chrony.service - chrony, an NTP client/server.
-- Boot 56db71938b304a57bdedf30f89860e1f --
Oct 21 05:23:50 demo-felhom systemd[1]: Starting chrony.service - chrony, an NTP client/server...
Oct 21 05:23:50 demo-felhom chronyd[676]: chronyd version 4.8 starting (+CMDMON +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +NTS +SECHASH +IPV6 -DEBUG)
Oct 21 05:23:50 demo-felhom chronyd[676]: Loaded 0 symmetric keys
Oct 21 05:23:50 demo-felhom chronyd[676]: Using leap second list /usr/share/zoneinfo/leap-seconds.list
Oct 21 05:23:50 demo-felhom chronyd[676]: Frequency -2.666 +/- 0.016 ppm read from /var/lib/chrony/chrony.drift
Oct 21 05:23:50 demo-felhom chronyd[676]: Loaded seccomp filter (level 1)
Oct 21 05:23:50 demo-felhom chronyd[676]: Fatal error : Could not send notification to $NOTIFY_SOCKET
Oct 21 05:23:50 demo-felhom chronyd[676]: Fatal error : Could not send notification to $NOTIFY_SOCKET
Oct 21 05:23:50 demo-felhom systemd[1]: chrony.service: Main process exited, code=exited, status=1/FAILURE
Oct 21 05:23:50 demo-felhom systemd[1]: chrony.service: Failed with result 'exit-code'.
Oct 21 05:23:50 demo-felhom systemd[1]: Failed to start chrony.service - chrony, an NTP client/server.
2026-10-21 05:23:45
[Unit]
Description=chrony, an NTP client/server
Documentation=man:chronyd(8) man:chronyc(1) man:chrony.conf(5)
Conflicts=openntpd.service ntp.service ntpsec.service
ConditionVirtualization=|!container
ConditionVirtualization=|wsl
ConditionCapability=CAP_SYS_TIME
[Service]
Type=notify
PIDFile=/run/chrony/chronyd.pid
EnvironmentFile=-/etc/default/chrony
User=_chrony
ExecStart=!/usr/sbin/chronyd -n $DAEMON_OPTS
CapabilityBoundingSet=~CAP_AUDIT_CONTROL CAP_AUDIT_READ CAP_AUDIT_WRITE
CapabilityBoundingSet=~CAP_BLOCK_SUSPEND CAP_KILL CAP_LEASE CAP_LINUX_IMMUTABLE
CapabilityBoundingSet=~CAP_MAC_ADMIN CAP_MAC_OVERRIDE CAP_MKNOD CAP_SYS_ADMIN
CapabilityBoundingSet=~CAP_SYS_BOOT CAP_SYS_CHROOT CAP_SYS_MODULE CAP_SYS_PACCT
CapabilityBoundingSet=~CAP_SYS_PTRACE CAP_SYS_RAWIO CAP_SYS_TTY_CONFIG CAP_WAKE_ALARM
DeviceAllow=char-pps rw
DeviceAllow=char-ptp rw
DeviceAllow=char-rtc rw
DevicePolicy=closed
LockPersonality=yes
MemoryDenyWriteExecute=yes
NoNewPrivileges=yes
PrivateTmp=yes
ProcSubset=pid
ProtectControlGroups=yes
ProtectHome=yes
ProtectHostname=yes
DAEMON_OPTS="-F 1"
ii chrony 4.8-4~bpo13+2 amd64 Versatile implementation of the Network Time Protocol
@@ -0,0 +1,26 @@
== felhom-pve
demo-felhom
VMID Status Lock Name
9201 running demo-felhom
-- ct 9201
felhom-controller gitea.dooplex.hu/admin/felhom-controller:0.345.0 Up 6 hours (healthy)
cloudflared cloudflare/cloudflared:2026.9.3 Up 5 days (healthy)
== demo-hp
demo-hp
VMID Status Lock Name
9201 running demo-hp
9202 running demo-hp-scratch
9401 stopped upgrade-harness
-- ct 9201
felhom-controller gitea.dooplex.hu/admin/felhom-controller:0.345.0 Up 6 hours (healthy)
cloudflared cloudflare/cloudflared:2026.9.3 Up 3 days (healthy)
-- ct 9202
felhom-controller gitea.dooplex.hu/admin/felhom-controller:0.343.0 Up 2 hours (healthy)
341 night1004-tester1 running 8192 200.00 1364274
== root@192.168.0.154
felhom
VMID Status Lock Name
9201 running tester-1
-- ct 9201
felhom-controller gitea.dooplex.hu/admin/felhom-controller:0.345.0 Up 6 hours (healthy)
cloudflared cloudflare/cloudflared:2026.9.3 Up 2 days (healthy)
@@ -0,0 +1,15 @@
== k3s pods
== k3s images any
== docker
== systemd
== dpkg
== processes
2667091 /bin/bash -c source /home/kisfenyo/.claude/shell-snapshots/snapshot-bash-1793042538348-zvqq4e.sh 2>/dev/null || true && shopt -u extglob 2>/dev/null || true && { \builtin unalias -- 'unsetenv'
2667092 /bin/bash -c source /home/kisfenyo/.claude/shell-snapshots/snapshot-bash-1793042538348-zvqq4e.sh 2>/dev/null || true && shopt -u extglob 2>/dev/null || true && { \builtin unalias -- 'unsetenv'
2667753 /bin/bash -c source /home/kisfenyo/.claude/shell-snapshots/snapshot-bash-1793042538348-zvqq4e.sh 2>/dev/null || true && shopt -u extglob 2>/dev/null || true && { \builtin unalias -- 'unsetenv'
== positive control: same queries find traefik/hub
1
2
1
== docker images cached
== homelab-manifests mentions
@@ -0,0 +1,4 @@
Host | Customer | Agent | Proxmox / kernel | Status | Guests | CPU | Mem | Disk | Cloudflared | Worst Storage
demo-felhom-8363b5 | Demo Ügyfél | 0.166.0 floor: declared MinAgent | 9.2.21 7.0.14-25-pve | ONLINE | 1/2 | 0% | 20% | 35% | running (connected) | 35% local
demo-hp-bb76ea | Demo HP | 0.166.0 floor: declared MinAgent | 9.2.21 7.0.14-25-pve | ONLINE | 1/2 | 11% | 45% | 61% | running (connected) | 61% local
tester-1-d70be4 | Tester 1 | 0.166.0 floor: declared MinAgent | 9.2.2 7.0.14-22-pve | ONLINE | 1/2 | 7% | 33% | 27% | running (connected) | 27% local
@@ -0,0 +1,21 @@
== felhom-pve
traefik=172.20.0.2
/bin/openssl
0 s:CN=TRAEFIK DEFAULT CERT
i:CN=TRAEFIK DEFAULT CERT
Verify return code: 18 (self-signed certificate)
Verify return code: 18 (self-signed certificate)
== demo-hp
traefik=172.26.0.2
/bin/openssl
0 s:CN=TRAEFIK DEFAULT CERT
i:CN=TRAEFIK DEFAULT CERT
Verify return code: 18 (self-signed certificate)
Verify return code: 18 (self-signed certificate)
== root@192.168.0.154
traefik=172.22.0.2
/bin/openssl
0 s:CN=TRAEFIK DEFAULT CERT
i:CN=TRAEFIK DEFAULT CERT
Verify return code: 18 (self-signed certificate)
Verify return code: 18 (self-signed certificate)
@@ -0,0 +1,18 @@
== felhom-pve
2026-10-21T03:24:06Z INF Starting tunnel tunnelID=8b4edf48-1846-4484-870e-68b48cf43483
2026-10-21T03:24:06Z INF Version 2026.9.3 (Checksum af73b73c18b1fe8c50293af01630a59789ddd9eb1edb56472fe5559b3a4a340c)
2026-10-21T03:24:06Z INF GOOS: linux, GOVersion: go1.26.8, GoArch: amd64
2026-10-21T03:24:07Z INF Updated to new configuration config="{\"ingress\":[{\"hostname\":\"*.demo-felhom.eu\", \"originRequest\":{\"noTLSVerify\":true}, \"service\":\"https://traefik\"}, {\"service\":\"http_status:404\"}], \"warp-routing\":{\"enabled\":false}}" version=1
cloudflared version 2026.9.3 (built 2026-09-24-16:19 UTC)
== demo-hp
2026-10-23T15:34:00Z INF Starting tunnel tunnelID=d7a3c848-d754-46ce-a1c1-ca6bc7a81775
2026-10-23T15:34:00Z INF Version 2026.9.3 (Checksum af73b73c18b1fe8c50293af01630a59789ddd9eb1edb56472fe5559b3a4a340c)
2026-10-23T15:34:00Z INF GOOS: linux, GOVersion: go1.26.8, GoArch: amd64
2026-10-23T15:34:01Z INF Updated to new configuration config="{\"ingress\":[{\"hostname\":\"*.enkisfelhom.hu\", \"originRequest\":{\"noTLSVerify\":true}, \"service\":\"https://traefik\"}, {\"service\":\"http_status:404\"}], \"warp-routing\":{\"enabled\":false}}" version=1
cloudflared version 2026.9.3 (built 2026-09-24-16:19 UTC)
== root@192.168.0.154
2026-10-24T17:47:21Z INF Starting tunnel tunnelID=52d0c214-b833-477c-86d8-f787d9b550dd
2026-10-24T17:47:21Z INF Version 2026.9.3 (Checksum af73b73c18b1fe8c50293af01630a59789ddd9eb1edb56472fe5559b3a4a340c)
2026-10-24T17:47:21Z INF GOOS: linux, GOVersion: go1.26.8, GoArch: amd64
2026-10-24T17:47:22Z INF Updated to new configuration config="{\"ingress\":[{\"hostname\":\"*.enkicsifelhom.hu\", \"originRequest\":{\"noTLSVerify\":true}, \"service\":\"https://traefik\"}, {\"service\":\"http_status:404\"}], \"warp-routing\":{\"enabled\":false}}" version=2
cloudflared version 2026.9.3 (built 2026-09-24-16:19 UTC)
@@ -0,0 +1,4 @@
docker.io/cloudflare/cloudflared:2026.10.3
cloudflare/cloudflared@sha256:faa8e0a1475f137c910be6025f43c8e4092fdd35461b31e19fd1390657a1ff39 2026-10-21T13:26:38.565206178Z
cloudflared version 2026.10.3 (built 2026-10-21-13:24 UTC)
removed
@@ -0,0 +1,181 @@
[INFO] ╔══════════════════════════════════════╗
[INFO] ║ felhom-controller image builder ║
[INFO] ╚══════════════════════════════════════╝
[INFO] Version: 0.345.1
[INFO] Commit: f3204024
[INFO] Repo: /mnt/5_hdd/felhom.eu/git/felhom-controller-sec
[INFO] Source: /mnt/5_hdd/felhom.eu/git/felhom-controller-sec/controller
[INFO] Build dir: /mnt/5_hdd/felhom.eu/git/felhom-controller-mainsec/controller/workspace
[INFO] Image: gitea.dooplex.hu/admin/felhom-controller:0.345.1
[STEP] 0/4 — Checking the registry: is 0.345.1 already published?
[INFO] 0.345.1 is not present in the registry — proceeding.
[INFO] Source tree is clean and at the pushed tag v0.345.1 (not origin/main).
[STEP] 1/4 — Preparing build workspace...
[INFO] Source copied: 1079 Go files
[STEP] 2/4 — Syncing app assets...
[INFO] Synced 263 assets (52 SVG + 16 PNG logos, 195 screenshots)
[STEP] 3/4 — Preparing Go modules...
[INFO] Running go mod tidy...
[STEP] 4/4 — Building Docker image...
[INFO] Building for current platform + pushing...
#0 building with "default" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 6.94kB done
#1 DONE 0.0s
#2 [internal] load metadata for docker.io/library/golang:1.27.2-trixie@sha256:47667934874913a449b96faa7ef4777fa285d9ec29126ee80ed61c45b7cccf0e
#2 ...
#3 [auth] library/golang:pull token for registry-1.docker.io
#3 DONE 0.0s
#4 [auth] library/debian:pull token for registry-1.docker.io
#4 DONE 0.0s
#5 [internal] load metadata for docker.io/library/debian:13.7-slim@sha256:a29215f6a35e51e22adffa17f89e9d2ef06214e64a2bad10d765c46aea49f11f
#5 ...
#2 [internal] load metadata for docker.io/library/golang:1.27.2-trixie@sha256:47667934874913a449b96faa7ef4777fa285d9ec29126ee80ed61c45b7cccf0e
#2 DONE 1.0s
#5 [internal] load metadata for docker.io/library/debian:13.7-slim@sha256:a29215f6a35e51e22adffa17f89e9d2ef06214e64a2bad10d765c46aea49f11f
#5 DONE 1.1s
#6 [internal] load .dockerignore
#6 transferring context: 2B done
#6 DONE 0.0s
#7 [restic 1/3] FROM docker.io/library/debian:13.7-slim@sha256:a29215f6a35e51e22adffa17f89e9d2ef06214e64a2bad10d765c46aea49f11f
#7 resolve docker.io/library/debian:13.7-slim@sha256:a29215f6a35e51e22adffa17f89e9d2ef06214e64a2bad10d765c46aea49f11f 0.0s done
#7 DONE 0.0s
#8 [builder 1/7] FROM docker.io/library/golang:1.27.2-trixie@sha256:47667934874913a449b96faa7ef4777fa285d9ec29126ee80ed61c45b7cccf0e
#8 resolve docker.io/library/golang:1.27.2-trixie@sha256:47667934874913a449b96faa7ef4777fa285d9ec29126ee80ed61c45b7cccf0e 0.0s done
#8 DONE 0.0s
#9 [internal] load build context
#9 transferring context: 36.99MB 0.4s done
#9 DONE 0.4s
#10 [builder 3/7] COPY go.mod ./
#10 CACHED
#11 [builder 2/7] WORKDIR /build
#11 CACHED
#12 [builder 4/7] RUN go mod download || true
#12 CACHED
#13 [builder 5/7] COPY . .
#13 DONE 0.6s
#14 [builder 6/7] RUN go mod tidy
#14 0.532 go: downloading gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405
#14 0.619 go: downloading github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e
#14 0.619 go: downloading modernc.org/fileutil v1.3.40
#14 0.698 go: downloading golang.org/x/term v0.47.0
#14 1.291 go: downloading modernc.org/goabi0 v0.2.0
#14 1.291 go: downloading modernc.org/ccgo/v4 v4.30.1
#14 1.291 go: downloading modernc.org/cc/v4 v4.27.1
#14 1.291 go: downloading golang.org/x/tools v0.38.0
#14 1.422 go: downloading modernc.org/opt v0.1.4
#14 1.422 go: downloading modernc.org/token v1.1.0
#14 1.422 go: downloading modernc.org/sortutil v1.2.1
#14 1.422 go: downloading modernc.org/strutil v1.2.1
#14 1.598 go: downloading modernc.org/gc/v2 v2.6.5
#14 1.598 go: downloading golang.org/x/mod v0.29.0
#14 1.598 go: downloading modernc.org/gc/v3 v3.1.1
#14 1.820 go: downloading github.com/hashicorp/golang-lru/v2 v2.0.7
#14 2.038 go: downloading golang.org/x/sync v0.17.0
#14 DONE 2.4s
#15 [builder 7/7] RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w -X main.Version=0.345.1 -X main.BuildTime=$(date -u +%Y-%m-%dT%H:%M:%SZ) -X main.GitCommit=f3204024" -o /build/felhom-controller ./cmd/controller/
#15 DONE 22.3s
#16 [stage-2 3/7] COPY --from=restic /usr/local/bin/restic /usr/local/bin/restic
#16 CACHED
#17 [stage-2 4/7] RUN curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker.gpg && . /etc/os-release && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/debian ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list && apt-get update && apt-get install -y --no-install-recommends docker-ce-cli docker-compose-plugin && rm -rf /var/lib/apt/lists/*
#17 CACHED
#18 [stage-2 2/7] RUN apt-get update && apt-get upgrade -y --no-install-recommends && apt-get install -y --no-install-recommends ca-certificates curl gnupg git util-linux rsync openssh-client && rm -rf /var/lib/apt/lists/*
#18 CACHED
#19 [restic 2/3] COPY third_party/restic/restic-release-key.asc /tmp/restic-release-key.asc
#19 CACHED
#20 [restic 3/3] RUN set -eu; apt-get update && apt-get install -y --no-install-recommends ca-certificates curl gnupg gpgv bzip2; case "amd64" in amd64) want="f415415624dcc452f2a02b8c33641791a8c6d6d3b65bbb3543fcf9a25151585c" ;; arm64) want="a5f64aaab53d51e311fa3829124c5b703f2d14cf187d8640b6be3b2b49376465" ;; *) echo "no pinned restic checksum for architecture 'amd64'" >&2; exit 1 ;; esac; f="restic_0.19.1_linux_amd64.bz2"; url="https://github.com/restic/restic/releases/download/v0.19.1"; cd /tmp; curl -fsSL -o "$f" "$url/$f"; curl -fsSL -o SHA256SUMS "$url/SHA256SUMS"; curl -fsSL -o SHA256SUMS.asc "$url/SHA256SUMS.asc"; gpg --dearmor < /tmp/restic-release-key.asc > /tmp/restic-release-key.gpg; gpgv --keyring /tmp/restic-release-key.gpg SHA256SUMS.asc SHA256SUMS; grep " ${f}\$" SHA256SUMS | sha256sum -c -; echo "${want} ${f}" | sha256sum -c -; bunzip2 -c "$f" > /usr/local/bin/restic; chmod 0755 /usr/local/bin/restic; /usr/local/bin/restic version | grep -q "^restic 0.19.1 "
#20 CACHED
#21 [stage-2 5/7] RUN mkdir -p /opt/docker/felhom-controller/data
#21 CACHED
#22 [stage-2 6/7] COPY --from=builder /build/felhom-controller /usr/local/bin/felhom-controller
#22 DONE 0.1s
#23 [stage-2 7/7] COPY assets/ /usr/share/felhom/assets/
#23 DONE 0.1s
#24 exporting to image
#24 exporting layers
#24 exporting layers 2.6s done
#24 exporting manifest sha256:c64bc088431b2398ec209fe5b2971bfd33ead8bb1ba219dedf601f6b556ebb63
#24 exporting manifest sha256:c64bc088431b2398ec209fe5b2971bfd33ead8bb1ba219dedf601f6b556ebb63 0.3s done
#24 exporting config sha256:94b98adfce1d5f7610e683f3f8a6855a7fb2a4bd5c668d19cf1415d6ba0327fa
#24 exporting config sha256:94b98adfce1d5f7610e683f3f8a6855a7fb2a4bd5c668d19cf1415d6ba0327fa 0.2s done
#24 exporting attestation manifest sha256:7368ba4d08db112ea8eb69a8e35f247298306710e6f9220005ce3220638bb891
#24 exporting attestation manifest sha256:7368ba4d08db112ea8eb69a8e35f247298306710e6f9220005ce3220638bb891 0.3s done
#24 exporting manifest list sha256:7cfdf7e1f835628de9c7d536e0a60c06bad5bbe19e8133765cc0a6bb732dbff6
#24 exporting manifest list sha256:7cfdf7e1f835628de9c7d536e0a60c06bad5bbe19e8133765cc0a6bb732dbff6 0.2s done
#24 naming to gitea.dooplex.hu/admin/felhom-controller:0.345.1
#24 naming to gitea.dooplex.hu/admin/felhom-controller:0.345.1 0.0s done
#24 unpacking to gitea.dooplex.hu/admin/felhom-controller:0.345.1
#24 unpacking to gitea.dooplex.hu/admin/felhom-controller:0.345.1 0.6s done
#24 naming to gitea.dooplex.hu/admin/felhom-controller:latest 0.0s done
#24 unpacking to gitea.dooplex.hu/admin/felhom-controller:latest 0.1s done
#24 DONE 4.5s
[INFO] Pushing...
The push refers to repository [gitea.dooplex.hu/admin/felhom-controller]
c3f83389ce1b: Waiting
44136fa355b3: Waiting
b2b4e3e31fd1: Waiting
ecc510c1e359: Waiting
c3f83389ce1b: Layer already exists
44136fa355b3: Already exists
b2b4e3e31fd1: Waiting
ecc510c1e359: Layer already exists
e81c1fce9826: Layer already exists
63a1406b1961: Waiting
d747c9b6922d: Waiting
8c5bc1ea4981: Waiting
63a1406b1961: Layer already exists
d747c9b6922d: Layer already exists
b2b4e3e31fd1: Pushed
8c5bc1ea4981: Pushed
bd4abb283803: Pushed
0.345.1: digest: sha256:7cfdf7e1f835628de9c7d536e0a60c06bad5bbe19e8133765cc0a6bb732dbff6 size: 856
The push refers to repository [gitea.dooplex.hu/admin/felhom-controller]
b2b4e3e31fd1: Waiting
44136fa355b3: Waiting
c3f83389ce1b: Waiting
ecc510c1e359: Waiting
bd4abb283803: Layer already exists
44136fa355b3: Already exists
ecc510c1e359: Layer already exists
b2b4e3e31fd1: Already exists
d747c9b6922d: Layer already exists
c3f83389ce1b: Layer already exists
e81c1fce9826: Layer already exists
63a1406b1961: Layer already exists
8c5bc1ea4981: Layer already exists
latest: digest: sha256:7cfdf7e1f835628de9c7d536e0a60c06bad5bbe19e8133765cc0a6bb732dbff6 size: 856
[INFO] ╔══════════════════════════════════════╗
[INFO] ║ Build complete ✓ ║
[INFO] ╚══════════════════════════════════════╝
[INFO] Image: gitea.dooplex.hu/admin/felhom-controller:0.345.1
[INFO] Size: 486M
@@ -0,0 +1,26 @@
== demo-hp
cloudflared cloudflare/cloudflared:2026.10.3 Up 11 seconds (healthy)
felhom-controller gitea.dooplex.hu/admin/felhom-controller:0.345.1 Up 27 seconds (healthy)
started=2026-10-26T20:06:31.171324386Z
2026-10-26T20:06:31Z INF Version 2026.10.3 (Checksum 919cd4640a5984b57ed420f1dd61e4155ee60abb52ac5fe2adb5f8dc71d0c2e5)
2026-10-26T20:06:31Z INF GOOS: linux, GOVersion: go1.27.3, GoArch: amd64
2026-10-26T20:06:31Z INF Registered tunnel connection connIndex=0 connection=843ee444-05e8-4aec-9b3e-339cd75a0243 event=0 ip=198.41.200.113 location=vie06 protocol=quic
2026-10-26T20:06:31Z INF Updated to new configuration config="{\"ingress\":[{\"hostname\":\"*.enkisfelhom.hu\", \"originRequest\":{\"noTLSVerify\":true}, \"service\":\"https://traefik\"}, {\"service\":\"http_status:404\"}], \"warp-routing\":{\"enabled\":false}}" version=1
2026-10-26T20:06:32Z INF Registered tunnel connection connIndex=1 connection=f4340b8a-6bb4-47b2-a781-d649bf2f8f58 event=0 ip=198.41.192.47 location=bud01 protocol=quic
2026-10-26T20:06:33Z INF Registered tunnel connection connIndex=2 connection=fc7d8940-2277-4687-8942-c9a84142d9c9 event=0 ip=198.41.192.77 location=bud01 protocol=quic
cloudflared version 2026.10.3 (built 2026-10-21-13:24 UTC)
2026/10/26 20:06:16 updater.go:855: [INFO] [selfupdate] Post-update startup: update successful (0.345.0 → 0.345.1)
2026/10/26 20:06:17 infra.go:188: [INFO] [infra] cloudflared compose changed (tunnel network true) — recreating cloudflared (the tunnel reconnects in seconds)
== felhom-pve
cloudflared cloudflare/cloudflared:2026.10.3 Up 25 seconds (healthy)
felhom-controller gitea.dooplex.hu/admin/felhom-controller:0.345.1 Up 30 seconds (healthy)
started=2026-10-26T20:06:04.399090267Z
2026-10-26T20:06:04Z INF Version 2026.10.3 (Checksum 919cd4640a5984b57ed420f1dd61e4155ee60abb52ac5fe2adb5f8dc71d0c2e5)
2026-10-26T20:06:04Z INF GOOS: linux, GOVersion: go1.27.3, GoArch: amd64
2026-10-26T20:06:05Z INF Registered tunnel connection connIndex=0 connection=592e0ea3-9acc-4ed6-a5e6-cb68d2855353 event=0 ip=198.41.192.167 location=bud01 protocol=quic
2026-10-26T20:06:05Z INF Updated to new configuration config="{\"ingress\":[{\"hostname\":\"*.demo-felhom.eu\", \"originRequest\":{\"noTLSVerify\":true}, \"service\":\"https://traefik\"}, {\"service\":\"http_status:404\"}], \"warp-routing\":{\"enabled\":false}}" version=1
2026-10-26T20:06:05Z INF Registered tunnel connection connIndex=1 connection=da046196-a6fa-492c-8f47-65e607f005f8 event=0 ip=198.41.200.73 location=vie06 protocol=quic
2026-10-26T20:06:06Z INF Registered tunnel connection connIndex=2 connection=d183c0b2-19c3-4bd4-8779-e769170cf504 event=0 ip=198.41.200.23 location=vie05 protocol=quic
cloudflared version 2026.10.3 (built 2026-10-21-13:24 UTC)
2026/10/26 20:06:00 [INFO] [selfupdate] Post-update startup: update successful (0.345.0 → 0.345.1)
2026/10/26 20:06:00 [INFO] [infra] cloudflared compose changed (tunnel network true) — recreating cloudflared (the tunnel reconnects in seconds)
@@ -0,0 +1,8 @@
2026-10-26T20:06:04Z
customer demo-hp
HTTP/1.1 303 See Other
Location: /customers/demo-hp?flash=floor_set
2026-10-26T20:06:04Z
customer demo-felhom
HTTP/1.1 303 See Other
Location: /customers/demo-felhom?flash=floor_set
@@ -0,0 +1,34 @@
control NEGATIVE (a stub answering 200 over plain http): convicted, as it must (200 -)
== tester-1 (enkicsifelhom.hu): 6 public name(s)
OK control POSITIVE http://felhom.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://felhom.enkicsifelhom.hu/r1033-check?q=1
OK http://files.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://files.enkicsifelhom.hu/r1033-check?q=1
OK http://no-such-name-r1033.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://no-such-name-r1033.enkicsifelhom.hu/r1033-check?q=1
OK http://paperless.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://paperless.enkicsifelhom.hu/r1033-check?q=1
OK http://paste.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://paste.enkicsifelhom.hu/r1033-check?q=1
OK http://wiki.enkicsifelhom.hu/r1033-check?q=1 -> 301 https://wiki.enkicsifelhom.hu/r1033-check?q=1
== demo-hp (enkisfelhom.hu): 15 public name(s)
OK http://arcade.enkisfelhom.hu/r1033-check?q=1 -> 301 https://arcade.enkisfelhom.hu/r1033-check?q=1
OK http://books.enkisfelhom.hu/r1033-check?q=1 -> 301 https://books.enkisfelhom.hu/r1033-check?q=1
OK http://docs.enkisfelhom.hu/r1033-check?q=1 -> 301 https://docs.enkisfelhom.hu/r1033-check?q=1
OK http://felhom.enkisfelhom.hu/r1033-check?q=1 -> 301 https://felhom.enkisfelhom.hu/r1033-check?q=1
OK http://files.enkisfelhom.hu/r1033-check?q=1 -> 301 https://files.enkisfelhom.hu/r1033-check?q=1
OK http://gist.enkisfelhom.hu/r1033-check?q=1 -> 301 https://gist.enkisfelhom.hu/r1033-check?q=1
OK http://ha.enkisfelhom.hu/r1033-check?q=1 -> 301 https://ha.enkisfelhom.hu/r1033-check?q=1
OK http://no-such-name-r1033.enkisfelhom.hu/r1033-check?q=1 -> 301 https://no-such-name-r1033.enkisfelhom.hu/r1033-check?q=1
OK http://papir.enkisfelhom.hu/r1033-check?q=1 -> 301 https://papir.enkisfelhom.hu/r1033-check?q=1
OK http://paste.enkisfelhom.hu/r1033-check?q=1 -> 301 https://paste.enkisfelhom.hu/r1033-check?q=1
OK http://pdf.enkisfelhom.hu/r1033-check?q=1 -> 301 https://pdf.enkisfelhom.hu/r1033-check?q=1
OK http://plex.enkisfelhom.hu/r1033-check?q=1 -> 301 https://plex.enkisfelhom.hu/r1033-check?q=1
OK http://time.enkisfelhom.hu/r1033-check?q=1 -> 301 https://time.enkisfelhom.hu/r1033-check?q=1
OK http://travel.enkisfelhom.hu/r1033-check?q=1 -> 301 https://travel.enkisfelhom.hu/r1033-check?q=1
OK http://wiki.enkisfelhom.hu/r1033-check?q=1 -> 301 https://wiki.enkisfelhom.hu/r1033-check?q=1
== demo-felhom (demo-felhom.eu): 8 public name(s)
OK http://felhom.demo-felhom.eu/r1033-check?q=1 -> 301 https://felhom.demo-felhom.eu/r1033-check?q=1
OK http://files.demo-felhom.eu/r1033-check?q=1 -> 301 https://files.demo-felhom.eu/r1033-check?q=1
OK http://gist.demo-felhom.eu/r1033-check?q=1 -> 301 https://gist.demo-felhom.eu/r1033-check?q=1
OK http://no-such-name-r1033.demo-felhom.eu/r1033-check?q=1 -> 301 https://no-such-name-r1033.demo-felhom.eu/r1033-check?q=1
OK http://prowlarr.demo-felhom.eu/r1033-check?q=1 -> 301 https://prowlarr.demo-felhom.eu/r1033-check?q=1
OK http://radarr.demo-felhom.eu/r1033-check?q=1 -> 301 https://radarr.demo-felhom.eu/r1033-check?q=1
OK http://sonarr.demo-felhom.eu/r1033-check?q=1 -> 301 https://sonarr.demo-felhom.eu/r1033-check?q=1
OK http://torrent.demo-felhom.eu/r1033-check?q=1 -> 301 https://torrent.demo-felhom.eu/r1033-check?q=1
== every public name redirects http -> https
@@ -0,0 +1,5 @@
Host | Status | Cloudflared
Tester4-b5dbbd | ONLINE | unknown (no running customer guest)
demo-felhom-8363b5 | ONLINE | running (connected)
demo-hp-bb76ea | ONLINE | running (connected)
tester-1-d70be4 | ONLINE | running (connected)
@@ -0,0 +1,14 @@
2026-10-26T20:05:25Z INF Version 2026.10.3 (Checksum 919cd4640a5984b57ed420f1dd61e4155ee60abb52ac5fe2adb5f8dc71d0c2e5)
2026-10-26T20:05:25Z INF GOOS: linux, GOVersion: go1.27.3, GoArch: amd64
2026-10-26T20:05:25Z INF Registered tunnel connection connIndex=0 connection=3cc5adb1-aea4-4d4f-8f8e-d63fefd414b2 event=0 ip=198.41.192.37 location=bud01 protocol=quic
2026-10-26T20:05:25Z INF Updated to new configuration config="{\"ingress\":[{\"hostname\":\"*.enkicsifelhom.hu\", \"originRequest\":{\"noTLSVerify\":true}, \"service\":\"https://traefik\"}, {\"service\":\"http_status:404\"}], \"warp-routing\":{\"enabled\":false}}" version=2
2026-10-26T20:05:25Z INF Registered tunnel connection connIndex=1 connection=27f1251e-375d-4774-a0b9-54d8bfd1641a event=0 ip=198.41.200.33 location=vie05 protocol=quic
2026-10-26T20:05:27Z INF Registered tunnel connection connIndex=2 connection=be88ef22-3c33-4da0-ab61-cb14ec33e5ef event=0 ip=198.41.192.227 location=bud01 protocol=quic
2026-10-26T20:05:28Z INF Registered tunnel connection connIndex=3 connection=4e5fa7a2-4c94-4c0e-93d0-395fb2b0957d event=0 ip=198.41.200.63 location=vie06 protocol=quic
cloudflared version 2026.10.3 (built 2026-10-21-13:24 UTC)
2026/10/26 20:05:19 [INFO] [selfupdate] Post-update startup: update successful (0.345.0 → 0.345.1)
2026/10/26 20:05:19 [INFO] Self-update enabled (check every 6h, auto-update: false, auto-update time: 04:30)
2026/10/26 20:05:19 [INFO] [scheduler] Registered periodic job: selfupdate-check (every 6h0m0s)
2026/10/26 20:05:19 [INFO] [offsite-apply] settle-gate: awaiting floor knowledge (first report ACK) before offsite apply
2026/10/26 20:05:20 [INFO] [infra] cloudflared compose changed (tunnel network true) — recreating cloudflared (the tunnel reconnects in seconds)
2026/10/26 20:05:29 [INFO] [offsite-apply] settle-gate: GO — at/above floor 0.345.1 (we are 0.345.1), no managed update running
@@ -0,0 +1,3 @@
2026-10-26T20:05:08Z
HTTP/1.1 303 See Other
Location: /customers/tester-1?flash=floor_set
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,6 @@
20:39:54 clear tester-1
Location: /customers/tester-1?flash=floor_set
20:39:54 clear demo-hp
Location: /customers/demo-hp?flash=floor_set
20:39:54 clear demo-felhom
Location: /customers/demo-felhom?flash=floor_set
@@ -0,0 +1,7 @@
er action. Blank = no global floor. This setting is independent of the Day-0 artifact manifest below. Effective floor: v0.345.1 — source: DB (hub_settings) ; env fallback would be v0.120.0 Save global floor… DB override: v0.345.1 … Type the versio
(no manual copy). Choose — none — to clear an artifact. Agent — none — 0.166.0 0.165.0 0.164.0 0.163.0 0.162.0 0.161.0 0.158.1 Golden — none — 0.344.0 0.331.0 0.329.0 0.318.0 0.313.0 0.312.0 0.311.0 Min agent The golden's controller CHANGELOG Min
2026/10/26 21:05:08 [INFO] Customer tester-1 controller-version floor override set to "0.345.1" (declared MinAgent "0.158.1")
2026/10/26 21:05:08 [INFO] access token "cc-releases-2": POST /customers/tester-1/floor → 303
2026/10/26 21:05:11 [INFO] managed floor SERVED for tester-1: floor 0.345.1, agent requirement "0.158.1" from declared (golden 0.344.0)
2026/10/26 21:06:04 [INFO] Customer demo-hp controller-version floor override set to "0.345.1" (declared MinAgent "0.158.1")
2026/10/26 21:06:04 [INFO] access token "cc-releases-2": POST /customers/demo-hp/floor → 303
@@ -0,0 +1,3 @@
2026-10-26T20:08:39Z
HTTP/1.1 303 See Other
Location: /configuration?flash=floor_set
@@ -0,0 +1,11 @@
Customer ID | Name | Domain | Status | Version | Floor | Config
Tester-2 | Tester 2 | sajatfelhom.hu | DOWN | 0.292.0 | v0.345.1 ● | MANAGED
Tester4 | Tester4 | tester4.test | OK | 0.345.1 | v0.345.1 | MANAGED
demo-felhom | Demo Ügyfél | demo-felhom.eu | OK | 0.345.1 | v0.345.1 | MANAGED
demo-hp | Demo HP | enkisfelhom.hu | OK | 0.345.1 | v0.345.1 | MANAGED
tester-1 | Tester 1 | enkicsifelhom.hu | OK | 0.345.1 | v0.345.1 | MANAGED
Host | Customer | Agent | Proxmox / kernel | Status | Guests | CPU | Mem | Disk | Cloudflared | Worst Storage
Tester4-b5dbbd | Tester4 | 0.167.0-night1 floor held | 9.2.2 7.0.2-6-pve | ONLINE | 1/1 | 8% | 27% | 18% | absent (no cloudflared container in the guest (no tunnel set up on this box)) | 18% local
demo-felhom-8363b5 | Demo Ügyfél | 0.166.0 floor: declared MinAgent | 9.2.21 7.0.14-25-pve | ONLINE | 1/2 | 5% | 20% | 35% | running (connected) | 35% local
demo-hp-bb76ea | Demo HP | 0.166.0 floor: declared MinAgent | 9.2.21 7.0.14-25-pve | ONLINE | 1/2 | 19% | 66% | 65% | running (connected) | 65% local
tester-1-d70be4 | Tester 1 | 0.166.0 floor: declared MinAgent | 9.2.2 7.0.14-22-pve | ONLINE | 1/2 | 0% | 34% | 27% | running (connected) | 27% local
@@ -0,0 +1,28 @@
== 20:09:04
felhom-pve: cloudflared=cloudflare/cloudflared:2026.10.3(Up 2 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 2 minutes (healthy))
demo-hp: cloudflared=cloudflare/cloudflared:2026.10.3(Up 2 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 2 minutes (healthy))
root@192.168.0.154: cloudflared=cloudflare/cloudflared:2026.10.3(Up 3 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 3 minutes (healthy))
== 20:14:08
felhom-pve: cloudflared=cloudflare/cloudflared:2026.10.3(Up 7 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 7 minutes (healthy))
demo-hp: cloudflared=cloudflare/cloudflared:2026.10.3(Up 7 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 7 minutes (healthy))
root@192.168.0.154: cloudflared=cloudflare/cloudflared:2026.10.3(Up 8 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 8 minutes (healthy))
== 20:19:14
felhom-pve: cloudflared=cloudflare/cloudflared:2026.10.3(Up 12 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 13 minutes (healthy))
demo-hp: cloudflared=cloudflare/cloudflared:2026.10.3(Up 12 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 13 minutes (healthy))
root@192.168.0.154: cloudflared=cloudflare/cloudflared:2026.10.3(Up 13 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 14 minutes (healthy))
== 20:24:19
felhom-pve: cloudflared=cloudflare/cloudflared:2026.10.3(Up 18 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 18 minutes (healthy))
demo-hp: cloudflared=cloudflare/cloudflared:2026.10.3(Up 17 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 18 minutes (healthy))
root@192.168.0.154: cloudflared=cloudflare/cloudflared:2026.10.3(Up 18 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 19 minutes (healthy))
== 20:29:23
felhom-pve: cloudflared=cloudflare/cloudflared:2026.10.3(Up 23 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 23 minutes (healthy))
demo-hp: cloudflared=cloudflare/cloudflared:2026.10.3(Up 22 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 23 minutes (healthy))
root@192.168.0.154: cloudflared=cloudflare/cloudflared:2026.10.3(Up 24 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 24 minutes (healthy))
== 20:34:27
felhom-pve: cloudflared=cloudflare/cloudflared:2026.10.3(Up 28 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 28 minutes (healthy))
demo-hp: cloudflared=cloudflare/cloudflared:2026.10.3(Up 27 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 28 minutes (healthy))
root@192.168.0.154: cloudflared=cloudflare/cloudflared:2026.10.3(Up 29 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 29 minutes (healthy))
== 20:39:31
felhom-pve: cloudflared=cloudflare/cloudflared:2026.10.3(Up 33 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 33 minutes (healthy))
demo-hp: cloudflared=cloudflare/cloudflared:2026.10.3(Up 33 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 33 minutes (healthy))
root@192.168.0.154: cloudflared=cloudflare/cloudflared:2026.10.3(Up 34 minutes (healthy)) felhom-controller=gitea.dooplex.hu/admin/felhom-controller:0.345.1(Up 34 minutes (healthy))
@@ -0,0 +1,62 @@
# D53 — a held app reaches the operator: build and live proof (2026-10-26 evening)
**Design:** `architecture/08-alarm-ladder.md` §10. **Ruling:** D53 = operator-only reminders first (`09` §3 decision 265).
**Code (commit only, not released):** controller `5bd03ad` (CI 2377 ✓), hub `7e57e824` (CI 2378 ✓).
## Red proofs
- Controller `internal/holdreport`: with an inert `Tick`, all six behaviour tests failed; with the scheduler line
commented out, the wiring test failed.
- Hub: six mutations, each turned its test red — `redproof-hub.txt` (one first attempt was only a compile error; it was
redone with a compiling mutation, the last line).
## Live proof — method
No hub deploy is allowed in this run, so the hub side ran as a **test hub process** on DooPlex (`192.168.0.180:18090`),
built from a clean clone at `7e57e824`, scratch database, a throwaway login, its own random global key, operator mail to
`d53-test@felhom.eu` (the catch-all), and `alerting.held_app_grace_override: 3m` (the test configuration). Scratch guest
9202 ran a **local-only** controller image built from `5bd03ad` (`0.346.0-d53test`, `docker save`/`load`, never pushed to
the registry), pointed at the test hub for the test. Pages were read through the test hub's own login (the endpoints
the operator's browser uses); the mail was read in the mailbox (a different channel from the hub log).
## Live proof — what happened (UTC)
| Time | What | Evidence |
|---|---|---|
| 17:28 | Both lists empty: „No app is held on this box." / „… on any box." | `live/0-before_*.html` |
| 17:29:52 | Test controller up; „Notifier enabled (hub: …:18090)", job `hold-report` every 1m | `live/9202-controller-log.txt` |
| 17:30:52 | The first tick reported **four old holds 9202 has carried since 2026-09-24** (`chaoscrash`, `chaosoom`, `chaosoomb`, `gokapi`) | `live/test-hub.log` |
| 17:33:35 | Four operator reminders (one per app, per-app cooldown) | mailbox, `live/notification_log.txt` |
| 17:35:41 | Throwaway Radicale installed through the product | — |
| 17:36:18–17:37:48 | Seven `kill -9` of its main process, 15 s apart | — |
| 17:37:52 | The guard stopped it: „crash_loop — 7 in 10m0s; STOPPING it"; hold `unhealthy_stop` | `live/9202-controller-log.txt` |
| 17:38:52 | `app_held` radicale reached the hub (next tick) | `live/test-hub.log` |
| 17:41:34 | One reminder after the 3-minute grace; mail „[Felhom] ⚠️ demo-hp: the app radicale is still held — a person must act" in the inbox at 17:41:35 | mailbox |
| 17:42 | Both pages list 5 held apps, Radicale with its reason, sentence, and who may clear it | `live/1-held_*.html` |
| 17:45:37 | The household's Start (`POST /api/stacks/radicale/start`) lifted the hold | controller log |
| 17:45:52 | `app_hold_cleared` → the Radicale row went from both pages; no reminder after it | `live/2-cleared_*.html`, `live/held_apps_final.txt` |
**No household mail:** every reminder's customer leg is `skipped operator_only` (`live/notification_log.txt`).
## Teardown
- **Machine (9202):** Radicale removed through the product (no container, volume, `app.yaml`, data or subdomain left);
config and image file put back byte-identical to the saved copies; the test's two settings traces (`reported_holds`, the
Radicale stop time) removed while the controller was stopped; the test image removed; controller 0.343.0 healthy, hub off,
exactly as found. The four old holds and an old PrivateBin record (below) were there before and stay.
- **Host (demo-hp):** nothing provisioned; the transfer file removed.
- **Hub:** the real hub was not touched. The test hub process stopped; its database, login, key and binary deleted. The
local test image on DooPlex removed.
## Observations
- FILED: R-1298 — 9202 carries leftovers made outside the product: four crash-loop holds since 2026-09-24 for apps that
are not installed, and a PrivateBin `app.yaml` (2026-10-25) with no container, so the product reads it as installed.
Once D53 is released, such orphan holds would be reminded weekly about apps that do not exist.
- NOT-A-FINDING: the test hub's log looked cut mid-line at 18:45:52 local — the `sec` wrapper holds back an unfinished
part of a long-running child's output; the full line was there when the process ended.
- NOT-A-FINDING: my first switch of 9202 used `systemctl start` on the bootstrap oneshot, which was still active, so the
controller was briefly not running (about one minute); `restart` is the right verb. Fixed in the run.
Secrets: the evidence was scanned for the Resend key, the hub token, the report key and 9202's password — 0 hits; the
test hub's CSRF tokens are redacted.
@@ -0,0 +1,126 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hosts — Felhom Hub</title>
<link rel="stylesheet" href="/style.css?v=0.173.0-d53test">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
<symbol id="i-triangle-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /> <path d="M12 9v4" /> <path d="M12 17h.01" /></symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5" /></symbol>
<symbol id="i-server" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2" /> <rect width="20" height="8" x="2" y="14" rx="2" ry="2" /> <line x1="6" x2="6.01" y1="6" y2="6" /> <line x1="6" x2="6.01" y1="18" y2="18" /></symbol>
<symbol id="i-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /> <circle cx="12" cy="12" r="3" /></symbol>
<symbol id="i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /> <path d="m6 6 12 12" /></symbol>
<symbol id="i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 16v-4" /> <path d="M12 8h.01" /></symbol>
<symbol id="i-hard-drive" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 16h.01" /> <path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" /> <path d="M21.946 12.013H2.054" /> <path d="M6 16h.01" /></symbol>
<symbol id="i-cpu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20v2" /> <path d="M12 2v2" /> <path d="M17 20v2" /> <path d="M17 2v2" /> <path d="M2 12h2" /> <path d="M2 17h2" /> <path d="M2 7h2" /> <path d="M20 12h2" /> <path d="M20 17h2" /> <path d="M20 7h2" /> <path d="M7 20v2" /> <path d="M7 2v2" /> <rect x="4" y="4" width="16" height="16" rx="2" /> <rect x="8" y="8" width="8" height="8" rx="1" /></symbol>
<symbol id="i-clock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 6v6l4 2" /></symbol>
<symbol id="i-boxes" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /> <path d="m7 16.5-4.74-2.85" /> <path d="m7 16.5 5-3" /> <path d="M7 16.5v5.17" /> <path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /> <path d="m17 16.5-5-3" /> <path d="m17 16.5 4.74-2.85" /> <path d="M17 16.5v5.17" /> <path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" /> <path d="M12 8 7.26 5.15" /> <path d="m12 8 4.74-2.85" /> <path d="M12 13.5V8" /></symbol>
<symbol id="i-users" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /> <path d="M16 3.128a4 4 0 0 1 0 7.744" /> <path d="M22 21v-2a4 4 0 0 0-3-3.87" /> <circle cx="9" cy="7" r="4" /></symbol>
</svg>
<script>
function felhomConfirm(el,question,onYes){
if(!el||el.dataset.fcOpen)return;
el.dataset.fcOpen='1';
var wrap=document.createElement('span');wrap.className='inline-confirm';
var q=document.createElement('span');q.className='inline-confirm-q';q.textContent=question;
var yes=document.createElement('button');yes.type='button';yes.className='btn btn-sm btn-danger';yes.textContent='Igen';
var no=document.createElement('button');no.type='button';no.className='btn btn-sm btn-outline';no.textContent='Mégse';
wrap.appendChild(q);wrap.appendChild(yes);wrap.appendChild(no);
el.style.display='none';el.parentNode.insertBefore(wrap,el.nextSibling);
function close(){wrap.remove();el.style.display='';delete el.dataset.fcOpen;}
no.addEventListener('click',close);
yes.addEventListener('click',function(){close();onYes();});
}
document.addEventListener('click',function(e){
var btn=e.target.closest?e.target.closest('[data-confirm]'):null;
if(!btn)return;
e.preventDefault();
felhomConfirm(btn,btn.getAttribute('data-confirm'),function(){
var form=btn.closest('form');
if(form){if(form.requestSubmit)form.requestSubmit(btn);else form.submit();}
});
});
</script>
<div class="container">
<header>
<h1>Felhom <span>Hub</span></h1>
<nav class="nav-links">
<a href="/" class="nav-link">Dashboard</a>
<a href="/configs" class="nav-link">Customers</a>
<a href="/apps" class="nav-link">Apps</a>
<a href="/hosts" class="nav-link active">Hosts</a>
<a href="/system" class="nav-link">System</a>
<a href="/offsite" class="nav-link">Offsite</a>
<a href="/configuration" class="nav-link">Configuration</a>
</nav>
</header>
<h2 style="margin-bottom: 1rem;">Hosts</h2>
<section class="card" id="held-apps" style="margin-bottom: 1.5rem; padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem; margin-top: 0;">Held apps</h2>
<div class="empty-state" style="border: none;">
<p>No app is held on any box.</p>
</div>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<table class="data-table">
<thead>
<tr>
<th>Host</th>
<th>Customer</th>
<th>Agent</th>
<th>Proxmox / kernel</th>
<th>Status</th>
<th>Guests</th>
<th>CPU</th>
<th>Mem</th>
<th>Disk</th>
<th>Cloudflared</th>
<th>Worst Storage</th>
</tr>
</thead>
<tbody>
<tr onclick="window.location='/hosts/d53-test-9202'" style="cursor: pointer;">
<td><a href="/hosts/d53-test-9202">d53-test-9202</a></td>
<td>demo-hp</td>
<td>—</td>
<td style="font-size: 0.85em;">unknown<br><span class="text-muted">unknown</span></td>
<td><span class="status-badge status-badge-pending">NO REPORT</span></td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
</tr>
</tbody>
</table>
</section>
<footer style="margin-top: 2rem; color: var(--text-muted); font-size: 0.8rem; text-align: center;">
Felhom Hub <span style="font-family: var(--font-mono)">0.173.0-d53test</span>
</footer>
</div>
</body>
</html>
@@ -0,0 +1,347 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>d53-test-9202 — Felhom Hub</title>
<link rel="stylesheet" href="/style.css?v=0.173.0-d53test">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
<symbol id="i-triangle-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /> <path d="M12 9v4" /> <path d="M12 17h.01" /></symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5" /></symbol>
<symbol id="i-server" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2" /> <rect width="20" height="8" x="2" y="14" rx="2" ry="2" /> <line x1="6" x2="6.01" y1="6" y2="6" /> <line x1="6" x2="6.01" y1="18" y2="18" /></symbol>
<symbol id="i-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /> <circle cx="12" cy="12" r="3" /></symbol>
<symbol id="i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /> <path d="m6 6 12 12" /></symbol>
<symbol id="i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 16v-4" /> <path d="M12 8h.01" /></symbol>
<symbol id="i-hard-drive" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 16h.01" /> <path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" /> <path d="M21.946 12.013H2.054" /> <path d="M6 16h.01" /></symbol>
<symbol id="i-cpu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20v2" /> <path d="M12 2v2" /> <path d="M17 20v2" /> <path d="M17 2v2" /> <path d="M2 12h2" /> <path d="M2 17h2" /> <path d="M2 7h2" /> <path d="M20 12h2" /> <path d="M20 17h2" /> <path d="M20 7h2" /> <path d="M7 20v2" /> <path d="M7 2v2" /> <rect x="4" y="4" width="16" height="16" rx="2" /> <rect x="8" y="8" width="8" height="8" rx="1" /></symbol>
<symbol id="i-clock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 6v6l4 2" /></symbol>
<symbol id="i-boxes" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /> <path d="m7 16.5-4.74-2.85" /> <path d="m7 16.5 5-3" /> <path d="M7 16.5v5.17" /> <path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /> <path d="m17 16.5-5-3" /> <path d="m17 16.5 4.74-2.85" /> <path d="M17 16.5v5.17" /> <path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" /> <path d="M12 8 7.26 5.15" /> <path d="m12 8 4.74-2.85" /> <path d="M12 13.5V8" /></symbol>
<symbol id="i-users" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /> <path d="M16 3.128a4 4 0 0 1 0 7.744" /> <path d="M22 21v-2a4 4 0 0 0-3-3.87" /> <circle cx="9" cy="7" r="4" /></symbol>
</svg>
<div class="container">
<header>
<h1>Felhom <span>Hub</span></h1>
<nav class="nav-links">
<a href="/" class="nav-link">Dashboard</a>
<a href="/configs" class="nav-link">Customers</a>
<a href="/apps" class="nav-link">Apps</a>
<a href="/hosts" class="nav-link active">Hosts</a>
<a href="/system" class="nav-link">System</a>
<a href="/offsite" class="nav-link">Offsite</a>
<a href="/configuration" class="nav-link">Configuration</a>
</nav>
</header>
<a href="/hosts" class="back-link">&larr; Hosts</a>
<section class="card">
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem;">
<h2 style="margin: 0;">d53-test-9202</h2>
<span class="status-badge status-badge-pending">NO REPORT</span>
</div>
<div class="info-grid" style="margin-top: 1rem;">
<div class="info-item">
<span class="label">Host ID</span>
<span class="value" style="font-family: var(--font-mono)">d53-test-9202</span>
</div>
<div class="info-item">
<span class="label">Customer</span>
<span class="value"><a href="/customers/demo-hp">demo-hp</a></span>
</div>
<div class="info-item">
<span class="label">Agent Version</span>
<span class="value">—</span>
</div>
<div class="info-item">
<span class="label">Enrolled</span>
<span class="value">just now</span>
</div>
<div class="info-item">
<span class="label">Last Report</span>
<span class="value">waiting for first report</span>
</div>
<div class="info-item">
<span class="label">Box connection</span>
<span class="value" data-box-connection="unknown">unknown (the hub restarted recently, or the host has no customer)</span>
</div>
<div class="info-item">
<span class="label">Desired Generation</span>
<span class="value">0</span>
</div>
</div>
</section>
<section class="card">
<div class="empty-state">
<p>Waiting for first report.</p>
<p class="hint">Vitals, guests and storage appear once this host's agent sends a host-report.</p>
</div>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Guests</h2>
<div class="empty-state" style="border: none;">
<p>No guests reported on this host.</p>
</div>
</section>
<section class="card" id="held-apps" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Held apps</h2>
<div class="empty-state" style="border: none;">
<p>No app is held on this box.</p>
</div>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Storage Targets</h2>
<div class="empty-state" style="border: none;">
<p>No storage targets reported.</p>
</div>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Capabilities</h2>
<div class="empty-state" style="border: none;">
<p>No capability report yet (waiting for the first host report).</p>
</div>
</section>
<section class="card">
<h2>Diagnostics — Log Bundles</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
Pull-based: the box ships its debug ring on its own next cycle — controller &le; one report interval (~15 min),
agent &asymp; one heartbeat. The pull is recorded in the box's own log (customer-visible). Bundles expire after 72 h.
</p>
<div style="display: flex; gap: 0.5rem; margin: 0.75rem 0;">
<form method="POST" action="/hosts/d53-test-9202/request-logs" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="component" value="controller">
<button type="submit" class="btn btn-sm">Request controller logs</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/request-logs" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="component" value="agent">
<button type="submit" class="btn btn-sm">Request agent logs</button>
</form>
</div>
<div class="empty-state" style="border: none;">
<p>No log bundles. Use the request buttons above — the box delivers on its next cycle.</p>
</div>
</section>
<section class="card" id="operator-actions">
<h2>Operator Actions</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
The box acts on its next report reply (usually seconds, at most one report interval) and answers on the
report after that. Each press runs once. Recorded in the box's own log and in Events. Unanswered after a day: expired.
</p>
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.75rem 0;">
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="offsite_backup_now">
<button type="submit" class="btn btn-sm">Run off-site backup now</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="run_job">
<select name="arg"><option value="disk-health-check">disk-health-check</option><option value="fill-watch">fill-watch</option><option value="offsite-integrity">offsite-integrity</option><option value="offsite-proof">offsite-proof</option></select>
<button type="submit" class="btn btn-sm">Run check now</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="abandon_stop">
<button type="submit" class="btn btn-sm btn-outline">Stop deletion countdown</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="abandon_extend">
<input type="number" name="arg" min="1" max="30" value="7" style="width: 4.5em; padding: 0.3em 0.5em;" aria-label="days">
<button type="submit" class="btn btn-sm btn-outline">Extend countdown (days from now)</button>
</form>
</div>
<div class="empty-state" style="border: none;">
<p>No operator actions for this box yet.</p>
</div>
</section>
<section class="card">
<h2>Network</h2>
<div class="info-grid">
<div class="info-item">
<span class="label">WireGuard</span>
<span class="value">
<span class="text-muted">no peer allocated</span>
</span>
</div>
</div>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem; margin-top: 0.75rem;">
Waiting for the first host report.
</p>
</section>
<section class="card">
<h2>Guest network
<span class="badge badge-neutral" title="A capable agent sent no guest-network stanza">unknown</span>
</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
This host reported no guest-network state, so it is <strong>unknown</strong> &mdash; not healthy.
The watchdog is default-on; a silent capable agent means it was switched off
(<code>guest_net.disable</code>), or this report predates it on this box.
</p>
</section>
<section class="card">
<h2>DR / Backup</h2>
<div class="info-grid">
<div class="info-item">
<span class="label">DR Recipe</span>
<span class="value"><span class="text-muted">none</span></span>
</div>
<div class="info-item">
<span class="label">Key Escrow</span>
<span class="value"><span class="text-muted">none</span></span>
</div>
<div class="info-item" id="offsite-integrity">
<span class="label">Last full check (off-site)</span>
<span class="value">not reported (no off-site status in the box&#39;s report)</span>
</div>
</div>
</section>
<section class="card">
<h2>Console access</h2>
<p><span class="badge badge-neutral">not vaulted</span></p>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
No console credential is vaulted for this host. Expected for a byo host — the owner manages root@pam. Otherwise the installer's step 4b did not run; re-run felhom-host-install.sh, or set and vault one per the break-glass runbook &sect;5.
</p>
</section>
<section class="card" style="border-color: var(--crit);">
<h2>Danger zone</h2>
<p class="text-muted" style="font-size: 0.85rem;">
Removing this host deletes its reports, guests, log bundles and WireGuard peer, and
permanently invalidates its API key — a still-running agent would receive 401s.
Re-enrollment requires the Day-0 passphrase flow.
</p>
<button type="button" class="btn btn-danger btn-sm" onclick="hostDeleteConfirm('d53-test-9202')">Remove host&hellip;</button>
<div id="host-delete-confirm-d53-test-9202" style="display: none; margin-top: 0.75rem; padding: 0.75rem; border: 1px solid var(--crit); background: var(--crit-dim); border-radius: var(--radius); max-width: 44em;">
<p id="host-delete-impact-d53-test-9202" style="margin: 0 0 0.5rem; font-size: 0.9em;">&hellip;</p>
<label id="host-delete-escrow-row-d53-test-9202" style="display: none; margin: 0 0 0.5rem; font-size: 0.85em;">
<input type="checkbox" id="host-delete-escrow-d53-test-9202">
Move key escrow to retained custody (required when escrow present) + remove DR bundle for this host
</label>
<p style="margin: 0 0 0.5rem; font-size: 0.85em; color: var(--text-2);">Type the host id to confirm:</p>
<form method="POST" action="/hosts/d53-test-9202/delete" id="host-delete-form-d53-test-9202" style="display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="confirm_host_id" id="host-delete-confirm-hidden-d53-test-9202" value="">
<input type="hidden" name="delete_escrow" id="host-delete-escrow-hidden-d53-test-9202" value="">
<input type="text" id="host-delete-confirm-input-d53-test-9202" placeholder="retype the host id&hellip;" style="padding: 0.3em 0.5em; width: 16em;">
<button type="button" class="btn btn-danger btn-sm" onclick="hostDeleteSubmit('d53-test-9202')">Confirm &amp; remove</button>
<button type="button" class="btn btn-sm btn-outline" onclick="document.getElementById('host-delete-confirm-d53-test-9202').style.display='none';">Cancel</button>
</form>
<p id="host-delete-err-d53-test-9202" style="margin: 0.4em 0 0; font-size: 0.8em; color: var(--crit);"></p>
</div>
</section>
<script>
function hostDeleteConfirm(hostID) {
var box = document.getElementById('host-delete-confirm-' + hostID);
var impact = document.getElementById('host-delete-impact-' + hostID);
document.getElementById('host-delete-confirm-input-' + hostID).value = '';
document.getElementById('host-delete-err-' + hostID).textContent = '';
box.style.display = 'block';
impact.textContent = 'Checking impact…';
fetch('/hosts/' + encodeURIComponent(hostID) + '/delete-impact')
.then(function(r){ return r.json(); })
.then(function(d){
var parts = ['Deleting ' + hostID + ' removes ' + d.guests + ' guest row(s), ' +
d.reports + ' host report(s), ' + d.log_bundles + ' agent log bundle(s)'];
if (d.wg_peer_bound) parts.push('the bound WireGuard peer');
if (d.pbs_secret_present) parts.push('the staged PBS secret');
if (d.recovery_present) parts.push('the break-glass recovery credential');
impact.textContent = parts.join(', ') + '. Host status: ' + d.status + '.' +
(d.deletable ? (d.off_tick_required ? ' No box connection for 6+ minutes — the "box is off" tick is required.' : '') : ' Host is ONLINE — deletion will be refused.');
document.getElementById('host-delete-escrow-row-' + hostID).style.display =
d.escrow_present ? 'block' : 'none';
})
.catch(function(){ impact.textContent = 'Could not compute the impact — the server will still enforce every gate.'; });
}
function hostDeleteSubmit(hostID) {
var typed = document.getElementById('host-delete-confirm-input-' + hostID).value.trim();
var err = document.getElementById('host-delete-err-' + hostID);
if (typed !== hostID) { err.textContent = 'Confirmation does not match the host id.'; return; }
var escrowRow = document.getElementById('host-delete-escrow-row-' + hostID);
var escrowCb = document.getElementById('host-delete-escrow-' + hostID);
if (escrowRow.style.display !== 'none' && !escrowCb.checked) {
err.textContent = 'This host has a key escrow — tick the acknowledgement to delete it too.';
return;
}
var offCb = document.getElementById('host-delete-off-' + hostID);
if (offCb && !offCb.checked) {
err.textContent = 'Tick "I checked: the box is off" first.';
return;
}
if (offCb) { document.getElementById('host-delete-off-hidden-' + hostID).value = '1'; }
document.getElementById('host-delete-confirm-hidden-' + hostID).value = typed;
document.getElementById('host-delete-escrow-hidden-' + hostID).value = escrowCb.checked ? '1' : '';
document.getElementById('host-delete-form-' + hostID).submit();
}
</script>
<footer style="margin-top: 2rem; color: var(--text-muted); font-size: 0.8rem; text-align: center;">
Felhom Hub <span style="font-family: var(--font-mono)">0.173.0-d53test</span>
</footer>
</div>
</body>
</html>
@@ -0,0 +1,177 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hosts — Felhom Hub</title>
<link rel="stylesheet" href="/style.css?v=0.173.0-d53test">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
<symbol id="i-triangle-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /> <path d="M12 9v4" /> <path d="M12 17h.01" /></symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5" /></symbol>
<symbol id="i-server" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2" /> <rect width="20" height="8" x="2" y="14" rx="2" ry="2" /> <line x1="6" x2="6.01" y1="6" y2="6" /> <line x1="6" x2="6.01" y1="18" y2="18" /></symbol>
<symbol id="i-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /> <circle cx="12" cy="12" r="3" /></symbol>
<symbol id="i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /> <path d="m6 6 12 12" /></symbol>
<symbol id="i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 16v-4" /> <path d="M12 8h.01" /></symbol>
<symbol id="i-hard-drive" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 16h.01" /> <path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" /> <path d="M21.946 12.013H2.054" /> <path d="M6 16h.01" /></symbol>
<symbol id="i-cpu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20v2" /> <path d="M12 2v2" /> <path d="M17 20v2" /> <path d="M17 2v2" /> <path d="M2 12h2" /> <path d="M2 17h2" /> <path d="M2 7h2" /> <path d="M20 12h2" /> <path d="M20 17h2" /> <path d="M20 7h2" /> <path d="M7 20v2" /> <path d="M7 2v2" /> <rect x="4" y="4" width="16" height="16" rx="2" /> <rect x="8" y="8" width="8" height="8" rx="1" /></symbol>
<symbol id="i-clock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 6v6l4 2" /></symbol>
<symbol id="i-boxes" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /> <path d="m7 16.5-4.74-2.85" /> <path d="m7 16.5 5-3" /> <path d="M7 16.5v5.17" /> <path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /> <path d="m17 16.5-5-3" /> <path d="m17 16.5 4.74-2.85" /> <path d="M17 16.5v5.17" /> <path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" /> <path d="M12 8 7.26 5.15" /> <path d="m12 8 4.74-2.85" /> <path d="M12 13.5V8" /></symbol>
<symbol id="i-users" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /> <path d="M16 3.128a4 4 0 0 1 0 7.744" /> <path d="M22 21v-2a4 4 0 0 0-3-3.87" /> <circle cx="9" cy="7" r="4" /></symbol>
</svg>
<script>
function felhomConfirm(el,question,onYes){
if(!el||el.dataset.fcOpen)return;
el.dataset.fcOpen='1';
var wrap=document.createElement('span');wrap.className='inline-confirm';
var q=document.createElement('span');q.className='inline-confirm-q';q.textContent=question;
var yes=document.createElement('button');yes.type='button';yes.className='btn btn-sm btn-danger';yes.textContent='Igen';
var no=document.createElement('button');no.type='button';no.className='btn btn-sm btn-outline';no.textContent='Mégse';
wrap.appendChild(q);wrap.appendChild(yes);wrap.appendChild(no);
el.style.display='none';el.parentNode.insertBefore(wrap,el.nextSibling);
function close(){wrap.remove();el.style.display='';delete el.dataset.fcOpen;}
no.addEventListener('click',close);
yes.addEventListener('click',function(){close();onYes();});
}
document.addEventListener('click',function(e){
var btn=e.target.closest?e.target.closest('[data-confirm]'):null;
if(!btn)return;
e.preventDefault();
felhomConfirm(btn,btn.getAttribute('data-confirm'),function(){
var form=btn.closest('form');
if(form){if(form.requestSubmit)form.requestSubmit(btn);else form.submit();}
});
});
</script>
<div class="container">
<header>
<h1>Felhom <span>Hub</span></h1>
<nav class="nav-links">
<a href="/" class="nav-link">Dashboard</a>
<a href="/configs" class="nav-link">Customers</a>
<a href="/apps" class="nav-link">Apps</a>
<a href="/hosts" class="nav-link active">Hosts</a>
<a href="/system" class="nav-link">System</a>
<a href="/offsite" class="nav-link">Offsite</a>
<a href="/configuration" class="nav-link">Configuration</a>
</nav>
</header>
<h2 style="margin-bottom: 1rem;">Hosts</h2>
<section class="card" id="held-apps" style="margin-bottom: 1.5rem; padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem; margin-top: 0;">Held apps</h2>
<table class="data-table">
<thead>
<tr>
<th>Customer</th>
<th>App</th>
<th>Reason</th>
<th>Since</th>
<th>Who may clear it</th>
</tr>
</thead>
<tbody>
<tr data-held-app="demo-hp/gokapi">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>gokapi</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
<tr data-held-app="demo-hp/chaosoom">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>chaosoom</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
<tr data-held-app="demo-hp/chaoscrash">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>chaoscrash</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
<tr data-held-app="demo-hp/chaosoomb">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>chaosoomb</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
<tr data-held-app="demo-hp/radicale">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>radicale</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>7 min ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
</tbody>
</table>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<table class="data-table">
<thead>
<tr>
<th>Host</th>
<th>Customer</th>
<th>Agent</th>
<th>Proxmox / kernel</th>
<th>Status</th>
<th>Guests</th>
<th>CPU</th>
<th>Mem</th>
<th>Disk</th>
<th>Cloudflared</th>
<th>Worst Storage</th>
</tr>
</thead>
<tbody>
<tr onclick="window.location='/hosts/d53-test-9202'" style="cursor: pointer;">
<td><a href="/hosts/d53-test-9202">d53-test-9202</a></td>
<td>Demo HP (scratch guest 9202)</td>
<td>—</td>
<td style="font-size: 0.85em;">unknown<br><span class="text-muted">unknown</span></td>
<td><span class="status-badge status-badge-pending">NO REPORT</span></td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
</tr>
</tbody>
</table>
</section>
<footer style="margin-top: 2rem; color: var(--text-muted); font-size: 0.8rem; text-align: center;">
Felhom Hub <span style="font-family: var(--font-mono)">0.173.0-d53test</span>
</footer>
</div>
</body>
</html>
@@ -0,0 +1,399 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>d53-test-9202 — Felhom Hub</title>
<link rel="stylesheet" href="/style.css?v=0.173.0-d53test">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
<symbol id="i-triangle-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /> <path d="M12 9v4" /> <path d="M12 17h.01" /></symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5" /></symbol>
<symbol id="i-server" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2" /> <rect width="20" height="8" x="2" y="14" rx="2" ry="2" /> <line x1="6" x2="6.01" y1="6" y2="6" /> <line x1="6" x2="6.01" y1="18" y2="18" /></symbol>
<symbol id="i-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /> <circle cx="12" cy="12" r="3" /></symbol>
<symbol id="i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /> <path d="m6 6 12 12" /></symbol>
<symbol id="i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 16v-4" /> <path d="M12 8h.01" /></symbol>
<symbol id="i-hard-drive" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 16h.01" /> <path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" /> <path d="M21.946 12.013H2.054" /> <path d="M6 16h.01" /></symbol>
<symbol id="i-cpu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20v2" /> <path d="M12 2v2" /> <path d="M17 20v2" /> <path d="M17 2v2" /> <path d="M2 12h2" /> <path d="M2 17h2" /> <path d="M2 7h2" /> <path d="M20 12h2" /> <path d="M20 17h2" /> <path d="M20 7h2" /> <path d="M7 20v2" /> <path d="M7 2v2" /> <rect x="4" y="4" width="16" height="16" rx="2" /> <rect x="8" y="8" width="8" height="8" rx="1" /></symbol>
<symbol id="i-clock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 6v6l4 2" /></symbol>
<symbol id="i-boxes" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /> <path d="m7 16.5-4.74-2.85" /> <path d="m7 16.5 5-3" /> <path d="M7 16.5v5.17" /> <path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /> <path d="m17 16.5-5-3" /> <path d="m17 16.5 4.74-2.85" /> <path d="M17 16.5v5.17" /> <path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" /> <path d="M12 8 7.26 5.15" /> <path d="m12 8 4.74-2.85" /> <path d="M12 13.5V8" /></symbol>
<symbol id="i-users" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /> <path d="M16 3.128a4 4 0 0 1 0 7.744" /> <path d="M22 21v-2a4 4 0 0 0-3-3.87" /> <circle cx="9" cy="7" r="4" /></symbol>
</svg>
<div class="container">
<header>
<h1>Felhom <span>Hub</span></h1>
<nav class="nav-links">
<a href="/" class="nav-link">Dashboard</a>
<a href="/configs" class="nav-link">Customers</a>
<a href="/apps" class="nav-link">Apps</a>
<a href="/hosts" class="nav-link active">Hosts</a>
<a href="/system" class="nav-link">System</a>
<a href="/offsite" class="nav-link">Offsite</a>
<a href="/configuration" class="nav-link">Configuration</a>
</nav>
</header>
<a href="/hosts" class="back-link">&larr; Hosts</a>
<section class="card">
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem;">
<h2 style="margin: 0;">d53-test-9202</h2>
<span class="status-badge status-badge-pending">NO REPORT</span>
</div>
<div class="info-grid" style="margin-top: 1rem;">
<div class="info-item">
<span class="label">Host ID</span>
<span class="value" style="font-family: var(--font-mono)">d53-test-9202</span>
</div>
<div class="info-item">
<span class="label">Customer</span>
<span class="value"><a href="/customers/demo-hp">Demo HP (scratch guest 9202)</a></span>
</div>
<div class="info-item">
<span class="label">Agent Version</span>
<span class="value">—</span>
</div>
<div class="info-item">
<span class="label">Enrolled</span>
<span class="value">16 min ago</span>
</div>
<div class="info-item">
<span class="label">Last Report</span>
<span class="value">waiting for first report</span>
</div>
<div class="info-item">
<span class="label">Box connection</span>
<span class="value" data-box-connection="not_connected" style="color: var(--warn)">not connected since the hub started (2026-10-26 17:28 UTC, 17 min ago)</span>
</div>
<div class="info-item">
<span class="label">Desired Generation</span>
<span class="value">0</span>
</div>
</div>
</section>
<section class="card">
<div class="empty-state">
<p>Waiting for first report.</p>
<p class="hint">Vitals, guests and storage appear once this host's agent sends a host-report.</p>
</div>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Guests</h2>
<div class="empty-state" style="border: none;">
<p>No guests reported on this host.</p>
</div>
</section>
<section class="card" id="held-apps" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Held apps</h2>
<table class="data-table">
<thead>
<tr>
<th>App</th>
<th>Reason</th>
<th>Since</th>
<th>Why</th>
<th>Who may clear it</th>
</tr>
</thead>
<tbody>
<tr data-held-app="gokapi">
<td><code>gokapi</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>stopped by the box for a crash loop (2026-09-24T10:37:48Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
<tr data-held-app="chaosoom">
<td><code>chaosoom</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>stopped by the box for a oom storm (2026-09-24T11:48:01Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
<tr data-held-app="chaoscrash">
<td><code>chaoscrash</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>stopped by the box for a crash loop (2026-09-24T12:16:24Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
<tr data-held-app="chaosoomb">
<td><code>chaosoomb</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>stopped by the box for a oom storm (2026-09-24T12:39:51Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
<tr data-held-app="radicale">
<td><code>radicale</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>7 min ago</td>
<td>stopped by the box for a crash loop (2026-10-26T17:37:52Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
</tbody>
</table>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Storage Targets</h2>
<div class="empty-state" style="border: none;">
<p>No storage targets reported.</p>
</div>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Capabilities</h2>
<div class="empty-state" style="border: none;">
<p>No capability report yet (waiting for the first host report).</p>
</div>
</section>
<section class="card">
<h2>Diagnostics — Log Bundles</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
Pull-based: the box ships its debug ring on its own next cycle — controller &le; one report interval (~15 min),
agent &asymp; one heartbeat. The pull is recorded in the box's own log (customer-visible). Bundles expire after 72 h.
</p>
<div style="display: flex; gap: 0.5rem; margin: 0.75rem 0;">
<form method="POST" action="/hosts/d53-test-9202/request-logs" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="component" value="controller">
<button type="submit" class="btn btn-sm">Request controller logs</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/request-logs" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="component" value="agent">
<button type="submit" class="btn btn-sm">Request agent logs</button>
</form>
</div>
<div class="empty-state" style="border: none;">
<p>No log bundles. Use the request buttons above — the box delivers on its next cycle.</p>
</div>
</section>
<section class="card" id="operator-actions">
<h2>Operator Actions</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
The box acts on its next report reply (usually seconds, at most one report interval) and answers on the
report after that. Each press runs once. Recorded in the box's own log and in Events. Unanswered after a day: expired.
</p>
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.75rem 0;">
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="offsite_backup_now">
<button type="submit" class="btn btn-sm">Run off-site backup now</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="run_job">
<select name="arg"><option value="disk-health-check">disk-health-check</option><option value="fill-watch">fill-watch</option><option value="offsite-integrity">offsite-integrity</option><option value="offsite-proof">offsite-proof</option></select>
<button type="submit" class="btn btn-sm">Run check now</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="abandon_stop">
<button type="submit" class="btn btn-sm btn-outline">Stop deletion countdown</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="abandon_extend">
<input type="number" name="arg" min="1" max="30" value="7" style="width: 4.5em; padding: 0.3em 0.5em;" aria-label="days">
<button type="submit" class="btn btn-sm btn-outline">Extend countdown (days from now)</button>
</form>
</div>
<div class="empty-state" style="border: none;">
<p>No operator actions for this box yet.</p>
</div>
</section>
<section class="card">
<h2>Network</h2>
<div class="info-grid">
<div class="info-item">
<span class="label">WireGuard</span>
<span class="value">
<span class="text-muted">no peer allocated</span>
</span>
</div>
</div>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem; margin-top: 0.75rem;">
Waiting for the first host report.
</p>
</section>
<section class="card">
<h2>Guest network
<span class="badge badge-neutral" title="A capable agent sent no guest-network stanza">unknown</span>
</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
This host reported no guest-network state, so it is <strong>unknown</strong> &mdash; not healthy.
The watchdog is default-on; a silent capable agent means it was switched off
(<code>guest_net.disable</code>), or this report predates it on this box.
</p>
</section>
<section class="card">
<h2>DR / Backup</h2>
<div class="info-grid">
<div class="info-item">
<span class="label">DR Recipe</span>
<span class="value"><span class="text-muted">none</span></span>
</div>
<div class="info-item">
<span class="label">Key Escrow</span>
<span class="value"><span class="text-muted">none</span></span>
</div>
<div class="info-item" id="offsite-integrity">
<span class="label">Last full check (off-site)</span>
<span class="value">not reported (no off-site status in the box&#39;s report)</span>
</div>
</div>
</section>
<section class="card">
<h2>Console access</h2>
<p><span class="badge badge-neutral">not vaulted</span></p>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
No console credential is vaulted for this host. Expected for a byo host — the owner manages root@pam. Otherwise the installer's step 4b did not run; re-run felhom-host-install.sh, or set and vault one per the break-glass runbook &sect;5.
</p>
</section>
<section class="card" style="border-color: var(--crit);">
<h2>Danger zone</h2>
<p class="text-muted" style="font-size: 0.85rem;">
Removing this host deletes its reports, guests, log bundles and WireGuard peer, and
permanently invalidates its API key — a still-running agent would receive 401s.
Re-enrollment requires the Day-0 passphrase flow.
</p>
<button type="button" class="btn btn-danger btn-sm" onclick="hostDeleteConfirm('d53-test-9202')">Remove host&hellip;</button>
<div id="host-delete-confirm-d53-test-9202" style="display: none; margin-top: 0.75rem; padding: 0.75rem; border: 1px solid var(--crit); background: var(--crit-dim); border-radius: var(--radius); max-width: 44em;">
<p id="host-delete-impact-d53-test-9202" style="margin: 0 0 0.5rem; font-size: 0.9em;">&hellip;</p>
<label id="host-delete-escrow-row-d53-test-9202" style="display: none; margin: 0 0 0.5rem; font-size: 0.85em;">
<input type="checkbox" id="host-delete-escrow-d53-test-9202">
Move key escrow to retained custody (required when escrow present) + remove DR bundle for this host
</label>
<p style="margin: 0 0 0.5rem; font-size: 0.85em; color: var(--text-2);">Type the host id to confirm:</p>
<form method="POST" action="/hosts/d53-test-9202/delete" id="host-delete-form-d53-test-9202" style="display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="confirm_host_id" id="host-delete-confirm-hidden-d53-test-9202" value="">
<input type="hidden" name="delete_escrow" id="host-delete-escrow-hidden-d53-test-9202" value="">
<input type="text" id="host-delete-confirm-input-d53-test-9202" placeholder="retype the host id&hellip;" style="padding: 0.3em 0.5em; width: 16em;">
<button type="button" class="btn btn-danger btn-sm" onclick="hostDeleteSubmit('d53-test-9202')">Confirm &amp; remove</button>
<button type="button" class="btn btn-sm btn-outline" onclick="document.getElementById('host-delete-confirm-d53-test-9202').style.display='none';">Cancel</button>
</form>
<p id="host-delete-err-d53-test-9202" style="margin: 0.4em 0 0; font-size: 0.8em; color: var(--crit);"></p>
</div>
</section>
<script>
function hostDeleteConfirm(hostID) {
var box = document.getElementById('host-delete-confirm-' + hostID);
var impact = document.getElementById('host-delete-impact-' + hostID);
document.getElementById('host-delete-confirm-input-' + hostID).value = '';
document.getElementById('host-delete-err-' + hostID).textContent = '';
box.style.display = 'block';
impact.textContent = 'Checking impact…';
fetch('/hosts/' + encodeURIComponent(hostID) + '/delete-impact')
.then(function(r){ return r.json(); })
.then(function(d){
var parts = ['Deleting ' + hostID + ' removes ' + d.guests + ' guest row(s), ' +
d.reports + ' host report(s), ' + d.log_bundles + ' agent log bundle(s)'];
if (d.wg_peer_bound) parts.push('the bound WireGuard peer');
if (d.pbs_secret_present) parts.push('the staged PBS secret');
if (d.recovery_present) parts.push('the break-glass recovery credential');
impact.textContent = parts.join(', ') + '. Host status: ' + d.status + '.' +
(d.deletable ? (d.off_tick_required ? ' No box connection for 6+ minutes — the "box is off" tick is required.' : '') : ' Host is ONLINE — deletion will be refused.');
document.getElementById('host-delete-escrow-row-' + hostID).style.display =
d.escrow_present ? 'block' : 'none';
})
.catch(function(){ impact.textContent = 'Could not compute the impact — the server will still enforce every gate.'; });
}
function hostDeleteSubmit(hostID) {
var typed = document.getElementById('host-delete-confirm-input-' + hostID).value.trim();
var err = document.getElementById('host-delete-err-' + hostID);
if (typed !== hostID) { err.textContent = 'Confirmation does not match the host id.'; return; }
var escrowRow = document.getElementById('host-delete-escrow-row-' + hostID);
var escrowCb = document.getElementById('host-delete-escrow-' + hostID);
if (escrowRow.style.display !== 'none' && !escrowCb.checked) {
err.textContent = 'This host has a key escrow — tick the acknowledgement to delete it too.';
return;
}
var offCb = document.getElementById('host-delete-off-' + hostID);
if (offCb && !offCb.checked) {
err.textContent = 'Tick "I checked: the box is off" first.';
return;
}
if (offCb) { document.getElementById('host-delete-off-hidden-' + hostID).value = '1'; }
document.getElementById('host-delete-confirm-hidden-' + hostID).value = typed;
document.getElementById('host-delete-escrow-hidden-' + hostID).value = escrowCb.checked ? '1' : '';
document.getElementById('host-delete-form-' + hostID).submit();
}
</script>
<footer style="margin-top: 2rem; color: var(--text-muted); font-size: 0.8rem; text-align: center;">
Felhom Hub <span style="font-family: var(--font-mono)">0.173.0-d53test</span>
</footer>
</div>
</body>
</html>
@@ -0,0 +1,169 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hosts — Felhom Hub</title>
<link rel="stylesheet" href="/style.css?v=0.173.0-d53test">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
<symbol id="i-triangle-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /> <path d="M12 9v4" /> <path d="M12 17h.01" /></symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5" /></symbol>
<symbol id="i-server" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2" /> <rect width="20" height="8" x="2" y="14" rx="2" ry="2" /> <line x1="6" x2="6.01" y1="6" y2="6" /> <line x1="6" x2="6.01" y1="18" y2="18" /></symbol>
<symbol id="i-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /> <circle cx="12" cy="12" r="3" /></symbol>
<symbol id="i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /> <path d="m6 6 12 12" /></symbol>
<symbol id="i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 16v-4" /> <path d="M12 8h.01" /></symbol>
<symbol id="i-hard-drive" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 16h.01" /> <path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" /> <path d="M21.946 12.013H2.054" /> <path d="M6 16h.01" /></symbol>
<symbol id="i-cpu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20v2" /> <path d="M12 2v2" /> <path d="M17 20v2" /> <path d="M17 2v2" /> <path d="M2 12h2" /> <path d="M2 17h2" /> <path d="M2 7h2" /> <path d="M20 12h2" /> <path d="M20 17h2" /> <path d="M20 7h2" /> <path d="M7 20v2" /> <path d="M7 2v2" /> <rect x="4" y="4" width="16" height="16" rx="2" /> <rect x="8" y="8" width="8" height="8" rx="1" /></symbol>
<symbol id="i-clock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 6v6l4 2" /></symbol>
<symbol id="i-boxes" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /> <path d="m7 16.5-4.74-2.85" /> <path d="m7 16.5 5-3" /> <path d="M7 16.5v5.17" /> <path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /> <path d="m17 16.5-5-3" /> <path d="m17 16.5 4.74-2.85" /> <path d="M17 16.5v5.17" /> <path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" /> <path d="M12 8 7.26 5.15" /> <path d="m12 8 4.74-2.85" /> <path d="M12 13.5V8" /></symbol>
<symbol id="i-users" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /> <path d="M16 3.128a4 4 0 0 1 0 7.744" /> <path d="M22 21v-2a4 4 0 0 0-3-3.87" /> <circle cx="9" cy="7" r="4" /></symbol>
</svg>
<script>
function felhomConfirm(el,question,onYes){
if(!el||el.dataset.fcOpen)return;
el.dataset.fcOpen='1';
var wrap=document.createElement('span');wrap.className='inline-confirm';
var q=document.createElement('span');q.className='inline-confirm-q';q.textContent=question;
var yes=document.createElement('button');yes.type='button';yes.className='btn btn-sm btn-danger';yes.textContent='Igen';
var no=document.createElement('button');no.type='button';no.className='btn btn-sm btn-outline';no.textContent='Mégse';
wrap.appendChild(q);wrap.appendChild(yes);wrap.appendChild(no);
el.style.display='none';el.parentNode.insertBefore(wrap,el.nextSibling);
function close(){wrap.remove();el.style.display='';delete el.dataset.fcOpen;}
no.addEventListener('click',close);
yes.addEventListener('click',function(){close();onYes();});
}
document.addEventListener('click',function(e){
var btn=e.target.closest?e.target.closest('[data-confirm]'):null;
if(!btn)return;
e.preventDefault();
felhomConfirm(btn,btn.getAttribute('data-confirm'),function(){
var form=btn.closest('form');
if(form){if(form.requestSubmit)form.requestSubmit(btn);else form.submit();}
});
});
</script>
<div class="container">
<header>
<h1>Felhom <span>Hub</span></h1>
<nav class="nav-links">
<a href="/" class="nav-link">Dashboard</a>
<a href="/configs" class="nav-link">Customers</a>
<a href="/apps" class="nav-link">Apps</a>
<a href="/hosts" class="nav-link active">Hosts</a>
<a href="/system" class="nav-link">System</a>
<a href="/offsite" class="nav-link">Offsite</a>
<a href="/configuration" class="nav-link">Configuration</a>
</nav>
</header>
<h2 style="margin-bottom: 1rem;">Hosts</h2>
<section class="card" id="held-apps" style="margin-bottom: 1.5rem; padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem; margin-top: 0;">Held apps</h2>
<table class="data-table">
<thead>
<tr>
<th>Customer</th>
<th>App</th>
<th>Reason</th>
<th>Since</th>
<th>Who may clear it</th>
</tr>
</thead>
<tbody>
<tr data-held-app="demo-hp/gokapi">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>gokapi</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
<tr data-held-app="demo-hp/chaosoom">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>chaosoom</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
<tr data-held-app="demo-hp/chaoscrash">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>chaoscrash</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
<tr data-held-app="demo-hp/chaosoomb">
<td><a href="/hosts/d53-test-9202#held-apps">demo-hp</a></td>
<td><code>chaosoomb</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>the household&#39;s Start (one more try)</td>
</tr>
</tbody>
</table>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<table class="data-table">
<thead>
<tr>
<th>Host</th>
<th>Customer</th>
<th>Agent</th>
<th>Proxmox / kernel</th>
<th>Status</th>
<th>Guests</th>
<th>CPU</th>
<th>Mem</th>
<th>Disk</th>
<th>Cloudflared</th>
<th>Worst Storage</th>
</tr>
</thead>
<tbody>
<tr onclick="window.location='/hosts/d53-test-9202'" style="cursor: pointer;">
<td><a href="/hosts/d53-test-9202">d53-test-9202</a></td>
<td>Demo HP (scratch guest 9202)</td>
<td>—</td>
<td style="font-size: 0.85em;">unknown<br><span class="text-muted">unknown</span></td>
<td><span class="status-badge status-badge-pending">NO REPORT</span></td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
<td>—</td>
</tr>
</tbody>
</table>
</section>
<footer style="margin-top: 2rem; color: var(--text-muted); font-size: 0.8rem; text-align: center;">
Felhom Hub <span style="font-family: var(--font-mono)">0.173.0-d53test</span>
</footer>
</div>
</body>
</html>
@@ -0,0 +1,391 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>d53-test-9202 — Felhom Hub</title>
<link rel="stylesheet" href="/style.css?v=0.173.0-d53test">
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
<symbol id="i-triangle-alert" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" /> <path d="M12 9v4" /> <path d="M12 17h.01" /></symbol>
<symbol id="i-check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6 9 17l-5-5" /></symbol>
<symbol id="i-server" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2" /> <rect width="20" height="8" x="2" y="14" rx="2" ry="2" /> <line x1="6" x2="6.01" y1="6" y2="6" /> <line x1="6" x2="6.01" y1="18" y2="18" /></symbol>
<symbol id="i-settings" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" /> <circle cx="12" cy="12" r="3" /></symbol>
<symbol id="i-x" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18" /> <path d="m6 6 12 12" /></symbol>
<symbol id="i-info" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 16v-4" /> <path d="M12 8h.01" /></symbol>
<symbol id="i-hard-drive" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 16h.01" /> <path d="M2.212 11.577a2 2 0 0 0-.212.896V18a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-5.527a2 2 0 0 0-.212-.896L18.55 5.11A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z" /> <path d="M21.946 12.013H2.054" /> <path d="M6 16h.01" /></symbol>
<symbol id="i-cpu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20v2" /> <path d="M12 2v2" /> <path d="M17 20v2" /> <path d="M17 2v2" /> <path d="M2 12h2" /> <path d="M2 17h2" /> <path d="M2 7h2" /> <path d="M20 12h2" /> <path d="M20 17h2" /> <path d="M20 7h2" /> <path d="M7 20v2" /> <path d="M7 2v2" /> <rect x="4" y="4" width="16" height="16" rx="2" /> <rect x="8" y="8" width="8" height="8" rx="1" /></symbol>
<symbol id="i-clock" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /> <path d="M12 6v6l4 2" /></symbol>
<symbol id="i-boxes" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z" /> <path d="m7 16.5-4.74-2.85" /> <path d="m7 16.5 5-3" /> <path d="M7 16.5v5.17" /> <path d="M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z" /> <path d="m17 16.5-5-3" /> <path d="m17 16.5 4.74-2.85" /> <path d="M17 16.5v5.17" /> <path d="M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z" /> <path d="M12 8 7.26 5.15" /> <path d="m12 8 4.74-2.85" /> <path d="M12 13.5V8" /></symbol>
<symbol id="i-users" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /> <path d="M16 3.128a4 4 0 0 1 0 7.744" /> <path d="M22 21v-2a4 4 0 0 0-3-3.87" /> <circle cx="9" cy="7" r="4" /></symbol>
</svg>
<div class="container">
<header>
<h1>Felhom <span>Hub</span></h1>
<nav class="nav-links">
<a href="/" class="nav-link">Dashboard</a>
<a href="/configs" class="nav-link">Customers</a>
<a href="/apps" class="nav-link">Apps</a>
<a href="/hosts" class="nav-link active">Hosts</a>
<a href="/system" class="nav-link">System</a>
<a href="/offsite" class="nav-link">Offsite</a>
<a href="/configuration" class="nav-link">Configuration</a>
</nav>
</header>
<a href="/hosts" class="back-link">&larr; Hosts</a>
<section class="card">
<div style="display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem;">
<h2 style="margin: 0;">d53-test-9202</h2>
<span class="status-badge status-badge-pending">NO REPORT</span>
</div>
<div class="info-grid" style="margin-top: 1rem;">
<div class="info-item">
<span class="label">Host ID</span>
<span class="value" style="font-family: var(--font-mono)">d53-test-9202</span>
</div>
<div class="info-item">
<span class="label">Customer</span>
<span class="value"><a href="/customers/demo-hp">Demo HP (scratch guest 9202)</a></span>
</div>
<div class="info-item">
<span class="label">Agent Version</span>
<span class="value">—</span>
</div>
<div class="info-item">
<span class="label">Enrolled</span>
<span class="value">22 min ago</span>
</div>
<div class="info-item">
<span class="label">Last Report</span>
<span class="value">waiting for first report</span>
</div>
<div class="info-item">
<span class="label">Box connection</span>
<span class="value" data-box-connection="not_connected" style="color: var(--warn)">not connected since the hub started (2026-10-26 17:28 UTC, 23 min ago)</span>
</div>
<div class="info-item">
<span class="label">Desired Generation</span>
<span class="value">0</span>
</div>
</div>
</section>
<section class="card">
<div class="empty-state">
<p>Waiting for first report.</p>
<p class="hint">Vitals, guests and storage appear once this host's agent sends a host-report.</p>
</div>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Guests</h2>
<div class="empty-state" style="border: none;">
<p>No guests reported on this host.</p>
</div>
</section>
<section class="card" id="held-apps" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Held apps</h2>
<table class="data-table">
<thead>
<tr>
<th>App</th>
<th>Reason</th>
<th>Since</th>
<th>Why</th>
<th>Who may clear it</th>
</tr>
</thead>
<tbody>
<tr data-held-app="gokapi">
<td><code>gokapi</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>stopped by the box for a crash loop (2026-09-24T10:37:48Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
<tr data-held-app="chaosoom">
<td><code>chaosoom</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>stopped by the box for a oom storm (2026-09-24T11:48:01Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
<tr data-held-app="chaoscrash">
<td><code>chaoscrash</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>stopped by the box for a crash loop (2026-09-24T12:16:24Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
<tr data-held-app="chaosoomb">
<td><code>chaosoomb</code></td>
<td><span class="severity-badge severity-warning">unhealthy_stop</span></td>
<td>32d ago</td>
<td>stopped by the box for a oom storm (2026-09-24T12:39:51Z) — the household&#39;s Start gives it one more try</td>
<td>the household&#39;s Start (one more try) <span class="text-muted">(operator reminded)</span></td>
</tr>
</tbody>
</table>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Storage Targets</h2>
<div class="empty-state" style="border: none;">
<p>No storage targets reported.</p>
</div>
</section>
<section class="card" style="padding: 0; overflow: hidden;">
<h2 style="padding: 1.25rem 1.25rem 0.5rem;">Capabilities</h2>
<div class="empty-state" style="border: none;">
<p>No capability report yet (waiting for the first host report).</p>
</div>
</section>
<section class="card">
<h2>Diagnostics — Log Bundles</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
Pull-based: the box ships its debug ring on its own next cycle — controller &le; one report interval (~15 min),
agent &asymp; one heartbeat. The pull is recorded in the box's own log (customer-visible). Bundles expire after 72 h.
</p>
<div style="display: flex; gap: 0.5rem; margin: 0.75rem 0;">
<form method="POST" action="/hosts/d53-test-9202/request-logs" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="component" value="controller">
<button type="submit" class="btn btn-sm">Request controller logs</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/request-logs" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="component" value="agent">
<button type="submit" class="btn btn-sm">Request agent logs</button>
</form>
</div>
<div class="empty-state" style="border: none;">
<p>No log bundles. Use the request buttons above — the box delivers on its next cycle.</p>
</div>
</section>
<section class="card" id="operator-actions">
<h2>Operator Actions</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
The box acts on its next report reply (usually seconds, at most one report interval) and answers on the
report after that. Each press runs once. Recorded in the box's own log and in Events. Unanswered after a day: expired.
</p>
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.75rem 0;">
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="offsite_backup_now">
<button type="submit" class="btn btn-sm">Run off-site backup now</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="run_job">
<select name="arg"><option value="disk-health-check">disk-health-check</option><option value="fill-watch">fill-watch</option><option value="offsite-integrity">offsite-integrity</option><option value="offsite-proof">offsite-proof</option></select>
<button type="submit" class="btn btn-sm">Run check now</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="abandon_stop">
<button type="submit" class="btn btn-sm btn-outline">Stop deletion countdown</button>
</form>
<form method="POST" action="/hosts/d53-test-9202/operator-action" style="display: inline;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="action" value="abandon_extend">
<input type="number" name="arg" min="1" max="30" value="7" style="width: 4.5em; padding: 0.3em 0.5em;" aria-label="days">
<button type="submit" class="btn btn-sm btn-outline">Extend countdown (days from now)</button>
</form>
</div>
<div class="empty-state" style="border: none;">
<p>No operator actions for this box yet.</p>
</div>
</section>
<section class="card">
<h2>Network</h2>
<div class="info-grid">
<div class="info-item">
<span class="label">WireGuard</span>
<span class="value">
<span class="text-muted">no peer allocated</span>
</span>
</div>
</div>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem; margin-top: 0.75rem;">
Waiting for the first host report.
</p>
</section>
<section class="card">
<h2>Guest network
<span class="badge badge-neutral" title="A capable agent sent no guest-network stanza">unknown</span>
</h2>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
This host reported no guest-network state, so it is <strong>unknown</strong> &mdash; not healthy.
The watchdog is default-on; a silent capable agent means it was switched off
(<code>guest_net.disable</code>), or this report predates it on this box.
</p>
</section>
<section class="card">
<h2>DR / Backup</h2>
<div class="info-grid">
<div class="info-item">
<span class="label">DR Recipe</span>
<span class="value"><span class="text-muted">none</span></span>
</div>
<div class="info-item">
<span class="label">Key Escrow</span>
<span class="value"><span class="text-muted">none</span></span>
</div>
<div class="info-item" id="offsite-integrity">
<span class="label">Last full check (off-site)</span>
<span class="value">not reported (no off-site status in the box&#39;s report)</span>
</div>
</div>
</section>
<section class="card">
<h2>Console access</h2>
<p><span class="badge badge-neutral">not vaulted</span></p>
<p class="hint" style="color: var(--text-muted); font-size: 0.85rem;">
No console credential is vaulted for this host. Expected for a byo host — the owner manages root@pam. Otherwise the installer's step 4b did not run; re-run felhom-host-install.sh, or set and vault one per the break-glass runbook &sect;5.
</p>
</section>
<section class="card" style="border-color: var(--crit);">
<h2>Danger zone</h2>
<p class="text-muted" style="font-size: 0.85rem;">
Removing this host deletes its reports, guests, log bundles and WireGuard peer, and
permanently invalidates its API key — a still-running agent would receive 401s.
Re-enrollment requires the Day-0 passphrase flow.
</p>
<button type="button" class="btn btn-danger btn-sm" onclick="hostDeleteConfirm('d53-test-9202')">Remove host&hellip;</button>
<div id="host-delete-confirm-d53-test-9202" style="display: none; margin-top: 0.75rem; padding: 0.75rem; border: 1px solid var(--crit); background: var(--crit-dim); border-radius: var(--radius); max-width: 44em;">
<p id="host-delete-impact-d53-test-9202" style="margin: 0 0 0.5rem; font-size: 0.9em;">&hellip;</p>
<label id="host-delete-escrow-row-d53-test-9202" style="display: none; margin: 0 0 0.5rem; font-size: 0.85em;">
<input type="checkbox" id="host-delete-escrow-d53-test-9202">
Move key escrow to retained custody (required when escrow present) + remove DR bundle for this host
</label>
<p style="margin: 0 0 0.5rem; font-size: 0.85em; color: var(--text-2);">Type the host id to confirm:</p>
<form method="POST" action="/hosts/d53-test-9202/delete" id="host-delete-form-d53-test-9202" style="display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap;">
<input type="hidden" name="_csrf" value="<redacted-test-csrf>">
<input type="hidden" name="confirm_host_id" id="host-delete-confirm-hidden-d53-test-9202" value="">
<input type="hidden" name="delete_escrow" id="host-delete-escrow-hidden-d53-test-9202" value="">
<input type="text" id="host-delete-confirm-input-d53-test-9202" placeholder="retype the host id&hellip;" style="padding: 0.3em 0.5em; width: 16em;">
<button type="button" class="btn btn-danger btn-sm" onclick="hostDeleteSubmit('d53-test-9202')">Confirm &amp; remove</button>
<button type="button" class="btn btn-sm btn-outline" onclick="document.getElementById('host-delete-confirm-d53-test-9202').style.display='none';">Cancel</button>
</form>
<p id="host-delete-err-d53-test-9202" style="margin: 0.4em 0 0; font-size: 0.8em; color: var(--crit);"></p>
</div>
</section>
<script>
function hostDeleteConfirm(hostID) {
var box = document.getElementById('host-delete-confirm-' + hostID);
var impact = document.getElementById('host-delete-impact-' + hostID);
document.getElementById('host-delete-confirm-input-' + hostID).value = '';
document.getElementById('host-delete-err-' + hostID).textContent = '';
box.style.display = 'block';
impact.textContent = 'Checking impact…';
fetch('/hosts/' + encodeURIComponent(hostID) + '/delete-impact')
.then(function(r){ return r.json(); })
.then(function(d){
var parts = ['Deleting ' + hostID + ' removes ' + d.guests + ' guest row(s), ' +
d.reports + ' host report(s), ' + d.log_bundles + ' agent log bundle(s)'];
if (d.wg_peer_bound) parts.push('the bound WireGuard peer');
if (d.pbs_secret_present) parts.push('the staged PBS secret');
if (d.recovery_present) parts.push('the break-glass recovery credential');
impact.textContent = parts.join(', ') + '. Host status: ' + d.status + '.' +
(d.deletable ? (d.off_tick_required ? ' No box connection for 6+ minutes — the "box is off" tick is required.' : '') : ' Host is ONLINE — deletion will be refused.');
document.getElementById('host-delete-escrow-row-' + hostID).style.display =
d.escrow_present ? 'block' : 'none';
})
.catch(function(){ impact.textContent = 'Could not compute the impact — the server will still enforce every gate.'; });
}
function hostDeleteSubmit(hostID) {
var typed = document.getElementById('host-delete-confirm-input-' + hostID).value.trim();
var err = document.getElementById('host-delete-err-' + hostID);
if (typed !== hostID) { err.textContent = 'Confirmation does not match the host id.'; return; }
var escrowRow = document.getElementById('host-delete-escrow-row-' + hostID);
var escrowCb = document.getElementById('host-delete-escrow-' + hostID);
if (escrowRow.style.display !== 'none' && !escrowCb.checked) {
err.textContent = 'This host has a key escrow — tick the acknowledgement to delete it too.';
return;
}
var offCb = document.getElementById('host-delete-off-' + hostID);
if (offCb && !offCb.checked) {
err.textContent = 'Tick "I checked: the box is off" first.';
return;
}
if (offCb) { document.getElementById('host-delete-off-hidden-' + hostID).value = '1'; }
document.getElementById('host-delete-confirm-hidden-' + hostID).value = typed;
document.getElementById('host-delete-escrow-hidden-' + hostID).value = escrowCb.checked ? '1' : '';
document.getElementById('host-delete-form-' + hostID).submit();
}
</script>
<footer style="margin-top: 2rem; color: var(--text-muted); font-size: 0.8rem; text-align: center;">
Felhom Hub <span style="font-family: var(--font-mono)">0.173.0-d53test</span>
</footer>
</div>
</body>
</html>
@@ -0,0 +1,253 @@
2026/10/26 17:29:52 notifier.go:81: [INFO] Notifier enabled (hub: http://192.168.0.180:18090)
2026/10/26 17:29:52 scheduler.go:120: [INFO] [scheduler] Registered periodic job: hold-report (every 1m0s)
2026/10/26 17:29:52 scheduler.go:85: [DEBUG] [scheduler] periodic job registered: name="hold-report" interval=1m0s totalJobs=8
2026/10/26 17:29:52 notifier.go:1145: [DEBUG] SyncPreferences: url=http://192.168.0.180:18090/api/v1/preferences source=default email= events=[backup_failed db_dump_failed disk_warning disk_critical storage_disconnected node_down health_critical expected_backup_missed expected_dbdump_missed offbox_enlarge_blocked app_update_undone app_update_held app_stopped_unhealthy storage_reconnected backup_integrity_failed crossdrive_failed health_recovered] cooldown=6h
2026/10/26 17:29:52 notifier.go:1176: [INFO] Notification preferences synced to hub: source=default status=ok email=, events=[backup_failed db_dump_failed disk_warning disk_critical storage_disconnected node_down health_critical expected_backup_missed expected_dbdump_missed offbox_enlarge_blocked app_update_undone app_update_held app_stopped_unhealthy storage_reconnected backup_integrity_failed crossdrive_failed health_recovered], cooldown=6h, email_cleared=false
2026/10/26 17:29:52 sync.go:559: [DEBUG] [sync] radicale/docker-compose.yml: hash match, skipped
2026/10/26 17:29:52 sync.go:559: [DEBUG] [sync] radicale/.felhom.yml: hash match, skipped
2026/10/26 17:30:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:30:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:30:52 holdreport.go:137: [INFO] [holdreport] chaoscrash held (unhealthy_stop since 2026-09-24T12:16:24Z) — reported to the hub
2026/10/26 17:30:52 holdreport.go:137: [INFO] [holdreport] chaosoom held (unhealthy_stop since 2026-09-24T11:48:01Z) — reported to the hub
2026/10/26 17:30:52 holdreport.go:137: [INFO] [holdreport] chaosoomb held (unhealthy_stop since 2026-09-24T12:39:51Z) — reported to the hub
2026/10/26 17:30:52 holdreport.go:137: [INFO] [holdreport] gokapi held (unhealthy_stop since 2026-09-24T10:37:48Z) — reported to the hub
2026/10/26 17:30:52 holdreport.go:137: [DEBUG] [holdreport] full re-send: 4 hold(s) sent, 0 cleared
2026/10/26 17:30:52 notifier.go:317: [DEBUG] PushEvent: type=app_held severity=info url=http://192.168.0.180:18090/api/v1/event
2026/10/26 17:30:52 notifier.go:317: [DEBUG] PushEvent: type=app_held severity=info url=http://192.168.0.180:18090/api/v1/event
2026/10/26 17:30:52 notifier.go:317: [DEBUG] PushEvent: type=app_held severity=info url=http://192.168.0.180:18090/api/v1/event
2026/10/26 17:30:52 notifier.go:317: [DEBUG] PushEvent: type=app_held severity=info url=http://192.168.0.180:18090/api/v1/event
2026/10/26 17:30:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 1ms)
2026/10/26 17:30:52 notifier.go:343: [DEBUG] PushEvent: app_held pushed OK (HTTP 200)
2026/10/26 17:30:52 notifier.go:355: [INFO] Event pushed: app_held (info) [hu-only] — App chaosoom is held: stopped by the box for a oom storm (2026-09-24T11:48:01Z) — the household's Start gives it one more try
2026/10/26 17:30:52 notifier.go:343: [DEBUG] PushEvent: app_held pushed OK (HTTP 200)
2026/10/26 17:30:52 notifier.go:355: [INFO] Event pushed: app_held (info) [hu-only] — App gokapi is held: stopped by the box for a crash loop (2026-09-24T10:37:48Z) — the household's Start gives it one more try
2026/10/26 17:30:52 notifier.go:343: [DEBUG] PushEvent: app_held pushed OK (HTTP 200)
2026/10/26 17:30:52 notifier.go:355: [INFO] Event pushed: app_held (info) [hu-only] — App chaoscrash is held: stopped by the box for a crash loop (2026-09-24T12:16:24Z) — the household's Start gives it one more try
2026/10/26 17:30:52 notifier.go:343: [DEBUG] PushEvent: app_held pushed OK (HTTP 200)
2026/10/26 17:30:52 notifier.go:355: [INFO] Event pushed: app_held (info) [hu-only] — App chaosoomb is held: stopped by the box for a oom storm (2026-09-24T12:39:51Z) — the household's Start gives it one more try
2026/10/26 17:31:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:31:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:31:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:32:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:32:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:32:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:33:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:33:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:33:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:34:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:34:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:34:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:35:41 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale
2026/10/26 17:35:41 router.go:78: [DEBUG] [api] GET /api/stacks/radicale (path=/stacks/radicale)
2026/10/26 17:35:41 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale/deploy-fields
2026/10/26 17:35:41 router.go:78: [DEBUG] [api] GET /api/stacks/radicale/deploy-fields (path=/stacks/radicale/deploy-fields)
2026/10/26 17:35:41 auth.go:144: [DEBUG] [web] auth: valid session for POST /api/stacks/radicale/deploy
2026/10/26 17:35:41 router.go:78: [DEBUG] [api] POST /api/stacks/radicale/deploy (path=/stacks/radicale/deploy)
2026/10/26 17:35:41 router.go:442: [INFO] [api] Deploy requested for stack: radicale
2026/10/26 17:35:41 router.go:78: [DEBUG] [api] deployStack: name=radicale contentLength=145
2026/10/26 17:35:41 deploy.go:338: [DEBUG] Deploy radicale: received 4 user values
2026/10/26 17:35:41 [DEBUG] [stacks] SaveAppConfig: saving /opt/docker/stacks/radicale — 4 env vars, 1 encrypted, 1 sensitive fields
2026/10/26 17:35:41 [INFO] [stacks] SaveAppConfig: saved config for radicale
2026/10/26 17:35:41 deploy.go:574: [INFO] [stacks] Deploying stack radicale with 4 env vars: [SUBDOMAIN, RADICALE_USER, RADICALE_PASSWORD, DOMAIN]
2026/10/26 17:35:41 manager.go:1856: [INFO] [stacks] Deploying stack radicale — checking 1 images...
2026/10/26 17:35:41 manager.go:1860: [DEBUG] ghcr.io/kozea/radicale:3.8.1@sha256:54d9406cd30f9e206a9dd6d61dfac48da26b9afc37200e14f23beb8fafa7d11c — not found locally, will pull
2026/10/26 17:35:41 lifecycle.go:70: [DEBUG] [integrations] OnStackStart: stack=radicale, waiting 5s for state refresh
2026/10/26 17:35:41 manager.go:1701: [DEBUG] Running: docker compose up -d (in /opt/docker/stacks/radicale)
2026/10/26 17:35:46 lifecycle.go:86: [DEBUG] [integrations] OnStackStart: stack=radicale integrationsFound=0
2026/10/26 17:35:46 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale
2026/10/26 17:35:46 router.go:78: [DEBUG] [api] GET /api/stacks/radicale (path=/stacks/radicale)
2026/10/26 17:35:50 deploy.go:664: [INFO] [stacks] Stack radicale deployed successfully (took 9.0s)
2026/10/26 17:35:50 [DEBUG] [stacks] SaveAppConfig: saving /opt/docker/stacks/radicale — 4 env vars, 1 encrypted, 1 sensitive fields
2026/10/26 17:35:50 [INFO] [stacks] SaveAppConfig: saved config for radicale
2026/10/26 17:35:50 [DEBUG] [stacks] SaveAppConfig: saving /opt/docker/stacks/radicale — 4 env vars, 0 encrypted, 1 sensitive fields
2026/10/26 17:35:50 [INFO] [stacks] SaveAppConfig: saved config for radicale
2026/10/26 17:35:50 installed.go:420: [INFO] [stacks] installed-images radicale: recorded 1 service(s) (radicale=ghcr.io/kozea/radicale:3.8.1 (sha256:54d9406cd30f…))
2026/10/26 17:35:50 [DEBUG] [stacks] SaveAppConfig: saving /opt/docker/stacks/radicale — 4 env vars, 0 encrypted, 1 sensitive fields
2026/10/26 17:35:50 [INFO] [stacks] SaveAppConfig: saved config for radicale
2026/10/26 17:35:50 pin.go:93: [INFO] [stacks] pin radicale: radicale=ghcr.io/kozea/radicale:3.8.1
2026/10/26 17:35:50 [DEBUG] [backup] radicale: off-site default not applied: no off-site target
2026/10/26 17:35:51 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale
2026/10/26 17:35:51 router.go:78: [DEBUG] [api] GET /api/stacks/radicale (path=/stacks/radicale)
2026/10/26 17:35:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:35:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:35:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:35:53 manager.go:1701: [DEBUG] Running: docker compose ps -a --format table {{.Name}} {{.Image}} {{.State}} {{.Status}} (in /opt/docker/stacks/radicale)
2026/10/26 17:35:53 manager.go:1817: [INFO] [stacks] Stack radicale post-start status:
2026/10/26 17:35:53 manager.go:1820: [INFO] [stacks] radicale ghcr.io/kozea/radicale:3.8.1@sha256:54d9406cd30f9e206a9dd6d61dfac48da26b9afc37200e14f23beb8fafa7d11c running Up 3 seconds (health: starting)
2026/10/26 17:35:56 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale
2026/10/26 17:35:56 router.go:78: [DEBUG] [api] GET /api/stacks/radicale (path=/stacks/radicale)
2026/10/26 17:36:01 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale
2026/10/26 17:36:01 router.go:78: [DEBUG] [api] GET /api/stacks/radicale (path=/stacks/radicale)
2026/10/26 17:36:06 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale
2026/10/26 17:36:06 router.go:78: [DEBUG] [api] GET /api/stacks/radicale (path=/stacks/radicale)
2026/10/26 17:36:12 healthprobe.go:187: [DEBUG] Health probe radicale: API GET :5232/.web/ → 200 (4ms)
2026/10/26 17:36:22 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 10s ago, effective interval 5m0s, healthy=true
2026/10/26 17:36:42 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 30s ago, effective interval 5m0s, healthy=true
2026/10/26 17:36:52 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 40s ago, effective interval 5m0s, healthy=true
2026/10/26 17:36:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:36:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:36:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:37:02 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 50s ago, effective interval 5m0s, healthy=true
2026/10/26 17:37:12 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m0s ago, effective interval 5m0s, healthy=true
2026/10/26 17:37:32 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m20s ago, effective interval 5m0s, healthy=true
2026/10/26 17:37:42 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m30s ago, effective interval 5m0s, healthy=true
2026/10/26 17:37:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:37:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:37:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:37:52 main.go:4311: [WARN] [deadapp] radicale: crash_loop — 7 in 10m0s; STOPPING it (decision 28)
2026/10/26 17:37:52 manager.go:1443: [DEBUG] [stacks] StopStack radicale: current state=starting deployed=true containers=1
2026/10/26 17:37:52 manager.go:1446: [INFO] [stacks] Stopping stack: radicale
2026/10/26 17:37:52 manager.go:1701: [DEBUG] Running: docker compose down (in /opt/docker/stacks/radicale)
2026/10/26 17:37:52 manager.go:1455: [INFO] [stacks] Stack radicale stopped successfully (took 0.3s)
2026/10/26 17:37:52 settings.go:2043: [WARN] [settings] restore hold SET for radicale — the app stays stopped until it is cleared
2026/10/26 17:37:52 update_guard.go:873: [WARN] [backup] radicale is STOPPED by the box: crash_loop (trip 1 within 24h0m0s) — Start gives it one more try (decision 28)
2026/10/26 17:37:52 notifier.go:317: [DEBUG] PushEvent: type=app_stopped_unhealthy severity=warning url=http://192.168.0.180:18090/api/v1/event
2026/10/26 17:37:52 notifier.go:343: [DEBUG] PushEvent: app_stopped_unhealthy pushed OK (HTTP 200)
2026/10/26 17:37:52 notifier.go:355: [INFO] Event pushed: app_stopped_unhealthy (warning) [hu-only] — A(z) radicale alkalmazást leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). Az Indítás gombbal újra megpróbálhatod.
2026/10/26 17:38:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:38:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:38:52 holdreport.go:137: [INFO] [holdreport] radicale held (unhealthy_stop since 2026-10-26T17:37:52Z) — reported to the hub
2026/10/26 17:38:52 notifier.go:317: [DEBUG] PushEvent: type=app_held severity=info url=http://192.168.0.180:18090/api/v1/event
2026/10/26 17:38:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 1ms)
2026/10/26 17:38:52 notifier.go:343: [DEBUG] PushEvent: app_held pushed OK (HTTP 200)
2026/10/26 17:38:52 notifier.go:355: [INFO] Event pushed: app_held (info) [hu-only] — App radicale is held: stopped by the box for a crash loop (2026-10-26T17:37:52Z) — the household's Start gives it one more try
2026/10/26 17:39:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:39:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:39:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:39:52 backup.go:540: [DEBUG] groupStacksByDrive: /mnt/sys_drive → [privatebin, radicale]
2026/10/26 17:40:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:40:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:40:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:41:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:41:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:41:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:42:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:42:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:42:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:43:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:43:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:43:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:44:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:44:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:44:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:44:52 backup.go:540: [DEBUG] groupStacksByDrive: /mnt/sys_drive → [privatebin, radicale]
2026/10/26 17:44:52 sync.go:559: [DEBUG] [sync] radicale/docker-compose.yml: hash match, skipped
2026/10/26 17:44:52 sync.go:559: [DEBUG] [sync] radicale/.felhom.yml: hash match, skipped
2026/10/26 17:45:37 auth.go:144: [DEBUG] [web] auth: valid session for POST /api/stacks/radicale/start
2026/10/26 17:45:37 router.go:78: [DEBUG] [api] POST /api/stacks/radicale/start (path=/stacks/radicale/start)
2026/10/26 17:45:37 router.go:663: [INFO] [api] start requested for stack: radicale
2026/10/26 17:45:37 router.go:78: [DEBUG] [api] actionStack: action=start name=radicale
2026/10/26 17:45:37 settings.go:2960: [INFO] [settings] unhealthy-stop hold LIFTED for radicale (Start)
2026/10/26 17:45:37 router.go:687: [INFO] [api] radicale: the unhealthy stop is LIFTED by Start — one more try (decision 28)
2026/10/26 17:45:37 manager.go:1354: [DEBUG] [stacks] StartStack radicale: current state=stopped deployed=true
2026/10/26 17:45:37 manager.go:1357: [INFO] [stacks] Starting stack: radicale
2026/10/26 17:45:37 manager.go:1364: [DEBUG] [stacks] StartStack radicale: prepared 10 env vars for compose
2026/10/26 17:45:37 manager.go:1701: [DEBUG] Running: docker compose up -d (in /opt/docker/stacks/radicale)
2026/10/26 17:45:37 manager.go:1372: [INFO] [stacks] Stack radicale started successfully (took 0.4s)
2026/10/26 17:45:38 installed.go:409: [DEBUG] [stacks] installed-images radicale: unchanged (1 service(s)) — app.yaml not rewritten
2026/10/26 17:45:38 lifecycle.go:70: [DEBUG] [integrations] OnStackStart: stack=radicale, waiting 5s for state refresh
2026/10/26 17:45:41 manager.go:1701: [DEBUG] Running: docker compose ps -a --format table {{.Name}} {{.Image}} {{.State}} {{.Status}} (in /opt/docker/stacks/radicale)
2026/10/26 17:45:41 manager.go:1817: [INFO] [stacks] Stack radicale post-start status:
2026/10/26 17:45:41 manager.go:1820: [INFO] [stacks] radicale ghcr.io/kozea/radicale:3.8.1@sha256:54d9406cd30f9e206a9dd6d61dfac48da26b9afc37200e14f23beb8fafa7d11c running Up 3 seconds (health: starting)
2026/10/26 17:45:43 lifecycle.go:86: [DEBUG] [integrations] OnStackStart: stack=radicale integrationsFound=0
2026/10/26 17:45:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:45:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:45:52 holdreport.go:137: [INFO] [holdreport] radicale hold cleared — reported to the hub
2026/10/26 17:45:52 notifier.go:317: [DEBUG] PushEvent: type=app_hold_cleared severity=info url=http://192.168.0.180:18090/api/v1/event
2026/10/26 17:45:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 1ms)
2026/10/26 17:45:52 notifier.go:343: [DEBUG] PushEvent: app_hold_cleared pushed OK (HTTP 200)
2026/10/26 17:45:52 notifier.go:355: [INFO] Event pushed: app_hold_cleared (info) [hu-only] — App radicale is no longer held
2026/10/26 17:45:52 healthprobe.go:187: [DEBUG] Health probe radicale: API GET :5232/.web/ → 200 (3ms)
2026/10/26 17:46:02 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 10s ago, effective interval 5m0s, healthy=true
2026/10/26 17:46:12 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 20s ago, effective interval 5m0s, healthy=true
2026/10/26 17:46:22 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 30s ago, effective interval 5m0s, healthy=true
2026/10/26 17:46:32 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 40s ago, effective interval 5m0s, healthy=true
2026/10/26 17:46:42 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 50s ago, effective interval 5m0s, healthy=true
2026/10/26 17:46:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:46:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:46:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:46:52 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m0s ago, effective interval 5m0s, healthy=true
2026/10/26 17:47:02 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m10s ago, effective interval 5m0s, healthy=true
2026/10/26 17:47:12 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m20s ago, effective interval 5m0s, healthy=true
2026/10/26 17:47:22 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m30s ago, effective interval 5m0s, healthy=true
2026/10/26 17:47:32 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m40s ago, effective interval 5m0s, healthy=true
2026/10/26 17:47:42 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 1m50s ago, effective interval 5m0s, healthy=true
2026/10/26 17:47:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:47:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:47:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:47:52 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 2m0s ago, effective interval 5m0s, healthy=true
2026/10/26 17:48:02 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 2m10s ago, effective interval 5m0s, healthy=true
2026/10/26 17:48:12 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 2m20s ago, effective interval 5m0s, healthy=true
2026/10/26 17:48:22 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 2m30s ago, effective interval 5m0s, healthy=true
2026/10/26 17:48:32 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 2m40s ago, effective interval 5m0s, healthy=true
2026/10/26 17:48:42 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 2m50s ago, effective interval 5m0s, healthy=true
2026/10/26 17:48:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:48:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:48:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:48:52 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 3m0s ago, effective interval 5m0s, healthy=true
2026/10/26 17:49:02 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 3m10s ago, effective interval 5m0s, healthy=true
2026/10/26 17:49:12 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 3m20s ago, effective interval 5m0s, healthy=true
2026/10/26 17:49:22 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 3m30s ago, effective interval 5m0s, healthy=true
2026/10/26 17:49:32 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 3m40s ago, effective interval 5m0s, healthy=true
2026/10/26 17:49:42 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 3m50s ago, effective interval 5m0s, healthy=true
2026/10/26 17:49:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:49:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:49:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:49:52 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 4m0s ago, effective interval 5m0s, healthy=true
2026/10/26 17:49:52 backup.go:540: [DEBUG] groupStacksByDrive: /mnt/sys_drive → [privatebin, radicale]
2026/10/26 17:49:52 dbdump.go:149: [DEBUG] DiscoverDatabases: docker ps output: 9fa4e86f3613 radicale radicale ghcr.io/kozea/radicale:3.8.1
2026/10/26 17:49:52 dbdump.go:171: [DEBUG] DiscoverDatabases: skipping container radicale (image=ghcr.io/kozea/radicale:3.8.1, not a database)
2026/10/26 17:49:52 recovery_unit.go:297: [INFO] [backup] Recovery unit captured for radicale → /mnt/sys_drive/felhom-data/backups/primary/radicale (images=1, secrets-referenced=1, data_keys=0, portable-carried=0/0, withheld=1)
2026/10/26 17:50:02 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 4m10s ago, effective interval 5m0s, healthy=true
2026/10/26 17:50:12 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 4m20s ago, effective interval 5m0s, healthy=true
2026/10/26 17:50:22 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 4m30s ago, effective interval 5m0s, healthy=true
2026/10/26 17:50:32 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 4m40s ago, effective interval 5m0s, healthy=true
2026/10/26 17:50:42 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 4m50s ago, effective interval 5m0s, healthy=true
2026/10/26 17:50:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:50:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:50:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:50:52 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 5m0s ago, effective interval 5m0s, healthy=true
2026/10/26 17:51:02 healthprobe.go:187: [DEBUG] Health probe radicale: API GET :5232/.web/ → 200 (3ms)
2026/10/26 17:51:12 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 10s ago, effective interval 5m0s, healthy=true
2026/10/26 17:51:22 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 20s ago, effective interval 5m0s, healthy=true
2026/10/26 17:51:32 healthprobe.go:64: [DEBUG] [stacks] RunHealthProbes: skipping radicale — last check 30s ago, effective interval 5m0s, healthy=true
2026/10/26 17:51:34 auth.go:144: [DEBUG] [web] auth: valid session for POST /api/stacks/radicale/stop
2026/10/26 17:51:34 router.go:78: [DEBUG] [api] POST /api/stacks/radicale/stop (path=/stacks/radicale/stop)
2026/10/26 17:51:34 router.go:663: [INFO] [api] stop requested for stack: radicale
2026/10/26 17:51:34 router.go:78: [DEBUG] [api] actionStack: action=stop name=radicale
2026/10/26 17:51:34 [DEBUG] [stacks] SaveAppConfig: saving /opt/docker/stacks/radicale — 4 env vars, 0 encrypted, 1 sensitive fields
2026/10/26 17:51:34 [INFO] [stacks] SaveAppConfig: saved config for radicale
2026/10/26 17:51:34 desiredstate.go:81: [INFO] [stacks] desired state for radicale recorded as "stopped" (was "running")
2026/10/26 17:51:34 manager.go:1443: [DEBUG] [stacks] StopStack radicale: current state=running deployed=true containers=1
2026/10/26 17:51:34 manager.go:1446: [INFO] [stacks] Stopping stack: radicale
2026/10/26 17:51:34 manager.go:1701: [DEBUG] Running: docker compose down (in /opt/docker/stacks/radicale)
2026/10/26 17:51:35 manager.go:1455: [INFO] [stacks] Stack radicale stopped successfully (took 0.4s)
2026/10/26 17:51:35 lifecycle.go:24: [DEBUG] [integrations] OnStackStop: stack=radicale integrationsFound=0
2026/10/26 17:51:40 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale
2026/10/26 17:51:40 router.go:78: [DEBUG] [api] GET /api/stacks/radicale (path=/stacks/radicale)
2026/10/26 17:51:40 auth.go:144: [DEBUG] [web] auth: valid session for POST /api/stacks/radicale/remove
2026/10/26 17:51:40 router.go:78: [DEBUG] [api] POST /api/stacks/radicale/remove (path=/stacks/radicale/remove)
2026/10/26 17:51:40 router.go:1025: [INFO] [api] Remove requested for stack: radicale
2026/10/26 17:51:40 router.go:78: [DEBUG] [api] removeStack: name=radicale
2026/10/26 17:51:40 router.go:78: [DEBUG] [api] removeStack: name=radicale removeHDDData=true removeBackups=true
2026/10/26 17:51:40 delete.go:626: [DEBUG] [stacks] RemoveStack called: name="radicale", removeHDDData=true, backupPathsToRemove=3
2026/10/26 17:51:40 delete.go:640: [DEBUG] [stacks] RemoveStack radicale: state=stopped, deployed=true, orphaned=false, deploying=false
2026/10/26 17:51:40 delete.go:697: [INFO] Removing deployed stack: radicale (removeHDDData=true, hddDeclared=false, backupPaths=3)
2026/10/26 17:51:40 delete.go:710: [DEBUG] [stacks] RemoveStack radicale: found 0 HDD mounts from compose file
2026/10/26 17:51:40 manager.go:1701: [DEBUG] Running: docker compose down --volumes (in /opt/docker/stacks/radicale)
2026/10/26 17:51:40 delete.go:736: [DEBUG] [stacks] RemoveStack radicale: compose down output:
2026/10/26 17:51:52 scheduler.go:450: [INFO] [scheduler] Running job: hold-report
2026/10/26 17:51:52 scheduler.go:85: [DEBUG] [scheduler] job hold-report: execution starting
2026/10/26 17:51:52 scheduler.go:467: [INFO] [scheduler] Job hold-report completed (took 0s)
2026/10/26 17:52:06 delete.go:774: [INFO] [stacks] RemoveStack radicale: removed volume(s) [radicale_radicale_data]
2026/10/26 17:52:06 delete.go:837: [DEBUG] [stacks] RemoveStack radicale: processing 3 backup paths for removal (base=/mnt/sys_drive/felhom-data/backups)
2026/10/26 17:52:06 delete.go:854: [INFO] Removed backup data: /mnt/sys_drive/felhom-data/backups/primary/radicale (36K)
2026/10/26 17:52:06 delete.go:862: [DEBUG] [stacks] RemoveStack radicale: removing app.yaml at /opt/docker/stacks/radicale/app.yaml
2026/10/26 17:52:06 delete.go:879: [INFO] Stack radicale removed successfully (took 26.8s)
2026/10/26 17:52:07 lifecycle.go:176: [DEBUG] [integrations] OnStackRemove: stack=radicale integrationsFound=0
2026/10/26 17:52:07 notifier.go:355: [INFO] Event pushed: app_removed (info) [hu-only] — Alkalmazás eltávolítva: radicale
2026/10/26 17:52:07 image_retention.go:265: [INFO] [stacks] image retention (remove of radicale): deleted [ghcr.io/kozea/radicale:<none>] (0139a3fcd1ed, 96.6MB) — no container, installed app or undo names it (decision 53)
2026/10/26 17:52:07 image_retention.go:238: [INFO] [stacks] image retention (remove of radicale): pass over 40 image(s) of [ghcr.io/kozea/radicale] — 1 candidate(s), 1 deleted, the rest kept
2026/10/26 17:52:12 auth.go:144: [DEBUG] [web] auth: valid session for GET /api/stacks/radicale
2026/10/26 17:52:12 router.go:78: [DEBUG] [api] GET /api/stacks/radicale (path=/stacks/radicale)
privatebin
@@ -0,0 +1 @@
held_apps after: [('chaosoom', 'unhealthy_stop'), ('gokapi', 'unhealthy_stop'), ('chaoscrash', 'unhealthy_stop'), ('chaosoomb', 'unhealthy_stop')]
@@ -0,0 +1,14 @@
['id', 'customer_id', 'event_type', 'severity', 'message', 'status', 'error_message', 'created_at', 'channel']
['1', 'demo-hp', 'app_definition_refused', 'warning', 'immich: the box REFUSED a catalog definition — it asks for c', 'sent', '', '2026-10-26 17:29:52', 'operator']
['2', 'demo-hp', 'app_definition_refused', 'warning', 'immich: the box REFUSED a catalog definition — it asks for c', 'skipped', 'operator_only', '2026-10-26 17:29:52', 'customer']
['3', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app gokapi has been held for 32 days (', 'sent', '', '2026-10-26 17:33:35', 'operator']
['4', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app gokapi has been held for 32 days (', 'skipped', 'operator_only', '2026-10-26 17:33:35', 'customer']
['5', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app chaosoom has been held for 32 days', 'sent', '', '2026-10-26 17:33:35', 'operator']
['6', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app chaosoom has been held for 32 days', 'skipped', 'operator_only', '2026-10-26 17:33:35', 'customer']
['7', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app chaoscrash has been held for 32 da', 'sent', '', '2026-10-26 17:33:35', 'operator']
['8', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app chaoscrash has been held for 32 da', 'skipped', 'operator_only', '2026-10-26 17:33:35', 'customer']
['9', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app chaosoomb has been held for 32 day', 'sent', '', '2026-10-26 17:33:35', 'operator']
['10', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app chaosoomb has been held for 32 day', 'skipped', 'operator_only', '2026-10-26 17:33:35', 'customer']
['11', 'demo-hp', 'app_stopped_unhealthy', 'warning', 'A(z) radicale alkalmazást leállítottuk, mert újra és újra ös', 'sent', '', '2026-10-26 17:37:53', 'operator']
['12', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app radicale has been held for 4m0s (u', 'sent', '', '2026-10-26 17:41:35', 'operator']
['13', 'demo-hp', 'app_held_reminder', 'warning', 'Customer demo-hp: the app radicale has been held for 4m0s (u', 'skipped', 'operator_only', '2026-10-26 17:41:35', 'customer']
@@ -0,0 +1,82 @@
2026/10/26 18:28:34 [INFO] felhom-hub 0.173.0-d53test starting
2026/10/26 18:28:34 [INFO] [store] app-update event types added to 0 household(s)' notification prefs (one-time, add-only): []
2026/10/26 18:28:34 [INFO] [store] app_stopped_unhealthy added to 0 household(s)' notification prefs (one-time, add-only): []
2026/10/26 18:28:34 [ERROR] OFFSITE_SECRET_KEY unset — off-site passwords cannot be sealed; provisioning and the key registrar are DISABLED
2026/10/26 18:28:34 [INFO] Database opened at /tmp/claude-1000/-mnt-5-hdd-felhom-eu-git/0b76c4d7-9b39-4e4e-869d-d0d2c6006331/scratchpad/testhub/data/hub.db
2026/10/26 18:28:34 [WARN] Cannot read seed dir /usr/share/felhom/assets-seed: open /usr/share/felhom/assets-seed: no such file or directory (no assets will be available until uploaded)
2026/10/26 18:28:34 [INFO] Asset manifest built: 0 files
2026/10/26 18:28:34 [INFO] App-email relay enabled (limit 30/min/customer, From domains [felhom.eu])
2026/10/26 18:28:34 [INFO] osupdates: approval rule = every ring-0 box healthy for 24h0m0s and 1 night run(s)
2026/10/26 18:28:34 [INFO] osupdates: the Docker engine set is approved only by the operator, after 2 healthy ring-0 night(s)
2026/10/26 18:28:34 [INFO] osupdates: alarms = no OS leg 168h0m0s, reboot needed 336h0m0s, ring 0 stalled 168h0m0s, not covered 336h0m0s
2026/10/26 18:28:34 [INFO] access log: /tmp/claude-1000/-mnt-5-hdd-felhom-eu-git/0b76c4d7-9b39-4e4e-869d-d0d2c6006331/scratchpad/testhub/data/access-log, one file per UTC day, kept 90 days
2026/10/26 18:28:34 [INFO] Registry version checker disabled (no credentials configured)
2026/10/26 18:28:34 [INFO] WG peer-sync disabled (endpoint not configured)
2026/10/26 18:28:34 [INFO] PBS DR tenantsync disabled (key or endpoint not configured)
2026/10/26 18:28:34 [INFO] agent-plane poke disabled (key or endpoint not configured)
2026/10/26 18:28:34 [INFO] PBS-DR self-heal reconciler started (interval 5m)
2026/10/26 18:28:34 [INFO] offsite credential self-heal reconciler started (interval 5m, debounce 2 reports)
2026/10/26 18:28:34 [INFO] Staleness checker initialized: 0 ok, 0 stale, 0 down (node_stale after 45m0s, node_down after 1h30m0s)
2026/10/26 18:28:34 [INFO] prune: next run at 2026-10-27 04:30 CET (in 10h1m25s)
2026/10/26 18:28:34 [INFO] Host staleness checker initialized: 0 ok, 0 already alarmed (seeded silently, R-1001), 0 stale, 0 down (left unseeded → first Check emits; host_stale after 45m0s, host_down after 1h30m0s)
2026/10/26 18:28:34 [INFO] Host capability checker initialized: 0 ok, 0 degraded, 0 with a refused whole-guest backup (degraded/refused left unseeded → first Check emits)
2026/10/26 18:28:34 [INFO] Host leaf checker initialized: 0 host fingerprint(s) seeded
2026/10/26 18:28:34 [INFO] Host disk checker initialized: warn=90% crit=95%, 0 ok seeded, 0 already-breached left unseeded (first Check emits)
2026/10/26 18:28:34 [INFO] Storage fill checker initialized: warn=90% crit=95%, 0 ok seeded, 0 already-breached left unseeded, 0 root-backed excluded
2026/10/26 18:28:34 [INFO] Host mgmt-plane checker initialized: 0 host heal-state(s) seeded
2026/10/26 18:28:34 [INFO] Host OOB checker initialized: 0 host(s) seeded degraded
2026/10/26 18:28:34 [INFO] Offsite checker initialized: fill warn=90% crit=95%, stale after 48h0m0s, 0 ok-seeded
2026/10/26 18:28:34 [WARN] Held apps: the reminder grace is OVERRIDDEN to 3m0s for every reason — a test configuration
2026/10/26 18:28:34 [WARN] Golden vouch check OFF: no registry credentials, so the hub cannot list published goldens
2026/10/26 18:28:34 [INFO] db-snapshot 08:00: next run at 2026-10-27 08:00 CET (in 13h31m25s)
2026/10/26 18:28:34 [INFO] db-snapshot 20:00: next run at 2026-10-26 20:00 CET (in 1h31m25s)
2026/10/26 18:28:34 [INFO] deadline-check: next run at 2026-10-27 05:00 CET (in 10h31m25s)
2026/10/26 18:28:34 [INFO] Listening on 192.168.0.180:18090
2026/10/26 18:28:34 [INFO] db-snapshot 14:00: next run at 2026-10-27 14:00 CET (in 19h31m25s)
2026/10/26 18:28:34 [INFO] db-snapshot 02:00: next run at 2026-10-27 02:00 CET (in 7h31m25s)
2026/10/26 18:28:34 [INFO] db snapshot written: hub-20261026T172834Z.db (409600 bytes, 13ms); pruned 0, keeping 2
2026/10/26 18:29:34 [INFO] osupdates: guest candidate (0 packages, first seen 0001-01-01T00:00:00Z): waiting — no ring-0 box
2026/10/26 18:29:34 [INFO] osupdates: host candidate (0 packages, first seen 0001-01-01T00:00:00Z): waiting — no ring-0 box
2026/10/26 18:29:34 [INFO] osupdates: alarm check done in 4ms, 0 alarm(s) sent []
2026/10/26 18:29:52 [DEBUG] Notification prefs read for demo-hp: exists=false household_saved=false
2026/10/26 18:29:52 [INFO] Notification preferences updated for demo-hp: address set=false, household=false, events=[backup_failed db_dump_failed disk_warning disk_critical storage_disconnected node_down health_critical expected_backup_missed expected_dbdump_missed offbox_enlarge_blocked app_update_undone app_update_held app_stopped_unhealthy storage_reconnected backup_integrity_failed crossdrive_failed health_recovered]
2026/10/26 18:29:52 [INFO] Event from demo-hp: app_definition_refused (warning) — immich: the box REFUSED a catalog definition — it asks for container rights not on the box's allow-list. Nothing was written; the app keeps its last good compose. Check who pushed to the catalog. the catalog definition of immich asks for container rights the box does not allow: immich-server: bind /mnt/sizing-bench/appdata/immich -> /usr/src/app/upload rw; immich-server: bind /mnt/sizing-bench/userdata/media/photos -> /external/photos ro
2026/10/26 18:29:52 [INFO] Operator email sent for demo-hp/app_definition_refused
2026/10/26 18:29:57 [INFO] Event from demo-hp: controller_started (info) — Controller elindult (0.346.0-d53test)
2026/10/26 18:29:58 [INFO] DR-recipe app-half stored for customer demo-hp (v1)
2026/10/26 18:29:58 [INFO] Received report from demo-hp (8171 bytes)
2026/10/26 18:30:52 [INFO] Event from demo-hp: app_held (info) — App chaosoom is held: stopped by the box for a oom storm (2026-09-24T11:48:01Z) — the household's Start gives it one more try
2026/10/26 18:30:52 [DEBUG] [held-apps] demo-hp/chaosoom held (unhealthy_stop since 2026-09-24T11:48:01Z)
2026/10/26 18:30:52 [INFO] Event from demo-hp: app_held (info) — App gokapi is held: stopped by the box for a crash loop (2026-09-24T10:37:48Z) — the household's Start gives it one more try
2026/10/26 18:30:52 [DEBUG] [held-apps] demo-hp/gokapi held (unhealthy_stop since 2026-09-24T10:37:48Z)
2026/10/26 18:30:52 [INFO] Event from demo-hp: app_held (info) — App chaoscrash is held: stopped by the box for a crash loop (2026-09-24T12:16:24Z) — the household's Start gives it one more try
2026/10/26 18:30:52 [DEBUG] [held-apps] demo-hp/chaoscrash held (unhealthy_stop since 2026-09-24T12:16:24Z)
2026/10/26 18:30:52 [INFO] Event from demo-hp: app_held (info) — App chaosoomb is held: stopped by the box for a oom storm (2026-09-24T12:39:51Z) — the household's Start gives it one more try
2026/10/26 18:30:52 [DEBUG] [held-apps] demo-hp/chaosoomb held (unhealthy_stop since 2026-09-24T12:39:51Z)
2026/10/26 18:33:34 [INFO] Held apps: reminder for demo-hp/gokapi (unhealthy_stop, held 32 days, repeat=false)
2026/10/26 18:33:35 [INFO] Operator email sent for demo-hp/app_held_reminder
2026/10/26 18:33:35 [INFO] Held apps: reminder for demo-hp/chaosoom (unhealthy_stop, held 32 days, repeat=false)
2026/10/26 18:33:35 [INFO] Operator email sent for demo-hp/app_held_reminder
2026/10/26 18:33:35 [INFO] Held apps: reminder for demo-hp/chaoscrash (unhealthy_stop, held 32 days, repeat=false)
2026/10/26 18:33:35 [INFO] Operator email sent for demo-hp/app_held_reminder
2026/10/26 18:33:35 [INFO] Held apps: reminder for demo-hp/chaosoomb (unhealthy_stop, held 32 days, repeat=false)
2026/10/26 18:33:35 [INFO] Operator email sent for demo-hp/app_held_reminder
2026/10/26 18:35:41 [INFO] Event from demo-hp: app_deploy_started (info) — Alkalmazás telepítése elindult: Radicale
2026/10/26 18:35:44 [INFO] DR-recipe app-half stored for customer demo-hp (v1)
2026/10/26 18:35:44 [INFO] Received report from demo-hp (8070 bytes)
2026/10/26 18:35:50 [INFO] Event from demo-hp: app_deployed (info) — Alkalmazás telepítve: Radicale
2026/10/26 18:37:52 [INFO] Event from demo-hp: app_stopped_unhealthy (warning) — A(z) radicale alkalmazást leállítottuk, mert újra és újra összeomlott (vagy elfogyott a memóriája). Az Indítás gombbal újra megpróbálhatod.
2026/10/26 18:37:53 [INFO] Operator email sent for demo-hp/app_stopped_unhealthy
2026/10/26 18:38:52 [INFO] Event from demo-hp: app_held (info) — App radicale is held: stopped by the box for a crash loop (2026-10-26T17:37:52Z) — the household's Start gives it one more try
2026/10/26 18:38:52 [DEBUG] [held-apps] demo-hp/radicale held (unhealthy_stop since 2026-10-26T17:37:52Z)
2026/10/26 18:41:34 [INFO] Held apps: reminder for demo-hp/radicale (unhealthy_stop, held 4m0s, repeat=false)
2026/10/26 18:41:35 [INFO] Operator email sent for demo-hp/app_held_reminder
2026/10/26 18:44:52 [INFO] DR-recipe app-half stored for customer demo-hp (v1)
2026/10/26 18:44:52 [INFO] Received report from demo-hp (7771 bytes)
2026/10/26 18:45:52 [INFO] Event from demo-hp: app_hold_cleared (info) — App radicale is no longer held
2026/10/26 18:45:52 [INFO] [held-apps] demo-hp/radicale no longer held (a row existed: true)
2026/10/26 18:52:07 [INFO] Event from demo-hp: app_removed (info) — Alkalmazás eltávolítva: radicale
2026/10/26 18:52:09 [INFO] DR-recipe app-half stored for customer demo-hp (v1)
2026/10/26 18:52:09 [INFO] Received report from demo-hp (7122 bytes)
2026/10/26 18:52:49 [INFO] Received signal terminated, shutting down...
2026/10/26 18:52:49 [INFO] felhom-hub stopped
@@ -0,0 +1,7 @@
RED internal/notify/dispatcher.go | "app_held_reminder": true, } // IsOperatorOnly | ['--- FAIL: TestD53_TheHeldAppReminderMailsTheOperatorOnly (0.04s)']
RED internal/api/handler.go | h.recordHeldApp(payload.CustomerID, payload.EventType, paylo | ['--- FAIL: TestD53_TheBoxsHeldAppsAreMirrored (0.05s)']
RED internal/monitor/held_apps.go | if age < hc.grace(h.Reason) { return } | ['--- FAIL: TestD53_OneReminderAfterTheGraceThenWeekly (0.04s)', '--- FAIL: TestD53_TheGraceFollowsTheReason (0.17s)']
RED internal/monitor/held_apps.go | if !h.RemindedAt.IsZero() && now.Sub(h.RemindedAt) < heldApp | ['--- FAIL: TestD53_OneReminderAfterTheGraceThenWeekly (0.03s)']
RED internal/web/hosts.go | "HeldApps": heldApps, | []
RED internal/web/templates/host_detail_body.html | <td>{{.WhoClears}}{{if .Reminded}} | ['--- FAIL: TestD53_HeldAppsListOnTheHostPageAndTheHostsPage (0.05s)']
RED internal/web/hosts.go | HeldApps emptied (compiling mutation) | TestD53_HeldAppsListOnTheHostPageAndTheHostsPage
@@ -0,0 +1,114 @@
[13:22:12] scratch drive folders cleared before FROM (R-656): none existed
[13:22:12] MV-homepage: deploying homepage at FROM {'homepage': 'ghcr.io/gethomepage/homepage:v1.13.2'}
[13:23:07] FROM settled=True in 30.9s :: {"homepage": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[13:23:07] fixture: the BOX walk's own (Homepage), through upgrade_boxport
[13:23:07] homepage: first-start config read: services=['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'] bookmarks=['Developer', 'Developer/Github', 'Entertainment', 'Entertainment/YouTube', 'Social', 'Social/Reddit']
[13:23:07] homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
[13:23:07] C1 (seed reads back BEFORE): True
[13:23:07] MV-homepage: swapping to TO {'homepage': 'ghcr.io/gethomepage/homepage:v2.7.0'}
[13:23:25] TO up -d rc=0
[13:23:56] TO settled=True in 30.9s :: {"homepage": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[13:23:56] migration lines observed: 0
[13:23:56] homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
[13:23:56] RESULT (seed reads back AFTER): True
[13:23:57] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:3000
[13:24:12] + 15s homepage=154M/256M peak=171M kills=0 rs=0 reqs=280
[13:24:27] + 30s homepage=156M/256M peak=199M kills=0 rs=0 reqs=562
[13:24:42] + 45s homepage=155M/256M peak=199M kills=0 rs=0 reqs=844
[13:24:57] + 60s homepage=162M/256M peak=199M kills=0 rs=0 reqs=1127
[13:25:12] + 76s homepage=160M/256M peak=199M kills=0 rs=0 reqs=1409
[13:25:27] + 91s homepage=160M/256M peak=199M kills=0 rs=0 reqs=1692
[13:25:43] + 106s homepage=161M/256M peak=199M kills=0 rs=0 reqs=1972
[13:25:58] + 121s homepage=161M/256M peak=199M kills=0 rs=0 reqs=2256
[13:26:13] + 136s homepage=160M/256M peak=199M kills=0 rs=0 reqs=2539
[13:26:28] + 151s homepage=162M/256M peak=199M kills=0 rs=0 reqs=2822
[13:26:43] + 166s homepage=161M/256M peak=199M kills=0 rs=0 reqs=3102
[13:26:58] + 182s homepage=161M/256M peak=199M kills=0 rs=0 reqs=3386
[13:27:13] + 197s homepage=161M/256M peak=199M kills=0 rs=0 reqs=3670
[13:27:28] + 212s homepage=161M/256M peak=199M kills=0 rs=0 reqs=3954
[13:27:44] + 227s homepage=161M/256M peak=199M kills=0 rs=0 reqs=4235
[13:27:59] + 242s homepage=162M/256M peak=199M kills=0 rs=0 reqs=4519
[13:28:14] + 257s homepage=162M/256M peak=199M kills=0 rs=0 reqs=4802
[13:28:29] + 272s homepage=162M/256M peak=199M kills=0 rs=0 reqs=5085
[13:28:44] + 288s homepage=163M/256M peak=199M kills=0 rs=0 reqs=5366
[13:28:59] + 303s homepage=163M/256M peak=199M kills=0 rs=0 reqs=5651
[13:29:14] + 318s homepage=163M/256M peak=199M kills=0 rs=0 reqs=5932
[13:29:30] + 333s homepage=162M/256M peak=199M kills=0 rs=0 reqs=6216
[13:29:45] + 348s homepage=162M/256M peak=199M kills=0 rs=0 reqs=6498
[13:30:00] + 363s homepage=163M/256M peak=199M kills=0 rs=0 reqs=6782
[13:30:15] + 378s homepage=162M/256M peak=199M kills=0 rs=0 reqs=7064
[13:30:30] + 393s homepage=164M/256M peak=199M kills=0 rs=0 reqs=7348
[13:30:45] + 408s homepage=163M/256M peak=199M kills=0 rs=0 reqs=7633
[13:31:00] + 424s homepage=163M/256M peak=199M kills=0 rs=0 reqs=7917
[13:31:15] + 439s homepage=163M/256M peak=199M kills=0 rs=0 reqs=8202
[13:31:31] + 454s homepage=163M/256M peak=199M kills=0 rs=0 reqs=8486
[13:31:46] + 469s homepage=163M/256M peak=199M kills=0 rs=0 reqs=8769
[13:32:01] + 484s homepage=163M/256M peak=199M kills=0 rs=0 reqs=9054
[13:32:16] + 499s homepage=163M/256M peak=199M kills=0 rs=0 reqs=9339
[13:32:31] + 514s homepage=163M/256M peak=199M kills=0 rs=0 reqs=9623
[13:32:46] + 530s homepage=163M/256M peak=199M kills=0 rs=0 reqs=9907
[13:33:01] + 545s homepage=162M/256M peak=199M kills=0 rs=0 reqs=10191
[13:33:17] + 560s homepage=163M/256M peak=199M kills=0 rs=0 reqs=10475
[13:33:32] + 575s homepage=165M/256M peak=199M kills=0 rs=0 reqs=10759
[13:33:47] + 590s homepage=163M/256M peak=199M kills=0 rs=0 reqs=11044
[13:34:02] + 605s homepage=163M/256M peak=199M kills=0 rs=0 reqs=11328
[13:34:02] memory watch: killed=False tight=[] requests=11329 codes={'200': 11329}
[13:34:02] MV-homepage: ABORT — putting the FROM images back
[13:34:34] homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
[13:34:34] ABORT: app came back in 30.9s; data present=True
{
"harness_version": 5,
"edge": "MV-homepage",
"app": "homepage",
"note": "night 2026-09-23 within-a-major move: homepage=ghcr.io/gethomepage/homepage:v2.7.0",
"from": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"to": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": null,
"abort": "starts-and-serves",
"abort_detail": null,
"engine_state_after": null,
"memory": {
"soak_s": 605.6,
"requested_s": 600,
"requests": 11329,
"codes": {
"200": 11329
},
"first_kill": null,
"containers": {
"homepage": {
"limit": 268435456,
"peak": 208699392,
"peak_pct": 0.777,
"anon_peak_sampled": 161771520,
"anon_peak_pct": 0.603,
"swap_peak": 0,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": [],
"venue_swap_bytes": 0,
"load": "reached"
},
"marks": [],
"bench_overrides": null,
"duration_s": 30.9,
"measured_at": "2026-10-28T13:34:34Z",
"evidence": "evidence/MV-homepage",
"scratch_cleared": [],
"files_changed": [],
"files_changed_detail": [],
"files_ignored": [],
"total_s": 741.8
}
@@ -0,0 +1,8 @@
{
"homepage": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,7 @@
homepage | Skipping ownership changes for /app/config
homepage | Skipping ownership changes for /app/config/logs
homepage | /app/.next already owned by correct UID/GID or running as root, skipping chown
homepage | ▲ Next.js 16.2.6
homepage | - Local: http://[::1]:3000
homepage | - Network: http://[::]:3000
homepage | ✓ Ready in 0ms
@@ -0,0 +1,762 @@
[
{
"t": 15.1,
"containers": {
"homepage": {
"limit": 268435456,
"current": 161652736,
"peak": 179814400,
"anon": 150859776,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 280
},
{
"t": 30.3,
"containers": {
"homepage": {
"limit": 268435456,
"current": 163991552,
"peak": 208699392,
"anon": 152416256,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 562
},
{
"t": 45.4,
"containers": {
"homepage": {
"limit": 268435456,
"current": 163385344,
"peak": 208699392,
"anon": 152231936,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 844
},
{
"t": 60.5,
"containers": {
"homepage": {
"limit": 268435456,
"current": 169988096,
"peak": 208699392,
"anon": 158003200,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1127
},
{
"t": 75.6,
"containers": {
"homepage": {
"limit": 268435456,
"current": 168656896,
"peak": 208699392,
"anon": 157360128,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1409
},
{
"t": 90.8,
"containers": {
"homepage": {
"limit": 268435456,
"current": 168165376,
"peak": 208699392,
"anon": 156856320,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1692
},
{
"t": 105.9,
"containers": {
"homepage": {
"limit": 268435456,
"current": 169406464,
"peak": 208699392,
"anon": 158060544,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 1972
},
{
"t": 121.0,
"containers": {
"homepage": {
"limit": 268435456,
"current": 169168896,
"peak": 208699392,
"anon": 157667328,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 2256
},
{
"t": 136.2,
"containers": {
"homepage": {
"limit": 268435456,
"current": 168607744,
"peak": 208699392,
"anon": 157224960,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 2539
},
{
"t": 151.3,
"containers": {
"homepage": {
"limit": 268435456,
"current": 170373120,
"peak": 208699392,
"anon": 158826496,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 2822
},
{
"t": 166.4,
"containers": {
"homepage": {
"limit": 268435456,
"current": 169033728,
"peak": 208699392,
"anon": 157913088,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 3102
},
{
"t": 181.6,
"containers": {
"homepage": {
"limit": 268435456,
"current": 169242624,
"peak": 208699392,
"anon": 157732864,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 3386
},
{
"t": 196.7,
"containers": {
"homepage": {
"limit": 268435456,
"current": 169426944,
"peak": 208699392,
"anon": 157798400,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 3670
},
{
"t": 211.8,
"containers": {
"homepage": {
"limit": 268435456,
"current": 168857600,
"peak": 208699392,
"anon": 157683712,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 3954
},
{
"t": 227.0,
"containers": {
"homepage": {
"limit": 268435456,
"current": 169488384,
"peak": 208699392,
"anon": 157790208,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 4235
},
{
"t": 242.1,
"containers": {
"homepage": {
"limit": 268435456,
"current": 170385408,
"peak": 208699392,
"anon": 158494720,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 4519
},
{
"t": 257.2,
"containers": {
"homepage": {
"limit": 268435456,
"current": 169967616,
"peak": 208699392,
"anon": 158564352,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 4802
},
{
"t": 272.4,
"containers": {
"homepage": {
"limit": 268435456,
"current": 170127360,
"peak": 208699392,
"anon": 159055872,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 5085
},
{
"t": 287.5,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171749376,
"peak": 208699392,
"anon": 160464896,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 5366
},
{
"t": 302.6,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171405312,
"peak": 208699392,
"anon": 159744000,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 5651
},
{
"t": 317.7,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171618304,
"peak": 208699392,
"anon": 160129024,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 5932
},
{
"t": 332.9,
"containers": {
"homepage": {
"limit": 268435456,
"current": 170696704,
"peak": 208699392,
"anon": 159551488,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 6216
},
{
"t": 348.0,
"containers": {
"homepage": {
"limit": 268435456,
"current": 170672128,
"peak": 208699392,
"anon": 159531008,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 6498
},
{
"t": 363.1,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171352064,
"peak": 208699392,
"anon": 160030720,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 6782
},
{
"t": 378.3,
"containers": {
"homepage": {
"limit": 268435456,
"current": 170725376,
"peak": 208699392,
"anon": 159576064,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 7064
},
{
"t": 393.4,
"containers": {
"homepage": {
"limit": 268435456,
"current": 172216320,
"peak": 208699392,
"anon": 160309248,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 7348
},
{
"t": 408.5,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171229184,
"peak": 208699392,
"anon": 159686656,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 7633
},
{
"t": 423.7,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171028480,
"peak": 208699392,
"anon": 159797248,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 7917
},
{
"t": 438.8,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171425792,
"peak": 208699392,
"anon": 159899648,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 8202
},
{
"t": 454.0,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171757568,
"peak": 208699392,
"anon": 159948800,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 8486
},
{
"t": 469.1,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171950080,
"peak": 208699392,
"anon": 160251904,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 8769
},
{
"t": 484.2,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171294720,
"peak": 208699392,
"anon": 160100352,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 9054
},
{
"t": 499.4,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171728896,
"peak": 208699392,
"anon": 159932416,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 9339
},
{
"t": 514.5,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171315200,
"peak": 208699392,
"anon": 160292864,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 9623
},
{
"t": 529.7,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171278336,
"peak": 208699392,
"anon": 160030720,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 9907
},
{
"t": 544.8,
"containers": {
"homepage": {
"limit": 268435456,
"current": 170803200,
"peak": 208699392,
"anon": 159604736,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 10191
},
{
"t": 559.9,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171347968,
"peak": 208699392,
"anon": 159899648,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 10475
},
{
"t": 575.0,
"containers": {
"homepage": {
"limit": 268435456,
"current": 173502464,
"peak": 208699392,
"anon": 161771520,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 10759
},
{
"t": 590.2,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171962368,
"peak": 208699392,
"anon": 160731136,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 11044
},
{
"t": 605.3,
"containers": {
"homepage": {
"limit": 268435456,
"current": 171524096,
"peak": 208699392,
"anon": 160374784,
"swap": 0,
"swap_peak": 0,
"oom_kill": 0,
"restarts": 0,
"oomkilled_flag": false,
"status": "running",
"cgroup": true
}
},
"requests": 11328
}
]
@@ -0,0 +1,58 @@
[13:22:12] scratch drive folders cleared before FROM (R-656): none existed
[13:22:12] MV-homepage: deploying homepage at FROM {'homepage': 'ghcr.io/gethomepage/homepage:v1.13.2'}
[13:23:07] FROM settled=True in 30.9s :: {"homepage": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[13:23:07] fixture: the BOX walk's own (Homepage), through upgrade_boxport
[13:23:07] homepage: first-start config read: services=['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'] bookmarks=['Developer', 'Developer/Github', 'Entertainment', 'Entertainment/YouTube', 'Social', 'Social/Reddit']
[13:23:07] homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
[13:23:07] C1 (seed reads back BEFORE): True
[13:23:07] MV-homepage: swapping to TO {'homepage': 'ghcr.io/gethomepage/homepage:v2.7.0'}
[13:23:25] TO up -d rc=0
[13:23:56] TO settled=True in 30.9s :: {"homepage": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[13:23:56] migration lines observed: 0
[13:23:56] homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
[13:23:56] RESULT (seed reads back AFTER): True
[13:23:57] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:3000
[13:24:12] + 15s homepage=154M/256M peak=171M kills=0 rs=0 reqs=280
[13:24:27] + 30s homepage=156M/256M peak=199M kills=0 rs=0 reqs=562
[13:24:42] + 45s homepage=155M/256M peak=199M kills=0 rs=0 reqs=844
[13:24:57] + 60s homepage=162M/256M peak=199M kills=0 rs=0 reqs=1127
[13:25:12] + 76s homepage=160M/256M peak=199M kills=0 rs=0 reqs=1409
[13:25:27] + 91s homepage=160M/256M peak=199M kills=0 rs=0 reqs=1692
[13:25:43] + 106s homepage=161M/256M peak=199M kills=0 rs=0 reqs=1972
[13:25:58] + 121s homepage=161M/256M peak=199M kills=0 rs=0 reqs=2256
[13:26:13] + 136s homepage=160M/256M peak=199M kills=0 rs=0 reqs=2539
[13:26:28] + 151s homepage=162M/256M peak=199M kills=0 rs=0 reqs=2822
[13:26:43] + 166s homepage=161M/256M peak=199M kills=0 rs=0 reqs=3102
[13:26:58] + 182s homepage=161M/256M peak=199M kills=0 rs=0 reqs=3386
[13:27:13] + 197s homepage=161M/256M peak=199M kills=0 rs=0 reqs=3670
[13:27:28] + 212s homepage=161M/256M peak=199M kills=0 rs=0 reqs=3954
[13:27:44] + 227s homepage=161M/256M peak=199M kills=0 rs=0 reqs=4235
[13:27:59] + 242s homepage=162M/256M peak=199M kills=0 rs=0 reqs=4519
[13:28:14] + 257s homepage=162M/256M peak=199M kills=0 rs=0 reqs=4802
[13:28:29] + 272s homepage=162M/256M peak=199M kills=0 rs=0 reqs=5085
[13:28:44] + 288s homepage=163M/256M peak=199M kills=0 rs=0 reqs=5366
[13:28:59] + 303s homepage=163M/256M peak=199M kills=0 rs=0 reqs=5651
[13:29:14] + 318s homepage=163M/256M peak=199M kills=0 rs=0 reqs=5932
[13:29:30] + 333s homepage=162M/256M peak=199M kills=0 rs=0 reqs=6216
[13:29:45] + 348s homepage=162M/256M peak=199M kills=0 rs=0 reqs=6498
[13:30:00] + 363s homepage=163M/256M peak=199M kills=0 rs=0 reqs=6782
[13:30:15] + 378s homepage=162M/256M peak=199M kills=0 rs=0 reqs=7064
[13:30:30] + 393s homepage=164M/256M peak=199M kills=0 rs=0 reqs=7348
[13:30:45] + 408s homepage=163M/256M peak=199M kills=0 rs=0 reqs=7633
[13:31:00] + 424s homepage=163M/256M peak=199M kills=0 rs=0 reqs=7917
[13:31:15] + 439s homepage=163M/256M peak=199M kills=0 rs=0 reqs=8202
[13:31:31] + 454s homepage=163M/256M peak=199M kills=0 rs=0 reqs=8486
[13:31:46] + 469s homepage=163M/256M peak=199M kills=0 rs=0 reqs=8769
[13:32:01] + 484s homepage=163M/256M peak=199M kills=0 rs=0 reqs=9054
[13:32:16] + 499s homepage=163M/256M peak=199M kills=0 rs=0 reqs=9339
[13:32:31] + 514s homepage=163M/256M peak=199M kills=0 rs=0 reqs=9623
[13:32:46] + 530s homepage=163M/256M peak=199M kills=0 rs=0 reqs=9907
[13:33:01] + 545s homepage=162M/256M peak=199M kills=0 rs=0 reqs=10191
[13:33:17] + 560s homepage=163M/256M peak=199M kills=0 rs=0 reqs=10475
[13:33:32] + 575s homepage=165M/256M peak=199M kills=0 rs=0 reqs=10759
[13:33:47] + 590s homepage=163M/256M peak=199M kills=0 rs=0 reqs=11044
[13:34:02] + 605s homepage=163M/256M peak=199M kills=0 rs=0 reqs=11328
[13:34:02] memory watch: killed=False tight=[] requests=11329 codes={'200': 11329}
[13:34:02] MV-homepage: ABORT — putting the FROM images back
[13:34:34] homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
[13:34:34] ABORT: app came back in 30.9s; data present=True
@@ -0,0 +1,9 @@
homepage | Skipping ownership changes for /app/config
homepage | Skipping ownership changes for /app/config/logs
homepage | /app/.next already owned by correct UID/GID or running as root, skipping chown
homepage | ▲ Next.js 16.4.1
homepage | - Local: http://[::1]:3000
homepage | - Network: http://[::]:3000
homepage | ✓ Ready in 0ms
homepage | ✓ Running next.config took 2ms
homepage | [2026-10-28T13:23:55.893Z] info: widgets.yaml was copied to the config folder
@@ -0,0 +1,8 @@
{
"homepage": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,56 @@
{
"harness_version": 5,
"edge": "MV-homepage",
"app": "homepage",
"note": "night 2026-09-23 within-a-major move: homepage=ghcr.io/gethomepage/homepage:v2.7.0",
"from": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"to": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": null,
"abort": "starts-and-serves",
"abort_detail": null,
"engine_state_after": null,
"memory": {
"soak_s": 605.6,
"requested_s": 600,
"requests": 11329,
"codes": {
"200": 11329
},
"first_kill": null,
"containers": {
"homepage": {
"limit": 268435456,
"peak": 208699392,
"peak_pct": 0.777,
"anon_peak_sampled": 161771520,
"anon_peak_pct": 0.603,
"swap_peak": 0,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": [],
"venue_swap_bytes": 0,
"load": "reached"
},
"marks": [],
"bench_overrides": null,
"duration_s": 30.9,
"measured_at": "2026-10-28T13:34:34Z",
"evidence": "evidence/MV-homepage",
"scratch_cleared": [],
"files_changed": [],
"files_changed_detail": [],
"files_ignored": [],
"total_s": 741.8
}
@@ -0,0 +1,231 @@
{
"app": "homepage",
"walk": "security",
"box_walk_version": 1,
"verdict": "proven",
"venue": "box 9202 (drill catalog), the guarded Update",
"from": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"to": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"observables_before": {
"pinned_images": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"installed_images": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"catalog_images": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"live_compose_image_lines": [
"image: ghcr.io/gethomepage/homepage:v1.13.2"
],
"docker_inspect": [
"homepage ghcr.io/gethomepage/homepage:v1.13.2 running=true restarts=0"
]
},
"setup_gate_before": {
"browser": {
"status": "302",
"redirect": "https://felhom.enkisfelhom.hu/__family/start?…"
},
"script": {
"status": "401",
"redirect": null
}
},
"seed": "read_back",
"drill_commit": "05ffd16393f5",
"sync_waited_s": 4.5,
"badge_before": {
"hu": [
{
"title": "Újabb változat érhető el ehhez az alkalmazáshoz. A frissítés indításához nyomd meg a Frissítés gombot.",
"text": "Frissítés elérhető — ma"
}
],
"en": [
{
"title": "A newer version of this app is available. Select the Update button to start it.",
"text": "Update available — today"
}
]
},
"measured_at": "2026-10-28T14:06:00Z",
"update": {
"accepted": true,
"http": "202",
"phases": [
{
"t": 0.0,
"phase": "backing-up",
"label": "Biztonsági mentés készül a frissítés előtt…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 2.1,
"phase": "safety-dump",
"label": "Adatbázis pillanatkép…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 3.1,
"phase": "pulling",
"label": "Új verzió letöltése…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 15.4,
"phase": "copying",
"label": "Az adatok másolása a frissítés előtt…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 21.5,
"phase": "starting",
"label": "Indítás az új verzióval…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 22.6,
"phase": "verifying",
"label": "Működés ellenőrzése…",
"updating": true,
"error": null,
"hold": null
},
{
"t": 32.8,
"phase": "done",
"label": "Frissítve",
"updating": false,
"error": null,
"hold": null
}
],
"duration_s": 32.8,
"final_phase": "done",
"update_error": null,
"hold_reason": null,
"state": "running"
},
"observables_after": {
"pinned_images": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"installed_images": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"catalog_images": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"live_compose_image_lines": [
"image: ghcr.io/gethomepage/homepage:v2.7.0"
],
"docker_inspect": [
"homepage ghcr.io/gethomepage/homepage:v2.7.0 running=true restarts=0"
]
},
"badge_after": {
"hu": [
{
"title": "Ez az alkalmazás a legfrissebb elérhető változatot futtatja.",
"text": "Naprakész"
}
],
"en": [
{
"title": "This app is running the newest version available.",
"text": "Up to date"
}
]
},
"state_after": "running",
"hold_after": null,
"to_digests": {
"homepage": "sha256:19c5c09184458a41b7b5915e71463a39f36cd33540f41bdbed008791b8182d5f"
},
"four_observables": {
"pinned": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"installed": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"catalog": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"live_compose": [
"ghcr.io/gethomepage/homepage:v2.7.0"
]
},
"seed_read_after": true,
"setup_gate_after": {
"browser": {
"status": "302",
"redirect": "https://felhom.enkisfelhom.hu/__family/start?…"
},
"script": {
"status": "401",
"redirect": null
}
},
"memory": {
"soak_s": 600,
"interval_s": 10,
"samples": 60,
"containers": {
"homepage": {
"samples": 60,
"anon_peak_bytes": 113119232,
"limit_bytes": 268435456,
"anon_peak_pct": 42.1,
"cgroup_peak_pct": 47.1,
"oom_kill_delta": 0,
"oom_killed_flag": false,
"restarts_delta": 0,
"running_all_samples": true,
"cgroup": "/sys/fs/cgroup/system.slice/docker-08d02265b7bf6977d598cb090c27333644e839e6f3afc81cf33231564b86826d.scope"
}
},
"oom_kills": 0,
"restarts": 0,
"peak_pct": 42.1
},
"why": "the security-fix step ran on the box through the guarded Update; healthy, TO on all four observables, no undo, no hold, a clean soak, seed read back",
"log": [
"15:05:02 [5] the box's drill mirror now at 4834d9dce",
"15:05:06 [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'}",
"15:05:41 [1] deployed, controller state=running, pinned={'homepage': 'ghcr.io/gethomepage/homepage:v1.13.2'}",
"15:05:42 family gate: home is family-gated — passed as the household (cookie set)",
"15:05:45 [2] setup gate as installed: {'browser': {'status': '302', 'redirect': 'https://felhom.enkisfelhom.hu/__family/start?…'}, 'script': {'status': '401', 'redirect': None}}",
"15:05:45 homepage: first-start config read: services=['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'] bookmarks=['Developer', 'Developer/Github', 'Entertainment', 'Entertainment/YouTube', 'Social', 'Social/Reddit']",
"15:05:45 homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])",
"15:05:46 [5] drill commit 05ffd16393f5: homepage ghcr.io/gethomepage/homepage:v1.13.2 -> ghcr.io/gethomepage/homepage:v2.7.0 (push rc=0)",
"15:05:55 [5] the box's drill mirror now at 05ffd1639",
"15:06:00 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}",
"15:06:00 + 0.0s phase=backing-up label=Biztonsági mentés készül a frissítés előtt… err=None hold=None",
"15:06:02 + 2.1s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None",
"15:06:03 + 3.1s phase=pulling label=Új verzió letöltése… err=None hold=None",
"15:06:15 + 15.4s phase=copying label=Az adatok másolása a frissítés előtt… err=None hold=None",
"15:06:21 + 21.5s phase=starting label=Indítás az új verzióval… err=None hold=None",
"15:06:22 + 22.6s phase=verifying label=Működés ellenőrzése… err=None hold=None",
"15:06:33 + 32.8s phase=done label=Frissítve err=None hold=None",
"15:06:51 homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])",
"15:06:51 [7] memory soak 600 s …",
"15:16:57 [7] soak: peak 42.1% of the limit (anon), kills 0, restarts 0"
]
}
@@ -0,0 +1,25 @@
15:05:02 [5] the box's drill mirror now at 4834d9dce
15:05:06 [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'}
15:05:41 [1] deployed, controller state=running, pinned={'homepage': 'ghcr.io/gethomepage/homepage:v1.13.2'}
15:05:42 family gate: home is family-gated — passed as the household (cookie set)
15:05:45 [2] setup gate as installed: {'browser': {'status': '302', 'redirect': 'https://felhom.enkisfelhom.hu/__family/start?…'}, 'script': {'status': '401', 'redirect': None}}
15:05:45 homepage: first-start config read: services=['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'] bookmarks=['Developer', 'Developer/Github', 'Entertainment', 'Entertainment/YouTube', 'Social', 'Social/Reddit']
15:05:45 homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
15:05:46 [5] drill commit 05ffd16393f5: homepage ghcr.io/gethomepage/homepage:v1.13.2 -> ghcr.io/gethomepage/homepage:v2.7.0 (push rc=0)
15:05:55 [5] the box's drill mirror now at 05ffd1639
15:06:00 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
15:06:00 + 0.0s phase=backing-up label=Biztonsági mentés készül a frissítés előtt… err=None hold=None
15:06:02 + 2.1s phase=safety-dump label=Adatbázis pillanatkép… err=None hold=None
15:06:03 + 3.1s phase=pulling label=Új verzió letöltése… err=None hold=None
15:06:15 + 15.4s phase=copying label=Az adatok másolása a frissítés előtt… err=None hold=None
15:06:21 + 21.5s phase=starting label=Indítás az új verzióval… err=None hold=None
15:06:22 + 22.6s phase=verifying label=Működés ellenőrzése… err=None hold=None
15:06:33 + 32.8s phase=done label=Frissítve err=None hold=None
15:06:51 homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
15:06:51 [7] memory soak 600 s …
15:16:57 [7] soak: peak 42.1% of the limit (anon), kills 0, restarts 0
15:16:57 [9] verdict proven -> /tmp/claude-1000/-mnt-5-hdd-felhom-eu-git/0b76c4d7-9b39-4e4e-869d-d0d2c6006331/scratchpad/p2/box/homepage/verdict.json
15:16:57 RESULT proven — the security-fix step ran on the box through the guarded Update; healthy, TO on all four observables, no undo, no hold, a clean soak, seed read back
15:16:57 [X] stop -> 200 {'ok': True, 'message': 'Stack homepage stop completed'}
15:17:29 [X] remove (with drive data) -> 200 {'ok': True, 'data': {'removed': 'homepage', 'volumes_removed': ['homepage_homepage_config'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note': 'A
15:17:38 [X] after remove: deployed=False leftovers=''
@@ -0,0 +1,24 @@
16:06:23 [5] the box's drill mirror now at c1b7f241d
16:06:28 [1] deploy -> 202 {'ok': True, 'message': 'Telepítés elindítva – az állapot a kártyán követhető'}
16:06:58 [1] deployed, controller state=running, pinned={'homepage': 'ghcr.io/gethomepage/homepage:v1.13.2'}
16:06:58 family gate: home is family-gated — passed as the household (cookie set)
16:06:58 homepage: first-start config read: services=['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'] bookmarks=['Developer', 'Developer/Github', 'Entertainment', 'Entertainment/YouTube', 'Social', 'Social/Reddit']
16:06:58 homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
16:06:59 drill commit c6c4b528c5ab: homepage TO with failing checks
16:07:08 [5] the box's drill mirror now at c6c4b528c
16:07:13 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Frissítés elindult – az állapot a kártyán követhető'}
16:07:13 + 0.0s phase=backing-up label=Biztonsági mentés készül a frissítés előtt… err=None hold=None
16:07:16 + 3.1s phase=pulling label=Új verzió letöltése… err=None hold=None
16:07:36 + 22.6s phase=copying label=Az adatok másolása a frissítés előtt… err=None hold=None
16:07:43 + 29.8s phase=starting label=Indítás az új verzióval… err=None hold=None
16:07:44 + 30.8s phase=verifying label=Működés ellenőrzése… err=None hold=None
16:12:46 + 333.1s phase=undoing label=Visszaállítás az előző változatra… err=None hold=None
16:12:59 + 345.5s phase=undone label=Visszaállítva az előző változatra err=None hold=None
16:13:28 homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])
16:13:28 RESULT proven — TO started on the data and failed its check; the box undid it: FROM runs again and the seed reads back
16:13:29 [X] stop -> 200 {'ok': True, 'message': 'Stack homepage stop completed'}
16:14:01 [X] remove (with drive data) -> 200 {'ok': True, 'data': {'removed': 'homepage', 'volumes_removed': ['homepage_homepage_config'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note': 'A
16:14:09 [X] after remove: deployed=False leftovers=''
16:14:19 [5] the box's drill mirror now at f574f6fef
16:14:19 drill revert c6c4b528c5ab: rc=0
16:14:19 drill templates/homepage equal to before: True
@@ -0,0 +1,144 @@
{
"app": "homepage",
"from": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"to": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"started": "2026-10-28T15:06:14Z",
"drill_head_before": "c1b7f241da1dfef40579011f9d032dcafbbf29c4",
"failing_compose_main_healthcheck": [
"test: [\"CMD\", \"false\"]"
],
"failing_probe": true,
"update": {
"accepted": true,
"http": "202",
"phases": [
{
"t": 0.0,
"phase": "backing-up",
"label": "Biztons\u00e1gi ment\u00e9s k\u00e9sz\u00fcl a friss\u00edt\u00e9s el\u0151tt\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 3.1,
"phase": "pulling",
"label": "\u00daj verzi\u00f3 let\u00f6lt\u00e9se\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 22.6,
"phase": "copying",
"label": "Az adatok m\u00e1sol\u00e1sa a friss\u00edt\u00e9s el\u0151tt\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 29.8,
"phase": "starting",
"label": "Ind\u00edt\u00e1s az \u00faj verzi\u00f3val\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 30.8,
"phase": "verifying",
"label": "M\u0171k\u00f6d\u00e9s ellen\u0151rz\u00e9se\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 333.1,
"phase": "undoing",
"label": "Vissza\u00e1ll\u00edt\u00e1s az el\u0151z\u0151 v\u00e1ltozatra\u2026",
"updating": true,
"error": null,
"hold": null
},
{
"t": 345.5,
"phase": "undone",
"label": "Vissza\u00e1ll\u00edtva az el\u0151z\u0151 v\u00e1ltozatra",
"updating": false,
"error": null,
"hold": null
}
],
"duration_s": 345.5,
"final_phase": "undone",
"update_error": null,
"hold_reason": null,
"state": "running"
},
"to_log_while_verifying": [
"ghcr.io/gethomepage/homepage:v2.7.0",
"Skipping ownership changes for /app/config",
"Skipping ownership changes for /app/config/logs",
"/app/.next already owned by correct UID/GID or running as root, skipping chown",
"\u25b2 Next.js 16.4.1",
"- Local: http://[::1]:3000",
"- Network: http://[::]:3000",
"\u2713 Ready in 0ms",
"\u2713 Running next.config took 3ms"
],
"observables_after": {
"pinned_images": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"installed_images": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"catalog_images": {
"homepage": "ghcr.io/gethomepage/homepage:v2.7.0"
},
"live_compose_image_lines": [
"image: ghcr.io/gethomepage/homepage:v1.13.2"
],
"docker_inspect": [
"homepage ghcr.io/gethomepage/homepage:v1.13.2 running=true restarts=0"
]
},
"running_images_after": {
"homepage": "ghcr.io/gethomepage/homepage:v1.13.2"
},
"seed_after_undo": true,
"verdict": "proven",
"why": "TO started on the data and failed its check; the box undid it: FROM runs again and the seed reads back",
"drill_head_after": "f574f6fef47182eaa13b330a2b69c7ad8dfdfa18",
"drill_tree_equal_to_before": true,
"log": [
"16:06:23 [5] the box's drill mirror now at c1b7f241d",
"16:06:28 [1] deploy -> 202 {'ok': True, 'message': 'Telep\u00edt\u00e9s elind\u00edtva \u2013 az \u00e1llapot a k\u00e1rty\u00e1n k\u00f6vethet\u0151'}",
"16:06:58 [1] deployed, controller state=running, pinned={'homepage': 'ghcr.io/gethomepage/homepage:v1.13.2'}",
"16:06:58 family gate: home is family-gated \u2014 passed as the household (cookie set)",
"16:06:58 homepage: first-start config read: services=['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'] bookmarks=['Developer', 'Developer/Github', 'Entertainment', 'Entertainment/YouTube', 'Social', 'Social/Reddit']",
"16:06:58 homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])",
"16:06:59 drill commit c6c4b528c5ab: homepage TO with failing checks",
"16:07:08 [5] the box's drill mirror now at c6c4b528c",
"16:07:13 [6] Update -> 202 {'ok': True, 'data': {'accepted': True, 'completed': False}, 'message': 'Friss\u00edt\u00e9s elindult \u2013 az \u00e1llapot a k\u00e1rty\u00e1n k\u00f6vethet\u0151'}",
"16:07:13 + 0.0s phase=backing-up label=Biztons\u00e1gi ment\u00e9s k\u00e9sz\u00fcl a friss\u00edt\u00e9s el\u0151tt\u2026 err=None hold=None",
"16:07:16 + 3.1s phase=pulling label=\u00daj verzi\u00f3 let\u00f6lt\u00e9se\u2026 err=None hold=None",
"16:07:36 + 22.6s phase=copying label=Az adatok m\u00e1sol\u00e1sa a friss\u00edt\u00e9s el\u0151tt\u2026 err=None hold=None",
"16:07:43 + 29.8s phase=starting label=Ind\u00edt\u00e1s az \u00faj verzi\u00f3val\u2026 err=None hold=None",
"16:07:44 + 30.8s phase=verifying label=M\u0171k\u00f6d\u00e9s ellen\u0151rz\u00e9se\u2026 err=None hold=None",
"16:12:46 + 333.1s phase=undoing label=Vissza\u00e1ll\u00edt\u00e1s az el\u0151z\u0151 v\u00e1ltozatra\u2026 err=None hold=None",
"16:12:59 + 345.5s phase=undone label=Vissza\u00e1ll\u00edtva az el\u0151z\u0151 v\u00e1ltozatra err=None hold=None",
"16:13:28 homepage: the same services and bookmarks after: True (['My First Group', 'My First Group/My First Service', 'My Second Group', 'My Second Group/My Second Service', 'My Third Group', 'My Third Group/My Third Service'])",
"16:13:28 RESULT proven \u2014 TO started on the data and failed its check; the box undid it: FROM runs again and the seed reads back",
"16:13:29 [X] stop -> 200 {'ok': True, 'message': 'Stack homepage stop completed'}",
"16:14:01 [X] remove (with drive data) -> 200 {'ok': True, 'data': {'removed': 'homepage', 'volumes_removed': ['homepage_homepage_config'], 'hdd_paths_removed': [], 'hdd_paths_preserved': [], 'hdd_note': 'A",
"16:14:09 [X] after remove: deployed=False leftovers=''",
"16:14:19 [5] the box's drill mirror now at f574f6fef",
"16:14:19 drill revert c6c4b528c5ab: rc=0",
"16:14:19 drill templates/homepage equal to before: True"
]
}
@@ -0,0 +1,260 @@
2026-10-28T07:02:45.6766584Z felhom-gates-runner(version:v0.6.1) received task 2474 of job watch, be triggered by event: workflow_dispatch
2026-10-28T07:02:45.6776680Z workflow prepared
2026-10-28T07:02:45.6792173Z evaluating expression 'success()'
2026-10-28T07:02:45.6793981Z expression 'success()' evaluated to 'true'
2026-10-28T07:02:45.6827518Z evaluating expression ''
2026-10-28T07:02:45.6828507Z expression '' evaluated to 'true'
2026-10-28T07:02:45.6828949Z ⭐ Run Main Fetch main (latest, for the memory) and the two sibling repos
2026-10-28T07:02:45.6835870Z Wrote command \n\necho "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"\nbase=http://gitea.gitea-system.svc.cluster.local:3000/admin\ngit init -q . && git remote add origin $base/felhom.eu.git\ngit fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD\necho "felhom.eu main at $(git rev-parse --short=12 HEAD)"\nfor r in felhom-controller app-catalog-felhom.eu; do\n git init -q ../$r && git -C ../$r remote add origin $base/$r.git\n git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD\n echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"\ndone\n\n\n to 'workflow/0.sh'
2026-10-28T07:02:45.6838134Z ::group::Run echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
2026-10-28T07:02:45.6838581Z echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
2026-10-28T07:02:45.6838855Z base=http://gitea.gitea-system.svc.cluster.local:3000/admin
2026-10-28T07:02:45.6839093Z git init -q . && git remote add origin $base/felhom.eu.git
2026-10-28T07:02:45.6839329Z git fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD
2026-10-28T07:02:45.6839561Z echo "felhom.eu main at $(git rev-parse --short=12 HEAD)"
2026-10-28T07:02:45.6839801Z for r in felhom-controller app-catalog-felhom.eu; do
2026-10-28T07:02:45.6840014Z git init -q ../$r && git -C ../$r remote add origin $base/$r.git
2026-10-28T07:02:45.6840242Z git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD
2026-10-28T07:02:45.6840600Z echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"
2026-10-28T07:02:45.6840825Z done
2026-10-28T07:02:45.6841022Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T07:02:45.6841309Z ::endgroup::
2026-10-28T07:03:52.1610192Z felhom.eu main at a3247d9f4402
2026-10-28T07:03:56.0824506Z felhom-controller at ed3927f03a52
2026-10-28T07:03:58.4269801Z app-catalog-felhom.eu at 0158b5054137
2026-10-28T07:03:58.4289933Z ::group::Run set -u
2026-10-28T07:03:58.4290302Z set -u
2026-10-28T07:03:58.4290487Z mkdir -p documentation/security-watch
2026-10-28T07:03:58.4290932Z mode="${MODE:-run}"
2026-10-28T07:03:58.4291054Z [ "${GITHUB_EVENT_NAME:-}" = "schedule" ] && mode=run
2026-10-28T07:03:58.4291207Z echo "mode: $mode"
2026-10-28T07:03:58.4291312Z case "$mode" in
2026-10-28T07:03:58.4291418Z test-mail) python3 scripts/security_watch.py --test-mail; exit $? ;;
2026-10-28T07:03:58.4291577Z dry) extra="--no-mail" ; state=/tmp/state-dry.json
2026-10-28T07:03:58.4291706Z cp documentation/security-watch/state.json "$state" 2>/dev/null || true ;;
2026-10-28T07:03:58.4291853Z seed) extra="--seed" ; state=documentation/security-watch/state.json ;;
2026-10-28T07:03:58.4292063Z run) extra="" ; state=documentation/security-watch/state.json ;;
2026-10-28T07:03:58.4292250Z *) echo "unknown mode $mode"; exit 2 ;;
2026-10-28T07:03:58.4292361Z esac
2026-10-28T07:03:58.4292453Z python3 scripts/security_watch.py --state="$state" --catalog=../app-catalog-felhom.eu \
2026-10-28T07:03:58.4292612Z --controller=../felhom-controller --json=/tmp/watch-results.json $extra
2026-10-28T07:03:58.4292806Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T07:03:58.4292956Z env:
2026-10-28T07:03:58.4293085Z RESEND_API_KEY: ***
2026-10-28T07:03:58.4293216Z GH_ADVISORY_TOKEN: ***
2026-10-28T07:03:58.4293326Z MODE: dry
2026-10-28T07:03:58.4293424Z FELHOM_WHEEL_FETCH: 1
2026-10-28T07:03:58.4293559Z ::endgroup::
2026-10-28T07:03:58.4328718Z mode: dry
2026-10-28T07:03:58.6964846Z /root/.cache/act/c519d37010cb2508/hostexecutor/scripts/security_watch.py:846: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
2026-10-28T07:03:58.6965920Z today = datetime.date.fromisoformat(opts["today"]) if "today" in opts else datetime.datetime.utcnow().date()
2026-10-28T07:03:58.7527191Z security watch 2026-10-28: 197 pins (11 box/build, 97 app, 89 DooPlex); GitHub key PRESENT — every repo's advisories tonight
2026-10-28T07:05:17.7461447Z RUNTIME-READ ghcr.io/immich-app/immich-machine-learning:v3.3.5 45 s ok
2026-10-28T07:05:25.1474391Z RUNTIME-READ rommapp/romm:5.4.1 25 s ok
2026-10-28T07:05:50.2048023Z RUNTIME-READ ghcr.io/immich-app/immich-server:v3.3.5 71 s NOT CHECKED: blob sha256:1fea3edc99a2: HTTP 429
2026-10-28T07:05:58.3868665Z RUNTIME-READ ghcr.io/home-assistant/home-assistant:2026.10.4 87 s ok
2026-10-28T07:06:08.4045906Z RUNTIME-READ docker.io/library/nextcloud:34.0.5-apache 44 s ok
2026-10-28T07:06:19.2808031Z ADVISORY doop actualbudget/actual-server 26.10.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2808841Z ADVISORY doop advplyr/audiobookshelf 2.37.1 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2809047Z ADVISORY box cloudflare/cloudflared 2026.10.4 feed:cloudflare-blog:01M5DK5J81T0VC8YTBR2FKD8A3 (fixed read the notice); vulnnotes:cloudflared@2026.10.5:VULN-183456 (fixed 2026.10.5)
2026-10-28T07:06:19.2809294Z ADVISORY doop codewithcj/sparkyfitness_server v1.9.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2809442Z ADVISORY doop crocodilestick/calibre-web-automated dev CVE-2026-111497 (fixed 1.2.1)
2026-10-28T07:06:19.2809607Z ADVISORY doop docker.io/calcom/cal.com v6.2.0 CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T07:06:19.2809773Z ADVISORY doop flomp/wanderer-db v0.21.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 1 more
2026-10-28T07:06:19.2809979Z ADVISORY doop flomp/wanderer-web v0.21.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 2 more
2026-10-28T07:06:19.2810162Z ADVISORY doop ghcr.io/gethomepage/homepage v1.13.2 GHSA-669x-4pg4-w24r (fixed 2.2.0); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T07:06:19.2811325Z ADVISORY doop ghcr.io/immich-app/immich-machine-learning v2.7.5 GHSA-q89f-h332-8q2h (fixed v3.2.4); GHSA-h5w4-vjv4-9r5q (fixed a version after 3.1.0 (the notice names none)); GHSA-g4w3-c888-cr93 (fixed v3.2.0); GHSA-72rm-x7xr-v679 (fixed v3.3.0); … 7 more
2026-10-28T07:06:19.2811702Z ADVISORY doop ghcr.io/immich-app/immich-server v2.7.5 GHSA-q89f-h332-8q2h (fixed v3.2.4); GHSA-h5w4-vjv4-9r5q (fixed a version after 3.1.0 (the notice names none)); GHSA-g4w3-c888-cr93 (fixed v3.2.0); GHSA-72rm-x7xr-v679 (fixed v3.3.0); … 8 more
2026-10-28T07:06:19.2811897Z ADVISORY doop ghcr.io/lukegus/termix release-2.9.2 CVE-2026-111497 (fixed 26.12.1)
2026-10-28T07:06:19.2812040Z ADVISORY doop ghcr.io/paperless-ngx/paperless-ngx 3.3.4 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T07:06:19.2812197Z ADVISORY doop gitea/gitea 1.26.2 GHSA-wx44-9m3m-rjqx (fixed 28.2.0); GHSA-4jmf-h2cm-hg7w (fixed 28.2.0); GHSA-8j56-f865-gqq2 (fixed 28.2.0); GHSA-fxq4-gr55-7x5g (fixed 28.2.0); … 127 more
2026-10-28T07:06:19.2812396Z ADVISORY doop grafana/grafana 13.2.4 GHSA-8xmm-x63g-f6xv (fixed no fixed version named yet); GHSA-4724-7jwc-3fpw (fixed the range is unreadable — check by hand); GHSA-2x6g-h2hg-rq84 (fixed the range is unreadable — check by hand); GHSA-8wjh-59cw-9xh4 (fixed no fixed version named yet); … 2 more
2026-10-28T07:06:19.2812773Z ADVISORY box gtstef/filebrowser 1.5.8-stable GHSA-gfgm-886h-6r47 (fixed 2.0.2-stable, 2.1.4-beta); GHSA-wxj5-g3qp-g732 (fixed 2.0.2-stable, 2.1.3-beta); GHSA-3j46-5w28-f8p2 (fixed 2.1.0-stable, 2.1.3-beta); GHSA-4vrc-935w-xxq2 (fixed 2.1.0-stable, 2.1.3-beta); … 31 more
2026-10-28T07:06:19.2812979Z ADVISORY doop louislam/uptime-kuma 2.5.6 GHSA-qjxc-h5jf-c7rj (fixed the range is unreadable — check by hand); release:louislam/uptime-kuma@2.5.8 (fixed 2.5.8); release:louislam/uptime-kuma@2.5.7 (fixed 2.5.7); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T07:06:19.2813197Z ADVISORY doop outlinewiki/outline 1.11.0 GHSA-x4w3-9p9j-cprh (fixed 1.12.0); GHSA-rq53-m97j-f2pg (fixed 1.12.0); GHSA-h6ff-rw9x-5mq2 (fixed 1.12.0); GHSA-rvj7-2gww-6xfq (fixed 1.12.0); … 3 more
2026-10-28T07:06:19.2813419Z ADVISORY doop redis 8.10.2 GHSA-c8h9-259x-jff4 (fixed the range is unreadable — check by hand); GHSA-8ghh-qpmp-7826 (fixed no fixed version named yet); GHSA-93m2-935m-8rj3 (fixed no fixed version named yet); GHSA-m8fj-85cg-7vhp (fixed the range is unreadable — check by hand); … 8 more
2026-10-28T07:06:19.2813645Z ADVISORY doop rommapp/romm 5.4.0 release:rommapp/romm@5.4.1 (fixed 5.4.1); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2813794Z ADVISORY doop vabene1111/recipes 2.6.15 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2814086Z ADVISORY app actualbudget/actual-server 26.9.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2814260Z ADVISORY app calcom/cal.com v6.2.0 GHSA-p3f6-52gv-cj7m (fixed the range is unreadable — check by hand); GHSA-cpf2-q635-xrwx (fixed the range is unreadable — check by hand); CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T07:06:19.2814452Z ADVISORY app codewithcj/sparkyfitness v0.17.3 GHSA-v883-jx9h-qf29 (fixed a version after 1.7.2 (the notice names none)); GHSA-cmmf-53wf-r5gv (fixed a version after 1.6.5 (the notice names none)); GHSA-p8cf-g8rv-gvrq (fixed a version after 1.6.5 (the notice names none))
2026-10-28T07:06:19.2814645Z ADVISORY app codewithcj/sparkyfitness_server v0.17.3 GHSA-v883-jx9h-qf29 (fixed a version after 1.7.2 (the notice names none)); GHSA-cmmf-53wf-r5gv (fixed a version after 1.6.5 (the notice names none)); GHSA-p8cf-g8rv-gvrq (fixed a version after 1.6.5 (the notice names none)); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2814899Z ADVISORY app crocodilestick/calibre-web-automated v4.0.8 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T07:06:19.2815056Z ADVISORY app f0rc3/gokapi v1.9.6 GHSA-45vh-rpc8-hxpp (fixed 2.2.4); GHSA-qwc6-vc2v-2ggj (fixed 2.2.4); GHSA-j6jp-78w8-34x6 (fixed 2.2.4); GHSA-m2hx-wjxc-9fp4 (fixed 2.2.3); … 6 more
2026-10-28T07:06:19.2815243Z ADVISORY app fallenbagel/jellyseerr 2.7.3 GHSA-8j73-j6rc-q8xh (fixed 3.5.0); GHSA-xc6j-6p6h-p799 (fixed 3.5.0); GHSA-mc6w-69r3-62h8 (fixed 3.4.0); GHSA-gx3h-3jg5-q65f (fixed 3.1.0); … 3 more
2026-10-28T07:06:19.2815430Z ADVISORY app flomp/wanderer-db v0.20.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 7 more
2026-10-28T07:06:19.2815616Z ADVISORY app flomp/wanderer-web v0.20.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 8 more
2026-10-28T07:06:19.2815794Z ADVISORY app freikin/dawarich 1.15.3 release:Freika/dawarich@1.17.0 (fixed 1.17.0); CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T07:06:19.2815986Z ADVISORY app ghcr.io/alexta69/metube 2026.09.29 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T07:06:19.2816145Z ADVISORY app ghcr.io/diced/zipline 4.8.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2816289Z ADVISORY app ghcr.io/gethomepage/homepage v1.13.2 GHSA-669x-4pg4-w24r (fixed 2.2.0); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T07:06:19.2816436Z ADVISORY app ghcr.io/immich-app/immich-machine-learning v3.3.5 GHSA-8244-8vpr-vp9c (fixed the range is unreadable — check by hand)
2026-10-28T07:06:19.2816600Z ADVISORY app ghcr.io/immich-app/immich-server v3.3.5 GHSA-8244-8vpr-vp9c (fixed the range is unreadable — check by hand)
2026-10-28T07:06:19.2816807Z ADVISORY app ghcr.io/karakeep-app/karakeep 0.33.2 GHSA-pp34-2c9r-mchw (fixed no fixed version named yet); release:karakeep-app/karakeep@v0.34.1 (fixed v0.34.1); release:karakeep-app/karakeep@v0.34.0 (fixed v0.34.0); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2817026Z ADVISORY app ghcr.io/lukegus/termix 2.8.0 GHSA-6gr3-r7jx-wfmh (fixed >= 26.10.0); GHSA-frx8-qqgg-7j7g (fixed >= 26.10.0); GHSA-3q2m-5r5p-w45r (fixed >= 26.10.0); GHSA-rgf3-2q88-q4wp (fixed >= 26.10.0); … 9 more
2026-10-28T07:06:19.2817231Z ADVISORY app ghcr.io/paperless-ngx/paperless-ngx 2.20.15 GHSA-c8f3-pqr2-rr24 (fixed 3.3.2); GHSA-2jhj-xqrq-rmrq (fixed 3.1.2); CVE-2026-111497 (fixed 1.1.1)
2026-10-28T07:06:19.2817433Z ADVISORY app ghcr.io/papra-hq/papra 26.6.2-rootless CVE-2026-111497 (fixed 26.12.1)
2026-10-28T07:06:19.2817602Z ADVISORY app ghcr.io/seanmorley15/adventurelog-backend v0.13.0 release:seanmorley15/AdventureLog@v0.13.1 (fixed v0.13.1)
2026-10-28T07:06:19.2817773Z ADVISORY app ghcr.io/seanmorley15/adventurelog-frontend v0.13.0 release:seanmorley15/AdventureLog@v0.13.1 (fixed v0.13.1); CVE-2026-111497 (fixed 26.12.1)
2026-10-28T07:06:19.2817940Z ADVISORY app ghcr.io/tandoorrecipes/recipes 2.6.15 GHSA-5f74-7rgh-pc97 (fixed a version after 2.6.15 (the notice names none)); GHSA-pcq2-64qw-jm4x (fixed no fixed version named yet); GHSA-69q3-5q6x-7hmx (fixed no fixed version named yet); GHSA-xq7g-9q95-vjc6 (fixed a version after 2.6.15 (the notice names none)); … 7 more
2026-10-28T07:06:19.2818170Z ADVISORY app ghost 6.67.0-alpine CVE-2026-111497 (fixed 22.23.4)
2026-10-28T07:06:19.2818408Z ADVISORY app gitea/gitea 1.27.3 GHSA-wx44-9m3m-rjqx (fixed 28.2.0); GHSA-4jmf-h2cm-hg7w (fixed 28.2.0); GHSA-8j56-f865-gqq2 (fixed 28.2.0); GHSA-fxq4-gr55-7x5g (fixed 28.2.0); … 37 more
2026-10-28T07:06:19.2818587Z ADVISORY app glanceapp/glance v0.8.5 GHSA-r225-jhr6-68cc (fixed >= 0.8.7)
2026-10-28T07:06:19.2818766Z ADVISORY app grafana/grafana 13.2.4 GHSA-8xmm-x63g-f6xv (fixed no fixed version named yet); GHSA-4724-7jwc-3fpw (fixed the range is unreadable — check by hand); GHSA-2x6g-h2hg-rq84 (fixed the range is unreadable — check by hand); GHSA-8wjh-59cw-9xh4 (fixed no fixed version named yet); … 2 more
2026-10-28T07:06:19.2818989Z ADVISORY app louislam/uptime-kuma 2.5.7 GHSA-qjxc-h5jf-c7rj (fixed the range is unreadable — check by hand); release:louislam/uptime-kuma@2.5.8 (fixed 2.5.8)
2026-10-28T07:06:19.2819151Z ADVISORY app n8nio/n8n 2.44.7 GHSA-365g-vjw2-grx8 (fixed no fixed version named yet)
2026-10-28T07:06:19.2819317Z ADVISORY app rommapp/romm 5.4.1 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T07:06:19.2819466Z NOT CHECKED doop gitea.dooplex.hu/admin/felhom-act-runner 0.1.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T07:06:19.2819660Z NOT CHECKED doop gitea.dooplex.hu/admin/jarr latest registry gitea.dooplex.hu: no anonymous token route
2026-10-28T07:06:19.2819812Z NOT CHECKED doop gitea.dooplex.hu/admin/recipe-importer latest registry gitea.dooplex.hu: no anonymous token route
2026-10-28T07:06:19.2819968Z NOT CHECKED doop gitea.dooplex.hu/admin/revfulop-calendar 1.6.2 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T07:06:19.2820118Z NOT CHECKED doop gitea.dooplex.hu/admin/sparkyfitness-export 0.3.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T07:06:19.2820296Z NOT CHECKED doop gitea.dooplex.hu/admin/wan-probe 0.1.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T07:06:19.2820494Z NOT CHECKED doop linuxserver/qbittorrent 5.3.0 https://hub.docker.com/v2/repositories/linuxserver/qbittorrent/tags: The read operation timed out
2026-10-28T07:06:19.2820673Z NOT CHECKED doop minio/minio latest Docker registry tags of minio/minio: HTTP 401; manifest minio/minio:latest: HTTP 401
2026-10-28T07:06:19.2820825Z NOT CHECKED doop mongodb/mongodb-community-server 8.0.5-ubuntu2204 https://hub.docker.com/v2/repositories/mongodb/mongodb-community-server/tags: The read operation timed out
2026-10-28T07:06:19.2821003Z BEHIND doop getmeili/meilisearch v1.11.3 newest v1.56.0
2026-10-28T07:06:19.2821158Z BEHIND doop ghcr.io/diced/zipline 4.8.1 newest 4.8.2
2026-10-28T07:06:19.2821311Z BEHIND app getmeili/meilisearch v1.41.0 newest v1.56.0
2026-10-28T07:06:19.2821481Z BEHIND app getmeili/meilisearch v1.36.0 newest v1.56.0
2026-10-28T07:06:19.2821620Z BEHIND app ghcr.io/hargata/lubelogger v1.7.3 newest v1.7.4
2026-10-28T07:06:19.2821898Z BEHIND app ghcr.io/kozea/radicale 3.8.1 newest 3.9.0
2026-10-28T07:06:19.2822053Z BEHIND app gotson/komga 1.28.0 newest 1.29.2
2026-10-28T07:06:19.2822213Z BEHIND app kimai/kimai2 2.67.0 newest 2.71.0
2026-10-28T07:06:19.2822364Z BEHIND app lscr.io/linuxserver/bookstack 26.09.2 newest 26.09.20260929
2026-10-28T07:06:19.2822692Z BEHIND app nextcloud 34.0.4-apache newest 34.0.5-apache
2026-10-28T07:06:19.2822853Z BEHIND app nginx 1.30.5-alpine newest 1.31.8-alpine
2026-10-28T07:06:19.2823023Z BEHIND app qbittorrentofficial/qbittorrent-nox 5.2.4-1 newest 5.3.0-2
2026-10-28T07:06:19.2823180Z GAP buil alpine 3.24.2 newest 3.24.3
2026-10-28T07:06:19.2823332Z GAP buil alpine 3.24.2 newest 3.24.3
2026-10-28T07:06:19.2823490Z GAP doop alpine/k8s 1.37.1
2026-10-28T07:06:19.2823632Z GAP doop arcadiatechnology/crafty-4 4.11.0
2026-10-28T07:06:19.2823805Z GAP doop bhgedigital/envsubst latest
2026-10-28T07:06:19.2823948Z GAP doop busybox 1.38
2026-10-28T07:06:19.2824101Z GAP doop codercom/code-server 4.143.1
2026-10-28T07:06:19.2824262Z GAP buil debian 13.7-slim
2026-10-28T07:06:19.2824412Z GAP buil debian 13.7-slim
2026-10-28T07:06:19.2825231Z GAP doop docker.io/bitnamilegacy/postgresql 17.6.0-debian-12-r3
2026-10-28T07:06:19.2825603Z GAP doop docker.io/library/nextcloud 34.0.5-apache
2026-10-28T07:06:19.2825886Z GAP doop docker.io/valkey/valkey 9.2-alpine
2026-10-28T07:06:19.2826195Z GAP doop filebrowser/filebrowser v2.63.23
2026-10-28T07:06:19.2826496Z GAP doop ghcr.io/cloudnative-pg/postgresql 17.2 newest 17.11
2026-10-28T07:06:19.2826774Z GAP doop ghcr.io/headlamp-k8s/headlamp v0.46.0
2026-10-28T07:06:19.2827069Z GAP doop ghcr.io/immich-app/postgres 16-vectorchord0.3.0
2026-10-28T07:06:19.2827313Z GAP doop ghcr.io/jimmidyson/configmap-reload v0.15.0
2026-10-28T07:06:19.2827553Z GAP doop ghcr.io/onedr0p/exportarr v2.3.0
2026-10-28T07:06:19.2827841Z GAP doop ghcr.io/seerr-team/seerr v3.5.1
2026-10-28T07:06:19.2828093Z GAP doop ghcr.io/seriousm4x/upsnap 5
2026-10-28T07:06:19.2828445Z GAP doop ghcr.io/stakater/reloader v1.4.22 newest v1.4.23
2026-10-28T07:06:19.2828750Z GAP doop ghcr.io/tautulli/tautulli v2.18.2
2026-10-28T07:06:19.2828993Z GAP doop griefed/serverpackcreator 8.1.2
2026-10-28T07:06:19.2829238Z GAP doop gtstef/filebrowser 1.5.8-stable
2026-10-28T07:06:19.2829490Z GAP doop guacamole/guacamole 1.6.0
2026-10-28T07:06:19.2829690Z GAP doop guacamole/guacd 1.6.0
2026-10-28T07:06:19.2829883Z GAP doop index.docker.io/plexinc/pms-docker 1.43.5.11029-6bf8af3f0
2026-10-28T07:06:19.2830113Z GAP doop itzg/mc-backup 2026.10.1 newest 2026.10.2
2026-10-28T07:06:19.2830457Z GAP doop itzg/minecraft-server 2026.10.0-java21 newest 2026.10.1-java17
2026-10-28T07:06:19.2830760Z GAP doop linuxserver/bookstack 26.09.20260929
2026-10-28T07:06:19.2830962Z GAP doop linuxserver/prowlarr version-2.6.5.5623
2026-10-28T07:06:19.2831169Z GAP doop linuxserver/radarr version-6.4.4.10685
2026-10-28T07:06:19.2831453Z GAP doop linuxserver/sonarr version-4.0.20.3014
2026-10-28T07:06:19.2831659Z GAP doop mariadb 11
2026-10-28T07:06:19.2831867Z GAP doop mikefarah/yq 4.54.1
2026-10-28T07:06:19.2832243Z GAP doop msdeluise/plant-it-server 0.10.0
2026-10-28T07:06:19.2832532Z GAP doop mysql 8.4
2026-10-28T07:06:19.2832723Z GAP doop nicolaka/netshoot latest
2026-10-28T07:06:19.2832954Z GAP doop postgis/postgis 16-3.5
2026-10-28T07:06:19.2833142Z GAP doop postgres 15-alpine
2026-10-28T07:06:19.2833332Z GAP doop postgres 16-alpine
2026-10-28T07:06:19.2833852Z GAP doop privatebin/nginx-fpm-alpine 2.0.6 newest 2.1.0
2026-10-28T07:06:19.2834065Z GAP doop prom/alertmanager v0.34.1
2026-10-28T07:06:19.2834260Z GAP doop prom/node-exporter v1.12.1
2026-10-28T07:06:19.2834451Z GAP doop prom/prometheus v3.15.0 newest v3.15.1
2026-10-28T07:06:19.2834709Z GAP doop prometheuscommunity/smartctl-exporter v0.15.0
2026-10-28T07:06:19.2834902Z GAP doop python 3.15-bookworm
2026-10-28T07:06:19.2835088Z GAP doop quay.io/jetstack/version-checker v0.11.0
2026-10-28T07:06:19.2835327Z GAP doop quay.io/prometheus/blackbox-exporter v0.29.1
2026-10-28T07:06:19.2835572Z GAP doop renovate/renovate 44.181.1 newest 44.190.1
2026-10-28T07:06:19.2835776Z GAP doop tailscale/tailscale v1.104.2
2026-10-28T07:06:19.2835973Z GAP app emby/embyserver 4.11.0.4 newest 4.11.0.11
2026-10-28T07:06:19.2836221Z GAP app ghcr.io/immich-app/postgres 16-vectorchord0.4.3-pg
2026-10-28T07:06:19.2836415Z GAP app ghcr.io/karakeep-app/karakeep-chrome 151.0.7922.47-r1
2026-10-28T07:06:19.2836611Z GAP app mariadb 12.3
2026-10-28T07:06:19.2836937Z GAP app mariadb 11.4 newest 11.8
2026-10-28T07:06:19.2837133Z GAP app mariadb 11.8
2026-10-28T07:06:19.2837324Z GAP app mariadb 12.3
2026-10-28T07:06:19.2837511Z GAP app mariadb 11.8
2026-10-28T07:06:19.2837695Z GAP app msdeluise/plant-it 0.10.0
2026-10-28T07:06:19.2837984Z GAP app plexinc/pms-docker 1.43.5.11029-6bf8af3f0
2026-10-28T07:06:19.2838180Z GAP app postgis/postgis 16-3.5-alpine
2026-10-28T07:06:19.2838465Z GAP app postgis/postgis 17-3.5-alpine
2026-10-28T07:06:19.2838650Z GAP app postgres 18-alpine
2026-10-28T07:06:19.2838855Z GAP app postgres 17-alpine
2026-10-28T07:06:19.2839043Z GAP app postgres 18-alpine
2026-10-28T07:06:19.2839235Z GAP app postgres 18-alpine
2026-10-28T07:06:19.2839427Z GAP app postgres 18-alpine
2026-10-28T07:06:19.2839618Z GAP app postgres 18-alpine
2026-10-28T07:06:19.2839819Z GAP app postgres 18-alpine
2026-10-28T07:06:19.2840019Z GAP app postgres 17-alpine
2026-10-28T07:06:19.2840214Z GAP app postgres 16-alpine
2026-10-28T07:06:19.2840408Z GAP app registry.gitlab.com/crafty-controller/crafty-4 4.11.0
2026-10-28T07:06:19.2840601Z FLOATING doop ghcr.io/seanmorley15/adventurelog-backend latest
2026-10-28T07:06:19.2840803Z FLOATING doop ghcr.io/seanmorley15/adventurelog-frontend latest
2026-10-28T07:06:19.2841001Z FLOATING doop nginx 1.31-alpine
2026-10-28T07:06:19.2841215Z FLOATING doop redis 8-alpine
2026-10-28T07:06:19.2841485Z FLOATING doop redis 8.10-alpine
2026-10-28T07:06:19.2841674Z FLOATING app ghcr.io/claperco/claper 2.5
2026-10-28T07:06:19.2841873Z FLOATING app ghcr.io/thomiceli/opengist 1.15
2026-10-28T07:06:19.2842060Z FLOATING app jellyfin/jellyfin 12.4
2026-10-28T07:06:19.2842251Z FLOATING app lscr.io/linuxserver/prowlarr version-2.6.5.5623
2026-10-28T07:06:19.2842446Z FLOATING app lscr.io/linuxserver/sabnzbd version-5.1.3
2026-10-28T07:06:19.2842657Z FLOATING app lscr.io/linuxserver/transmission version-4.1.3-r0
2026-10-28T07:06:19.2842863Z FLOATING app nzbgetcom/nzbget v26.3
2026-10-28T07:06:19.2843053Z FLOATING app redis 7.4-alpine
2026-10-28T07:06:19.2843248Z FLOATING app redis 7-alpine
2026-10-28T07:06:19.2843658Z FLOATING app redis 7-alpine
2026-10-28T07:06:19.2843924Z FLOATING app redis 7-alpine
2026-10-28T07:06:19.2844113Z FLOATING app redis 7-alpine
2026-10-28T07:06:19.2844335Z FLOATING app redis 7-alpine
2026-10-28T07:06:19.2844538Z FLOATING app redis 7-alpine
2026-10-28T07:06:19.2844728Z FLOATING app wger/server 2.7
2026-10-28T07:06:19.2844931Z SELF box gitea.dooplex.hu/admin/felhom-samba 1.2.0
2026-10-28T07:06:19.2845119Z SELF app gitea.dooplex.hu/admin/recipe-importer v0.9.11
2026-10-28T07:06:19.2845312Z CURRENT doop codewithcj/sparkyfitness v1.9.0
2026-10-28T07:06:19.2845490Z CURRENT doop f0rc3/gokapi v2.2.4
2026-10-28T07:06:19.2845684Z CURRENT doop ghcr.io/alam00000/bentopdf 2.8.10
2026-10-28T07:06:19.2845875Z CURRENT doop ghcr.io/thomiceli/opengist 1.15.3
2026-10-28T07:06:19.2846055Z CURRENT doop glanceapp/glance v0.8.7
2026-10-28T07:06:19.2846307Z CURRENT buil golang 1.27.3-trixie
2026-10-28T07:06:19.2846492Z CURRENT buil golang 1.27.3-alpine3.24
2026-10-28T07:06:19.2846699Z CURRENT doop onlyoffice/documentserver 9.4.0
2026-10-28T07:06:19.2846892Z CURRENT buil restic 0.19.1
2026-10-28T07:06:19.2847085Z CURRENT box traefik v3.7.16
2026-10-28T07:06:19.2847284Z CURRENT doop vaultwarden/server 1.37.4
2026-10-28T07:06:19.2847475Z CURRENT app deluan/navidrome 0.64.2
2026-10-28T07:06:19.2847665Z CURRENT app docmost/docmost 0.97.0
2026-10-28T07:06:19.2847859Z CURRENT app ghcr.io/advplyr/audiobookshelf 2.37.2
2026-10-28T07:06:19.2848040Z CURRENT app ghcr.io/alam00000/bentopdf v2.8.10
2026-10-28T07:06:19.2848250Z CURRENT app ghcr.io/cmintey/wishlist v0.69.0
2026-10-28T07:06:19.2848439Z CURRENT app ghcr.io/gramps-project/grampsweb v25.6.0
2026-10-28T07:06:19.2848647Z CURRENT app ghcr.io/grimmory-tools/grimmory v3.5.0
2026-10-28T07:06:19.2848841Z CURRENT app ghcr.io/home-assistant/home-assistant 2026.10.4
2026-10-28T07:06:19.2849037Z CURRENT app ghcr.io/mealie-recipes/mealie v3.29.0
2026-10-28T07:06:19.2849278Z CURRENT app ghcr.io/sysadminsmedia/homebox 0.27.1
2026-10-28T07:06:19.2849468Z CURRENT app lscr.io/linuxserver/code-server 4.143.1
2026-10-28T07:06:19.2849668Z CURRENT app lscr.io/linuxserver/grocy 4.7.1
2026-10-28T07:06:19.2849876Z CURRENT app lscr.io/linuxserver/radarr 6.4.4
2026-10-28T07:06:19.2850077Z CURRENT app lscr.io/linuxserver/sonarr 4.0.20
2026-10-28T07:06:19.2850269Z CURRENT app lukevella/rallly 4.16.3
2026-10-28T07:06:19.2850469Z CURRENT app onlyoffice/documentserver 9.4.0
2026-10-28T07:06:19.2850970Z CURRENT app outlinewiki/outline 1.12.0
2026-10-28T07:06:19.2851212Z CURRENT app privatebin/pdo 2.1.0
2026-10-28T07:06:19.2851512Z CURRENT app vaultwarden/server 1.37.4-alpine
2026-10-28T07:06:19.2851749Z CURRENT app vikunja/vikunja 2.7.1
2026-10-28T07:06:19.2851952Z COUNTS ADVISORY=50 BEHIND=12 CURRENT=31 FLOATING=20 GAP=73 NOT_CHECKED=9 SELF=2
2026-10-28T07:06:19.2852161Z RUNTIME read=5 (272 s) from-cache=180 not-checked=1 zstd-decoder=<module 'zstandard' from '/tmp/felhom-zstandard-ahylbyrh/zstandard/__init__.py'>
2026-10-28T07:06:19.2852475Z REQUESTS api.github.com=68 api.osv.dev=1 auth.docker.io=1 blog.cloudflare.com=1 ghcr.io=174 github.com=62 hub.docker.com=224 raw.githubusercontent.com=1 registry-1.docker.io=1
2026-10-28T07:06:19.3082763Z MAIL (not sent, --no-mail): [Felhom security] the watch could not check runtime
2026-10-28T07:06:19.3203515Z STATE written: /tmp/state-dry.json (323 known advisories)
2026-10-28T07:06:19.3776008Z Cleaning up container for job watch
2026-10-28T07:06:19.9594784Z 🏁 Job succeeded
@@ -0,0 +1,271 @@
2026-10-28T11:47:02.4712178Z felhom-gates-runner-2(version:v0.6.1) received task 2482 of job watch, be triggered by event: workflow_dispatch
2026-10-28T11:47:02.4727581Z workflow prepared
2026-10-28T11:47:02.4741272Z evaluating expression 'success()'
2026-10-28T11:47:02.4742773Z expression 'success()' evaluated to 'true'
2026-10-28T11:47:02.4783413Z evaluating expression ''
2026-10-28T11:47:02.4784409Z expression '' evaluated to 'true'
2026-10-28T11:47:02.4784720Z ⭐ Run Main Fetch main (latest, for the memory) and the two sibling repos
2026-10-28T11:47:02.4790937Z Wrote command \n\necho "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"\nbase=http://gitea.gitea-system.svc.cluster.local:3000/admin\ngit init -q . && git remote add origin $base/felhom.eu.git\ngit fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD\necho "felhom.eu main at $(git rev-parse --short=12 HEAD)"\nfor r in felhom-controller app-catalog-felhom.eu; do\n git init -q ../$r && git -C ../$r remote add origin $base/$r.git\n git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD\n echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"\ndone\n\n\n to 'workflow/0.sh'
2026-10-28T11:47:02.4793153Z ::group::Run echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
2026-10-28T11:47:02.4793593Z echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
2026-10-28T11:47:02.4794051Z base=http://gitea.gitea-system.svc.cluster.local:3000/admin
2026-10-28T11:47:02.4794292Z git init -q . && git remote add origin $base/felhom.eu.git
2026-10-28T11:47:02.4794511Z git fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD
2026-10-28T11:47:02.4794786Z echo "felhom.eu main at $(git rev-parse --short=12 HEAD)"
2026-10-28T11:47:02.4795009Z for r in felhom-controller app-catalog-felhom.eu; do
2026-10-28T11:47:02.4795221Z git init -q ../$r && git -C ../$r remote add origin $base/$r.git
2026-10-28T11:47:02.4795448Z git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD
2026-10-28T11:47:02.4795888Z echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"
2026-10-28T11:47:02.4796114Z done
2026-10-28T11:47:02.4796293Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T11:47:02.4796580Z ::endgroup::
2026-10-28T11:47:56.5865886Z felhom.eu main at fe677bae9415
2026-10-28T11:47:59.8988977Z felhom-controller at ed3927f03a52
2026-10-28T11:48:01.5259435Z app-catalog-felhom.eu at 0829994440ca
2026-10-28T11:48:01.5277395Z ::group::Run set -u
2026-10-28T11:48:01.5277618Z set -u
2026-10-28T11:48:01.5277735Z mkdir -p documentation/security-watch
2026-10-28T11:48:01.5277846Z mode="${MODE:-run}"
2026-10-28T11:48:01.5278088Z [ "${GITHUB_EVENT_NAME:-}" = "schedule" ] && mode=run
2026-10-28T11:48:01.5278204Z echo "mode: $mode"
2026-10-28T11:48:01.5278306Z case "$mode" in
2026-10-28T11:48:01.5278415Z test-mail) python3 scripts/security_watch.py --test-mail; exit $? ;;
2026-10-28T11:48:01.5278539Z dry) extra="--no-mail" ; state=/tmp/state-dry.json
2026-10-28T11:48:01.5278661Z cp documentation/security-watch/state.json "$state" 2>/dev/null || true ;;
2026-10-28T11:48:01.5278798Z seed) extra="--seed" ; state=documentation/security-watch/state.json ;;
2026-10-28T11:48:01.5278945Z run) extra="" ; state=documentation/security-watch/state.json ;;
2026-10-28T11:48:01.5279081Z *) echo "unknown mode $mode"; exit 2 ;;
2026-10-28T11:48:01.5279194Z esac
2026-10-28T11:48:01.5279291Z python3 scripts/security_watch.py --state="$state" --catalog=../app-catalog-felhom.eu \
2026-10-28T11:48:01.5279432Z --controller=../felhom-controller --json=/tmp/watch-results.json $extra
2026-10-28T11:48:01.5279561Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T11:48:01.5279705Z env:
2026-10-28T11:48:01.5279832Z RESEND_API_KEY: ***
2026-10-28T11:48:01.5279958Z GH_ADVISORY_TOKEN: ***
2026-10-28T11:48:01.5280076Z MODE: dry
2026-10-28T11:48:01.5280181Z FELHOM_WHEEL_FETCH: 1
2026-10-28T11:48:01.5280300Z ::endgroup::
2026-10-28T11:48:01.5315547Z mode: dry
2026-10-28T11:48:01.8669447Z /root/.cache/act/f1c467c06942a567/hostexecutor/scripts/security_watch.py:905: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
2026-10-28T11:48:01.8670299Z today = datetime.date.fromisoformat(opts["today"]) if "today" in opts else datetime.datetime.utcnow().date()
2026-10-28T11:48:01.9215140Z security watch 2026-10-28: 197 pins (11 box/build, 97 app, 89 DooPlex); GitHub key PRESENT — every repo's advisories tonight
2026-10-28T11:48:40.4619259Z RUNTIME-READ golang:1.27.3-trixie 19 s ok
2026-10-28T11:50:57.5410366Z RUNTIME-READ ghost:6.73.0-alpine 82 s ok
2026-10-28T11:51:12.1336631Z RUNTIME-READ ghcr.io/immich-app/immich-machine-learning:v3.3.5 69 s ok
2026-10-28T11:51:28.9427653Z RUNTIME-READ freikin/dawarich:1.19.0 123 s ok
2026-10-28T11:51:33.4310838Z RUNTIME-READ ghcr.io/home-assistant/home-assistant:2026.10.4 112 s ok
2026-10-28T11:51:44.1628720Z RUNTIME-READ ghcr.io/immich-app/immich-server:v3.3.5 107 s ok
2026-10-28T11:51:48.7752810Z RUNTIME-READ ghcr.io/karakeep-app/karakeep:0.34.1 117 s ok
2026-10-28T11:51:53.3128744Z RUNTIME-READ ghcr.io/alexta69/metube:2026.10.27 37 s ok
2026-10-28T11:52:26.9311967Z RUNTIME-READ ghcr.io/papra-hq/papra:26.7.1-rootless 44 s ok
2026-10-28T11:52:35.4240046Z RUNTIME-READ rommapp/romm:5.4.1 29 s ok
2026-10-28T11:52:52.6459707Z RUNTIME-READ ghcr.io/tandoorrecipes/recipes:2.7.2 47 s ok
2026-10-28T11:53:08.2131671Z RUNTIME-READ ghcr.io/diced/zipline:4.8.2 41 s ok
2026-10-28T11:53:22.4556889Z RUNTIME-READ docker.io/library/nextcloud:34.0.5-apache 42 s ok
2026-10-28T11:53:59.4333189Z RUNTIME-READ python:3.15-bookworm 21 s ok
2026-10-28T11:53:59.5401475Z ADVISORY doop actualbudget/actual-server 26.10.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T11:53:59.5402195Z ADVISORY doop advplyr/audiobookshelf 2.37.1 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T11:53:59.5402380Z ADVISORY box cloudflare/cloudflared 2026.10.4 feed:cloudflare-blog:01M5DK5J81T0VC8YTBR2FKD8A3 (fixed read the notice); vulnnotes:cloudflared@2026.10.5:VULN-183456 (fixed 2026.10.5)
2026-10-28T11:53:59.5402575Z ADVISORY doop codewithcj/sparkyfitness_server v1.9.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T11:53:59.5402755Z ADVISORY doop crocodilestick/calibre-web-automated dev CVE-2026-111497 (fixed 1.2.1)
2026-10-28T11:53:59.5402938Z ADVISORY doop docker.io/calcom/cal.com v6.2.0 CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T11:53:59.5403115Z ADVISORY doop flomp/wanderer-db v0.21.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 1 more
2026-10-28T11:53:59.5403474Z ADVISORY doop flomp/wanderer-web v0.21.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 2 more
2026-10-28T11:53:59.5403659Z ADVISORY doop ghcr.io/gethomepage/homepage v1.13.2 GHSA-669x-4pg4-w24r (fixed 2.2.0); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T11:53:59.5403825Z ADVISORY doop ghcr.io/immich-app/immich-machine-learning v2.7.5 GHSA-q89f-h332-8q2h (fixed v3.2.4); GHSA-h5w4-vjv4-9r5q (fixed a version after 3.1.0 (the notice names none)); GHSA-g4w3-c888-cr93 (fixed v3.2.0); GHSA-72rm-x7xr-v679 (fixed v3.3.0); … 7 more
2026-10-28T11:53:59.5404003Z ADVISORY doop ghcr.io/immich-app/immich-server v2.7.5 GHSA-q89f-h332-8q2h (fixed v3.2.4); GHSA-h5w4-vjv4-9r5q (fixed a version after 3.1.0 (the notice names none)); GHSA-g4w3-c888-cr93 (fixed v3.2.0); GHSA-72rm-x7xr-v679 (fixed v3.3.0); … 8 more
2026-10-28T11:53:59.5404194Z ADVISORY doop ghcr.io/lukegus/termix release-2.9.2 CVE-2026-111497 (fixed 26.12.1)
2026-10-28T11:53:59.5404329Z ADVISORY doop ghcr.io/paperless-ngx/paperless-ngx 3.3.4 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T11:53:59.5404487Z ADVISORY doop gitea/gitea 1.26.2 GHSA-wx44-9m3m-rjqx (fixed 28.2.0); GHSA-4jmf-h2cm-hg7w (fixed 28.2.0); GHSA-8j56-f865-gqq2 (fixed 28.2.0); GHSA-fxq4-gr55-7x5g (fixed 28.2.0); … 127 more
2026-10-28T11:53:59.5404679Z ADVISORY doop grafana/grafana 13.2.4 GHSA-8xmm-x63g-f6xv (fixed no fixed version named yet); GHSA-4724-7jwc-3fpw (fixed the range is unreadable — check by hand); GHSA-2x6g-h2hg-rq84 (fixed the range is unreadable — check by hand); GHSA-8wjh-59cw-9xh4 (fixed no fixed version named yet); … 2 more
2026-10-28T11:53:59.5404914Z ADVISORY box gtstef/filebrowser 1.5.8-stable GHSA-gfgm-886h-6r47 (fixed 2.0.2-stable, 2.1.4-beta); GHSA-wxj5-g3qp-g732 (fixed 2.0.2-stable, 2.1.3-beta); GHSA-3j46-5w28-f8p2 (fixed 2.1.0-stable, 2.1.3-beta); GHSA-4vrc-935w-xxq2 (fixed 2.1.0-stable, 2.1.3-beta); … 31 more
2026-10-28T11:53:59.5405103Z ADVISORY doop louislam/uptime-kuma 2.5.6 GHSA-qjxc-h5jf-c7rj (fixed the range is unreadable — check by hand); release:louislam/uptime-kuma@2.5.8 (fixed 2.5.8); release:louislam/uptime-kuma@2.5.7 (fixed 2.5.7); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T11:53:59.5406272Z ADVISORY doop outlinewiki/outline 1.11.0 GHSA-x4w3-9p9j-cprh (fixed 1.12.0); GHSA-rq53-m97j-f2pg (fixed 1.12.0); GHSA-h6ff-rw9x-5mq2 (fixed 1.12.0); GHSA-rvj7-2gww-6xfq (fixed 1.12.0); … 3 more
2026-10-28T11:53:59.5406483Z ADVISORY doop redis 8.10.2 GHSA-c8h9-259x-jff4 (fixed the range is unreadable — check by hand); GHSA-8ghh-qpmp-7826 (fixed no fixed version named yet); GHSA-93m2-935m-8rj3 (fixed no fixed version named yet); GHSA-m8fj-85cg-7vhp (fixed the range is unreadable — check by hand); … 8 more
2026-10-28T11:53:59.5406678Z ADVISORY doop rommapp/romm 5.4.0 release:rommapp/romm@5.4.1 (fixed 5.4.1); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T11:53:59.5406811Z ADVISORY doop vabene1111/recipes 2.6.15 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T11:53:59.5406943Z ADVISORY app actualbudget/actual-server 26.9.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T11:53:59.5407072Z ADVISORY app calcom/cal.com v6.2.0 GHSA-p3f6-52gv-cj7m (fixed the range is unreadable — check by hand); GHSA-cpf2-q635-xrwx (fixed the range is unreadable — check by hand); CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T11:53:59.5407282Z ADVISORY app codewithcj/sparkyfitness v0.17.3 GHSA-v883-jx9h-qf29 (fixed a version after 1.7.2 (the notice names none)); GHSA-cmmf-53wf-r5gv (fixed a version after 1.6.5 (the notice names none)); GHSA-p8cf-g8rv-gvrq (fixed a version after 1.6.5 (the notice names none))
2026-10-28T11:53:59.5407455Z ADVISORY app codewithcj/sparkyfitness_server v0.17.3 GHSA-v883-jx9h-qf29 (fixed a version after 1.7.2 (the notice names none)); GHSA-cmmf-53wf-r5gv (fixed a version after 1.6.5 (the notice names none)); GHSA-p8cf-g8rv-gvrq (fixed a version after 1.6.5 (the notice names none)); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T11:53:59.5407635Z ADVISORY app crocodilestick/calibre-web-automated v4.0.8 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T11:53:59.5407767Z ADVISORY app f0rc3/gokapi v1.9.6 GHSA-45vh-rpc8-hxpp (fixed 2.2.4); GHSA-qwc6-vc2v-2ggj (fixed 2.2.4); GHSA-j6jp-78w8-34x6 (fixed 2.2.4); GHSA-m2hx-wjxc-9fp4 (fixed 2.2.3); … 6 more
2026-10-28T11:53:59.5407937Z ADVISORY app fallenbagel/jellyseerr 2.7.3 GHSA-8j73-j6rc-q8xh (fixed 3.5.0); GHSA-xc6j-6p6h-p799 (fixed 3.5.0); GHSA-mc6w-69r3-62h8 (fixed 3.4.0); GHSA-gx3h-3jg5-q65f (fixed 3.1.0); … 3 more
2026-10-28T11:53:59.5408110Z ADVISORY app flomp/wanderer-db v0.20.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 7 more
2026-10-28T11:53:59.5408268Z ADVISORY app flomp/wanderer-web v0.20.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 8 more
2026-10-28T11:53:59.5408424Z ADVISORY app ghcr.io/gethomepage/homepage v1.13.2 GHSA-669x-4pg4-w24r (fixed 2.2.0); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T11:53:59.5408574Z ADVISORY app ghcr.io/immich-app/immich-machine-learning v3.3.5 GHSA-8244-8vpr-vp9c (fixed the range is unreadable — check by hand)
2026-10-28T11:53:59.5408739Z ADVISORY app ghcr.io/immich-app/immich-server v3.3.5 GHSA-8244-8vpr-vp9c (fixed the range is unreadable — check by hand)
2026-10-28T11:53:59.5408953Z ADVISORY app ghcr.io/karakeep-app/karakeep 0.34.1 GHSA-pp34-2c9r-mchw (fixed no fixed version named yet)
2026-10-28T11:53:59.5409117Z ADVISORY app ghcr.io/lukegus/termix 2.8.0 GHSA-6gr3-r7jx-wfmh (fixed >= 26.10.0); GHSA-frx8-qqgg-7j7g (fixed >= 26.10.0); GHSA-3q2m-5r5p-w45r (fixed >= 26.10.0); GHSA-rgf3-2q88-q4wp (fixed >= 26.10.0); … 9 more
2026-10-28T11:53:59.5410068Z ADVISORY app ghcr.io/paperless-ngx/paperless-ngx 2.20.15 GHSA-c8f3-pqr2-rr24 (fixed 3.3.2); GHSA-2jhj-xqrq-rmrq (fixed 3.1.2); CVE-2026-111497 (fixed 1.1.1)
2026-10-28T11:53:59.5411038Z ADVISORY app ghcr.io/tandoorrecipes/recipes 2.7.2 GHSA-c7mc-c9jr-38hf (fixed the range is unreadable — check by hand); GHSA-cqj3-64qw-4w52 (fixed the range is unreadable — check by hand)
2026-10-28T11:53:59.5411537Z ADVISORY app gitea/gitea 1.27.3 GHSA-wx44-9m3m-rjqx (fixed 28.2.0); GHSA-4jmf-h2cm-hg7w (fixed 28.2.0); GHSA-8j56-f865-gqq2 (fixed 28.2.0); GHSA-fxq4-gr55-7x5g (fixed 28.2.0); … 37 more
2026-10-28T11:53:59.5411889Z ADVISORY app glanceapp/glance v0.8.5 GHSA-r225-jhr6-68cc (fixed >= 0.8.7)
2026-10-28T11:53:59.5412063Z ADVISORY app grafana/grafana 13.2.4 GHSA-8xmm-x63g-f6xv (fixed no fixed version named yet); GHSA-4724-7jwc-3fpw (fixed the range is unreadable — check by hand); GHSA-2x6g-h2hg-rq84 (fixed the range is unreadable — check by hand); GHSA-8wjh-59cw-9xh4 (fixed no fixed version named yet); … 2 more
2026-10-28T11:53:59.5412282Z ADVISORY app louislam/uptime-kuma 2.5.7 GHSA-qjxc-h5jf-c7rj (fixed the range is unreadable — check by hand); release:louislam/uptime-kuma@2.5.8 (fixed 2.5.8)
2026-10-28T11:53:59.5412449Z ADVISORY app n8nio/n8n 2.44.7 GHSA-2x68-96jw-5r6c (fixed >= 3.0.1); GHSA-9p7v-45m2-wxgj (fixed >= 3.0.1); GHSA-mx4r-96jx-v278 (fixed >= 3.0.1); GHSA-4v22-g448-h4rg (fixed >= 2.45.5, >= 2.46.1, >= 3.0.1); … 9 more
2026-10-28T11:53:59.5412609Z ADVISORY app rommapp/romm 5.4.1 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T11:53:59.5412768Z NOT CHECKED doop gitea.dooplex.hu/admin/felhom-act-runner 0.1.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T11:53:59.5412922Z NOT CHECKED doop gitea.dooplex.hu/admin/jarr latest registry gitea.dooplex.hu: no anonymous token route
2026-10-28T11:53:59.5413054Z NOT CHECKED doop gitea.dooplex.hu/admin/recipe-importer latest registry gitea.dooplex.hu: no anonymous token route
2026-10-28T11:53:59.5413180Z NOT CHECKED doop gitea.dooplex.hu/admin/revfulop-calendar 1.6.2 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T11:53:59.5413313Z NOT CHECKED doop gitea.dooplex.hu/admin/sparkyfitness-export 0.3.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T11:53:59.5413556Z NOT CHECKED doop gitea.dooplex.hu/admin/wan-probe 0.1.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T11:53:59.5413785Z NOT CHECKED doop minio/minio latest Docker registry tags of minio/minio: HTTP 401; manifest minio/minio:latest: HTTP 401
2026-10-28T11:53:59.5413926Z BEHIND doop getmeili/meilisearch v1.11.3 newest v1.56.0
2026-10-28T11:53:59.5414047Z BEHIND doop ghcr.io/diced/zipline 4.8.1 newest 4.8.2
2026-10-28T11:53:59.5414187Z BEHIND app getmeili/meilisearch v1.41.0 newest v1.56.0
2026-10-28T11:53:59.5414307Z BEHIND app getmeili/meilisearch v1.36.0 newest v1.56.0
2026-10-28T11:53:59.5414445Z BEHIND app ghcr.io/hargata/lubelogger v1.7.3 newest v1.7.4
2026-10-28T11:53:59.5414564Z BEHIND app ghcr.io/kozea/radicale 3.8.1 newest 3.9.0
2026-10-28T11:53:59.5414679Z BEHIND app gotson/komga 1.28.0 newest 1.29.2
2026-10-28T11:53:59.5414794Z BEHIND app kimai/kimai2 2.67.0 newest 2.71.0
2026-10-28T11:53:59.5414929Z BEHIND app lscr.io/linuxserver/bookstack 26.09.2 newest 26.09.20260929
2026-10-28T11:53:59.5415078Z BEHIND app nextcloud 34.0.4-apache newest 34.0.5-apache
2026-10-28T11:53:59.5415199Z BEHIND app nginx 1.30.5-alpine newest 1.31.8-alpine
2026-10-28T11:53:59.5415329Z BEHIND app qbittorrentofficial/qbittorrent-nox 5.2.4-1 newest 5.3.0-2
2026-10-28T11:53:59.5415452Z GAP buil alpine 3.24.2 newest 3.24.3
2026-10-28T11:53:59.5415593Z GAP buil alpine 3.24.2 newest 3.24.3
2026-10-28T11:53:59.5415728Z GAP doop alpine/k8s 1.37.1
2026-10-28T11:53:59.5415849Z GAP doop arcadiatechnology/crafty-4 4.11.0
2026-10-28T11:53:59.5415970Z GAP doop bhgedigital/envsubst latest
2026-10-28T11:53:59.5416086Z GAP doop busybox 1.38
2026-10-28T11:53:59.5416212Z GAP doop codercom/code-server 4.143.1
2026-10-28T11:53:59.5416346Z GAP buil debian 13.7-slim
2026-10-28T11:53:59.5416499Z GAP buil debian 13.7-slim
2026-10-28T11:53:59.5416632Z GAP doop docker.io/bitnamilegacy/postgresql 17.6.0-debian-12-r3
2026-10-28T11:53:59.5416777Z GAP doop docker.io/library/nextcloud 34.0.5-apache
2026-10-28T11:53:59.5416923Z GAP doop docker.io/valkey/valkey 9.2-alpine
2026-10-28T11:53:59.5417043Z GAP doop filebrowser/filebrowser v2.63.23
2026-10-28T11:53:59.5417185Z GAP doop ghcr.io/cloudnative-pg/postgresql 17.2 newest 17.11
2026-10-28T11:53:59.5417367Z GAP doop ghcr.io/headlamp-k8s/headlamp v0.46.0
2026-10-28T11:53:59.5417502Z GAP doop ghcr.io/immich-app/postgres 16-vectorchord0.3.0
2026-10-28T11:53:59.5417649Z GAP doop ghcr.io/jimmidyson/configmap-reload v0.15.0
2026-10-28T11:53:59.5417769Z GAP doop ghcr.io/onedr0p/exportarr v2.3.0
2026-10-28T11:53:59.5417888Z GAP doop ghcr.io/seerr-team/seerr v3.5.1
2026-10-28T11:53:59.5418006Z GAP doop ghcr.io/seriousm4x/upsnap 5
2026-10-28T11:53:59.5418136Z GAP doop ghcr.io/stakater/reloader v1.4.22 newest v1.4.23
2026-10-28T11:53:59.5418297Z GAP doop ghcr.io/tautulli/tautulli v2.18.2
2026-10-28T11:53:59.5418444Z GAP doop griefed/serverpackcreator 8.1.2
2026-10-28T11:53:59.5418588Z GAP doop gtstef/filebrowser 1.5.8-stable
2026-10-28T11:53:59.5418717Z GAP doop guacamole/guacamole 1.6.0
2026-10-28T11:53:59.5418857Z GAP doop guacamole/guacd 1.6.0
2026-10-28T11:53:59.5418985Z GAP doop index.docker.io/plexinc/pms-docker 1.43.5.11029-6bf8af3f0
2026-10-28T11:53:59.5419147Z GAP doop itzg/mc-backup 2026.10.1 newest 2026.10.2
2026-10-28T11:53:59.5419594Z GAP doop itzg/minecraft-server 2026.10.0-java21 newest 2026.10.1-java17
2026-10-28T11:53:59.5419808Z GAP doop linuxserver/bookstack 26.09.20260929
2026-10-28T11:53:59.5419982Z GAP doop linuxserver/prowlarr version-2.6.5.5623
2026-10-28T11:53:59.5420145Z GAP doop linuxserver/qbittorrent 5.3.0
2026-10-28T11:53:59.5420268Z GAP doop linuxserver/radarr version-6.4.4.10685
2026-10-28T11:53:59.5420386Z GAP doop linuxserver/sonarr version-4.0.20.3014
2026-10-28T11:53:59.5420500Z GAP doop mariadb 11
2026-10-28T11:53:59.5420700Z GAP doop mikefarah/yq 4.54.1
2026-10-28T11:53:59.5420851Z GAP doop mongodb/mongodb-community-server 8.0.5-ubuntu2204 newest 8.3.13-ubuntu2204
2026-10-28T11:53:59.5420988Z GAP doop msdeluise/plant-it-server 0.10.0
2026-10-28T11:53:59.5421111Z GAP doop mysql 8.4
2026-10-28T11:53:59.5421256Z GAP doop nicolaka/netshoot latest
2026-10-28T11:53:59.5421371Z GAP doop postgis/postgis 16-3.5
2026-10-28T11:53:59.5421562Z GAP doop postgres 15-alpine
2026-10-28T11:53:59.5421889Z GAP doop postgres 16-alpine
2026-10-28T11:53:59.5422012Z GAP doop privatebin/nginx-fpm-alpine 2.0.6 newest 2.1.0
2026-10-28T11:53:59.5422132Z GAP doop prom/alertmanager v0.34.1
2026-10-28T11:53:59.5422246Z GAP doop prom/node-exporter v1.12.1
2026-10-28T11:53:59.5422393Z GAP doop prom/prometheus v3.15.0 newest v3.15.1
2026-10-28T11:53:59.5422517Z GAP doop prometheuscommunity/smartctl-exporter v0.15.0
2026-10-28T11:53:59.5422636Z GAP doop python 3.15-bookworm
2026-10-28T11:53:59.5422785Z GAP doop quay.io/jetstack/version-checker v0.11.0
2026-10-28T11:53:59.5422901Z GAP doop quay.io/prometheus/blackbox-exporter v0.29.1
2026-10-28T11:53:59.5423021Z GAP doop renovate/renovate 44.181.1 newest 44.190.2
2026-10-28T11:53:59.5423136Z GAP doop tailscale/tailscale v1.104.2
2026-10-28T11:53:59.5423277Z GAP app emby/embyserver 4.11.0.4 newest 4.11.0.11
2026-10-28T11:53:59.5423391Z GAP app ghcr.io/immich-app/postgres 16-vectorchord0.4.3-pg
2026-10-28T11:53:59.5423509Z GAP app ghcr.io/karakeep-app/karakeep-chrome 151.0.7922.47-r1
2026-10-28T11:53:59.5423653Z GAP app mariadb 12.3
2026-10-28T11:53:59.5423765Z GAP app mariadb 11.4 newest 11.8
2026-10-28T11:53:59.5423942Z GAP app mariadb 11.8
2026-10-28T11:53:59.5424110Z GAP app mariadb 12.3
2026-10-28T11:53:59.5424246Z GAP app mariadb 11.8
2026-10-28T11:53:59.5424354Z GAP app msdeluise/plant-it 0.10.0
2026-10-28T11:53:59.5424468Z GAP app plexinc/pms-docker 1.43.5.11029-6bf8af3f0
2026-10-28T11:53:59.5424658Z GAP app postgis/postgis 16-3.5-alpine
2026-10-28T11:53:59.5424868Z GAP app postgis/postgis 17-3.5-alpine
2026-10-28T11:53:59.5424980Z GAP app postgres 18-alpine
2026-10-28T11:53:59.5425088Z GAP app postgres 17-alpine
2026-10-28T11:53:59.5425406Z GAP app postgres 18-alpine
2026-10-28T11:53:59.5425533Z GAP app postgres 18-alpine
2026-10-28T11:53:59.5425641Z GAP app postgres 18-alpine
2026-10-28T11:53:59.5425794Z GAP app postgres 18-alpine
2026-10-28T11:53:59.5425968Z GAP app postgres 18-alpine
2026-10-28T11:53:59.5426086Z GAP app postgres 17-alpine
2026-10-28T11:53:59.5426196Z GAP app postgres 16-alpine
2026-10-28T11:53:59.5426377Z GAP app registry.gitlab.com/crafty-controller/crafty-4 4.11.0
2026-10-28T11:53:59.5426501Z FLOATING doop ghcr.io/seanmorley15/adventurelog-backend latest
2026-10-28T11:53:59.5426617Z FLOATING doop ghcr.io/seanmorley15/adventurelog-frontend latest
2026-10-28T11:53:59.5426769Z FLOATING doop nginx 1.31-alpine
2026-10-28T11:53:59.5426941Z FLOATING doop redis 8-alpine
2026-10-28T11:53:59.5427058Z FLOATING doop redis 8.10-alpine
2026-10-28T11:53:59.5427167Z FLOATING app ghcr.io/claperco/claper 2.5
2026-10-28T11:53:59.5427319Z FLOATING app ghcr.io/thomiceli/opengist 1.15
2026-10-28T11:53:59.5427427Z FLOATING app jellyfin/jellyfin 12.4
2026-10-28T11:53:59.5427594Z FLOATING app lscr.io/linuxserver/prowlarr version-2.6.5.5623
2026-10-28T11:53:59.5427755Z FLOATING app lscr.io/linuxserver/sabnzbd version-5.1.3
2026-10-28T11:53:59.5427870Z FLOATING app lscr.io/linuxserver/transmission version-4.1.3-r0
2026-10-28T11:53:59.5427979Z FLOATING app nzbgetcom/nzbget v26.3
2026-10-28T11:53:59.5428091Z FLOATING app redis 7.4-alpine
2026-10-28T11:53:59.5428225Z FLOATING app redis 7-alpine
2026-10-28T11:53:59.5428338Z FLOATING app redis 7-alpine
2026-10-28T11:53:59.5428442Z FLOATING app redis 7-alpine
2026-10-28T11:53:59.5428584Z FLOATING app redis 7-alpine
2026-10-28T11:53:59.5428690Z FLOATING app redis 7-alpine
2026-10-28T11:53:59.5428799Z FLOATING app redis 7-alpine
2026-10-28T11:53:59.5428904Z FLOATING app wger/server 2.7
2026-10-28T11:53:59.5429101Z SELF box gitea.dooplex.hu/admin/felhom-samba 1.2.0
2026-10-28T11:53:59.5429438Z SELF app gitea.dooplex.hu/admin/recipe-importer v0.9.11
2026-10-28T11:53:59.5429556Z CURRENT doop codewithcj/sparkyfitness v1.9.0
2026-10-28T11:53:59.5429700Z CURRENT doop f0rc3/gokapi v2.2.4
2026-10-28T11:53:59.5429815Z CURRENT doop ghcr.io/alam00000/bentopdf 2.8.10
2026-10-28T11:53:59.5429929Z CURRENT doop ghcr.io/thomiceli/opengist 1.15.3
2026-10-28T11:53:59.5430043Z CURRENT doop glanceapp/glance v0.8.7
2026-10-28T11:53:59.5430182Z CURRENT buil golang 1.27.3-trixie
2026-10-28T11:53:59.5430292Z CURRENT buil golang 1.27.3-alpine3.24
2026-10-28T11:53:59.5430397Z CURRENT doop onlyoffice/documentserver 9.4.0
2026-10-28T11:53:59.5430545Z CURRENT buil restic 0.19.1
2026-10-28T11:53:59.5430657Z CURRENT box traefik v3.7.16
2026-10-28T11:53:59.5430828Z CURRENT doop vaultwarden/server 1.37.4
2026-10-28T11:53:59.5430947Z CURRENT app deluan/navidrome 0.64.2
2026-10-28T11:53:59.5431083Z CURRENT app docmost/docmost 0.97.0
2026-10-28T11:53:59.5431193Z CURRENT app freikin/dawarich 1.19.0
2026-10-28T11:53:59.5431306Z CURRENT app ghcr.io/advplyr/audiobookshelf 2.37.2
2026-10-28T11:53:59.5431445Z CURRENT app ghcr.io/alam00000/bentopdf v2.8.10
2026-10-28T11:53:59.5431657Z CURRENT app ghcr.io/alexta69/metube 2026.10.27
2026-10-28T11:53:59.5431768Z CURRENT app ghcr.io/cmintey/wishlist v0.69.0
2026-10-28T11:53:59.5431878Z CURRENT app ghcr.io/diced/zipline 4.8.2
2026-10-28T11:53:59.5432012Z CURRENT app ghcr.io/gramps-project/grampsweb v25.6.0
2026-10-28T11:53:59.5432127Z CURRENT app ghcr.io/grimmory-tools/grimmory v3.5.0
2026-10-28T11:53:59.5432246Z CURRENT app ghcr.io/home-assistant/home-assistant 2026.10.4
2026-10-28T11:53:59.5432448Z CURRENT app ghcr.io/mealie-recipes/mealie v3.29.0
2026-10-28T11:53:59.5432622Z CURRENT app ghcr.io/papra-hq/papra 26.7.1-rootless
2026-10-28T11:53:59.5432734Z CURRENT app ghcr.io/seanmorley15/adventurelog-backend v0.13.1
2026-10-28T11:53:59.5432849Z CURRENT app ghcr.io/seanmorley15/adventurelog-frontend v0.13.1
2026-10-28T11:53:59.5432986Z CURRENT app ghcr.io/sysadminsmedia/homebox 0.27.1
2026-10-28T11:53:59.5433094Z CURRENT app ghost 6.73.0-alpine
2026-10-28T11:53:59.5433201Z CURRENT app lscr.io/linuxserver/code-server 4.143.1
2026-10-28T11:53:59.5433382Z CURRENT app lscr.io/linuxserver/grocy 4.7.1
2026-10-28T11:53:59.5433494Z CURRENT app lscr.io/linuxserver/radarr 6.4.4
2026-10-28T11:53:59.5433600Z CURRENT app lscr.io/linuxserver/sonarr 4.0.20
2026-10-28T11:53:59.5433712Z CURRENT app lukevella/rallly 4.16.3
2026-10-28T11:53:59.5433845Z CURRENT app onlyoffice/documentserver 9.4.0
2026-10-28T11:53:59.5434024Z CURRENT app outlinewiki/outline 1.12.0
2026-10-28T11:53:59.5434134Z CURRENT app privatebin/pdo 2.1.0
2026-10-28T11:53:59.5434276Z CURRENT app vaultwarden/server 1.37.4-alpine
2026-10-28T11:53:59.5434505Z CURRENT app vikunja/vikunja 2.7.1
2026-10-28T11:53:59.5434622Z COUNTS ADVISORY=43 BEHIND=12 CURRENT=38 FLOATING=20 GAP=75 NOT_CHECKED=7 SELF=2
2026-10-28T11:53:59.5434737Z RUNTIME read=14 (890 s) from-cache=171 not-checked=0 zstd-decoder=zstandard 0.25.0 (pinned wheel, sha256 checked)
2026-10-28T11:53:59.5434899Z TAGS fetched=119 from-cache=0 retried-429=0 (cache /root/.cache/felhom-watch-tags.json)
2026-10-28T11:53:59.5435025Z REQUESTS api.github.com=69 api.osv.dev=1 auth.docker.io=1 blog.cloudflare.com=1 ghcr.io=174 github.com=62 hub.docker.com=211 raw.githubusercontent.com=1 registry-1.docker.io=1
2026-10-28T11:53:59.5638426Z MAIL (not sent, --no-mail): [Felhom security] n8n — 12 new advisories
2026-10-28T11:53:59.5638978Z MAIL (not sent, --no-mail): [Felhom security] the watch could not check runtime
2026-10-28T11:53:59.5729218Z STATE written: /tmp/state-dry.json (382 known advisories)
2026-10-28T11:53:59.6741799Z Cleaning up container for job watch
2026-10-28T11:54:00.2357155Z 🏁 Job succeeded
@@ -0,0 +1,271 @@
2026-10-28T12:00:46.5409701Z felhom-gates-runner(version:v0.6.1) received task 2483 of job watch, be triggered by event: workflow_dispatch
2026-10-28T12:00:46.5422394Z workflow prepared
2026-10-28T12:00:46.5423739Z evaluating expression 'success()'
2026-10-28T12:00:46.5424693Z expression 'success()' evaluated to 'true'
2026-10-28T12:00:46.5431767Z evaluating expression ''
2026-10-28T12:00:46.5432232Z expression '' evaluated to 'true'
2026-10-28T12:00:46.5432477Z ⭐ Run Main Fetch main (latest, for the memory) and the two sibling repos
2026-10-28T12:00:46.5436130Z Wrote command \n\necho "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"\nbase=http://gitea.gitea-system.svc.cluster.local:3000/admin\ngit init -q . && git remote add origin $base/felhom.eu.git\ngit fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD\necho "felhom.eu main at $(git rev-parse --short=12 HEAD)"\nfor r in felhom-controller app-catalog-felhom.eu; do\n git init -q ../$r && git -C ../$r remote add origin $base/$r.git\n git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD\n echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"\ndone\n\n\n to 'workflow/0.sh'
2026-10-28T12:00:46.5437293Z ::group::Run echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
2026-10-28T12:00:46.5437525Z echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
2026-10-28T12:00:46.5437687Z base=http://gitea.gitea-system.svc.cluster.local:3000/admin
2026-10-28T12:00:46.5437812Z git init -q . && git remote add origin $base/felhom.eu.git
2026-10-28T12:00:46.5437929Z git fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD
2026-10-28T12:00:46.5438048Z echo "felhom.eu main at $(git rev-parse --short=12 HEAD)"
2026-10-28T12:00:46.5438173Z for r in felhom-controller app-catalog-felhom.eu; do
2026-10-28T12:00:46.5438288Z git init -q ../$r && git -C ../$r remote add origin $base/$r.git
2026-10-28T12:00:46.5438403Z git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD
2026-10-28T12:00:46.5438538Z echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"
2026-10-28T12:00:46.5438650Z done
2026-10-28T12:00:46.5438747Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T12:00:46.5438878Z ::endgroup::
2026-10-28T12:01:23.5016827Z felhom.eu main at fe677bae9415
2026-10-28T12:01:25.6366262Z felhom-controller at ed3927f03a52
2026-10-28T12:01:26.5667050Z app-catalog-felhom.eu at 0829994440ca
2026-10-28T12:01:26.5693927Z ::group::Run set -u
2026-10-28T12:01:26.5694317Z set -u
2026-10-28T12:01:26.5694546Z mkdir -p documentation/security-watch
2026-10-28T12:01:26.5694764Z mode="${MODE:-run}"
2026-10-28T12:01:26.5695012Z [ "${GITHUB_EVENT_NAME:-}" = "schedule" ] && mode=run
2026-10-28T12:01:26.5695227Z echo "mode: $mode"
2026-10-28T12:01:26.5695412Z case "$mode" in
2026-10-28T12:01:26.5695665Z test-mail) python3 scripts/security_watch.py --test-mail; exit $? ;;
2026-10-28T12:01:26.5695895Z dry) extra="--no-mail" ; state=/tmp/state-dry.json
2026-10-28T12:01:26.5696103Z cp documentation/security-watch/state.json "$state" 2>/dev/null || true ;;
2026-10-28T12:01:26.5696329Z seed) extra="--seed" ; state=documentation/security-watch/state.json ;;
2026-10-28T12:01:26.5696598Z run) extra="" ; state=documentation/security-watch/state.json ;;
2026-10-28T12:01:26.5696818Z *) echo "unknown mode $mode"; exit 2 ;;
2026-10-28T12:01:26.5697006Z esac
2026-10-28T12:01:26.5697209Z python3 scripts/security_watch.py --state="$state" --catalog=../app-catalog-felhom.eu \
2026-10-28T12:01:26.5697447Z --controller=../felhom-controller --json=/tmp/watch-results.json $extra
2026-10-28T12:01:26.5697669Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T12:01:26.5697920Z env:
2026-10-28T12:01:26.5698109Z RESEND_API_KEY: ***
2026-10-28T12:01:26.5698321Z GH_ADVISORY_TOKEN: ***
2026-10-28T12:01:26.5698526Z MODE: dry
2026-10-28T12:01:26.5698742Z FELHOM_WHEEL_FETCH: 1
2026-10-28T12:01:26.5698922Z ::endgroup::
2026-10-28T12:01:26.5739323Z mode: dry
2026-10-28T12:01:26.7660320Z /root/.cache/act/11ac34485efd370e/hostexecutor/scripts/security_watch.py:905: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
2026-10-28T12:01:26.7661677Z today = datetime.date.fromisoformat(opts["today"]) if "today" in opts else datetime.datetime.utcnow().date()
2026-10-28T12:01:26.8191595Z security watch 2026-10-28: 197 pins (11 box/build, 97 app, 89 DooPlex); GitHub key PRESENT — every repo's advisories tonight
2026-10-28T12:02:04.9781238Z RUNTIME-READ golang:1.27.3-trixie 19 s ok
2026-10-28T12:04:20.3838872Z RUNTIME-READ ghcr.io/immich-app/immich-server:v3.3.5 69 s NOT CHECKED: blob sha256:845df800fea0: HTTP 429
2026-10-28T12:04:26.7947758Z RUNTIME-READ ghost:6.73.0-alpine 85 s ok
2026-10-28T12:04:29.8329970Z RUNTIME-READ ghcr.io/immich-app/immich-machine-learning:v3.3.5 79 s NOT CHECKED: blob sha256:203d435a3538: HTTP 429
2026-10-28T12:04:48.2494557Z RUNTIME-READ freikin/dawarich:1.19.0 120 s ok
2026-10-28T12:05:13.1838084Z RUNTIME-READ ghcr.io/home-assistant/home-assistant:2026.10.4 126 s ok
2026-10-28T12:05:16.0600394Z RUNTIME-READ ghcr.io/alexta69/metube:2026.10.27 41 s ok
2026-10-28T12:05:26.7771906Z RUNTIME-READ ghcr.io/karakeep-app/karakeep:0.34.1 131 s ok
2026-10-28T12:05:41.7159205Z RUNTIME-READ ghcr.io/papra-hq/papra:26.7.1-rootless 46 s ok
2026-10-28T12:05:44.7800807Z RUNTIME-READ rommapp/romm:5.4.1 27 s ok
2026-10-28T12:06:14.5281629Z RUNTIME-READ ghcr.io/tandoorrecipes/recipes:2.7.2 47 s ok
2026-10-28T12:06:29.2610581Z RUNTIME-READ ghcr.io/diced/zipline:4.8.2 45 s ok
2026-10-28T12:06:44.6827138Z RUNTIME-READ docker.io/library/nextcloud:34.0.5-apache 48 s ok
2026-10-28T12:07:16.4518103Z RUNTIME-READ python:3.15-bookworm 20 s ok
2026-10-28T12:07:16.5208430Z ADVISORY doop actualbudget/actual-server 26.10.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T12:07:16.5209224Z ADVISORY doop advplyr/audiobookshelf 2.37.1 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T12:07:16.5209638Z ADVISORY box cloudflare/cloudflared 2026.10.4 feed:cloudflare-blog:01M5DK5J81T0VC8YTBR2FKD8A3 (fixed read the notice); vulnnotes:cloudflared@2026.10.5:VULN-183456 (fixed 2026.10.5)
2026-10-28T12:07:16.5209829Z ADVISORY doop codewithcj/sparkyfitness_server v1.9.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T12:07:16.5209968Z ADVISORY doop crocodilestick/calibre-web-automated dev CVE-2026-111497 (fixed 1.2.1)
2026-10-28T12:07:16.5210104Z ADVISORY doop docker.io/calcom/cal.com v6.2.0 CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T12:07:16.5210298Z ADVISORY doop flomp/wanderer-db v0.21.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 1 more
2026-10-28T12:07:16.5210546Z ADVISORY doop flomp/wanderer-web v0.21.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 2 more
2026-10-28T12:07:16.5211078Z ADVISORY doop ghcr.io/gethomepage/homepage v1.13.2 GHSA-669x-4pg4-w24r (fixed 2.2.0); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T12:07:16.5211262Z ADVISORY doop ghcr.io/immich-app/immich-machine-learning v2.7.5 GHSA-q89f-h332-8q2h (fixed v3.2.4); GHSA-h5w4-vjv4-9r5q (fixed a version after 3.1.0 (the notice names none)); GHSA-g4w3-c888-cr93 (fixed v3.2.0); GHSA-72rm-x7xr-v679 (fixed v3.3.0); … 7 more
2026-10-28T12:07:16.5211466Z ADVISORY doop ghcr.io/immich-app/immich-server v2.7.5 GHSA-q89f-h332-8q2h (fixed v3.2.4); GHSA-h5w4-vjv4-9r5q (fixed a version after 3.1.0 (the notice names none)); GHSA-g4w3-c888-cr93 (fixed v3.2.0); GHSA-72rm-x7xr-v679 (fixed v3.3.0); … 8 more
2026-10-28T12:07:16.5211642Z ADVISORY doop ghcr.io/lukegus/termix release-2.9.2 CVE-2026-111497 (fixed 26.12.1)
2026-10-28T12:07:16.5211794Z ADVISORY doop ghcr.io/paperless-ngx/paperless-ngx 3.3.4 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T12:07:16.5211940Z ADVISORY doop gitea/gitea 1.26.2 GHSA-wx44-9m3m-rjqx (fixed 28.2.0); GHSA-4jmf-h2cm-hg7w (fixed 28.2.0); GHSA-8j56-f865-gqq2 (fixed 28.2.0); GHSA-fxq4-gr55-7x5g (fixed 28.2.0); … 127 more
2026-10-28T12:07:16.5212136Z ADVISORY doop grafana/grafana 13.2.4 GHSA-8xmm-x63g-f6xv (fixed no fixed version named yet); GHSA-4724-7jwc-3fpw (fixed the range is unreadable — check by hand); GHSA-2x6g-h2hg-rq84 (fixed the range is unreadable — check by hand); GHSA-8wjh-59cw-9xh4 (fixed no fixed version named yet); … 2 more
2026-10-28T12:07:16.5212375Z ADVISORY box gtstef/filebrowser 1.5.8-stable GHSA-gfgm-886h-6r47 (fixed 2.0.2-stable, 2.1.4-beta); GHSA-wxj5-g3qp-g732 (fixed 2.0.2-stable, 2.1.3-beta); GHSA-3j46-5w28-f8p2 (fixed 2.1.0-stable, 2.1.3-beta); GHSA-4vrc-935w-xxq2 (fixed 2.1.0-stable, 2.1.3-beta); … 31 more
2026-10-28T12:07:16.5212570Z ADVISORY doop louislam/uptime-kuma 2.5.6 GHSA-qjxc-h5jf-c7rj (fixed the range is unreadable — check by hand); release:louislam/uptime-kuma@2.5.8 (fixed 2.5.8); release:louislam/uptime-kuma@2.5.7 (fixed 2.5.7); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T12:07:16.5213092Z ADVISORY doop outlinewiki/outline 1.11.0 GHSA-x4w3-9p9j-cprh (fixed 1.12.0); GHSA-rq53-m97j-f2pg (fixed 1.12.0); GHSA-h6ff-rw9x-5mq2 (fixed 1.12.0); GHSA-rvj7-2gww-6xfq (fixed 1.12.0); … 3 more
2026-10-28T12:07:16.5213432Z ADVISORY doop redis 8.10.2 GHSA-c8h9-259x-jff4 (fixed the range is unreadable — check by hand); GHSA-8ghh-qpmp-7826 (fixed no fixed version named yet); GHSA-93m2-935m-8rj3 (fixed no fixed version named yet); GHSA-m8fj-85cg-7vhp (fixed the range is unreadable — check by hand); … 8 more
2026-10-28T12:07:16.5213650Z ADVISORY doop rommapp/romm 5.4.0 release:rommapp/romm@5.4.1 (fixed 5.4.1); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T12:07:16.5213812Z ADVISORY doop vabene1111/recipes 2.6.15 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T12:07:16.5213944Z ADVISORY app actualbudget/actual-server 26.9.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T12:07:16.5214098Z ADVISORY app calcom/cal.com v6.2.0 GHSA-p3f6-52gv-cj7m (fixed the range is unreadable — check by hand); GHSA-cpf2-q635-xrwx (fixed the range is unreadable — check by hand); CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T12:07:16.5214430Z ADVISORY app codewithcj/sparkyfitness v0.17.3 GHSA-v883-jx9h-qf29 (fixed a version after 1.7.2 (the notice names none)); GHSA-cmmf-53wf-r5gv (fixed a version after 1.6.5 (the notice names none)); GHSA-p8cf-g8rv-gvrq (fixed a version after 1.6.5 (the notice names none))
2026-10-28T12:07:16.5214601Z ADVISORY app codewithcj/sparkyfitness_server v0.17.3 GHSA-v883-jx9h-qf29 (fixed a version after 1.7.2 (the notice names none)); GHSA-cmmf-53wf-r5gv (fixed a version after 1.6.5 (the notice names none)); GHSA-p8cf-g8rv-gvrq (fixed a version after 1.6.5 (the notice names none)); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T12:07:16.5214787Z ADVISORY app crocodilestick/calibre-web-automated v4.0.8 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T12:07:16.5214920Z ADVISORY app f0rc3/gokapi v1.9.6 GHSA-45vh-rpc8-hxpp (fixed 2.2.4); GHSA-qwc6-vc2v-2ggj (fixed 2.2.4); GHSA-j6jp-78w8-34x6 (fixed 2.2.4); GHSA-m2hx-wjxc-9fp4 (fixed 2.2.3); … 6 more
2026-10-28T12:07:16.5215098Z ADVISORY app fallenbagel/jellyseerr 2.7.3 GHSA-8j73-j6rc-q8xh (fixed 3.5.0); GHSA-xc6j-6p6h-p799 (fixed 3.5.0); GHSA-mc6w-69r3-62h8 (fixed 3.4.0); GHSA-gx3h-3jg5-q65f (fixed 3.1.0); … 3 more
2026-10-28T12:07:16.5215267Z ADVISORY app flomp/wanderer-db v0.20.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 7 more
2026-10-28T12:07:16.5215438Z ADVISORY app flomp/wanderer-web v0.20.0 CVE-2026-111497 (fixed 22.23.4)
2026-10-28T12:07:16.5215572Z ADVISORY app ghcr.io/gethomepage/homepage v1.13.2 GHSA-669x-4pg4-w24r (fixed 2.2.0); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T12:07:16.5215706Z ADVISORY app ghcr.io/immich-app/immich-machine-learning v3.3.5 GHSA-8244-8vpr-vp9c (fixed the range is unreadable — check by hand)
2026-10-28T12:07:16.5215859Z ADVISORY app ghcr.io/immich-app/immich-server v3.3.5 GHSA-8244-8vpr-vp9c (fixed the range is unreadable — check by hand)
2026-10-28T12:07:16.5216051Z ADVISORY app ghcr.io/karakeep-app/karakeep 0.34.1 GHSA-pp34-2c9r-mchw (fixed no fixed version named yet)
2026-10-28T12:07:16.5216202Z ADVISORY app ghcr.io/lukegus/termix 2.8.0 GHSA-6gr3-r7jx-wfmh (fixed >= 26.10.0); GHSA-frx8-qqgg-7j7g (fixed >= 26.10.0); GHSA-3q2m-5r5p-w45r (fixed >= 26.10.0); GHSA-rgf3-2q88-q4wp (fixed >= 26.10.0); … 9 more
2026-10-28T12:07:16.5216380Z ADVISORY app ghcr.io/paperless-ngx/paperless-ngx 2.20.15 GHSA-c8f3-pqr2-rr24 (fixed 3.3.2); GHSA-2jhj-xqrq-rmrq (fixed 3.1.2); CVE-2026-111497 (fixed 1.1.1)
2026-10-28T12:07:16.5216533Z ADVISORY app ghcr.io/tandoorrecipes/recipes 2.7.2 GHSA-c7mc-c9jr-38hf (fixed the range is unreadable — check by hand); GHSA-cqj3-64qw-4w52 (fixed the range is unreadable — check by hand)
2026-10-28T12:07:16.5216688Z ADVISORY app gitea/gitea 1.27.3 GHSA-wx44-9m3m-rjqx (fixed 28.2.0); GHSA-4jmf-h2cm-hg7w (fixed 28.2.0); GHSA-8j56-f865-gqq2 (fixed 28.2.0); GHSA-fxq4-gr55-7x5g (fixed 28.2.0); … 37 more
2026-10-28T12:07:16.5216836Z ADVISORY app glanceapp/glance v0.8.5 GHSA-r225-jhr6-68cc (fixed >= 0.8.7)
2026-10-28T12:07:16.5216970Z ADVISORY app grafana/grafana 13.2.4 GHSA-8xmm-x63g-f6xv (fixed no fixed version named yet); GHSA-4724-7jwc-3fpw (fixed the range is unreadable — check by hand); GHSA-2x6g-h2hg-rq84 (fixed the range is unreadable — check by hand); GHSA-8wjh-59cw-9xh4 (fixed no fixed version named yet); … 2 more
2026-10-28T12:07:16.5217162Z ADVISORY app louislam/uptime-kuma 2.5.7 GHSA-qjxc-h5jf-c7rj (fixed the range is unreadable — check by hand); release:louislam/uptime-kuma@2.5.8 (fixed 2.5.8)
2026-10-28T12:07:16.5217302Z ADVISORY app n8nio/n8n 2.44.7 GHSA-2x68-96jw-5r6c (fixed >= 3.0.1); GHSA-9p7v-45m2-wxgj (fixed >= 3.0.1); GHSA-mx4r-96jx-v278 (fixed >= 3.0.1); GHSA-4v22-g448-h4rg (fixed >= 2.45.5, >= 2.46.1, >= 3.0.1); … 9 more
2026-10-28T12:07:16.5217523Z ADVISORY app rommapp/romm 5.4.1 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T12:07:16.5217655Z NOT CHECKED doop gitea.dooplex.hu/admin/felhom-act-runner 0.1.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T12:07:16.5217798Z NOT CHECKED doop gitea.dooplex.hu/admin/jarr latest registry gitea.dooplex.hu: no anonymous token route
2026-10-28T12:07:16.5217926Z NOT CHECKED doop gitea.dooplex.hu/admin/recipe-importer latest registry gitea.dooplex.hu: no anonymous token route
2026-10-28T12:07:16.5218066Z NOT CHECKED doop gitea.dooplex.hu/admin/revfulop-calendar 1.6.2 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T12:07:16.5218191Z NOT CHECKED doop gitea.dooplex.hu/admin/sparkyfitness-export 0.3.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T12:07:16.5218325Z NOT CHECKED doop gitea.dooplex.hu/admin/wan-probe 0.1.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T12:07:16.5218447Z NOT CHECKED doop griefed/serverpackcreator 8.1.2 https://hub.docker.com/v2/repositories/griefed/serverpackcreator/tags: The read operation timed out
2026-10-28T12:07:16.5218610Z NOT CHECKED doop minio/minio latest Docker registry tags of minio/minio: HTTP 401; manifest minio/minio:latest: HTTP 401
2026-10-28T12:07:16.5218755Z BEHIND doop getmeili/meilisearch v1.11.3 newest v1.56.0
2026-10-28T12:07:16.5218874Z BEHIND doop ghcr.io/diced/zipline 4.8.1 newest 4.8.2
2026-10-28T12:07:16.5218989Z BEHIND app getmeili/meilisearch v1.41.0 newest v1.56.0
2026-10-28T12:07:16.5219138Z BEHIND app getmeili/meilisearch v1.36.0 newest v1.56.0
2026-10-28T12:07:16.5219257Z BEHIND app ghcr.io/hargata/lubelogger v1.7.3 newest v1.7.4
2026-10-28T12:07:16.5219403Z BEHIND app ghcr.io/kozea/radicale 3.8.1 newest 3.9.0
2026-10-28T12:07:16.5219620Z BEHIND app gotson/komga 1.28.0 newest 1.29.2
2026-10-28T12:07:16.5220213Z BEHIND app kimai/kimai2 2.67.0 newest 2.71.0
2026-10-28T12:07:16.5220506Z BEHIND app lscr.io/linuxserver/bookstack 26.09.2 newest 26.09.20260929
2026-10-28T12:07:16.5220739Z BEHIND app nextcloud 34.0.4-apache newest 34.0.5-apache
2026-10-28T12:07:16.5220973Z BEHIND app nginx 1.30.5-alpine newest 1.31.8-alpine
2026-10-28T12:07:16.5221186Z BEHIND app qbittorrentofficial/qbittorrent-nox 5.2.4-1 newest 5.3.0-2
2026-10-28T12:07:16.5221421Z GAP buil alpine 3.24.2 newest 3.24.3
2026-10-28T12:07:16.5221640Z GAP buil alpine 3.24.2 newest 3.24.3
2026-10-28T12:07:16.5221775Z GAP doop alpine/k8s 1.37.1
2026-10-28T12:07:16.5221895Z GAP doop arcadiatechnology/crafty-4 4.11.0
2026-10-28T12:07:16.5222014Z GAP doop bhgedigital/envsubst latest
2026-10-28T12:07:16.5222130Z GAP doop busybox 1.38
2026-10-28T12:07:16.5222241Z GAP doop codercom/code-server 4.143.1
2026-10-28T12:07:16.5222357Z GAP buil debian 13.7-slim
2026-10-28T12:07:16.5222470Z GAP buil debian 13.7-slim
2026-10-28T12:07:16.5222581Z GAP doop docker.io/bitnamilegacy/postgresql 17.6.0-debian-12-r3
2026-10-28T12:07:16.5222698Z GAP doop docker.io/library/nextcloud 34.0.5-apache
2026-10-28T12:07:16.5222804Z GAP doop docker.io/valkey/valkey 9.2-alpine
2026-10-28T12:07:16.5222923Z GAP doop filebrowser/filebrowser v2.63.23
2026-10-28T12:07:16.5223040Z GAP doop ghcr.io/cloudnative-pg/postgresql 17.2 newest 17.11
2026-10-28T12:07:16.5223167Z GAP doop ghcr.io/headlamp-k8s/headlamp v0.46.0
2026-10-28T12:07:16.5223297Z GAP doop ghcr.io/immich-app/postgres 16-vectorchord0.3.0
2026-10-28T12:07:16.5223454Z GAP doop ghcr.io/jimmidyson/configmap-reload v0.15.0
2026-10-28T12:07:16.5223577Z GAP doop ghcr.io/onedr0p/exportarr v2.3.0
2026-10-28T12:07:16.5223693Z GAP doop ghcr.io/seerr-team/seerr v3.5.1
2026-10-28T12:07:16.5223820Z GAP doop ghcr.io/seriousm4x/upsnap 5
2026-10-28T12:07:16.5223935Z GAP doop ghcr.io/stakater/reloader v1.4.22 newest v1.4.23
2026-10-28T12:07:16.5224053Z GAP doop ghcr.io/tautulli/tautulli v2.18.2
2026-10-28T12:07:16.5224175Z GAP doop gtstef/filebrowser 1.5.8-stable
2026-10-28T12:07:16.5224290Z GAP doop guacamole/guacamole 1.6.0
2026-10-28T12:07:16.5224406Z GAP doop guacamole/guacd 1.6.0
2026-10-28T12:07:16.5224537Z GAP doop index.docker.io/plexinc/pms-docker 1.43.5.11029-6bf8af3f0
2026-10-28T12:07:16.5224656Z GAP doop itzg/mc-backup 2026.10.1 newest 2026.10.2
2026-10-28T12:07:16.5224782Z GAP doop itzg/minecraft-server 2026.10.0-java21 newest 2026.10.1-java17
2026-10-28T12:07:16.5224906Z GAP doop linuxserver/bookstack 26.09.20260929
2026-10-28T12:07:16.5225035Z GAP doop linuxserver/prowlarr version-2.6.5.5623
2026-10-28T12:07:16.5225149Z GAP doop linuxserver/qbittorrent 5.3.0
2026-10-28T12:07:16.5225260Z GAP doop linuxserver/radarr version-6.4.4.10685
2026-10-28T12:07:16.5225460Z GAP doop linuxserver/sonarr version-4.0.20.3014
2026-10-28T12:07:16.5225601Z GAP doop mariadb 11
2026-10-28T12:07:16.5225715Z GAP doop mikefarah/yq 4.54.1
2026-10-28T12:07:16.5225825Z GAP doop mongodb/mongodb-community-server 8.0.5-ubuntu2204 newest 8.3.13-ubuntu2204
2026-10-28T12:07:16.5225988Z GAP doop msdeluise/plant-it-server 0.10.0
2026-10-28T12:07:16.5226104Z GAP doop mysql 8.4
2026-10-28T12:07:16.5226219Z GAP doop nicolaka/netshoot latest
2026-10-28T12:07:16.5226331Z GAP doop postgis/postgis 16-3.5
2026-10-28T12:07:16.5226482Z GAP doop postgres 15-alpine
2026-10-28T12:07:16.5226606Z GAP doop postgres 16-alpine
2026-10-28T12:07:16.5226725Z GAP doop privatebin/nginx-fpm-alpine 2.0.6 newest 2.1.0
2026-10-28T12:07:16.5226886Z GAP doop prom/alertmanager v0.34.1
2026-10-28T12:07:16.5227005Z GAP doop prom/node-exporter v1.12.1
2026-10-28T12:07:16.5227122Z GAP doop prom/prometheus v3.15.0 newest v3.15.1
2026-10-28T12:07:16.5227240Z GAP doop prometheuscommunity/smartctl-exporter v0.15.0
2026-10-28T12:07:16.5227377Z GAP doop python 3.15-bookworm
2026-10-28T12:07:16.5227491Z GAP doop quay.io/jetstack/version-checker v0.11.0
2026-10-28T12:07:16.5227607Z GAP doop quay.io/prometheus/blackbox-exporter v0.29.1
2026-10-28T12:07:16.5227762Z GAP doop renovate/renovate 44.181.1 newest 44.190.2
2026-10-28T12:07:16.5227885Z GAP doop tailscale/tailscale v1.104.2
2026-10-28T12:07:16.5227996Z GAP app emby/embyserver 4.11.0.4 newest 4.11.0.11
2026-10-28T12:07:16.5228244Z GAP app ghcr.io/immich-app/postgres 16-vectorchord0.4.3-pg
2026-10-28T12:07:16.5228390Z GAP app ghcr.io/karakeep-app/karakeep-chrome 151.0.7922.47-r1
2026-10-28T12:07:16.5228505Z GAP app mariadb 12.3
2026-10-28T12:07:16.5228617Z GAP app mariadb 11.4 newest 11.8
2026-10-28T12:07:16.5228829Z GAP app mariadb 11.8
2026-10-28T12:07:16.5228940Z GAP app mariadb 12.3
2026-10-28T12:07:16.5229046Z GAP app mariadb 11.8
2026-10-28T12:07:16.5229154Z GAP app msdeluise/plant-it 0.10.0
2026-10-28T12:07:16.5229292Z GAP app plexinc/pms-docker 1.43.5.11029-6bf8af3f0
2026-10-28T12:07:16.5229405Z GAP app postgis/postgis 16-3.5-alpine
2026-10-28T12:07:16.5229582Z GAP app postgis/postgis 17-3.5-alpine
2026-10-28T12:07:16.5229804Z GAP app postgres 18-alpine
2026-10-28T12:07:16.5229929Z GAP app postgres 17-alpine
2026-10-28T12:07:16.5230036Z GAP app postgres 18-alpine
2026-10-28T12:07:16.5230146Z GAP app postgres 18-alpine
2026-10-28T12:07:16.5230285Z GAP app postgres 18-alpine
2026-10-28T12:07:16.5230456Z GAP app postgres 18-alpine
2026-10-28T12:07:16.5230568Z GAP app postgres 18-alpine
2026-10-28T12:07:16.5230709Z GAP app postgres 17-alpine
2026-10-28T12:07:16.5230827Z GAP app postgres 16-alpine
2026-10-28T12:07:16.5230934Z GAP app registry.gitlab.com/crafty-controller/crafty-4 4.11.0
2026-10-28T12:07:16.5231049Z FLOATING doop ghcr.io/seanmorley15/adventurelog-backend latest
2026-10-28T12:07:16.5231193Z FLOATING doop ghcr.io/seanmorley15/adventurelog-frontend latest
2026-10-28T12:07:16.5231307Z FLOATING doop nginx 1.31-alpine
2026-10-28T12:07:16.5231420Z FLOATING doop redis 8-alpine
2026-10-28T12:07:16.5231565Z FLOATING doop redis 8.10-alpine
2026-10-28T12:07:16.5231682Z FLOATING app ghcr.io/claperco/claper 2.5
2026-10-28T12:07:16.5231874Z FLOATING app ghcr.io/thomiceli/opengist 1.15
2026-10-28T12:07:16.5232046Z FLOATING app jellyfin/jellyfin 12.4
2026-10-28T12:07:16.5232223Z FLOATING app lscr.io/linuxserver/prowlarr version-2.6.5.5623
2026-10-28T12:07:16.5232336Z FLOATING app lscr.io/linuxserver/sabnzbd version-5.1.3
2026-10-28T12:07:16.5232449Z FLOATING app lscr.io/linuxserver/transmission version-4.1.3-r0
2026-10-28T12:07:16.5232596Z FLOATING app nzbgetcom/nzbget v26.3
2026-10-28T12:07:16.5232705Z FLOATING app redis 7.4-alpine
2026-10-28T12:07:16.5232811Z FLOATING app redis 7-alpine
2026-10-28T12:07:16.5232918Z FLOATING app redis 7-alpine
2026-10-28T12:07:16.5233057Z FLOATING app redis 7-alpine
2026-10-28T12:07:16.5233162Z FLOATING app redis 7-alpine
2026-10-28T12:07:16.5233336Z FLOATING app redis 7-alpine
2026-10-28T12:07:16.5233486Z FLOATING app redis 7-alpine
2026-10-28T12:07:16.5233664Z FLOATING app wger/server 2.7
2026-10-28T12:07:16.5233775Z SELF box gitea.dooplex.hu/admin/felhom-samba 1.2.0
2026-10-28T12:07:16.5233883Z SELF app gitea.dooplex.hu/admin/recipe-importer v0.9.11
2026-10-28T12:07:16.5234027Z CURRENT doop codewithcj/sparkyfitness v1.9.0
2026-10-28T12:07:16.5234138Z CURRENT doop f0rc3/gokapi v2.2.4
2026-10-28T12:07:16.5234370Z CURRENT doop ghcr.io/alam00000/bentopdf 2.8.10
2026-10-28T12:07:16.5234523Z CURRENT doop ghcr.io/thomiceli/opengist 1.15.3
2026-10-28T12:07:16.5234641Z CURRENT doop glanceapp/glance v0.8.7
2026-10-28T12:07:16.5234755Z CURRENT buil golang 1.27.3-trixie
2026-10-28T12:07:16.5234868Z CURRENT buil golang 1.27.3-alpine3.24
2026-10-28T12:07:16.5235007Z CURRENT doop onlyoffice/documentserver 9.4.0
2026-10-28T12:07:16.5235116Z CURRENT buil restic 0.19.1
2026-10-28T12:07:16.5235295Z CURRENT box traefik v3.7.16
2026-10-28T12:07:16.5235444Z CURRENT doop vaultwarden/server 1.37.4
2026-10-28T12:07:16.5235558Z CURRENT app deluan/navidrome 0.64.2
2026-10-28T12:07:16.5235735Z CURRENT app docmost/docmost 0.97.0
2026-10-28T12:07:16.5235844Z CURRENT app freikin/dawarich 1.19.0
2026-10-28T12:07:16.5235981Z CURRENT app ghcr.io/advplyr/audiobookshelf 2.37.2
2026-10-28T12:07:16.5236089Z CURRENT app ghcr.io/alam00000/bentopdf v2.8.10
2026-10-28T12:07:16.5236198Z CURRENT app ghcr.io/alexta69/metube 2026.10.27
2026-10-28T12:07:16.5236348Z CURRENT app ghcr.io/cmintey/wishlist v0.69.0
2026-10-28T12:07:16.5236463Z CURRENT app ghcr.io/diced/zipline 4.8.2
2026-10-28T12:07:16.5236572Z CURRENT app ghcr.io/gramps-project/grampsweb v25.6.0
2026-10-28T12:07:16.5236688Z CURRENT app ghcr.io/grimmory-tools/grimmory v3.5.0
2026-10-28T12:07:16.5236940Z CURRENT app ghcr.io/home-assistant/home-assistant 2026.10.4
2026-10-28T12:07:16.5237051Z CURRENT app ghcr.io/mealie-recipes/mealie v3.29.0
2026-10-28T12:07:16.5237165Z CURRENT app ghcr.io/papra-hq/papra 26.7.1-rootless
2026-10-28T12:07:16.5237306Z CURRENT app ghcr.io/seanmorley15/adventurelog-backend v0.13.1
2026-10-28T12:07:16.5237422Z CURRENT app ghcr.io/seanmorley15/adventurelog-frontend v0.13.1
2026-10-28T12:07:16.5237598Z CURRENT app ghcr.io/sysadminsmedia/homebox 0.27.1
2026-10-28T12:07:16.5237711Z CURRENT app ghost 6.73.0-alpine
2026-10-28T12:07:16.5237872Z CURRENT app lscr.io/linuxserver/code-server 4.143.1
2026-10-28T12:07:16.5237983Z CURRENT app lscr.io/linuxserver/grocy 4.7.1
2026-10-28T12:07:16.5238094Z CURRENT app lscr.io/linuxserver/radarr 6.4.4
2026-10-28T12:07:16.5238243Z CURRENT app lscr.io/linuxserver/sonarr 4.0.20
2026-10-28T12:07:16.5238359Z CURRENT app lukevella/rallly 4.16.3
2026-10-28T12:07:16.5238594Z CURRENT app onlyoffice/documentserver 9.4.0
2026-10-28T12:07:16.5238706Z CURRENT app outlinewiki/outline 1.12.0
2026-10-28T12:07:16.5238842Z CURRENT app privatebin/pdo 2.1.0
2026-10-28T12:07:16.5238956Z CURRENT app vaultwarden/server 1.37.4-alpine
2026-10-28T12:07:16.5239065Z CURRENT app vikunja/vikunja 2.7.1
2026-10-28T12:07:16.5239262Z COUNTS ADVISORY=43 BEHIND=12 CURRENT=38 FLOATING=20 GAP=74 NOT_CHECKED=8 SELF=2
2026-10-28T12:07:16.5239380Z RUNTIME read=14 (904 s) from-cache=171 not-checked=2 zstd-decoder=zstandard 0.25.0 (pinned wheel, sha256 checked)
2026-10-28T12:07:16.5239508Z TAGS fetched=117 from-cache=0 retried-429=0 (cache /root/.cache/felhom-watch-tags.json)
2026-10-28T12:07:16.5239627Z REQUESTS api.github.com=70 api.osv.dev=1 auth.docker.io=1 blog.cloudflare.com=1 ghcr.io=125 github.com=62 hub.docker.com=210 raw.githubusercontent.com=1 registry-1.docker.io=1
2026-10-28T12:07:16.5488789Z MAIL (not sent, --no-mail): [Felhom security] n8n — 12 new advisories
2026-10-28T12:07:16.5489387Z MAIL (not sent, --no-mail): [Felhom security] the watch could not check runtime
2026-10-28T12:07:16.5598084Z STATE written: /tmp/state-dry.json (379 known advisories)
2026-10-28T12:07:16.6775446Z Cleaning up container for job watch
2026-10-28T12:07:17.1822675Z 🏁 Job succeeded
@@ -0,0 +1,285 @@
2026-10-28T03:40:06.3485708Z felhom-gates-runner-2(version:v0.6.1) received task 2469 of job watch, be triggered by event: schedule
2026-10-28T03:40:06.3521612Z workflow prepared
2026-10-28T03:40:06.3523208Z evaluating expression 'success()'
2026-10-28T03:40:06.3524206Z expression 'success()' evaluated to 'true'
2026-10-28T03:40:06.3530159Z evaluating expression ''
2026-10-28T03:40:06.3530552Z expression '' evaluated to 'true'
2026-10-28T03:40:06.3530959Z ⭐ Run Main Fetch main (latest, for the memory) and the two sibling repos
2026-10-28T03:40:06.3534372Z Wrote command \n\necho "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"\nbase=http://gitea.gitea-system.svc.cluster.local:3000/admin\ngit init -q . && git remote add origin $base/felhom.eu.git\ngit fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD\necho "felhom.eu main at $(git rev-parse --short=12 HEAD)"\nfor r in felhom-controller app-catalog-felhom.eu; do\n git init -q ../$r && git -C ../$r remote add origin $base/$r.git\n git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD\n echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"\ndone\n\n\n to 'workflow/0.sh'
2026-10-28T03:40:06.3535721Z ::group::Run echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
2026-10-28T03:40:06.3535978Z echo "WATCH_STARTED_AT=$(date +%s)" >> "$GITHUB_ENV"
2026-10-28T03:40:06.3536252Z base=http://gitea.gitea-system.svc.cluster.local:3000/admin
2026-10-28T03:40:06.3536383Z git init -q . && git remote add origin $base/felhom.eu.git
2026-10-28T03:40:06.3536547Z git fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD
2026-10-28T03:40:06.3536673Z echo "felhom.eu main at $(git rev-parse --short=12 HEAD)"
2026-10-28T03:40:06.3536803Z for r in felhom-controller app-catalog-felhom.eu; do
2026-10-28T03:40:06.3536958Z git init -q ../$r && git -C ../$r remote add origin $base/$r.git
2026-10-28T03:40:06.3537095Z git -C ../$r fetch -q --depth 1 origin main && git -C ../$r checkout -q FETCH_HEAD
2026-10-28T03:40:06.3537224Z echo "$r at $(git -C ../$r rev-parse --short=12 HEAD)"
2026-10-28T03:40:06.3537342Z done
2026-10-28T03:40:06.3537482Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T03:40:06.3537613Z ::endgroup::
2026-10-28T03:40:39.3201705Z felhom.eu main at 3d3cd3ad7cb0
2026-10-28T03:40:41.5191870Z felhom-controller at ed3927f03a52
2026-10-28T03:40:42.7211795Z app-catalog-felhom.eu at 540f18552bbf
2026-10-28T03:40:42.7235514Z ::group::Run set -u
2026-10-28T03:40:42.7235894Z set -u
2026-10-28T03:40:42.7236110Z mkdir -p documentation/security-watch
2026-10-28T03:40:42.7236376Z mode="${MODE:-run}"
2026-10-28T03:40:42.7236571Z [ "${GITHUB_EVENT_NAME:-}" = "schedule" ] && mode=run
2026-10-28T03:40:42.7236777Z echo "mode: $mode"
2026-10-28T03:40:42.7236961Z case "$mode" in
2026-10-28T03:40:42.7237243Z test-mail) python3 scripts/security_watch.py --test-mail; exit $? ;;
2026-10-28T03:40:42.7237461Z dry) extra="--no-mail" ; state=/tmp/state-dry.json
2026-10-28T03:40:42.7237664Z cp documentation/security-watch/state.json "$state" 2>/dev/null || true ;;
2026-10-28T03:40:42.7237932Z seed) extra="--seed" ; state=documentation/security-watch/state.json ;;
2026-10-28T03:40:42.7238152Z run) extra="" ; state=documentation/security-watch/state.json ;;
2026-10-28T03:40:42.7238354Z *) echo "unknown mode $mode"; exit 2 ;;
2026-10-28T03:40:42.7238545Z esac
2026-10-28T03:40:42.7238776Z python3 scripts/security_watch.py --state="$state" --catalog=../app-catalog-felhom.eu \
2026-10-28T03:40:42.7239012Z --controller=../felhom-controller --json=/tmp/watch-results.json $extra
2026-10-28T03:40:42.7239227Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T03:40:42.7239528Z env:
2026-10-28T03:40:42.7240564Z RESEND_API_KEY: ***
2026-10-28T03:40:42.7240790Z GH_ADVISORY_TOKEN: ***
2026-10-28T03:40:42.7241057Z MODE:
2026-10-28T03:40:42.7241238Z ::endgroup::
2026-10-28T03:40:42.7278994Z mode: run
2026-10-28T03:40:42.9280801Z /root/.cache/act/0366a85aab65e222/hostexecutor/scripts/security_watch.py:829: DeprecationWarning: datetime.datetime.utcnow() is deprecated and scheduled for removal in a future version. Use timezone-aware objects to represent datetimes in UTC: datetime.datetime.now(datetime.UTC).
2026-10-28T03:40:42.9281606Z today = datetime.date.fromisoformat(opts["today"]) if "today" in opts else datetime.datetime.utcnow().date()
2026-10-28T03:40:42.9827880Z security watch 2026-10-28: 197 pins (11 box/build, 97 app, 89 DooPlex); GitHub key PRESENT — every repo's advisories tonight
2026-10-28T03:42:15.7217578Z ADVISORY doop actualbudget/actual-server 26.10.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7218164Z ADVISORY doop advplyr/audiobookshelf 2.37.1 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7218581Z ADVISORY box cloudflare/cloudflared 2026.10.4 feed:cloudflare-blog:01M5DK5J81T0VC8YTBR2FKD8A3 (fixed read the notice); vulnnotes:cloudflared@2026.10.5:VULN-183456 (fixed 2026.10.5)
2026-10-28T03:42:15.7218766Z ADVISORY doop codewithcj/sparkyfitness_server v1.9.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7218908Z ADVISORY doop crocodilestick/calibre-web-automated dev CVE-2026-111497 (fixed 1.2.1)
2026-10-28T03:42:15.7219112Z ADVISORY doop docker.io/calcom/cal.com v6.2.0 CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T03:42:15.7219254Z ADVISORY doop flomp/wanderer-db v0.21.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 1 more
2026-10-28T03:42:15.7219436Z ADVISORY doop flomp/wanderer-web v0.21.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 2 more
2026-10-28T03:42:15.7219603Z ADVISORY doop ghcr.io/gethomepage/homepage v1.13.2 GHSA-669x-4pg4-w24r (fixed 2.2.0); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T03:42:15.7219763Z ADVISORY doop ghcr.io/immich-app/immich-machine-learning v2.7.5 GHSA-q89f-h332-8q2h (fixed v3.2.4); GHSA-h5w4-vjv4-9r5q (fixed a version after 3.1.0 (the notice names none)); GHSA-g4w3-c888-cr93 (fixed v3.2.0); GHSA-72rm-x7xr-v679 (fixed v3.3.0); … 7 more
2026-10-28T03:42:15.7220024Z ADVISORY doop ghcr.io/immich-app/immich-server v2.7.5 GHSA-q89f-h332-8q2h (fixed v3.2.4); GHSA-h5w4-vjv4-9r5q (fixed a version after 3.1.0 (the notice names none)); GHSA-g4w3-c888-cr93 (fixed v3.2.0); GHSA-72rm-x7xr-v679 (fixed v3.3.0); … 8 more
2026-10-28T03:42:15.7220186Z ADVISORY doop ghcr.io/lukegus/termix release-2.9.2 CVE-2026-111497 (fixed 26.12.1)
2026-10-28T03:42:15.7220446Z ADVISORY doop ghcr.io/paperless-ngx/paperless-ngx 3.3.4 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T03:42:15.7220603Z ADVISORY doop gitea/gitea 1.26.2 GHSA-wx44-9m3m-rjqx (fixed 28.2.0); GHSA-4jmf-h2cm-hg7w (fixed 28.2.0); GHSA-8j56-f865-gqq2 (fixed 28.2.0); GHSA-fxq4-gr55-7x5g (fixed 28.2.0); … 127 more
2026-10-28T03:42:15.7220779Z ADVISORY doop grafana/grafana 13.2.4 GHSA-8xmm-x63g-f6xv (fixed no fixed version named yet); GHSA-4724-7jwc-3fpw (fixed the range is unreadable — check by hand); GHSA-2x6g-h2hg-rq84 (fixed the range is unreadable — check by hand); GHSA-8wjh-59cw-9xh4 (fixed no fixed version named yet); … 2 more
2026-10-28T03:42:15.7221080Z ADVISORY box gtstef/filebrowser 1.5.8-stable GHSA-gfgm-886h-6r47 (fixed 2.0.2-stable, 2.1.4-beta); GHSA-wxj5-g3qp-g732 (fixed 2.0.2-stable, 2.1.3-beta); GHSA-3j46-5w28-f8p2 (fixed 2.1.0-stable, 2.1.3-beta); GHSA-4vrc-935w-xxq2 (fixed 2.1.0-stable, 2.1.3-beta); … 31 more
2026-10-28T03:42:15.7221265Z ADVISORY doop louislam/uptime-kuma 2.5.6 GHSA-qjxc-h5jf-c7rj (fixed the range is unreadable — check by hand); release:louislam/uptime-kuma@2.5.8 (fixed 2.5.8); release:louislam/uptime-kuma@2.5.7 (fixed 2.5.7); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T03:42:15.7221932Z ADVISORY doop outlinewiki/outline 1.11.0 GHSA-x4w3-9p9j-cprh (fixed 1.12.0); GHSA-rq53-m97j-f2pg (fixed 1.12.0); GHSA-h6ff-rw9x-5mq2 (fixed 1.12.0); GHSA-rvj7-2gww-6xfq (fixed 1.12.0); … 3 more
2026-10-28T03:42:15.7222145Z ADVISORY doop redis 8.10.2 GHSA-c8h9-259x-jff4 (fixed the range is unreadable — check by hand); GHSA-8ghh-qpmp-7826 (fixed no fixed version named yet); GHSA-93m2-935m-8rj3 (fixed no fixed version named yet); GHSA-m8fj-85cg-7vhp (fixed the range is unreadable — check by hand); … 8 more
2026-10-28T03:42:15.7222496Z ADVISORY doop rommapp/romm 5.4.0 release:rommapp/romm@5.4.1 (fixed 5.4.1); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7222629Z ADVISORY doop vabene1111/recipes 2.6.15 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7222789Z ADVISORY app actualbudget/actual-server 26.9.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7222944Z ADVISORY app calcom/cal.com v6.2.0 GHSA-p3f6-52gv-cj7m (fixed the range is unreadable — check by hand); GHSA-cpf2-q635-xrwx (fixed the range is unreadable — check by hand); CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T03:42:15.7223116Z ADVISORY app codewithcj/sparkyfitness v0.17.3 GHSA-v883-jx9h-qf29 (fixed a version after 1.7.2 (the notice names none)); GHSA-cmmf-53wf-r5gv (fixed a version after 1.6.5 (the notice names none)); GHSA-p8cf-g8rv-gvrq (fixed a version after 1.6.5 (the notice names none))
2026-10-28T03:42:15.7223287Z ADVISORY app codewithcj/sparkyfitness_server v0.17.3 GHSA-v883-jx9h-qf29 (fixed a version after 1.7.2 (the notice names none)); GHSA-cmmf-53wf-r5gv (fixed a version after 1.6.5 (the notice names none)); GHSA-p8cf-g8rv-gvrq (fixed a version after 1.6.5 (the notice names none)); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7223494Z ADVISORY app crocodilestick/calibre-web-automated v4.0.8 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T03:42:15.7223662Z ADVISORY app f0rc3/gokapi v1.9.6 GHSA-45vh-rpc8-hxpp (fixed 2.2.4); GHSA-qwc6-vc2v-2ggj (fixed 2.2.4); GHSA-j6jp-78w8-34x6 (fixed 2.2.4); GHSA-m2hx-wjxc-9fp4 (fixed 2.2.3); … 6 more
2026-10-28T03:42:15.7223840Z ADVISORY app fallenbagel/jellyseerr 2.7.3 GHSA-8j73-j6rc-q8xh (fixed 3.5.0); GHSA-xc6j-6p6h-p799 (fixed 3.5.0); GHSA-mc6w-69r3-62h8 (fixed 3.4.0); GHSA-gx3h-3jg5-q65f (fixed 3.1.0); … 3 more
2026-10-28T03:42:15.7224007Z ADVISORY app flomp/wanderer-db v0.20.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 7 more
2026-10-28T03:42:15.7224158Z ADVISORY app flomp/wanderer-web v0.20.0 GHSA-vprp-gr6m-j375 (fixed v0.21.2); GHSA-3xp7-7492-j2q6 (fixed v0.21.2); GHSA-j9m4-8qwf-jvx6 (fixed v0.21.2); GHSA-fprh-3pp9-68m9 (fixed v0.21.2); … 8 more
2026-10-28T03:42:15.7224314Z ADVISORY app freikin/dawarich 1.15.3 release:Freika/dawarich@1.17.0 (fixed 1.17.0); CVE-2026-111497 (fixed 22.23.4, 24.22.1, 26.12.1)
2026-10-28T03:42:15.7224463Z ADVISORY app ghcr.io/alexta69/metube 2026.09.29 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T03:42:15.7224635Z ADVISORY app ghcr.io/diced/zipline 4.8.0 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7224769Z ADVISORY app ghcr.io/gethomepage/homepage v1.13.2 GHSA-669x-4pg4-w24r (fixed 2.2.0); CVE-2026-111497 (fixed 22.23.4)
2026-10-28T03:42:15.7224897Z ADVISORY app ghcr.io/home-assistant/home-assistant 2026.9.4 CVE-2026-111497 (fixed 1.2.1)
2026-10-28T03:42:15.7225037Z ADVISORY app ghcr.io/immich-app/immich-machine-learning v3.2.4 GHSA-8244-8vpr-vp9c (fixed the range is unreadable — check by hand); release:immich-app/immich@v3.3.5 (fixed v3.3.5)
2026-10-28T03:42:15.7225219Z ADVISORY app ghcr.io/immich-app/immich-server v3.2.4 GHSA-8244-8vpr-vp9c (fixed the range is unreadable — check by hand); release:immich-app/immich@v3.3.5 (fixed v3.3.5); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7225412Z ADVISORY app ghcr.io/karakeep-app/karakeep 0.33.2 GHSA-pp34-2c9r-mchw (fixed no fixed version named yet); release:karakeep-app/karakeep@v0.34.1 (fixed v0.34.1); release:karakeep-app/karakeep@v0.34.0 (fixed v0.34.0); CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7225576Z ADVISORY app ghcr.io/lukegus/termix 2.8.0 GHSA-6gr3-r7jx-wfmh (fixed >= 26.10.0); GHSA-frx8-qqgg-7j7g (fixed >= 26.10.0); GHSA-3q2m-5r5p-w45r (fixed >= 26.10.0); GHSA-rgf3-2q88-q4wp (fixed >= 26.10.0); … 9 more
2026-10-28T03:42:15.7225737Z ADVISORY app ghcr.io/paperless-ngx/paperless-ngx 2.20.15 GHSA-c8f3-pqr2-rr24 (fixed 3.3.2); GHSA-2jhj-xqrq-rmrq (fixed 3.1.2); CVE-2026-111497 (fixed 1.1.1)
2026-10-28T03:42:15.7225906Z ADVISORY app ghcr.io/papra-hq/papra 26.6.2-rootless CVE-2026-111497 (fixed 26.12.1)
2026-10-28T03:42:15.7226028Z ADVISORY app ghcr.io/seanmorley15/adventurelog-backend v0.13.0 release:seanmorley15/AdventureLog@v0.13.1 (fixed v0.13.1)
2026-10-28T03:42:15.7226162Z ADVISORY app ghcr.io/seanmorley15/adventurelog-frontend v0.13.0 release:seanmorley15/AdventureLog@v0.13.1 (fixed v0.13.1); CVE-2026-111497 (fixed 26.12.1)
2026-10-28T03:42:15.7226383Z ADVISORY app ghcr.io/tandoorrecipes/recipes 2.6.15 GHSA-5f74-7rgh-pc97 (fixed a version after 2.6.15 (the notice names none)); GHSA-pcq2-64qw-jm4x (fixed no fixed version named yet); GHSA-69q3-5q6x-7hmx (fixed no fixed version named yet); GHSA-xq7g-9q95-vjc6 (fixed a version after 2.6.15 (the notice names none)); … 7 more
2026-10-28T03:42:15.7226613Z ADVISORY app ghost 6.67.0-alpine CVE-2026-111497 (fixed 22.23.4)
2026-10-28T03:42:15.7226803Z ADVISORY app gitea/gitea 1.27.3 GHSA-wx44-9m3m-rjqx (fixed 28.2.0); GHSA-4jmf-h2cm-hg7w (fixed 28.2.0); GHSA-8j56-f865-gqq2 (fixed 28.2.0); GHSA-fxq4-gr55-7x5g (fixed 28.2.0); … 37 more
2026-10-28T03:42:15.7226959Z ADVISORY app glanceapp/glance v0.8.5 GHSA-r225-jhr6-68cc (fixed >= 0.8.7)
2026-10-28T03:42:15.7227132Z ADVISORY app grafana/grafana 13.2.4 GHSA-8xmm-x63g-f6xv (fixed no fixed version named yet); GHSA-4724-7jwc-3fpw (fixed the range is unreadable — check by hand); GHSA-2x6g-h2hg-rq84 (fixed the range is unreadable — check by hand); GHSA-8wjh-59cw-9xh4 (fixed no fixed version named yet); … 2 more
2026-10-28T03:42:15.7227311Z ADVISORY app louislam/uptime-kuma 2.5.7 GHSA-qjxc-h5jf-c7rj (fixed the range is unreadable — check by hand); release:louislam/uptime-kuma@2.5.8 (fixed 2.5.8)
2026-10-28T03:42:15.7227461Z ADVISORY app n8nio/n8n 2.44.7 GHSA-365g-vjw2-grx8 (fixed no fixed version named yet)
2026-10-28T03:42:15.7227594Z ADVISORY app rommapp/romm 5.4.1 CVE-2026-111497 (fixed 24.22.1)
2026-10-28T03:42:15.7227725Z NOT CHECKED doop gitea.dooplex.hu/admin/felhom-act-runner 0.1.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T03:42:15.7228028Z NOT CHECKED doop gitea.dooplex.hu/admin/jarr latest registry gitea.dooplex.hu: no anonymous token route
2026-10-28T03:42:15.7228163Z NOT CHECKED doop gitea.dooplex.hu/admin/recipe-importer latest registry gitea.dooplex.hu: no anonymous token route
2026-10-28T03:42:15.7228306Z NOT CHECKED doop gitea.dooplex.hu/admin/revfulop-calendar 1.6.2 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T03:42:15.7228430Z NOT CHECKED doop gitea.dooplex.hu/admin/sparkyfitness-export 0.3.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T03:42:15.7228564Z NOT CHECKED doop gitea.dooplex.hu/admin/wan-probe 0.1.0 registry gitea.dooplex.hu: no anonymous token route
2026-10-28T03:42:15.7228704Z NOT CHECKED doop linuxserver/sonarr version-4.0.20.3014 Docker Hub tags of linuxserver/sonarr: HTTP 429
2026-10-28T03:42:15.7228830Z NOT CHECKED doop mikefarah/yq 4.54.1 Docker Hub tags of mikefarah/yq: HTTP 429
2026-10-28T03:42:15.7229054Z NOT CHECKED doop minio/minio latest Docker Hub tags of minio/minio: HTTP 429; manifest minio/minio:latest: HTTP 401
2026-10-28T03:42:15.7229183Z NOT CHECKED doop mongodb/mongodb-community-server 8.0.5-ubuntu2204 Docker Hub tags of mongodb/mongodb-community-server: HTTP 429
2026-10-28T03:42:15.7229390Z NOT CHECKED doop msdeluise/plant-it-server 0.10.0 Docker Hub tags of msdeluise/plant-it-server: HTTP 429
2026-10-28T03:42:15.7229544Z NOT CHECKED doop mysql 8.4 Docker Hub tags of library/mysql: HTTP 429
2026-10-28T03:42:15.7229682Z NOT CHECKED doop nicolaka/netshoot latest Docker Hub tags of nicolaka/netshoot: HTTP 429
2026-10-28T03:42:15.7230430Z NOT CHECKED doop privatebin/nginx-fpm-alpine 2.0.6 Docker Hub tags of privatebin/nginx-fpm-alpine: HTTP 429
2026-10-28T03:42:15.7230619Z NOT CHECKED doop prom/alertmanager v0.34.1 Docker Hub tags of prom/alertmanager: HTTP 429
2026-10-28T03:42:15.7230824Z NOT CHECKED doop prom/node-exporter v1.12.1 Docker Hub tags of prom/node-exporter: HTTP 429
2026-10-28T03:42:15.7230961Z NOT CHECKED doop prom/prometheus v3.15.0 Docker Hub tags of prom/prometheus: HTTP 429
2026-10-28T03:42:15.7231106Z NOT CHECKED doop prometheuscommunity/smartctl-exporter v0.15.0 Docker Hub tags of prometheuscommunity/smartctl-exporter: HTTP 429
2026-10-28T03:42:15.7231240Z NOT CHECKED doop python 3.15-bookworm Docker Hub tags of library/python: HTTP 429
2026-10-28T03:42:15.7231394Z NOT CHECKED doop renovate/renovate 44.181.1 Docker Hub tags of renovate/renovate: HTTP 429
2026-10-28T03:42:15.7231559Z NOT CHECKED doop tailscale/tailscale v1.104.2 Docker Hub tags of tailscale/tailscale: HTTP 429
2026-10-28T03:42:15.7231701Z NOT CHECKED app lscr.io/linuxserver/sonarr 4.0.20 https://hub.docker.com/v2/repositories/linuxserver/sonarr/tags: The read operation timed out
2026-10-28T03:42:15.7231846Z BEHIND doop getmeili/meilisearch v1.11.3 newest v1.56.0
2026-10-28T03:42:15.7231966Z BEHIND doop ghcr.io/diced/zipline 4.8.1 newest 4.8.2
2026-10-28T03:42:15.7232100Z BEHIND app getmeili/meilisearch v1.41.0 newest v1.56.0
2026-10-28T03:42:15.7232262Z BEHIND app getmeili/meilisearch v1.36.0 newest v1.56.0
2026-10-28T03:42:15.7232393Z BEHIND app ghcr.io/hargata/lubelogger v1.7.3 newest v1.7.4
2026-10-28T03:42:15.7232538Z BEHIND app ghcr.io/kozea/radicale 3.8.1 newest 3.9.0
2026-10-28T03:42:15.7232666Z BEHIND app gotson/komga 1.28.0 newest 1.29.2
2026-10-28T03:42:15.7232788Z BEHIND app kimai/kimai2 2.67.0 newest 2.71.0
2026-10-28T03:42:15.7232902Z BEHIND app lscr.io/linuxserver/bookstack 26.09.2 newest 26.09.20260929
2026-10-28T03:42:15.7233054Z BEHIND app nextcloud 34.0.4-apache newest 34.0.5-apache
2026-10-28T03:42:15.7233178Z BEHIND app nginx 1.30.5-alpine newest 1.31.8-alpine
2026-10-28T03:42:15.7233298Z BEHIND app qbittorrentofficial/qbittorrent-nox 5.2.4-1 newest 5.3.0-2
2026-10-28T03:42:15.7233424Z GAP buil alpine 3.24.2 newest 3.24.3
2026-10-28T03:42:15.7233548Z GAP buil alpine 3.24.2 newest 3.24.3
2026-10-28T03:42:15.7233664Z GAP doop alpine/k8s 1.37.1
2026-10-28T03:42:15.7233814Z GAP doop arcadiatechnology/crafty-4 4.11.0
2026-10-28T03:42:15.7233939Z GAP doop bhgedigital/envsubst latest
2026-10-28T03:42:15.7234057Z GAP doop busybox 1.38
2026-10-28T03:42:15.7234173Z GAP doop codercom/code-server 4.143.1
2026-10-28T03:42:15.7234329Z GAP buil debian 13.7-slim
2026-10-28T03:42:15.7234566Z GAP buil debian 13.7-slim
2026-10-28T03:42:15.7234808Z GAP doop docker.io/bitnamilegacy/postgresql 17.6.0-debian-12-r3
2026-10-28T03:42:15.7235046Z GAP doop docker.io/library/nextcloud 34.0.5-apache
2026-10-28T03:42:15.7235268Z GAP doop docker.io/valkey/valkey 9.2-alpine
2026-10-28T03:42:15.7235388Z GAP doop filebrowser/filebrowser v2.63.23
2026-10-28T03:42:15.7235507Z GAP doop ghcr.io/cloudnative-pg/postgresql 17.2 newest 17.11
2026-10-28T03:42:15.7235668Z GAP doop ghcr.io/headlamp-k8s/headlamp v0.46.0
2026-10-28T03:42:15.7235787Z GAP doop ghcr.io/immich-app/postgres 16-vectorchord0.3.0
2026-10-28T03:42:15.7235926Z GAP doop ghcr.io/jimmidyson/configmap-reload v0.15.0
2026-10-28T03:42:15.7236042Z GAP doop ghcr.io/onedr0p/exportarr v2.3.0
2026-10-28T03:42:15.7236206Z GAP doop ghcr.io/seerr-team/seerr v3.5.1
2026-10-28T03:42:15.7236329Z GAP doop ghcr.io/seriousm4x/upsnap 5
2026-10-28T03:42:15.7236443Z GAP doop ghcr.io/stakater/reloader v1.4.22 newest v1.4.23
2026-10-28T03:42:15.7236591Z GAP doop ghcr.io/tautulli/tautulli v2.18.2
2026-10-28T03:42:15.7236800Z GAP doop griefed/serverpackcreator 8.1.2
2026-10-28T03:42:15.7237002Z GAP doop gtstef/filebrowser 1.5.8-stable
2026-10-28T03:42:15.7237126Z GAP doop guacamole/guacamole 1.6.0
2026-10-28T03:42:15.7237300Z GAP doop guacamole/guacd 1.6.0
2026-10-28T03:42:15.7237434Z GAP doop index.docker.io/plexinc/pms-docker 1.43.5.11029-6bf8af3f0
2026-10-28T03:42:15.7237638Z GAP doop itzg/mc-backup 2026.10.1 newest 2026.10.2
2026-10-28T03:42:15.7237758Z GAP doop itzg/minecraft-server 2026.10.0-java21 newest 2026.10.1-java17
2026-10-28T03:42:15.7237883Z GAP doop linuxserver/bookstack 26.09.20260929
2026-10-28T03:42:15.7238012Z GAP doop linuxserver/prowlarr version-2.6.5.5623
2026-10-28T03:42:15.7238130Z GAP doop linuxserver/qbittorrent 5.3.0
2026-10-28T03:42:15.7238255Z GAP doop linuxserver/radarr version-6.4.4.10685
2026-10-28T03:42:15.7238369Z GAP doop mariadb 11
2026-10-28T03:42:15.7238484Z GAP doop postgis/postgis 16-3.5
2026-10-28T03:42:15.7238592Z GAP doop postgres 15-alpine
2026-10-28T03:42:15.7238705Z GAP doop postgres 16-alpine
2026-10-28T03:42:15.7238815Z GAP doop quay.io/jetstack/version-checker v0.11.0
2026-10-28T03:42:15.7238925Z GAP doop quay.io/prometheus/blackbox-exporter v0.29.1
2026-10-28T03:42:15.7239181Z GAP app emby/embyserver 4.11.0.4 newest 4.11.0.11
2026-10-28T03:42:15.7239348Z GAP app ghcr.io/immich-app/postgres 16-vectorchord0.4.3-pg
2026-10-28T03:42:15.7239472Z GAP app ghcr.io/karakeep-app/karakeep-chrome 151.0.7922.47-r1
2026-10-28T03:42:15.7239647Z GAP app mariadb 12.3
2026-10-28T03:42:15.7239779Z GAP app mariadb 11.4 newest 11.8
2026-10-28T03:42:15.7239902Z GAP app mariadb 11.8
2026-10-28T03:42:15.7240014Z GAP app mariadb 12.3
2026-10-28T03:42:15.7240135Z GAP app mariadb 11.8
2026-10-28T03:42:15.7240246Z GAP app msdeluise/plant-it 0.10.0
2026-10-28T03:42:15.7240358Z GAP app plexinc/pms-docker 1.43.5.11029-6bf8af3f0
2026-10-28T03:42:15.7240468Z GAP app postgis/postgis 16-3.5-alpine
2026-10-28T03:42:15.7240576Z GAP app postgis/postgis 17-3.5-alpine
2026-10-28T03:42:15.7240690Z GAP app postgres 18-alpine
2026-10-28T03:42:15.7240798Z GAP app postgres 17-alpine
2026-10-28T03:42:15.7240962Z GAP app postgres 18-alpine
2026-10-28T03:42:15.7241074Z GAP app postgres 18-alpine
2026-10-28T03:42:15.7241185Z GAP app postgres 18-alpine
2026-10-28T03:42:15.7241294Z GAP app postgres 18-alpine
2026-10-28T03:42:15.7241403Z GAP app postgres 18-alpine
2026-10-28T03:42:15.7241514Z GAP app postgres 17-alpine
2026-10-28T03:42:15.7241620Z GAP app postgres 16-alpine
2026-10-28T03:42:15.7241939Z GAP app registry.gitlab.com/crafty-controller/crafty-4 4.11.0
2026-10-28T03:42:15.7242058Z FLOATING doop ghcr.io/seanmorley15/adventurelog-backend latest
2026-10-28T03:42:15.7242176Z FLOATING doop ghcr.io/seanmorley15/adventurelog-frontend latest
2026-10-28T03:42:15.7242386Z FLOATING doop nginx 1.31-alpine
2026-10-28T03:42:15.7242496Z FLOATING doop redis 8-alpine
2026-10-28T03:42:15.7242674Z FLOATING doop redis 8.10-alpine
2026-10-28T03:42:15.7242787Z FLOATING app ghcr.io/claperco/claper 2.5
2026-10-28T03:42:15.7242935Z FLOATING app ghcr.io/thomiceli/opengist 1.15
2026-10-28T03:42:15.7243042Z FLOATING app jellyfin/jellyfin 12.4
2026-10-28T03:42:15.7243153Z FLOATING app lscr.io/linuxserver/prowlarr version-2.6.5.5623
2026-10-28T03:42:15.7243293Z FLOATING app lscr.io/linuxserver/sabnzbd version-5.1.3
2026-10-28T03:42:15.7243399Z FLOATING app lscr.io/linuxserver/transmission version-4.1.3-r0
2026-10-28T03:42:15.7243507Z FLOATING app nzbgetcom/nzbget v26.3
2026-10-28T03:42:15.7243614Z FLOATING app redis 7.4-alpine
2026-10-28T03:42:15.7243803Z FLOATING app redis 7-alpine
2026-10-28T03:42:15.7243996Z FLOATING app redis 7-alpine
2026-10-28T03:42:15.7244149Z FLOATING app redis 7-alpine
2026-10-28T03:42:15.7244417Z FLOATING app redis 7-alpine
2026-10-28T03:42:15.7244528Z FLOATING app redis 7-alpine
2026-10-28T03:42:15.7244741Z FLOATING app redis 7-alpine
2026-10-28T03:42:15.7244913Z FLOATING app wger/server 2.7
2026-10-28T03:42:15.7245044Z SELF box gitea.dooplex.hu/admin/felhom-samba 1.2.0
2026-10-28T03:42:15.7245151Z SELF app gitea.dooplex.hu/admin/recipe-importer v0.9.11
2026-10-28T03:42:15.7245266Z CURRENT doop codewithcj/sparkyfitness v1.9.0
2026-10-28T03:42:15.7245378Z CURRENT doop f0rc3/gokapi v2.2.4
2026-10-28T03:42:15.7245493Z CURRENT doop ghcr.io/alam00000/bentopdf 2.8.10
2026-10-28T03:42:15.7245605Z CURRENT doop ghcr.io/thomiceli/opengist 1.15.3
2026-10-28T03:42:15.7245712Z CURRENT doop glanceapp/glance v0.8.7
2026-10-28T03:42:15.7245830Z CURRENT buil golang 1.27.3-trixie
2026-10-28T03:42:15.7246008Z CURRENT buil golang 1.27.3-alpine3.24
2026-10-28T03:42:15.7246128Z CURRENT doop onlyoffice/documentserver 9.4.0
2026-10-28T03:42:15.7246244Z CURRENT buil restic 0.19.1
2026-10-28T03:42:15.7246359Z CURRENT box traefik v3.7.16
2026-10-28T03:42:15.7246469Z CURRENT doop vaultwarden/server 1.37.4
2026-10-28T03:42:15.7246576Z CURRENT app deluan/navidrome 0.64.2
2026-10-28T03:42:15.7246692Z CURRENT app docmost/docmost 0.97.0
2026-10-28T03:42:15.7246802Z CURRENT app ghcr.io/advplyr/audiobookshelf 2.37.2
2026-10-28T03:42:15.7246978Z CURRENT app ghcr.io/alam00000/bentopdf v2.8.10
2026-10-28T03:42:15.7247177Z CURRENT app ghcr.io/cmintey/wishlist v0.69.0
2026-10-28T03:42:15.7247296Z CURRENT app ghcr.io/gramps-project/grampsweb v25.6.0
2026-10-28T03:42:15.7247418Z CURRENT app ghcr.io/grimmory-tools/grimmory v3.5.0
2026-10-28T03:42:15.7247594Z CURRENT app ghcr.io/mealie-recipes/mealie v3.29.0
2026-10-28T03:42:15.7247746Z CURRENT app ghcr.io/sysadminsmedia/homebox 0.27.1
2026-10-28T03:42:15.7247858Z CURRENT app lscr.io/linuxserver/code-server 4.143.1
2026-10-28T03:42:15.7247966Z CURRENT app lscr.io/linuxserver/grocy 4.7.1
2026-10-28T03:42:15.7248220Z CURRENT app lscr.io/linuxserver/radarr 6.4.4
2026-10-28T03:42:15.7248424Z CURRENT app lukevella/rallly 4.16.3
2026-10-28T03:42:15.7248536Z CURRENT app onlyoffice/documentserver 9.4.0
2026-10-28T03:42:15.7248649Z CURRENT app outlinewiki/outline 1.12.0
2026-10-28T03:42:15.7248802Z CURRENT app privatebin/pdo 2.1.0
2026-10-28T03:42:15.7248915Z CURRENT app vaultwarden/server 1.37.4-alpine
2026-10-28T03:42:15.7249085Z CURRENT app vikunja/vikunja 2.7.1
2026-10-28T03:42:15.7249229Z COUNTS ADVISORY=51 BEHIND=12 CURRENT=29 FLOATING=20 GAP=61 NOT_CHECKED=22 SELF=2
2026-10-28T03:42:15.7249414Z REQUESTS api.github.com=71 api.osv.dev=1 blog.cloudflare.com=1 ghcr.io=174 github.com=64 hub.docker.com=211 raw.githubusercontent.com=1
2026-10-28T03:42:16.5211202Z MAIL RESEND-ACCEPTED id=01a18099-f665-75b7-9940-1fa0a1a7a500 kind=advisory subject=[Felhom security] cloudflared, filebrowser, cal.com, sparkyfitness … — 198 new advisories
2026-10-28T03:42:16.7734211Z MAIL RESEND-ACCEPTED id=01a18099-f846-7018-b995-78e039a7c71b kind=not_checked subject=[Felhom security] the watch could not check registry:docker.io
2026-10-28T03:42:16.7971703Z STATE written: documentation/security-watch/state.json (325 known advisories)
2026-10-28T03:42:16.8539518Z ::group::Run set -u
2026-10-28T03:42:16.8539956Z set -u
2026-10-28T03:42:16.8540303Z f=documentation/security-watch/state.json
2026-10-28T03:42:16.8540529Z if [ ! -f "$f" ]; then
2026-10-28T03:42:16.8540732Z echo "no memory file was written - nothing to commit"; exit 0
2026-10-28T03:42:16.8541128Z fi
2026-10-28T03:42:16.8541460Z if git ls-files --error-unmatch "$f" >/dev/null 2>&1 && git diff --quiet -- "$f"; then
2026-10-28T03:42:16.8541717Z echo "memory unchanged - nothing to commit"; exit 0
2026-10-28T03:42:16.8541934Z fi
2026-10-28T03:42:16.8542185Z cp "$f" /tmp/state.json
2026-10-28T03:42:16.8542385Z auth=$(python3 -c 'import base64,os;print(base64.b64encode(("x:"+os.environ["PUSH_TOKEN"]).encode()).decode())')
2026-10-28T03:42:16.8542639Z for attempt in 1 2 3; do
2026-10-28T03:42:16.8543110Z git fetch -q --depth 1 origin main && git checkout -q -B main FETCH_HEAD
2026-10-28T03:42:16.8543362Z mkdir -p "$(dirname "$f")" && cp /tmp/state.json "$f"
2026-10-28T03:42:16.8543581Z git add "$f"
2026-10-28T03:42:16.8543778Z git -c user.name="felhom security watch" -c user.email=monitoring@felhom.eu \
2026-10-28T03:42:16.8544074Z commit -q -m "security-watch: memory of $(date -u +%F) (R-1303). Docs only." || { echo "nothing to commit"; exit 0; }
2026-10-28T03:42:16.8544358Z if git -c http.extraHeader="Authorization: Basic $auth" push -q origin HEAD:main; then
2026-10-28T03:42:16.8544587Z echo "memory pushed: $(git rev-parse --short=12 HEAD)"; exit 0
2026-10-28T03:42:16.8544860Z fi
2026-10-28T03:42:16.8545057Z echo "push refused (attempt $attempt) - re-fetching main"
2026-10-28T03:42:16.8545451Z sleep 5
2026-10-28T03:42:16.8545659Z done
2026-10-28T03:42:16.8545898Z echo "MEMORY NOT SAVED after 3 attempts"; exit 1
2026-10-28T03:42:16.8546111Z shell: bash --noprofile --norc -e -o pipefail {0}
2026-10-28T03:42:16.8546355Z env:
2026-10-28T03:42:16.8546835Z PUSH_TOKEN: ***
2026-10-28T03:42:16.8547181Z ::endgroup::
2026-10-28T03:42:18.2521180Z remote: . Processing 1 references
2026-10-28T03:42:18.2522785Z remote: Processed 1 references in total
2026-10-28T03:42:18.2588253Z memory pushed: 9b4b5fe5e7f7
2026-10-28T03:42:18.2608654Z Cleaning up container for job watch
2026-10-28T03:42:18.8472537Z 🏁 Job succeeded
@@ -0,0 +1,16 @@
RESTORED-IDENTICAL
26: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
2026/10/28 17:21:37 sync.go:535: [INFO] [sync] Updated wanderer/.felhom.yml
2026/10/28 17:21:37 sync.go:535: [INFO] [sync] Updated zipline/docker-compose.yml
2026/10/28 17:21:37 sync.go:535: [INFO] [sync] Updated zipline/.felhom.yml
2026/10/28 17:21:37 sync.go:261: [INFO] [sync] catalog moved dff3cb84fcea -> 9ef06a7a891f (0 new, 14 stack dir(s) changed)
2026/10/28 17:21:38 sync.go:299: [INFO] [sync] Catalog sync complete
2026/10/28 17:21:38 sync.go:142: [INFO] [sync] Initial sync: Sablonok frissítve — frissítve: adventurelog, dawarich, ghost, home-assistant, homepage, immich, karakeep, metube, papra, seerr, tandoo
26: repo_url: https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
-rw------- 1 root root 1994 Oct 22 14:47 /var/lib/docker/volumes/felhom-controller-data/_data/controller.yaml.pre-release1026-drill
mirror main dff3cb84fc
cache HEAD 9ef06a7
https://gitea.dooplex.hu/admin/app-catalog-felhom.eu.git
@@ -0,0 +1,35 @@
[15:23:46] scratch drive folders cleared before FROM (R-656): none existed
[15:23:46] MV-seerr: deploying seerr at FROM {'seerr': 'fallenbagel/jellyseerr:2.7.3'}
[15:24:17] FROM settled=True in 30.9s :: {"seerr": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[15:24:17] fixture: the BOX walk's own (Seerr), through upgrade_boxport
[15:24:22] seerr: throwaway Jellyfin on traefik-public: user=503 complete=503
[15:24:22] seerr: first sign-in through Jellyfin http=500 cookie=False
[15:24:22] INCONCLUSIVE — no non-browser seed route. Nothing was planted by hand.
{
"harness_version": 5,
"edge": "MV-seerr",
"app": "seerr",
"note": "definition step to seerr-v3",
"from": {
"seerr": "fallenbagel/jellyseerr:2.7.3"
},
"to": {
"seerr": "ghcr.io/seerr-team/seerr:v3.5.1"
},
"verdict": "inconclusive",
"seed_read_before": false,
"seed_read_after": false,
"healthy_after": false,
"migration_observed": null,
"abort": "not-attempted",
"abort_detail": "no non-browser seed route",
"engine_state_after": null,
"memory": null,
"marks": [],
"bench_overrides": null,
"duration_s": 35.8,
"measured_at": "2026-10-28T15:24:22Z",
"evidence": "evidence/MV-seerr",
"scratch_cleared": [],
"total_s": 35.8
}
@@ -0,0 +1,24 @@
seerr |
seerr | > jellyseerr@2.7.3 start /app
seerr | > NODE_ENV=production node dist/index.js
seerr |
seerr | 2026-10-28T15:23:50.009Z [info]: Commit Tag: $GIT_SHA
seerr | 2026-10-28T15:23:50.602Z [info]: Starting Jellyseerr version 2.7.3
seerr | 2026-10-28T15:23:51.718Z [info][Notifications]: Registered notification agents
seerr | 2026-10-28T15:23:51.725Z [info][Server]: Skipping starting the scheduled jobs as we have no Plex/Jellyfin/Emby servers setup yet
seerr | 2026-10-28T15:23:51.731Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":1,"enabled":true,"isBuiltIn":true,"order":0}}
seerr | 2026-10-28T15:23:51.752Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":2,"enabled":true,"isBuiltIn":true,"order":1}}
seerr | 2026-10-28T15:23:51.759Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":3,"enabled":true,"isBuiltIn":true,"order":2}}
seerr | 2026-10-28T15:23:51.766Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":4,"enabled":true,"isBuiltIn":true,"order":3}}
seerr | 2026-10-28T15:23:51.773Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":5,"enabled":true,"isBuiltIn":true,"order":4}}
seerr | 2026-10-28T15:23:51.784Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":6,"enabled":true,"isBuiltIn":true,"order":5}}
seerr | 2026-10-28T15:23:51.790Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":7,"enabled":true,"isBuiltIn":true,"order":6}}
seerr | 2026-10-28T15:23:51.796Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":8,"enabled":true,"isBuiltIn":true,"order":7}}
seerr | 2026-10-28T15:23:51.803Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":9,"enabled":true,"isBuiltIn":true,"order":8}}
seerr | 2026-10-28T15:23:51.810Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":10,"enabled":true,"isBuiltIn":true,"order":9}}
seerr | 2026-10-28T15:23:51.816Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":11,"enabled":true,"isBuiltIn":true,"order":10}}
seerr | 2026-10-28T15:23:51.822Z [info][Discover Slider]: Creating built-in discovery slider {"slider":{"type":12,"enabled":true,"isBuiltIn":true,"order":11}}
seerr | 2026-10-28T15:23:52.024Z [info][Server]: Server ready on port 5055
seerr | 2026-10-28T15:24:22.415Z [debug][Jellyfin API]: Failed to authenticate with headers {"error":"Service Unavailable","ip":"172.18.0.1"}
seerr | 2026-10-28T15:24:22.424Z [error][Jellyfin API]: Something went wrong while authenticating with the Jellyfin server: Request failed with status code 503 {"error":503,"ip":"172.18.0.1"}
seerr | 2026-10-28T15:24:22.424Z [error][Auth]:
@@ -0,0 +1,7 @@
[15:23:46] scratch drive folders cleared before FROM (R-656): none existed
[15:23:46] MV-seerr: deploying seerr at FROM {'seerr': 'fallenbagel/jellyseerr:2.7.3'}
[15:24:17] FROM settled=True in 30.9s :: {"seerr": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[15:24:17] fixture: the BOX walk's own (Seerr), through upgrade_boxport
[15:24:22] seerr: throwaway Jellyfin on traefik-public: user=503 complete=503
[15:24:22] seerr: first sign-in through Jellyfin http=500 cookie=False
[15:24:22] INCONCLUSIVE — no non-browser seed route. Nothing was planted by hand.
@@ -0,0 +1,28 @@
{
"harness_version": 5,
"edge": "MV-seerr",
"app": "seerr",
"note": "definition step to seerr-v3",
"from": {
"seerr": "fallenbagel/jellyseerr:2.7.3"
},
"to": {
"seerr": "ghcr.io/seerr-team/seerr:v3.5.1"
},
"verdict": "inconclusive",
"seed_read_before": false,
"seed_read_after": false,
"healthy_after": false,
"migration_observed": null,
"abort": "not-attempted",
"abort_detail": "no non-browser seed route",
"engine_state_after": null,
"memory": null,
"marks": [],
"bench_overrides": null,
"duration_s": 35.8,
"measured_at": "2026-10-28T15:24:22Z",
"evidence": "evidence/MV-seerr",
"scratch_cleared": [],
"total_s": 35.8
}
@@ -0,0 +1,115 @@
[15:24:47] scratch drive folders cleared before FROM (R-656): none existed
[15:24:47] MV-seerr: deploying seerr at FROM {'seerr': 'fallenbagel/jellyseerr:2.7.3'}
[15:25:18] FROM settled=True in 30.8s :: {"seerr": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[15:25:18] fixture: the BOX walk's own (Seerr), through upgrade_boxport
[15:25:30] seerr: throwaway Jellyfin on traefik-public: user=204 complete=204
[15:25:31] seerr: admin drilld5609dd3 signed in through Jellyfin; application title stored http=200
[15:25:32] seerr: the title read back True; sign-in http=200 (wrong password refused: http 401) ok=True
[15:25:32] C1 (seed reads back BEFORE): True
[15:25:32] MV-seerr: swapping to TO {'seerr': 'ghcr.io/seerr-team/seerr:v3.5.1'}
[15:25:33] TO up -d rc=0
[15:26:04] TO settled=True in 31.0s :: {"seerr": {"status": "running", "health": "healthy", "restarts": 0, "exit": 0}}
[15:26:04] migration lines observed: 6
[15:26:05] seerr: the title read back True; sign-in http=200 (wrong password refused: http 401) ok=True
[15:26:05] RESULT (seed reads back AFTER): True
[15:26:05] memory watch: 600s, 4 callers on 1 path(s) at 172.18.0.2:5055
[15:26:21] + 15s seerr=207M/384M peak=209M kills=0 rs=0 reqs=285
[15:26:36] + 30s seerr=208M/384M peak=209M kills=0 rs=0 reqs=572
[15:26:51] + 45s seerr=208M/384M peak=211M kills=0 rs=0 reqs=860
[15:27:06] + 60s seerr=208M/384M peak=211M kills=0 rs=0 reqs=1145
[15:27:21] + 76s seerr=208M/384M peak=211M kills=0 rs=0 reqs=1435
[15:27:36] + 91s seerr=207M/384M peak=211M kills=0 rs=0 reqs=1721
[15:27:51] + 106s seerr=207M/384M peak=212M kills=0 rs=0 reqs=2010
[15:28:06] + 121s seerr=208M/384M peak=212M kills=0 rs=0 reqs=2300
[15:28:22] + 136s seerr=207M/384M peak=212M kills=0 rs=0 reqs=2589
[15:28:37] + 151s seerr=207M/384M peak=212M kills=0 rs=0 reqs=2877
[15:28:52] + 166s seerr=208M/384M peak=217M kills=0 rs=0 reqs=3165
[15:29:07] + 182s seerr=210M/384M peak=217M kills=0 rs=0 reqs=3457
[15:29:22] + 197s seerr=210M/384M peak=217M kills=0 rs=0 reqs=3745
[15:29:37] + 212s seerr=209M/384M peak=217M kills=0 rs=0 reqs=4033
[15:29:52] + 227s seerr=209M/384M peak=217M kills=0 rs=0 reqs=4325
[15:30:07] + 242s seerr=215M/384M peak=220M kills=0 rs=0 reqs=4603
[15:30:23] + 257s seerr=221M/384M peak=225M kills=0 rs=0 reqs=4892
[15:30:38] + 272s seerr=223M/384M peak=225M kills=0 rs=0 reqs=5183
[15:30:53] + 287s seerr=222M/384M peak=228M kills=0 rs=0 reqs=5471
[15:31:08] + 302s seerr=223M/384M peak=228M kills=0 rs=0 reqs=5763
[15:31:23] + 318s seerr=223M/384M peak=229M kills=0 rs=0 reqs=6051
[15:31:38] + 333s seerr=223M/384M peak=229M kills=0 rs=0 reqs=6339
[15:31:53] + 348s seerr=223M/384M peak=229M kills=0 rs=0 reqs=6631
[15:32:08] + 363s seerr=222M/384M peak=229M kills=0 rs=0 reqs=6919
[15:32:24] + 378s seerr=223M/384M peak=229M kills=0 rs=0 reqs=7210
[15:32:39] + 393s seerr=222M/384M peak=229M kills=0 rs=0 reqs=7499
[15:32:54] + 408s seerr=223M/384M peak=229M kills=0 rs=0 reqs=7787
[15:33:09] + 424s seerr=223M/384M peak=229M kills=0 rs=0 reqs=8079
[15:33:24] + 439s seerr=223M/384M peak=229M kills=0 rs=0 reqs=8367
[15:33:39] + 454s seerr=223M/384M peak=229M kills=0 rs=0 reqs=8656
[15:33:54] + 469s seerr=223M/384M peak=229M kills=0 rs=0 reqs=8947
[15:34:09] + 484s seerr=223M/384M peak=229M kills=0 rs=0 reqs=9235
[15:34:25] + 499s seerr=223M/384M peak=229M kills=0 rs=0 reqs=9527
[15:34:40] + 514s seerr=223M/384M peak=229M kills=0 rs=0 reqs=9815
[15:34:55] + 529s seerr=223M/384M peak=229M kills=0 rs=0 reqs=10104
[15:35:10] + 545s seerr=223M/384M peak=229M kills=0 rs=0 reqs=10395
[15:35:25] + 560s seerr=223M/384M peak=229M kills=0 rs=0 reqs=10685
[15:35:40] + 575s seerr=223M/384M peak=229M kills=0 rs=0 reqs=10975
[15:35:55] + 590s seerr=223M/384M peak=229M kills=0 rs=0 reqs=11265
[15:36:11] + 605s seerr=223M/384M peak=229M kills=0 rs=0 reqs=11555
[15:36:11] memory watch: killed=False tight=[] requests=11555 codes={'307': 11555}
[15:36:11] MV-seerr: ABORT — putting the FROM images back
[15:36:43] seerr: the title read back True; sign-in http=500 (wrong password refused: http 500) ok=False
[15:36:43] ABORT: app came back in 30.9s; data present=False
{
"harness_version": 5,
"edge": "MV-seerr",
"app": "seerr",
"note": "definition step to seerr-v3",
"from": {
"seerr": "fallenbagel/jellyseerr:2.7.3"
},
"to": {
"seerr": "ghcr.io/seerr-team/seerr:v3.5.1"
},
"verdict": "proven",
"seed_read_before": true,
"seed_read_after": true,
"healthy_after": true,
"migration_observed": "\u001b[2Kseerr | 2026-10-28T15:25:39.146Z [\u001b[34mdebug\u001b[39m][Settings Migrator]: Checking migration '0001_migrate_hostname.js'...",
"abort": "starts-data-gone",
"abort_detail": "the app started but the seeded data was gone",
"engine_state_after": null,
"memory": {
"soak_s": 605.3,
"requested_s": 600,
"requests": 11555,
"codes": {
"307": 11555
},
"first_kill": null,
"containers": {
"seerr": {
"limit": 402653184,
"peak": 240267264,
"peak_pct": 0.597,
"anon_peak_sampled": 206442496,
"anon_peak_pct": 0.513,
"swap_peak": 0,
"oom_kills": 0,
"restarts": 0,
"oomkilled_flag": false,
"measured": true
}
},
"unmeasured": [],
"venue_swap_bytes": 0,
"load": "reached"
},
"marks": [],
"bench_overrides": null,
"duration_s": 31.0,
"measured_at": "2026-10-28T15:36:43Z",
"evidence": "evidence/MV-seerr",
"scratch_cleared": [],
"files_changed": [],
"files_changed_detail": [],
"files_ignored": [],
"total_s": 716.0
}
@@ -0,0 +1,8 @@
{
"seerr": {
"status": "running",
"health": "healthy",
"restarts": 0,
"exit": 0
}
}
@@ -0,0 +1,17 @@
seerr |
seerr | > jellyseerr@2.7.3 start /app
seerr | > NODE_ENV=production node dist/index.js
seerr |
seerr | 2026-10-28T15:36:14.807Z [info]: Commit Tag: $GIT_SHA
seerr | 2026-10-28T15:36:15.338Z [info]: Starting Jellyseerr version 2.7.3
seerr | 2026-10-28T15:36:16.170Z [debug][Settings Migrator]: Checking migration '0001_migrate_hostname.js'...
seerr | 2026-10-28T15:36:16.173Z [debug][Settings Migrator]: Checking migration '0002_migrate_apitokens.js'...
seerr | 2026-10-28T15:36:16.176Z [debug][Settings Migrator]: Checking migration '0003_emby_media_server_type.js'...
seerr | 2026-10-28T15:36:16.178Z [debug][Settings Migrator]: Checking migration '0004_migrate_region_setting.js'...
seerr | 2026-10-28T15:36:16.179Z [debug][Settings Migrator]: Checking migration '0005_migrate_network_settings.js'...
seerr | 2026-10-28T15:36:16.180Z [debug][Settings Migrator]: Checking migration '0006_remove_lunasea.js'...
seerr | 2026-10-28T15:36:16.186Z [info][Notifications]: Registered notification agents
seerr | 2026-10-28T15:36:16.233Z [info][Jobs]: Scheduled jobs loaded
seerr | 2026-10-28T15:36:16.411Z [info][Server]: Server ready on port 5055
seerr | 2026-10-28T15:36:43.306Z [error][Auth]: SQLITE_ERROR: no such column: User_settings.discordId
seerr | 2026-10-28T15:36:43.346Z [error][Auth]: SQLITE_ERROR: no such column: User_settings.discordId
Loaded 100 of 903 files, more files were not shown because too many files have changed in this diff. Show more