From 42443b4659084153740e66757d3b3c0e7f51def8 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 9 Nov 2026 12:55:12 -0500 Subject: [PATCH] docs(site-runtime): IsMesReportable and AckTime now ride the wire (ScadaBridge#60, #84) Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV --- docs/requirements/Component-SiteRuntime.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements/Component-SiteRuntime.md b/docs/requirements/Component-SiteRuntime.md index ce5b7555..a82d83d7 100644 --- a/docs/requirements/Component-SiteRuntime.md +++ b/docs/requirements/Component-SiteRuntime.md @@ -562,7 +562,7 @@ Available to all script runs and alarm on-trigger runs: - **Not scope-prefixed**, unlike `Attributes`: alarm identity is not a scope-relative attribute name (computed alarms are keyed by configured name, native conditions by a source-supplied reference), so every scope sees the same list rather than a silently truncated one. - The snapshot is built by the same `BuildAlarmStatesSnapshot()` the Debug View uses, so it **includes placeholder rows** for configured-but-quiet native source bindings (`IsConfiguredPlaceholder`). Callers enumerating real alarms filter on `Active && !IsConfiguredPlaceholder`. - `ScriptAlarm` is a flat projection of the retained `AlarmStateChanged`: `Name`, `SourceReference`, `NativeSourceCanonicalName`, `Active`, `Acknowledged`, `Confirmed?`, `Shelved` (all shelve sub-states collapse to one boolean), `Suppressed`, `Severity` (0–1000), `Kind`, `Message`, `AlarmTypeName`, `Category`, `OperatorUser`, `OperatorComment`, `OriginalRaiseTime?`, `Timestamp`, `AckTime?`, `CurrentValue`, `LimitValue`, `IsConfiguredPlaceholder`, `IsMesReportable` (trailing, 2026-09-11 — always `false` on native rows). The `Condition` is the authority for active/acked/severity, so computed and native alarms read identically from one filter expression. -- **`IsMesReportable` is stamped in one place.** `InstanceActor.BuildAlarmStatesSnapshot()` sets `AlarmStateChanged.IsMesReportable` from `ResolvedAlarm.IsMesReportable` on every row it produces — retained (fired/active) rows and the fallback/idle rows alike — so `Alarms.CurrentAsync()`/`MesReportableAsync()` and the Debug View snapshot always agree regardless of whether the alarm has fired. The flag is **not** carried on the gRPC stream or `DebugAlarmStateDto` (no proto change in this slice — deferred-work register row 122), so central-side surfaces (Debug View live stream, Alarm Summary) see `false` until that follow-up lands. +- **`IsMesReportable` is stamped at two points.** `InstanceActor.BuildAlarmStatesSnapshot()` sets `AlarmStateChanged.IsMesReportable` from `ResolvedAlarm.IsMesReportable` on every row it produces — retained (fired/active) rows and the fallback/idle rows alike — and `InstanceActor.HandleAlarmStateChanged` stamps the Alarm Actor's own live events before storing and publishing them, so `Alarms.CurrentAsync()`/`MesReportableAsync()`, the Debug View snapshot and the live stream always agree. Since ScadaBridge#60 the flag rides the wire as `AlarmStateUpdate.is_mes_reportable` (25) and `DebugAlarmStateDto.is_mes_reportable` (20); `DebugAlarmStateDto` also carries `ack_time` (21, ScadaBridge#84). Both are additive — an older peer reads `false`/null. - The type lives in Commons so the runtime accessor and the Script Analysis compile-only surface (`ScriptCompileSurface.CompileAlarmsAccessor`) project to the **same** type — a script binding at the design-time gate binds identically at the site. Parity is pinned by `CompileSurfaceParityTests`. - Design record: `docs/plans/2026-06-30-mes-alarm-status-api.md` §5.2.