docs: define QNAP watchdog singleton contract (#1617)

This commit is contained in:
courtmanr@gmail.com
2026-07-30 00:43:31 +01:00
parent 69475117be
commit 378ffcde16
2 changed files with 13 additions and 2 deletions
@@ -5108,7 +5108,12 @@ check when both paths share a filesystem, honors an operator-selected
Unraid watchdogs must route agent output through the agent's rotating
`--log-file` writer instead of an unbounded shell append; their own watchdog
messages must also be size-bounded so either logging path cannot exhaust a
RAM-backed appliance root.
RAM-backed appliance root. The QNAP wrapper is also a singleton lifecycle
owner: concurrent starts from flash-backed `autorun.sh` and an install or
upgrade must elect exactly one watchdog before terminating or launching an
agent. The elected watchdog records both supervisor and child PIDs, removes
only lock state it owns, and terminates its child on shutdown so a second
watchdog or orphan agent cannot accumulate appliance CPU.
Unified Agent lifecycle truth is agent-authored. The host report contract now
carries the non-secret applied managed-config fingerprint, self-updater state
@@ -2750,7 +2750,13 @@ an operator-supplied `TMPDIR`. `--preflight-only` must exercise the same
storage check and report an actionable alternate-temporary-directory hint.
Generated QNAP and Unraid watchdogs must use the agent's rotating `--log-file`
path rather than an unbounded stdout append, while keeping watchdog-owned
messages independently size-bounded.
messages independently size-bounded. Because QNAP may launch the same
persistent wrapper from both flash-backed `autorun.sh` and an installer or
upgrader, that wrapper must acquire one portable atomic singleton lock before
killing or starting an agent, track its owned child, recover stale lock state,
and remove only its own PID and lock artifacts on shutdown. Installer
verification must exercise concurrent wrapper launches and prove that they
produce one watchdog/agent pair with no orphan after termination.
The in-app updater's apply pipeline now owns a downgrade guard on the normal
apply path. A syntactically valid release asset URL can name a release older