Batch 4 contracts commit (coordinator lands before Wave A fan-out). Purely
additive so wave agents branch from a green base:
- AddressSpaceRealm enum (Raw | Uns) — the explicit realm discriminator that
travels alongside a node's s= identifier at every sink seam (WP2 adds it to
IOpcUaAddressSpaceSink / ISurgicalAddressSpaceSink; WP3 threads it).
- V3NodeIds — the two namespace URI constants (https://zb.com/otopcua/raw,
https://zb.com/otopcua/uns, replacing the single .../ns) + Raw() pass-through
(s= id == RawPath) + Uns()/UnsChild() slash-joined Area/Line/Equipment[/Eff]
builders, both sharing RawPaths.Separator + ordinal segment validation.
Placement note: URIs live in V3NodeIds (Commons) rather than beside the retired
OtOpcUaNodeManager.DefaultNamespaceUri so runtime + tests reference them without
depending on OpcUaServer (single-source-of-truth, §5). WP2 rewires the node
manager to register both via V3NodeIds.RawNamespaceUri/UnsNamespaceUri.
EquipmentNodeIds retirement is NOT in this commit: its callers are the applier +
runtime (DriverHostActor/VirtualTagHostActor/DiscoveredNodeMapper), all WP3-owned
(the composer does not use it) — deleting it here would red the base. WP3 sweeps
it in Wave B.
Claude-Session: https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox