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

iter 14 โ€” row-order invariance holds FIXED

Attack item X-3 ยท 2026-07-30 ยท harness harness/row_order_invariance.py ยท gate /xi:order-invariance

Why X-3 was aimed here rather than at "byte-identical double run"

Read literally, X-3 would pass vacuously โ€” every harness in this campaign is seeded. The version that can actually fail, and that this loop has a direct stake in, is the metamorphic one: re-order the rows without changing their content; the verdict must not move.

The stake is mine. Iteration 1 (PR #674) changed the fetch from ORDER BY close_time_us DESC to ORDER BY close_time_us DESC, first_agg_trade_id DESC. That was done to make the row set deterministic under a LIMIT โ€” but it also changes the row order for every row tied on close_time_us, and BTCUSDT@250's window carries 40,054 such ties. If ฮพ were order-dependent, that "pure correctness fix" would have silently moved verdicts. I made the change, so I am not willing to leave the claim untested.

Result 1 โ€” the estimator's claim verified, both directions

  x ties   content-addressed    positional (default)
   0.000     |diff| 0.00e+00         |diff| 0.00e+00
   0.100     |diff| 0.00e+00         |diff| 1.71e-03
   0.309     |diff| 0.00e+00         |diff| 4.47e-04
   0.950     |diff| 0.00e+00         |diff| 5.27e-03

negative control: positional tie-break moved in 3/3 tied cases -> gate can fire

Content-addressed keys give exact invariance โ€” 0.00e+00, not "small", at every tie rate including the 0.95 rate-valued-kernel shape. The positional default demonstrably does not, which is what makes this a gate rather than a formality.

Worth sizing: the positional drift reaches 5.27e-03 at the rate-kernel tie rate. The ฮพ PASS moat is 0.006. So under the positional default, merely re-ordering rows could move a verdict almost the full width of the moat. That is what the content-addressed fix bought, quantified.

Result 2 โ€” PR #674's re-ordering moved nothing

xi_max_pair   before 0.353897485246   after 0.353897485246   |diff| 0.00e+00   -> unchanged

Replaying the exact permutation the ORDER BY change induces โ€” rows tied on close_time_us, re-sorted by first_agg_trade_id โ€” leaves ฮพ bit-identical. Iteration 1's substrate fix did not move verdicts through this mechanism. Verified, not assumed.

Result 3 โ€” through the cascade's own entry point

before xi=0.338218625462 stable=True    after xi=0.338218625462 stable=True   -> IDENTICAL

Both the value and the stability flag survive a joint permutation, so the invariance holds through xi_cell_vote_stable, not merely through the bare estimator.

A self-consistency check that fell out of building this

Section 2 needed an identity key for the rows, and the natural candidate โ€” close_time_us โ€” is duplicated by construction in that scenario, since the whole point is rows tied on it. So the harness uses the unique key instead. That is precisely the degeneracy iteration 1's G2 gate now refuses (assert_deduplicated rejects a non-unique identity column, because row_identity_keys silently degrades on it). The campaign's own gate and this harness independently arrived at the same requirement.

What landed

/xi:order-invariance, wired into /xi:check-full and verified by /xi:doctor. Unlike X-2 โ€” which is real but currently failing, and was deliberately kept out of the suite โ€” this one passes, so it belongs in the gate set. The full suite runs green: oracle parity exact to 2.44e-15, shuffled null clean both directions, row-order invariance exact.

Zero free parameters. No dial, band or threshold touched.

Limits

Evidence: harness/row_order_invariance_evidence.json. Reproduce: mise run xi:order-invariance