Files
ScadaBridge/archreview/08-conventions-tests-underdeveloped.md
T
Joseph Doherty 5bbd7689fa docs(archreview): round-2 re-review (2026-07-12) + 8 fix plans (86 tasks)
Re-ran all 8 domain reviews at HEAD 8c888f13 against the b910f5eb baseline:
every round-1 finding source-verified (168 fixed, 0 regressions, 0 false
claims); 56 new findings (1 Critical / 4 High / 15 Medium / 36 Low),
concentrated in post-baseline code (anti-entropy resync, KPI rollup
backfill, live alarm stream) and seams the fixes exposed.

Headliners: S&F resync predicate inversion can wipe the delivering node's
buffer (02-N1 Critical); resync snapshot exceeds the Akka remoting frame
size (02-N2); failover drill kills the one node keep-oldest can't survive
(01-N1); unbounded rollup backfill per failover (04-R1); live production
API key in untracked test.txt (08-NF1).

Adds PLAN-R2-01..08 + .tasks.json manifests and the Round-2 board,
P0 list, cross-plan mutexes, and wave order in 00-MASTER-TRACKER.
2026-07-12 23:52:10 -04:00

26 KiB
Raw Blame History

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 5760); 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 5094). 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 AreaIdAreaNameById; importer resolves-or-creates. Residual stale comment at :553554 (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, 530StringComparer.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:117RequireGoodQuality 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-36ContinuationToken + 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)