docs: deferred-table closure, stale-comment sweep, as-built execution record
This commit is contained in:
@@ -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`.
|
||||
|
||||
Reference in New Issue
Block a user