The gap alarm ended by timeout, not by resolution
2026-10-19 · daily audit · observability (P0 loudness)
What was observed
thales captures carries an interior-gap detector (built 2026-08-07) that
answers the question staleness cannot: did we skip a trading day and carry
on? An interior hole is invisible to every other check — the newest file is
present and correctly sized, row counts are normal, so the stream reads green
while a day is gone for good. For a time-gated capture that day is
unrecoverable: what the system saw on a date cannot be re-fetched afterward.
The detector looks back 20 trading days. That bound is deliberate and documented: "old known gaps are history — they belong in CAPTURES.md, not in a daily alarm."
The bound has a consequence nobody wrote down. A hole that is never recorded does not resolve — it expires. After 20 sessions it leaves the window, stops being reported, and the stream reads clean again. The alarm ends by timeout.
That happened today, in the open. The eight sessions lost to the
2026-09-21→09-30 Actions-billing outage were never entered in
captures.ACKNOWLEDGED_GAPS (zero entries for any of them) and never given a
per-stream notch in CAPTURES.md. At 19:08Z the day's own skew capture
advanced the window by one session, and 2026-09-21 dropped out of
options_skew, options_chains, options_iv_term and shortability. No
layer anywhere said so, because by construction none could: the only reader of
a gap is the detector whose window it just left.
It had happened once before and was caught only by hand. CAPTURES.md's
pit_snapshots section records that 2026-06-16 "predates the interior-gap
detector and had been recorded nowhere until this sweep" (2026-08-17). The
same outcome, reached the other way — and a manual sweep is not a detector.
As of today the remaining exposure is 35 stream-days across seven streams, all
within five sessions of the same fate: 2026-09-22 goes after the next
capture, and on the current cadence the last of them (2026-09-30) is
invisible by 2026-10-28.
What it turned out to be
A detector defect, not a system failure — the shop's most common finding class, and the third time a silence has been traced to an instrument's own bounds rather than to the thing it watches.
The architecture was already right and is worth restating because it is easy
to invert: CAPTURES.md is the ledger; ACKNOWLEDGED_GAPS is only a
recent-window alarm suppressor. Acknowledging without recording is a
silenced alarm. What was missing is the converse — nothing made the recording
deadline visible, so a hole could pass out of reach while every layer stayed
green and truthful.
What was done
captures.expiring_gaps() counts every unacknowledged in-window gap down to
the session it becomes invisible, and thales captures prints one line per
stream: how many days, the soonest, and how many further captures remain. The
deadline now announces itself.
Two properties are load-bearing:
- Forward-only. It counts down gaps still inside the window and never
resurrects ones already outside it. Full history would bury the live signal:
momentum's
order_logalone carries 39 interior holes from its monthly-rebalance era, every one of them legitimate. A detector that fires on ordinary cadence is worse than no detector. - Same window as
capture_gaps. The countdown and the alarm cannot disagree about which days are in scope.
Five tests, three of them negative controls at exactly the boundary that matters (deep-inside gap not counted down; already-expired gap not resurrected; acknowledged gap not counted down while its unexplained neighbour still is). Full suite 1799 passed / 1 skipped.
CAPTURES.md now states the deadline in its header, where the contract lives.
What remains
The countdown prevents the next loss; it does not recover 2026-09-21, and it
deliberately will not resurrect it. Writing the September outage's per-stream
notches into CAPTURES.md — and the matching ACKNOWLEDGED_GAPS citations —
is queue row GAP-1, and its framing needs one correction: the record is
writable forever; what expires is the detector's visibility, which this
change makes announce itself. The urgency is real but the deadline was never
on the record, only on the alarm.