You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a040d48
Browse filesBrowse the repository at this point in the historyBrowse files
Addresses all three findings from the #889 review (4856837957) and the #888
post-merge note (5181899915). Each was reproduced before fixing.
P1 — omega was still UNIT-DEPENDENT. Four absolute floors survived in
omega_total: `.max(1.0)` in the lambda^2 guard, the psi guard, and both sign
cutoffs. Below unit variance those degrade to an absolute 1e-9, so on data
whose covariances are ~1e-16 every tolerance is enormous, every sign
comparison vacuous, and (measured) omega flips 0.25 -> 0.75 purely by
rescaling. All four removed; tolerances are now relative to the item's own
variance, and covariance cutoffs to sqrt(var_i * var_j).
This is the SAME defect class as the R-squared absolute pivot fixed two
commits earlier. I fixed the instance and left the class — the floors were in
the function I was actively editing.
Constant items (zero variance) are now rejected explicitly: they carry no
signal, leave the model unidentified, and would make every scale-relative
tolerance degenerate.
P1 — the regressions blessed the old wrong answer. The zero-loading test
asserted only `(0.0..=1.0).contains(&w)`, which 0.75 also satisfies, so it
proved "did not reject" rather than "computed the signed omega". Worse, the
invariance tests compared against a SELF-COMPUTED baseline, so a consistently
wrong implementation would satisfy them at every scale and permutation.
Both absolute values are now pinned as constants derived by hand:
ZERO_ANCHOR_OMEGA = 0.25 (lambda = [0,+1,-1,+1], psi = [V,0,V,V])
CONGENERIC_OMEGA = 18/19 (exact rational; the 8-digit decimal is
1.05e-9 off and a 1e-9 invariance
tolerance correctly rejects it)
and the rescale/permutation tests assert against those, not against
themselves. Invariance alone never pins a value.
P2 — the "independent" frustration oracle mirrored the implementation. It
reconstructed signs from each anchor row and looked for conflicts, which is an
anchor-shaped decision procedure, not the specification. Replaced with the
literal predicate: fix the free global sign and enumerate all 2^(k-1) = 8
assignments, asserting NONE satisfies every materially non-zero covariance
edge, plus an anti-vacuity assert that the sign graph carries >= 4 material
edges.
Also removed (review): the global-observation-sign-flip test. Negating every
item leaves the covariance matrix bit-identical, and omega_total consumes only
that matrix, so the assertion could not fail for ANY implementation — the
workspace's own "assertion implied by the code it tests". Replaced by common
rescaling, item permutation (including rotations that move the zero-loading
item into index 0), and a single-item flip that must CHANGE omega.
118 lib + 13 doctests green; stats.rs clippy-clean.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01K3RyLEbuNSHxxB3NTTrGki
0 commit comments