feat(opcuaserver): classifier — non-alarm raw-tag + UNS-reference deltas are surgical, not rebuilds

This commit is contained in:
Joseph Doherty
2026-08-15 13:18:04 -04:00
parent cf69d03f9b
commit 9f68f27218
3 changed files with 178 additions and 31 deletions
@@ -1249,11 +1249,14 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
/// Wave C review M3 — this is a RECONCILE, not additive-only: it wires the supplied set AND unwires any
/// previously-tracked folder whose id is no longer in <paramref name="notifierFolderNodeIds"/>
/// (bidirectional), so a de-referenced equipment stops receiving the alarm. Today the applier always
/// passes the COMPLETE referencing-equipment set for the condition, and a de-reference arrives as a
/// <c>ChangedRawTags</c> full rebuild (which clears the wiring), so the unwire leg is a no-op on the
/// current paths — but it makes this method correct for a FUTURE surgical <c>ChangedRawTags</c> path
/// (see <c>AddressSpaceChangeClassifier</c>'s <c>ChangedRawTags → Rebuild</c> branch, which carries the
/// matching binding guard).
/// passes the COMPLETE referencing-equipment set for the condition, and a de-reference on an
/// ALARM-BEARING raw tag still arrives as a full rebuild (which clears the wiring), so the unwire leg is
/// a no-op on the current paths — but it makes this method correct for a FUTURE surgical path that
/// reaches an alarm-bearing tag. The 2026-08-15 surgical-deploys work narrowed the classifier's blanket
/// <c>ChangedRawTags → Rebuild</c> branch to <em>alarm-bearing / identity-changing</em> raw-tag deltas
/// only (see <c>AddressSpaceChangeClassifier.RawTagDeltaIsSurgicalEligible</c>, which carries the
/// matching binding guard): a NON-alarm raw tag carries no notifier wiring, so its
/// <c>ReferencingEquipmentPaths</c> edit is node-inert and routes surgically.
/// </remarks>
public void WireAlarmNotifiers(string alarmNodeId, AddressSpaceRealm alarmRealm,
IReadOnlyList<string> notifierFolderNodeIds, AddressSpaceRealm notifierFolderRealm)