# 2026-10-05 — the in-session skew dispatch did not fire, and by design nothing could say so

**Daily audit, 2026-10-05.** Verdict INCIDENT. Trading was clean on every
sleeve. The finding is in the capture layer: the Mac's `com.thales.dispatch-skew`
agent did not fire, the option-skew capture was still absent 3h14m after its
intended instant, and **every channel that could have reported that is either
deleted, unconfigured, or structurally blind to it.**

This note exists for two reasons. The first is the finding. The second is that
the owner asked for a piece of reasoning to be preserved when PR #210 was closed
over the weekend, and the record that carried it was closed with the PR
(§4 below).

## 1. What happened

Measured from the GitHub Actions API and the committed tree at `493e547`:

| job | intended | actual | result |
|---|---|---|---|
| trading dispatch (momentum / meanrev / vrp) | 14:35Z (Mac, 07:35 PT) | **14:35:08 / 14:35:10 / 14:35:13Z** | all green, state committed 14:36:59–14:47:46Z |
| **skew dispatch** | **19:00Z (Mac, 12:00 PT)** | **never created** | — |
| skew `schedule:` backup leg | 19:00Z | **not delivered as of 22:13:42Z** | — |
| trading backup legs | 15:30 / 15:35 / 15:40Z | 22:06:30 / 22:09:23 / 22:09:36Z | green, correctly no-op |
| fleet digest | 15:50Z | 22:12:08Z (in progress) | — |

So the same Mac that dispatched trading punctually at 07:35 PT did not dispatch
skew at 12:00 PT. The cause is on the Mac and is not visible from a cloud
container: the agent unloaded, the machine asleep at noon, or `gh` auth. The
discriminator is one command — `launchctl list | grep thales` plus the tail of
`logs/dispatch.log`, which the script writes on every path including the
dispatch-nothing path.

**The last skew capture is 2026-10-02** (`skew: snapshot 2026-10-02`, committed
19:08:50Z after a 19:00:04Z dispatch). `data/options_skew.jsonl` holds
`2026-10-01` and `2026-10-02` as its newest dates; today is absent.

## 2. Why nothing reported it — four independent layers, all silent

1. **`thales-skew` no longer exists.** The owner deleted the four
   trading/capture healthchecks (`thales-momentum`, `-meanrev`, `-vrp`,
   `-skew`) on 2026-10-02 (#212), having decided thales runs without
   healthchecks.io for now (#211: "sandbox, add it when it matters"). That is a
   legitimate owner call and this note does not argue with it. It does mean the
   one out-of-band alarm that would have noticed a missing capture is gone.
2. **The Mac's dispatch beacon is not configured.** `HEALTHCHECK_URL_DISPATCH`
   is read from `config/.env` and absent means *silently disabled*
   (`scripts/dispatch_workflows.sh:44-53`), and `RUNBOOK.md`'s 14-row beacon
   inventory has no row for it — directly below that file's own warning that
   "an unconfigured beacon reads as coverage while providing none". Established
   by DSP-1 (panel run 25) and unchanged.
3. **The digest cannot see captures at all.** `digest_exceptions`
   (`src/thales/execution/fleet_digest.py:1157`) has exactly four legs — fleet
   red, a sleeve with no run record, a dark routine, a NEW failed order. There
   is no capture leg and no timeliness leg, and the gather never collects
   capture state in the first place. Today is a Monday, and the email policy is
   weekly-Friday-plus-exceptions, so even a digest that runs correctly mails
   nothing about this.
4. **Capture QA cannot see the capture instant.** `capture_qa` tests per-date
   row counts and never reads `captured_at` — CQA-3, open since panel run 25,
   on the evidence of 2026-09-14 and 2026-09-15, when every row was taken at
   18:24 ET and 18:03 ET and both days scored perfect.

## 3. The harm, stated honestly

Bounded, and not a trading risk. No sleeve depends on this stream; the live
path imports only prices and VIX.

The cost is to the forward-capture moat. If the backup cron lands tonight at
the hour it landed on 10-02 (22:53Z = 18:53 ET), today becomes the **third**
post-close skew day after 09-14 and 09-15 — stale, wide quotes wearing an
in-session label, and passing every gate, because of layer 4. If it does not
land, today is a permanent hole in a stream that has no heal path (contrast the
equity ledgers, which healed from broker truth over the September outage).
Either way it is unmarked in `CAPTURES.md`.

Timing matters here: BTB-1's 60-trading-day clock stands at 50 elapsed
(60th = 2026-10-19) against 39 panel days accrued, 11 missing. Days are the
scarce input, and this is the class of loss that takes them without saying so.

**The pattern is not new and that is the point.** DSP-1's own table recorded a
missing skew dispatch on 2026-09-14 and 2026-09-15 (single post-close commits at
22:29Z and 22:10Z) and a missing vrp dispatch on 09-16. DSP-1 was dismissed at
panel run 25 on the ground of "zero realized harm, and the backstop worked every
single day" — which was true *of trading*, where the backstop is a late trade
inside the session. For the capture, the backstop is a post-close observation,
which is a different thing from a late one. Today is at least the third
occurrence, and it is the first to happen with `thales-skew` already deleted.

## 4. Preserved from PR #210, at the owner's request

#210 was closed (not merged) on 2026-10-03 06:27:30Z. The owner's close comment:

> "The diagnosis here was correct (an early ping does not satisfy a cron check's
> later slot). If healthchecks is re-introduced, use this PR's `30 14` reasoning
> when re-creating the checks."

The record that carried that reasoning rode the closed branch and never landed,
so it is restated here in full:

**Mechanism.** healthchecks sets a cron check's next deadline to the first cron
occurrence *after* the last ping. A ping landing *earlier in the day* than the
check's own expected minute therefore leaves that day's slot unsatisfied, and
the check alarms one grace period later. The three sleeve checks were created
with the staggered GitHub crons `35 / 40 / 45 14 * * 1-5`, grace 8h; the
executors then moved twice (2026-09-02, the Mac's dispatch to 14:35Z for all
three; 2026-10-02 #201, GitHub's legs to 15:30–15:40Z) and the checks moved
neither time. Arithmetic, matched to the second on 2026-10-01: ping 14:37:16Z →
next `45 14` occurrence 14:45Z → +8h grace → `DOWN | thales-vrp` at 22:45:00Z.

**The forecast, and its confirmation.** The 10-02 audit predicted a
`DOWN | thales-meanrev` at ~22:40Z and a `DOWN | thales-vrp` at ~22:45Z that
night as a falsifiable test of this mechanism. Both arrived: **22:40:03Z** and
**22:45:00Z**. The mechanism is confirmed, not merely plausible.

**If the checks are re-created**, give each a cron of `30 14 * * 1-5`, TZ UTC,
grace 8h: ≥5 minutes of margin before the 14:35Z dispatch slot, while an 8h
grace still alarms the same evening (22:30Z) and still absorbs a GitHub backup
leg delayed to ~20:00Z. Note that momentum's old `35 14` was never safe either —
it had *zero* margin and survived only because its run takes ~15 minutes.

## 5. What was not done, and why

No detector was built. The fix that would make this loud — a capture-absence or
capture-instant leg in the digest's exception list — needs capture state wired
into the digest gather, which collects none today, and it lands on top of CQA-3,
whose own header marks it "not approvable for build until you rule on the
2026-09-02 B4 append". Building it tonight would both exceed one careful session
and step over the owner-only approval gate at `research/queue/approved/`. It is
escalated instead, with the ask stated as a ruling plus an approved row.

Carried in the 2026-10-05 daily audit report.
