# A sweep that resolves nothing says nothing — OSR-1 leg 1's first live day

**2026-10-22 (daily audit).** The terminal-status sweep merged the night before
(#262, OSR-1 leg 1) ran for the first time today on the trading box. On the
mean-reversion sleeve it corrected **211 of 211** order records whose outcome
had never been recorded. On the VRP options sleeve it corrected **0 of 1**.

Both sleeves produced the same amount of evidence about what happened: none.

## What the records show

The sweep re-asks the broker about recent orders whose recorded status is still
"in flight", and appends a `status_update` line for each one the broker has
finished with. Measured from committed state:

| sleeve | orders in the 5-day window | corrected today | status_update rows ever |
|---|---|---|---|
| meanrev | 211 | **211** | 211 |
| momentum | 0 (no orders — `vol_check_only` day) | — | 0 |
| vrp | 1 (the 2026-10-19 spread open) | **0** | 0 |

And the VRP sleeve's whole history reads the same way: **all 17 orders it has
ever submitted — 9 opens and 8 closes, 2026-07-13 through 2026-10-19 — are
recorded `OrderStatus.PENDING_NEW`.** Not one has an outcome. The live position
file agrees: `data/state/vrp/vrp_position.json` carries
`"submit_status": "OrderStatus.PENDING_NEW"` for the spread the sleeve has been
managing for four sessions, and on 2026-10-22 that spread's profit-take trigger
fired (`manage:hold-unconfirmed`).

## Why nobody could tell

Three facts compose into the silence.

1. **`found is None` was a bare `continue`.** If the broker returns no order for
   the id we minted, the sweep skipped it without counting or logging it. That
   is not a lag — it means we hold a submitted-order record the broker has never
   heard of, and no future sweep resolves it either.
2. **The summary log fired only `if written`.** A sweep that wrote nothing
   logged nothing, so "there was nothing to correct" and "every lookup came back
   empty" were the same observable.
3. **`thales run` printed only `if swept`**, and the box's stdout is not
   committed. So even a logged line would not reach a reader.

Taken together: on the sleeve where an unrecorded outcome matters most — an
options sleeve where a CLOSE that did not fill leaves a short put live into
expiry — the instrument was structurally incapable of saying so.

This is the house failure shape, applied to a brand-new detector on its first
day: **a green you cannot believe is worse than a red.**

## What was not determined

Why the VRP lookup produced nothing is **not** established here, and this note
does not guess. Two candidates, indistinguishable from committed state:

- Alpaca does not resolve a multi-leg options parent order through
  `get_order_by_client_id`, so the lookup returned `None`;
- the lookup raised and was swallowed into a log line on the box.

The submission path was checked and is *not* the cause: `submit_mleg_order`
takes and sets the same `client_order_id` the order log records
(`pipeline.py:397`, `alpaca_broker.py:266`), so the key is right. Resolving the
rest needs broker credentials, which this audit does not have. The fix below is
deliberately the one that makes the next run answer the question by itself.

## The fix

**Not** a retry, a widened window, or a guess about Alpaca's options API. Just:
make the sweep account for every candidate, and make the condition visible from
committed state alone.

- `SweepReport` — `candidates / resolved / in_flight / not_found /
  lookup_failed / capped`, with `not_found_keys` named. `not_found` and
  `lookup_failed` are `unexplained`: logged at WARNING, printed by `thales run`
  and by `thales portfolio sweep-status`. `sweep_terminal_statuses` keeps its
  signature and return — adding observability is not a reason to change a
  trading-path return type.
- `unrecorded_outcomes(state)` — pure and broker-free: orders submitted since
  the sweep went live, now **older than its window** (so no sweep can reach
  them again), still carrying no outcome. Surfaced as a `digest_exceptions`
  line, which is uncapped and is what the steward reads on a non-Friday.

## Calibration — the part that decides whether this gets read

A naive version of that detector counts every non-terminal record and reports
**5,559** on day one:

| sleeve | records with no recorded outcome | oldest |
|---|---|---|
| meanrev | 5,073 | 2026-07-13 |
| momentum | 469 | 2026-04-07 |
| vrp | 17 | 2026-07-13 |

Every one of those predates the sweep and was already outside its 5-day reach
when it went live, so **no sweep will ever clear them** — the number would never
fall, and an alarm that cannot go green is one the reader learns to skip. So the
boundary is `SWEEP_LIVE_DATE - DEFAULT_DAYS` (2026-10-17), derived rather than
written twice, and the backlog is a recorded fact in this note instead.

Measured against live state, the detector reads **0 for all three sleeves
today** and **1 for vrp on Monday 2026-10-26** if nothing resolves the
2026-10-19 open before then. It fires on the live defect and on nothing else.

## What remains, and needs credentials

The backlog is clearable but only from a credentialed machine, and it includes
the 130 rejections that motivated OSR-1 in the first place: the 2026-08-28 and
2026-08-31 batches are **still recorded `OrderStatus.ACCEPTED`** — 444 and 502
records, zero corrections. `thales --sleeve meanrev portfolio sweep-status
--days 60` is the command; the 300-lookup cap means more than one pass, and
`sweep-status` exposes no `--max-lookups` flag today.

**Controls.** 12 tests, each paired with the revert that reds it: removing the
two counters reds exactly the three behavioural tests and nothing else (3
failed / 39 passed, restored to 42 passed); dropping the backlog boundary turns
an 2026-08-31 record back into an alarm. Full suite 1845 → **1857 passed, 1
skipped**; pre-trade gate 1299 passed, 1 skipped, 558 deselected.
