feat(scripted-alarms): materialise real Part 9 AlarmConditionState nodes (T14)

This commit is contained in:
Joseph Doherty
2026-06-10 19:19:10 -04:00
parent 4217b213b0
commit 60d48a2a0a
14 changed files with 443 additions and 12 deletions
+14 -5
View File
@@ -581,11 +581,20 @@ ServiceResult OnAck(ISystemContext ctx, ConditionState c, byte[] eventId, Locali
confirm `Server.Telemetry` (`ITelemetryContext`) is non-null in our host
before relying on the telemetry ctor — fall back to `new AlarmConditionState(parent)`
if not. (Not load-bearing; pick whichever the host supports.)
2. **Optional children before `Create`.** Whether `ShelvingState` /
`ConfirmedState` are auto-created by `Create` or must be instantiated first
(the sample instantiates them) — **[SAMPLE-ONLY]** behaviour; verify by
inspecting the live node after `Create` (browse the children). If Confirm /
Shelve children are missing, materialise them like the sample before `Create`.
2. **Optional children before `Create`.** ~~Whether `ShelvingState` /
`ConfirmedState` are auto-created by `Create` or must be instantiated first.~~
**RESOLVED in T14 (real-server integration test, 1.5.378.106):** `Create`
auto-builds the **full** optional Part 9 child set from the embedded type
definition with **no** pre-setting — for `OffNormalAlarmState`, both
`ConfirmedState` AND `ShelvingState` come back **non-null** after `Create`
(richer than the `[SAMPLE-ONLY]` caveat predicted). So T15/T16 can call
`SetConfirmedState` / `SetShelvingState` directly; no manual child
materialisation is needed. **Gotcha also found:** `BranchId.Value` is left a
**null reference** by `Create`, and the very first `Set*` call
(`SetEnableState` → `UpdateRetainState` → `GetRetainState` → `IsBranch()`)
**NREs** on it. Fix: set `alarm.BranchId.Value = NodeId.Null` (the main
branch) **before** any `Set*` call. T14's `MaterialiseAlarmCondition` does
this. (Covered by `SdkAddressSpaceSinkTests.MaterialiseAlarmCondition_*`.)
3. **`InstanceStateSnapshot` vs reporting the node directly.** The sample uses
an `InstanceStateSnapshot` as the `IFilterTarget`. Confirm whether reporting
the alarm node itself (which is also an `IFilterTarget`) is acceptable — the