bug(alarms): an active scripted alarm under-reports as normal after a full-rebuild deploy #487

Open
opened 2026-07-21 03:36:40 -04:00 by dohertj2 · 0 comments
Owner

Confirmed pre-existing bug, deferred out of v3 Batch 4 because the fix carries real risk (see below). Recorded in docs/plans/2026-07-16-v3-batch4-PR.md under "Documented follow-ups"; filed now so it is tracked rather than living in a plan doc.

What happens

The scripted-alarm Part 9 condition node has the same redeploy-reset race the VirtualTag ReassertValue fix closed:

  • RebuildAddressSpace clears _alarmConditions, and MaterialiseScriptedAlarms recreates each condition fresh/normal.
  • ScriptedAlarmEngine.LoadAsync reloads from persisted state and yields EmissionKind.None for a still-active condition, which OnEngineEmission drops.

So an active scripted alarm with static dependencies under-reports as normal after a full-rebuild deploy, until its next real transition. This is the known "snapshot-is-one-shot / restart-to-re-deliver" behaviour, not a Batch 4 regression.

Why it was deferred

The fix is a Core-engine emission-contract change carrying double-alarm-history risk — a naive re-emit would append a duplicate historian/AVEVA row per deploy. That is the alarm analogue of the VirtualTag M1 historian issue.

Proposed shape

A host-driven, node-only AlarmStateUpdate re-assert in OnAlarmsLoaded, using the same safe post-materialise ordering as the VirtualTag fix, reusing _engine.GetState(alarmId) + LoadedAlarmIds, and never touching the alerts topic (that is what would duplicate history).

Verified still unfixed as of master 7808faa7: ReassertValue exists only in VirtualTagActor/VirtualTagHostActor; there is no OnAlarmsLoaded equivalent.

Live-verify this one — the VirtualTag analogue was only caught on the rig, and the failure mode (an alarm silently reading normal) is invisible to unit tests that drive a transition.

**Confirmed pre-existing bug**, deferred out of v3 Batch 4 because the fix carries real risk (see below). Recorded in `docs/plans/2026-07-16-v3-batch4-PR.md` under "Documented follow-ups"; filed now so it is tracked rather than living in a plan doc. ## What happens The scripted-alarm Part 9 condition node has the same redeploy-reset race the VirtualTag `ReassertValue` fix closed: - `RebuildAddressSpace` clears `_alarmConditions`, and `MaterialiseScriptedAlarms` recreates each condition **fresh/normal**. - `ScriptedAlarmEngine.LoadAsync` reloads from persisted state and yields `EmissionKind.None` for a still-active condition, which `OnEngineEmission` drops. So an **active scripted alarm with static dependencies under-reports as normal after a full-rebuild deploy**, until its next real transition. This is the known "snapshot-is-one-shot / restart-to-re-deliver" behaviour, not a Batch 4 regression. ## Why it was deferred The fix is a Core-engine emission-contract change carrying **double-alarm-history risk** — a naive re-emit would append a duplicate historian/AVEVA row per deploy. That is the alarm analogue of the VirtualTag M1 historian issue. ## Proposed shape A host-driven, **node-only** `AlarmStateUpdate` re-assert in `OnAlarmsLoaded`, using the same safe post-materialise ordering as the VirtualTag fix, reusing `_engine.GetState(alarmId)` + `LoadedAlarmIds`, and **never touching the `alerts` topic** (that is what would duplicate history). Verified still unfixed as of `master` `7808faa7`: `ReassertValue` exists only in `VirtualTagActor`/`VirtualTagHostActor`; there is no `OnAlarmsLoaded` equivalent. Live-verify this one — the VirtualTag analogue was only caught on the rig, and the failure mode (an alarm silently reading normal) is invisible to unit tests that drive a transition.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#487