RAD-1 — "a file exists" is the unit for every capture count, and one of the 45 sessions feeding the options_iv_term retire-or-keep criterion is a 33-row stub; the evaluator that will read them does not exist yet, so the input-set question gets decided after the data is in
status: open · raised panel run 39 (2026-10-16, queue-and-clocks candidate C1, narrowed and re-evidenced at the chair's adversarial pass) · class: registration hygiene (G5 — a pinned criterion whose input set is still unruled) with a G4 measurement leg · judgement: YES · effort ~0.1 pd (the ruling) + ~0.3 pd (optional predicate) · horizon: the ruling must land before ~2026-11-05, the earlier of the two accrual dates it governs
Plain-language summary
Several of this shop's pinned criteria say "wait 60 trading days, then decide".
On 2026-10-15 the owner ruled what "60 trading days" counts: captured
sessions, not elapsed ones — defined as "trading days with a file in
data/options_iv_term". That ruling was pinned before the criterion was
computed, which is exactly right.
It leaves one question unanswered: what makes a file a session? Today the answer is "it exists". A file can exist and be worthless. One of the 45 files now counting toward that 60 holds 33 rows against a median of 7,928 — four tenths of one percent of a normal day. The criterion those 45 files feed is a per-name median of captured expiries, and a 33-row day cannot supply a per-name median for more than a handful of names.
The evaluator that will compute this does not exist yet. It has to be written in the next ~three weeks. Whoever writes it will decide — in code, silently, with the data already on disk — whether that stub counts. That is the post-hoc decision the 10-15 ruling existed to prevent, one level down.
Mechanism — why it would pay, and who is on the other side
Nobody is on the other side; this is not an alpha claim. It pays in TRUST
(NORTHSTAR.md §1 asset 1, gauge G5): a criterion whose inputs are chosen
after its data exists cannot be quoted as pre-registered, and this stream's
criterion is a retire-or-keep decision on a moat asset. The bias direction
is the part that matters: a near-empty day dragging a per-name median
downward pushes the verdict toward VACUOUS, i.e. toward retiring a
capture that may not be vacuous at all. A false VACUOUS is permanent — the
write is removed from the run and the stream stops accruing.
Evidence — all re-measured this run
The criterion, verbatim (CAPTURES.md:299-307):
at 60 trading days of accrual (~late 2026-10), compute each name's median-per-day count of distinct captured expiries; if the cross-name median is < 5, the capture is recorded VACUOUS … and the stream is RETIRED
The unit ruling, verbatim (CAPTURES.md:307-318):
RULED 2026-10-15 (owner): "60 trading days" means 60 CAPTURED sessions. These are trading days with a file in
data/options_iv_term… 45 were captured through 10-15 … It was pinned before the criterion was computed. Capture-qa's daily line prints only the newest day's median (7–8 expiries/name this week), not each name's median across its captured days. The ruling sets when the check runs, not what passes it.
The stub. 45 files in data/options_iv_term; row counts, measured:
| file | rows |
|---|---|
| 2026-08-07 | 33 |
| 2026-08-05 | 7,592 |
| 2026-08-03 | 7,595 |
| 2026-08-04 | 7,609 |
| median of all 45 | 7,928 |
The stub is not a borderline case: the next-thinnest file is 230× larger.
Why it is there, and why it is the shop's own precedent that forces the
question. The 2026-09-06 re-session ruling's ledger (CAPTURES.md:605-613)
records, in the same list:
options_chains2026-08-07: 82 rows stayed (captured in-session)options_iv_term2026-08-07: 33 rows stayed (captured in-session)options_skew2026-08-07: 5 rows stayed (captured in-session)- totals: relabelled 239179, quarantined 85028, dropped 0
That ruling quarantined 85,028 rows of thin holiday re-serves as not
sessions — and left these three stubs in place, because its test was
capture instant, not row adequacy. One ledger, two unit rules, and only the
first was ever ruled on. The remedy is already built and already used:
data/quarantine/, excluded by the loaders by default.
No evaluator exists. grep -rniE "median.*expir|expir.*median|vacuous" src/thales/ --include="*.py" returns only captures.py:750 — capture-qa's
newest-day breakage check, which CAPTURES.md:315-317 explicitly
distinguishes from the kill criterion — and backtest/dtc_vacuity.py, which
is the A4 DTC battery, a different stream. So the 60-session evaluator is
unwritten with ~20 days to go, against §3 G5's own rule that "no forward
clock may reach maturity without its evaluator already pinned."
The same unit gap, second instance, already recorded in prose and
unimplemented. CAPTURES.md:425-430 rules on the two truncated PiT sessions:
"2026-10-12 = 49 rows and 2026-10-13 = 1 row, against an 886-row norm …
both mislabel themselves as sessions, and both are permanent … Treat them as
missing." No instrument does. thales captures --json reports
pit_snapshots gaps=8; the true unusable-session count is 10.
ACKNOWLEDGED_GAPS (captures.py:295-317) structurally cannot hold them —
capture_gaps (:412) tests d not in have, and both dates are in
have. PIT-1 (built 2026-10-15) closes the forward hole at the writer and
cannot reach backwards. So a human instruction exists with no machine reader,
and gauge G4 under-reports permanent notches by two.
Scope — measured before anyone asks, and it is in this row's disfavour
A rows >= 0.5 × median(trailing 10 same-stream files) predicate flags:
options_iv_term: 1 of 45 (2026-08-07)shortability: 0 of 48 — thinnest 14,137 vs a ~14,400 norm = 98%
So shortability's ~2026-11-02 date is unaffected, and
options_iv_term's ~2026-11-05 moves by at most one day (to 11-06) if the
stub is excluded. On the cross-name median itself the stub touches roughly a
dozen of ~880 names, by one datum each. This is a one-day, one-clock unit
question plus a two-day census correction — not a build. It is proposed
because it is cheap and must be pinned before 11-05, not because it is large.
Test design — how it gets falsified on this apparatus
- Define
rows_adequate(f) = rows(f) >= 0.5 × median(rows of the trailing 10 same-stream files)— reusing capture-qa's existing floor convention (captures.py:595-606), introducing no second tunable number. This is the same reuse discipline PIT-1 adopted and the same floor that correctly red the skew workflow on 10-12/13/14. - Run it over every committed file in
pit_snapshots,options_iv_term,shortability,options_skew,options_chains. - Compare the flagged set against the files already named in
CAPTURES.md's own disposition ledgers.
Kill criterion — pre-registered
If the predicate flags only the files already named in CAPTURES.md's
disposition ledgers — options_iv_term 2026-08-07, pit_snapshots 2026-10-12
and 2026-10-13 — then the defect is confined to days the record already knows
about, the remedy is one owner ruling plus one quarantine move, and this row
DIES as bookkeeping with no code change. It converts to a P2 detector row
only if it flags a fourth file nobody has recorded.
Written down because the narrow outcome is the one I expect: half the predicate is already run above, and it found exactly the three known files.
Second, independent kill: if the owner rules that file presence alone is the unit — a legitimate call, and the conservative one for keeping a stream alive — the row closes immediately with that ruling recorded, and the PiT census correction becomes a separate ~0.1 pd G4 bookkeeping item or nothing.
Effort · horizon · whose job
- ~0.1 pd — the ruling: does a present-but-row-inadequate file count as a
captured session for an accrual count, and do the three named files move to
data/quarantine/? - ~0.3 pd — optional: wire a reusable
rows_adequateintocapture_gaps/capture_statussothales capturesstops under-counting G4 by two. - Horizon: before ~2026-11-05. Deciding it after that date, with the verdict computable, is the gate-shopping the 10-15 ruling was pinned to prevent. The clock is the same shape and the same reason.
- Whose job: the unit choice is the owner's — it moves a pinned criterion's input set, and the ruling is the whole deliverable. The quarantine move and the predicate are implementer work once ruled. The panel proposes only.
Why no existing slug covers this
grep -rliE "row.?adequa|present.?but.?worthless|presence is not"overresearch/,CAPTURES.md,TECH_DEBT.md,RESEARCH.mdandkilllist.json→ zero hits.grep -rn "33 rows\|33-row"→ one hit,CAPTURES.md:611, the ledger line quoted above.- GAP-1 (dismissed) covers missing days and the 20-td trailing window's re-blinding; its instrument structurally cannot represent present-but-worthless, and its reopen clause already fired and was escalated in runs 28 and 32 with a third annotation killed by run 38. Not duplicated here, and deliberately not annotated a fourth time.
- CLK-1 (dismissed, fired 2026-10-06) covers the absence of a §6 row and
an evaluator for these two clocks, generically. This row is the distinct
question of which inputs the evaluator must count when it is written.
CLK-1's remedy is owner-side in agent-denied
NORTHSTAR.md; this one is a ruling plus an optional predicate. - PIT-1 (built) is writer-side and forward-only, by its own text.
- CQA-2 (dismissed) is latest-file-only QA plus alert-subject attribution.
- RSN-1 (dismissed) covers quarantine counters, not the admission rule.
- BTB-1 (open) covers the shortability degeneracy claim, not the unit.
- CQA-3 (open) covers the capture instant — the 2026-09-06 ruling's test. This row is the orthogonal axis that ruling left open, and the two together are the reason the stub survived.
Reopen / resurrection note
If this row is dismissed on the "presence is the unit" ruling, it reopens if any accrual criterion is ever computed on a panel containing a file flagged by the predicate above, or if a stream is retired as VACUOUS on a panel including one.
Annotation — panel run 40, 2026-10-19: the stub moves the kill statistic by exactly zero, and a second, dated input defect sits on the axis this row says CQA-3 owns
Two measurements, both taken from the committed store at HEAD 6c8d2d0.
Neither changes this row's judgement; the first narrows it and makes the
ruling cheaper, the second widens the ruling's scope by one clause.
(a) The 33-row stub's effect on the kill criterion is zero, measured
The criterion this row protects is "at 60 captured sessions, cross-name median of per-day distinct expiries < 5 → VACUOUS, stream RETIRED". Computed today over 898 names:
| panel | cross-name median expiries/name | names below 5 |
|---|---|---|
all 46 options_iv_term files | 7.0 | 221 of 898 (24.6%) |
| the 45 excluding the 33-row stub | 7.0 | 221 of 898 |
The stub holds 33 rows across 7 underlyings, so it contributes one datum to 7 of 898 names and moves no median. This row's estimate of "roughly a dozen names" was high; the measured figure is 7.
What this does and does not change. The harm mechanism stated above is real in form and measures zero on the kill statistic today. Its live effect is on the count — 46 files vs 45 row-adequate sessions, i.e. the check date moves by one session (~11-05 vs ~11-06). So the expected outcome of the ruling is the narrow one this row already anticipated, and the owner can make it knowing the decision does not currently turn on it. That is an argument for ruling cheaply and soon, not for leaving it unruled: the whole point is that the ruling must pre-date the computation, and a criterion whose input set is still open on the day it is computed is unpinned regardless of which way the number happens to fall.
(b) 2026-10-16 is disqualified for the skew stream by the owner's own signed grace, and silently counts for these two
This row delegates the capture instant to CQA-3. CQA-3's gate is the
skew stream's B4 signal-date rule. So for options_iv_term and
shortability — whose unit is file presence — no row owns the instant,
and there is now a dated instance on disk:
| date | captured_at | names | median exp/name | mean exp/name | min dte |
|---|---|---|---|---|---|
| 10-13 | 19:00Z (15:00 ET, box) | 895 | 7.0 | 9.18 | 1 |
| 10-14 | 19:00Z | 895 | 7.0 | 9.15 | 2 |
| 10-15 | 19:00Z | 895 | 8.0 | 9.54 | 1 |
| 10-16 | 21:59Z = 17:59 ET | 895 | 7.0 | 8.71 | 3 |
The 10-16 files were committed at 22:04Z by skew: snapshot 2026-10-16 —
GitHub's late backup leg, past the 60-minute post-close grace the owner
countersigned on 2026-10-15 (CAPTURES.md). The 2026-10-16 steward report
calls 10-16 "permanently lost as a skew signal date" and is right. Yet the
options_iv_term and shortability files for that day exist, so under the
10-15 unit the same instant the shop has already ruled disqualifying for one
stream is admitted for the other two.
Direction of the bias, which is the part that matters. 10-16 was the third
Friday — monthly expiration. A post-close snapshot loses the front expiries:
min dte 1→3, and mean expiries/name 8.71, the lowest of the four days.
The statistic is a median against a floor, and the floor retires the stream.
So an admitted post-close day pulls the number toward VACUOUS — toward
retiring the options stream, the one surviving experiment candidate in the
shop and the asset whose entire thesis is 12–18 months of un-backfillable
accrual. The bias runs the same direction as the stub's and, unlike the stub's,
has a mechanism large enough to measure.
Effort: still ~0. captured_at is already column 11 of the parquet. This
asks for one additional clause in the ruling this row already requests —
whether a session captured outside the signed grace counts toward the
options_iv_term and shortability accrual — not a build and not a new row.
Kill criterion for this leg specifically. It dies if the owner rules that
presence alone is the unit for these two streams with the OPEX measurement
above in front of him (a ruling made on the evidence is pinned; that is the
whole requirement), or if the evaluator, when written, filters captured_at
against the signed grace, which closes it in code.
Prior art re-checked for (b): cqa-3 (skew stream only), rsn-1
(quarantine counters), kbm-1 (dateless booking), b4-notch-skew-row-floor
(the W27/W40 notches and the ≥400-valid-row floor — a skew-side rule). None
states this. Raised by the queue-and-clocks lens as candidate C1 and the
frontier lens independently; kept as an annotation, not a row, because the
remedy is the same single owner ruling.
Triage annotation — 2026-10-19 (annotation only; the body above is untouched) — A LIVE INSTANCE OF THIS ROW'S EXACT QUESTION, AND THE ROW'S OWN KILL CRITERION DOES NOT FIRE AS WRITTEN
1. The naive unit over-counts the shortability clock by one TODAY, and the only reason nobody has noticed is that three humans each excluded the file by hand
data/shortability/ holds 50 files. One of them, 2026-07-26.parquet,
is dated a Sunday (verified: date(2026,7,26).weekday() == 6). The stream's
registration date is a non-trading day. The owner's 2026-10-15 ruling
(CAPTURES.md:375-377) defines the unit as "trading days with a file in
data/shortability" — which excludes it. Nothing in code does.
That single file reconciles three published numbers that otherwise disagree:
| source | count | = disk minus the Sunday? |
|---|---|---|
raw ls data/shortability (the "a file exists" unit) | 50 | — |
| panel run 40, 2026-10-19 | 49 | 50 − 1 ✓ |
the owner's pin, CAPTURES.md:381-382, "48 captured through 10-15" | 48 | 49 files ≤10-15, − 1 ✓ |
So both published readings are correct and mutually consistent because each
author dropped the Sunday by hand, while the mechanical unit the ruling's
words imply — and that any evaluator written from them would implement — gives
a number one higher and reaches 60 one session early. This row says the
admission test gets decided in code, silently, by whoever writes the evaluator
first; here is that decision already pending, on the clock that matures first
(~2026-11-02, 11 captured sessions away). options_iv_term has no weekend-dated
file: 46 files, all session-dated, 45 through 10-15, matching its pin exactly.
Re-measured ground truth for the row's own figures: the stub is
options_iv_term/2026-08-07 at 33 rows; the median of the 45 files through
10-15 is 7,928 exactly as claimed (46 files at HEAD → 7,925.5); next
thinnest 7,592. "45 sessions" is now 46 (10-16 landed after the row was
written).
2. The row's pre-registered kill criterion does not fire, and the direction is MORE work than claimed
The criterion dies "if the predicate flags only the files already named in
CAPTURES.md's disposition ledgers" and converts to a P2 detector "if it flags
a fourth file nobody has recorded". The body states that half of it was already
run and "found exactly the three known files" — but it was run over two of
the five streams the row declares. Run over all five, the declared
predicate (rows >= 0.5 x median(trailing 10 same-stream files)) flags 22
files:
options_iv_term1 of 46 — 2026-08-07 (33 vs 7,602) ✓ as claimedshortability0 of 50 — thinnest 14,137 vs median 14,276 = 99%. So the 11-02 clock is unaffected on row adequacy; its only defect is the Sunday abovepit_snapshots4 of 80 — 08-27 (123), 08-28 (58), 10-12 (49), 10-13 (1)options_chains9 of 81 — 08-07 (82) plus eight ~25-28k coverage notchesoptions_skew11 of 83 — 08-07 (5 rows) plus ten ~281-283-row days
Every one of the 22 is recorded somewhere in CAPTURES.md — pit 08-27/08-28
at :409-413 ("partial, non-representative samples"), the thin skew/chains
class as the calendar coverage notch at :108-121 ("reduced-coverage days, not
missing days"). So the criterion is satisfied on its clause and falsified on
its enumeration. It needs re-grounding before this row is picked up, or
a builder will read "three known files" and find twenty-two.
3. Nothing has been written, and thales captures was run this session to confirm it
Neither 60-session criterion has an evaluator. thales captures executed here
prints staleness and gap columns and no 60-session column at all;
captures.py:751-752 explicitly disclaims its daily median as "a breakage bar,
not the pre-registered <5-median kill criterion"; the only VACUOUS evaluator
in src/ is backtest/dtc_vacuity.py, a different stream (A4 DTC). There are
zero consumers of the borrow flags outside the capture/QA path. And
NORTHSTAR.md §6 (:192-202), whose own header reads "every entry must have
a pinned evaluator before maturity", contains neither clock — which is
dismissed/clk-1's reopen condition, fired on its own date 2026-10-06 and
still true 13 days later.
Live state: horizon ~2026-11-05 (shortability's sibling clock ~2026-11-02 arrives first) · blocked on one owner/steward ruling (~0.1 pd) · the ruling is now cheaper than when it was filed (panel run 40 measured the stub moving the cross-name median by exactly zero: 7.0 either way, 221 of 898 names below the <5 bar either way) · and the ruling should settle the non-trading-day case in the same sentence, because that one is already live.