controller v0.120.0: dead-app alerting (fix-3) + ring revision (fix-6) — CLOSES CAMPAIGN-3 (docs+CHANGELOG+REPORT+CONTEXT)

fix-3: deadapp-check job -> self-clearing WARN banner + one app_start_failed hub
event per running->down transition. fix-6: ring 1000->5000, periodic spam->TRACE
(ring-dropped), atomic SSD spill/load across restart. Live-validated on 9201+hub 0.48.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017CDMFpFx84pfviCTVuGGhf
This commit is contained in:
2026-07-12 10:31:12 +02:00
parent 40498254c6
commit 92d670e8a6
4 changed files with 129 additions and 47 deletions
+33
View File
@@ -1,5 +1,38 @@
## Changelog
### v0.120.0 — dead-app alerting (fix-3) + debug-ring revision (fix-6) — CLOSES CAMPAIGN-3 (2026-07-12) — MinAgent: 0.81.0
The last CAMPAIGN-3 findings (`felhom.eu/documentation/audits/CAMPAIGN-3-2026-07-11.md`). MinAgent
UNCHANGED (0.81.0). Pairs with hub v0.48.0 (accepts the new `app_start_failed` event).
- **fix-3 (MED) — a dead deployed app is LOUD, not silent.** The campaign's CWA sat dead 4 h with no
signal; F11 then produced 4 silently-dead NAS apps per reboot. A new `deadapp-check` job (every 30 s)
scans `stackMgr.GetStacks()`: a DEPLOYED app whose containers are `stopped`/`exited`
(`stacks.IsDownState`; `created`/`dead` map to `stopped` — the F11 dead-at-boot case) raises a
state-based WARN dashboard banner ("Telepített alkalmazás nem fut: <app>"; grouped above 3 to survive
a reboot storm) that SELF-CLEARS the moment the app runs again, AND fires an `app_start_failed` hub
event ONCE per running→down transition (`Notifier.NotifyAppStartFailures` tracks per-app state — the
hub owns the real cooldown; the controller adds no timer and does not spam). A 90 s boot grace skips
the controller's own startup settle so apps that legitimately take 3060 s to come up don't
false-alarm; after the grace an app that never came up STILL fires (the whole point).
- **fix-6 (MED) — the post-incident window survives.** The 1000-entry ring wrapped in ~6.5 min under
the campaign's load and died on every restart. Three changes: **(a) cap 1000→5000** (viewer +
`Entries`/handler display cap raised to match — a larger ring is useless if unreadable); **(b)
periodic-noise policy** — the every-cycle scheduler "job finished" + `refreshStatusLocked` success
lines are demoted to a new `[TRACE]` level the ring DROPS at write-time (failures/transitions are
never TRACE, so nothing is lost); **(c) spill persistence** — `LogBuffer.SpillTo`/`LoadFrom`
atomically (tmp+rename, JSON-lines) spill the ring to `<DataDir>/debug-ring.log` on the SSD state dir
(NEVER a NAS path) every 30 s and on clean shutdown, loading it back on boot so a restart / container
recreation preserves the pre-restart window. Corruption-safe (a truncated line is skipped, never
fatal).
- **Live-validated (demo 9201 + hub):** fix-3 — `docker stop seerr` → the dashboard banner
"Telepített alkalmazás nem fut: Jellyseerr (stopped)" appeared AND the hub received exactly ONE
`app_start_failed` event across 3 down-cycles (anti-spam); `docker start` → banner self-cleared.
fix-6 — the ring showed 0 periodic-spam lines; a controller restart PRESERVED the pre-restart window
(oldest entry unchanged across the restart; 63 KB spill on the persistent SSD volume). Tests incl.
the fix-3 silent-regression + one-event-per-transition red-proofs, the fix-6 TRACE-drop-keeps-failure
+ corrupt-spill-safe red-proofs, all green.
### v0.119.0 — storage-health coherence (F8) + mapped_uid validation (F4) (2026-07-12) — MinAgent: 0.81.0
Fixes CAMPAIGN-3 (`felhom.eu/documentation/audits/CAMPAIGN-3-2026-07-11.md`) storage-UI findings.