DISMISSED — FOS-2 — FOS-1's NEW-vs-STANDING split reaches the per-sleeve digest but not THE fleet email
status: dismissed by TRIAGE 2026-09-14 · OVERFLOW — ranked 16 of 21 at the pre-registered 12-item cap · FOLDED INTO DGX-1 (same module, adjacent lines, same defect class) · raised 2026-09-09 · body verbatim below
Resolution — folded into DGX-1; PR #163 closed the detection half and halved what remains
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 one is a fold, not a
kill: DGX-1 (kept, ranked 5) is the same defect — the digest's renderer and
the digest's send-gate read different sources of truth — in the same file,
within forty lines of this row's fix site.
Re-verified at HEAD 340bc5f; PR #163 (3fc2dba, 2026-09-12) changed this
row materially and in the good direction:
- Detection leg CLOSED.
fleet_digest.py:1183-1187now readsfailed_standingand counts onlyn_failed - n_standingas NEW, so a fresh failure does force an off-cadence email under the new weekly policy. That is the onlyfailed_standingreference in the module. - Rendering leg STILL OPEN.
fleet_digest.py:781-785still builds the line fromd.get("failed_orders")alone, so the operator reading the mail still cannot tell a 16-session standing failure from a fresh one. The exception reason never reaches the body either —should_emailreturns it (:1205-1207) and it only prefixes the subject with ⚠️ (:1245). - The gather half of the filed fix is already done —
digest.py:247-249emitsfailed_orders/failed_new/failed_standingfor weights sleeves, andfleet_digest.py:470routes them there. So the remaining job is liftingdigest.py:515-528 _failed_detailinto a shared formatter.
Re-tiered by this run, on evidence: P0 → P2, effort 0.25 pd → ~0.1 pd. After #163 this is an operator-comprehension defect (a structural condition rendered as an event), not a loudness defect.
ARMED, unlike its fold partner. data/state/meanrev/order_log.jsonl holds
23 failed records, 15 of them AVB emergency-exit sells, 2026-08-17 →
2026-09-11 consecutive, cause APIError 40010001 asset AVB is not active.
This renders on the next fleet email that includes meanrev. (DGX-1's three legs
are all latent by measurement.)
Reopen condition. Reopen immediately if DGX-1 is dismissed, or if DGX-1 is built without a shared failed-order formatter reaching the fleet email body — the fold is only safe while DGX-1 carries it. FOS-2's negative control should survive into DGX-1's test set: revert the fleet renderer to the flat line and assert the test reds.
Body as filed (verbatim, untouched)
FOS-2 — FOS-1's NEW-vs-STANDING split was built into the per-sleeve digest only; THE daily email still prints the flat furniture line, so AVB's 14-session standing failure reads exactly like a fresh one-off
status: open · raised 2026-09-09 (owner-side interactive session, reviewing #154 in the panel's absence — the change reviewer that would normally catch this was rate-limited dead 09-07…09-09) · class: truth divergence between layers (the AI-native audit's recurring class) · judgement: YES · effort ~0.25 pd · horizon: live every day; it silently un-does a guard merged 2026-09-07
Plain-language summary for an owner reading one paragraph. FOS-1 was
built to stop a repeating order failure from looking like a fresh one — a
name that has failed to sell for fourteen sessions is a structural
condition, a name that failed today is an event, and the flat line
!! 1 FAILED order(s): AVB cannot tell them apart. The split was
implemented in digest.py, which renders the single-sleeve digest
(thales --sleeve meanrev portfolio digest). The message that actually
reaches the operator is the fleet digest, and that renderer was not
touched. So the guard is real, tested, merged — and invisible in the only
channel anybody reads. The escalation half of FOS-1 (a fresh de-risking
failure exits 4 and fires the workflow alert) is intact and is not what
this row is about.
Mechanism — ground truth measured at HEAD ee68ebe
- Rendered, not inferred.
thales fleet digestrun 2026-09-10 01:50 ET for session 2026-09-09 prints, in the MEANREV section:!! 1 FAILED order(s): AVB— no streak, no length, no cause. AVB's actual state that session:cause: emergency_exit,status: failed, fourteenth failed session since 2026-08-17, broker textAPIError: {"code":40010001,"message":"asset AVB is not active"}. src/thales/execution/fleet_digest.py:781-785builds that line fromd["failed_orders"]alone.grep -n "failed_streaks|split_new_and_standing|failed_standing" src/thales/execution/fleet_digest.pyreturns nothing — the module never imports FOS-1's machinery.src/thales/execution/digest.py:120-132gathers the split,:516-528formats it,:590-591renders the standing lines. That is the per-sleeve renderer, reached by a command a human must type.- The escalation half is fine and stays out of scope:
cli.py:1176raisestyper.Exit(4)for de-risking orders failing for the first time. Both meanrev runs on 09-09 exited 0 correctly, because AVB is standing, not fresh. - The same divergence already happened once, and its scar is three lines
above the defect.
fleet_digest.py:777-779carries the comment: "Failed submissions must be visible in THE daily email (2026-07-20: a broker-rejected SATS buy was invisible here; only the standalone single-sleeve digest rendered it)." A fix landed in the per-sleeve renderer and not the fleet one, was caught, was patched — and the next reporting feature took the identical wrong turn. That recurrence is the argument for a structural fix over a second patch.
Why it matters beyond the control sleeve
The renderers are shared across sleeves. On momentum the same silence is a stuck live position whose exit is standing-unable to execute, reported as an ordinary count. The December gate reads TCA and safety-HALT history on the assumption that exits execute; a standing exit failure that never distinguishes itself is exactly the input that assumption cannot survive.
Fix shape (propose-only)
One formatter, two callers — not a second copy of the logic. Lift the
new/standing formatting into a single function (digest.py's
_failed_detail is already almost it) and have fleet_digest.py call it
with each sleeve's own order history and run summaries. A third renderer
added later then cannot diverge silently, which is the actual defect class.
The minimal alternative (duplicate the gather in fleet_digest.py) fixes
today's symptom and re-arms tomorrow's.
Test design + negative control
Fixture order log with a ≥3-session streak on one symbol plus a fresh
same-day failure on another → the rendered fleet email must name both
distinctly (1 NEW: XYZ [selection]; 1 standing: AVB x14 [emergency_exit]).
Negative control, shown in the PR: revert the fleet renderer to the flat
line and assert the test fails. A control that passes against the bug is
decoration — the FOS-1 build note says so in its own words, and this row
exists because the thing it verified was not the thing the operator reads.
Kill criterion (pre-registered)
If a path already exists by which the standing/new split reaches the daily email — any path, including one this row missed — the item dies on that evidence and is filed dismissed with the path named. If the shared-formatter shape cannot be built without touching trading-path code, it drops to the render-only fix and says so; it does not grow.
Prior art
research/queue/built/fos-1-per-symbol-failed-streak.md (the guard this
row says is half-landed) and research/queue/built/exq-1-batch-quote-fail-open.md
(whose BUILT note first recorded the furniture line). The AVB position
itself is not relitigated: the daily audit adjudicated it a broker-side
owner chore (Alpaca 40010001 asset not active), that ruling stands, and
nothing here touches it. This row is about the detector only.