DISMISSED — SAC-1 — census of trading-path persist sites: "state advanced or keyed without regard to run outcome"
status: dismissed by TRIAGE 2026-09-14 · OVERFLOW — ranked 13 of 21 at the pre-registered 12-item cap · FOLDED INTO RWG-1, which this row's own cap note asks to be sequenced with · raised panel run 15 (2026-09-04) · body verbatim below
Resolution — folded, not killed: the ruling it needs is RWG-1's, and RWG-1 stays open
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 is one of them, and it
is the one dismissal that costs the queue nothing: this row asks, in its own
cap note (:79-84), to be sequenced with RWG-1 so the owner rules once. That
is exactly what this run's decide-list does — RWG-1 is decide item 3 and carries
SAC-1's live members with it.
Re-verified at HEAD 340bc5f. Nothing here is overtaken; the content is
carried, not discarded. Two of the five named members are CLOSED by KSP-1
(PR #151):
- kill-switch
active: Truepublished before liquidation — CLOSED,daily.py:1227-1230(publish deferred). - Kelly-snapshot wipe on a halted liquidation — CLOSED,
daily.py:1231-1234(clears only on the non-halt branch).
Three members are LIVE, and the owner must see them when he rules on RWG-1:
last_targets—daily.py:1795-1803, guarded only byif not self.pipeline.dry_run:(:1796) whileexecute_ordersruns at:1862. This one IS RWG-1 leg 2, so RWG-1's ruling disposes of it directly.last_construction/vol_scalar—daily.py:840(if not self.pipeline.dry_run:) →:843-849persists; consumed atdaily.py:667-668. A halted momentum selection leaves the vol-target estimator de-scaling against a book that was never held, for up to a month. RWG-1 does not contain this member._record_safety_eventarms same-day idempotency —pipeline.py:274(log_runon any HALT) →state.py:180-187(already_ran_todaymatches anyrun_summaryfor the date) →daily.py:1523returns the skip →cli.py:1107critical_skips = {"No signals", "Stale price panel"}does not include "Already ran today", so the run exits 0. RWG-1 does not contain this member either.
Also recorded so it is not re-derived: the row's kill criterion has an
unfireable zero-branch (three live members remain), so it is a census whose
output is a table, not a falsification test. The census memo does not exist in
research/, and no test pins any live member (tests/ greps for SAC-1/RWG-1
hit only test_pipeline.py:197 and test_kill_switch_booking.py:106).
Reopen condition. Reopen the moment RWG-1's two rulings are made if they
do not dispose of members 2 and 3 above — last_construction
(daily.py:840-849) and the same-day idempotency arming (pipeline.py:274 /
state.py:180-187 / cli.py:1107), neither of which RWG-1 contains. Reopen
immediately if RWG-1 is itself dismissed or closed without a ruling, since
this row would then be the only place those three sites are written down.
Body as filed (verbatim, untouched)
SAC-1 — census of trading-path persist sites: "state advanced or keyed without regard to run completion" (member four already found)
status: open · raised panel run 15 (2026-08-31), answering the owner handoff in 60a6630 / RESEARCH.md's top banner ("sweep for member four instead of waiting for it") · class: loudness & safety (live path) · judgement: YES · effort ~0.5–1 pd · horizon: before momentum's next halted-selection retry sequence (the 08-19/20 meanrev sequence puts the trigger cadence at roughly monthly)
Plain-language summary for an owner reading one paragraph. The last month produced three separately-discovered defects with one shape: the system wrote down what it intended to do — or what day it believed it was — without checking that the run actually completed. RWG-1 leg 2 (the turnover-blend base advanced during a safety halt), STAMP-1/STAMP-2 (a wall-clock date consumed the next session's idempotency slot), and the Kelly double-booking fixed in PR #120. You asked the panel to sweep for member four instead of waiting for it to fire. The sweep found it in under an hour — which is the evidence the class is productive and a one-shot census is worth a row.
Member four (verified this run; recorded here so the census consumes it rather than rediscovers it)
src/thales/execution/daily.py:821-831 persists last_construction
(including the intended vol_scalar) inside _size_targets, gated only on
dry_run. _size_targets runs at daily.py:1638; execute_orders at
:1719 — the persist precedes the safety gate. Consumption chain:
daily.py:658-662 reads last_construction.vol_scalar into every subsequent
daily portfolio snapshot, and _gross_returns (:714-721) divides each
realized return by it for the vol-target estimator. So a selection that sizes,
persists the scalar, then safety-HALTs leaves the estimator attributing the
real (old-scalar) book's returns to a scalar that was never applied — for up
to a month on momentum, which sizes from state this corrupts.
Mechanism — the census
One-shot enumeration of every persist site in the trading path (daily.py,
vrp_daily.py, pipeline.py, state.py, tca.py), each classified on two
axes:
- (a) gated on run completion (halt/exception) vs ungated;
- (b) keyed on the unit of work (period/session) vs wall-clock.
For each ungated site, a ruling: deliberate (fact-recording/telemetry —
e.g. append_equity, portfolio snapshots record what IS, regardless of what
executed) vs defect (intent persisted as if executed — e.g.
last_construction, the class members above). Deliverable: the classification
table as a memo in research/. Propose-only; no gate ships from this row.
Scope boundary (C0 — stated so this cannot collide with existing rows)
- Trading-path persist sites only. The capture writers are STAMP-1/STAMP-2's owned territory and are out of scope here.
- Per-site rulings for
last_targetsand the kill-switch Kelly-snapshot wipe defer to RWG-1 (legs 2–3), which owns them. The census enumerates and classifies; it does not re-litigate a row that already owns a site.
Data plan
Static code reading, cross-checked against the committed natural experiment: for each site, diff its persisted value across meanrev's 08-19/20 halted runs and the 08-21 recovery (the same commits that confirmed the Kelly double-booking). Observed advancement during a halt is ground truth, not inference. Owned; zero external data; zero registry rows.
Test design
For every site the owner rules "must be gated": a halt-injection test — force a safety HALT, assert the site's persisted state is unchanged — with a negative control per gate (revert the gate; only its own test reds). Sites ruled deliberately ungated get a pinned comment naming the ruling, not a test.
Kill criterion (pre-registered)
If the census finds zero ungated-defect sites beyond the already-recorded
members (RWG-1 legs 2/3) plus last_construction (named above), the class is
declared fully enumerated, the row closes with the table as its record, and
the class may not be reopened without a new fired instance.
Cap note for triage
queue/open/ is at/over the 12-cap. Rank this against the tree explicitly
rather than letting it slide in — if something must yield, the natural
fold-partner is the STAMP-1+STAMP-2 shared fix-sitting (same family), never
RWG-1 (deliberately narrowed).
Dated note — 2026-09-05 (maintainer, from the external design review r2 verification)
Two more sites for the census, both verified at cd571b2, neither owned by
another row at the time of writing:
_record_safety_eventarms the same-day idempotency gate on a HALT.pipeline.py:274writes arun_summaryfor any safety HALT;already_ran_today(state.py:180-187) honours anyrun_summaryfor the date;daily.py:1392then skips with"Already ran today", which is not incli.py:1107'scritical_skips, so the run exits 0. RUNBOOK.md's post-halt instruction ("fix the cause, thenthales run --skip-market-checklocally", :253-254) is therefore a green no-op without--force— which the same sentence says never to use casually. Axis (a): ungated — a HALT is recorded as if the day's unit of work completed. Ruling needed: is a HALT a completed unit of work for idempotency purposes? Damage is bounded to one lost day because the month stays open viaselection_completed=False(daily.py:502-511), which is why the reviewer filed it as a near-miss rather than a finding.- Kill-switch
active: Truepersisted before the liquidation is attempted (daily.py:1024-1026, then_liquidate_to_cash→execute_ordersat:1133). Owned by KSP-1 (raised the same day) for the fix; listed here so the census consumes it rather than rediscovers it. Same class: intent written as fact.
Neither changes this row's kill criterion; both count as members beyond the already-recorded ones, so the criterion's zero-branch cannot fire on the current tree.
Triage note — 2026-09-07 (annotation only; the body above is untouched)
Two of the five named members are CLOSED by KSP-1 (#151, 47ea024); three
stand, and they are the three that corrupt sizing state. Verified at HEAD
e25f80b:
| member | status |
|---|---|
last_construction / vol_scalar (member four) | live — daily.py:841-849, gated only on dry_run (:840); _size_targets at :1781, execute_orders at :1862 |
_record_safety_event arms same-day idempotency | live — pipeline.py:274 writes a run_summary on any HALT; state.already_ran_today honours any of them (state.py:180-187); daily.py:1523 then skips, and "Already ran today" is not in cli.py:1107's critical_skips, so the run exits 0 |
kill-switch active: True before liquidation | CLOSED (KSP-1: deferred publish, daily.py:1103-1106 → :1227-1230) |
| Kelly-snapshot wipe on a halted liquidation | CLOSED (KSP-1: non-halt branch only, daily.py:1231-1234) |
last_targets (deferred to RWG-1) | live — daily.py:1795-1803 |
The kill criterion's zero-branch therefore cannot fire, exactly as the 09-05 dated note anticipated. STAMP-1/2/3 closed the wall-clock keying axis for the two run wrappers; they closed none of the persist sites above, which sit on axis (a).
The deliverable does not exist yet: no census memo among
research/2026-09-*; a grep of research/ for SAC-1 returns only queue files
and the two design-review memos. Triage carries this into the decide-list
folded with RWG-1 legs 2+3, per this row's own sequencing request — one
ruling sitting, not two.