Five operational docs rewritten for v2 (multi-process, multi-driver, Config-DB authoritative):
- docs/Configuration.md — replaced appsettings-only story with the two-layer model.
appsettings.json is bootstrap only (Node identity, Config DB connection string,
transport security, LDAP bind, logging). Authoritative config (clusters, namespaces,
UNS, equipment, tags, driver instances, ACLs, role grants, poll groups) lives in
the Config DB accessed via OtOpcUaConfigDbContext and edited through the Admin UI
draft/publish workflow. Added v1-to-v2 migration index so operators can locate where
each old section moved. Cross-links to docs/v2/config-db-schema.md + docs/v2/admin-ui.md.
- docs/Redundancy.md — Phase 6.3 rewrite. Named every class under
src/ZB.MOM.WW.OtOpcUa.Server/Redundancy/: RedundancyCoordinator, RedundancyTopology,
ApplyLeaseRegistry (publish fencing), PeerReachabilityTracker, RecoveryStateManager,
ServiceLevelCalculator (pure function), RedundancyStatePublisher. Documented the
full 11-band ServiceLevel matrix (Maintenance=0 through AuthoritativePrimary=255)
from ServiceLevelCalculator.cs and the per-ClusterNode fields (RedundancyRole,
ServiceLevelBase, ApplicationUri). Covered metrics
(otopcua.redundancy.role_transition counter + primary/secondary/stale_count gauges
on meter ZB.MOM.WW.OtOpcUa.Redundancy) and SignalR RoleChanged push from
FleetStatusPoller to RedundancyTab.razor.
- docs/security.md — preserved the transport-security section (still accurate) and
added Phase 6.2 authorization. Four concerns now documented in one place:
(1) transport security profiles, (2) OPC UA auth via LdapUserAuthenticator
(note: task spec called this LdapAuthenticationProvider — actual class name is
LdapUserAuthenticator in Server/Security/), (3) data-plane authorization via
NodeAcl + PermissionTrie + AuthorizationGate — additive-only model per decision
#129, ClusterId → Namespace → UnsArea → UnsLine → Equipment → Tag hierarchy,
NodePermissions bundle, PermissionProbeService in Admin for "probe this permission",
(4) control-plane authorization via LdapGroupRoleMapping + AdminRole
(ConfigViewer / ConfigEditor / FleetAdmin, CanEdit / CanPublish policies) —
deliberately independent of data-plane ACLs per decision #150. Documented the
OTOPCUA0001 Roslyn analyzer (UnwrappedCapabilityCallAnalyzer) as the compile-time
guard ensuring every driver-capability async call is wrapped by CapabilityInvoker.
- docs/ServiceHosting.md — three-process rewrite: OtOpcUa Server (net10 x64,
BackgroundService + AddWindowsService, hosts OPC UA endpoint + all non-Galaxy
drivers), OtOpcUa Admin (net10 x64, Blazor Server + SignalR + /metrics via
OpenTelemetry Prometheus exporter), OtOpcUa Galaxy.Host (.NET Framework 4.8 x86,
NSSM-wrapped, env-variable driven, STA thread + MXAccess COM). Pipe ACL
denies-Admins detail + non-elevated shell requirement captured from feedback memory.
Divergence from CLAUDE.md: task spec said "TopShelf is still the service-installer
wrapper per CLAUDE.md note" but no csproj in the repo references TopShelf — decision
#30 replaced it with the generic host's AddWindowsService wrapper (per the doc
comment on OpcUaServerService). Reflected the actual state + flagged this divergence
here so someone can update CLAUDE.md separately.
- docs/StatusDashboard.md — replaced the full v1 reference (dashboard endpoints,
health check rules, StatusData DTO, etc.) with a short "superseded by Admin UI"
pointer that preserves git-blame continuity + avoids broken links from other docs
that reference it.
Class references verified by reading:
src/ZB.MOM.WW.OtOpcUa.Server/Redundancy/{RedundancyCoordinator, ServiceLevelCalculator,
ApplyLeaseRegistry, RedundancyStatePublisher}.cs
src/ZB.MOM.WW.OtOpcUa.Core/Authorization/{PermissionTrie, PermissionTrieBuilder,
PermissionTrieCache, TriePermissionEvaluator, AuthorizationGate}.cs
src/ZB.MOM.WW.OtOpcUa.Server/Security/{AuthorizationGate, LdapUserAuthenticator}.cs
src/ZB.MOM.WW.OtOpcUa.Admin/{Program.cs, Services/AdminRoles.cs,
Services/RedundancyMetrics.cs, Hubs/FleetStatusPoller.cs}
src/ZB.MOM.WW.OtOpcUa.Server/Program.cs + appsettings.json
src/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Host/{Program.cs, Ipc/PipeServer.cs}
src/ZB.MOM.WW.OtOpcUa.Configuration/Entities/{ClusterNode, NodeAcl,
LdapGroupRoleMapping}.cs
src/ZB.MOM.WW.OtOpcUa.Analyzers/UnwrappedCapabilityCallAnalyzer.cs
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Current reference at the top level (docs/*.md) — describes what's shipped today. Start here for operator + integrator reference.
Implementation history + design notes at docs/v2/*.md — the authoritative plan + decision log the current reference is built from. Start here when you need the why behind an architectural choice, or when a top-level doc says "see plan.md § X".
The project was originally called LmxOpcUa (a single-driver Galaxy/MXAccess OPC UA server) and has since become OtOpcUa, a multi-driver OPC UA server platform. Any lingering LmxOpcUa-string in a path you see in docs is a deliberate residual (executable name lmxopcua-cli, client PKI folder {LocalAppData}/LmxOpcUaClient/) — fixing those requires migration shims + is tracked as follow-ups.
Platform overview
Core owns the OPC UA stack, address space, session/security/subscription machinery.
Drivers plug in via capability interfaces in ZB.MOM.WW.OtOpcUa.Core.Abstractions: IDriver, IReadable, IWritable, ITagDiscovery, ISubscribable, IHostConnectivityProbe, IAlarmSource, IHistoryProvider, IPerCallHostResolver. Each driver opts into whichever it supports.
Server is the OPC UA endpoint process (net10, x64). Hosts every driver except Galaxy in-process; talks to Galaxy via a named pipe because MXAccess COM is 32-bit-only.
Admin is the Blazor Server operator UI (net10, x64). Owns the Config DB draft/publish flow, ACL + role-grant authoring, fleet status + /metrics scrape endpoint.
Galaxy.Host is a .NET Framework 4.8 x86 Windows service that wraps MXAccess COM on an STA thread for the Galaxy driver.