fix(opcua): structural equality for EquipmentVirtualTagPlan so no-op redeploys diff empty

IReadOnlyList<string> DependencyRefs compared by reference in the auto-generated record
equality, causing every VirtualTag with dependencies to be flagged "Changed" on every parse
(fresh list instances from composer and artifact-decoder). Add Equals/GetHashCode overrides
with element-wise ordinal comparison so Phase7Plan.IsEmpty short-circuits a no-op redeploy.
Add regression test Identical_virtualtag_snapshots_diff_to_empty_plan (separate list instances,
same contents → IsEmpty true). Add TODO comment in Phase7Applier near needsRebuild predicate.
This commit is contained in:
Joseph Doherty
2026-06-07 05:19:47 -04:00
parent 9464c91546
commit 9818d0cba8
3 changed files with 64 additions and 1 deletions
@@ -81,6 +81,7 @@ public sealed class Phase7Applier
// VirtualTag topology requires a real address-space rebuild. Driver-instance changes don't
// touch the address-space topology directly — they go through DriverHostActor's spawn-plan
// in Runtime.
// TODO(equipment-virtualtags): when MaterialiseEquipmentVirtualTags drives per-delta sink work, revisit whether ChangedEquipmentVirtualTags should also force needsRebuild.
var needsRebuild =
plan.AddedEquipment.Count > 0 || plan.RemovedEquipment.Count > 0 ||
plan.AddedAlarms.Count > 0 || plan.RemovedAlarms.Count > 0 ||