v0.342.0 (unreleased): the upload and CPU watch — an app that sends or burns far more than its own numbers explain is one operator-only alarm; the line learnt from the off-site push; qBittorrent's default upload limit (never over the household's)
gates / gates (push) Successful in 1m17s

internal/upwatch: exact per-container counters from the Docker Engine API, per-app judging (upload >= max(5 Mbit/s,
25% of the line) for 15 min; CPU >= max(150%, 50% x cores) for 30 min), explainers qBittorrent / Transmission / Plex,
app_unexplained_upload / app_unexplained_cpu + _cleared (hub 0.169.0). The off-site push is sampled once a second
for the line (a lower bound). qBittorrent limit = 50% of the line, the household's limit always wins. 20 red-proofs.
Spike + design: felhom.eu audits/SPIKE-upload-watch-2026-10-23.md, architecture/08 section 9. Not released.
This commit is contained in:
admin committed 2026-10-23 21:26:09 +02:00
1 parent 277e99839d
commit a9c1997fbc
35 files changed
+2438

No files matched your search

+11
View File
@@ -685,6 +685,15 @@ func main() {
// R-550: an interrupted restore is raised once, now that the notifier exists.
reportInterruptedRestore(notifier, interruptedRestore)
// The upload and CPU watch (internal/upwatch; felhom.eu `08` §9, operator ruling 2026-10-23). Built here, where the
// notifier first exists, and its push measurement handed to the off-site backup BEFORE any scheduler can start a
// push. Wiring pinned by TestUpwatchIsWiredAtStartup.
upwatchSvc := newUpwatch(sett, stackMgr, backupMgr, metricsStore, notifier, logger)
if backupMgr != nil {
backupMgr.SetOffboxPushObserver(upwatchSvc.PushObserver)
}
startUpwatch(ctx, upwatchSvc, logger)
// R-97a: wire the quiesce loop's hub-event seam. It MUST happen here and not in
// startQuiesceLoop, because the notifier is constructed after it — and it must happen at all,
// or the seam is inert (the "built but never wired" trap, four recorded instances). Reachability
@@ -2044,6 +2053,8 @@ func main() {
// URL is derived from it, so two builds of one version can never share a cache entry. Init-only,
// before the HTTP server starts.
webServer.SetBuildIdentity(GitCommit, BuildTime)
// The upload watch's two page lines: the measured line (settings → system) and qBittorrent's limit (its app page).
webServer.SetUpwatchView(upwatchSvc.View)
// R-871 (decision 110): the missed-backup banner reads the night ledger and the box's own on/off record.
webServer.SetMissedBackupBanner(webNightLedger, metricsStore)
// Migration done-hook: a decommission-initiated migration finalizes the source decommission on