#!/usr/bin/env python3 # -*- coding: utf-8 -*- """test_spectrum.py -- consolidated REAL-ENGINE verification suite. SAFE WORDING (binding, repeated in every engine + report): This suite verifies that every observed particle is quantum-number- consistent with its geometry-derived constituents and that the parameter-free QCD symmetry relations hold against PDG-2024; it does NOT compute or claim absolute hadron masses from geometry. This module is the single mandated test file. It runs the THREE real engines (qn_check.py, mass_relations.py, coverage_check.py) against the REAL PDG-2024 ./data and asserts on their real output values / bytes / exit codes. Nothing here is a trivially-true stub: every assertion is downstream of an actual engine call (in-process function or subprocess CLI). GOVERNANCE (PM-AGENT, adopted): * RUNNABLE-FIRST -- bare Python 3, stdlib only (csv, json, shutil, subprocess, sys, fractions, pathlib) plus pytest as the runner. Zero pip-installed runtime deps in the engines themselves. * FAIL-CLOSED -- a quantum-number inconsistency, a missing required field, or a RELATION residual beyond its declared tolerance must make the engine FAIL and exit non-zero. The headline guard `test_qn_broken_charge_row_*` feeds a row whose stated charge != sum of its constituents and asserts the real engine exits non-zero. * CITE EVERY CONSTANT -- the GMO/decuplet tolerances asserted here are read from relations_config.json (not hard-coded); the PDG numbers come from the aux CSVs, each carrying its own pdg_source. * TESTS MANDATORY + REAL -- pytest actually runs the engines. Three coverage areas (one section each), as mandated: (1) qn_check -- Q/B/S/C/B' derived from constituents + a deliberately broken charge row that MUST fail closed (exit != 0). (2) mass_relations -- the GMO octet residual AND the decuplet equal-spacing residual hold within their DECLARED tolerances, computed by the real engine from the REAL PDG-2024 masses. (3) coverage -- total covered == dataset row count, and 0 orphans, computed by the real coverage engine on the real data. Run: python -m pytest tests/test_spectrum.py -q (from .) """ from __future__ import annotations import csv import json import shutil import subprocess import sys from fractions import Fraction from pathlib import Path import pytest # --------------------------------------------------------------------------- # # Make the three engines importable regardless of the working directory. # # --------------------------------------------------------------------------- # HERE = Path(__file__).resolve().parent ROOT = HERE.parent if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) import qn_check as qn # noqa: E402 quantum-number engine import mass_relations as mr # noqa: E402 parameter-free RELATION engine import coverage_check as cc # noqa: E402 completeness engine DATA = ROOT / "data" CONFIG = ROOT / "relations_config.json" SECTIONS = Path("/sections") FOUNDATION = Path("/foundation") SAFE_WORDING_FRAGMENT = "does NOT compute or claim absolute hadron masses" # --------------------------------------------------------------------------- # # Helpers. # # --------------------------------------------------------------------------- # def _qn_row(**ov) -> dict: """A minimally-valid qn_check dataset row (proton by default).""" base = dict.fromkeys(qn.SCHEMA, "") base.update({ "pdg_name": "p", "quark_content": "uud", "charge_Q": "1", "J": "1/2", "P": "+", "isospin_I": "1/2", "I3": "1/2", "baryon_B": "1", "strangeness_S": "0", "charm_C": "0", "bottom_Bprime": "0", "mass_MeV": "938.272", "mass_unc_MeV": "0.0001", "status_stars": "4", "sector": "test", "chunk": "T", "pdg_source": "PDG 2024 unit-test row", }) base.update(ov) return base def _declared_tol(name: str) -> float: """Read a DECLARED tolerance straight out of relations_config.json (no magic numbers in the test).""" cfg = json.loads(CONFIG.read_text(encoding="utf-8")) return float(cfg["tolerances"][name]["value"]) def _dataset_row_count(data_dir: Path) -> int: """Ground-truth dataset row count straight from the CSV bytes (independent of the engine), so the coverage total can be cross-checked against it.""" total = 0 for csv_path in sorted(data_dir.glob("dataset_*.csv")): with csv_path.open("r", encoding="utf-8", newline="") as fh: total += sum(1 for _ in csv.DictReader(fh)) return total # =========================================================================== # # (1) qn_check -- quantum-number consistency. # # =========================================================================== # def test_qn_proton_derivation_real_engine(): """The real flavour algebra derives Q=+1, B=1, S=0 for uud.""" c = qn.parse_quark_content("uud") d = qn.derive_quantum_numbers(c, Fraction(1)) assert d["charge_Q"] == Fraction(1) assert d["baryon_B"] == Fraction(1) assert d["strangeness_S"] == 0 assert d["color_singlet"] is True def test_qn_omega_minus_sss_real_engine(): """sss => Q=-1, S=-3, B=1 (decuplet apex).""" d = qn.derive_quantum_numbers(qn.parse_quark_content("sss"), Fraction(-1)) assert d["charge_Q"] == Fraction(-1) assert d["strangeness_S"] == -3 assert d["baryon_B"] == Fraction(1) def test_qn_good_proton_row_passes(): """A consistent proton row passes the real per-row verifier.""" assert qn.verify_row(_qn_row()).passed is True def test_qn_broken_charge_row_fails_closed_unit(): """DELIBERATELY-BROKEN row: stated charge 2 != sum of uud constituent charges (1). The real per-row verifier MUST flag it (fail-closed).""" r = qn.verify_row(_qn_row(pdg_name="DELIBERATELY_BROKEN", quark_content="uud", charge_Q="2")) assert r.passed is False assert "charge_Q" in [f["field"] for f in r.failures] detail = " ".join(f["detail"] for f in r.failures).lower() assert "charge" in detail def test_qn_broken_charge_row_makes_engine_exit_nonzero(tmp_path): """END-TO-END, MANDATORY: copy the real data, inject ONE row whose stated charge != sum of constituents, run the qn_check.py engine as a real process, and assert it EXITS NON-ZERO and names the broken particle. This is the deliberately-broken row that must make the engine fail closed.""" data = tmp_path / "data" shutil.copytree(DATA, data) bad = data / "dataset_INJECTED_BROKEN.csv" header = ",".join(qn.SCHEMA) # 'uud' sums to charge +1; we lie and claim charge 7 => MUST fail closed. row = ("DELIBERATELY_BROKEN,uud,7,1/2,+,,1/2,1/2,1,0,0,0,938.272,0.0001,4," "test_injected,T,unit-test-broken") bad.write_text(header + "\n" + row + "\n", encoding="utf-8") out = tmp_path / "out" proc = subprocess.run( [sys.executable, str(ROOT / "qn_check.py"), "--data", str(data), "--out", str(out)], capture_output=True, text=True, ) assert proc.returncode != 0, ( "qn_check MUST fail closed on a charge!=sum-of-constituents row\n" + proc.stdout + proc.stderr) report = json.loads((out / "qn_report.json").read_text(encoding="utf-8")) assert report["overall_pass"] is False names = {f["pdg_name"] for f in report["quantum_number_failures"]} assert "DELIBERATELY_BROKEN" in names def test_qn_engine_passes_on_real_data_and_exits_zero(tmp_path): """The real qn_check.py engine passes on the unmodified PDG-2024 data and exits 0; the report carries the verbatim safe-wording scope statement.""" out = tmp_path / "out" proc = subprocess.run( [sys.executable, str(ROOT / "qn_check.py"), "--data", str(DATA), "--out", str(out)], capture_output=True, text=True, ) assert proc.returncode == 0, proc.stdout + proc.stderr report = json.loads((out / "qn_report.json").read_text(encoding="utf-8")) assert report["overall_pass"] is True assert report["particles_failed"] == 0 assert report["relations_failed"] == 0 assert report["total_particles"] > 400 assert SAFE_WORDING_FRAGMENT in report["scope_statement"] # =========================================================================== # # (2) mass_relations -- GMO octet + decuplet equal-spacing within tolerance. # # Computed by the real engine from the REAL PDG-2024 masses. # # =========================================================================== # def test_relations_gmo_octet_holds_within_declared_tolerance(): """REAL engine, REAL PDG-2024 octet masses: the Gell-Mann-Okubo relation 2(m_N+m_Xi) = 3 m_Lambda + m_Sigma holds within its DECLARED tolerance.""" cfg = mr.load_config(CONFIG) octet = mr.load_csv(DATA / "baryon_octet.csv") r = mr.relation_gmo_octet(octet, cfg) tol = _declared_tol("gmo_octet_rel_tol") # PDG-2024 isospin averages: LHS ~ 4514.41 MeV, RHS ~ 4540.20 MeV. assert r.observed == pytest.approx(4514.4075, abs=0.05) # LHS = 2(m_N+m_Xi) assert r.predicted == pytest.approx(4540.2027, abs=0.05) # RHS = 3 Lambda+Sigma # Residual is real, positive, sub-percent, and WITHIN the declared bound. assert r.residual == pytest.approx(0.005698, abs=1e-4) assert 0.0 < r.residual <= tol assert r.passed is True assert r.grade == "RELATION" def test_relations_decuplet_equal_spacing_holds_within_declared_tolerance(): """REAL engine, REAL PDG-2024 decuplet masses: the equal-spacing rule (Sigma*-Delta == Xi*-Sigma* == Omega-Xi*) holds within its DECLARED tolerance. Asserts the actual MeV steps and the max relative deviation.""" cfg = mr.load_config(CONFIG) dec = mr.load_csv(DATA / "baryon_decuplet.csv") r = mr.relation_decuplet_equal_spacing(dec, cfg) tol = _declared_tol("decuplet_equal_spacing_rel_tol") steps = r.observed # [Sigma*-Delta, Xi*-Sigma*, Omega-Xi*] in MeV assert steps[0] == pytest.approx(151.93, abs=0.05) assert steps[1] == pytest.approx(148.97, abs=0.05) assert steps[2] == pytest.approx(140.65, abs=0.05) assert r.predicted == pytest.approx(147.18, abs=0.05) # mean step # Max deviation from the mean step ~4.4%, WITHIN the declared 10% bound. assert r.residual == pytest.approx(0.04439, abs=2e-3) assert 0.0 < r.residual <= tol assert r.passed is True def test_relations_engine_exits_zero_on_real_data(tmp_path): """The whole RELATION engine runs green on the real data, the QN gate passes, and GMO(R1)+decuplet(R2) both PASS in the emitted report bytes.""" out = tmp_path / "out" rc = mr.main([ "--data", str(DATA), "--out", str(out), "--config", str(CONFIG), ]) assert rc == 0, "the parameter-free RELATION suite must pass on PDG-2024 data" rep = json.loads((out / "relations_report.json").read_text(encoding="utf-8")) assert rep["overall_pass"] is True assert rep["quantum_number_gate"]["passed"] is True assert rep["totals"]["relations_failed"] == 0 by_id = {r["relation_id"]: r for r in rep["relations"]} assert by_id["R1"]["passed"] is True # GMO octet assert by_id["R2"]["passed"] is True # decuplet equal-spacing md = (out / "relations_report.md").read_text(encoding="utf-8") assert SAFE_WORDING_FRAGMENT in md def test_relations_decuplet_residual_beyond_tolerance_fails_closed(tmp_path): """FAIL-CLOSED proof for the RELATION gate: corrupt the Omega- mass so the equal-spacing residual blows past its declared tolerance; the QN gate stays green (charges still consistent) but R2 -- and the whole engine -- fails.""" box = tmp_path shutil.copytree(DATA, box / "data") shutil.copy(CONFIG, box / "relations_config.json") dec_path = box / "data" / "baryon_decuplet.csv" with dec_path.open("r", encoding="utf-8-sig", newline="") as fh: reader = csv.DictReader(fh) fields = reader.fieldnames rows = list(reader) for row in rows: if row["particle"] == "Omega-": row["mass_MeV"] = "2200.0" # absurd: step ~668 MeV vs ~150 MeV with dec_path.open("w", encoding="utf-8", newline="") as fh: w = csv.DictWriter(fh, fieldnames=fields) w.writeheader() w.writerows(rows) rc = mr.main([ "--data", str(box / "data"), "--out", str(box / "out"), "--config", str(box / "relations_config.json"), ]) assert rc == 1, "an equal-spacing residual beyond tolerance MUST fail closed" rep = json.loads((box / "out" / "relations_report.json").read_text(encoding="utf-8")) assert rep["quantum_number_gate"]["passed"] is True # QN gate unaffected r2 = next(r for r in rep["relations"] if r["relation_id"] == "R2") assert r2["passed"] is False assert r2["residual"] > _declared_tol("decuplet_equal_spacing_rel_tol") assert rep["overall_pass"] is False # =========================================================================== # # (3) coverage -- total covered == dataset row count, and 0 orphans. # # Computed by the real coverage engine on the real data. # # =========================================================================== # @pytest.fixture(scope="module") def real_coverage(): """Run the real coverage engine ONCE against the real data/sections. Skips (rather than silently passing) only if the section/foundation inputs are absent on this box -- absence is never treated as a pass-maker.""" if not SECTIONS.is_dir() or not FOUNDATION.is_dir(): pytest.skip(f"section/foundation inputs not present: {SECTIONS}") if not list(DATA.glob("dataset_*.csv")): pytest.skip("no dataset_*.csv present") return cc.run_coverage(DATA, SECTIONS, FOUNDATION) def test_coverage_total_equals_dataset_row_count(real_coverage): """MANDATORY: the coverage engine's covered total equals the actual number of dataset rows (every row is accounted, none dropped or double-counted).""" expected = _dataset_row_count(DATA) assert expected > 400, "sanity: the live dataset has hundreds of rows" assert real_coverage.total_particles == expected, ( f"coverage total {real_coverage.total_particles} != dataset row count " f"{expected}") def test_coverage_zero_orphans(real_coverage): """MANDATORY: every dataset row has a section home -- 0 orphans in the data->section direction (no row with an empty/unknown/home-less chunk).""" assert real_coverage.orphan_data_rows == [], ( "every dataset row must map to one of the 51 accounting sections; " f"orphans={real_coverage.orphan_data_rows[:3]}") def test_coverage_passes_clean_on_real_data(real_coverage): """The live, reconciled dataset must PASS coverage cleanly (genuine green): 0 hard errors, 0 orphans, 0 sector/chunk contradictions, 0 missing sections, and 0 per-chunk count mismatches against the AUTHORITATIVE (reconciled) counts.""" assert real_coverage.hard_errors == [], real_coverage.hard_errors[:3] assert real_coverage.sector_chunk_contradictions == [] assert real_coverage.empty_sections == [] assert real_coverage.chunk_count_mismatches == [], ( "every per-chunk dataset count must reconcile with the authoritative count; " f"mismatches={real_coverage.chunk_count_mismatches}") assert real_coverage.passed is True # the six documented Wave-0 estimate corrections are recorded (auditable, not silent) assert set(real_coverage.reconciled_count_overrides) == { "LM-9", "HB-1", "HB-2", "HB-3", "BB-2", "BB-3"} def test_coverage_unknown_chunk_is_orphan_and_exits_nonzero(tmp_path): """FAIL-CLOSED proof for the coverage engine: a row whose chunk is NOT one of the 51 sections MUST be reported as an orphan and make the CLI exit non-zero. Built by copying the real data and appending one ghost row.""" data = tmp_path / "data" shutil.copytree(DATA, data) cols = cc.REQUIRED_COLUMNS ghost = {c: "" for c in cols} ghost.update({ "pdg_name": "ZZ_ghost_particle", "quark_content": "uud", "charge_Q": "1", "baryon_B": "1", "strangeness_S": "0", "charm_C": "0", "bottom_Bprime": "0", "mass_MeV": "938.0", "mass_unc_MeV": "0.0", "status_stars": "4", "sector": "light_mesons", "chunk": "ZZ-99", "pdg_source": "synthetic broken row", }) shard = data / "dataset_light_mesons.csv" with shard.open("a", encoding="utf-8", newline="") as fh: csv.DictWriter(fh, fieldnames=cols).writerow({c: ghost[c] for c in cols}) if not SECTIONS.is_dir() or not FOUNDATION.is_dir(): pytest.skip(f"section/foundation inputs not present: {SECTIONS}") res = cc.run_coverage(data, SECTIONS, FOUNDATION) assert res.passed is False assert any(o["chunk"] == "ZZ-99" for o in res.orphan_data_rows) out = tmp_path / "out" proc = subprocess.run( [sys.executable, str(ROOT / "coverage_check.py"), "--data", str(data), "--sections", str(SECTIONS), "--foundation", str(FOUNDATION), "--out", str(out)], capture_output=True, text=True, ) assert proc.returncode != 0, "an orphan row MUST make coverage_check exit non-zero" rep = json.loads((out / "coverage_report.json").read_text(encoding="utf-8")) assert rep["result"] == "FAIL" assert any(o["chunk"] == "ZZ-99" for o in rep["orphans_dataset_no_section_home"]) assert SAFE_WORDING_FRAGMENT in rep["safe_wording"] if __name__ == "__main__": sys.exit(pytest.main([__file__, "-q"]))