ADR-0020 next-level: close the parity-gate hole on the four remaining
ungated Rust surfaces.
Gates landed (subprocess-based, raw f32/f64 byte equality):
cga_inner — 14/14 bit-identical (random + basis blades + self-norm)
geometric_product — 15/15 bit-identical (random + basis blades + scalar identity)
versor_condition — 9/9 bit-identical AFTER kernel fix
versor_apply — 8/8 intentionally skipped (see below)
Kernel fix: versor_condition_raw
The Python source-of-truth (algebra.versor.versor_unit_residual) folds
the geometric product + identity subtraction + Frobenius norm in f64.
The Rust kernel was folding in f32, drifting by 1 ULP on out-of-shell
inputs. Rewrote versor_condition_raw to promote inputs to f64, use the
existing geometric_product_f64/reverse_f64 building blocks, and cast
only the final scalar back to f32. Python is canonical per CLAUDE.md
sequencing rule 5.
Honest disable: versor_apply
The Rust versor_apply_closed diverges structurally:
(1) precision — f32 sandwich vs Python's f64 throughout
(2) closure form — Rust has a null-vector early branch + no
post-unitize condition recheck; Python is the
inverse (no null branch; recheck + seed-rotor
fallback)
Per ADR-0020 "default-off until parity passes", the Rust dispatch for
versor_apply is disabled in algebra/backend.py with a pointer to the
gate. The parity tests are skipped with explicit reason. The follow-up
f64 port is documented in the ADR's new Parity status table.
Lane registration: all four parity files added to --suite algebra.
After: algebra 124 passed, 8 skipped (was 86). All other lanes green:
smoke 54, runtime 19, cognition 57, teaching 17, packs 6. Cognition
eval 100%.