docs: file Gitea issues for every deferred item; correct a stale limitation

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
This commit is contained in:
Joseph Doherty
2026-07-21 03:37:25 -04:00
parent 7808faa7f6
commit 5ebf9876a5
2 changed files with 17 additions and 11 deletions
+11 -6
View File
@@ -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 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. `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 **No longer a limitation.** The cutover was live-validated against the real gateway on
`wonder-sql-vd03`, gateway running the prerequisites above) before it is merged or trusted. Run the `wonder-sql-vd03`: read ✅, write-persist ✅, alarm-send ✅, alarm-readback skipped as a *confirmed
env-gated suite: 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 ```bash
export HISTGW_GATEWAY_ENDPOINT=https://wonder-sql-vd03:5222 # absolute gateway URI; absent ⇒ all live tests skip 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 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. 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 + The `ContinuousHistorizationRecorder` is fully wired (actor + FasterLog outbox + gateway value-writer +
meters). It is spawned with an **empty *initial* ref set** (`Array.Empty<string>()` in meters). It is spawned with an **empty *initial* ref set** (`Array.Empty<string>()` 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 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 (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, 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**.
+6 -5
View File
@@ -94,7 +94,7 @@ dual-namespace + event-delivery), Runtime 377 (+ VT reassert regression), AdminU
## Documented follow-ups (non-blocking) ## 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: 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 `RebuildAddressSpace` clears `_alarmConditions` and `MaterialiseScriptedAlarms` recreates each condition
fresh/normal, but `ScriptedAlarmEngine.LoadAsync` reloads from the persisted state and yields 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` 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`, (same safe post-materialise ordering as the VT fix), reusing `_engine.GetState(alarmId)` + `LoadedAlarmIds`,
**never touching the `alerts` topic**. **never touching the `alerts` topic**.
- Raw-tag rename hot-rebind of the renamed tag's live value without a recreate (today: deploy-THEN-recreate). - 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). - 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=<RawPath>` / - Cross-repo (post-merge): ScadaBridge Data-Connection-Layer NodeId/namespace cutover (raw `s=<RawPath>` /
UNS `s=<Area>/<Line>/<Equipment>/<EffectiveName>`, retired `EquipmentNodeIds`) + the umbrella index UNS `s=<Area>/<Line>/<Equipment>/<EffectiveName>`, retired `EquipmentNodeIds`) tracked in the
`../scadaproj/CLAUDE.md` OtOpcUa entry. 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 https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox