# Architecture Review 08 — Cross-Cutting Conventions, Test Posture, Underdeveloped Areas (Round 2)

**Date:** 2026-07-12 (round 2; round 1 dated 2026-07-08, baseline commit `b910f5eb`)
**Repo state reviewed:** `main` @ `8c888f13` — 268 commits past the round-1 baseline (all eight archreview fix plans, PLAN-01…PLAN-08, plus the two post-initiative features: aggregated live alarm stream and KPI hourly rollups, both merged 2026-07-10).

Reviewer domain: cross-cutting conventions, code organization, test posture, docs-code drift, deferred-work inventory. Individual subsystems are covered in depth by the other seven reviews; this one covers the seams and the whole.

## Scope

- Disposition audit: every round-1 finding re-verified against current source with file:line evidence (plan claims not trusted — checked directly).
- Fresh convention sweep over `src/` (26 projects) and `tests/` (30 projects): UTC discipline, TODO/HACK/NotImplementedException surface, Commons purity, options-validation coverage, correlation IDs, csproj hygiene, message-contract enforcement.
- Drift audit of the 268 post-baseline commits: new options classes vs validators, new wire contracts vs contract locks, CHANGELOG/README/CLAUDE.md claims vs code, register accuracy.
- Deferred-work register (`docs/plans/2026-07-08-deferred-work-register.md`, created by PLAN-08 T11) — item-by-item accuracy check, including the two register rows that shipped post-initiative (#10 live alarm stream, #22 KPI rollups).

Method: targeted greps and direct file reads only (static review; no builds/test runs — suites verified green 2026-07-10 per the master tracker). Read-only except this report.

## Verdict

**Round 1 vs round 2 in one line:** every actionable round-1 finding was genuinely fixed (17 fixed, 3 partially, 6 consciously deferred with register rows, 0 regressed) and the conventions that were already clean stayed clean through 268 commits of fix-plan churn; the new residue is small and mostly hygiene — one real embarrassment (a live production API key sitting in an untracked `test.txt` at the repo root), a failover-perf placeholder whose stated precondition has already been satisfied, and an abandoned CHANGELOG that is now factually wrong.

---

## 1. Round-1 Finding Disposition

Every round-1 finding, verified in current source. "Fixed (verified)" means the fix was confirmed at the cited location, not taken from plan claims.

| Round-1 finding | Sev | Disposition | Evidence (current source) |
|---|---|---|---|
| §1.1 Commons folders beyond documented four (`Observability/` etc.) | Low | **Fixed** | `docs/requirements/Component-Commons.md:294` documents `Observability/` in the layout tree (PLAN-08 T10 had narrowed this: `Serialization/`/`Validators/` were already documented) |
| §1.2 POCO persistence-ignorance | Pass | **Still Pass** | 0 EF/DataAnnotations refs in Commons (excluding `cref`); csproj's only PackageReference remains `ZB.MOM.WW.Audit` |
| §1.3 Site-side repository exception undocumented | Low | **Fixed** | `docs/requirements/Component-ConfigurationDatabase.md:170` documents the `SiteExternalSystemRepository` exception with the `NotSupportedException` rationale |
| §1.3/#23 Vestigial `SiteNotificationRepository` + dead write paths | Low/Med | **Fixed** | File deleted (0 hits in `src/`); only historical why-comments remain (`SiteRuntime/Persistence/SiteStorageService.cs:804-805`); design-invariant lock `Site_NotificationRepository_IsNotRegistered` at `tests/ZB.MOM.WW.ScadaBridge.Host.Tests/CompositionRootTests.cs:446` |
| §1.4 Communication → HealthMonitoring layering inversion | Low | **Deferred (accepted)** | Still present (`Communication/Actors/CentralCommunicationActor.cs:13`); register row with rationale + revisit trigger (`2026-07-08-deferred-work-register.md:48`) |
| §1.4 `..\` csproj path separator | Low | **Fixed** | 0 backslash project references across all csprojs |
| §1.5 Options validation on only ~6 of ~20 option classes | Med | **Partially fixed** | 16 `OptionsValidatorBase<T>` validators now exist (all 12 PLAN-08 target components + the prior 4), wired `.ValidateOnStart()` + `TryAddEnumerable`; **residue remains** — see New Finding NF4 (AuditLog's 6 sub-options, Host's Node/Database/Logging options) |
| §1.6 UTC discipline | Pass | **Still Pass** | 0 non-Utc `DateTime.Now`/`DateTimeOffset.Now` in src (.cs + .razor) |
| §1.7 Correlation IDs | Pass | **Still Pass** | 99 `CorrelationId` declarations in `Commons/Messages/` (was 96 — new messages kept the convention) |
| §1.8 No contract-lock tests for ClusterClient records | Low | **Fixed** | `tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Messages/ClusterClientContractLockTests.cs` — 9 tests over 7 records (old-shape, unknown-field, round-trip); locks the real wire finding that Newtonsoft ignores C# ctor optional-param defaults → missing trailing fields deserialize to `default(T)` (lines 57–60); Newtonsoft pinned 13.0.3 in `Directory.Packages.props:54` |
| §1.9 Naming/namespaces | Pass | **Still Pass** | spot checks consistent |
| §2.3 PerformanceTests a correctness-at-small-scale suite | Med | **Partially fixed** | Real throughput test shipped: `PerformanceTests/Streaming/SiteStreamThroughputTests.cs` (100k events, asserts ≥10k events/s + ≥90% delivery, lines 50–94). Failover timing is still a `Skip` placeholder — and its skip reason is now stale (New Finding NF2) |
| §2.4 CLI.Tests excluded from slnx | High | **Fixed** | `ZB.MOM.WW.ScadaBridge.slnx` contains all 30 test projects incl. CLI.Tests; CLAUDE.md gotcha retired; CLI suite (359 cases) runs at solution level |
| §3.1 / §4 Transport `AreaName: null` vs doc claim | High | **Fixed** | Exporter now carries area by name: `Transport/Serialization/EntitySerializer.cs:273` resolves `AreaId` → `AreaNameById`; importer resolves-or-creates. Residual stale comment at :553–554 (New Finding NF6) |
| §3.3 AuditLog reconciliation dials NodeA only | Med | **Fixed** | `AuditLog/Central/SiteEnumerator.cs:31-33, 64-77` — primary = NodeA else NodeB (NodeB-only sites no longer skipped), distinct NodeB rides along as failover endpoint |
| §3.5 `SmsConfiguration.MaxRetryCount` stored but unused | Med | **Fixed** | `NotificationOutbox/NotificationOutboxActor.cs:470, 485` honors `SmsConfiguration.MaxRetries`/`RetryDelay` (PLAN-06 T18) |
| §3.6 Role-check case-sensitivity asymmetry | Med | **Fixed** | `ManagementService/ManagementActor.cs:108, 499, 515, 530` — `StringComparer.OrdinalIgnoreCase` throughout; PLAN-07 T12 canonicalized casing at write |
| §3.7 SecuredWrite audit rows `SourceNode` NULL | Low/Med | **Fixed** | `ManagementActor.cs:1208` routes secured-write audit through `ICentralAuditWriter`, which stamps `SourceNode` from `INodeIdentityProvider` |
| §3.8 Hash-chain tamper evidence (no-op `verify-chain`) | Low/Med | **Deferred (accepted)** | Register row 8 (v1.x locked decision) |
| §3.9 Parquet archival (501) | Low | **Deferred (accepted)** | Register row 9 |
| §3.10 Aggregated live alarm stream | Low/Med | **Fixed (shipped 2026-07-10)** | `Communication/ISiteAlarmLiveCache.cs`, `Communication/Actors/SiteAlarmAggregatorActor.cs`, `SubscribeSite` rpc in `Communication/Protos/sitestream.proto:13`; options eagerly validated (`CommunicationOptionsValidator.cs:72-87`); no central store (in-memory only, no EF migration) — register row moved to Resolved |
| §3.11 Central-persisted cert-trust audit | Low | **Deferred (accepted)** | Register row 11 |
| §3.12 Native-alarm-source-override CSV import | Low | **Partially fixed** | Parser + ManagementActor handler + CLI `instance native-alarm-source import --file` shipped 2026-07-10; only the Central UI upload affordance remains (register row 12 updated accordingly) |
| §3.13 `WaitForAttribute` quality-gated mode | Low | **Fixed** | `Commons/Messages/InboundApi/RouteToInstanceRequest.cs:117` — `RequireGoodQuality` param, enforced site-side, tested |
| §3.14 `WaitForAttribute` in Test-Run sandbox | Low | **Fixed** | Sandbox `Attributes.WaitAsync`/`WaitForAsync` route via `ISandboxInstanceGateway`; predicate-form waits documented unsupported (register Resolved row 14) |
| §3.15 `BrowseNext` final-page signal | Low | **Fixed / no longer applicable** | `Commons/Messages/Management/BrowseCommands.cs:18-36` — `ContinuationToken` + `Truncated` on `BrowseNodeResult`; "Load more" renders only while a token remains |
| §3.16 `StubOpcUaClient` throws on browse | Low | **Fixed** | Browse + search supported; `tests/.../DataConnectionLayer.Tests/StubOpcUaClientBrowseTests.cs`, `StubOpcUaClientSearchTests.cs` |
| §3.17 Unified outbox page | Low | **Deferred (accepted)** | Register row 17 (explicit M9 decision) |
| §3.18 Folder drag-drop | — | **Closed (permanent)** | Register row 18 `[PERM]` |
| §3.19 Bundle signing / cluster pull / differential bundles | Low | **Deferred (accepted)** | Register row 19 |
| §3.20 Deployment EXPIRED-row purge | Low | **Fixed** | `Communication/Actors/PendingDeploymentPurgeActor.cs` (central singleton, options-validated interval; PLAN-04) |
| §3.21 `SiteAuditBacklogReporter` threshold consolidation | Low | **Fixed** | `SqliteAuditWriterOptions.BacklogPollIntervalSeconds` drives the reporter cadence (`AuditLog/Site/SiteAuditBacklogReporter.cs:61-87`) |
| §3.22 KPI hourly rollups | Low | **Fixed (shipped 2026-07-10)** | `Commons/Entities/Kpi/KpiRollupHourly.cs`; `KpiHistoryOptions.cs:46-73` (RollupInterval 1h, Lookback 3h, Retention 365d, Threshold 168h); validator bounds (`KpiHistoryOptionsValidator.cs:31-44`); `Component-KpiHistory.md` updated (24 rollup mentions) — register row moved to Resolved |
| §4 `docs/components/` lags 3 components vs README claim | Low | **Fixed (via scoping)** | `README.md:111` + `docs/components/README.md:8-9` now state "24 of the 27… ScriptAnalysis/KpiHistory/DelmiaNotifier pending", pointing at the register; actual count verified: 24 component docs + TreeView + index = 26 files. Backfill itself remains deferred (register) |
| §4 DelmiaNotifier breaks `Component-<Name>.md` convention | Low | **Fixed (documented exception)** | CLAUDE.md Document Conventions now carries the explicit DelmiaNotifier exception bullet |

**Disposition counts: 20 Fixed (verified) · 3 Partially fixed · 6 Deferred (accepted, register rows) · 1 Closed-permanent · 0 Not fixed · 0 Regressed.** (The 7 always-Pass items stayed Pass.)

---

## 2. Refreshed Convention Audit (round-2 sweep)

- **UTC**: 0 non-Utc `DateTime.Now`/`DateTimeOffset.Now` across src `.cs`/`.razor` — total compliance held through 268 commits.
- **TODO surface**: 0 `// TODO` / `// FIXME` / `// HACK` in all of src (round 1 had two, both the Transport area export — now shipped). 0 `NotImplementedException` in production code. 29 "deferred/follow-up" comment mentions (was 39), sampled — all are pointer-style documentation of logged decisions, none load-bearing stubs.
- **Commons purity**: intact — 0 EF/DataAnnotations dependencies; Commons csproj still references only `ZB.MOM.WW.Audit`.
- **Correlation IDs**: 99 declarations in `Commons/Messages/` — the new cross-cluster messages added by the plans (per-node KPI requests, secured-write paging, `RouteToWaitForAttributeRequest`, browse `SiteIdentifier` additions) all kept the convention or ride `ManagementEnvelope`.
- **Options pattern**: 16 eager validators (`OptionsValidatorBase<T>` + `ValidateOnStart` + `TryAddEnumerable`) covering every primary per-component options class, including the two post-initiative features (live-alarm-cache fields validated at `CommunicationOptionsValidator.cs:72-87`; rollup fields bounded in `KpiHistoryOptionsValidator.cs:31-44`). Residue: NF4 below.
- **Message-contract enforcement**: additive-only is now *enforced* for the 7 highest-traffic ClusterClient records (`ClusterClientContractLockTests`) and the gRPC protos (existing proto contract tests; the new `SubscribeSite` stream has behavioral coverage in `Communication.Tests/Grpc/`). The lock suite deliberately covers "top" records, not all — new records added by the plans are outside it, which is the accepted design of the guard.
- **csproj hygiene**: 0 `Version=` attributes on PackageReferences in src/tests (central package management honored); 0 backslash path separators; 0 third-party Blazor component frameworks (MudBlazor/Radzen/Blazorise/Syncfusion) — the "custom components only" UI rule held.
- **Slnx**: all 30 test projects are members (the 31st `tests/` match is the `<Folder Name="/tests/">` element).
- **CLAUDE.md accuracy spot-checks**: the claims audited all match code — CLI.Tests slnx note, live-alarm-stream description (`ISiteAlarmLiveCache`, seed-then-stream, 15s poll fallback, no persisted store — no EF migration exists for it), KPI rollup knobs (168h threshold / 365d retention match `KpiHistoryOptions.cs:65-73`), SecuredWrite `SourceNode` stamping, SMS retry policy.

---

## 3. Refreshed Test Inventory

30 test projects (all in the slnx), **~5,620 `[Fact]`/`[Theory]` attribute sites** (round 1: ~5,050; +~570 from the fix plans), ~170k test LOC against ~212k src LOC. Executed-case counts run higher with Theory expansion — the 2026-07-10 terminal sweeps report e.g. CentralUI 898, Commons 609, SiteRuntime 494, ManagementService 448, CLI 359 — roughly **6,300+ executed cases**. Attribute counts per project (grep-based, approximate):

| Project | Attrs | Δ vs r1 | Notes |
|---|---|---|---|
| CentralUI.Tests | 860 | +31 | still the largest suite |
| Commons.Tests | 506 | +41 | now incl. ClusterClientContractLockTests |
| SiteRuntime.Tests | 497 | +40 | |
| TemplateEngine.Tests | 452 | +19 | |
| ManagementService.Tests | 306 | +72 | frozen 138-command authz matrix + dispatch-coverage guard (PLAN-07 UA2) |
| CLI.Tests | 300 | +21 | **now in the slnx** |
| Communication.Tests | 269 | +58 | live-alarm-cache/aggregator suites added |
| AuditLog.Tests | 263 | +26 | |
| InboundAPI.Tests / ConfigurationDatabase.Tests | 234 / 234 | +16 / +15 | |
| DataConnectionLayer.Tests | 200 | +10 | incl. Stub browse/search tests |
| Host.Tests | 164 | +22 | incl. the site-notification design-invariant lock |
| Transport.Tests / Transport.IntegrationTests | 148 / 96 | +24 / +36 | round-trip equivalence guard (PLAN-05 T8) |
| StoreAndForward.Tests / Security.Tests | 144 / 144 | +28 / +11 | |
| NotificationOutbox.Tests | 132 | +10 | |
| DeploymentManager.Tests | 112 | +14 | still thin relative to scope (register row) |
| HealthMonitoring.Tests | 94 | +10 | |
| ExternalSystemGateway.Tests | 85 | +16 | |
| IntegrationTests | 74 | +5 | incl. `Cluster/TwoNodeClusterFixture` + failover/recovery drills |
| SiteEventLogging.Tests | 58 | +4 | |
| SiteCallAudit.Tests | 44 | +13 | grew ~40% but still the thinnest per src LOC (register row) |
| ScriptAnalysis.Tests / NotificationService.Tests | 43 / 43 | +3 / +7 | |
| CentralUI.PlaywrightTests | 36 | 0 | 8 env-only failures documented (need live docker cluster) |
| KpiHistory.Tests | 29 | +15 | doubled with rollup coverage |
| DelmiaNotifier.Tests | 23 | 0 | |
| ClusterInfrastructure.Tests | 18 | +3 | |
| PerformanceTests | 12 | +2 | see below |

**PLAN-08's new tests are real, with one asterisk.** The contract-lock suite (9 tests) does exactly what the review asked and surfaced a genuine wire-behavior finding (Newtonsoft `default(T)` on missing trailing fields — now locked as documented reality). The stream-throughput test is a genuine measurement (100k events through the real `SiteStreamManager` BroadcastHub, asserting ≥10k events/s and ≥90% delivery). The asterisk is the failover-timing placeholder: it shipped as designed (a documented, skipped protocol), but its skip precondition is already satisfied — see NF2.

---

## 4. Deferred-Work Register Assessment

The register (`docs/plans/2026-07-08-deferred-work-register.md`) exists, is committed, and is substantially accurate — including a "Resolved (verified against the code 2026-07-10)" section whose ten resolution claims I spot-verified (items 7, 10, 13, 14, 15, 16, 20, 21, 22, 12-CLI: all confirmed in source, citations in §1 above). Post-initiative work genuinely retired two register rows (#10 live alarm stream, #22 KPI rollups) and most of a third (#12 CSV import — only the Blazor upload affordance remains).

**Remaining open deferrals (verified still-accurate):** #8 hash-chain (CLI `verify-chain` still a no-op), #9 Parquet (501), #11 central cert-trust persistence, #12 (UI upload button only), #17 unified outbox page, #19 bundle signing/pull/differential, plus the four "new deferrals from review 08" rows (layering inversion — still present at `CentralCommunicationActor.cs:13`; three reference docs; SiteCallAudit/DeploymentManager test backfill; perf envelope). #18 is permanently closed. **Net: ~10 open deferrals, all with rationale + trigger, none mislabeled.**

Two register-integrity problems, though:

1. **One revisit trigger has already fired unnoticed** — the perf-envelope row's trigger is "PLAN-01 rig landing", and `tests/.../IntegrationTests/Cluster/TwoNodeClusterFixture.cs` landed 2026-07-08, *before* the placeholder itself shipped (2026-07-10). Nobody revisited (NF2).
2. **The register is no longer the single place.** The master tracker grew its own initiative-level "Deferred / Won't-Fix Registry" (`archreview/plans/00-MASTER-TRACKER.md:137+`) holding items absent from the register — most notably the **SBR oldest-crash total-outage gap** (a real operational risk, owner: user decision) and the unapplied `deploy/wonder-app-vd03` overlay edits (whose absence NULLs `SourceNode` on that deployment's audit rows). An untracked root-level `deferred.md` snapshot duplicates the register a third time and has already drifted from it (NF5). The register's own Fix-now table also violates its stated remove-when-landed rule — all 7 rows landed but are still listed as open.

---

## 5. New Findings (round 2)

### NF1 [High] — Live production API key in plaintext at the repo root
`test.txt` (untracked, repo root) contains a working Inbound API key for the production host `wonder-app-vd03.zmr.zimmer.com:8085` (`sbk_eb5acc0b…`, full key present). It is one `git add -A` (or one run of the `pushit` skill, which stages everything) away from entering history, and it is a live credential regardless. **Rotate/revoke the key** (the dual-key rotation procedure from PLAN-06 T24 exists for exactly this), delete the file, and consider a `.gitignore`/pre-commit secret-scan guard for the root. (File: `/Users/dohertj2/Desktop/ScadaBridge/test.txt`.)

### NF2 [Medium] — Failover-timing test's skip precondition is already satisfied; the 25s envelope remains unmeasured
`tests/ZB.MOM.WW.ScadaBridge.PerformanceTests/Failover/FailoverTimingTests.cs:26-28` skips with "Requires the real two-node failover rig delivered by PLAN-01 … wire it to the rig when PLAN-01 lands" — but PLAN-01's rig landed 2026-07-08 (`tests/ZB.MOM.WW.ScadaBridge.IntegrationTests/Cluster/TwoNodeClusterFixture.cs`), two days before this placeholder shipped. The design's single most-quoted performance claim (~25s failover) is still unverified by any test, the register's revisit trigger for this row has fired, and the skip message is now misleading. Wire the protocol to the fixture (or update the skip reason + register row with the real blocker, e.g. "in-proc rig can't hard-kill a process").

### NF3 [Medium] — CHANGELOG.md abandoned and now factually wrong
`CHANGELOG.md` was last touched 2026-06-02 (`b104760b`), 268+ commits and the entire arch-review initiative ago; its only entry sits under `[Unreleased]`. Worse, that entry asserts "`Operator`/`Engineer` are unused" (`CHANGELOG.md:11-12`) — false since M7 shipped the `Operator`/`Verifier` secured-write roles. A changelog that is both stale and wrong is worse than none: either backfill it from the merge history (the master tracker's wave summaries are ready-made material) or delete it and declare the tracker + `docs/plans/` the release record.

### NF4 [Low] — Options-validation residue: AuditLog sub-options and Host-owned options still bind without validation
PLAN-08 covered the 12 primary component options, but six AuditLog sub-option classes bind via `AddOptions<T>().Bind(...)` with no `.ValidateOnStart()` and no validator: `SqliteAuditWriterOptions`, `SiteAuditTelemetryOptions`, `SiteAuditRetentionOptions` (`AuditLog/ServiceCollectionExtensions.cs:100-108`) and `AuditLogPartitionMaintenanceOptions`, `AuditLogPurgeOptions`, `SiteAuditReconciliationOptions` (`:368-390`). Host-owned `NodeOptions`, `DatabaseOptions`, `LoggingOptions` remain plain `services.Configure<>` (`Host/SiteServiceRegistration.cs:160-172`) — notable because an empty `NodeOptions.NodeName` silently NULLs the `SourceNode` audit column (the exact failure mode the tracker logged for wonder-app-vd03). Also, `OperationTrackingOptions` has no binding site at all (only consumed at `SiteRuntime/Tracking/OperationTrackingStore.cs:59`) — defaults-only, not configurable from appsettings; either bind it or document that it is code-configured.

### NF5 [Low] — Deferral tracking has re-scattered into three places, one of them untracked and drifting
The register's charter ("new deferrals get appended here instead of scattering") is already violated: (a) the master tracker's own registry (`archreview/plans/00-MASTER-TRACKER.md:137-150`) holds the **SBR oldest-crash gap** and the **wonder-app-vd03 overlay edits** — arguably the two highest-risk open items in the whole program — with no register rows; (b) an untracked root `deferred.md` snapshot duplicates the register and has drifted (it counts "12 open deferrals" vs the register's ~10; different section layout); (c) the register's Fix-now table still lists all 7 landed items despite its remove-when-landed rule. Fold the tracker's two live items into the register, delete or commit-and-subordinate `deferred.md`, and clear the Fix-now table.

### NF6 [Low] — Stale comment contradicts the shipped Transport area export
`Transport/Serialization/EntitySerializer.cs:553-554`: "Areas don't travel (see export TODO), so AreaId stays null" — but the export TODO was fixed (area travels by name, `:268-273`) and no TODO exists anymore. The comment sits in `FromBundleContent`, which still materializes `AreaId = null`; it is off the importer's path (BundleImporter walks the raw DTO), so this is comment drift plus a round-trip-fidelity trap in the helper rather than a functional bug — but it is precisely the "half-fixed-looking" confusion round 1 flagged for this feature. Update the comment (and either populate `AreaName`-awareness in the helper or say why it intentionally doesn't).

### NF7 [Low] — Untracked working-tree residue, including an uncommitted design plan
Beyond `test.txt` (NF1): `docs/plans/2026-06-30-mes-alarm-status-api.md` is a 12-day-old draft plan sitting untracked inside `docs/plans/` — the repo's docs-as-spec convention says plan docs are committed decision records; untracked, it is invisible to every other session and one `git clean` from gone. `ScadaBridge-docs-fixed.md` / `ScadaBridge-docs-issues.md` (root-level generated reports) and `.claire/` (tool worktrees) are also untracked clutter. Commit the plan doc (marked Draft), and remove or relocate the rest.

### NF8 [Low] — Duplicate `DataConnectionOptions` binding in the Host
`Host/SiteServiceRegistration.cs:140` binds `DataConnectionOptions` via `services.Configure<>` even though `AddDataConnectionLayer()` (called at `:51`) already binds it with `.ValidateOnStart()` (`DataConnectionLayer/ServiceCollectionExtensions.cs:17-19`). Both bindings compose so validation still runs, but the duplicate invites section-name drift between the two sites. Delete the Host copy (same applies to the `CommunicationOptions`/`NotificationOptions` `Configure<>` calls in `BindSharedOptions` at `:166/:171`, which are redundant on roles where the owning SCE runs).

---

## 6. What's Genuinely Good

- **The fix plans actually fixed things.** 20 of 23 actionable round-1 items verified fixed at the exact seams the review pointed at, with zero regressions found in this sweep — and several fixes exceeded the ask (the contract-lock suite surfaced a real wire-behavior discovery; the round-trip equivalence guard in Transport caught 5 silent-data-loss bugs the per-field tests missed).
- **Convention discipline survived 268 commits of high-velocity parallel-agent churn.** UTC still total, Commons still pure, TODO count went 2 → 0, correlation IDs on every new message, central package management unviolated, no third-party UI frameworks crept in.
- **The two post-initiative features shipped convention-complete on day one**: both came with validated options (live-cache fields in `CommunicationOptionsValidator`, rollup bounds in `KpiHistoryOptionsValidator`), tests, design-doc updates (`Component-KpiHistory.md`, the 2026-07-10 plan docs), CLAUDE.md updates, and register-row closure — the "docs + code + tests together" rule working as designed, unprompted.
- **Deferral honesty**: shipped no-ops and 501s still say what they are; the register's Resolved section shows items being verified against code before being marked done, and two register rows were retired by real shipped work within 48 hours of the register's creation.
- **Test posture improved where it was weakest**: KpiHistory.Tests doubled, SiteCallAudit.Tests +40%, the frozen 138-command authorization matrix turned the largest unaudited security surface into a locked contract, and CLI.Tests finally runs at the solution level.

---

## 7. Prioritized Recommendations (round 2)

1. **[High] Rotate the exposed wonder-app-vd03 API key and delete `test.txt`** (NF1); consider a root-level secret-scan/gitignore guard.
2. **[Medium] Wire `FailoverTimingTests` to `TwoNodeClusterFixture`** or update the skip reason + register row with the true blocker (NF2) — the 25s envelope is the last unmeasured headline design claim.
3. **[Medium] Fix or kill CHANGELOG.md** (NF3) — at minimum correct the now-false Operator/Engineer claim.
4. **[Low] Finish the options sweep's tail**: ValidateOnStart + validators for the 6 AuditLog sub-options and a minimal `NodeOptions` validator (non-empty `NodeName` when auditing is active) (NF4); drop the duplicate Host bindings (NF8).
5. **[Low] Re-consolidate deferral tracking** (NF5): move the SBR gap + wonder-app overlay items into the register, clear the landed Fix-now rows, delete/subordinate root `deferred.md`.
6. **[Low] Commit `docs/plans/2026-06-30-mes-alarm-status-api.md` and clean root clutter** (NF7); fix the stale `EntitySerializer.cs:553` comment (NF6).

## Severity Tally — NEW findings only

| Severity | Count | Findings |
|---|---|---|
| Critical | 0 | — |
| High | 1 | NF1 (production API key in working tree) |
| Medium | 2 | NF2 (failover envelope unmeasured, stale skip), NF3 (CHANGELOG abandoned + wrong) |
| Low | 5 | NF4 (options residue), NF5 (deferral scattering), NF6 (stale Transport comment), NF7 (untracked plan doc + clutter), NF8 (duplicate bindings) |
