dca822dc59
Review 01 P1/P2/P3/P5 — work done under the manager-wide SDK Lock on the pinned publish thread, where every Read/Browse/Publish waits. - P1 RebuildAddressSpace detaches the shared root's top-level children once instead of every leaf from its parent (NodeState.RemoveChild is a linear scan + RemoveAt, ~k²/2 compares per k-child folder); root notifiers are cleared as a list instead of one O(F) RemoveRootNotifier each; ForgetPredefinedSubtree / TombstoneMonitoredSubtree are iterative with one child buffer. - P2 RemoveEquipmentSubtree walks a parent→children index maintained by EnsureFolder/EnsureVariable/MaterialiseAlarmCondition (keyed by the parent id the caller named) instead of prefix-scanning six maps per removed equipment; a surviving condition's wiring into a removed folder is found through the folder's own notifier list; descendants are not detached from a folder that is itself being discarded. - P3 LowerAllEventsMonitoring(condition) replaces the full O(C) reconcile on RemoveAlarmConditionNode / RemoveEquipmentSubtree / the kind-swap. - P5 AlarmNotifierWiring.Folders is a reference-identity HashSet and an already-wired pair skips the SDK's linear AddNotifier dedup. Benchmark (NodeManagerLockTimeBenchmarkTests, M-series Mac under load, three runs each): rebuild of a 10k-tag folder 75–150 ms → 5–6 ms; removing 200 equipment (250 signals each) from a 50k-node space 471–681 ms → 58–64 ms; all-events bookkeeping visits for 10 condition removals over 50 conditions 900 → 10. The two timing legs assert < 1 s; the P3 leg asserts the visit count (machine-independent). Refs #732 Claude-Session: https://claude.ai/code/session_01Ub9hGmYLQvn9XETzw7CMsT