From 8143a2c872fb5a00416256ecbc6aa50c86c1c531 Mon Sep 17 00:00:00 2001 From: kisfenyo Date: Mon, 26 Oct 2026 18:07:22 +0100 Subject: [PATCH] =?UTF-8?q?docs:=20record=20D53,=20D54=20and=20R-1297=20(B?= =?UTF-8?q?)=20(09=20=C2=A73=20decisions=20265-267);=20STATUS=20moves=20th?= =?UTF-8?q?e=20two=20picks=20to=20history?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CONTEXT.md | 6 ++++++ STATUS.md | 6 ++---- .../architecture/09-update-architecture.md | 17 +++++++++++++++++ documentation/backlog/OPEN-ITEMS.md | 6 +++--- documentation/backlog/STATUS-HISTORY.md | 9 +++++++++ 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/CONTEXT.md b/CONTEXT.md index 34ca455c..0edb82c7 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -16,6 +16,12 @@ > and holds nothing of its own; this file does hold its own content, namely the standing rulings below. +> **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/` (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, diff --git a/STATUS.md b/STATUS.md index 7ffcdd6c..b1844957 100644 --- a/STATUS.md +++ b/STATUS.md @@ -2,7 +2,7 @@ **Ready for Tester 2? Yes — tell the friend go (hand-over list: `documentation/pilot/TESTER2-handover.md`).** -**Updated 2026-10-26 (afternoon).** A fresh install's whole-box off-site copy no longer fails silently: the cause (PBS's 5-second permission cache) is fixed on ep0, and the hub retries and mails you if it still fails (hub 0.172.0). Every box runs controller 0.345.0: the torrent rule leaves the household's alternative speed alone. Two picks wait for you (D53, D54). +**Updated 2026-10-26 (evening).** You ruled D53 (held apps: reminders to you first) and D54 (demo-hp: one clean-up with a cap of 220), and the second CI runner is in. CC now trims CI, builds the held-app list (commit only), and runs Tuesday's line test. ## What works - **The Plex attack (10-17 → 10-23) did not reach Felhom's secrets** (R-1241). @@ -32,8 +32,6 @@ Newest first. CC's pick is in the „Pick" column. Each row also has its full te | # | Row | Question | Pick (why) | The other option costs | If you do nothing | Blocked | |---|---|---|---|---|---|---| -| D54 | R-1294 | demo-hp's weekly off-site clean-up is stuck: its plan (209 old copies, all from a test day and normal ageing) is above the safety cap (179), and it cannot catch up by itself. Prune it once by hand, or change the cap? | **Prune once** — on your yes, demo-hp gets one clean-up window with a raised cap of 220 through the hub's existing one-shot grant (the plan is honest: every removal is 7–30 days old, every app keeps ≥ 9 copies) | change the cap rule: code in hub + controller, and a weaker guard against a mass deletion | it is refused every Sunday, mails an error each week, and the store grows ~100 copies a week | — | -| D53 | R-1291 | A stopped-and-held app (like Kimai for 11 days) should reach you. Operator-only reminders, or also mail the household for the two holds it can clear itself? | **Operator only first** (the design in `08` §10: a „Held apps" list and a reminder after a grace per reason; ~1.5 days of work) | also the household: two more customer mails to write and translate, and a mail about a stop they may not understand | held apps stay invisible until someone opens the app's page | — | | D38 | R-1235 | Put the newest golden (637 MB) into the nightly release copy on ep0 too? | **Yes** (a new install after a DooPlex loss needs it; it fits under the 3 GB cap) | leave it out: after a loss, no new install until a golden is rebuilt and vouched | the same | — | | D37 | R-1236 | Raise Gitea's memory limit from 1 GiB to 2 GiB? It was killed for memory 4 times in 17 days, once during today's release. | **Yes** (DooPlex has the RAM; a DooPlex change, so yours) | keep 1 GiB: a restart in release hours fails box updates and CI for a minute | the same | — | | D9 | R-1062 | Split the N100's USB drive in two, for multi-drive tests? | **No — keep one drive** (the lived-in box keeps its nightly whole-box backup) | Split: the box loses its local whole-box backup, or you buy a second drive first | it stays one drive; multi-drive tests stay on Tester 1 | — | @@ -50,7 +48,7 @@ Newest first. CC's pick is in the „Pick" column. Each row also has its full te 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. -**2026-10-26.** On the hub's Hosts page, delete `Tester4-b5ec39` (CC's test VM, destroyed). If not: the hub alarms that the box went silent. And a second CI runner on DooPlex (R-1297): if not, jobs queue behind felhom.eu's run. +**2026-10-26.** On the hub's Hosts page, delete `Tester4-b5ec39` (CC's test VM, destroyed). If not: the hub alarms that the box went silent. **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. If not: a dead entry alarms. diff --git a/documentation/architecture/09-update-architecture.md b/documentation/architecture/09-update-architecture.md index acf3c81e..2cbed3df 100644 --- a/documentation/architecture/09-update-architecture.md +++ b/documentation/architecture/09-update-architecture.md @@ -1099,6 +1099,23 @@ its length, and both fixes cost something the household would notice — operato `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. +### 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 diff --git a/documentation/backlog/OPEN-ITEMS.md b/documentation/backlog/OPEN-ITEMS.md index aaa0b7a2..c355638c 100644 --- a/documentation/backlog/OPEN-ITEMS.md +++ b/documentation/backlog/OPEN-ITEMS.md @@ -211,7 +211,7 @@ stopping line that lies. | **R-1232** | Backup & restore | P2 | **A reinstalled box may take its first whole-box copy to ep0 up to a week late: the old box's copy in the same household space seems to count as its last one.** Test night 2026-10-23 (`audits/night-2026-10-23/P4-testnight/`): the new Tester4 box (guest 9201) had its PBS tier applied at 19:28 UTC, but no whole-box run to ep0 came all night; the only archive in the household's ep0 space is the rehearsal box's `ct/9201` of 2026-10-20 (same guest number), and the tier's cadence is 168 h. The agent's due-check reads the newest archive for that vmid on the tier's storage (`localapi/server.go` `newestArchiveOn`) — so the old box's copy reads as „2.6 days old, not due”. If so, the ep0 copy is the OLD box's for up to a week. PLAUSIBLE — read from the code and the night's silence, not proven by a log line (the controller logs the due-check only at debug). | OPEN | — | Prove: read `GET /backup/tiers` for the box (the agent's answer per tier) on the next reinstall; fix: a tier's „last backup” counts only archives this host wrote (or after the host's enrollment); an agent test with a foreign archive in the namespace | CC | | **R-1235** | Backup & restore | P3 | **The release copy on ep0 (D33) is proven to load, not yet to restore a registry — and it follows the newest versions, not the ones the fleet needs.** Built 2026-10-23 (`scripts/release-copy/`, `audits/day-2026-10-23/08-release-copy-D33.txt`). (a) `total-loss-of-dooplex.md` „Restore the release copy” steps 2 (skopeo push back, same digest) and 3 (agent packages back) were never walked into a real new registry — only a `docker load` on 9202. (b) The copy keeps the newest 3 image tags and 5 agent versions; it does not ask the hub for the floor and the vouched agent and always include them — a vouch more than 5 releases behind would fall out. (c) The golden (`felhom-golden`, 637 MB for 0.331.0) is not copied: a new install after a DooPlex loss needs it (the brief named images + agent packages only; one golden fits under the 3 GB cap). | OPEN | — | (a) a throwaway registry on demo-hp, push one tag back, compare digests; (b) read `/configuration`'s floor + vouched agent; (c) the operator says whether the golden goes in | CC | | **R-1263** | Backup & restore | P4 | **Small items from review round 2:** a LOCAL restore's put-back mails the operator „its off-site restore FAILED” (`felhom-controller/controller/cmd/controller/main.go:1514-1518`, shared via `restore_unit.go:517-518`); Remove — even „keep my data” — deletes undeclared volumes labelled with the app's project, which no tier holds (`internal/stacks/delete.go:763-764`, R-1117); the capped copy's `--delete` reads the source in the daemon's mount view, the emptiness check in the controller's (`tier2.go:834` vs `:464`); stale comments — `felhom-agent/internal/localapi/backup_cap.go:15` („keep-last”) and `restore_crash_putback.go:32` (names a test file that does not exist); the qBittorrent password goes to whatever answers the DNS name `qbittorrent` (`upwatch/explain.go:94,108-113`); kept-copy Remove has a check-to-remove gap (`tier2_kept.go:92-111`); the release-copy restore check trusts hashes stored on ep0 (`runbooks/total-loss-of-dooplex.md`); rrsync without `-munge`/`-wo` (`audits/day-2026-10-23/08-release-copy-D33.txt:6`). | OPEN | — | fix in each repo's next attended pass | CC | -| **R-1294** | Backup & restore | P3 | **demo-hp's weekly off-site clean-up was refused by its own guard on 2026-10-26 (window 16): the plan would remove 209 of 359 snapshots, above the week's cap (179) — nothing was deleted, and each refused week adds to the next plan.** Seen in the operator mailbox during the 2026-10-26 release run (03:17Z, `offsite_prune_guard_refused`, error; details `count_before 359, count_after 359, outcome guard-refused`). The cap refusal is kept on purpose (R-824, R-867 closed the false ones); the open question is whether a store that once exceeds the cap can ever prune again by itself, or refuses every week while it grows. demo-hp is the Tier-0 box with many hand-made backups (sweeps, probes). Earlier cap refusals: demo-hp 2026-10-03 (window 1), demo-felhom 2026-10-05 (window 3). | **WAITING-ON-OPERATOR** — 2026-10-26 (read only, `audits/r1294-offsite-cap-2026-10-26/`): the plan is HONEST (restic's own dry-run: keep 150, remove 209; every removal 7–30 days old; every app keeps ≥ 9 or its last copies; the bulk is one test day, 2026-10-16, 152 snapshots). It can NOT recover by itself: the cap is half the store and grows ~49/week while the plan grows ~84/week. Only demo-hp has this shape (demo-felhom and Tester 1 pruned normally 10-26). The pick is STATUS D54. **Earlier:** OPEN | — | read the guard's cap rule (controller off-site prune) against demo-hp's snapshot list: is the plan honest (old, superseded) or not; if honest, say how such a store gets back under the cap (an attended one-time prune, or a cap that follows the store) — a design question for the operator if it changes what a box may delete | CC | +| **R-1294** | Backup & restore | P3 | **demo-hp's weekly off-site clean-up was refused by its own guard on 2026-10-26 (window 16): the plan would remove 209 of 359 snapshots, above the week's cap (179) — nothing was deleted, and each refused week adds to the next plan.** Seen in the operator mailbox during the 2026-10-26 release run (03:17Z, `offsite_prune_guard_refused`, error; details `count_before 359, count_after 359, outcome guard-refused`). The cap refusal is kept on purpose (R-824, R-867 closed the false ones); the open question is whether a store that once exceeds the cap can ever prune again by itself, or refuses every week while it grows. demo-hp is the Tier-0 box with many hand-made backups (sweeps, probes). Earlier cap refusals: demo-hp 2026-10-03 (window 1), demo-felhom 2026-10-05 (window 3). | **OPEN** — ruled 2026-10-26 evening: **D54 = prune once** (one window, cap 220, the hub's one-shot grant; `09` §3 decision 266). **Earlier:** WAITING-ON-OPERATOR — 2026-10-26 (read only, `audits/r1294-offsite-cap-2026-10-26/`): the plan is HONEST (restic's own dry-run: keep 150, remove 209; every removal 7–30 days old; every app keeps ≥ 9 or its last copies; the bulk is one test day, 2026-10-16, 152 snapshots). It can NOT recover by itself: the cap is half the store and grows ~49/week while the plan grows ~84/week. Only demo-hp has this shape (demo-felhom and Tester 1 pruned normally 10-26). The pick is STATUS D54. **Earlier:** OPEN | — | read the guard's cap rule (controller off-site prune) against demo-hp's snapshot list: is the plan honest (old, superseded) or not; if honest, say how such a store gets back under the cap (an attended one-time prune, or a cap that follows the store) — a design question for the operator if it changes what a box may delete | CC | ## Storage & devices — 13 rows (P3 4, P4 9) @@ -305,7 +305,7 @@ stopping line that lies. | **R-1223** | Monitoring & notifications | P3 | **After a reboot, a box whose tunnel ep0 refuses is invisible: the future stamp is gone, so neither the D30 re-key nor the hub's alarm sees it.** Fresh review 2026-10-23 night (`REPORT-night-2026-10-23.md`, A8 + H1): the kernel forgets `latest-handshake` when the interface restarts (0 = never); the agent then sends neither `last_handshake_age_s` nor `handshake_future_s`, and `checkWGTunnel` (`hub/internal/api/host_tunnel.go`) does not judge a registered, active tunnel with no handshake at all. Shape: the clock ran ahead, was corrected, the box rebooted (some households switch off at night), ep0 still holds the future stamp and starts nothing. | OPEN | — | Agent: report `tunnel_up_s` (how long the unit has been active) with no handshake; hub: a registered, active tunnel with no handshake for > 30 min while reporting → `wg_tunnel_stale`; the agent re-keys the same way after 30 min with no handshake. Tests both sides; rides an agent release + a hub deploy | CC | | **R-1224** | Monitoring & notifications | P4 | **The operator's 1-hour mail cooldown for `wg_tunnel_stale` is per customer, not per host, and `wg_tunnel_ok` does not end it.** Fresh review 2026-10-23 night (`REPORT-night-2026-10-23.md`, H3): `notify/dispatcher.go:620` keys the cooldown `customerID:eventType`. Two hosts of one household going stale within an hour, or stale → ok → stale, store a second event row but mail once (the suppression is in `notification_log`). | OPEN | — | Key the cooldown by `host_id` from the details for host-scoped operator events, and let the matching ok event end it; a dispatcher test with two hosts; rides a hub deploy | CC | | **R-1233** | Monitoring & notifications | P4 | **`[ERROR] [stacks] execCommand failed: exit status 1` names no command.** Seen once a night (2026-10-21 00:30:49 and 2026-10-23 02:17:14 UTC, each right after an app stopped for its dump); the command and stderr go only into the returned error, which the caller may drop (`internal/stacks/manager.go:1757`). An ERROR nobody can judge. | OPEN | — | Log the command's first two words (`docker inspect`, never the arguments — `docker exec … psql` can carry a password) and the stderr's first line; find the caller of the nightly one | CC | -| **R-1291** | Monitoring & notifications | P3 | **A held app gives the operator no lasting signal: one event at the stop, then nothing — demo-hp's Kimai sat held 11 days unseen.** Found 2026-10-25 night (R-1286). No held-app state reaches the hub (the report carries none; the hub shows none); the crash-loop stop sends `app_stopped_unhealthy` once. On a household box an app held after a crash loop, a failed update or a failed restore stays stopped until someone opens its page. | **WAITING-ON-OPERATOR** — 2026-10-26: the design is written (`08` §10 [DESIGN — proposed]: `app_held` / `app_hold_cleared` events + a daily re-send, a „Held apps" list on the host page, an operator reminder after a grace per reason, the hub never clears a hold; ~½ day controller + ~1 day hub). The pick is STATUS D53. **Earlier:** OPEN | — | a two-repo design: the controller reports its holds (stack, reason, since), the hub shows them on the host and mails a reminder after N days (the D-level of the reason); one row's worth of design first | CC | +| **R-1291** | Monitoring & notifications | P3 | **A held app gives the operator no lasting signal: one event at the stop, then nothing — demo-hp's Kimai sat held 11 days unseen.** Found 2026-10-25 night (R-1286). No held-app state reaches the hub (the report carries none; the hub shows none); the crash-loop stop sends `app_stopped_unhealthy` once. On a household box an app held after a crash loop, a failed update or a failed restore stays stopped until someone opens its page. | **OPEN** — ruled 2026-10-26 evening: **D53 = operator-only reminders first** (`09` §3 decision 265); CC builds `08` §10, commit only. **Earlier:** WAITING-ON-OPERATOR — 2026-10-26: the design is written (`08` §10 [DESIGN — proposed]: `app_held` / `app_hold_cleared` events + a daily re-send, a „Held apps" list on the host page, an operator reminder after a grace per reason, the hub never clears a hold; ~½ day controller + ~1 day hub). The pick is STATUS D53. **Earlier:** OPEN | — | a two-repo design: the controller reports its holds (stack, reason, since), the hub shows them on the host and mails a reminder after N days (the D-level of the reason); one row's worth of design first | CC | | **R-1296** | Monitoring & notifications | P4 | **When ep0's tenancy script refuses, the hub log shows only its one-line error — PBS's own reason (the 403 `missing Datastore.Audit|Datastore.Backup on …`) stays in the script's stderr, which the hub drops on a refusal.** Found 2026-10-26 diagnosing R-1295: the cause was visible only by reading ep0's proxy journal over root SSH. `hub/internal/tenantsync/client.go` `parseResponse` returns the JSON error and ignores stderr; the script keeps secrets off stderr by design (its header), so the tail is safe to log. | OPEN | — | append the last ~3 stderr lines to the refusal error (bounded, never stdout); a test that a secret on stdout never appears | CC | ## Hub & operator — 12 rows (P3 3, P4 9) @@ -399,4 +399,4 @@ stopping line that lies. | R-528 | 2026-11-12 | no failed oom_check / unexplained app_oom since 2026-10-12; detail in the R-528 row | | R-1035 | 2026-12-09 | the same three numbers 8 weeks after publishing, compared with the 4-week read; a null at 4 weeks is not a verdict, both reads are needed; detail in the R-1035 row | -| **R-1297** | Process & tooling | P3 | **CI waits dominate a working day: felhom.eu's CI run takes ~13 min and the ONE runner makes every repo's job wait behind it (up to 10–17 min queued).** Measured 2026-10-26 (operator: „these CI waiting times are getting out of hand"): since 10-25 felhom.eu runs median 793 s, the controller/agent/catalog 57–102 s; queue median 5 s, max 548–1023 s. In run 2366, ~10 of 13 minutes are four suites — `test_gate_decoys.py` 232 s, `test_due_checks_gate.py` 133 s, `test_repo_gates.py` 132 s (it runs the whole gate set a SECOND time), `dooplex-offsite/test_dooplex_offsite.py` 69 s — plus `hub-gofmt` ~110 s (a cold Go cache per run). **Ruled 2026-10-26 by the operator: BOTH** — (A) trim felhom.eu CI: the heavy suites only when their own files change, no duplicate full run, a Go cache for hub-gofmt; (B) a second CI runner on DooPlex. | OPEN | — | (A) CC, a run of its own (a CI scope change, ruled); (B) a DooPlex change — a brief or the homelab session; and CC waits on CI only before a release or at the end of a run | CC + operator | +| **R-1297** | Process & tooling | P3 | **CI waits dominate a working day: felhom.eu's CI run takes ~13 min and the ONE runner makes every repo's job wait behind it (up to 10–17 min queued).** Measured 2026-10-26 (operator: „these CI waiting times are getting out of hand"): since 10-25 felhom.eu runs median 793 s, the controller/agent/catalog 57–102 s; queue median 5 s, max 548–1023 s. In run 2366, ~10 of 13 minutes are four suites — `test_gate_decoys.py` 232 s, `test_due_checks_gate.py` 133 s, `test_repo_gates.py` 132 s (it runs the whole gate set a SECOND time), `dooplex-offsite/test_dooplex_offsite.py` 69 s — plus `hub-gofmt` ~110 s (a cold Go cache per run). **Ruled 2026-10-26 by the operator: BOTH** — (A) trim felhom.eu CI: the heavy suites only when their own files change, no duplicate full run, a Go cache for hub-gofmt; (B) a second CI runner on DooPlex. | OPEN — (B) DONE by the operator 2026-10-26: a second runner, both runners 2 CPUs (`09` §3 decision 267); (A) CC, 2026-10-26 evening | — | (A) CC, a run of its own (a CI scope change, ruled); (B) a DooPlex change — a brief or the homelab session; and CC waits on CI only before a release or at the end of a run | CC | diff --git a/documentation/backlog/STATUS-HISTORY.md b/documentation/backlog/STATUS-HISTORY.md index e8922f28..fb31b91e 100644 --- a/documentation/backlog/STATUS-HISTORY.md +++ b/documentation/backlog/STATUS-HISTORY.md @@ -5,6 +5,15 @@ Moved here byte for byte on 2026-10-14 (night session), newest first, so that `S **Updated 2026-10-13 (night): demo-hp, demo-felhom and Tester 1 run agent 0.155.0; demo-felhom runs controller 0.310.0, the other two 0.309.0 until the floor is raised. The open-items list is at 127. Reports: `REPORT-poweroff.md`, `REPORT-plugmeter.md`, `REPORT-usenet-2026-10-12.md`, `REPORT-newapps-2026-10-12.md`, `REPORT-disk-evening-2026-10-12.md`, `REPORT-answers-2026-10-12.md`, `REPORT-m3-2026-10-11.md`, `REPORT-redesign-2026-10-10.md`, `REPORT-testers-2026-10-10.md`, `REPORT-register-shrink-2026-10-10.md`, `REPORT-new-apps-2026-10-10.md`, `REPORT-release-2026-10-10.md`, `REPORT-break-the-circle-2026-10-09.md`, `REPORT-dooplex-survival-2026-10-09.md`, `REPORT-day4-2026-10-09.md`.** +## Moved from STATUS on 2026-10-26 (evening run) + +**Updated 2026-10-26 (afternoon).** A fresh install's whole-box off-site copy no longer fails silently: the cause (PBS's 5-second permission cache) is fixed on ep0, and the hub retries and mails you if it still fails (hub 0.172.0). Every box runs controller 0.345.0: the torrent rule leaves the household's alternative speed alone. Two picks wait for you (D53, D54). + +| D54 | R-1294 | demo-hp's weekly off-site clean-up is stuck: its plan (209 old copies, all from a test day and normal ageing) is above the safety cap (179), and it cannot catch up by itself. Prune it once by hand, or change the cap? | **Prune once** — on your yes, demo-hp gets one clean-up window with a raised cap of 220 through the hub's existing one-shot grant (the plan is honest: every removal is 7–30 days old, every app keeps ≥ 9 copies) | change the cap rule: code in hub + controller, and a weaker guard against a mass deletion | it is refused every Sunday, mails an error each week, and the store grows ~100 copies a week | — | +| D53 | R-1291 | A stopped-and-held app (like Kimai for 11 days) should reach you. Operator-only reminders, or also mail the household for the two holds it can clear itself? | **Operator only first** (the design in `08` §10: a „Held apps" list and a reminder after a grace per reason; ~1.5 days of work) | also the household: two more customer mails to write and translate, and a mail about a stop they may not understand | held apps stay invisible until someone opens the app's page | — | + +**Ruled:** D53 = operator-only reminders first (`09` §3 decision 265); D54 = prune once, cap 220, the one-shot grant (decision 266) — both by starting the evening brief, 2026-10-26. Done by the operator 2026-10-26: a second CI runner on DooPlex, both runners 2 CPUs (R-1297 B, decision 267). + ## Moved from STATUS on 2026-10-26 (afternoon run) **Updated 2026-10-26 (release day).** Every box runs hub 0.171.0, agent 0.166.0 and controller 0.344.0, and new installs start on golden 0.344.0 — all vouched: the torrent line hold, FileBrowser off the app network, a set-aside mails „nothing failed", a signed job lasts at most 24 h. One leftover: on a BYO host the SSH clean-up still comes one release late (R-1285).