Thales
← research journal

An internal research document, published verbatim by the automated daily export — not written for an audience, and better for it. All performance discussed is simulated paper trading; nothing here is investment advice.

DISMISSED — GAP-1 — six permanent capture-days are lost inside the clean-clock window and gauge G4 claims they are machine-checked

status: dismissed by TRIAGE 2026-09-14 · OVERFLOW — ranked 17 of 21 at the pre-registered 12-item cap · raised panel run 1 (2026-08-06), migrated 2026-09-04 · body verbatim below

Resolution — mechanical overflow; most of this row is BUILT, and what survives is two residuals, one of them a countersigned call

research/queue/open/ held 21 files after this run's sweep against the pre-registered 12-item cap (ops/QUEUE_TRIAGE.md:86-91), so the nine lowest-ranked are dismissed with reopen conditions. This row ranks here because it is largely already built — re-running it whole would be waste, and the narrowed remainder is ~0.2 pd, not the 0.75 pd the status line still claims.

BUILT and confirmed at HEAD 340bc5f: the ACKNOWLEDGED_GAPS ledger (captures.py:295-343), capture_gaps() (:364), the GAPPED status wired into capture_status (:505-506), and acknowledged_gaps_seen() (:420).

Two residuals, both re-verified live this run:

  1. The detector is a trailing window, against this row's own pre-registration. def capture_gaps(..., lookback_td: int = 20) (:364-365), window built at :406-408 ([-lookback_td:]). The body pre-registered "The scan must cover full history, not a trailing window, or it re-blinds by drift." No full-history mode exists and no ruling is recorded in CAPTURES.md.
  2. 2026-06-17 is a permanent notch recorded in no ledger at all. An ordinary Wednesday; absent from both data/processed/order_log.jsonl and data/processed/portfolio_snapshots.jsonl (both hold 06-15, 06-16, —, 06-18); in neither ACKNOWLEDGED_GAPS (captures.py:296-310 lists only 07-16, 07-17, 08-06 for those two streams) nor CAPTURES.md. It is ~60 trading days old, so the 20-td window structurally cannot surface it. AUDIT.md:234's Jun-22 closure is written entirely about the equity backfill and never mentions the two irreplaceable streams.

The status line's horizon: detector kill resolves ~2026-09-04 is STALE and nothing lapsed — the 2026-08-31 triage already ruled that, and the abandon-the-detector kill criterion is conditional on a shadow run that was never armed because this row was never approved. Recorded again here so the date is not read as an expiry by a future reader.

The G4-wording half (make the gauge true vs amend the text) sits in NORTHSTAR's hash-frozen §1–§5 and is a countersigned call, not a routine's and not a build.

Reopen condition. Reopen on the 06-17 notch alone at any time — one ledger line in ACKNOWLEDGED_GAPS closes it, and it is the cheapest open item in the tree. Reopen immediately if capture_gaps is ever cited for a full-history claim (its window is 20 trading days), or if a seventh permanent capture-day is found. The G4 wording question reopens with charter §7 cycle 3, whose starting list this is.


Body as filed (verbatim, untouched)

GAP-1 — six permanent capture-days are already lost, and charter gauge G4 claims they are machine-checked when no instrument can see them

status: open · raised panel run 1 (2026-08-06) · migrated 2026-08-24 (body verbatim below) · class: moat / instrument-calibration · judgement: YES · effort 0.75 pd · horizon: detector kill resolves ~2026-09-04


4. GAP-1 — six permanent capture-days are already lost, and charter gauge G4 claims they are machine-checked when no instrument can see them. · judgement: YES · effort 0.75 pd · horizon: detector kill resolves in 20 td (~2026-09-04)

Mechanism. Verified interior holes inside the pinned clean-clock window:

streamclassmissing trading days
data/processed/portfolio_snapshots.jsonlTIME-GATED2026-06-17, 07-16, 07-17
data/processed/order_log.jsonlTIME-GATED2026-06-17, 07-16, 07-17
data/pit_snapshots/TIME-GATED2026-06-16, 07-15, 07-16 (T-1 lag)
data/equity_history.jsonlBACKFILLABLE0 — healed by backfill-equity

Causes: the 2026-06-17 Tiingo 429 and the 07-16/17 clock-rotted test_fleet_gather_and_renders fail-close. Both incidents are marked CLOSED in AUDIT.md — but both closures were written against the one backfillable stream ("gaps self-heal on today's backfill-equity", "fully green"). The three irreplaceable streams were never mentioned. data/options_skew.jsonl has all four dates, so these were ordinary trading days, not calendar effects.

