# Cluster 01 — Architecture DOC: gateway.md LINES: 737–769 CLAIM: Project layout lists `src/MxGateway.Server`, `src/MxGateway.Worker`, `src/MxGateway.Contracts`, `src/MxGateway.Tests`, `src/MxGateway.Worker.Tests`, `src/MxGateway.IntegrationTests` as suggested path names. CLAIM_TYPE: path VERDICT: stale EVIDENCE: src/ directory listing — actual project directories are `ZB.MOM.WW.MxGateway.Server`, `ZB.MOM.WW.MxGateway.Worker`, `ZB.MOM.WW.MxGateway.Contracts`, `ZB.MOM.WW.MxGateway.Tests`, `ZB.MOM.WW.MxGateway.Worker.Tests`, `ZB.MOM.WW.MxGateway.IntegrationTests` CODE_AREA: arch.layout SEVERITY: medium PROPOSED_FIX: Replace all short project names in the layout block with the fully-qualified names (e.g. `src/ZB.MOM.WW.MxGateway.Server/`, `src/ZB.MOM.WW.MxGateway.Worker/`, etc.). --- DOC: gateway.md LINES: 231–248 CLAIM: `WorkerEnvelope` has `uint64 correlation_id = 4` and oneof body field numbers: `worker_hello=10, gateway_hello=11, worker_ready=12, command=20, command_reply=21, event=22, heartbeat=23, cancel=24, shutdown=25, fault=26`. CLAIM_TYPE: rpc/proto VERDICT: wrong EVIDENCE: src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_worker.proto:4,20–38 — actual proto has `string correlation_id = 4` (not uint64); body fields are `gateway_hello=10, worker_hello=11, worker_ready=12, worker_command=13, worker_command_reply=14, worker_cancel=15, worker_shutdown=16, worker_shutdown_ack=17, worker_event=18, worker_heartbeat=19, worker_fault=20`; field names also differ (e.g. `command` → `worker_command`, `event` → `worker_event`). CODE_AREA: arch.ipc SEVERITY: high PROPOSED_FIX: Replace the WorkerEnvelope protobuf block in gateway.md with the actual proto content from `mxaccess_worker.proto`, including the correct field type for `correlation_id` (string), the correct field numbers, and the correct field names. Also add the missing `WorkerShutdownAck worker_shutdown_ack = 17` entry. --- DOC: gateway.md LINES: 898–913 CLAIM: Session state machine is `Creating -> StartingWorker -> WaitingForPipe -> InitializingWorker -> Ready -> Closing -> Closed -> Faulted`. CLAIM_TYPE: behavior-rule VERDICT: stale EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Sessions/SessionWorkerClientFactory.cs:75 — code transitions to `SessionState.Handshaking` between `WaitingForPipe` and `InitializingWorker`; this state also appears in the generated proto enum (`MxaccessGateway.cs:726`, `SESSION_STATE_HANDSHAKING = 4`). CODE_AREA: arch.session SEVERITY: medium PROPOSED_FIX: Add `-> Handshaking` between `WaitingForPipe` and `InitializingWorker` in the state machine diagram, and add a description: "`Handshaking`: pipe is connected and protocol hello is being verified." --- DOC: gateway.md LINES: 119–121 CLAIM: Blazor dashboard mounts at the host root and renders pages at `/`, `/sessions`, `/workers`, `/events`, `/galaxy`, `/alarms`, `/apikeys`, and `/settings`. CLAIM_TYPE: path VERDICT: stale EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/BrowsePage.razor:1 — there is also a `/browse` page (`@page "/browse"`) that is not listed. `/login` is also present. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: Add `/browse` (and `/login`) to the list of documented dashboard routes. --- DOC: gateway.md LINES: 662–663 CLAIM: Rejects valid keys lacking the required `session, invoke, event, metadata, or admin` scope with gRPC `PermissionDenied`. CLAIM_TYPE: config-key VERDICT: stale EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Security/Authorization/GatewayScopes.cs:5–12 — actual scopes are `session:open`, `session:close`, `invoke:read`, `invoke:write`, `invoke:secure`, `events:read`, `metadata:read`, `admin`. The simplified short-form names (`session`, `invoke`, `event`) do not match the canonical scope strings. CODE_AREA: arch.auth SEVERITY: medium PROPOSED_FIX: Replace the simplified scope names with the canonical forms: `session:open`, `session:close`, `invoke:read`, `invoke:write`, `invoke:secure`, `events:read`, `metadata:read`, `admin`. --- DOC: docs/DesignDecisions.md LINES: 360–363 CLAIM: "Dashboard access should require API-key-backed dashboard authentication with `admin` scope when enabled." CLAIM_TYPE: behavior-rule VERDICT: wrong EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Dashboard/DashboardAuthenticator.cs:9 — dashboard authentication is LDAP-backed (bind + group-to-role mapping), not API-key-backed. This is also confirmed in `GatewayProcessDesign.md` lines 291–299 and `gateway.md` lines 147–156. CODE_AREA: arch.auth SEVERITY: high PROPOSED_FIX: Replace "API-key-backed dashboard authentication with `admin` scope" with "LDAP-backed authentication with `GroupToRole` mapping to `Admin` or `Viewer` roles." Keep the note about `AllowAnonymousLocalhost` for local development. --- DOC: docs/GatewayProcessDesign.md LINES: 249–255 CLAIM: Dashboard suggested routes use a `/dashboard` prefix: `/dashboard`, `/dashboard/sessions`, `/dashboard/sessions/{sessionId}`, `/dashboard/workers`, `/dashboard/events`, `/dashboard/settings`. CLAIM_TYPE: path VERDICT: wrong EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Dashboard/Components/Pages/ — actual Blazor pages are mounted at `/` (DashboardHome.razor), `/sessions` (SessionsPage.razor), `/sessions/{SessionId}` (SessionDetailsPage.razor), `/workers` (WorkersPage.razor), `/events` (EventsPage.razor), `/settings` (SettingsPage.razor), `/alarms` (AlarmsPage.razor), `/galaxy` (GalaxyPage.razor), `/browse` (BrowsePage.razor), `/apikeys` (ApiKeysPage.razor). None have a `/dashboard` prefix. CODE_AREA: arch.layout SEVERITY: high PROPOSED_FIX: Replace the `/dashboard`-prefixed route table with the actual routes: `/`, `/sessions`, `/sessions/{sessionId}`, `/workers`, `/events`, `/alarms`, `/galaxy`, `/browse`, `/apikeys`, `/settings`. --- DOC: docs/GatewayProcessDesign.md LINES: 689 CLAIM: "`Dashboard:AllowAnonymousLocalhost` permits loopback requests to bypass the cookie requirement." CLAIM_TYPE: config-key VERDICT: stale EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Configuration/DashboardOptions.cs:9 — property is `AllowAnonymousLocalhost` under `DashboardOptions`, which maps to `MxGateway:Dashboard:AllowAnonymousLocalhost`. The shorthand `Dashboard:AllowAnonymousLocalhost` omits the root `MxGateway:` prefix used throughout the project (also confirmed in GatewayProcessDesign.md line 298 which correctly uses `MxGateway:Dashboard:AllowAnonymousLocalhost`). CODE_AREA: arch.config SEVERITY: low PROPOSED_FIX: Standardize to `MxGateway:Dashboard:AllowAnonymousLocalhost` (the form used in GatewayOptions / the configuration section name) everywhere this key is referenced. --- DOC: docs/GatewayProcessDesign.md LINES: 854–855 CLAIM: Worker `ExecutablePath` default is `src/ZB.MOM.WW.MxGateway.Worker/bin/x86/Release/ZB.MOM.WW.MxGateway.Worker.exe` (forward-slash path shown in JSON block). CLAIM_TYPE: config-key VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Configuration/WorkerOptions.cs:7 — actual default is `src\ZB.MOM.WW.MxGateway.Worker\bin\x86\Release\ZB.MOM.WW.MxGateway.Worker.exe` (backslashes on Windows). The path and filename match; only the separator style differs between the JSON doc sample and the C# literal. CODE_AREA: arch.config SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/DesignDecisions.md LINES: 36 CLAIM: Interop assembly identity: `ArchestrA.MxAccess, Version=3.2.0.0, PublicKeyToken=23106a86e706d0ae`. CLAIM_TYPE: version VERDICT: unverifiable EVIDENCE: src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessInteropInfo.cs — the file records the assembly path and name (`ArchestrA.MxAccess`) but does not hard-code the version or public key token; `InteropAssemblyVersion` is read dynamically from the loaded assembly at runtime (`typeof(LMXProxyServerClass).Assembly.GetName().Version`). Cannot verify the exact version string without MXAccess installed. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/DesignDecisions.md LINES: 36–48 CLAIM: COM class `ArchestrA.MxAccess.LMXProxyServerClass`, CLSID `{C30B52F5-2CB5-4760-AF0A-3A344A7EB5DC}`, ProgID `LMXProxy.LMXProxyServer.1`, version-independent ProgID `LMXProxy.LMXProxyServer`, registered server `C:\Program Files (x86)\ArchestrA\Framework\Bin\LmxProxy.dll`, interop assembly `C:\Program Files (x86)\ArchestrA\Framework\Bin\ArchestrA.MXAccess.dll`. CLAIM_TYPE: config-key VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessInteropInfo.cs:14,19,24,29–30,35–36,41 — `ComClassName = "ArchestrA.MxAccess.LMXProxyServerClass"`, `Clsid = "{C30B52F5-2CB5-4760-AF0A-3A344A7EB5DC}"`, `ProgId = "LMXProxy.LMXProxyServer.1"`, `VersionIndependentProgId = "LMXProxy.LMXProxyServer"`, `RegisteredServerPath = @"C:\Program Files (x86)\ArchestrA\Framework\Bin\LmxProxy.dll"`, `InteropAssemblyPath = @"C:\Program Files (x86)\ArchestrA\Framework\Bin\ArchestrA.MXAccess.dll"`. All match. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/DesignDecisions.md LINES: 55 CLAIM: Worker should reference `ArchestrA.MXAccess.dll` (upper-case MXAccess in filename). CLAIM_TYPE: path VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Worker/ZB.MOM.WW.MxGateway.Worker.csproj:27 — `C:\Program Files (x86)\ArchestrA\Framework\Bin\ArchestrA.MXAccess.dll`. Matches. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 88–94 CLAIM: Gateway runtime is `.NET 10`, `C#`, `x64 preferred`, `ASP.NET Core gRPC server`. CLAIM_TYPE: version VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/ZB.MOM.WW.MxGateway.Server.csproj:4 — `net10.0`; no explicit `` is set (so the default is AnyCPU/x64-preferred on .NET 10). Grpc.AspNetCore is referenced. Matches. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 162–165 CLAIM: Worker runtime is `.NET Framework 4.8`, `C#`, `x86 build by default`. CLAIM_TYPE: version VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Worker/ZB.MOM.WW.MxGateway.Worker.csproj:5–7 — `net48`, `x86`, `true`. Matches. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 198–210 CLAIM: Pipe name format is `mxaccess-gateway-{gatewayProcessId}-{sessionId}` and framing is `uint32 little-endian payload_length` followed by `payload_length bytes protobuf WorkerEnvelope`. CLAIM_TYPE: rpc/proto VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Sessions/SessionManager.cs:433 — `string pipeName = $"mxaccess-gateway-{Environment.ProcessId}-{sessionId}"`. Framing confirmed by `WorkerFrameReader.cs` and `WorkerFrameWriter.cs` in `src/ZB.MOM.WW.MxGateway.Server/Workers/`. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 108 CLAIM: "The gateway must never instantiate or call MXAccess directly." CLAIM_TYPE: behavior-rule VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/ZB.MOM.WW.MxGateway.Server.csproj — no reference to `ArchestrA.MXAccess.dll`. MXAccess COM is only referenced in the Worker project csproj (line 26–29). CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 646–650 CLAIM: Gateway restart does not reattach old workers; `OrphanWorkerCleanupHostedService` runs `OrphanWorkerTerminator` once on startup to kill leftover `ZB.MOM.WW.MxGateway.Worker.exe` processes. CLAIM_TYPE: behavior-rule VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Workers/OrphanWorkerCleanupHostedService.cs:7 — class exists and references `OrphanWorkerTerminator`. `OrphanWorkerTerminator.cs:19` is present. Worker executable name `ZB.MOM.WW.MxGateway.Worker.exe` confirmed in `IntegrationTestEnvironment.cs:66`. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 420–428 CLAIM: Pipe name format is `mxaccess-gateway-{gatewayProcessId}-{sessionId}` and framing is `uint32 little-endian payload_length` followed by `payload_length bytes protobuf WorkerEnvelope`. CLAIM_TYPE: rpc/proto VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Sessions/SessionManager.cs:433 — confirmed matching. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 459–475 CLAIM: `IWorkerClient` has methods `StartAsync`, `InvokeAsync(WorkerCommand, TimeSpan, CancellationToken)`, `ReadEventsAsync(CancellationToken)`, `ShutdownAsync(TimeSpan, CancellationToken)`, `Kill(string)`. CLAIM_TYPE: rpc/proto VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Workers/IWorkerClient.cs:22,28–31,35,40,44 — all five methods are present with matching signatures. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 713–719 CLAIM: API-key admin CLI subcommands are `init-db`, `create-key`, `list-keys`, `revoke-key`, `rotate-key` on `ZB.MOM.WW.MxGateway.Server apikey`. CLAIM_TYPE: command VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Security/Authentication/ApiKeyAdminCommandLineParser.cs:121–135 — all five subcommands are parsed. Matches. CODE_AREA: arch.auth SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 408–410 CLAIM: Nonce is passed via `MXGATEWAY_WORKER_NONCE` environment variable so the command line remains safe to log. CLAIM_TYPE: config-key VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Workers/WorkerProcessLauncher.cs:17–18 — `public const string WorkerNonceEnvironmentVariableName = "MXGATEWAY_WORKER_NONCE"`. Matches. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 223–229 CLAIM: `EventStreamService` rejects a second subscriber with `EventSubscriberAlreadyActive`; faults the session with `EventQueueOverflow` if the queue fills. CLAIM_TYPE: term VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Sessions/SessionManagerErrorCode.cs:7–8 — enum values `EventSubscriberAlreadyActive` and `EventQueueOverflow` present. Also used at `MxAccessGatewayService.cs:929–930` and `EventStreamService.cs:150,160`. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 291–299 CLAIM: Dashboard auth uses LDAP bind + role mapping (`MxGateway:Dashboard:GroupToRole`), issues HTTP-only secure cookie, allows `Dashboard:AllowAnonymousLocalhost` to default to `true`. CLAIM_TYPE: behavior-rule VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Dashboard/DashboardAuthenticator.cs:9 (LDAP-backed); `DashboardOptions.cs:9` (`AllowAnonymousLocalhost` defaults to `true`). Matches. CODE_AREA: arch.auth SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 527–530 CLAIM: "During shutdown the worker client treats `WorkerShutdownAck` as the protocol close signal." CLAIM_TYPE: rpc/proto VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_worker.proto:34,80 — `WorkerShutdownAck` is field 17 in the oneof body and its message is defined at line 80. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 301–314 CLAIM: Session state machine (in the "Session Manager" section): `Creating -> StartingWorker -> WaitingForPipe -> InitializingWorker -> Ready -> Closing -> Closed -> Faulted`. CLAIM_TYPE: behavior-rule VERDICT: stale EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Sessions/SessionWorkerClientFactory.cs:75 — `session.TransitionTo(SessionState.Handshaking)` is called between `WaitingForPipe` and `InitializingWorker`. The `Handshaking` state also exists in the public `SessionState` proto enum (`MxaccessGateway.cs:726`). The state machine in gateway.md at this location (the Gateway Implementation Plan / Session Manager section) is missing the `Handshaking` state exactly as in the earlier reference at lines 898–913. CODE_AREA: arch.session SEVERITY: medium PROPOSED_FIX: Add `-> Handshaking` between `WaitingForPipe` and `InitializingWorker` in both state machine diagrams in gateway.md. --- DOC: gateway.md LINES: 1023–1025 CLAIM: "MXAccess COM target is `ArchestrA.MxAccess.LMXProxyServerClass` / `LMXProxy.LMXProxyServer.1` from the installed 32-bit `LmxProxy.dll`." CLAIM_TYPE: term VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessInteropInfo.cs:14,41 — `ComClassName = "ArchestrA.MxAccess.LMXProxyServerClass"`, `ProgId = "LMXProxy.LMXProxyServer.1"`, registered server `LmxProxy.dll`. Matches. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 62–93 CLAIM: High-level component list references namespace `ZB.MOM.WW.MxGateway.Server` with sub-components including `GatewayMetrics` (under `Metrics`) and `HealthChecks` (under `Diagnostics`). CLAIM_TYPE: term VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Metrics/GatewayMetrics.cs:4 — `namespace ZB.MOM.WW.MxGateway.Server.Metrics`; src/ZB.MOM.WW.MxGateway.Server/Diagnostics/AuthStoreHealthCheck.cs:5 — `namespace ZB.MOM.WW.MxGateway.Server.Diagnostics`. Matches. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 110–116 CLAIM: Gateway observability foundation lives in `ZB.MOM.WW.MxGateway.Server.Diagnostics` and `ZB.MOM.WW.MxGateway.Server.Metrics`; `GatewayMetrics` exposes counters/gauges/histograms through .NET `Meter`; `DashboardSnapshotService` projects sessions/workers/metrics into immutable DTOs. CLAIM_TYPE: term VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Metrics/GatewayMetrics.cs:4; src/ZB.MOM.WW.MxGateway.Server/Dashboard/DashboardSnapshotService.cs:8. Both namespaces confirmed. Matches. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 119–121 CLAIM: SignalR hubs at `/hubs/{snapshot,alarms,events}` accept either the cookie or a 30-minute bearer minted at `/hubs/token`. CLAIM_TYPE: path VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Dashboard/DashboardEndpointRouteBuilderExtensions.cs:63–65,73 — `MapHub("/hubs/snapshot")`, `MapHub("/hubs/alarms")`, `MapHub("/hubs/events")`, `/hubs/token` endpoint mapped at line 73. Matches. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 121–122 CLAIM: "`/hubs/events` mirrors per-session `MxEvent` traffic from `EventStreamService` to clients subscribed to `session:{id}`." CLAIM_TYPE: term VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Dashboard/Hubs/EventsHub.cs:27 — `public static string GroupName(string sessionId) => $"session:{sessionId}"`. Matches. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 864–893 CLAIM: Configuration JSON block shows `MxGateway:Worker:ExecutablePath`, `MxGateway:Sessions:AllowMultipleEventSubscribers`, `MxGateway:Events:QueueCapacity`, `MxGateway:Protocol:WorkerProtocolVersion`, etc. CLAIM_TYPE: config-key VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Configuration/WorkerOptions.cs:6–7,13 — `ExecutablePath` and `RequiredArchitecture` match; `SessionOptions.cs` and `EventsOptions` confirm the other keys through bound configuration. CODE_AREA: arch.config SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/DesignDecisions.md LINES: 85–95 CLAIM: The single-subscriber rule for `StreamEvents` no longer applies to alarms. `GatewayAlarmMonitor` owns one gateway-managed worker session, fans alarm state to any number of clients through session-less `StreamAlarms`. `AcknowledgeAlarm` is session-less and routes through the monitor. CLAIM_TYPE: behavior-rule VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Alarms/GatewayAlarmMonitor.cs:17 — class exists. `MxAccessGatewayService.cs:167` — `StreamAlarms` and `AcknowledgeAlarm` are session-less. Matches. CODE_AREA: arch.session SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/DesignDecisions.md LINES: 217–225 CLAIM: Bulk commands are `AddItemBulk`, `AdviseItemBulk`, `RemoveItemBulk`, `UnAdviseItemBulk`, `SubscribeBulk`, `UnsubscribeBulk`, `WriteBulk`, `Write2Bulk`, `WriteSecuredBulk`, `WriteSecured2Bulk`, `ReadBulk`. Each runs single-item MXAccess COM calls sequentially on the STA; per-entry failures are non-throwing. CLAIM_TYPE: rpc/proto VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_gateway.proto — all eleven bulk command kinds are present in the `MxCommandKind` enum and corresponding request/reply messages. Verified by cross-referencing `GatewayGrpcScopeResolver.cs:39` which maps `WriteBulk`, `Write2Bulk`, etc. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 129–130 CLAIM: "`/browse` walks the `IGalaxyHierarchyCache` tree and reads subscribed tag values live through `IDashboardLiveDataService`." CLAIM_TYPE: term VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Server/Dashboard/IDashboardBrowseService.cs — `IDashboardBrowseService` references `IGalaxyHierarchyCache`. `IDashboardLiveDataService.cs` exists in the same Dashboard directory. `/browse` page confirmed in `BrowsePage.razor:1`. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 2–19 CLAIM: Gateway preserves MXAccess behavior first, including public MXAccess command semantics, native MXAccess event families, STA/message-pump delivery behavior, HRESULT/status/value marshaling, and per-client isolation. "Installed MXAccess COM component is the compatibility baseline." CLAIM_TYPE: behavior-rule VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Worker/MxAccess/MxAccessInteropInfo.cs (installs/references real COM interop); docs/DesignDecisions.md:26–28 — "target the installed MXAccess COM interop surface directly from the x86 worker." Consistent across all three docs. CODE_AREA: arch.layout SEVERITY: low PROPOSED_FIX: flag only --- DOC: docs/GatewayProcessDesign.md LINES: 100–105 CLAIM: gRPC service surface at this stage is limited to `OpenSession`, `CloseSession`, `Invoke`, `StreamEvents` (with `Session(stream ClientMessage) returns (stream ServerMessage)` deferred). CLAIM_TYPE: rpc/proto VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_gateway.proto — `MxAccessGateway` service defines `OpenSession`, `CloseSession`, `Invoke`, `StreamEvents`, and additional alarm/galaxy RPCs. The bidirectional `Session` RPC is not present in the current proto, consistent with the deferral noted in the doc. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only --- DOC: gateway.md LINES: 266–273 CLAIM: Public gRPC service is `MxAccessGateway` with `OpenSession`, `CloseSession`, `Invoke`, `StreamEvents`, and deferred bidirectional `Session` RPC. CLAIM_TYPE: rpc/proto VERDICT: accurate EVIDENCE: src/ZB.MOM.WW.MxGateway.Contracts/Protos/mxaccess_gateway.proto — confirmed. The `Session` bidirectional RPC is absent as expected for deferred rollout. CODE_AREA: arch.ipc SEVERITY: low PROPOSED_FIX: flag only