DISMISSED — CQA-2 — capture-qa reads only the latest file, so a missing today-file fails nothing and a failing stream mails under another stream's name
status: dismissed by TRIAGE 2026-09-21 · OVERFLOW — ranked 13 of 13 at the pre-registered 12-item cap · raised panel run 16 (2026-09-01) · body verbatim below, nothing edited
Resolution — mechanical overflow, not a finding
research/queue/open/ held 13 files after this run's sweep against the
pre-registered 12-item cap (ops/QUEUE_TRIAGE.md:86-91), so the
lowest-ranked one is dismissed with reopen conditions. This is it. The defect
is real and still present — this is the ranking rule applying, not a judgement
that the row was wrong.
Re-verified at HEAD a325c3c, all of it still true: capture_qa still
reads files[-1] per stream (src/thales/data/captures.py:619, 679, 798, 829
— the body's :810-834 has drifted by line number only); "today's file is
missing" is still not a failing condition anywhere; and _alert.yml:85 still
builds Subject: 🔴 {label} {result} ({day}) from a workflow-static label while
skew-snapshot.yml:115 runs thales capture-qa across every stream, so a
pit_snapshots failure still mails as "skew-snapshot capture".
Why it ranks last of thirteen. Three things, none of which were true when it was filed on 2026-09-01:
- No clock. Every other row in the queue carries a date or a live bleed. This one predicted "repeat mislabeled 🔴 mails until a full pit snapshot lands" — and there has been no mislabeled-🔴 recurrence in the twenty days since it was raised.
- Both of its legs now have absorbing fold partners. The missing-today
half is the detection side of PIT-1's writer-side hole (same day, same
stream, same silence); the module-gate half is the same
captures.pygate CQA-3 must open to readcaptured_at. Whoever builds either row is standing in this file. - What is left is uniquely its own is an alert SUBJECT LINE — attribution, not detection. A 🔴 that fires under the wrong stream's name is a worse alarm than a correct one and a far better alarm than none, and "none" is what the other twelve rows are about.
Fold instruction, so nothing is lost: when CQA-3's owner ruling lands and
somebody opens captures.py, carry this row's subject-attribution leg
(name the failing stream(s) in the alert subject) into that build — it is
minutes once the file is open. The missing-today leg belongs to PIT-1.
Reopens if
- (a) a capture stream loses a day and no instrument reds — the exact failure this row exists to prevent; reopen immediately and rank it P0, because the recurrence falsifies point 1 above; or
- (b) a second mislabeled 🔴 mail arrives (a failing stream mailing under another stream's workflow label), re-arming the premise; or
- (c) CQA-3 is dismissed or is built without the subject-attribution leg folded in — the fold instruction above is then unhonoured and this row is the only place the work is recorded; or
- (d) PIT-1 leaves the queue without the missing-today detection leg being built.
Nothing here decays. Reopening costs one git mv.
Original body, verbatim
CQA-2 — capture-qa reads only the latest file, so a missing today-file fails nothing and a failing stream mails under another stream's name
status: open · raised panel run 16 (2026-09-01), executing the 2026-08-31 daily-audit memo's detector hand-off (items a+b, folded by adversarial review) · class: instrument-calibration / loudness (capture QA layer) · judgement: YES · effort ~0.25–0.4 pd · horizon: live now — the memo predicts repeat mislabeled 🔴 mails until a full pit snapshot lands, and the trailing-hole blindness holds for every expect-every-day stream
Plain-language summary for an owner reading one paragraph. The nightly capture quality check only ever looks at the newest file a stream has. Two consequences, both observed last week: when today's file is missing entirely, nothing fails — the check re-reads yesterday's file, so the one condition that means "we are losing a day right now" is invisible to the one instrument that can red; and because the check for ALL streams runs inside the skew-snapshot job, the failure mails arrive as "🔴 skew-snapshot capture" even when the failing stream is pit_snapshots, owned by a different workflow — which is exactly how the 08-28/08-29 alerts mislabeled themselves. The fix: make "today's file is missing" a distinct failing condition naming the stream and date, and put the failing stream names in the alert subject.
Mechanism — verified at HEAD 29c6f23
capture_qareadsfiles[-1]per stream only (src/thales/data/captures.py:810-834). "Today's file missing" is not a failing condition anywhere: staleness (capture_status) is report-only by design (exit 0), and the interior-gap detectorcapture_gapswindows "up to the stream's OWN latest capture (never past it — a stream that is merely stale is STALE, which staleness already reports)" (its own comment,captures.py:357-363). That deliberate hand-off cedes the trailing hole to a channel that fails nothing — the hand-off with no failing endpoint is this row's defect, cited here so the row cannot be read as GAP-1 relitigation (GAP-1's narrowed scope is the full-history census + the window ruling).- The alert subject is workflow-static:
_alert.ymlbuildsSubject: 🔴 {label} {result}from a workflow-level env (.github/workflows/_alert.yml:85), andskew-snapshot.yml:103runsthales capture-qaacross all registered streams — so a pit_snapshots failure (owned by paper-trading.yml) is structurally guaranteed to mail as a skew failure. Per-stream ❌ lines exist only in the Actions log.
Struck by adversarial review, recorded so it stays struck: the memo's complaint that the same degraded file "re-fires nightly with no new information" is NOT part of this row. A standing red until fixed is correct fail-closed behavior, and the tempting remedy — an acknowledged-degradation ledger — would be a second ACK surface and a mechanism for making reds quiet, the opposite of this shop's doctrine. The observed harm was misattribution, not repetition.
Fix shape (propose-only)
- Missing-today check: for streams registered as expect-every-trading-day,
a trading day with no file (after the stream's normal publication lag —
pit is legitimately T-1) is a distinct
capture_qafailure naming the stream and the missing date. - Subject attribution:
capture-qaemits the failing stream names (e.g. to a step output/file) and the alert includes them in the subject — "🔴 capture-qa: pit_snapshots" instead of the owning workflow's static label.
Test design + kill criterion (pre-registered, negative-controlled)
- Fixture with today's file absent on a trading day → a distinct "missing" failure naming stream + date; revert → red.
- Lag negative control (required): a stream at T-1 within its normal registered publication lag must NOT red — without this the check manufactures a nightly false positive by construction, the alert-fatigue class this shop keeps paying for.
- Subject fixture: a forced pit_snapshots QA failure inside the skew job produces an alert whose subject names pit_snapshots; revert the wiring → only its test reds.
- Falsifier: if the missing-today check produces ≥1 false red on a legitimate holiday/lag day within 20 shadow trading days, the lag model is wrong — record and re-derive per-stream lags from the stream's own history; do not whitelist dates ad hoc.
Data plan
None — owned state and static code; rides the existing capture-qa cron.
Cap note
Ranked second of this run's two rows (PIT-1 first: it stops permanent data loss; this row stops misattribution and blindness, nothing is destroyed). If the 12-cap must hold hard after SKW-1's open→built move lands, this is the row to hold at the gate.
ANNOTATION 2026-10-16 (panel run 39) — leg (b) CANNOT FIRE as written: the event it describes occurred THREE TIMES on 10-12/13/14 and mailed nothing, because the 2026-10-07 delegation replaced "mails" with "records"
Plain-language summary. This file's second resurrection condition waits for a mail to arrive. Since 2026-10-07 the system does not mail that class of alert at all — it records it. The thing the condition is watching for happened three days running this week, and the condition could not see it. A tripwire that cannot fire is not a tripwire.
The clause, verbatim (:48-49):
- (b) a second mislabeled 🔴 mail arrives (a failing stream mailing under another stream's workflow label), re-arming the premise; or
The event, three times, measured. The Skew Snapshot workflow has
conclusion failure on 2026-10-12 (run 111, id 38331033605),
2026-10-13 (run 112, id 38482901781) and 2026-10-14 (run 113, id
38645700275), then success on 10-15. The 10-13 failed-job log, verbatim:
✅ options_chains: 2026-10-13.parquet: 56404 rows, 77% two-sided
✅ options_iv_term: 2026-10-13.parquet: 8214 rows, median 7 expiries/name
✅ options_skew: 2026-10-13: 882 records
✅ shortability: 2026-10-13.parquet: 14387 names, 5273 ETB
❌ pit_snapshots: rows 1 < 50% of trailing median 887
1 capture stream(s) FAILED integrity QA
##[error]Process completed with exit code 1.
That is exactly the mislabel this clause describes: a failing stream
(pit_snapshots) redding under another stream's workflow label (Skew
Snapshot). Zero mails arrived — under config/fleet.yaml
notifications.email: weekly_digest_only, _alert.yml records and exits 0 on
a non-Friday, with the steward as designated reader. The steward was itself
dark 10-12 → 10-15.
Two consequences for this file, both against it:
- Leg (b) is unfirable as written — not merely unfired. The delivery mechanism it names no longer exists for this alert class on six days in seven.
- The premise this row was ranked last on is falsified. Point 1 of the dismissal justified the ranking on "no mislabeled-🔴 recurrence in the twenty days since it was raised." There have now been three recurrences in three days.
Proposed channel-neutral re-cut, for the owner or triage to adopt (the panel proposes; it does not re-cut its own tripwires):
(b) a second mislabeled 🔴 is recorded — a failing stream reporting under another stream's workflow label — in a run annotation, job summary, outbox branch or email, delivery mechanism irrelevant.
Status and whose move. dismissed → open is the steward's git mv,
never a panel's (ops/QUEUE_TRIAGE.md:100-102). This row is already named in
triage's own mandate: ops/QUEUE_TRIAGE.md:94-102 requires a 14-day sweep of
dismissed/ for "reopen conditions … whose triggering event has already
occurred", and cites the 2026-10-01 research audit (M4) measuring five
fired-or-lapsed conditions "(LCK-1, BCN-1, RDR-1's leg (b), GAP-1, CQA-2)"
that no routine evaluated — this file among them by name. That sweep's
first real execution is Monday 2026-10-19 (its 2026-10-12 slot was lost to
the outage). This annotation exists so that run has the measurement in hand
rather than re-deriving it.
Leg (a) checked and NOT fired, for completeness: "a capture stream loses a
day and no instrument reds" — an instrument did red, three times. Leg
(a) is intact and correctly silent. Leg (d) is discharged: PIT-1 left the
queue with the missing-session check built (captures.py:613-640).
The wider class is NOT claimed here. A grep found ~12 dismissed files with
channel language in their reopen blocks; only this one was verified live by
hand. Per rdr-1:128 — "at the third firing the pattern is the finding, not
the instance" — one verified instance is an instance. The class belongs to
Monday's sweep, which reads every file in this directory.