Review fixes on top of cb2b104:
- Delete the write-only in-memory refuseUntil map and setRefusalBackoff now
that status.go is gone: the pass gate reads the durable stamp, so the map
was half-deleted dead state (spec review C-1).
- An outcome-query failure no longer blanks the Lane table into the false
'no data yet': rows render with 'none observed' chips instead (I-1).
- due-query and eligible-count skips get their own sentences instead of the
merged 'check failed' (I-2).
- ADR-0012 constrain wording corrected and trailing newline added (M-1)
2.1 KiB
ADR-0012: Persisted lane state
Date: 2026-08-21 Status: accepted
Supersedes the in-memory lane snapshot carried by latest's LaneState/Status
and the web.LaneReporter seam (ADR-0010 wrote the durable rows this page now
reads).
Decision
The admin Lanes page stops reading the poller's in-memory Lane state and
becomes a read of poll_passes/poll_lanes in Postgres. There is no
LaneReporter interface: web/admin_lanes.go walks store.LatestLanePasses()
into one row per Site and adds the window's outcome sums from
store.LanePassOutcomes(). The latest package's LaneState/Status snapshot
and its web.LaneReporter seam are deleted.
The browser is a deployment configuration fact plus a reachability derived
from the pass log: BROWSER_WS_URL set means "configured", and the browser is
"reachable" unless a recent browser-Site pass inside latest.RefuseBackoff is
a sidecar loss, a missing fetcher, or an interrupted read. A skip reason is
the whole difference between a Lane resting and a Lane stuck: a skipped pass
prints its sentence, and only an empty skip with Series due and none read
draws the true-stall fault. Sleep skips never count toward Attention.
Why
The old page lived on a poller snapshot. Because that state was in memory, a deploy erased it: the page read zeroes until a fresh pass ran, and browser reachability came through a reporter interface only a live poller could serve. Making the page answer from the database means a restart is complete the instant the store is up, the browser fact survives a poller restart, and a Lane that has not yet gathered figures shows a placeholder rather than a confident zero.
Constraints
The poller still owns the writes: each pass exit records one row (ADR-0010),
and a pass that returns before gathering figures carries the previous pass's
numbers forward instead of recording zeroes. A skip is a stable wire string;
asleep never counts toward Attention. When polling is switched off
(LATEST_CHAPTER_POLL_ENABLED unset) the page must say so, and the browser
statusline appears only when polling is switched on.