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.

RPL-1 — the marketable-limit market-replace is the one order path outside the safety chokepoint

status: open · raised 2026-08-29 (external design review finding 5 + maintainer verification) · class: execution-safety (standing-covenant violation) · judgement: YES · effort ~0.5–1 pd · horizon: live on momentum + meanrev every rebalance with an unfilled limit; P low (minutes-wide, BUY-only window)


Plain-language summary for an owner reading one paragraph. When a touch-priced limit order doesn't fully fill within the fill window, _resolve_unfilled_limits cancels it and re-submits the remainder as a market order. That replacement re-checks only the manual/fleet halt — not the daily-loss breaker or any per-order reject that materialized during the minutes-long wait — and it submits via broker.submit_market_order directly. That makes it the single order path in the codebase that bypasses pipeline.execute_orders, which the shop's own covenant (memory/execution-safety-layer, 2026-06-06) names THE fail-closed chokepoint: "never add an order path that bypasses it." A second facet shares the site: remaining = shares − filled_qty reads filled_qty BEFORE the cancel; fills landing between the read and the cancel taking effect over-buy the remainder (check-then-act race).

Mechanism — verified at HEAD (external review, re-verified by the maintainer)

  • src/thales/execution/daily.py _resolve_unfilled_limits: top-of-function re-check is manual_halt_engaged only; the replacement goes out via broker.submit_market_order(..., client_order_id=…-mr) with no evaluate_safety pass over the remainder batch.
  • filled_qty is read from get_order_status before cancel_order; the remainder is sized from that pre-cancel read.
  • Reachability: config/settings.yaml (momentum) and config/meanrev.yaml both run order_type: "marketable_limit"; only vrp is market.
  • Credit where due (also verified): the surrounding code is careful — unknown status → leave the resting limit untouched (fail closed, 2026-07-18 fix); failed cancel → no replacement. The gap is exactly the missing full-gate re-check and the stale read.

Why P is low (and why it still matters)

The trigger needs a >10% intraday move or a fresh reject to materialize inside a ≤5-minute fill window, and only bites a BUY remainder — a de-risking SELL remainder should complete. But the site is live on both equity sleeves on every rebalance, and it is a covenant violation independent of P: the gate's guarantee is only as good as the paths that go through it.

Fix shape (PROPOSE-only — this row does not implement it)

  1. Route the replacement through the full gate: run evaluate_safety over the remainder batch (fresh account snapshot) before any market replace; a HALT verdict cancels-without-replacing (the fail-closed arm already exists for the manual-halt case).
  2. Re-read filled_qty AFTER the cancel is confirmed, size the remainder from that.

Test design + kill criterion (pre-registered, negative-controlled)

  1. Stub broker whose account crosses the −10% daily-loss line between the initial submit and the resolve pass, with an unfilled BUY limit: the market replacement must NOT be submitted (deny-asserted — red today).
  2. Race test: the stubbed order reports more filled_qty on the post-cancel read than the pre-cancel read; the replacement must be sized from the post-cancel value (red today).
  3. De-risking SELL remainder with the breaker tripped: replacement still goes out (the exemption must survive the rewiring).

Kill criterion: all three green post-fix; revert the gate re-route and test 1 reds; revert the re-read and test 2 reds. If routing through the gate proves impossible without submitting a second time through execute_orders's idempotency machinery, that is a finding about the chokepoint's shape — record it, don't work around it.

Scheduling note

Deliberately NOT built in the 2026-08-29 review-response PR: rewiring order-path plumbing the weekend before a selection day + owner absence is worse risk management than the defect (minutes-wide, BUY-only exposure). First unhurried week.