The veto agent (labtrader/veto.py)
Scout as a picker turned out to be momentum wearing a hat — every visible pick sat in Momentum's top 20, because four of its five features were momentum features. An agent can only express what its inputs allow.
Vetoed wraps any strategy. The strategy proposes; the agent may drop some of
those buys and may do nothing else — it cannot add a name, resize one, or veto
a sell.
Three reasons this is the better experiment:
- Cleanly measurable. Same strategy, with and without, over identical order
flow.
test_a_veto_that_never_fires_reproduces_the_strategy_exactlyis the control — if the wrapper did anything of its own, no comparison would mean anything. - Bounded downside. The worst an over-eager veto can do is leave you in cash. It can never take a position you did not already want.
- Asks something momentum cannot answer. A cross-sectional rank is blind to regime, so the prompt carries market context — index return, breadth, median volatility — which is the one input a rank does not already contain.
Fail-open, deliberately. An outage or a nonsense reply lets everything through. That is the opposite of Scout and for the right reason: Scout was the strategy, so failing meant doing nothing; a veto is a filter, so failing means not filtering. An outage must never be able to stop a book trading.
Sells are never shown to it, let alone vetoed. Blocking a de-risking order is the one thing a risk check must not do — the same principle as the gate's "de-risking is always allowed".
First live call, 2026-09-08
Vetoed 3 of 20 (15%) on reasons a cross-sectional rank structurally cannot produce: CRM for realised volatility of 87.9% against a 24.2% index median, ORCL and TSLA for negative 60d returns despite ranking on 20d — momentum picking up a bounce inside a downtrend.
Cheaper than the picker, too: $0.0223 a call against $0.0496, since it screens 20 names rather than 112. A full backtest is $10.30, weekly running $1.11/yr.