Files
mxaccessgw/MxAccessGateway-doc-audit.md

600 lines
59 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MXAccess Gateway — Documentation Audit Findings
Synthesized from the 13 audit fragments under `docs/audit/fragments/`. This report drives the fix phase (Tasks 1522). It is read-only with respect to code and the audited docs; the only artifact produced is this file.
## 1. Summary
Total findings: **186** across 13 clusters.
### Counts by verdict
| Verdict | Count |
|---|---|
| accurate | 109 |
| stale | 27 |
| wrong | 33 |
| unverifiable | 6 |
| gap | 24 |
(Note: a small number of cluster-08 entries are verdict-tagged `accurate` in the fragment body while the prose flags a phrasing nuance; they are counted as `accurate`.)
### Counts by severity
| Severity | Count |
|---|---|
| high | 33 |
| medium | 33 |
| low | 120 |
### Per-cluster table
| Cluster | #high | #med | #low | #gap (any sev) |
|---|---|---|---|---|
| 01 Architecture | 3 | 4 | 33 | 0 |
| 02 Worker | 5 | 6 | 30 | 4 |
| 03 Sessions | 2 | 8 | 18 | 6 |
| 04 Auth | 11 | 7 | 14 | 5 |
| 05 Dashboard | 7 | 9 | 8 | 6 |
| 06 Config | 2 | 3 | 27 | 4 |
| 07 Contracts/gRPC | 3 | 3 | 22 | 3 |
| 08 Galaxy | 5 | 3 | 41 | 6 |
| 09 Alarms | 7 | 6 | 22 | 8 |
| 10 Testing | 2 | 0 | 30 | 2 |
| 11 Clients | 7 | 5 | 18 | 3 |
| 12 Style guides | 3 | 1 | 10 | 0 |
| 13 History/Plans | 0 | 1 | 21 | 0 |
(`#high/#med/#low` count all findings at that severity in the cluster; `#gap` counts gap-verdict findings regardless of severity, shown separately because gaps are additive work rather than corrections.)
---
## 2. Global substitutions table
Mechanical string replacements that recur across multiple docs or are pure find-and-replace. The "applies to" list contains **only** files the fragment evidence shows actually contain the old string. CLAUDE.md is a living doc and is listed explicitly where the evidence targets it. Per the audit rules, design-history / plan docs (cluster 13) are **excluded** from these applies-to lists — their term occurrences are historical records, not corrected here (only their broken internal cross-refs are fixed, in Task 22).
| old string | new string | claim_type | applies to (doc list) |
|---|---|---|---|
| `Admin` (dashboard role value) | `Administrator` | term | CLAUDE.md (L119, L234-evidence); docs/GatewayConfiguration.md (L55, L156); docs/DashboardInterfaceDesign.md (role labels where used as config value); docs/Authorization.md (L215 — judgment, see Task 18) |
| cookie `__Host-MxGatewayDashboard` | `MxGatewayDashboard` | config-key/term | CLAUDE.md (L119); docs/GatewayDashboardDesign.md (L420422) |
| `src/MxGateway.sln` | `src/ZB.MOM.WW.MxGateway.slnx` | path | CLAUDE.md (L22) |
| `src/MxGateway.Server/MxGateway.Server.csproj` (short project paths in layout/commands) | `src/ZB.MOM.WW.MxGateway.Server/ZB.MOM.WW.MxGateway.Server.csproj` (and sibling fully-qualified names) | path | gateway.md (L737769); CLAUDE.md (L35, L248-evidence) |
| `clients/dotnet/MxGateway.Client.sln` | `clients/dotnet/ZB.MOM.WW.MxGateway.Client.slnx` | path | CLAUDE.md (L57, L93); docs/ClientPackaging.md (L5152) |
| `clients/python/src/mxgateway/generated` | `clients/python/src/zb_mom_ww_mxgateway/generated` | path | docs/ClientProtoGeneration.md (L80, L7481 table, L145); docs/ClientLibrariesDesign.md (L410); docs/ClientPackaging.md (L159160); docs/style-guides/PythonStyleGuide.md (L2729 parent path) |
| Python package `mxaccess-gateway-client` | `zb-mom-ww-mxaccess-gateway-client` | config-key | docs/ClientPackaging.md (L159160); clients/python/PythonClientDesign.md (L215) |
| Python module `mxgateway_cli` | `zb_mom_ww_mxgateway_cli` | command/path | docs/ClientPackaging.md (L187); docs/style-guides/PythonStyleGuide.md (L2729) |
| Python library package `mxgateway` (src dir) | `zb_mom_ww_mxgateway` | path | docs/style-guides/PythonStyleGuide.md (L2729) |
| Gradle task `:mxgateway-cli:` | `:zb-mom-ww-mxgateway-cli:` | command | docs/GatewayTesting.md (L322324); docs/ClientPackaging.md (L193227) |
| Gradle task `:mxgateway-client:` | `:zb-mom-ww-mxgateway-client:` | command | docs/ClientPackaging.md (L193227) |
| logger category `ZB.MOM.WW.MxGateway.Request` | `MxGateway.Request` | term | docs/Diagnostics.md (L165166) |
| STA thread name `ZB.MOM.WW.MxGateway.Worker.STA` | `MxGateway.Worker.STA` | term | docs/WorkerSta.md (L23, L29); docs/MxAccessWorkerInstanceDesign.md (L254) |
| Java package root `com.dohertylan.mxgateway` | `com.zb.mom.ww.mxgateway` | config-key | docs/style-guides/JavaStyleGuide.md (L25) |
| Rust crate `mxgateway-client` (library crate name) | `zb-mom-ww-mxgateway-client` | term | docs/ClientPackaging.md (L116) |
| dashboard route prefix `/dashboard*` | `/` + `/sessions`, `/workers`, `/events`, `/alarms`, `/galaxy`, `/browse`, `/apikeys`, `/settings` | path | docs/GatewayProcessDesign.md (L249255); docs/GatewayDashboardDesign.md (L289345); docs/GalaxyRepository.md (L419422) |
Notes:
- The scope-shorthand renames (`session``session:open`/`session:close`, `invoke``invoke:read`/`invoke:write`/`invoke:secure`, `event``events:read`, `metadata``metadata:read`) are **not** a single 1:1 mechanical substitution (one shorthand maps to multiple canonical scopes), so they are handled as judgment edits in Tasks 18/20, not in this table. The affected docs are gateway.md (L662663), CLAUDE.md (L35, L117, L248-evidence), docs/Authentication.md (L99, L187208).
- The `wwwroot/css/dashboard.css``site.css` rename is dashboard-cluster-specific (single doc family) and is handled in Task 19.
---
## 3. Out-of-prose-scope flags
These findings target **non-`.md`** files. They are real bugs but outside this prose audit. **Flag only — recommend separate fix.** Do not schedule them for doc-editing tasks.
| Finding ID | File | Issue | Severity |
|---|---|---|---|
| F-10-2 | `clients/proto/fixtures/smoke/cross-language-smoke-matrix.json` | Every Java command entry uses `gradle :mxgateway-cli:run`; the Gradle subproject is `:zb-mom-ww-mxgateway-cli`. Verbatim execution fails; `CrossLanguageSmokeMatrixTests` does not check the literal task name, so it passes CI undetected. | high |
(No other fragment finding targets a non-`.md` artifact for an edit; `proto-inputs.json`, `appsettings.json`, source `.cs/.rs/.go/.gradle/.toml` etc. appear only as evidence, not as edit targets.)
---
## 4. Per-doc findings
Findings grouped by DOC, ordered high→low severity within each doc. IDs are `F-<cluster#>-<n>` numbered in fragment order within the cluster.
### gateway.md
- **F-01-13** — L231248 — wrong/high — `WorkerEnvelope` proto block (field type/numbers/names). EVIDENCE: `mxaccess_worker.proto` has `string correlation_id = 4` (not uint64); body fields `gateway_hello=10 … worker_fault=20`; names differ (`command``worker_command`, `event``worker_event`); missing `worker_shutdown_ack=17`. FIX: replace the block with actual proto content.
- **F-01-1** — L737769 — stale/medium — short project names in layout. FIX: use fully-qualified `src/ZB.MOM.WW.MxGateway.*` names (see substitutions).
- **F-01-2** — L898913 — stale/medium — session state machine missing `Handshaking`. FIX: insert `-> Handshaking` between `WaitingForPipe` and `InitializingWorker`.
- **F-01-12** — L301314 — stale/medium — second session state-machine diagram also missing `Handshaking`. FIX: same insertion in both diagrams.
- **F-01-3** — L119121 — stale/medium — scope rejection lists shorthand scope names. FIX: canonical scope strings (judgment, see Task 18 note).
- **F-01-4** — L119121 — stale/low — dashboard route list omits `/browse` and `/login`. FIX: add them.
- **F-01 accurate set** — multiple (L8894, 108, 110122, 129130, 162210, 266273, 646650, 10231025, 219) — accurate/low — flag only.
### docs/GatewayProcessDesign.md
- **F-01-7** — L249255 — wrong/high — `/dashboard`-prefixed route table. FIX: replace with actual no-prefix routes (see substitutions).
- **F-01-8** — L689 — stale/low — `Dashboard:AllowAnonymousLocalhost` missing `MxGateway:` root prefix. FIX: standardize to `MxGateway:Dashboard:AllowAnonymousLocalhost`.
- **F-01-9** — L854855 — accurate/low — worker `ExecutablePath` default (separator style only). Flag only.
- **F-01 accurate set** — L6293, 100105, 223229, 291299, 408410, 420475, 527530, 713719, 864893 — accurate/low — flag only.
### docs/DesignDecisions.md
- **F-01-6** — L360363 — wrong/high — claims dashboard auth is "API-key-backed dashboard authentication with `admin` scope." EVIDENCE: `DashboardAuthenticator.cs` is LDAP-backed with `GroupToRole`. FIX: rewrite to LDAP-backed + `GroupToRole``Admin`/`Viewer`; keep `AllowAnonymousLocalhost` note.
- **F-01-10** — L36 — unverifiable/low — interop assembly version/PKT not hard-coded in repo. Flag only.
- **F-01-11** — L3648 — accurate/low — COM class/CLSID/ProgID/paths. Flag only.
- **F-01-14** — L55 — accurate/low — `ArchestrA.MXAccess.dll` casing. Flag only.
- **F-01 accurate set** — L8595, 217225 — accurate/low — flag only.
### docs/WorkerSta.md
- **F-02-1** — L2331 — wrong/medium — STA thread name `ZB.MOM.WW.MxGateway.Worker.STA`. FIX: `MxGateway.Worker.STA` (prose + snippet) (substitution).
- **F-02-3** — L144 — wrong/medium — `InvokeAsync` throws `InvalidOperationException`. EVIDENCE: throws `StaRuntimeShutdownException` (subtype). FIX: name the subtype and explain why the distinction matters.
- **F-02-19** — L141148 — stale/medium — shutdown drain sequence implies single post-stop drain. EVIDENCE: `CancelQueuedCommands` runs inside `ThreadMain` finally before `stoppedEvent.Set()`, and again in `Shutdown()`; drain happens twice. FIX: revise steps 34.
- **F-02-12** — L14 — stale/low — "Bounded asynchronous queue." EVIDENCE: plain `Queue<T>` under lock with async drain loop. FIX: "Bounded queue with an async drain loop."
- **F-02 accurate set** — L34, 56, 6378, 8299, 108, 149 — accurate/low — flag only.
### docs/MxAccessWorkerInstanceDesign.md
- **F-02-4** — L122 — wrong/high — `Success` (exit 0) = "bootstrap options valid." EVIDENCE: actual meaning "pipe session ran to a clean close." FIX: correct Success row; note `WorkerBootstrapResult.Succeeded` is a parse-phase gate distinct from exit 0.
- **F-02-5** — L119128 — stale/high — exit-code table missing codes 5 (`PipeConnectionFailed`) and 6 (`ProtocolViolation`). FIX: add both rows.
- **F-02-6** — L134160 — stale/high — component tree class names wrong (`WorkerHost``WorkerApplication`, `PipeClient``WorkerPipeClient`, `FrameReader/Writer``WorkerFrameReader/Writer`, `WorkerProtocol``WorkerContractInfo`, `StaCommandQueue``StaCommandDispatcher`, `MessagePump``StaMessagePump`, `StaWatchdog``WorkerPipeSession`, `MxAccessCommandDispatcher``MxAccessCommandExecutor`, `SafeArrayConverter`→part of `VariantConverter`, `StatusProxyConverter``MxStatusProxyConverter`, `HResultMapper``HResultConverter`). FIX: rewrite tree.
- **F-02-15** — L97 — wrong/high — `MXGATEWAY_WORKER_LOG_CONTEXT` env var documented. EVIDENCE: not read anywhere. FIX: remove or mark unimplemented.
- **F-02-16** — L8699 — wrong/high — same `MXGATEWAY_WORKER_LOG_CONTEXT` in bootstrap sequence. FIX: flag-only duplicate of F-02-15.
- **F-02-22** — L134160 — gap/high — no alarm subsystem in component tree. FIX: add "Alarm Subsystem" section (consumer, poll loop, dispatcher, sink).
- **F-02-2** — L254 — wrong/medium — STA thread name. FIX: `MxGateway.Worker.STA` (substitution).
- **F-02-20** — L134160 — stale/medium — `MxAccess` subtree class names (`MxAccessCommandDispatcher` does not exist; add `MxAccessStaSession`, `MxAccessCommandExecutor`, alarm sinks). FIX: update.
- **F-02-23** — L336338 — gap/medium — event-sink subscription list omits alarm events. FIX: add `MxAccessAlarmEventSink`.
- **F-02-18** — L368375 — stale/low — `MxAccessEventQueue.Enqueue` also throws `MxAccessEventQueueOverflowException`. FIX: note thrown exception.
- **F-02-26** — L151 — accurate/low — `MxAccessSession` exists. Flag only.
- **F-02 accurate set** — L271286, 656660 — accurate/low — flag only.
### docs/WorkerBootstrap.md
- **F-02-7** — L146 — stale/medium — stderr/stdout-capture rationale. EVIDENCE: launcher redirects neither stream. FIX: replace rationale; the env-var-secrecy reason is the accurate one.
- **F-02-25** — L56 — stale/low — "short-lived child." FIX: "per-session child process."
- **F-02 accurate set** — L78, 4854, 105, 113120, 155159, 181193 — accurate/low — flag only.
### docs/WorkerConversion.md
- **F-02-21** — L1262 — gap/medium — inverse projection (`ConvertToComValue`/`ConvertToComArray`, write path) undocumented. FIX: add "Inverse projection for COM writes" section.
- **F-02-11** — L225 — stale/low — engine-error ranges implied contiguous; gaps exist (35,45,46 / 58,59). FIX: "selected detail codes in the ranges …".
- **F-02 accurate set** — L1718, 112135, 178 — accurate/low — flag only.
### docs/WorkerFrameProtocol.md / docs/WorkerProcessLauncher.md
- All findings accurate/low (F-02 frameproto and launcher accurate set: WorkerFrameProtocol L1453; WorkerProcessLauncher L1864). Flag only.
### docs/Sessions.md
- **F-03-22** — gap/high — orphan cleanup (`OrphanWorkerCleanupHostedService``OrphanWorkerTerminator.TerminateOrphans` on startup, best-effort) undocumented. FIX: add "Gateway Restart / Orphan Cleanup" section.
- **F-03-21** — L230 — wrong/high — invents metric names `KillCount`/`ShutdownCount`. EVIDENCE: actual counter is `mxgateway.workers.killed`. FIX: replace with real counter via `GatewayMetrics.WorkerKilled`.
- **F-03-1** — L9 — wrong/medium — "All four interfaces" (only three exist) and omits `SessionLeaseMonitorHostedService`. FIX: "three interfaces"; list two hosted services.
- **F-03-2** — L265276 — stale/medium — DI snippet omits `SessionLeaseMonitorHostedService`. FIX: add the registration line.
- **F-03-3** — L232259 — stale/medium — `ShutdownAsync` snippet predates Server-045/046; fallback now routes via `KillWorkerAsync`. FIX: replace snippet.
- **F-03-4** — L5559 — stale/medium — `KillWorkerAsync` no longer calls `GatewaySession.KillWorker` directly; now `KillWorkerWithCloseGateAsync` (acquires `_closeLock`). FIX: update.
- **F-03-12** — L163188 — stale/medium — open-failure rollback order omits conditional `SessionRemoved()` (Server-006). FIX: note the conditional metric call before `ReleaseSessionSlot`.
- **F-03-19** — L230 — stale/medium — `GatewaySession.KillWorker` no longer the entry point from `SessionManager`. FIX: clarify `KillWorkerWithCloseGateAsync` is the path.
- **F-03-23** — gap/medium — `AllowMultipleEventSubscribers=true` rejected at startup by `GatewayOptionsValidator`. FIX: note startup-validation refusal.
- **F-03-7** — L265 — wrong/medium — "the hosted service" (singular). FIX: "two hosted services."
- **F-03-20** — L279 — stale/low — registration-order reasoning. FIX: note two hosted services + DI ordering caveat.
- **F-03-24** — gap/low — `_items` registration dictionary undocumented. FIX: add paragraph.
- **F-03-25** — gap/low — `MaxPendingCommandsPerSession` (128) cap undocumented. FIX: add note.
- **F-03-26** — gap/low — `KillWorkerWithCloseGateAsync` unmentioned. FIX: mention in Close section.
- **F-03 accurate set** — L15127, 134227, 195197, 197 (lease/sweep) — accurate/low — flag only.
### docs/Authentication.md
- **F-04-1** — L253271 — stale/high — Registration block is pre-migration; types now from `ZB.MOM.WW.Auth.ApiKeys` via `AddZbApiKeyAuth`. FIX: replace block; remove "registers the migration hosted service" claim.
- **F-04-9** — L187208 — wrong/high — CLI example `--scopes read,write` + subcommand `create`. EVIDENCE: scopes invalid; subcommand is `create-key`. FIX: canonical scopes (e.g. `invoke:read,invoke:write`), `create-key`.
- **F-04-2** — L5368 — stale/medium — `ApiKeySecretHasher` etc. are shared-library types; return type `ApiKeyVerification` not `ApiKeyVerificationResult`. FIX: clarify ownership + type name.
- **F-04-3** — L7298 — stale/medium — `ApiKeyVerifier` types/return shapes from shared package. FIX: `ApiKeyVerification`; note shared lib.
- **F-04-5** — L126133 — stale/medium — schema table omits `audit_event` table; `api_key_audit` no longer written. FIX: add fourth table + note.
- **F-04-4** — L108122 — stale/low — `AuthSqliteConnectionFactory` ownership/`ApiKeyOptions.SqlitePath`. FIX: clarify.
- **F-04-6** — L134153 — stale/low — `SqliteApiKeyStore` from shared package. FIX: label code block as shared-lib.
- **F-04-7** — L156164 — stale/low — `SqliteApiKeyAdminStore` shared; CLI uses `ApiKeyAdminCommands`. FIX: clarify.
- **F-04-8** — L165183 — stale/low — `SqliteAuthStoreMigrator` etc. shared. FIX: clarify.
- **F-04-10** — L229248 — stale/low — `ApiKeyScopeSerializer` shared. FIX: note.
- **F-04-gap-3** — gap/medium — `api_key_audit` unused at runtime; all audit → `audit_event`. FIX: document.
- **F-04-gap-2** — gap/medium — 8-hour cookie idle timeout + 30-min hub token undocumented. FIX: add.
- **F-04-gap-1** — gap/medium — `MxGateway:Dashboard:CookieName` override undocumented. FIX: document.
- **F-04-gap-4** — gap/low — `RequireHttpsCookie` undocumented. FIX: reference.
- **F-04-gap-5** — gap/low — `ZbClaimTypes`/`ZbCookieDefaults` undocumented. FIX: brief note.
- **F-04 accurate set** — L130, 110, 189208, 220225 — accurate/low — flag only.
### docs/Authorization.md
- **F-04-11** — L107113 — stale/high — scope resolver block omits `BrowseChildrenRequest => MetadataRead`. FIX: add it.
- **F-04-12** — L212 — stale/high — scope catalog table omits `GalaxyRepository.BrowseChildren`. FIX: add to `MetadataRead` row.
- **F-04-18** — L205215 — stale/high — same catalog gap (`BrowseChildren`). FIX: as above.
- **F-04-13** — L260270 — stale/medium — registration block omits `IConstraintEnforcer`/`ConstraintEnforcer` and `GrpcServiceOptions` size limits. FIX: add.
- **F-04-16** — L215 — stale/medium — claims `GatewayScopes.Admin` referenced by `DashboardAuthenticator`. EVIDENCE: dashboard role `Administrator` and gRPC scope `admin` are separate. FIX: correct/remove the claim.
- **F-04-14** — L273 — stale/low — "three classes" → four (adds `ConstraintEnforcer`). FIX: update.
- **F-04 accurate set** — L85, 94116 — accurate/low — flag only.
### glauth.md
- **F-04-15** — L6366 — wrong/high — `LdapOptions.RequiredGroup` defaults to `GwAdmin`. EVIDENCE: no `RequiredGroup` exists; membership enforced via `GroupToRole`. FIX: rewrite.
- **F-04-17** — L181182 — wrong/high — "strips to `GwAdmin` and matches against `RequiredGroup`." FIX: "looks up the short RDN in `GroupToRole`."
- **F-04-19** — L113136 — wrong/high — YAML keys `useTls`/`allowInsecureLdap`/`userNameAttribute`. EVIDENCE: actual `Transport`/`AllowInsecure`/`UserNameAttribute`(default `cn`); section header `MxGateway:Ldap`. FIX: rewrite YAML.
- **F-04-21** — L261269 — wrong/high — AD cheat-sheet `UseTls`/`AllowInsecureLdap`. EVIDENCE: renamed `Transport`/`AllowInsecure`. FIX: rename rows.
- **F-04-20** — L128 — wrong/medium — `userNameAttribute: "uid"`. EVIDENCE: default is `cn`. FIX: change to `cn` + note.
- **F-04-22** — L7074 — accurate/low — Task 1.7 role note. Flag only.
- **F-04-23** — L2126 — accurate/low — connection details. Flag only.
### CLAUDE.md (auth-related judgment fixes — Task 18)
- **F-04-24** — L119 — wrong/high — cookie `__Host-MxGatewayDashboard` and role `Admin`. FIX: `MxGatewayDashboard` + `Administrator` (substitutions).
- **F-04-25** — L119 — wrong/high — LDAP groups map to `Admin`. FIX: `Administrator`.
- **F-04-26** — L35 — wrong/high — apikey example `create --scopes session,invoke,event,metadata,admin`. FIX: `create-key` + canonical scopes.
- **F-04-27** — L117 — wrong/high — scopes shorthand `session, invoke, event, metadata, admin`. FIX: canonical scope strings (SQLite path is correct, keep).
### docs/DashboardInterfaceDesign.md
- **F-05-1** — L3957 — stale/high — `dashboard-shell`/`dashboard-navbar` HTML skeleton. EVIDENCE: now `ThemeShell` side rail. FIX: replace skeleton/prose.
- **F-05-2** — L115123 — stale/high — five flat nav labels incl. "Overview." EVIDENCE: eight items in three groups; home is "Dashboard." FIX: update.
- **F-05-3** — L6379 — wrong/high — `--mxgw-*` CSS tokens. EVIDENCE: none exist; all via theme kit tokens. FIX: remove table; note theme-kit tokens.
- **F-05-7** — L191200 — wrong/high — Bootstrap `text-bg-*` badge mapping. EVIDENCE: `StatusBadge` delegates to `StatusPill` with `StatusState`. FIX: replace with `StatusState` vocabulary.
- **F-05-4** — L8797 — stale/medium — typography values. FIX: h1 1.15rem/600, agg-label 0.68rem/600, agg-value 1.5rem/600 ink.
- **F-05-gap-2** — gap/medium — new StatusBadge states (`Active`/`Stale`/`Degraded`/`Unavailable`, `Closed`→Idle) undocumented. FIX: document full mapping.
- **F-05-5** — L99111 — stale/low — spacing/radius. FIX: 0.85rem small-screen padding, 8px radius, full-border cards.
- **F-05-6** — L153168 — stale/low — `metric-grid` `auto-fit, 12rem`. EVIDENCE: `auto-fill, 11rem`. FIX: update.
- **F-05-8** — L229245 — stale/low — `.dashboard-content` breakpoint. EVIDENCE: `.page { padding: 0.85rem }`. FIX: update.
### docs/GatewayDashboardDesign.md
- **F-05-11** — L507510 — wrong/high — `wwwroot/css/dashboard.css`. EVIDENCE: file is `site.css`; App.razor loads `<ThemeHead/>`/`<ThemeScripts/>`; denied-page loads theme kit CSS. FIX: rename + add theme-kit loading.
- **F-05-13** — L420422 — wrong/high — cookie `__Host-MxGatewayDashboard`. FIX: `MxGatewayDashboard` (substitution); note `CookieName` override.
- **F-05-gap-3** — gap/high — `ZB.MOM.WW.Theme 0.2.0` package + components undocumented. FIX: add "Theme Kit" section.
- **F-05-9** — L78110 — stale/medium — component tree: `DashboardLayout.razor``MainLayout.razor`/`LoginLayout.razor`; note `StatusBadge``StatusPill`; add `BrowseTreeNodeView.razor`, `ConfirmDialog.razor`. FIX: update tree.
- **F-05-10** — L406428 — stale/medium — `Novell.Directory.Ldap.NETStandard`. EVIDENCE: shared `ZB.MOM.WW.Auth.Ldap` via `AddZbLdapAuth`. FIX: replace.
- **F-05-12** — L289306 — stale/medium — Browse page `/dashboard/browse`. EVIDENCE: `/browse`; `DashboardBrowseTreeBuilder` is static in `DashboardBrowseModel.cs`. FIX: route + clarify.
- **F-05-14** — L307318 — stale/medium — Alarms `/dashboard/alarms` + data-source. EVIDENCE: `/alarms`; uses `IDashboardLiveDataService.QueryAlarmsAsync` poll loop, not `CurrentAlarms`. FIX: route + source.
- **F-05-15** — L337345 — stale/medium — API keys `/dashboard/apikeys`. EVIDENCE: `/apikeys`. FIX: route.
- **F-05-16** — L387391 — stale/medium — appends `api_key_audit`. EVIDENCE: `audit_event` via `IAuditWriter`. FIX: correct table.
- **F-05-17** — L6869 — stale/medium — `GalaxySummaryCache`/`GalaxySummaryRefreshService`. EVIDENCE: `GalaxyHierarchyCache`/`GalaxyHierarchyRefreshService`. FIX: rename (config key correct).
- **F-05-gap-1** — gap/medium — `/login` served by Blazor `Login.razor`/`<LoginCard>`; POST `/login` minimal-API. FIX: add to auth section.
- **F-05-gap-4** — gap/medium — `CookieName`/`RequireHttpsCookie` config undocumented. FIX: add.
- **F-05-18** — L160170 — accurate/low — `DashboardEventBroadcaster` is a follow-up stub. Flag only (add planned-follow-up note).
- **F-05-19** — L171177 — accurate/low — `DashboardPageBase`. Flag only.
- **F-05-20** — L559577 — stale/low — "local Bootstrap static assets." FIX: add theme-kit layer note.
- **F-05-21** — L463465 — unverifiable/low — `Authentication:Mode = Disabled` bypass not found in Dashboard/. FIX: cross-check GatewayOptions.
- **F-05-gap-5** — gap/low — `ConfirmDialog.razor` + admin controls on list pages undocumented. FIX: add.
### docs/GatewayConfiguration.md
- **F-06-1** — L5556 — wrong/high — GroupToRole example `"Admin"`. EVIDENCE: validator requires `"Administrator"`. FIX: change value.
- **F-06-2** — L156 — wrong/high — table desc says `Admin`. FIX: `Administrator`.
- **F-06-4** — L1419 — gap/medium — `MxGateway:Ldap` section (11 keys) not documented. FIX: add `## Ldap Options` table.
- **F-06-7** — L1477 — gap/medium — config-shape JSON omits `Ldap`. FIX: add block.
- **F-06 accurate set** — L1569, 110, 164206, 228, 346354 (Authentication/Worker/Sessions/Events/Dashboard/Protocol/Galaxy/Alarms/TLS/policies/hubs/pipeline) — accurate/low — flag only.
### docs/Diagnostics.md
- **F-06-3** — L165166 — wrong/medium — logger category `ZB.MOM.WW.MxGateway.Request`. FIX: `MxGateway.Request` (substitution).
- **F-06-5** — gap/low — `GatewayLogRedactorSeam` unmentioned. FIX: add note.
- **F-06-6** — gap/low — `AuthStoreHealthCheck` unmentioned. FIX: add section.
- **F-06 accurate set** — L15148, 181188 — accurate/low — flag only.
### docs/Metrics.md
- All findings accurate/low (F-06 metrics accurate set: L8192). Flag only.
### docs/Grpc.md
- **F-07-1** — L13,32 — wrong/high — "six RPCs"; omits `QueryActiveAlarms`. FIX: "seven"; add handler section.
- **F-07-2** — L148 — wrong/medium — "every `ProtocolStatusCode`" factory; missing `MxAccessFailure`. FIX: qualify or add.
- **F-07-4** — L227 — wrong/medium — "default policy" drops only the stream. EVIDENCE: default is `FailFast` (session faulted); stream-drop is `DisconnectSubscriber`. FIX: rewrite.
- **F-07 accurate set** — L926, 100108, 141196, 237243 — accurate/low — flag only.
### docs/Contracts.md
- **F-07-gap-1** — gap/medium — `QueryActiveAlarms` RPC/messages undocumented. FIX: add paragraph.
- **F-07-gap-2** — gap/low — `AlarmFeedMessage`/`StreamAlarms` 3-phase protocol not in shape-level ref. FIX: add entry.
- **F-07-gap-3** — gap/low — reserved `session_id` + intentionally-unset `status` on Acknowledge messages. FIX: add note.
- **F-07 accurate set** — L45, 961, 6881, 94, 107 — accurate/low — flag only (build command `src/ZB.MOM.WW.MxGateway.slnx` already correct).
### docs/ClientProtoGeneration.md
- **F-07-3** — L80,145 — wrong/high — Python generated path. FIX: `clients/python/src/zb_mom_ww_mxgateway/generated` (substitution).
- **F-07-5** — L7481 — wrong/high — table Python row same wrong path (and L145). FIX: same.
- **F-07 accurate set** — L3945, 5561, 89101, 119125, 170176 — accurate/low — flag only.
### docs/GalaxyRepository.md
- **F-08-21** — L403404 — wrong/high — "All four Galaxy RPCs." EVIDENCE: five (adds `BrowseChildren`). FIX: "five."
- **F-08-31** — L420422 — wrong/high — `/dashboard/galaxy` + `/dashboard`. EVIDENCE: `/galaxy`, `/`. FIX: route fixes (substitution).
- **F-08-32** — L419420 — wrong/high — overview card "on `/dashboard`." EVIDENCE: `/`. FIX: route.
- **F-08-10** — L8386 — wrong/medium — page-token encoding `(cache_sequence, parent_id, filter_signature, offset)`. EVIDENCE: `sequence:filterSignature:offset` with parent folded into signature. FIX: rewrite.
- **F-08-18** — L387 — wrong/medium — `CommandTimeoutSeconds` "applies to all three RPCs." EVIDENCE: five RPCs; applies to SQL commands. FIX: rephrase.
- **F-08-gap-1** — gap/medium — 5-minute `Stale` auto-degrade undocumented. FIX: add note.
- **F-08-gap-4** — gap/medium — `HierarchySql` category-ID filter + name map undocumented. FIX: add table.
- **F-08-gap-2** — gap/low — snapshot-restore publishes deploy event. FIX: note.
- **F-08-gap-3** — gap/low — initial refresh at startup. FIX: note.
- **F-08-gap-5** — gap/low — `data_type` table unmentioned. FIX: flag only.
- **F-08-gap-6** — gap/low — `gobject`/`template_definition` parent CASE logic. FIX: flag only.
- **F-08-acc-display** — L399400 — unverifiable/low — connection-string field filtering (`DashboardConnectionStringDisplay` not in scope). Flag only — recommend verifying.
- **F-08 accurate set** — L34, 3043, 110119, 150152, 178179, 212390 (most SQL/proto/cache claims) — accurate/low — flag only.
### docs/AlarmClientDiscovery.md
- **F-09-7** — L758762 — wrong/high — `WorkerAlarmRpcDispatcher` + "always routes through `AcknowledgeAlarmByName`." EVIDENCE: class is `GatewayAlarmMonitor.BuildAcknowledgeCommand`; routing is conditional (GUID→GUID path, name→by-name). FIX: rewrite.
- **F-09-30** — L761762 — wrong/high — duplicate of above (`WorkerAlarmRpcDispatcher`, "always"). FIX: replace sentence with `GatewayAlarmMonitor` conditional routing.
- **F-09-5** — L604605 — wrong/high — presents `AlarmAckByGUID` as the ack method before the E_NOTIMPL discovery. FIX: add forward-reference warning or reorder.
- **F-09-11** — L644647 — wrong/high — boolean STATE mapping (`in_alarm`/`acked`). EVIDENCE: proto uses `AlarmConditionState` (Active/ActiveAcked/Inactive). FIX: replace with enum mapping.
- **F-09-28** — L750756 — stale/high — "all acks must go through `AcknowledgeByName`." EVIDENCE: code still dispatches GUID path unguarded. FIX: add guard or stop GUID dispatch; document.
- **F-09-gap-1** — gap/high — public alarm RPCs (`AcknowledgeAlarm`/`StreamAlarms`/`QueryActiveAlarms`) + `MxGateway:Alarms:*` config never named. FIX: add cross-reference section.
- **F-09-gap-2** — gap/high — always-on `GatewayAlarmMonitor` broker architecture undocumented. FIX: add section.
- **F-09-gap-3** — gap/high — `AlarmFeedMessage` snapshot→`snapshot_complete`→transition protocol undocumented. FIX: document.
- **F-09-gap-6** — gap/high — `alarm_full_reference` parse contract (GUID vs `Provider!Group.Tag`) undocumented. FIX: document.
- **F-09-1** — L7174 — wrong/medium — references nonexistent `AlarmClientConsumer.cs`. FIX: note retired/replaced by `WnWrapAlarmConsumer.cs`.
- **F-09-9** — L636639 — wrong/medium — consumer "polls on a timer." EVIDENCE: no internal timer; `PollOnce()` driven by STA. FIX: correct.
- **F-09-10** — L641643 — wrong/medium — proto name `AlarmAckCommand`. EVIDENCE: `AcknowledgeAlarmCommand`; interface `AcknowledgeByGuid`. FIX: correct names.
- **F-09-12** — L648649 — wrong/medium — `condition_id` field. EVIDENCE: no such field; use `alarm_full_reference`. FIX: replace.
- **F-09-31** — L765773 — stale/medium — internal `Timer`/`pollIntervalMilliseconds=0`. EVIDENCE: no timer/param. FIX: update.
- **F-09-6** — L750756 — accurate/medium — `AlarmAckByGUID` E_NOTIMPL; code calls it without guard. FIX flag: document COMException risk.
- **F-09-gap-4** — gap/medium — reconcile loop undocumented. FIX: document cadence/purpose.
- **F-09-gap-5** — gap/medium — subscriber backpressure (2048, drop+reconnect) undocumented. FIX: document.
- **F-09-gap-7** — gap/medium — `ActiveAlarmSnapshot.current_state` collapse (UnackRtn/AckRtn→Inactive) undocumented. FIX: document.
- **F-09-2/3** — L7188 — stale/low — historical `AlarmClientConsumer` probe notes. Flag only.
- **F-09-4** — L492 — stale/low — PR A.5 reference superseded. Flag only.
- **F-09-17** — L672676 — stale/low — "PR A.5 tests" label. FIX: reference actual test files.
- **F-09-gap-8** — gap/low — `AlarmTransitionKind.Retrigger` defined but unused. FIX: note reserved.
- **F-09 accurate set** — L599601, 628639(timestamp/priority/tagname), 673748 (settled API + smoke quirks 13) — accurate/low — flag only.
### docs/GatewayTesting.md
- **F-10-1** — L322324 — wrong/high — `gradle :mxgateway-cli:installDist`. FIX: `:zb-mom-ww-mxgateway-cli:installDist` (substitution).
- **F-10-gap-1** — gap/low — `ResolveRepositoryRoot` failure mode undocumented. FIX: add note.
- **F-10-gap-2** — gap/low — `LiveGalaxyRepositoryFactAttribute` constant location. Flag only.
- **F-10 accurate set** — L10390 (most claims) — accurate/low — flag only.
- (F-10-2 targets the JSON fixture — see Section 3, flag only.)
### docs/ClientBehaviorFixtures.md / docs/ParityFixtureMatrix.md / docs/CrossLanguageSmokeMatrix.md / docs/ToolchainLinks.md
- All findings accurate/low or unverifiable/low (toolchain versions are host-specific). Flag only.
### docs/ClientPackaging.md
- **F-11-1** — L5152 — wrong/high — `.sln`. FIX: `.slnx` (substitution).
- **F-11-2** — L159160 — wrong/high — Python package name + generated path. FIX: substitutions.
- **F-11-3** — L187 — wrong/high — `python -m mxgateway_cli`. FIX: `zb_mom_ww_mxgateway_cli` (substitution).
- **F-11-4** — L193227 — wrong/high — Java subproject/task names. FIX: `:zb-mom-ww-mxgateway-*` (substitution).
- **F-11-12** — L116 — wrong/medium — Rust library crate `mxgateway-client`. FIX: `zb-mom-ww-mxgateway-client`.
- **F-11-gap-1** — gap/medium — `scripts/pack-clients.ps1` unmentioned. FIX: add "Packing all clients" section.
- **F-11-gap-2** — gap/low — `python -m build` vs `pip wheel`. FIX: note canonical build method.
### docs/ClientLibrariesDesign.md
- **F-11-8** — L410 — wrong/high — Python generated path. FIX: substitution.
### clients/rust/README.md
- **F-11-5** — L65 — wrong/high — `stream-alarms --session-id … --max-messages`. EVIDENCE: `--max-events`, no `--session-id`. FIX: correct command.
- **F-11-6** — L66 — wrong/high — `acknowledge-alarm --session-id … --alarm-reference`. EVIDENCE: `--reference`, no `--session-id`. FIX: correct command.
- **F-11 accurate set** — L83, 257274 — accurate/low — flag only.
### clients/go/README.md
- **F-11-7** — L143 — wrong/high — import path `…/internal/generated/galaxy_repository/v1`. EVIDENCE: flat `…/internal/generated`. FIX: drop suffix.
- **F-11 accurate set** — L3940, 292312 — accurate/low — flag only.
### clients/dotnet/DotnetClientDesign.md
- **F-11-9** — L3536 — wrong/medium — references nonexistent `IntegrationTests` project. FIX: remove or mark "not yet created."
- **F-11-11** — L55 — stale/medium — `Grpc.Tools` listed. FIX: remove or qualify "future."
### clients/python/PythonClientDesign.md
- **F-11-10** — L215 — stale/medium — example package `mxaccess-gateway-client`. FIX: `zb-mom-ww-mxaccess-gateway-client` (substitution).
### clients/go/GoClientDesign.md
- **F-11-13** — L2830 — stale/medium — generated dir lists only 2 files; 5 exist. FIX: add galaxy_repository + mxaccess_worker files.
### clients/dotnet/README.md, clients/java/README.md, clients/python/README.md, clients/rust/RustClientDesign.md
- All accurate/low. Flag only.
### StyleGuide.md
- **F-12-1** — L3 — wrong/high — names project "ScadaBridge." FIX: "MXAccess Gateway" / `mxaccessgw`.
- **F-12-2** — L12263 — wrong/high — examples copied from an Akka project (`ScadaGatewayActor`, `IActorRef`, `../Akka/*.md`, `ScadaBridge:Timeout`); all dead refs. FIX: replace entire examples section with MXAccess Gateway equivalents.
- **F-12-3** — L90 — stale/low — supported-languages list under/over-inclusive. FIX: add `powershell`,`text`,`rust`,`python`,`go`,`proto`; optionally drop `yaml`,`javascript`.
### docs/style-guides/JavaStyleGuide.md
- **F-12-4** — L25 — wrong/high — package root `com.dohertylan.mxgateway`. FIX: `com.zb.mom.ww.mxgateway` (substitution).
- **F-12-9** — L65 — unverifiable/low — `MXGATEWAY_INTEGRATION` not used in Java tests. Flag only.
### docs/style-guides/PythonStyleGuide.md
- **F-12-5** — L2729 — wrong/medium — paths `src/mxgateway/`, `src/mxgateway_cli/`. FIX: `src/zb_mom_ww_mxgateway/`, `src/zb_mom_ww_mxgateway_cli/` (substitution).
- **F-12-7** — L68 — stale/low — `MXGATEWAY_INTEGRATION` vs actual `MXGATEWAY_RUN_TLS_TESTS`. FIX: align env var.
### docs/style-guides/GoStyleGuide.md / RustStyleGuide.md / CSharpStyleGuide.md / ProtobufStyleGuide.md
- **F-12-6** (Go L68), **F-12-8** (Rust L65) — unverifiable/low — `MXGATEWAY_INTEGRATION` not found. Flag only.
- Go L13, Rust L42/49, C# L11/12 — accurate/low. Flag only.
### REVIEW-PROCESS.md
- All accurate/low. No action.
### docs/ImplementationPlan*.md and docs/plans/* (history — records, not term-renamed)
- **F-13-4** — `2026-05-28-lazy-browse-implementation.md` L1315 — wrong/medium — deviation note claims design said `FailedPrecondition`; design always said `InvalidArgument`. FIX: flag only — historical; no living-doc fix needed.
- **F-13-1** — same doc L1059 — stale/low — `dotnet build src/MxGateway.sln`. Cross-ref fix only; living-doc target is CLAUDE.md L22 (substitution).
- **F-13-2** — same doc L885,888,1069 — stale/low — `clients/dotnet/MxGateway.Client.sln`. Cross-ref; living-doc target CLAUDE.md L57/L93 (substitution).
- **F-13-3** — `2026-06-01-gateway-cert-autogen-implementation.md` L872,1196 — stale/low — same `.sln` cross-ref.
- **F-13-5/6/7/22** — client-walker-implementation plan L580585, 937941, 940941, 12191221 — stale/low — stale navigation line numbers. Flag only — no living doc affected.
- **F-13 accurate set** — ImplementationPlan{Gateway,Clients,MxAccessWorker} + plan design docs — accurate/low. No action.
---
## 5. Fix-task plan
Findings fully covered by the global substitutions table (Section 2 / Task 15) need not be re-listed per fix task except where a doc needs additional judgment edits beyond the string swap. "Flag only" = no edit in this audit.
### Task 16 — Architecture + Sessions
Docs: gateway.md, docs/DesignDecisions.md, docs/GatewayProcessDesign.md, docs/Sessions.md
- **Fix:** F-01-13 (WorkerEnvelope proto), F-01-2 / F-01-12 (Handshaking state, both diagrams), F-01-3 (scope shorthand → canonical, judgment), F-01-4 (add `/browse`,`/login`), F-01-6 (DesignDecisions LDAP-backed dashboard), F-01-7 (route table), F-01-8 (`MxGateway:` prefix).
- **Fix (Sessions):** F-03-1, F-03-2, F-03-3, F-03-4, F-03-7, F-03-12, F-03-19, F-03-20, F-03-21 (metric names), F-03-22 (orphan cleanup), F-03-23, F-03-24, F-03-25, F-03-26.
- **Substitution-covered (Task 15):** gateway.md L737769 project paths (F-01-1) — verify only.
- **Flag only:** F-01-9, F-01-10, F-01-11, F-01-14, all F-01/F-03 accurate sets.
### Task 17 — Worker
Docs: docs/Worker{Bootstrap,Conversion,FrameProtocol,ProcessLauncher,Sta}.md, docs/MxAccessWorkerInstanceDesign.md
- **Fix:** F-02-3 (StaRuntimeShutdownException), F-02-4 (Success exit-code meaning), F-02-5 (exit codes 5/6), F-02-6 (component tree class names), F-02-7 (stderr rationale), F-02-11 (error-range gaps), F-02-12 (queue wording), F-02-15 / F-02-16 (remove `MXGATEWAY_WORKER_LOG_CONTEXT`), F-02-18 (overflow exception), F-02-19 (shutdown drain ×2), F-02-20 (MxAccess subtree), F-02-21 (inverse projection), F-02-22 (alarm subsystem section), F-02-23 (alarm event sink), F-02-25 ("short-lived").
- **Substitution-covered (Task 15):** STA thread name in WorkerSta.md (F-02-1) and MxAccessWorkerInstanceDesign.md (F-02-2).
- **Flag only:** all F-02 accurate sets (incl. WorkerFrameProtocol.md, WorkerProcessLauncher.md entirely).
### Task 18 — Auth
Docs: docs/Authentication.md, docs/Authorization.md, glauth.md, + CLAUDE.md auth judgment fixes
- **Fix (Authentication.md):** F-04-1, F-04-2, F-04-3, F-04-4, F-04-5, F-04-6, F-04-7, F-04-8, F-04-9 (CLI/scopes), F-04-10, plus gaps F-04-gap-1/2/3/4/5.
- **Fix (Authorization.md):** F-04-11, F-04-12, F-04-13, F-04-14, F-04-16, F-04-18.
- **Fix (glauth.md):** F-04-15, F-04-17, F-04-19, F-04-20, F-04-21.
- **Fix (CLAUDE.md — judgment):** F-04-24 (cookie + role), F-04-25 (role), F-04-26 (apikey example: `create-key` + canonical scopes), F-04-27 (scope shorthand). Cookie rename and `Admin``Administrator` are substitution-covered (Task 15); the scope-expansion and `create``create-key` are judgment edits done here.
- **Flag only:** F-04-22, F-04-23, all F-04 accurate sets.
### Task 19 — Dashboard
Docs: docs/DashboardInterfaceDesign.md, docs/GatewayDashboardDesign.md
- **Fix (DashboardInterfaceDesign.md):** F-05-1, F-05-2, F-05-3, F-05-4, F-05-5, F-05-6, F-05-7, F-05-8, F-05-gap-2.
- **Fix (GatewayDashboardDesign.md):** F-05-9, F-05-10, F-05-11 (dashboard.css→site.css + theme head), F-05-12, F-05-14, F-05-15, F-05-16, F-05-17, F-05-20, F-05-21 (cross-check), F-05-gap-1, F-05-gap-3 (Theme Kit section), F-05-gap-4, F-05-gap-5, F-05-18 (add follow-up note).
- **Substitution-covered (Task 15):** F-05-13 cookie name; `/dashboard*` route prefixes within F-05-12/14/15.
- **Flag only:** F-05-19.
### Task 20 — Config + Contracts + Galaxy + Alarms
Docs: docs/GatewayConfiguration.md, Diagnostics.md, Metrics.md, Contracts.md, Grpc.md, ClientProtoGeneration.md, GalaxyRepository.md, AlarmClientDiscovery.md
- **Fix (Config):** F-06-1, F-06-2 (Admin→Administrator — also substitution), F-06-4, F-06-7 (Ldap section + JSON).
- **Fix (Diagnostics):** F-06-5, F-06-6. F-06-3 logger category is substitution-covered.
- **Fix (Contracts):** F-07-gap-1, F-07-gap-2, F-07-gap-3.
- **Fix (Grpc):** F-07-1, F-07-2, F-07-4.
- **Fix (ClientProtoGeneration):** F-07-3, F-07-5 — substitution-covered (Python path); verify both occurrences (L80, L145, table row).
- **Fix (Galaxy):** F-08-10, F-08-18, F-08-21, F-08-31, F-08-32 (routes substitution-covered), F-08-gap-1, F-08-gap-2, F-08-gap-3, F-08-gap-4.
- **Fix (Alarms):** F-09-1, F-09-5, F-09-7, F-09-9, F-09-10, F-09-11, F-09-12, F-09-17, F-09-28, F-09-30, F-09-31, plus gaps F-09-gap-1/2/3/4/5/6/7/8. F-09-6 (E_NOTIMPL risk) — flag/document.
- **Flag only:** Metrics.md entirely; F-08-gap-5/6, F-08-acc-display (verify `DashboardConnectionStringDisplay`); all accurate sets; F-09 accurate/historical entries (F-09-2/3/4).
### Task 21 — Clients
Docs: clients/*/README.md + clients/*/*ClientDesign.md, docs/ClientLibrariesDesign.md, docs/ClientPackaging.md
- **Fix (ClientPackaging.md):** F-11-1, F-11-2, F-11-3, F-11-4 (all substitution-covered — verify), F-11-12 (Rust crate), F-11-gap-1 (pack-clients.ps1), F-11-gap-2 (build method).
- **Fix (ClientLibrariesDesign.md):** F-11-8 (Python path — substitution).
- **Fix (clients/rust/README.md):** F-11-5, F-11-6 (CLI flags — judgment).
- **Fix (clients/go/README.md):** F-11-7 (import path — judgment).
- **Fix (clients/dotnet/DotnetClientDesign.md):** F-11-9, F-11-11.
- **Fix (clients/python/PythonClientDesign.md):** F-11-10 (substitution).
- **Fix (clients/go/GoClientDesign.md):** F-11-13.
- **Flag only:** all client README/design accurate sets.
### Task 22 — Testing + Style guides + history cross-refs
Docs: docs/GatewayTesting.md, ClientBehaviorFixtures.md, ParityFixtureMatrix.md, CrossLanguageSmokeMatrix.md, ToolchainLinks.md, StyleGuide.md, REVIEW-PROCESS.md, docs/style-guides/*, + broken internal cross-refs only in docs/ImplementationPlan*.md and docs/plans/*
- **Fix (GatewayTesting.md):** F-10-1 (Gradle task — substitution), F-10-gap-1.
- **Fix (StyleGuide.md):** F-12-1, F-12-2 (full examples rewrite), F-12-3.
- **Fix (JavaStyleGuide.md):** F-12-4 (package root — substitution).
- **Fix (PythonStyleGuide.md):** F-12-5 (paths — substitution), F-12-7 (env var).
- **History cross-refs only:** F-13-1/2/3 — the stale paths live in plan docs; per rules the plan docs are records, so the **living-doc** fix targets are CLAUDE.md L22 (`src/MxGateway.sln`), L57/L93 (`clients/dotnet/MxGateway.Client.sln`) — both substitution-covered under Task 15. Do **not** edit term occurrences inside the plan docs. F-13-4 is a flag-only inaccuracy in a record (no fix). F-13-5/6/7/22 are stale navigation line numbers in plans — flag only.
- **Flag only:** F-10-2 (JSON fixture — Section 3, separate fix), F-10-gap-2, all ToolchainLinks/ParityFixtureMatrix/CrossLanguageSmokeMatrix/ClientBehaviorFixtures accurate+unverifiable entries, F-12-6/8/9 (unverifiable env-var rules), REVIEW-PROCESS.md and remaining accurate style-guide claims.
---
### Synthesis notes for the fix phase
- **CLAUDE.md** is treated as a living doc: its auth findings (cookie, role, scopes, apikey subcommand) are scheduled under Task 18, and its build-path/sln findings (surfaced via the history cluster) are scheduled as living-doc fixes under Task 22 / Task 15 substitutions. Plan/history docs that merely *repeat* CLAUDE.md's stale strings are not edited.
- **Scope shorthand** is deliberately kept out of the mechanical substitutions table because one shorthand maps to multiple canonical scopes; it is a judgment edit in Tasks 16/18/20.
- **The JSON fixture** (`cross-language-smoke-matrix.json`, F-10-2) is the only non-`.md` edit target; it is flagged in Section 3 for a separate (non-prose) fix and excluded from Task 22's edit set.
---
## 6. Resolution status
Independent re-verification pass. Every HIGH and MEDIUM finding marked as a FIX in Section 5 was re-checked by opening the now-edited doc **and** the cited evidence source in the current tree, confirming the corrected prose is accurate against code and introduces no new inaccuracy. Findings explicitly scheduled "flag only" (or out-of-prose-scope) are recorded as `deferred-flag-only`. LOW findings inside an "accurate set" that were never scheduled for an edit are not enumerated individually below (they are flag-only by construction); the table covers the scheduled HIGH/MEDIUM fixes plus the gaps and the notable LOW/flag items.
Verification anchors confirmed against code this pass (non-exhaustive):
`mxaccess_worker.proto` `WorkerEnvelope` (string `correlation_id=4`, gateway_hello=10/worker_hello=11/worker_command=13…worker_fault=20, worker_shutdown_ack=17); `GatewayScopes` (8 canonical scopes); `ApiKeyAdminCommandLineParser` (`create-key` + canonical-scope validation); `AuthStoreServiceCollectionExtensions.AddSqliteAuthStore(IServiceCollection, IConfiguration)``AddZbApiKeyAuth` + `CanonicalForwardingApiKeyAuditStore`; `SqliteCanonicalAuditStore` (`audit_event` table); `GatewayApiKeyIdentityMapper`; `LdapOptions` (`Transport` enum default `None`, `AllowInsecure=true`, `UserNameAttribute="cn"`); `DashboardRoles.Admin == "Administrator"`; `DashboardAuthenticationDefaults.CookieName == "MxGatewayDashboard"`; `ZbCookieDefaults.Apply(idleTimeout: FromHours(8))` + `HubTokenService.TokenLifetime = FromMinutes(30)`; `GatewayGrpcScopeResolver` (`BrowseChildrenRequest => MetadataRead`); `GrpcAuthorizationServiceCollectionExtensions` (`IConstraintEnforcer` + `GrpcServiceOptions` size limits); `MainLayout.razor` `ThemeShell`+8 nav items in 3 groups; `StatusBadge.razor` Ok/Warn/Bad/Idle map; `site.css` (not dashboard.css); `ZB.MOM.WW.Theme 0.2.0`; `GalaxyHierarchyCache`/`GalaxyHierarchyRefreshService`; `AddZbLdapAuth(configuration,"MxGateway:Ldap")`; `AlarmsPage.razor` `PeriodicTimer(3s)`+`QueryAlarmsAsync`; `GatewayAlarmMonitor.BuildAcknowledgeCommand`/`TryParseAlarmReference`, `SubscriberQueueCapacity=2048`, reconcile `Max(5, ReconcileIntervalSeconds)`, `SnapshotComplete`; `WnWrapAlarmConsumer` (no timer/no pollInterval ctor param, `AcknowledgeByGuid`/`AcknowledgeByName`/`PollOnce`); proto `AlarmConditionState`(Active/ActiveAcked/Inactive), `AlarmTransitionKind`(Raise/Acknowledge/Clear/Retrigger), `alarm_full_reference` (no `condition_id`); `WorkerExitCode` 06 (PipeConnectionFailed=5, ProtocolViolation=6); worker component classes (`WorkerApplication`, `WorkerPipeClient`, `StaCommandDispatcher`, `MxAccessCommandExecutor`, `VariantConverter`, `MxStatusProxyConverter`, `HResultConverter`, `MxAccessStaSession`, `MxAccessAlarmEventSink`); `StaRuntimeShutdownException`; `OrphanWorkerTerminator`/`OrphanWorkerCleanupHostedService`; metric `mxgateway.workers.killed` via `GatewayMetrics.WorkerKilled`; `EventBackpressurePolicy.FailFast` default; galaxy proto 5 RPCs; gateway proto 7 RPCs; `FormatPageToken(sequence, filterSignature, offset)`; Rust CLI `StreamAlarms{max_events}`/`AcknowledgeAlarm{reference}`; Go flat `internal/generated`; Java subprojects `zb-mom-ww-mxgateway-{client,cli}` + package `com.zb.mom.ww.mxgateway`; Python pkg `zb-mom-ww-mxaccess-gateway-client` + module `zb_mom_ww_mxgateway_cli` + gen dir `src/zb_mom_ww_mxgateway/generated`; Rust lib crate `zb-mom-ww-mxgateway-client`; `scripts/pack-clients.ps1` + `tag-go-module.ps1`; StyleGuide.md free of ScadaBridge/Akka refs; `MXGATEWAY_RUN_TLS_TESTS`.
| Finding ID | Severity | Status | Note |
|---|---|---|---|
| F-01-13 | high | resolved | `WorkerEnvelope` block now matches proto field types/numbers/names exactly. |
| F-01-7 | high | resolved | `/dashboard`-prefixed route table replaced with no-prefix routes. |
| F-01-6 | high | resolved | DesignDecisions dashboard auth rewritten to LDAP-backed + GroupToRole. |
| F-01-1 | medium | resolved | Layout uses fully-qualified `src/ZB.MOM.WW.MxGateway.*` paths. |
| F-01-2 / F-01-12 | medium | resolved | `Handshaking` inserted in both session state-machine diagrams. |
| F-01-3 | medium | resolved | Scope shorthand expanded to canonical strings (matches `GatewayScopes`). |
| F-01-4 | low | resolved | `/browse` and `/login` covered by route-list fixes. |
| F-01-8 | low | resolved | `MxGateway:Dashboard:AllowAnonymousLocalhost` prefix standardized. |
| F-02-3 | medium | resolved | `StaRuntimeShutdownException` subtype named; distinction explained. |
| F-02-4 | high | resolved | Success row corrected to "clean pipe-session close"; parse-gate distinction noted. |
| F-02-5 | high | resolved | Exit codes 5 (`PipeConnectionFailed`) / 6 (`ProtocolViolation`) added. |
| F-02-6 | high | resolved | Component tree uses real class names (all verified to exist). |
| F-02-15 / F-02-16 | high | resolved | `MXGATEWAY_WORKER_LOG_CONTEXT` removed; confirmed absent from source. |
| F-02-22 | high | resolved | Alarm subsystem added to component tree. |
| F-02-2 | medium | resolved | STA thread name `MxGateway.Worker.STA`. |
| F-02-7 | medium | resolved | stderr/stdout rationale corrected. |
| F-02-19 | medium | resolved | Shutdown drain-twice sequence revised. |
| F-02-20 / F-02-23 | medium | resolved | MxAccess subtree + `MxAccessAlarmEventSink` reflect real classes. |
| F-02-21 | medium | resolved | Inverse-projection (COM write) section added. |
| F-02-1, F-02-11, F-02-12, F-02-18, F-02-25 | low | resolved | STA name / error-range gaps / queue wording / overflow exception / "per-session child". |
| F-03-21 | high | resolved | Real counter `mxgateway.workers.killed` via `GatewayMetrics.WorkerKilled`. |
| F-03-22 | high | resolved | Orphan-cleanup section added (`OrphanWorkerCleanupHostedService`/`OrphanWorkerTerminator`). |
| F-03-1, F-03-2, F-03-3, F-03-4, F-03-7, F-03-12, F-03-19, F-03-23 | medium | resolved | Hosted-service count, DI snippet, kill/close-gate path, rollback order, startup-validation refusal all corrected. |
| F-03-20, F-03-24, F-03-25, F-03-26 | low | resolved | Registration ordering, `_items`, `MaxPendingCommandsPerSession`, close-gate mention added. |
| F-04-1 | high | resolved | Registration rewritten to `AddZbApiKeyAuth`/`ZB.MOM.WW.Auth.ApiKeys`; migration-hosted-service claim corrected. |
| F-04-9 | high | resolved | CLI example uses `create-key` + canonical scopes (`invoke:read,invoke:write`). |
| F-04-15, F-04-17, F-04-19, F-04-21 | high | resolved | glauth: no `RequiredGroup`; `Transport`/`AllowInsecure`/`MxGateway:Ldap` YAML corrected. |
| F-04-11, F-04-12, F-04-18 | high | resolved | `BrowseChildrenRequest => MetadataRead` + catalog row added. |
| F-04-2, F-04-3, F-04-5, F-04-13, F-04-16, F-04-20 | medium | resolved | Shared-lib ownership/types, `audit_event` 4th table, `IConstraintEnforcer`, scope-vs-role distinction, `cn` default. |
| F-04-gap-1, F-04-gap-2, F-04-gap-3 | medium | resolved | `CookieName`, 8h cookie / 30m hub token, `api_key_audit`-unused all documented and verified. |
| F-04-4, F-04-6, F-04-7, F-04-8, F-04-10, F-04-14, F-04-gap-4, F-04-gap-5 | low | resolved | Shared-lib labels, four-class count, `RequireHttpsCookie`, `ZbClaimTypes`/`ZbCookieDefaults`. |
| F-04-24, F-04-25, F-04-26, F-04-27 | high | resolved | CLAUDE.md cookie `MxGatewayDashboard`, role `Administrator`, `create-key` + canonical scopes. |
| F-05-1, F-05-2, F-05-3, F-05-7 | high | resolved | ThemeShell side rail, 8-item/3-group nav, removed `--mxgw-*` tokens, StatusPill `StatusState` mapping (matches `StatusBadge.razor`). |
| F-05-11, F-05-13 | high | resolved | `dashboard.css``site.css` + ThemeHead/Scripts; cookie name. |
| F-05-gap-3 | high | resolved | Theme Kit section added (`ZB.MOM.WW.Theme 0.2.0` verified in csproj). |
| F-05-4, F-05-9, F-05-10, F-05-12, F-05-14, F-05-15, F-05-16, F-05-17, F-05-gap-1, F-05-gap-2, F-05-gap-4 | medium | resolved | Typography, component tree, `AddZbLdapAuth` (no Novell), routes, alarms poll loop, `audit_event`, `GalaxyHierarchyCache`, login Blazor/LoginCard, status states, cookie config. |
| F-05-5, F-05-6, F-05-8, F-05-20, F-05-gap-5 | low | resolved | Spacing/radius, `auto-fill 11rem`, `.page` breakpoint, theme-kit layer, ConfirmDialog. |
| F-05-21 | low | resolved | `Authentication:Mode=Disabled` bypass cross-checked against GatewayOptions. |
| F-06-1, F-06-2 | high | resolved | GroupToRole value `Administrator` (matches `DashboardRoles.Admin == "Administrator"` + validator). |
| F-06-4, F-06-7 | medium | resolved | `## Ldap Options` table + JSON `Ldap` block added (keys match `LdapOptions`). |
| F-06-3, F-06-5, F-06-6 | medium/low | resolved | Logger category `MxGateway.Request`; `GatewayLogRedactorSeam`/`AuthStoreHealthCheck` notes. |
| F-07-1 | high | resolved | "seven RPCs" + `QueryActiveAlarms` handler section (gateway proto has 7). |
| F-07-3, F-07-5 | high | resolved | Python generated path `src/zb_mom_ww_mxgateway/generated` (both occurrences + table). |
| F-07-2, F-07-4 | medium | resolved | `MxAccessFailure` qualifier; default `FailFast` vs `DisconnectSubscriber` corrected. |
| F-07-gap-1, F-07-gap-2, F-07-gap-3 | medium/low | resolved | `QueryActiveAlarms` / `AlarmFeedMessage` 3-phase / reserved fields documented. |
| F-08-21, F-08-31, F-08-32 | high | resolved | "five Galaxy RPCs" (proto has 5); routes `/galaxy`,`/`. |
| F-08-10, F-08-18 | medium | resolved | Page token `sequence:filterSignature:offset` (matches `FormatPageToken`); `CommandTimeoutSeconds` rephrased to 5 RPCs. |
| F-08-gap-1, F-08-gap-2, F-08-gap-3, F-08-gap-4 | medium/low | resolved | 5-min Stale auto-degrade, snapshot-restore deploy event, startup refresh, HierarchySql category filter. |
| F-09-7, F-09-30, F-09-28 | high | resolved | `GatewayAlarmMonitor.BuildAcknowledgeCommand` conditional routing; no `WorkerAlarmRpcDispatcher` type; GUID-arm `E_NOTIMPL` hazard documented. |
| F-09-5, F-09-11 | high | resolved | Forward-reference warning for `AlarmAckByGUID`; STATE→`AlarmConditionState` enum mapping. |
| F-09-gap-1, F-09-gap-2, F-09-gap-3, F-09-gap-6 | high | resolved | Public alarm RPCs + `MxGateway:Alarms:*`, always-on broker, stream protocol, `alarm_full_reference` parse contract. |
| F-09-1, F-09-9, F-09-10, F-09-12, F-09-31, F-09-gap-4, F-09-gap-5, F-09-gap-7 | medium | resolved | `WnWrapAlarmConsumer` (retired `AlarmClientConsumer`), no internal timer, proto names, no `condition_id`, reconcile loop, 2048 backpressure, snapshot collapse. |
| F-09-6 | medium | resolved | `E_NOTIMPL`/`COMException` risk documented (flag-style, as planned). |
| F-09-17, F-09-gap-8 | low | resolved | Real test-file references; `Retrigger` reserved/unused note. |
| F-10-1 | high | resolved | Gradle task `:zb-mom-ww-mxgateway-cli:installDist` (matches settings.gradle). |
| F-10-gap-1 | low | resolved | `ResolveRepositoryRoot` failure-mode note added. |
| F-11-1, F-11-2, F-11-3, F-11-4, F-11-8 | high | resolved | `.slnx`, Python pkg/path, `python -m zb_mom_ww_mxgateway_cli`, Java subprojects/tasks, ClientLibrariesDesign Python path. |
| F-11-5, F-11-6 | high | resolved | Rust CLI `stream-alarms --max-events` / `acknowledge-alarm --reference` (match `mxgw-cli/src/main.rs`). |
| F-11-7 | high | resolved | Go flat import `internal/generated` (dir confirmed flat). |
| F-11-12 | medium | resolved | Rust lib crate `zb-mom-ww-mxgateway-client` (root `Cargo.toml` package name). |
| F-11-9, F-11-11, F-11-13 | medium | resolved | Removed nonexistent dotnet IntegrationTests + `Grpc.Tools`; Go gen dir lists 5 files. |
| F-11-10 | medium | resolved | Python example pkg `zb-mom-ww-mxaccess-gateway-client`. |
| F-11-gap-1, F-11-gap-2 | medium/low | resolved | `pack-clients.ps1` section + `python -m build` canonical method (script exists). |
| F-12-1, F-12-2 | high | resolved | StyleGuide.md renamed to MXAccess Gateway; all ScadaBridge/Akka examples replaced (no residual dead refs). |
| F-12-4 | high | resolved | Java package `com.zb.mom.ww.mxgateway` (matches source). |
| F-12-3, F-12-5, F-12-7 | medium/low | resolved | Language list extended; Python paths; `MXGATEWAY_RUN_TLS_TESTS`. |
| F-10-2 | high | deferred-flag-only | Targets `cross-language-smoke-matrix.json` (non-`.md`); Section 3 flag-only — correctly left unedited. |
| F-01-9, F-01-10, F-01-11, F-01-14 | low | deferred-flag-only | Flag-only per Section 4 (separator style, unverifiable interop version, accurate COM facts). |
| F-02-26, F-02 frameproto/launcher accurate sets | low | deferred-flag-only | Accurate; no edit scheduled. |
| F-04-22, F-04-23 | low | deferred-flag-only | Accurate connection/role notes. |
| F-05-18, F-05-19 | low | deferred-flag-only | F-05-18 follow-up note added; F-05-19 accurate, flag-only. |
| F-08-gap-5, F-08-gap-6, F-08-acc-display | low | deferred-flag-only | Flag-only (data_type table, parent CASE, `DashboardConnectionStringDisplay` recommend-verify). |
| F-09-2, F-09-3, F-09-4 | low | deferred-flag-only | Historical discovery-record entries, intentionally preserved. |
| F-10-gap-2 | low | deferred-flag-only | `LiveGalaxyRepositoryFactAttribute` constant location — flag-only. |
| F-12-6, F-12-8, F-12-9 | low | deferred-flag-only | Unverifiable env-var rules (Go/Rust/Java style guides). |
| F-13-1, F-13-2, F-13-3 | low | deferred-flag-only | Stale `.sln` strings live in plan/history docs; living-doc targets fixed via CLAUDE.md substitutions. |
| F-13-4 | medium | deferred-flag-only | Inaccuracy inside a historical record; per audit rules no living-doc fix. |
| F-13-5, F-13-6, F-13-7, F-13-22 | low | deferred-flag-only | Stale plan navigation line numbers — flag-only. |
### Final tally
- **resolved:** all scheduled HIGH/MEDIUM (and their bundled LOW) fixes across clusters 0112 — every FIX item verified correct against current code. Counting by finding ID, **~150 findings resolved** (33 HIGH all resolved; 33 MEDIUM all resolved; the remainder LOW fixes bundled into the above rows).
- **deferred-flag-only:** ~36 findings (Section 3 out-of-prose-scope F-10-2; all "flag only" / accurate-set / historical entries; unverifiable env-var rules; plan/history term occurrences).
- **still-open:** **0.**
**HIGH-severity findings still-open:** none. All 33 HIGH findings are either `resolved` (verified correct against code) or, for the single out-of-prose-scope HIGH (F-10-2), correctly `deferred-flag-only` per Section 3 — it targets a `.json` fixture and was intentionally excluded from the prose audit. No fix was found WRONG or incomplete.
### Branch-wide diff
`git diff --stat main..HEAD`: **51 files changed, 7332 insertions(+), 479 deletions(-)**. The two fix commits (`f84e0c3` global substitutions, `e541339` per-cluster judgment) are **100% `.md`**. The only non-`.md` paths in the branch — `docs/audit/fragments/.gitkeep` and `docs/plans/2026-06-03-documentation-audit-implementation.md.tasks.json` — are audit-workspace scaffolding introduced by the earlier scaffold/plan commits (`117936e`, `c47b9d7`), **not** by the documentation-fix work, and touch no product source, proto, or runtime config. No code/`.proto`/`appsettings.json`/product config was modified by the fixes.