# 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_chains` 2026-08-07: 82 rows **stayed** (captured in-session)
> - `options_iv_term` 2026-08-07: 33 rows **stayed** (captured in-session)
> - `options_skew` 2026-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

1. 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.
2. Run it over every committed file in `pit_snapshots`, `options_iv_term`,
   `shortability`, `options_skew`, `options_chains`.
3. 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_adequate` into
  `capture_gaps`/`capture_status` so `thales captures` stops 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"` over
  `research/`, `CAPTURES.md`, `TECH_DEBT.md`, `RESEARCH.md` and
  `killlist.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_term` **1 of 46** — 2026-08-07 (33 vs 7,602) ✓ as claimed
- `shortability` **0 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 above
- `pit_snapshots` **4 of 80** — 08-27 (123), 08-28 (58), 10-12 (49), 10-13 (1)
- `options_chains` **9 of 81** — 08-07 (82) plus eight ~25-28k coverage notches
- `options_skew` **11 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.**
