docs: deferred-table closure, stale-comment sweep, as-built execution record

This commit is contained in:
Joseph Doherty
2026-08-15 21:33:28 -04:00
parent bb7aa6209f
commit e1ff05c605
5 changed files with 83 additions and 8 deletions
@@ -308,3 +308,67 @@ Push the branch to origin, then on windev (`ssh windev`, clone `C:\build\mxacces
| Structural alarm-truncation degraded-status signal | Contract-level design (proto change candidate) — separate effort. |
| SEC-25 per-session dashboard event ACL | Security roadmap item; Task 6 deliberately preserves the current posture. |
| `MxAccessWriteCompletionCache` clone | Different lifecycle than the value cache; consciously kept (Task 12.5). |
---
## As-built notes (execution record)
Where the delivered work differs from the task text above, or where the route to it
is worth keeping, this is the record.
**Task 3 — `ReadEventsAsync` retained.** The method was not removed after
`MapWorkerEventsAsync` inlined the read-then-map chain: a second caller reaches it
through `ISessionManager.ReadEventsAsync`. That interface member itself has zero
production call sites — only test fakes implement and exercise it. Deleting it is a
mechanical but wide change (~15 test-fake touches), so it is recorded as a follow-up
rather than done here.
**Task 5 — dashboard event feed, two review rounds.** Review caught two races that
the first cut did not have. First, subscription lifetime: subscriptions are now
generation-tagged, a generation ends at the time the fault is *observed* (not when it
is raised), `Reset` is scoped to the dying generation so it cannot cancel its
successor, and a backstop restart covers the case where no subscriber is left to
drive recovery. Second, `UnsubscribeAsync` needed a generation-scoped idle gate so a
teardown for an old generation cannot tear down the new one. Both fixes are pinned by
tests verified against mutations of the fixed code.
**Task 6 — subscribe API placement.** The subscribe surface lives on
`IDashboardSessionEventSubscriber`, with DI forwarding to a single instance so every
consumer shares one feed. Batches that arrive for a session the renderer has already
moved off are dropped by a subscription identity check inside the renderer dispatch,
which is what makes a stale batch harmless rather than a cross-session leak.
**Task 10 — the delivered property is the delivery point, not awaited latency.** The
spec asked for control-frame completion to be observable before the pass's event
writes. That is unachievable in the enqueue-then-contend shape: a caller that loses
the write-lock race does not run again until the winning drainer releases the lock,
so its `await` cannot return early no matter when its frame completes. What shipped
is the honest half: control frames are written *and flushed* at the class-transition
boundary, so the priority class governs the frame's delivery point rather than only
its byte order. Getting the awaited-latency win too requires unparking the lock-race
loser from the winner's pass — a change to the write-lock shape, recorded as a
follow-up. One extra `FlushFileBuffers` per mixed pass is the accepted cost.
**Task 11 — teardown ordering and unconditional fault observation.** Teardown disposes
the session-owned transport first, then observes the read that dispose abandoned.
Fault observation is unconditional — a `ContinueWith(..., TaskContinuationOptions.OnlyOnFaulted)`
continuation, so the budget that bounds the wait is diagnostics-only and can never be
the reason a fault goes unobserved. The same continuation covers heartbeat and drain
overrun. `DisposeTransportStream` is exception-total: no dispose path can throw out of
teardown.
**Task 12 — three clones removed, plan rationale corrected in-code.** All three
`OnDataChange` value-cache clones are gone. The plan's stated reason for keeping the
`MxAccessWriteCompletionCache` clone ("different lifecycle than the value cache") is
wrong and was corrected where the code documents it: the clone is kept on
*provenance* grounds — the cached payload comes from a caller-supplied object the
worker does not own — not on lifecycle grounds.
**Task 13 — windev verification.** Solution build 0 warnings / 0 errors after
clearing stale `Contracts` `obj` artifacts (an infrastructure problem on the box, not
a regression from this branch). Worker x86: 509/509 (+8 new). Gateway: 1059/1059,
including `SecretsStorePathGuardTests` — the first fully green Windows gateway run,
that suite having been red before this branch. One load flake
(`InvokeAsync_WhenWorkerHandshakingThenReadyWithinTimeout_Succeeds`) passed in
isolation and on re-run, consistent with the load-sensitivity caveat documented in
`docs/GatewayTesting.md`.