When the agent waits for quiet and qBittorrent or Transmission runs: record the limit first,
hold at 1 KiB/s, ask the agent for a test on request, put the old limit back (deferred; a
household change during the test stays). Start-up puts back a limit a killed controller left;
the 50 % rule skips while a hold record exists. Commit only.
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.
compose down --volumes removes only the current definition's volumes; a volume a template dropped (or an older restore
re-created) survived 'remove with data' on 9202 (nextcloud_nextcloud_redis_data). Red-proofed.
FileBrowser config carries server.internalUrl http://filebrowser:80 (OnlyOffice fetched the public files address and got 403);
Nextcloud's DocumentServerInternalUrl gets its trailing slash (every save was lost: http://onlyoffice:80cache/...);
RestartStack("filebrowser") runs the R-1126 gate at once (files.<domain> was 502 for up to 5 min after the link switched).
Each red-proofed. MinAgent 0.158.1.
R-1142: the HDD_PATH root is appdata/<own folder>, with a compiled-in folder map (paperless-ngx ->
paperless). R-981: the allow-list is empty (homepage's socket served no Felhom feature). R-1063:
finalizeDecommissionWith asks the agent before it marks the drive or moves the default; the 403/409
come back typed and reach the household as a plain 409. R-1069: the agent's no-durable-id format
refusal is ErrNoDurableID and a plain sentence. R-1143: build.sh carries :latest only for x.y.z.
Each pinned by a red-proofed test. MinAgent 0.158.1.
internal/privpolicy checks the RENDERED compose (privileged, cap_add, devices, host namespaces, security_opt,
sysctls, volumes_from, build/include/extends, env_file/config files outside the stack dir, aliasing named volumes,
binds outside the box's data roots, the Docker socket, propagation, ${VAR} in a privileged key) against an
allow-list compiled into the controller (one entry: homepage's read-only socket). Asked before every compose
write: the 15-minute sync, the guarded update/ladder step, the install, both settings changes, both restores
(before the stop). A refusal writes nothing, keeps the app on its last good compose, raises the operator-only
event app_definition_refused once per definition and puts one line on the app page. The sync never copies a
template named like a controller infra stack. Structural guard TestAllowList_IsWiredIntoEveryComposeWriter.
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
v0.327.0's box walk: files.<domain> timed out on demo-hp and the N100. With labels, Traefik kept the address it chose at
container start (on felhom-filebrowser, before the gate joined traefik-public). FileBrowser now carries no Traefik
labels; dynamic/filebrowser.yml routes files.<domain> to http://filebrowser:80 by name, resolved per connection and
only while the gate keeps it on traefik-public. Test extended, red-proved.
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
The deploy page read /proc's host-wide figures (system.GetMemoryMB) while the install check reads the guest cap and
the installed apps' committed requests; on 9202 the page said 12,637 MB needed where the check counted 2,648. Both
now read stacks.InstallMemory. TestR1125_InstallMemoryIsTheChecksReading, red-proved.
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
deploy.nincs_eleg_memoria_foglalas_telepites (HU + EN) now says the memory is held by the installed apps and to
remove one or use a machine with more memory. deploy_new_blocked and deploy_new_memory_blocked re-captured as
*_r1125 (only that sentence differs); all other fixtures byte-identical.
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
web.SyncFileBrowserMounts can re-create FileBrowser between the check and the connect; a connect by name would publish
the new, unchecked container. The run is now "<id> <StartedAt>" and the connect targets that id.
TestFileBrowserGate_ConnectsTheCheckedContainerById, red-proved.
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS