โ€บNavigation
Dashboard โ€บ Probes โ€บ Probe Hardening Loop โ€บ iter 6

iter 6 โ€” a declared treatment, not a bug GROUNDED

Attack item L-2 ยท 2026-07-29 ยท harness harness/legacy_trade_id_panel.py

The claim, and what the code actually says

The campaign carried L-2 as trade IDs "re-entering" the legacy panel through legal_all โ€” framed as a harness defect. The harness says otherwise, in its own telemetry:

"deviation_from_shipped_probe": "a1_panel_excluded bypassed for the legacy panel ONLY โ€” that IS the variable under test"
โ€” step2b_real_legacy_loo.py:175

It builds legal_all, derives legal_a1 by applying the exclusion, and runs both (:74โ€“76, :110โ€“111). This is a declared, self-documented treatment. The "bug" framing is refuted.

The sharper question that survives

legal_all is the rotation probe's universe, not the legacy probe's. So does the "real legacy" arm actually run legacy's panel?

legal_all           (25 of 36 representative columns)
legal_a1            (18)
legacy's own panel  (19)

in legal_all but NOT in legacy's own panel (6):
  first_agg_trade_id, last_agg_trade_id, gap_trade_count,
  is_liquidation_cascade, is_orphan, max_gap_duration_us
in legacy's own panel but NOT in legal_all (0): []

trade IDs in legal_all: YES  |  in legacy's own panel: NO  |  in legal_a1: NO

legal_all is a strict superset of legacy's own panel, by exactly six columns โ€” two of which are the trade IDs. So the head-to-head's "real legacy" arm ran legacy's math over a panel legacy itself would never have used. Neither probe's own rules admit trade IDs; only the intermediate legal_all universe does.

Prediction, written before running

A trade ID is a perfectly monotone counter, so Spearman |ฯ| against it equals a candidate's own rank-monotonicity โ€” a far more aggressive competitor than price level. I predicted it would drive independent_but_trending from PASS to BAN (ฯโ‰ˆ0.95+) while leaving stationary candidates untouched.

Directionally right, magnitude slightly over: it reached WATCH, not BAN.

Result

candidateno TIDwith TIDworst competitorflip
independent_but_trending0.7764 PASS0.9340 WATCHfirst_agg_trade_idYES
rolling_mean_close_LEVEL1.0000 BAN1.0000 BANvwapโ€“
the 7 return-based kernelsunchangedโ€”โ€“
independent_stationary0.0820 PASS0.0820 PASSduration_usโ€“

|ฯ| against the monotone counter alone, ranked โ€” the mechanism as a number:

independent_but_trending     0.9340   <-- would WATCH on the TID alone
rolling_mean_close_LEVEL     0.8076
sign_flux                    0.4216
return_kurtosis              0.1906
realized_volatility          0.1438
independent_stationary       0.0200

What this establishes

A monotone trade ID is a stronger substrate artifact than a price level. The same independent-but-trending candidate that price levels lifted to 0.776 (iter 5, sub-threshold) is lifted to 0.934 by the trade ID โ€” over the 0.85 band. The trade ID adds +0.16 on top of what the price levels already did, and that is what crosses the line.

Stationary return-based kernels are untouched (ฯ โ‰ค 0.42), so the effect is trend-specific โ€” the same immunity iter 5 found. Both iterations point the same way: the panel penalises candidates for carrying a trend, regardless of whether the trend carries information.

Consequence โ€” and it is about interpretation, not code

Nothing here is a defect to fix in either probe: both already exclude trade IDs. What it changes is how the head-to-head's numbers should be read. Its "real legacy" arm is not "the legacy probe" โ€” it is legacy's math on a six-column-wider panel, and at least one of those extra columns (first_agg_trade_id) demonstrably moves a verdict across a band. Any conclusion drawn from that arm about "what legacy would say" carries that caveat.

No code was changed. No dial, band, threshold or exclusion rule was touched.

A correction to my own harness, disclosed

The first run's section 1 compared legacy's EXCLUDE against a1_panel_excluded alone, and reported 13 columns as "dropped by legacy only". That overstated the gap: legal_all is legal_feature_columns() without the A1 step, not "no filter at all" โ€” it still drops STR_KEY_PLACEHOLDER, PURE_META, string/date types and label_ prefixes. Comparing against the wrong baseline would have inflated the finding from 6 columns to 13. Corrected before publishing, and the corrected filter is reproduced in the harness rather than described.

Limits

Evidence: harness/legacy_trade_id_panel_evidence.json. Reproduce: VIRTUAL_ENV="" uv run --python 3.13 --no-project --with numpy --with pandas --with scipy python3 harness/legacy_trade_id_panel.py