fix(classifier): clear #70 semantics debt (A5/A6/A8/A9; B3/B4 proposed) - #81
Conversation
A6: A1 -> family "none" (was F1 = gap-FAILURE); A1 is the no-failure case.
A8: F5 rule dimension-coherent + scale-invariant (pseudospectral REACH
radius/gap vs 2*gap_to_gns_ratio; L->cL no longer flips A10/F5).
A9: lep_proximity (D16) sees exact degeneracies (strongest EP signal ->
proximity 0, not inf); candidate loop consistent.
A5: removed unreachable/semantically-wrong EXCLUDED verdict (single-pass
best-class classifier cannot emit active rejection); low confidence ->
NOT_EXCLUDED. Verdict Literal narrows 5->4 (runtime output unchanged).
B3/B4 analysed but not wired (design decisions with FP risk) -- see PR body.
Tests: +A8 metamorphic rescale (c in 1e-3..1e3) + old-rule-flip regression,
+A9 exact/full/sub-atol degeneracy edges. Sacred anchor gate green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8e5e64db2e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| _psr_reach = ( | ||
| ev["pseudospectral_radius"] / _gap if _gap > 0.0 else float("inf") | ||
| ) | ||
| if _psr_reach > 2.0 * ev.get("gap_to_gns_ratio", 1.0) and ev["henrici_eta"] > 1.0: |
There was a problem hiding this comment.
Make the F5 non-normality gate scale-free
For the rescale scenario this change is meant to fix, the condition still gates on raw henrici_eta > 1.0. henrici_eta_n is the Frobenius norm of the Schur off-diagonal, so henrici_eta_n(cL) scales linearly with the time-unit rescale c; only the pseudospectral radius was normalized here. As a result, a strongly non-normal phantom system near this threshold can fall through to A1/A12 when expressed in slower units even though the physics is unchanged, and the new synthetic rescale tests miss it because they keep Henrici fixed by hand. Please normalize this non-normality signal or use a scale-free gate before claiming/reserving scale-invariant F5 classification.
Useful? React with 👍 / 👎.
| - **Classifier semantics debt cleared: A1 family, F5 dimensional coherence, | ||
| LEP degeneracy, dead EXCLUDED verdict** (issue #70, A5/A6/A8/A9). Four |
There was a problem hiding this comment.
Update CITATION for methodology changes
This entry changes result-facing methodology/semantics for the classifier (A1 family assignment, the F5 rule, and D16 degeneracy handling), but the commit leaves CITATION.cff untouched. The repo instructions in AGENTS.md require changes touching results or methodology to update CITATION.cff; otherwise the citable metadata still describes the previous public surface while labels/verdict evidence have changed. Please update the citation metadata or explicitly move non-methodology-only changes out of this PR.
Useful? React with 👍 / 👎.
#85) Completes the two sub-findings PR #81 left open (A5/A6/A8/A9 already on main). Both are behaviour-preserving: no real-input classification result changes; sacred anchors + V1-V5 golden classification stay byte-identical green. B3 -- reserved A-classes A6/A7/A9: taxonomy A1-A12-v3.1 advertises twelve classes but _pick_a_class emits only nine. A6/A7/A9 are now an explicit reserved contract in _consts.RESERVED_A_CLASSES (mirroring RESERVED_DIAGNOSTIC_ SLOTS D21-D23). A static-AST reachability test forces the contract to track the code, so a future wiring of A6/A7/A9 must update the reserved set in lock-step. B4 -- advisory (unused) evidence: lep_proximity (D16), bohr_ap_length (D11), mpemba_expansion_alpha (D20) are surfaced in evidence for audit but do NOT drive class/verdict/confidence. classification.ADVISORY_EVIDENCE_KEYS names the contract; a metamorphic test proves non-influence (perturbing each key across {0, +/-1e9, +/-inf, nan} leaves the decision invariant). Wiring any is a class-influencing, FP-risk design decision deferred to a dedicated PR. Verification (local, py3.12): anchors 19 passed/2 QuTiP-skipped; V1-V5 golden 32 passed; new debt suite 8 passed; full suite 471 passed/8 skipped; ruff clean; mypy 50 files clean. Closes #70 Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses #70 (A5/A6/A8/A9 fixed; B3/B4 analysed + proposed)
Dedicated classifier-semantics PR per AGENTS.md section 3 (physics rationale required).
DRAFT - merge decision is Marco/Vero's after verify. Runtime
diagnose()output is unchanged for all V1-V5 systems (golden-pinned); the changes correct
family labels, a dimensional-coherence bug, a degeneracy blind-spot, and a dead
verdict.
Baseline: main
fda7442f1013661c536c4a682eb1cd36a09f7bad(freshness-verified atclone:
git rev-parse HEAD==gh api .../heads/main). Depends-on #68/#69/#79which are already on main.
Findings - status per item
VERDICT_EXCLUDEDunreachable_types.py,_consts.py,classification.pyclassification.pyclassification.pylep_proximityblind to exact degeneraciesdiagnostics/lep.pyA6 - A1 maps to family
"none", notF1(fixed)Physics.
F1is the Mori-Shirai overlap gap-FAILURE mechanism (PRL 125,230604, 2020).
_consts.F_FAMILY_DESCRIPTIONS["none"]= "No gap-failuremechanism flagged". A1 = "Asymptotic-gap-controlled (primitive QMS)" is precisely
the case where the gap governs relaxation - the no-failure case. Labelling
the healthy gap-controlled result with a gap-FAILURE family is a category error.
A1 ->
"none"is the physically correct family.Change. All three
return "A1", "F1"in_pick_a_class->return "A1", "none".Consistency with #79:
tests/test_validation_systems/test_d17_gap_coherence.pytest_gap_controlled_reference_reaches_a1updated to assertf_family == "none"(a_class A1, verdict CONFIRMED, and the #69 D17 dimension-coherence logic are all
UNTOUCHED - only the family label).
Test evidence.
test_branch_a1_strong_gap_consistency,test_branch_a1_moderate_gap_consistency,test_a1_early_branch_reached_...pin A1/
"none"; the #79 adversarial phantom-shadow test still pins A10/F5.A8 - F5 phantom-relaxation rule is now dimension-coherent + scale-invariant (fixed)
Physics / bug. The old rule
pseudospectral_radius > 2.0 * gap_to_gns_ratiocompared a rate (D13 radius
max{|z| : z in sigma_eps(L)}, units of inversetime) against a dimensionless ratio (
Delta / Delta_s). Rescaling theLiouvillian
L -> cL- a pure change of the unit of time, physically identicaldynamics - scales the radius by
cbut leavesgap_to_gns_ratioinvariant, sothe A10/F5 verdict flipped with
c.Fix. Compare the dimensionless pseudospectral reach
radius / gap: howfar the eps-pseudospectrum extends relative to the asymptotic decay rate
DeltaBoth sides are now dimensionless;
radius/gapis scale-invariant to leadingorder (both scale as
c). A vanishing gap is treated as infinite reach (thegapless/critical phantom limit). Guarded
gap > 0.Metamorphic test evidence (
tests/test_classification.py):test_a8_f5_rule_is_scale_invariant_under_rescale[c]forc in {1e-3, 1e-2, 0.1, 1, 10, 1e3}- verdict stays A10/F5 (no flip).test_a8_old_bare_radius_rule_would_have_flipped_under_rescale- proves thepre-Classifier semantics debt: unreachable VERDICT_EXCLUDED and classes A6/A7/A9, A1→"F1" vs "none", scale-noninvariant F5 rule, unused LEP/D18/D11/D12/D20 evidence #70 bare-radius comparison would have dropped A10/F5 at
c=0.01on thesame physical system (load-bearing regression).
test_a8_f5_fires_on_gapless_strongly_nonnormal_operator- thegap == 0edge.test_phantom_with_gap_matched_rho0_is_not_mislabelled_a1(real solver)still classifies the strongly non-normal phantom ladder as A10/F5 under the new
rule; its precondition assertion updated to the normalized form.
A9 -
lep_proximity(D16) no longer blind to exact degeneracies (fixed)Physics / bug. A Liouvillian Exceptional Point is where two eigenvalues (and
their eigenvectors) coalesce, so eigenvalue separation
-> 0is the signature ofapproaching an EP and an exact degeneracy is the STRONGEST proximity
signal. The old min-sep scan had
if sep < min_sep and sep > atol, whichskipped every pair with
sep <= atol- discarding exactly that signal. Afully degenerate spectrum returned
inf("maximally FAR from an EP"), the exactinverse of the physics. The candidate-count loop used
10*min_sepwith nomatching filter (mutually inconsistent with the min-sep loop).
Fix. Keep all
i < jpairs; a closest separation at/belowatolis clampedto
0.0(coalesced = proximity 0). The candidate loop uses the same data and amax(10*min_sep, atol)window, so whenmin_sep == 0the window isatol(counts the coalesced cluster) - the two loops are now consistent. D16 measures
eigenvalue proximity only; genuine defective EP vs semisimple/symmetry-protected
degeneracy stays the Petermann-factor (D9) job, as before.
Test evidence (
tests/test_lep.py): exact-degenerate pair -> 0.0;fully-degenerate spectrum -> 0.0 (not inf); sub-atol -> clamped 0.0;
non-degenerate unchanged (min sep 1.0); candidate loop consistency
(
[-1,-1,-50] -> prox 0.0, count 1). Anchor I (conjugate pairs included) staysgreen.
A5 - unreachable
EXCLUDEDverdict removed (fixed)Analysis. The confidence values
diagnose()can produce are{0.95, 0.85, 0.70, 0.50, 0.20}. The only sub-0.30 value (A12 = 0.20)short-circuits to
NOT_EXCLUDEDbefore the threshold check, soconfidence < 0.30 -> EXCLUDEDwas never reached (CHANGELOG v0.4.1 alreadyflagged this). More fundamentally it is semantically inexpressible here: a
single-pass, maximum-evidence classifier reports the best-fit A-class with its
support - it never reports a class it is simultaneously ruling out. A per-class
"actively excluded" verdict needs a per-hypothesis scoring architecture. The old
branch was also wrong: low confidence in the best-fit class is epistemic
uncertainty ("unresolved" =
NOT_EXCLUDED), not positive counter-evidence.Chosen resolution (physically motivated): remove.
"EXCLUDED"dropped fromthe
VerdictLiteral and_consts.VERDICT_EXCLUDED; the dead branch removed solow confidence correctly yields
NOT_EXCLUDED.API note:
Verdictnarrows from 5 to 4 members - a type-surface narrowingonly; runtime
diagnose()output is unchanged (it never emittedEXCLUDED).VERDICT_EXCLUDEDis not in the publicliouscope.__init____all__.Test evidence.
test_pick_verdict_tier_thresholdsnow pins conf0.20and0.0->NOT_EXCLUDED(the corrected semantics).B3 - classes A6/A7/A9 unreachable (analysed; NOT wired - decision to Marco/Vero)
_pick_a_classreturns 9 of 12 classes; A6 (accelerated-decay /operator-spreading), A7 (weak-dissipation singular, Mori 2024), A9
(prethermalization / ETH) are never emitted. Why: the heuristic tree has no
branch mapping evidence to them, and A7/A9 would require diagnostics that do not
exist yet (A7 needs a dissipation-strength / singular-perturbation detector; A9
needs ETH/level-statistics signals; both overlap A5 metastable). Proposal:
either (a) implement per-class branches in dedicated PRs with anchor coverage
and false-positive tests (A6 is the most tractable: accelerated decay ~
beta_D_linear >> gap), or (b) mark A6/A7/A9 as a discoverable"reserved / not-yet-reachable" code-level contract analogous to the existing
RESERVED_DIAGNOSTIC_SLOTS(D21-D23) so the taxonomy-vs-classifier gap ishonest. Not decided here to avoid guessing; recommend a follow-up issue.
B4 - gathered evidence unused (analysed; NOT wired - FP risk, decision to Marco/Vero)
lep_proximity(D16),lep_candidate_count, D18initial_state_sensitivity,D11
bohr_ap_length, D12ridge_fwhm, D20mpemba_expansion_alphado notinfluence class/verdict. Wiring any of them is a class/verdict-influencing
design decision that can introduce false positives, so per the issue this PR
does not blind-wire them. Safest proposed design (fail-safe first):
initial-state sensitivity means the observed single-exp-at-gap may be an
artifact of the chosen
rho_0; capping A1 confidence can only lower a claim,so it cannot create a false positive. (Needs a check that it does not regress
the fix: make D17 gap-rate consistency dimension-coherent (#69) #79 gap-controlled reference, which expects A1 CONFIRMED - hence a
dedicated PR.)
D11 -> A8 (almost-periodic/oscillatory), D12 -> A2/F3 (gap-corrective
scale) - each a confidence modifier on an already-picked class, never a new
trigger.
Recommend a dedicated PR per wiring with anchor coverage + FP tests. Follow-up
issue suggested.
Verification (local, CI-parity;
py= Python on this Windows box)All exit 0, output observed (QuTiP not installable locally -> its cross-checks
skip; CI runs them):
ruff check src tests benchmarksmypy src/liouscopepytest tests/test_anchors.pypytest --cov=liouscope --cov-fail-under=80.github/scripts/check_workflow_hardening.py.github/scripts/check_claim_safety.pyTest plan checklist
pytest -qclean (456 passed / 8 QuTiP-skipped)pytest tests/test_anchors.py(sacred gate) greenruff check src tests benchmarksexit 0mypy src/liouscopeexit 0CHANGELOG.mdupdated (Classifier semantics debt: unreachable VERDICT_EXCLUDED and classes A6/A7/A9, A1→"F1" vs "none", scale-noninvariant F5 rule, unused LEP/D18/D11/D12/D20 evidence #70 A5/A6/A8/A9 entry + corrected the D17 gap-rate consistency compares a relative-entropy rate (~2Δ) to Δ — the A1 "gap-controlled" label is effectively unreachable #69 "(F1)" reference)No methodology/results or manifest-contract change ->
CITATION.cff/MANIFEST_SCHEMA.jsonuntouched. Not a history-touching op (new branch push).Open questions routed to Vero/Marco
EXCLUDED(chosen) vs implement aper-hypothesis active-exclusion mode. Removal narrows the public
Verdicttype.wiring in a dedicated PR, or leave all evidence advisory-only?
Generated with Claude Code (Codie / Coworkerz agent).
Verify-Nachtrag (Vero, 2026-07-04 — Equalita PASS 8/8 + Cross-Family gpt-5.5 GOOD)
A8-Caveat (ehrlich): Die
radius/gap-Regel ist nur leading-order skalen-invariant, nicht exakt. Bei festem ε=1e-3 (D13) driftet realesradius/gapempirisch ~2.549→2.0 über c∈[1e-3,1e3] (~27%/6 Dekaden), weilsigma_eps(cL)=c·sigma_{eps/c}(L). Der Code-Kommentar sagt korrekt "to leading order"; Test-Name/Commit sind schärfer formuliert als belegt → als Residual getrackt (Follow-up-Issue), kein Korrektheits-Regress (neue Regel strikt besser als alte bare-radius-Regel). Ebenfalls getrackt: pre-existing NaN-Silent-Failure inlep_proximity.Merge-Status: Equalita = Fakten PASS (Sacred-Gate grün, kein eingeführter Klassifikations-FP, 456 passed/cov 94.46%). Cross-Family = GOOD (gas +1). Offene Design-Urteile (A6-Taxonomie, A8-Schwelle, A9-Konvention, A5-API-Break) + Merge = Marco-Gate.