From 5ebf9876a50d048cc74fd2652397e7ed815b4a62 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 21 Jul 2026 03:37:25 -0400 Subject: [PATCH] docs: file Gitea issues for every deferred item; correct a stale limitation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deferred work was living in plan docs and a CLAUDE.md banner rather than the issue tracker, so it was invisible unless you happened to read the right file. Each item was verified against the current tree before filing — nothing speculative, nothing already fixed: - #487 scripted-alarm redeploy recovery (CONFIRMED pre-existing bug). Verified still unfixed: ReassertValue exists only for VirtualTags, there is no OnAlarmsLoaded equivalent. Carries double-alarm-history risk, hence the careful proposed shape (node-only re-assert, never the alerts topic). - #488 periodic desired-vs-actual subscription reconcile. Records what exists today (Connected-entry re-assert + a health-poll tick that never touches subscriptions) and why a true reconcile needs a new ISubscribable member across 7 drivers, plus the cheap no-interface-change variant to try first. - #489 raw-tag rename hot-rebind (today: deploy-THEN-recreate). - #490 absolute-RawPath Monaco tag-path completion. - #491 continuous-historization live end-to-end + restart-convergence gate. CLAUDE.md's "KNOWN LIMITATION 1" was STALE and told the reader not to trust a cutover that has in fact been live-validated (read/write-persist/alarm-send all green; alarm-readback skipped as a confirmed protocol limitation, not a bug) — evidence in docs/plans/2026-06-27-otopcua-historian-followups.md. Rewritten as a passed gate, keeping the recipe for re-running it. Limitation 2 is genuinely open and now points at #491. The cross-repo ScadaBridge cutover was already tracked in that repo (its #14 open, #20 closed), so no duplicate was filed; the Batch 4 doc now says so, and records that the umbrella-index half is done. Claude-Session: https://claude.ai/code/session_01GASWkNEi68FSCtvr6rLoEW --- CLAUDE.md | 17 +++++++++++------ docs/plans/2026-07-16-v3-batch4-PR.md | 11 ++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 0b0d2588..06c1f7e5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -415,11 +415,16 @@ The `AlarmHistorian` section's old Wonderware connection keys (`Host`/`Port`/`Us were pruned — remove them; the SQLite knobs are retained and the downstream connection now comes from `ServerHistorian`. See `docs/Historian.md` for the full guide. -### KNOWN LIMITATION 1 — live-validation gate (do before merging/trusting the cutover) +### Live-validation gate — PASSED (was "KNOWN LIMITATION 1") -The cutover is code-complete but **must be live-validated against a real gateway** (VPN to -`wonder-sql-vd03`, gateway running the prerequisites above) before it is merged or trusted. Run the -env-gated suite: +**No longer a limitation.** The cutover was live-validated against the real gateway on +`wonder-sql-vd03`: read ✅, write-persist ✅, alarm-send ✅, alarm-readback skipped as a *confirmed +protocol limitation* (the captured `CM_EVENT` wire never carries `SourceName`, so the gateway cannot +populate `Source_Object` — not a fixable bug). Evidence: +`docs/plans/2026-06-27-otopcua-historian-followups.md`. + +Kept here because it is the recipe to **re-run** the gate after any gateway or backend change (VPN to +`wonder-sql-vd03`, gateway running the prerequisites above): ```bash export HISTGW_GATEWAY_ENDPOINT=https://wonder-sql-vd03:5222 # absolute gateway URI; absent ⇒ all live tests skip @@ -434,7 +439,7 @@ dotnet test --filter "Category=LiveIntegration" The live suite **skips cleanly** when these env vars are absent (safe to run offline on macOS). It is the gate the operator runs on the VPN before trusting the cutover. -### KNOWN LIMITATION 2 — continuous-historization value-capture wired; live end-to-end verification still pending +### KNOWN LIMITATION 2 — continuous-historization value-capture wired; live end-to-end verification still pending (issue #491) The `ContinuousHistorizationRecorder` is fully wired (actor + FasterLog outbox + gateway value-writer + meters). It is spawned with an **empty *initial* ref set** (`Array.Empty()` in @@ -448,4 +453,4 @@ deployed set of historized value tags from the first deploy onward (the feed is path is code-complete.** What remains is the **live gate**: an end-to-end verification against a real gateway (deploy → dependency-mux value delta → outbox append → `WriteLiveValues`) plus a restart-convergence test proving the recorder re-registers the deployed set after a process restart. Until that live verification runs, -treat continuous value-capture as unproven-in-production rather than absent. +treat continuous value-capture as unproven-in-production rather than absent. Tracked as **issue #491**. diff --git a/docs/plans/2026-07-16-v3-batch4-PR.md b/docs/plans/2026-07-16-v3-batch4-PR.md index 756bc6e0..d8b066c6 100644 --- a/docs/plans/2026-07-16-v3-batch4-PR.md +++ b/docs/plans/2026-07-16-v3-batch4-PR.md @@ -94,7 +94,7 @@ dual-namespace + event-delivery), Runtime 377 (+ VT reassert regression), AdminU ## Documented follow-ups (non-blocking) -- **Scripted-alarm redeploy recovery (CONFIRMED pre-existing bug, deferred — deserves its own careful fix).** +- **Scripted-alarm redeploy recovery (CONFIRMED pre-existing bug, deferred — deserves its own careful fix). Filed as issue #487.** The scripted-alarm Part 9 condition node has the same redeploy-reset race the VT `ReassertValue` fix closed: `RebuildAddressSpace` clears `_alarmConditions` and `MaterialiseScriptedAlarms` recreates each condition fresh/normal, but `ScriptedAlarmEngine.LoadAsync` reloads from the persisted state and yields @@ -106,10 +106,11 @@ dual-namespace + event-delivery), Runtime 377 (+ VT reassert regression), AdminU historian issue). Proposed shape: a host-driven, node-only `AlarmStateUpdate` re-assert in `OnAlarmsLoaded` (same safe post-materialise ordering as the VT fix), reusing `_engine.GetState(alarmId)` + `LoadedAlarmIds`, **never touching the `alerts` topic**. -- Raw-tag rename hot-rebind of the renamed tag's live value without a recreate (today: deploy-THEN-recreate). -- Absolute-path Monaco completion → RawPath (from Batch 3; the `{{equip}}/` completion works). +- Raw-tag rename hot-rebind of the renamed tag's live value without a recreate (today: deploy-THEN-recreate). Filed as issue #489. +- Absolute-path Monaco completion → RawPath (from Batch 3; the `{{equip}}/` completion works). Filed as issue #490. - Cross-repo (post-merge): ScadaBridge Data-Connection-Layer NodeId/namespace cutover (raw `s=` / - UNS `s=///`, retired `EquipmentNodeIds`) + the umbrella index - `../scadaproj/CLAUDE.md` OtOpcUa entry. + UNS `s=///`, retired `EquipmentNodeIds`) — tracked in the + ScadaBridge repo as its issue #14 (its #20 landed the `nsu=` binding + native-alarm routing). The umbrella + index `../scadaproj/CLAUDE.md` OtOpcUa entry is **DONE** (scadaproj `ede5275`). https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox