This iteration built the Chatterjee ξₙ confirmation harness — the asymmetric, non-monotone dependence gate that adjudicates the 16 Spearman-cleared keepers and the 2 HOLDs — and smoke-validated it on EURUSD@5 live_tail. The full 174-cell run was launched at the end of this iteration and is now in progress.
--mode chatterjee added to multislice_orthogonality_probe.py; clean-room asymmetric ξₙ kernel; scale-aware degeneracy gate replacing the broken range<1e-9 floor; per-cell xi_results/ + XI_AGGREGATE_VERDICT.json emitters. Smoke on EURUSD@5 live_tail: n_eval=7450, prod=125, maxXI(c→c)=0.83, maxXI_abs(prod→c)=0.95.rank().corr() → asymmetric Chatterjee ξₙ in both directions for every candidate×candidate pair and every candidate×(143-col legal production surface) pair. Reuses the existing generic fetch (FINAL + do_not_merge_across_partitions_select_final=1), de-gap (weekend/ouroboros gap-return nulling), 200-bar rolling windows, 10 slices, 19 cells.range<1e-9 gate (which missed updown_cjs at ~1e-5) is gone; a scale-aware panel now emits eff_bits, abs_p50, range, iqr, rel_range, h_norm per candidate per cell.xi_results/; --mode aggregate-xi rolls them into XI_AGGREGATE_VERDICT.json (worst/median directed ξ per pair, per-symbol medians, absorbed-symbol counts, scale-aware degeneracy roll-up, per-candidate verdict).ch() helper now uses --readonly 2 --max_threads 2 --priority 10 --os_thread_priority 19 (local on-box client; bar data never leaves bigblack).n_eval and a sane ξ matrix.Spearman measures only monotone dependence and is symmetric. Chatterjee's ξₙ measures general dependence — ξ(X→Y) ≈ 1 iff Y is a measurable function of X — and is asymmetric, which is exactly what "is candidate A absorbed by feature B?" needs.
xi(X→Y) = 1 − n·Σ|r_{i+1} − r_i| / (2·Σ l_i(n − l_i))
sort by X (deterministic, stable tie-break → replay-bit-exact)
r_i = #{j: Y_j ≤ Y_(i)} (rankdata 'max')
l_i = #{j: Y_j ≥ Y_(i)} (n − rankdata 'min' + 1)
Directional convention used here: a candidate is absorbed (redundant) when some shipped column p predicts it — i.e. xi(p → cand) is high (cand ≈ f(p)). xi(cand → p) is also computed and stored. Tie-breaking is a stable argsort (not Chatterjee's random break) so the run is replay-bit-exact — a no-silent-drift control (PITSLARP).
The new gate flags a candidate-symbol degenerate when eff_bits < 1.5 (fewer than ~3 distinguishable levels) OR (|p50| < 1e-4 AND range < 1e-4) (sits within 1e-4 of constant with sub-1e-4 spread). The smoke cell shows it discriminates the degenerate HOLD from the location HOLD and from healthy features:
| candidate | abs_p50 | range | eff_bits | iqr | gate |
|---|---|---|---|---|---|
| updown_cjs | 3.4e-07 | 2.3e-06 | 3.66 | 3.1e-07 | DEGENERATE (prong B) |
| candle_shoelace_area | 0.0 | 3.4e-04 | 3.04 | 2.6e-05 | not degenerate — location case |
| lziv_complexity_signs | 1.147 | 0.31 | 2.37 | 3.8e-02 | healthy |
| edge_spread_bps | 0.162 | 0.81 | 3.42 | 9.1e-02 | healthy |
updown_cjs's near-point-mass magnitude (~3e-7) without false-flagging candle_shoelace_area (range 3.4e-4 > 1e-4 → its problem is monotone location, adjudicated by ξ vs log_return_bar_sum, not degeneracy) or genuinely-varying features. Exactly the separation the run plan asked for.Per-candidate strongest shipped-column absorber max_p xi(p → cand). Single-cell only — the verdict is the median over 174 cells with ≥2-symbol replication; these are illustrative.
| candidate | abs ξ (prod→cand) | median absorber | top absorber col | fwd ξ (cand→prod) |
|---|---|---|---|---|
| mann_kendall_z | 0.954 | 0.134 | hawkes_intensity_bar_last | 0.041 |
| sevcik_fd | 0.940 | 0.126 | hawkes_intensity_bar_last | 0.133 |
| anderson_darling_a2 | 0.930 | 0.192 | hawkes_intensity_bar_last | 0.190 |
| pietra_hoover_durations | 0.912 | 0.137 | hawkes_intensity_bar_last | 0.056 |
| mean_cosine_turning_angle | 0.909 | 0.186 | hawkes_intensity_bar_last | 0.112 |
| spread_sign_reversal_rate | 0.873 | 0.116 | hawkes_intensity_bar_last | 0.918 |
| spectral_log_slope | 0.384 | 0.048 | session_fine_id | 0.018 |
| lziv_complexity_signs | 0.410 | 0.036 | hawkes_intensity_bar_last | 0.975 |
| candle_shoelace_area | 0.528 | 0.014 | bid_imbalance_ewma_bar_last | 0.965 |
hawkes_intensity_bar_last is the strongest absorber for ~14/16 candidates on this single 90-day slice (0.83–0.95). This is almost certainly an overlapping-window smoothness inflation of ξ: at stride=1 consecutive 200-bar windows share 199/200 bars, so every rolled feature is an extremely smooth (low-frequency) series; sorting by any other slow-drift column orders it smoothly → ξ(X→Y) inflates. Note the median absorber across all 125 prod cols stays low (0.01–0.19) — only one column drives the tail. The guard is built in: the absorption verdict uses the median over 174 cells with ≥2-symbol replication, not a single slice. Iteration 2 will check whether hawkes_intensity_bar_last is a universal absorber (real) or a per-slice artifact (drops out under the median).SELECT on the local on-box client; bars held in RAM, discarded after compute. No synthetic / surrogate / IAAFT / phase-randomized / with-replacement-bootstrapped series at any stage.loop-xi-keeper only; HTML lives outside the repo under ~/sites/.--max-hours 8, resumable — one JSON per cell).--mode aggregate-xi → worst + median directed ξ per pair; adjudicate. ξ>0.50 (absorbed) on ≥2 symbols ⇒ DROP/HOLD, else independent. Resolve the hawkes_intensity universal-absorber question via the cross-cell median.candle_shoelace_area — ξ vs log_return_bar_sum/nearest shipped col >0.50 on ≥2 symbols ⇒ DROP (shadow), else KEEP. updown_cjs — scale-aware gate flags it on liquid majors ⇒ DROP; real ξ-signal on XAU/XAG ⇒ KEEP metals-only.turning_point_rate_z drop. Then set implementation_ready:true for survivors and write the final verdict.Generated 2026-06-06 · iteration 1 · harness commit pending (PR-from-worktree at milestone) · ξ run plan: 2026-06-06-chatterjee-xi-keeper-run-plan.md