Why nothing caught it. thales captures reports only last + staleness_td of the newest file — I ran it: every stream reads OK, including all three carrying holes. capture_qa() iterates over files that exist, so an interior hole is invisible by construction. Meanwhile ops/DAILY_AUDIT.md step 7 instructs "No gap days", and charter G4 asserts capture-day gaps are "measured by thales captures / capture-qa, machine-checked". That claim is false today — a pinned gauge reading pass while blind, on the asset the charter calls irreplaceable (§1 asset #2: "a missed day is a permanent notch").

Precondition, before any code: enumerate every existing interior hole across all registered streams' full history and record them in CAPTURES.md as permanent notches. G4's metric is "capture-day gaps (target zero)" and the current count is literally unknown.

Kill criterion. Negative control first: delete one interior day from a temp copy of each time-gated stream and assert the checker reds naming the date, and greens on the untouched copy. The scan must cover full history, not a trailing window, or it re-blinds by drift. Then: if the census surfaces zero interior gaps beyond the six above, AND a 20-trading-day live shadow run raises zero true alerts while raising ≥1 lag/calendar false positive, abandon the standing detector — record the six notches and stop. Do not tune the detector to survive.

Owner judgement required: G4's wording is in the hash-frozen §1–§5 span. The honest fix may be to make the gauge true (build the check) rather than amend the text — but if amendment is wanted, that is a countersigned append, not a panel action.


Triage note — 2026-08-31 (annotation only; the body above is untouched)

PARTIALLY OVERTAKEN — most of this row was built; two residuals are live and one of them is a permanent notch that exists in no ledger at all. Kept open rather than dismissed, because the residuals are exactly what the row's own kill criterion forbade.

What was built since 2026-08-06 (verified at HEAD 528793d): an interior-gap detector — captures.capture_gaps() with an ACKNOWLEDGED_GAPS ledger, a GAPPED status wired into capture_status, and acknowledged_gaps_seen(). pit_snapshots was swept and its notches recorded in CAPTURES.md. Charter gauge G4's "machine-checked" claim is much closer to true than when this row was raised.

Residual 1 — the detector is a 20-trading-day TRAILING WINDOW, which this row pre-registered against. The body reads: "The scan must cover full history, not a trailing window, or it re-blinds by drift." The shipped capture_gaps takes lookback_td: int = 20. The code carries its own comment arguing for the window; that argument may well be right, but it is a decision taken against a pre-registered constraint and should be recorded as such (amended, or the constraint honoured) rather than left as a silent divergence.

Residual 2 — 2026-06-17 is a permanent notch that is in NO ledger. Independently verified by triage this run, not taken from the row: 2026-06-17 (a Wednesday, an ordinary trading day) is absent from BOTH data/processed/order_log.jsonl run-summaries (06-15, 06-16, —, 06-18) and data/processed/portfolio_snapshots.jsonl (same three dates). It appears in neither ACKNOWLEDGED_GAPS nor CAPTURES.md. It is 50+ trading days old, so the 20-td window can never surface it. This is the re-blinding the row predicted, already materialised, on a date the row itself named.

The "~2026-09-04" horizon in the status line is stale and should not be read as an expiry. It assumed a build starting 2026-08-06; the detector landed ~08-07 and was wired ~08-20, so the 20-td shadow window matures nearer 2026-09-17. Separately, the row's abandon-the-detector kill criterion is conditional on a shadow run that was never armed (this row was never approved), so nothing lapses on 09-04 in either reading.

Recommended re-scope (triage does not edit the body): narrow this row to the two residuals — the full-history census for order_log and portfolio_snapshots (starting with 2026-06-17), and an explicit ruling on trailing-window vs full-history — rather than re-running the row whole. Effort falls well below the 0.75 pd in the status line.


ANNOTATION 2026-09-25 (panel run 28) — the reopen condition is now massively exceeded, and the outage has put a DATED deadline under it

Plain-language summary. This item was killed but left a tripwire: reopen if a seventh permanently-lost capture-day is ever found. The Actions billing outage has just destroyed roughly twenty. Worse, the way this shop's gap detector is built means those days will be visible for about a month after captures resume and then go silent forever — so there is now a date by which they must be written into the ledger, or this outage quietly manufactures the exact defect this item exists to complain about.

The condition, and by how much it is exceeded

"Reopen immediately … if a seventh permanent capture-day is found."

Four refused trading sessions (Mon 2026-09-21 through Thu 09-24; 09-19 was a Saturday) across five time-gated streams = 20 irreplaceable stream-days, with Friday 09-25 in flight as the fifth session. Re-measured from the working tree this run — every time-gated stream shows a delta of exactly zero since the 09-21 panel:

streamdates heldlast capturebackfillable?
options_skew71 (58,146 rows)2026-09-18no
options_chains692026-09-18no
options_iv_term342026-09-18no
shortability38 files (37 td)2026-09-18no
pit_snapshots672026-09-17no
short_volume482026-09-17yes (FINRA CDN)

thales captures --json independently reports staleness_td: 4 / STALE on the option and borrow streams — the ledger's own count agrees with the manual one.

The deadline, and why it exists — verified in code this run

capture_gaps() (src/thales/data/captures.py:364-408) builds its window as the last lookback_td (default 20) trading days up to min(max(have), today) — never past the stream's own latest capture. The docstring is explicit that trailing staleness is STALE's job, not this detector's. Consequences, in order:

  1. While the outage persists, 09-21…09-24 are trailing and are structurally invisible to the gap detector. Nothing is being missed today.
  2. The moment captures resume they become interior and the detector will flag them — but only while they remain inside a 20-trading-day window that advances with every new capture.
  3. Once that window rolls past, they become unrecorded notches exactly like the 2026-06-17 one this item was filed about.

So: the lost days must be entered in ACKNOWLEDGED_GAPS (captures.py:295) and CAPTURES.md, citing research/2026-09-21_actions_refused_every_job_over_billing.md, within ~20 trading days of captures resuming — ≈ 2026-10-23 if trading restarts Monday 2026-09-28, and one trading day later for each further refused session. That estimate is the panel's arithmetic off the window mechanism above, not a pinned date; the mechanism is the verified part.

This is more than appending lines. ACKNOWLEDGED_GAPS currently holds only four stream keys — order_log, portfolio_snapshots, pit_snapshots, shortability (checked by importing the dict this run). There is no options_skew, options_chains or options_iv_term key at all, so three keys must be created, not extended.

Status — escalated, not reopened, and the reason is structural

This panel cannot make the move. ops/RESEARCH_PANEL.md §4 enumerates the sanctioned transitions — open→dismissed (triage), open→approved (owner), approved→built/dismissed (implementer). dismissed→open is not among them, and writing a second gap-1 file into open/ would put one slug in two directories. So this is recorded here and escalated in the run report instead.

Unlike dismissed/rdr-1-… (annotated today, row declined because its fix is owner prose no implementer may write), GAP-1 is genuinely implementer- buildable — a dict extension plus ledger lines, ~0.2 pd by this file's own narrowed estimate — and it now carries a real expiry. That combination is what approved/ exists for. The owner ask is one move, and it is the cheapest buildable item in the tree.


PANEL RUN 32 ANNOTATION 2026-10-01 — the blindness date is 2026-10-19, not ~10-23, and the stream count is seven, not three

Two corrections to the 2026-09-25 (panel run 28) annotation above. Neither reopens this file — dismissed → open is still not a sanctioned transition — but both make the escalation it already carries more urgent than it reads.

1. The detector goes blind on 2026-10-19. Three trading days of margin were imaginary.

capture_gaps (src/thales/data/captures.py:364-408) builds its window as get_trading_days(...)[-lookback_td:] ending at the newest capture, so the 20-session window runs backward from the latest data, not forward from the resumption. Simulated directly:

2026-10-16   window 2026-09-21 .. 2026-10-16   09-21 in window: True
2026-10-19   window 2026-09-22 .. 2026-10-19   09-21 in window: False
2026-10-23   window 2026-09-28 .. 2026-10-23   09-21 in window: False

Run 28 counted 20 trading days forward from the resumption (09-28 → 10-23). The correct date is 2026-10-19, and — unlike the earlier figure — it does not depend on when captures resume, given daily captures thereafter. After 2026-10-19 the instrument is structurally blind to the outage's first missing day; after 2026-10-29 it is blind to the last. If the outage is to be in any ledger, it must be written before 2026-10-19.

2. Seven streams were hit, not three.

From capture_status() this run, the expect_every_td streams stuck at 2026-09-18 (staleness_td: 9, 8 completed dark sessions 09-21…09-30): options_skew, options_chains, options_iv_term, shortability, order_log, portfolio_snapshots — plus pit_snapshots, stuck at 2026-09-17. Seven. The run-28 annotation names three. This does not change the reopen condition (already "massively exceeded" at a bar of a seventh capture-day), but it more than doubles the ledger work the escalation is asking for, and the three missing ACKNOWLEDGED_GAPS keys noted above are still only part of it.

Context

GitHub Actions resumed 2026-10-01 01:18Z after an 8-session repo-wide billing refusal (every job through 09-30 reports steps: 0). The outage is over; the ledger debt it created is not, and it now has a dated detector expiry.