fix(deploy): persist which nodes never acked on a deploy timeout (lmxopcua#784)

In the normal timeout branch (some acks landed) the deployment row was set to
TimedOut with a null FailureReason, so GET /api/deployments/{id} could not say
which node to fix; only the central log named it. The branch now persists a
reason naming the silent nodes ("Timed out waiting for acks (n/m landed). No ack
from: ..."), bounded to 20 named nodes plus a count of the rest, and still
backstopped by the 2048-char Truncate.

Tests: the reason names the silent node and not the acked one; on a 25-node
silence it names 20, counts 5 and fits the column. Mutation-checked: dropping
the SetFailureReason fails both, dropping the bound fails the second.

Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
Joseph Doherty
2026-11-09 21:16:53 -05:00
parent 43f61eba2e
commit 80118a01c5
3 changed files with 97 additions and 1 deletions
+2
View File
@@ -186,6 +186,8 @@ hold.
`GET /api/deployments/{id}` returns `status: TimedOut` with `failureReason: null`. Only the central log names the
silent node (`No ack from: site-b-1:4053`). The no-expected-rows branch does set a reason. An automation client
polling the API cannot see which node to fix.
**Resolved (lmxopcua#784):** the timeout branch now persists `failureReason` = `Timed out waiting for acks
(n/m landed). No ack from: <nodes>. …` (at most 20 nodes named, the rest counted).
2. **Rig: mesh PSK warnings on the centrals.** central logs `Mesh PSK secret ot-mesh-psk-{main,site-a,site-b} … is
absent (or blank) in the store; the key is REVOKED — commands to that cluster and acks from it are refused`. Yet
every gRPC dispatch and ack in these runs succeeded. Either the rig's PSK secrets are not seeded and enforcement is