489664d105
1. Orphaned subscriptions (session closed without deleting subs) have Session == null, so the public MonitoredNode2.InvalidatePermissionCacheForSession never reached their items: a cached allow survived a deploy, the moved alarm's events were queued and delivered on TransferSubscriptions. Each notifier's cache is now cleared whole through the SDK's private MonitoredNode2.InvalidatePermissionCaches (reflection, guard-tested; fallback = per-session drop + Remove/Add of session-less items). 2. The verdict is decided on the condition LIVE under the event's NodeId, not the event's own instance: the SDK key has no instance identity, so a replaced instance's late event cached a deny its successor inherited until the next invalidation. 3. Invalidation is skipped while enforcement is off (forced across an on/off authorizer transition) and is one O(cache) clear per node instead of a whole-cache scan per item. 4. TagReferencingEquipment carries alarm-bearing raw tags only (TagConfigIntent.Alarm); the snapshot adopts an OrdinalIgnoreCase set instead of copying it again. Tests (each fails with its fix reverted): FolderEventVerdictInvalidationTests (orphan + deploy + transfer; replaced instance's late event; ACL-off skip; SDK private-method guard), DeploymentArtifactScopePathTests (alarm-bearing projection).