docs(plans): Lever 1 live gate PASS on the docker rig (one request per 45 s ceiling, backoff 5→9.4→20.4 s, Good within ~95 s of restore); plan tasks 1-8 completed

Claude-Session: https://claude.ai/code/session_019ZxXT5sxZs5XrtdwYzJDPV
This commit is contained in:
Joseph Doherty
2026-08-28 15:06:22 -04:00
parent 0589486f4e
commit c52f14afca
2 changed files with 65 additions and 10 deletions
@@ -59,6 +59,9 @@ Levers 1 and 2 are each sufficient to break the feedback loop; together they are
**Invariants preserved:** a superseded correlation id is still ignored (`HandleSubscribeTagsResponse` :1262-1264 stale-reply drop); a `Success` still cancels the timer (:1269) and resets backoff; `PostStop` still cancels all timers (`:391-394`).
> **Live gate PASS 2026-08-28 (docker rig, main @ 0589486f).** OPC UA sim stopped and the instance's site node restarted so the boot-time subscribe could not be answered (failover landed `rig-probe-1` on site-a-b): the log shows exactly **one** outstanding `SubscribeTagsRequest` per in-flight ceiling — `unanswered for 45091ms … presuming lost, re-sending`, then `47130ms` — with the backoff climbing `next retry in 00:00:05 → 00:00:09.415 → 00:00:20.369` (jittered), i.e. 3 requests in ~110 s where the pre-Lever-1 actor would have issued ~22. Sim restarted → DCL `Entering Connected state` in 4 s → all three attributes `Good` with fresh timestamps within ~95 s (`debug snapshot --id 1492`). Steady state on a healthy node: one `subscribing` line per (instance, connection), no `still in flight` / `presuming lost` at all. Note for future gates: an OPC UA outage *alone* never reaches this path — the DCL reconnects and re-subscribes transparently and the Instance Actor's subscribe stays confirmed; you must make the subscribe itself go unanswered (node restart / redeploy while the source is down).
---
## 4. Lever 2 — bulk supervisory-advise RPC (capability-negotiated)
@@ -1,14 +1,66 @@
{
"planPath": "docs/plans/2026-08-28-tag-subscribe-inflight-guard-backoff.md",
"tasks": [
{"id": 1, "subject": "Task 1: Options + validator (new keys)", "status": "pending"},
{"id": 2, "subject": "Task 2: Pure backoff step NextTagSubscribeInterval", "status": "pending"},
{"id": 3, "subject": "Task 3: In-flight guard", "status": "pending", "blockedBy": [1, 2]},
{"id": 4, "subject": "Task 4: Failure reply frees slot, backs off, Success resets", "status": "pending", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: Superseded-reply lock-in test", "status": "pending", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: ConnectionQualityChanged(Good) resets backoff", "status": "pending", "blockedBy": [4]},
{"id": 7, "subject": "Task 7: Spec + CLAUDE.md + design-doc status", "status": "pending", "blockedBy": [5, 6]},
{"id": 8, "subject": "Task 8: Rig redeploy + live gate", "status": "pending", "blockedBy": [7]}
{
"id": 1,
"subject": "Task 1: Options + validator (new keys)",
"status": "completed"
},
{
"id": 2,
"subject": "Task 2: Pure backoff step NextTagSubscribeInterval",
"status": "completed"
},
{
"id": 3,
"subject": "Task 3: In-flight guard",
"status": "completed",
"blockedBy": [
1,
2
]
},
{
"id": 4,
"subject": "Task 4: Failure reply frees slot, backs off, Success resets",
"status": "completed",
"blockedBy": [
3
]
},
{
"id": 5,
"subject": "Task 5: Superseded-reply lock-in test",
"status": "completed",
"blockedBy": [
4
]
},
{
"id": 6,
"subject": "Task 6: ConnectionQualityChanged(Good) resets backoff",
"status": "completed",
"blockedBy": [
4
]
},
{
"id": 7,
"subject": "Task 7: Spec + CLAUDE.md + design-doc status",
"status": "completed",
"blockedBy": [
5,
6
]
},
{
"id": 8,
"subject": "Task 8: Rig redeploy + live gate",
"status": "completed",
"blockedBy": [
7
]
}
],
"lastUpdated": "2026-08-28T18:00:00Z"
}
"lastUpdated": "2026-08-28T19:06:22Z"
}