Six domain reports + overall synthesis. All 47 cycle-2 Done claims verified at HEAD with zero false Dones and zero regressions; 34 new findings (0 Critical, 0 High, 4 Medium, 25 Low, 5 Info): GWC-31..38, WRK-32..34, IPC-33..39, SEC-37..41, CLI-46..50, TST-31..36.
26 KiB
Testing, Documentation & Underdeveloped Areas — Re-Review (cycle 3)
- Date: 2026-08-19
- Commit:
8b3e3b3(main, "Merge feat/sweep-reread-tag-summary…") - Baseline: prior report
archreview/2026-07-12/60-testing-docs-gaps.md@4f5371f(2026-07-12); ~288 commits since. - Method: macOS static review — reading only, no builds, no test runs, no remote hosts. One read-only script executed (
python3 code-reviews/regen-readme.py --check, sanctioned by REVIEW-PROCESS.md). All paths relative to/Users/dohertj2/Desktop/MxAccessGateway.
Prior-finding verification
Cycle-2 findings (TST-25..30)
| ID | Claimed status | Verified? | Evidence (file:line) | Notes |
|---|---|---|---|---|
| TST-25 | Done | Yes | .gitea/workflows/ci.yml:144-165 (windows-x86 per-push job, Linux runner → SSH to windev, exit-code propagation) and :167-201 (nightly-windev, if: github.event_name == 'schedule', run-windev-ci.sh live, on-failure Gitea-issue step); scripts/ci/run-windev-ci.sh (SHA-shape validation :46-49, base64 key decode :70-78, bootstrap holds the worktree lock :91-119); scripts/ci/windev-worker-ci.ps1 (lock reuse via MXGW_CI_LOCK_HELD :77-94, re-checkout under lock + HEAD verification :99-111, cumulative build/test/live modes :119-139) |
The whole design shipped as specified, including the acceptance-check hardening: the CI key is stored base64 single-line so Gitea's line-oriented masker redacts it (ci.yml:156-159), the bootstrap fetch/checkout races were serialized under the mkdir lock, and the nightly failure issue carries a browser-reachable link via PUBLIC_SERVER_URL (ci.yml:174-181, Check 6 closed 2026-08-10 per docs/runbooks/TST-30-second-ci-runner.md). Ground truth from the operator confirms the tier runs green. |
| TST-26 | Done | Yes | docs/GatewayTesting.md:624-657 describes exactly the four jobs that exist (portable, java, windows-x86, nightly-windev) incl. the "red can mean the tier is down" triage (:649-652); scripts/check-codegen.ps1:26-27 now attributes the x86 guard to "the SSH-driven windows-x86 CI job"; ci.yml:14-18 cron comment matches what the schedule runs |
Guard attribution is correct both ways: primary = Check 2 regeneration diff in portable, secondary = the windows-x86 net48 compile (GatewayTesting.md:699-703). No named job is missing and no phantom job survives. |
| TST-27 | Done | Yes | docs/GatewayConfiguration.md:195 — the ShowTagValues row now describes all three seams (events-hub mirror, alarms hub, /browse live values incl. the successful-read-only nuance from e50ec49), the clone-don't-mutate guarantee, and the ACL layering |
"Reserved" is gone; the row was rewritten a second time when TST-16's residuals shipped (2026-08-17), so it documents strictly more than the finding asked. |
| TST-28 | Done | Yes | src/ZB.MOM.WW.MxGateway.Tests/Gateway/Workers/WorkerClientTests.cs:46 — StartAsync_SendsGatewayHelloWithConfiguredMaxFrameBytes(int maxMessageBytes) theory, in the CI-run portable suite |
Exactly the designed test (default + override), pinning the gateway half of the IPC-02 negotiation on Linux CI. |
| TST-29 | Done | Yes | oldtasks.md absent from the tree; the five *-docs-*.md root artifacts absent; docs/DesignDecisions.md:264 "Session-Resilience Epic Scope" carries the Phase-5 deferred-not-planned record and :295 the "EnableOrphanReattach does not exist and must not be referenced" rule; CLAUDE.md's invariant paragraph points at DesignDecisions |
Governance record migrated intact before deletion, exactly per the design. Residual: stillpending.md (also a TST-14 root artifact) still contradicts the migrated record — see new finding TST-33. |
| TST-30 | Done | Yes, with one pending operator action | docs/runbooks/TST-30-second-ci-runner.md:1-13 (Executed 2026-08-07: gitea-runner-2, id 5, capacity 2, container.network: traefik, token from a 0600 file mount; concurrency verified across three simultaneous runs) plus the honest correction that the per-repo runners endpoint legitimately returns 0 (instance-level registration); docs/GatewayTesting.md:659-685 documents the shared-capacity/no-cancel reality and the run-windev-ci.sh bypass |
The runner exists and the docs match the executed state. The follow-up it surfaced is still open: the shared instance registration token (world-readable ~5 months, proven still live by a probe registration) needs a web-UI reset — promoted to new finding TST-32 so it stops living only inside a closed finding's runbook. |
Done claims that failed verification: none. All six hold with file:line evidence; TST-30 carries the one explicitly-tracked operator residual (TST-32 below).
Cycle-1 leftovers still tracked open (spot-verified at HEAD)
| ID | Tracker status | State at HEAD |
|---|---|---|
| TST-05 | Partially done | Residual confirmed open. The live suite is 8 [LiveMxAccessFact]s (WorkerLiveMxAccessSmokeTests.cs:34-920) with zero references to Ping/GetSessionState/GetWorkerInfo/DrainEvents/ShutdownWorker; the gap is honestly documented at docs/GatewayTesting.md:90-95. The scheduling half stays closed (nightly-windev runs the suite). The two control-command live facts specified in archreview/remediation/60-testing-docs-gaps.md remain unauthored (windev-only work). |
| TST-06 | Not started | Materially narrowed, tracker stale. Tests/Gateway/Dashboard/DashboardLiveDataServiceTests.cs, EventsHubTests.cs, EventsHubViewerRegistryTests.cs, AlarmsHubPublisherTests.cs, SessionDetailsPageEventAclTests.cs all exist now (mostly landed with SEC-25/TST-16 closeouts and the in-process dashboard-feed work). The cycle-1 row deserves a re-audit-and-close pass rather than "Not started". |
| TST-07 | Not started | Partially addressed: the WorkerClientTests 150 ms sleep-then-negative-assert is gone; SessionManagerTests.cs:491 still has a real-clock Task.Delay(50). |
| TST-09 | Not started | Partially addressed: GatewayApplication.cs:117-124 now registers AuthStoreHealthCheck and SessionHealthCheck (the /health/active probe with off-repo consumers). Still no Galaxy SQL / LDAP / worker-executable checks. |
| TST-10 | Not started | Still no docs/Deployment.md; partial mitigation via docs/runbooks/IdentifyingADeployedBuild.md and the SEC-36 rotation runbook, but deploy/upgrade mechanics (dated Server-YYYYMMDD dirs, NSSM repoint, env-var config) still live in operator memory notes, and the 2026-08-09 credential-store-renamed-away outage (docs/GatewayConfiguration.md:100) shows the cost. |
| TST-14 | Not started | Mostly discharged by TST-29 (oldtasks + the five untracked artifacts gone). Remaining root-file triage: stillpending.md (now the stale one — see TST-33) and A2-galaxyrepository-adoption-handoff.md (carries a current "ADOPTED" banner; acceptable as a handoff record). |
| TST-17 | Not started | Materially changed — row needs refresh by the worker domain. WnWrapAlarmConsumer.cs:309-327 now passes szDomainName/szOprFullName into the COM call (the _ = ackOperatorDomain discard is gone), and the 2026-08 probe cycle recorded the vendor 8-arg leg as "unavailable by configuration" with evidence (docs/AlarmProbeFindings.md, commits d1ae43d, 540a118). Whether a caller-visible degrade signal exists is the worker reviewer's call, but "silent drop, unchanged" is no longer an accurate row. |
| TST-18 | Not started | Confirmed open — no *HostedService* tests under src/ZB.MOM.WW.MxGateway.Tests. |
| TST-19 | Not started | Confirmed open — FakeWorkerHarness.cs still has no lockstep note / WorkerPipeSession pointer. Mitigation since: the harness's canned control replies are no longer the only automation (windows-x86 runs the real worker suite per push), but the drift risk the finding names is intact. |
| TST-20 | Not started | Confirmed open — run-client-e2e-tests.ps1:48 DrainEveryTags = 15 workaround intact. |
| TST-21 | Not started | Confirmed open — Server/appsettings.json:10 daily rolling file sink, no size cap / retained-count. |
| TST-22 | Not started | Confirmed open — the shape block (docs/GatewayConfiguration.md:12-88) is maintained (gained GroupToTag, UntaggedSessionVisibility, RecentFaultLimit/RecentSessionLimit) but still omits documented keys (DisableLogin, AutoLoginUser, CookieName, Tls, Ldap, Security, Alarms:Fallback, Worker:WriteCompletionWaitMilliseconds, …). The option tables below it are complete and current — the omissions are only in the illustrative block. |
New-code / new-docs review since 4f5371f
CI workflow evolution — verified sound. ci.yml at HEAD is a four-job pipeline whose comments are accurate down to the failure semantics. Details worth recording: the portable job now runs the .NET client tests (TST-24 wire tests included, ci.yml:83-90), installs pwsh and the pinned Check-4 generators explicitly (:58-72), and pins protoc 34.1; the java job's git diff --exit-code is the true drift gate after IPC-24 deleted the churn-revert; run-windev-ci.sh validates CI_SHA shape before it reaches a remote shell (:46-49), never echoes the key, and pins host keys from the committed windev.known_hosts; windev-worker-ci.ps1 re-checks-out under the lock, verifies HEAD == Sha, git clean -fdx -e ci.log, and is deliberately PS5.1-safe. The nightly's issue-on-failure path uses the runner-resolvable github.server_url for the API call but PUBLIC_SERVER_URL for the human link — the exact defect Check 6 caught, fixed in 30c92e8.
check-codegen.ps1 — now four checks with the Check 3 reverse sweep (:98-103, canonical proto missing a vendored copy fails — the drift class no in-repo build can surface, 711793f) and Check 4 Windows support (.exe banner normalization in the per-client generate-proto.ps1 probes, c94c4d4; PS5.1-safe native-arg quoting, 8ae0c2f). The header comment (:2-27) is accurate.
fca978d marker sweep → f82dac1 restoration — assessed complete on sampled evidence. The sweep (2026-07-07, 203 files) deleted ~1,100 prose-bearing comment lines alongside the tracking markers; the 2026-08-18 re-read narrowed those to 816 residual lines, judged each, and restored 17 collateral deletions across 10 files (f82dac1, merged 8b3e3b3). Spot-checks of four substantive deletions outside the restored set all found surviving equivalents at HEAD: the SessionEventDistributor mode-vs-count FailFast race rationale survives in docs/Sessions.md:206 (including the "fixed mode rather than a live subscriber-count snapshot" decision) and docs/GatewayConfiguration.md:159; the MxAccessStaSession off-STA-deadlock affinity-guard rationale survives in AlarmCommandHandler.cs:68-80; the subtag source's own-COM-object isolation rationale survives in LmxSubtagAlarmSource.cs class remarks; the watchdog HeartbeatStuckCeiling rationale survives in WorkerPipeSessionOptions.cs:35+. No residual collateral damage found. The companion d3ac527 audit (re-verifying 20 doc-only Server-0xx resolutions, re-fixing the two the sweep had silently reverted — Server-040 among them) closes the loop on the sweep's other damage class. This is a model recovery process.
Doc currency at HEAD — high. Sampled claims all match code: docs/Sessions.md:17 pipe-name prose matches SessionManager.cs:536 (mxgw-{pid}-{uid}, with the sun_path rationale); docs/Sessions.md:248 owner-scoped attach matches EventStreamService; docs/GatewayConfiguration.md documents the new WriteCompletionWaitMilliseconds (:121, with the OtOpcUa 2 s budget interaction), EventQueueCapacity (:122), alarm poll/fetch ceilings incl. truncation semantics (:435-436), and the Fallback block (:448-451); docs/GatewayTesting.md is the standout — the windev sections (:488-622) record the 879 baseline, the two "environmental" failures that were test bugs, the load-sensitivity list, and a first-class post-mortem of the zero-buffer-pipe testhost hang with the structural fixes (TestNamedPipe.CreateServer, bounded PipePair.WriteAsync). docs/Authentication.md was made runnable-as-written (2b2748b); docs/AlarmProbeFindings.md states the probe questions and their evidence honestly (ack leg unavailable-by-configuration, GUID leg still assumed). python3 code-reviews/regen-readme.py --check passes at HEAD ("up to date and consistent").
New-feature test placement — correct layers. Alarm truncation / snapshot_status: proto-level flag plumbed with direct tests (b9fb0dd atomic snapshot+truncation read), gateway feed frame (AlarmTruncationSignalTests.cs), dashboard banner (AlarmsPageTruncationBannerTests.cs incl. the mid-truncation attach case, f57a6ae), and all five clients regenerated with render coverage (4d4f443). SEC-25 tag ACL: DashboardSessionAclTests, both subscribe seams covered (EventsHubTests, SessionDetailsPageEventAclTests), decision-table corners pinned (7ec0b35), plus live-LDAP ACL coverage (1d8a4a6). Drain cluster (WRK-21/IPC-23/IPC-30): worker-side byte-budget tests run per-push via windows-x86; the gateway side keeps the drain-to-empty walk inside the pipe-harness envelope (a256560). Write-completion correlation: worker executor tests (b0e2b8b, c867aca) plus gateway-side config plumb tests (GatewayOptionsTests, WorkerProcessLauncherTests). In-process wire tests (TST-24) exist for all five clients and run in CI (docs/GatewayTesting.md:280-321).
New findings
TST-31 — glauth.md's pre-provisioned-users table contradicts the directory, and its wrong credential propagated into the live-test surface — Medium · documentation currency / test fixtures (promotes NEXT-10)
- Files:
glauth.md:55(ReadOnly gid5501vs actual5601),:65-78(pre-provisioned users table:readonly/readonly123does not exist inscadaproj/infra/glauth/config.toml;admincarries the standard dev password, notadmin123),:124(Password: admin123in a worked example); propagation:docs/GatewayTesting.md:119(MXGATEWAY_LIVE_MXACCESS_WRITE_SECURED_PASSWORDdefaultadmin123) andsrc/ZB.MOM.WW.MxGateway.IntegrationTests/WorkerLiveMxAccessSmokeTests.cs:1432(?? "admin123", with:517attributing the identity to the GLAuth-bridged ArchestrAadmin/admin123). - Description: Carried over from
archreview/2026-07-12/remediation/90-candidate-findings-next-cycle.mdNEXT-10, which was deliberately deferred pending the OPC-UA group-taxonomy sweep and is still fully present at HEAD. The table was already the proven root cause of one defect (the NEXT-06 live-LDAP fixture drift, fixed 2026-08-07 — the fixtures were realigned but the table that misled them was not). The remaining propagation has a quiet coverage cost: the nightly live smoke'sWriteSecuredparity test authenticates with the defaultedadmin/admin123, and becauseAuthenticateUserlegitimately returns a real MXAccess failure reply on bad credentials (parity, notInvalidRequest), a wrong default does not fail the test — it silently degrades the WriteSecured leg from "authenticated round-trip" to "failure-reply shape check" every night. A reader also cannot tell which half ofglauth.mdto trust, since its dashboard section is correct. - Recommendation: Reconcile the table against
scadaproj/infra/glauth/config.tomlas one unit with the OPC-UA group taxonomy (the reason it was deferred), or — if that sweep stays parked — fix the two provably-wrong rows and the gid now and leave the taxonomy note. In the same change, re-derive theMXGATEWAY_LIVE_MXACCESS_WRITE_SECURED_PASSWORDdefault and theWorkerLiveMxAccessSmokeTestsliteral from whatever the rig's ArchestrA-bridged identity actually is, and make the live test log (not assert) whetherAuthenticateUsersucceeded, so a credential regression in the nightly is at least visible.
TST-32 — The shared Gitea runner registration token (world-readable for ~5 months, proven live) still awaits its web-UI reset — Medium · CI/ops security
- Files:
docs/runbooks/TST-30-second-ci-runner.md:33-42("Follow-up 2026-08-07 — token hygiene");archreview/2026-07-12/remediation/90-candidate-findings-next-cycle.md:24(the pending-operator-action row). - Description: Both CI runners share one instance-scope registration token that sat world-readable in
/opt/gitea/docker-compose.ymlfor roughly five months and is still valid — a probe registered runner id 6 with it and then deleted it. Host hygiene is done (token now a0600file mount, compose + backups locked down), but hygiene does not retire the credential: anyone who read it can register a rogue runner that receives this repo's jobs, including theWINDEV_SSH_KEYsecret that grants shell on windev. Gitea 1.26.4 exposes no rotation via CLI or API (both are get-or-create), so the reset must be done in the admin web UI, then/opt/gitea/runner_tokenrefreshed and the two token-bearing compose backups shredded. This has been a documented "pending operator action" since 2026-08-07 with no tracked finding forcing it to a close — precisely the state in which such actions rot. - Recommendation: Execute the reset per the runbook (minutes of work; re-registration of the two runners with the new token is the only follow-on). Track it here rather than only in a closed finding's runbook, and after the reset append the dated "Executed" note the runbook's own convention expects.
TST-33 — stillpending.md has drifted into self-contradiction and now overstates what is pending — Low · repo hygiene / documentation currency
- Files:
stillpending.md:54(reconnect "not safe to rely on end-to-end yet" — Tasks 13–15 shipped and were verified as cycle-2 TST-01/TST-02 with all-five-client consumers);:56(Phase 5 orphan reattach "planned (epic Phase 5, not started)" — directly contradicts the governance record TST-29 migrated todocs/DesignDecisions.md:264-295, which says deferred, not planned, and CLAUDE.md's invariant);:111("WorkerLiveMxAccessSmokeTests.cs (6[LiveMxAccessFact])" — there are 8);:118("Cross-language client↔gateway wire behavior — no per-client integration unit tests… All client wire behavior is unverified in default unit runs" — false since TST-24 closed 2026-08-10: all five clients have real-transport wire tests running in CI);:150(§8: per-session-ACL "still scheduled… not yet started") vs:65(§2: the same item "RESOLVED (2026-08-17)") — the file contradicts itself. - Description: The file is not a frozen snapshot — it has been annotated through 2026-08-17 — so readers reasonably treat it as live, and it is one of the two remaining root-level triage artifacts from TST-14. Its most dangerous staleness is
:56: it re-asserts the "planned Phase 5 /EnableOrphanReattach" framing that TST-04/TST-29 spent two cycles extinguishing, in the exact file a future contributor greps when asking "what's still pending". - Recommendation: One currency pass: fix the five spots above (§2 reconnect → shipped; §2 Phase 5 → deferred-not-planned, pointing at DesignDecisions; §5 counts and the wire-test bullet; §8 ACL row → resolved, matching §2). Then either commit to keeping it current or stamp it "historical snapshot — see archreview trackers for live status" at the top, which is the cheaper honest option.
TST-34 — The code-reviews README consistency check is "the intended hook for CI" but is wired into no CI job — Low · CI
- Files:
REVIEW-PROCESS.md:124-131("regen-readme.py --checkexits non-zero if README.md is stale… The PowerShell wrapperscripts/check-code-reviews-readme.ps1runs that check and is the intended hook for CI or a pre-commit step");.gitea/workflows/ci.yml(no reference to either script in any job); alsoREVIEW-PROCESS.md:130-131(the "barepython3alias resolves to the Windows Store stub — usepython" note is Windows-only advice presented unconditionally; on the macOS treepythonmay be absent andpython3is correct). - Description: The check passes at HEAD (verified this review), and the repo's process doc names CI as its intended home, but 13 months of CI evolution never picked it up — so a stale
code-reviews/README.mdor an inconsistent open-findings count merges silently until the next human runs the script. The portable job already installs Python 3.12, so the cost is one step. - Recommendation: Add a
Code-reviews README consistencystep to theportablejob (python code-reviews/regen-readme.py --check), and qualify the interpreter note in REVIEW-PROCESS.md as Windows-specific (macOS/Linux:python3).
TST-35 — The Windows-host run of the gateway (net10) suite is still manual-only, and its failure class recurred three times in August — Low · CI/coverage
- Files:
docs/GatewayTesting.md:488-498("The gateway suite… is not part of the CI Windows tier —windows-x86andnightly-windevrun only the x86 Worker build andWorker.Tests. It is still run on windev by hand…"); evidence the class is real:e2352d1(two Windows-only gateway test bugs long dismissed as environmental),bfcf829/02baf0c(zero-buffer Windows pipe wedged the whole suite's testhost),25f07f8(SQLite pool sharing-violation on Windows-only cleanup). - Description: TST-25 restored the Worker tier, but the gateway suite's Windows-specific divergences (platform crypto formatting, Windows pipe buffer semantics, file-sharing rules) surface only when someone remembers the manual windev run. Every one of the three August finds was a real defect in test code that CI could have caught nightly; the suite's idle wall time on windev is ~31 s, and the nightly job already builds the full slnx there — the marginal cost of running the suite is small. Severity Low, not Medium: the same 879 tests run on Linux per push, the manual procedure is well documented with a current baseline, and known load-sensitivity (the suite flakes when run concurrently with the x86 tier,
GatewayTesting.md:530-555) means naive stacking into the nightly needs care. - Recommendation: Extend
windev-worker-ci.ps1'slivemode with adotnet test src/ZB.MOM.WW.MxGateway.Testsstep after the Worker tier finishes (the lock already serializes the box, which addresses the documented load sensitivity), and record the 879 expectation in the script log. If nightly wall time becomes a concern, a weekly cadence still beats "when someone remembers".
TST-36 — Docs and CLAUDE.md refer to the "event scope"; the canonical scope string is events:read — Low · documentation
- Files:
CLAUDE.md:160(twice: "Possessing theeventscope…", "anevent-scoped key");docs/Sessions.md:248(twice);docs/DesignDecisions.md:93;docs/Grpc.md:103(mitigated — it parenthesizesGatewayScopes.EventsRead); canonical constants insrc/ZB.MOM.WW.MxGateway.Server/Security/Authorization/GatewayScopes.cs:10("events:read"). - Description:
f2a422b("canonical scope strings in the two remaining stale lists") fixed the scope lists but left theevent-scope shorthand in running prose. There is noeventscope: an operator who takes the prose literally and runsapikey create-key --scopes eventmints a key that cannot stream. CLAUDE.md even uses the correctevents:readforty lines earlier (:158), so the same file teaches both spellings. - Recommendation: Mechanical sweep: replace "
eventscope" with "events:readscope" in the four prose sites (Grpc.md's parenthesized form is acceptable as-is). One grep verifies completion:git grep -n '\event` scope'overCLAUDE.md docs/` returns nothing.
Severity roll-up (new findings)
| Severity | Count | IDs |
|---|---|---|
| High | 0 | — |
| Medium | 2 | TST-31, TST-32 |
| Low | 4 | TST-33, TST-34, TST-35, TST-36 |
Still good / preserved
- The windev CI tier is the best piece of infrastructure this domain has reviewed in three cycles. It shipped exactly per design and then got hardened by its own acceptance checks: the cleartext-key leak was found and fixed by storing the key base64 (with the masking rationale documented in three places), the bootstrap lock race was closed with an explicit
MXGW_CI_LOCK_HELDhandoff, the SHA is shape-validated before it reaches a remote shell, an unreachable windev fails red instead of wedging, and the nightly's failure path was itself tested to failure (Check 6) and fixed.scripts/ci/README.mdrecords the bring-up, the acceptance checks with dated outcomes, and the degraded mode. - The codegen guard now covers every generated surface in both directions: descriptor set,
Contracts/Generated, Rust vendored protos (including the reverse sweep for never-vendored canonical protos — drift no in-repo build can surface), Go/Python bindings with pinned generators that fail rather than skip when missing, and the Java aggregates via the java job's git-diff gate. Check 4 was additionally made Windows-runnable, so windev regen workflows use the same guard. - The prior cycle's High (TST-25) is not just closed — its unlocks were followed through: old TST-24 closed with real-transport wire tests in all five clients running in CI, old TST-05's scheduling half closed by the nightly, the EventBurst flake root-caused and deflaked (flush-edge sampling), the two "windev-environmental" failures exposed as test bugs, and the months-old full-suite testhost hang root-caused to a zero-buffer Windows pipe with structural fixes (
TestNamedPipe.CreateServer, boundedPipePair.WriteAsync) plus a first-class post-mortem indocs/GatewayTesting.md— the windev baseline now equals macOS at 879. - Documentation discipline visibly recovered from its one big self-inflicted wound. The
fca978dsweep's collateral damage was found by a systematic re-read (816 lines judged, 17 restorations), the doc-onlyServer-0xxresolutions were re-audited with the two regressions re-fixed (d3ac527), and every doc-currency spot-check this review ran (Sessions, GatewayConfiguration, GatewayTesting, Authentication, alarm probes, pipe naming, write-completion) matched code at HEAD. The two currency findings this cycle (TST-31, TST-33) are inherited debris, not new drift from the ~288-commit period. - New features landed with tests at the right layers: alarm truncation is asserted from the worker flag through the proto, the gateway feed frame, the dashboard banner (including mid-truncation attach), and all five client renders; the SEC-25 tag ACL is pinned at both subscribe seams with decision-table corners and live-LDAP coverage;
regen-readme.py --checkpasses;code-reviews/README.mdis consistent with the per-module findings at HEAD.