โ€บNavigation
Dashboard โ€บ Rotation-Orthogonal-Probe Campaign โ€บ iter 10

iter 10 โ€” h_norm gate battery: the last unattacked cascade stage

BREAKS โ†’ DEFENDED โ†’ CLOSED  2026-07-10 ยท 120 columns ร— 62 cells scanned + 160-check battery ยท a silent library-rot defect found in the degenerate contract ยท clean counter reset 2/3 โ†’ 0/3

Claim under attack (assumed true only to destroy it)

The h_norm mass-collapse gate (quintile entropy / log 5; frozen floor 0.05; min-over-cells) is a sound ยงB stage: monotone/order-invariant, catches degenerates (0.0 โ†’ BAN), respects FLOOR_1000 โ†’ PENDING, and โ€” the sharp edge โ€” its min-over-cells vote cannot false-BAN a feature that is healthy in the bulk of cells (this vote has NO quality guard; iter 4 protected only the ฮพ votes).

Result matrix

FalsifierResult
F1 โ€” monotone-transform verdict flips (ร—4, xยณ)0 (bit-stable)
F2 โ€” order dependence (multiset function, hash-perm)0 (exact)
F4 โ€” single-cell false BAN over the full 120-column live universe0 hits โ€” no real column reads < 0.05 in any cell while median-healthy; the unguarded min-over-cells vote is empirically safe on this universe
F3 โ€” degenerate contractBROKE โ€” a real point-mass column (the cell's modal value repeated, the exact case the gate exists for) read NaN โ†’ PENDING instead of the documented 0.0 โ†’ BAN

Root cause โ€” silent library rot

Current pandas' qcut(duplicates="drop") on a constant series returns all-NaN bins instead of raising ValueError. h_norm's exception path (โ†’ 0.0 โ†’ BAN) never fires; the total == 0 path returns NaN โ†’ PENDING. Fail-safe in direction (a degenerate can never PASS), but the gate's declared purpose โ€” rejecting degenerates โ€” silently rotted with a dependency behavior change. A degenerate candidate would idle as PENDING forever instead of being BANned.

DEFENSE (mechanism only; floor untouched)

+ if s.nunique() <= 1: return 0.0     # explicit degenerate short-circuit โ€” version-proof
+ if total == 0:       return 0.0     # all bins collapsed by duplicates="drop" โ€” degenerate mass
  (was: total == 0 โ†’ NaN)

Proof the defense closes the gap

CheckResult
Same attack re-run (full battery + universe scan)SURVIVES โ€” 0 breaches (constant column โ†’ 0.0 โ†’ BAN; sub-floor โ†’ NaN โ†’ PENDING; 160 battery checks exact; F4 still 0)
ยงB declaration self-test (includes hnorm_verdict anchors)PASS

Evidence

FileWhat
a10_hnorm_gate_attack.pyThe battery + universe scan โ€” falsifiers pre-declared in-file.
a10_results.jsonPost-fix run (0 breaches) + per-column h_min/h_median summary over 62 cells.
a10_stderr.log ยท a10_stderr_postfix.logPre-fix run (1 breach: F3_pointmass_not_banned, h_const=None) and post-fix run, both under the 2 CPU / 2 GB scope.
regression_tests/test_a10_hnorm_gate.shPermanent regression test โ€” re-runs the battery, asserts SURVIVES.

Consequence

Every stage of the ยงB cascade has now been attacked at least once. The 8th real defect of the campaign was library rot โ€” a dependency's silent behavior change breaking a documented contract โ€” a class no amount of initial code review catches, only re-attack. Clean rounds: reset to 0 of 3. The F4 sweep's clean result (no single-cell false-BAN candidates in the live universe) also pre-empts the would-be next attack on the unguarded h_norm vote.

iter 10 ยท h_norm gate battery ยท verdict BREAKS โ†’ DEFENDED โ†’ CLOSED ยท one atomic commit: iter 10: h_norm gate battery โ€” BREAKSโ†’DEFENDED ยท append-only.