"""p28_flavour — the ledger file of 28-flavour (the 28-flavour migration, 17 October 2026).

"Fermion Flavour Sector over Finite Relational Substrate" (Akhtman and Voether, preprint 2026; doi 10.20944/preprints202606.2124.v1).
The paper's predicate ledger is docs/28-flavour/28-flavour-ledger.json. This file binds its python-witnessed predicates to
the framework: the table of keys (generated from the ledger by ci/make_ledgers.py) and the checks of eight blocks. The
exact checks call the flavour theme (frc/flavour.py) over the interactions theme (frc/interactions.py, the sixteen) and
the horizon theme (frc/ladder.py, the closed role ladder); the continuum readings call the chart theme (frc/chart.py,
frc/chart_fields.py, frc/chart_flavour.py) and compare its readings with rational bounds. Each check names the
predicate(s) it witnesses (LEDGER) and carries a `# 28:XN (<key>)` marker when it decides one (PREDICATES).

The checks are EXACT or CHART, one kind per check. An EXACT check decides by integer, finite-field, rational or
cyclotomic arithmetic: the shells F_p and their extensions F_{p²} at p ≡ 5 (mod 12) (p = 17, 53, 89 and the laboratory
Carrier 2 408 561), the field Q(ω), the rationals; no float decides anything. A CHART check is a continuum reading of the
measured masses, mixings and splittings, every float converted exactly before the comparison; its label carries
"[chart]". The paper's own classes were EXACT, MIXED and APPROX, one per package record (src/28-flavour, sixteen scripts
run by flvcommon.py); FAMILY names the package record (flv.<script>) each check reproduces. The package stays the paper's
published witness until its release pins the framework (decision Q06).

The Lean side: the theorems of the flavour theme (lean/FrcCore/Theme/Flavour.lean) and the interactions theme's Koide form
(Theme/Interactions.lean), the chart readings on Mathlib (lean/FrcLedger/Theme/Flavour.lean); the keys in
Keys/Flavour.lean (core) and Keys/Chart.lean (Mathlib), the certificates Ledgers/P28Flavour.lean.

No numeral above Ω is formed: the one reading that names the Carrier's size (Z4's hierarchy α(m_P/m_p)² ≈ 10³⁶) is a ratio
of measured constants.

    python3 -m frc.ledgers.p28_flavour         every block, the census; exit 1 if a check fails (≈ 5 s)
    python3 -m frc.ledgers.p28_flavour C       one block (A to Z)
    from frc.ledgers.p28_flavour import R; R.predicate("28:C2")    one predicate: its blocks run once per session

Blocks:  A  the circulant and the Koide form: the eigenvalues, Q = 2/3, the quarter-turn boundary       (28:C1, C2, C3, X1, X7)
         B  the amplitudes: the norms 2 and 3, the colour count, the lock relations                     (28:C4, C5, X2, X5, P2)
         C  the texture: Gatto, the role depths, the lopsided transpose                                (28:C6, C7, C8, X3, X4, X6, X8, P3)
         D  the mixing: the reactor estimate, the protected column, the magic matrix, the TM2 relation  (28:C9, C10, X9, X10, P8)
         E  the seesaw of circulants and the signed amplitudes                                         (28:C11, C11b, X11, P5, Z2)
         F  the sixteen and the measured Koide value                                                   (28:C12, P1, X1)
         H  the neutrinos: the floor, the two orderings, the Majorana band                             (28:P5, P6, P7, X11)
         Z  the Ω-hard readings: the phase δ₀, the scales, the fine-structure anchor                    (28:Z1, Z3, Z4)

Checks: 31, of them 13 EXACT and 18 CHART (A3c, B1c, B2c, B3c, C1c, C2c, C3c, D1, D2c, E2c, F2, H1, H2, H3, Z1, Z3, Z4,
Z4b). The notebook frc/ledgers/p28_flavour.ipynb runs one predicate per cell, the cell's id its key (gate G13).
"""
import random
import sys
from fractions import Fraction as Q
from math import isqrt

from frc.registry import Registry
from frc import arith
from frc import flavour as FL
from frc import interactions as I
from frc import ladder as LD
from frc import chart as CH
from frc import chart_fields as CF
from frc import chart_flavour as CFL

# ---- generated by ci/make_ledgers.py from docs/28-flavour/28-flavour-ledger.json; edit the ledger, not this table ----
PAPER = "28-flavour"
KEYS = {"A1": "p28001", "A2": "p28002", "A3": "p28003", "A4": "p28004", "A5": "p28005", "A6": "p28006", "B1": "p28007", "B2": "p28008", "B3": "p28009", "B4": "p28010", "B5": "p28011", "B6": "p28051", "C1": "p28012", "C2": "p28013", "C3": "p28014", "C4": "p28015", "C5": "p28016", "C6": "p28017", "C7": "p28018", "C8": "p28019", "C9": "p28020", "C10": "p28021", "C11": "p28022", "C11b": "p28050", "C12": "p28024", "X1": "p28025", "X2": "p28026", "X3": "p28027", "X4": "p28028", "X5": "p28029", "X6": "p28030", "X7": "p28031", "X8": "p28032", "X9": "p28033", "X10": "p28034", "X11": "p28035", "P1": "p28036", "P2": "p28037", "P3": "p28038", "P5": "p28039", "P6": "p28040", "P7": "p28041", "P8": "p28042", "V1": "p28043", "V2": "p28044", "Z1": "p28046", "Z2": "p28047", "Z3": "p28048", "Z4": "p28049", "Y1": "p28052"}       # every row of the ledger: its label and its accession key
LEAN = {"C1": "core", "C2": "core", "C3": "core, ml", "C4": "core, ml", "C5": "core", "C6": "core, ml", "C7": "core, ml", "C8": "core", "C9": "ml", "C10": "core, ml", "C11": "core", "C11b": "core", "C12": "core", "X1": "core, ml", "X2": "core, ml", "X3": "core, ml", "X4": "core, ml", "X5": "core, ml", "X6": "core, ml", "X7": "core, ml", "X8": "core", "X9": "ml", "X10": "core, ml", "X11": "core, ml", "P1": "core, ml", "P2": "core, ml", "P3": "core, ml", "P5": "core, ml", "P6": "ml", "P7": "ml", "P8": "core, ml"}       # the rows with a Lean declaration: the libraries whose key files prove them
# ---- end of the generated table ----

LEAN_ONLY = ()                  # the predicates with a Lean declaration and no python check (gate G12): none

# The paper's predicate ledger (predicates cited as 28:XN): the predicate(s) each check witnesses.
LEDGER = {
    "A1": "28:C1, 28:C2, 28:Z1", "A2": "28:C2, 28:X1", "A3": "28:C3, 28:X7, 28:C1", "A3c": "28:C3, 28:X7",
    "B1": "28:C4, 28:X2, 28:P2", "B1c": "28:C4, 28:X2, 28:P2", "B2": "28:X5", "B2c": "28:X5", "B3": "28:C5", "B3c": "28:C5, 28:Z1",
    "C1": "28:C6, 28:X4", "C1c": "28:P3, 28:C6, 28:X4, 28:Z1", "C2": "28:C7, 28:X6, 28:X3", "C2c": "28:C7, 28:X6, 28:X3",
    "C3": "28:C8, 28:X8", "C3c": "28:C8, 28:X8",
    "D1": "28:C9, 28:X9", "D2": "28:C10, 28:X10, 28:P8", "D2c": "28:C10, 28:P8, 28:X10",
    "E1": "28:C11, 28:X11", "E2": "28:C11b", "E2c": "28:C11b, 28:P5, 28:X11, 28:Z2",
    "F1": "28:C12", "F2": "28:P1, 28:X1",
    "H1": "28:P6, 28:P5, 28:X11", "H2": "28:P5, 28:X11, 28:Z2", "H3": "28:P7",
    "Z1": "28:Z1", "Z3": "28:Z3", "Z4": "28:Z4", "Z4b": "28:Z4",
}

# the package record (flv.<script>) each check reproduces (a chart check with the suffix c reproduces its parent's record)
FAMILY = {
    "A1": "exact_core", "A2": "framed_koide", "A3": "m10", "A3c": "m10",
    "B1": "quark_amp", "B1c": "quark_amp", "B2": "tier_b", "B2c": "tier_b", "B3": "delta", "B3c": "delta",
    "C1": "spurion", "C1c": "spurion", "C2": "up_doubling", "C2c": "up_doubling", "C3": "tier_b", "C3c": "tier_b",
    "D1": "theta13", "D2": "pmns_cp", "D2c": "tm2_jointfit",
    "E1": "neutrino", "E2": "revision_checks", "E2c": "neutrino",
    "F1": "exact_core", "F2": "tier_b",
    "H1": "neutrino", "H2": "neutrino", "H3": "neutrino",
    "Z1": "revision_checks", "Z3": "scale_a", "Z4": "coupling_anchor", "Z4b": "alpha_probe",
}

BLOCK = {"A": "the circulant and the Koide form: the eigenvalues, Q = 2/3, the quarter-turn boundary",
         "B": "the amplitudes: the norms 2 and 3, the colour count, the lock relations",
         "C": "the texture: Gatto, the role depths, the lopsided transpose",
         "D": "the mixing: the reactor estimate, the protected column, the magic matrix, the TM2 relation",
         "E": "the seesaw of circulants and the signed amplitudes",
         "F": "the sixteen and the measured Koide value",
         "H": "the neutrinos: the floor, the two orderings, the Majorana band",
         "Z": "the Ω-hard readings: the phase δ₀, the scales, the fine-structure anchor"}

# the deciding check of each witnessed predicate (the other checks that touch it are corroboration)
PREDICATES = {
    "28:C1": "A1", "28:C2": "A2", "28:C3": "A3", "28:C4": "B1", "28:C5": "B3", "28:C6": "C1", "28:C7": "C2", "28:C8": "C3",
    "28:C9": "D1", "28:C10": "D2", "28:C11": "E1", "28:C11b": "E2", "28:C12": "F1",
    "28:X1": "A2", "28:X2": "B1", "28:X3": "C2", "28:X4": "C1", "28:X5": "B2", "28:X6": "C2", "28:X7": "A3", "28:X8": "C3",
    "28:X9": "D1", "28:X10": "D2", "28:X11": "E1",
    "28:P1": "F2", "28:P2": "B1", "28:P3": "C1c", "28:P5": "H2", "28:P6": "H1", "28:P7": "H3", "28:P8": "D2",
    "28:Z1": "Z1", "28:Z2": "H2", "28:Z3": "Z3", "28:Z4": "Z4",
}

R = Registry("28", "flavour", LEDGER, PREDICATES, sources=[__file__])

SHELLS = (17, 53, 89)                                   # the paper's shells p ≡ 5 (mod 12)
CARRIER = 2408561                                       # the laboratory Carrier of 37-sim, ≡ 5 (mod 12)
RNG = random.Random(28)


def _within(x, centre, tol):
    """|x − centre| < tol, x a float of the chart converted exactly."""
    return abs(Q(x) - Q(centre)) < Q(tol)


def _between(x, lo, hi):
    return Q(lo) < Q(x) < Q(hi)


def _rand_qomega():
    return FL.QOmega(Q(RNG.randint(-9, 9), RNG.randint(1, 5)), Q(RNG.randint(-9, 9), RNG.randint(1, 5)))


# ------------------------------------------------------------------------------------------------------------
# block A: the circulant and the Koide form (28:C1, C2, C3, X1, X7)
@R.block("A", BLOCK["A"])
def block_A():
    """Block A — the circulant and the Koide form: A1–A3 exact, A3c chart."""
    # A1 the circulant's spectrum in Q(ω): M(1, ω^k, ω^{2k}) = λ_k(1, ω^k, ω^{2k}), Σλ = 3a, Σλ² = 3a² + 6bc,
    #    det = a³ + b³ + c³ − 3abc = λ₀λ₁λ₂ (the cube invariant, at c = b̄: a³ + 2Re b³ − 3aN(b)), on 40 random rational
    #    circulants and 40 Hermitian ones (c = b̄, the eigenvalues then rational); the same on F_{p²} for the shells
    w = FL.OMEGA; ok = True
    for _ in range(40):
        a, b, c = _rand_qomega(), _rand_qomega(), _rand_qomega()
        ok &= FL.eigen_identities(a, b, c)
        ar = FL.QOmega(Q(RNG.randint(1, 9), RNG.randint(1, 5)))                   # a real: the Hermitian circulant (a, b, b̄)
        ok &= FL.eigen_identities(ar, b, b.conj()) and all(l.y == 0 for l in FL.eigenvalues(ar, b, b.conj()))
    det = []
    for p in SHELLS + (CARRIER,):
        S = FL.Shell(p); K = S.K
        for _ in range(8):
            a = RNG.randrange(1, p); b = (RNG.randrange(p), RNG.randrange(p)); c = K.conj(b)
            lam = [K.add(K.add((a, 0), K.mul(b, K.pow(S.omega, k))), K.mul(c, K.pow(S.omega, 2 * k))) for k in range(3)]
            s = K.add(K.add(lam[0], lam[1]), lam[2]); s2 = K.add(K.add(K.mul(lam[0], lam[0]), K.mul(lam[1], lam[1])), K.mul(lam[2], lam[2]))
            ok &= all(l[1] == 0 for l in lam) and s == ((3 * a) % p, 0) and s2 == ((3 * a * a + 6 * K.norm(b)) % p, 0)
        det.append(f"F_{p}²")
    # 28:C1 (p28012)
    R.check("A1", "the circulant (a, b, c) on a cube root ω has the eigenvectors (1, ω^k, ω^{2k}) with eigenvalues "
            "λ_k = a + bω^k + cω^{2k}, Σλ = 3a, Σλ² = 3a² + 6bc and det = a³ + b³ + c³ − 3abc = λ₀λ₁λ₂, in Q(ω) on 80 random "
            "circulants and on F_{p²} for p = 17, 53, 89, 2408561 with c = b̄ (the eigenvalues in F_p, Σλ² = 3a² + 6N(b))",
            ok, "the Koide form Q = Σλ²/(Σλ)² = 1/3 + (2/3)N(b)/a²; the shells " + ", ".join(det))

    # A2 Q = 2/3 ⟺ 2N(b) = a² on the shells: the circulant with N(b) = a²/2 has Q = 2/3 exactly in F_p, the one with
    #    N(b) = 3a²/4 has Q = 5/6, and a random b with 2N(b) ≠ a² has Q ≠ 2/3; in Q(ω) the identity 3Σλ² = 2(Σλ)² ⟺ 2N(b) = a²
    ok = True; det = []
    for p in SHELLS:
        S = FL.Shell(p)
        ls, Qv, b = S.koide_point(1, Q(1, 2)); ok &= Qv == S.frac(Q(2, 3))
        ls5, Qv5, _ = S.koide_point(1, Q(3, 4)); ok &= Qv5 == S.frac(Q(5, 6))
        for _ in range(20):
            bb = (RNG.randrange(p), RNG.randrange(p))
            if bb == (0, 0): continue
            n = S.K.norm(bb); a = 1
            lam = [S.K.add(S.K.add((a, 0), S.K.mul(bb, S.K.pow(S.omega, k))), S.K.mul(S.K.conj(bb), S.K.pow(S.omega, 2 * k))) for k in range(3)]
            l = [x[0] for x in lam]; s = sum(l) % p
            if s == 0: continue
            Qr = sum(x * x for x in l) * pow(s * s, -1, p) % p
            ok &= (Qr == S.frac(Q(2, 3))) == ((2 * n) % p == (a * a) % p)
        det.append(f"F_{p}: λ = {ls} (framed rationals), Q = 2/3")
    for _ in range(40):
        a = Q(RNG.randint(1, 9), RNG.randint(1, 5)); b = _rand_qomega()
        lam = FL.eigenvalues(FL.QOmega(a), b, b.conj()); ls = [l.x for l in lam]
        ok &= (3 * sum(x * x for x in ls) == 2 * sum(ls) ** 2) == (2 * b.norm() == a * a)
    # 28:C2 (p28013), 28:X1 (p28025)
    R.check("A2", "Q = 2/3 ⟺ 2N(b) = a² (ρ² = 1/2, r = √2): the circulant with N(b) = a²/2 has Q = 2/3 exactly in F_p for "
            "p = 17, 53, 89, the one with N(b) = 3a²/4 has Q = 5/6, a random b has Q = 2/3 exactly when 2N(b) = a² "
            "(60 draws), and in Q(ω) 3Σλ² = 2(Σλ)² ⟺ 2N(b) = a² on 40 random Hermitian circulants", ok, "; ".join(det))

    # A3 the quarter-turn boundary and the leading-order spectrum on F_{p²}: with i² = −1, h = 1/2, b = −h(1+i)aω²,
    #    c = −h(1−i)aω the eigenvalue λ₁ = 0 and 2bc = a²; λ₀ = ah(3 + s), λ₂ = ah(3 − s), s = i(ω − ω²), s² = 3;
    #    (3 − s)² = (7 − 4s)(3 + s)²; and δ_LO = 3/8 − 1/3 = 1/24 cycle in the rationals
    ok = Q(3, 8) - Q(1, 3) == Q(1, 24)
    det = []
    for p in SHELLS + (CARRIER,):
        good, lam = FL.boundary(p, a=5)
        ok &= good; det.append(f"F_{p}: λ = {lam}")
    # 28:C3 (p28014), 28:X7 (p28031)
    R.check("A3", "the quarter-turn boundary: on F_{p²} (p = 17, 53, 89, 2408561) the circulant with b = −h(1 + i)aω², "
            "c = −h(1 − i)aω has λ₁ = 0 and 2bc = a² (the massless generation at the quarter-turn diagonal, Q = 2/3), the other "
            "eigenvalues ah(3 ± s) with s = i(ω − ω²), s² = 3, and (3 − s)² = (7 − 4s)(3 + s)²; δ_LO = 3/8 − 1/3 = 1/24 cycle",
            ok, "; ".join(det))

    # A3c [chart] the leading-order ratio m_μ/m_τ = 7 − 4√3 = 0.0718 against the observed 0.0595, π/12 = 0.2618 rad
    lo, obs = CFL.lo_ratio()
    ok = _between(lo, "0.0717", "0.0719") and _between(obs, "0.0594", "0.0595") and _between(Q(lo) / Q(obs), "1.20", "1.22")
    R.check("A3c", "[chart] the leading-order mass ratio m_μ/m_τ = 7 − 4√3 = 0.0718 (the paper's 0.072) against the observed "
            "0.0595: the electron massless at leading order, the muon 21 % above its leading-order value", ok,
            f"7 − 4√3 = {lo:.5f}, observed {obs:.5f}, ratio {lo / obs:.3f}", kind="CHART")


# ------------------------------------------------------------------------------------------------------------
# block B: the amplitudes (28:C4, C5, X2, X5, P2)
@R.block("B", BLOCK["B"])
def block_B():
    """Block B — the amplitudes: B1–B3 exact, B1c, B2c, B3c chart."""
    # B1 N(1 − i) = 2 in F_p and N(1 − ω) = 3 in F_{p²} on the shells; Q = 1/3 + r²/6 gives 2/3 and 5/6
    ok = all(FL.norms_two_three(p) for p in SHELLS + (CARRIER,))
    ok &= FL.koide_of_norm(2) == Q(2, 3) and FL.koide_of_norm(3) == Q(5, 6)
    ok &= all(FL.Shell(p).koide_point(1, Q(3, 4))[1] == FL.Shell(p).frac(Q(5, 6)) for p in SHELLS)
    # 28:C4 (p28015), 28:X2 (p28026), 28:P2 (p28037)
    R.check("B1", "the squared amplitudes are the norms N(1 − i) = 2 (the quarter-turn, F_p) and N(1 − ω) = 3 (the cube root, "
            "F_{p²}) on p = 17, 53, 89, 2408561; Q = 1/3 + r²/6 gives 2/3 for the colourless and 5/6 for the coloured "
            "sector, and the circulant with 4N(b) = 3a² has Q = 5/6 exactly in F_p", ok,
            "Q_ℓ = 2/3, Q_u = 5/6 in framed arithmetic")

    # B1c [chart] Q_u in three schemes, inside the band [0.83, 0.89] that holds 5/6; r_u against √3; Q_d, the GJ dressing
    up = CFL.up_schemes(); Qd, rd, dd, Qgj = CFL.down_sector()
    ok = _within(up["up"][0], "0.849", "0.001") and _within(up["up_pole"][0], "0.832", "0.001") and _within(up["up_mz"][0], "0.888", "0.001")
    ok &= all(_between(v[0], "0.83", "0.89") for v in up.values()) and _between(Q(5, 6), "0.83", "0.89")
    ok &= _within(up["up"][1], Q(CFL.SQRT3), "0.03") and _within(Qd, "0.731", "0.001") and _within(Qgj, "0.745", "0.001")
    ok &= _within(rd, "1.545", "0.002")
    R.check("B1c", "[chart] Q_u = 0.849 in the working scheme, 0.832 with pole masses, 0.888 in MS-bar at M_Z, all in the band "
            "[0.83, 0.89] that holds 5/6; r_u = 1.759 within 3 % of √3; Q_d = 0.731 with r_d = 1.545, and the Georgi–Jarlskog-"
            "dressed leptons (3m_e, m_μ/3, m_τ) have Q = 0.745", ok,
            f"Q_u = {up['up'][0]:.4f}, {up['up_pole'][0]:.4f}, {up['up_mz'][0]:.4f}; r_u = {up['up'][1]:.3f}; Q_d = {Qd:.4f}, dressed {Qgj:.4f}",
            kind="CHART")

    # B2 the colour count on the sixteen: three d^c states against one e^c, N_c = 3, the double ratio N_c² = 9
    dc, ec, nine = FL.colour_count()
    # 28:X5 (p28029)
    R.check("B2", "the Georgi–Jarlskog factor is the colour count: on the sixteen the down-type antiquarks d^c are three "
            "states (colour 2, weak 2, 6Y = 2) against one e^c (0, 2, 6), N_c = 3, and the scale-robust double ratio is "
            "N_c² = 9", dc == 3 and ec == 1 and nine == 9, f"d^c × {dc}, e^c × {ec}, N_c² = {nine}")

    # B2c [chart] the double ratio (m_μ/m_e)/(m_s/m_d) = 10.34 against 9: the open excess between 10 % and 20 %
    gj, msd, btau = CFL.gj_double_ratio()
    ok = _between(gj, "10.3", "10.5") and _between(Q(gj) / 9 - 1, "0.10", "0.20") and _within(msd, "20.0", "0.1") and _within(btau, "0.43", "0.01")
    R.check("B2c", "[chart] the double ratio (m_μ/m_e)/(m_s/m_d) = 10.34 against N_c² = 9, the open 15 % excess (between 10 % "
            "and 20 %); m_s/m_d = 20.0; m_τ/m_b = 0.43 at low scale", ok, f"double ratio {gj:.3f}, excess {100 * (gj / 9 - 1):.1f} %",
            kind="CHART")

    # B3 the lock relations as trace identities: on every unit z of F_{p²} (zz̄ = 1), T(z²) = T(z)² − 2 and
    #    T(z³) = T(z)³ − 3T(z); the Chebyshev forms 2cos 2θ = (2cos θ)² − 2, 2cos 3θ = (2cos θ)³ − 3(2cos θ) on rationals
    ok = all(FL.trace_relations(p) for p in SHELLS)
    for _ in range(20):
        x = Q(RNG.randint(-9, 9), RNG.randint(1, 5))                    # x = 2cos θ: T2 = x² − 2, T3 = x³ − 3x as identities
        c = x / 2
        ok &= 2 * (2 * c * c - 1) == x * x - 2 and 2 * (4 * c ** 3 - 3 * c) == x ** 3 - 3 * x
    # 28:C5 (p28016)
    R.check("B3", "the lock δ_ℓ : δ_d : δ_u = 1 : 1/2 : 1/3 as relations between the cube invariants c = cos 3δ: for every "
            "unit z of F_{p²} (p = 17, 53, 89) T(z²) = T(z)² − 2 and T(z³) = T(z)³ − 3T(z), so δ_d = δ₀/2 gives "
            "c_ℓ = 2c_d² − 1 and δ_u = δ₀/3 gives c_ℓ = 4c_u³ − 3c_u", ok, "the trace relations of a unit, exhaustive on the three shells")

    # B3c [chart] the lock read in the working scheme: δ_d/δ_ℓ = 0.496, δ_u/δ_ℓ = 0.335 (0.388 with the pole charm mass),
    #     δ_ℓ = 0.2222 ≈ 2/9; the cube invariants satisfy the two relations within 0.5 %
    dl, dd, du, dup = CFL.phase_lock(); cl, cd, cu = CFL.cube_invariants(); r2, r3 = FL.chebyshev_lock(Q(cl), Q(cd), Q(cu))
    ok = _within(Q(dd) / Q(dl), "0.496", "0.002") and _within(Q(du) / Q(dl), "0.335", "0.002") and _within(Q(dup) / Q(dl), "0.388", "0.002")
    ok &= _within(dl, Q(2, 9), "0.001") and abs(r2 / Q(cl) - 1) < Q(1, 200) and abs(r3 / Q(cl) - 1) < Q(1, 200)
    R.check("B3c", "[chart] the phases from the masses in the working scheme: δ_ℓ = 0.2222 (≈ 2/9), δ_d/δ_ℓ = 0.496, "
            "δ_u/δ_ℓ = 0.335 (0.388 with the pole charm mass); the cube invariants c_ℓ, c_d, c_u satisfy c_ℓ = 2c_d² − 1 and "
            "c_ℓ = 4c_u³ − 3c_u within 0.5 %", ok,
            f"δ = ({dl:.4f}, {dd:.4f}, {du:.4f}); c = ({cl:.4f}, {cd:.4f}, {cu:.4f}), 2c_d² − 1 = {CH.show(r2, '.4f')}, 4c_u³ − 3c_u = {CH.show(r3, '.4f')}",
            kind="CHART")


# ------------------------------------------------------------------------------------------------------------
# block C: the texture (28:C6, C7, C8, X3, X4, X6, X8, P3)
@R.block("C", BLOCK["C"])
def block_C():
    """Block C — the texture: C1–C3 exact, C1c–C3c chart."""
    # C1 the Gatto–Sartori–Tonin relation: the texture R D Rᵀ with a vanishing (1,1) entry has m₂s² = −m₁c² (tan²θ = −m₁/m₂),
    #    on rational rotations (c, s) = ((1 − t²)/(1 + t²), 2t/(1 + t²)); the Cabibbo modulus on every unit of F_{p²}
    ok = True
    for _ in range(20):
        t = Q(RNG.randint(1, 8), 9); c, s = (1 - t * t) / (1 + t * t), 2 * t / (1 + t * t)      # t = tan(θ/2) < 1
        m2 = Q(RNG.randint(1, 9)); m1 = -m2 * s * s / (c * c)
        M, e11, e12 = FL.gst_relation(c, s, m1, m2)
        ok &= e11 and e12 and M[0][0] == 0 and m2 * s * s == -(m1 * c * c) and M[0][1] == M[1][0]
    for p in SHELLS: ok &= FL.cabibbo_modulus(p, RNG.randrange(1, p), RNG.randrange(1, p), RNG.randrange(1, p), RNG.randrange(1, p))
    # 28:C6 (p28017), 28:X4 (p28028)
    R.check("C1", "the Gatto relation from the texture: the symmetric 2×2 texture R D Rᵀ whose (1,1) entry vanishes has "
            "m₂s² = −m₁c², tan²θ = −m₁/m₂ (20 rational rotations); and |s_d c_u − c_d s_u z|² = s_d²c_u² + c_d²s_u² − "
            "s_d c_u c_d s_u T(z) on every unit z of F_{p²}, p = 17, 53, 89: V_us = |√(m_d/m_s) − e^{iφ}√(m_u/m_c)|", ok,
            "the texture zero fixes the angle from the two light masses; the phase enters through the trace T(z) = 2cos φ")

    # C1c [chart] the leading term √(m_d/m_s) = 0.2236 against V_us = 0.2243 (0.3 %), the up term 0.041, the band over φ,
    #     φ = 86° at the measured value, 0.227 at φ = π/2; λ ≈ δ₀ within 1 %
    x, y, at90, (blo, bhi), phi = CFL.gatto(); dl = CFL.phase_lock()[0]; Vus = CFL.DATA["ckm"]["V_us"]
    ok = _within(x, "0.2236", "0.0001") and abs(Q(x) - Vus) / Vus < Q(35, 10000) and _within(y, "0.041", "0.001")
    ok &= _within(at90, "0.2274", "0.0002") and _between(blo, "0.18", "0.19") and _between(bhi, "0.26", "0.27") and _between(phi, 75, 95)
    ok &= abs(Vus - Q(dl)) / Vus < Q(1, 100)
    # 28:P3 (p28038)
    R.check("C1c", "[chart] √(m_d/m_s) = 0.2236 against V_us = 0.2243 (0.3 %), the up term √(m_u/m_c) = 0.041, the relation "
            "sweeping 0.18–0.27 as φ runs, φ = 86° at the measured value (the paper's 85° ± 10°) and 0.227 at φ = π/2; "
            "λ = V_us coincides with the lepton phase δ₀ = 0.2222 within 1 %", ok,
            f"√(m_d/m_s) = {x:.4f}, up term {y:.4f}, at φ = π/2: {at90:.4f}, band ({blo:.3f}, {bhi:.3f}), φ = {phi:.0f}°", kind="CHART")

    # C2 the role-depth texture: depths (2, 1, 0) give the exponents (4, 2, 0) and, doubled, (8, 4, 0); the exponent
    #    matrices n_i + n_j symmetric; the closed role ladder on the shells (the tower read modulo p − 1, as 27:F6)
    down, up, Ed, Eu = FL.texture_exponents()
    ok = down == (4, 2, 0) and up == (8, 4, 0) and tuple(2 * k for k in down) == up
    ok &= all(Ed[i][j] == Ed[j][i] and Eu[i][j] == Eu[j][i] for i in range(3) for j in range(3))
    for p in (13, 53, 157, 421):
        g, n = arith.primitive_root(p), p - 1
        ok &= all(LD.tower(g, j, p)[0] == LD.tower(g, j, p)[1] for j in range(n)) and any(pow(g, j, p) >= n for j in range(n))
    # 28:C7 (p28018), 28:X6 (p28030), 28:X3 (p28027)
    R.check("C2", "the role depths (2, 1, 0) as flavour charges: the down and lepton exponents 2n = (4, 2, 0), the up exponents "
            "4n = (8, 4, 0) = 2·(4, 2, 0) (the 10·10 Yukawa carries the charge twice), the exponent matrices n_i + n_j symmetric; "
            "the ladder of roles closes on F_13, F_53, F_157, F_421 (the tower g^(g^j) read modulo p − 1, no fifth role)", ok,
            f"down {down}, up {up}")

    # C2c [chart] the effective powers log(m_i/m_3)/log λ inside their integer brackets: down (4.5, 2.5), lepton (5.5, 1.9),
    #     up (7.6, 3.3) at λ = V_us
    pw = CFL.effective_powers()
    ok = _between(pw["down"][0], 4, 5) and _between(pw["down"][1], 2, 3) and _between(pw["up"][0], 7, 8) and _between(pw["up"][1], 3, 4)
    ok &= _between(pw["leptons"][0], 5, 6) and _between(pw["leptons"][1], 1, 2)
    ok &= _within(pw["down"][0], "4.55", "0.05") and _within(pw["leptons"][0], "5.46", "0.05") and _within(pw["up"][0], "7.55", "0.05")
    R.check("C2c", "[chart] the effective powers log(m_i/m₃)/log λ at λ = V_us: down (4.5, 2.5), lepton (5.5, 1.9), up (7.6, 3.3), "
            "each inside the integer bracket of its exponent (4, 2), (4, 2), (8, 4), the electron one power below (the "
            "Georgi–Jarlskog outlier)", ok, "; ".join(f"{k} ({a:.2f}, {b:.2f})" for k, (a, b) in pw.items()), kind="CHART")

    # C3 the lopsided transpose: (L D Rᵀ)ᵀ = R D Lᵀ for a diagonal D and (AB)ᵀ = BᵀAᵀ on random rational matrices;
    #    circulants: (circ a b c)ᵀ = circ a c b
    ok = True
    for _ in range(20):
        L, Rm = FL.random_matrix(RNG), FL.random_matrix(RNG); D = [Q(RNG.randint(1, 9)) for _ in range(3)]
        ok &= FL.lopsided_transpose(L, D, Rm)
        a, b, c = (Q(RNG.randint(-9, 9)) for _ in range(3)); ok &= FL.transpose(FL.circ(a, b, c)) == FL.circ(a, c, b)
    # 28:C8 (p28019), 28:X8 (p28032)
    R.check("C3", "the lopsided split: (L D Rᵀ)ᵀ = R D Lᵀ for a diagonal D on 20 random rational triples, so the right-handed "
            "rotation of M_d (invisible to the quark mixing) is the left-handed rotation of M_e = M_dᵀ (seen by the lepton "
            "mixing); (AB)ᵀ = BᵀAᵀ; (circ a b c)ᵀ = circ a c b", ok, "one matrix, small on the left, large on the right")

    # C3c [chart] σ = 1.3 in the (3,2) slot of M_d at λ = 0.225: CKM θ₂₃ = 1.4°, PMNS θ₂₃ = 52.5° (the hidden right angle)
    ckm, pmns, right = CFL.lopsided()
    ok = _within(ckm, "1.4", "0.1") and _within(pmns, "52.5", "0.5") and _within(right, pmns, "0.01")
    R.check("C3c", "[chart] tier_b's lopsided M_d (σ = 1.3 at (3,2), λ = 0.225) with a diagonal M_u: CKM θ₂₃ = 1.4° (measured "
            "2.4°) and PMNS θ₂₃ = 52.5° from M_e = M_dᵀ (NuFIT 6.0: 48.5° without, 43.3° with atmospheric data), the lepton angle "
            "the hidden right-handed angle of M_d", ok, f"θ_CKM23 = {ckm:.2f}°, θ_PMNS23 = {pmns:.1f}°, right angle {right:.1f}°",
            kind="CHART")


# ------------------------------------------------------------------------------------------------------------
# block D: the mixing (28:C9, C10, X9, X10, P8)
@R.block("D", BLOCK["D"])
def block_D():
    """Block D — the mixing: D1 chart, D2 exact, D2c chart."""
    # D1 [chart] the reactor angle at leading order: sin θ_C/√2 = 0.1586 against 0.1488, 6.6 % high; θ₁₂ + θ_C = 46.6°
    est, s13, excess, qlc = CFL.theta13()
    ok = _within(est, "0.1586", "0.0001") and _between(excess, "0.06", "0.07") and _within(qlc, "46.6", "0.1")
    # 28:C9 (p28020), 28:X9 (p28033)
    R.check("D1", "[chart] the reactor angle at leading order, sin θ₁₃ = sin θ_C/√2 = 0.1586 against the measured 0.1488, "
            "6.6 % high (the paper's 7 %), an estimate with no correction derived; quark–lepton complementarity "
            "θ₁₂ + θ_C = 46.6° against 45°", ok, f"estimate {est:.4f}, excess {100 * excess:.1f} %, θ₁₂ + θ_C = {qlc:.1f}°", kind="CHART")

    # D2 the protected column, trimaximality and the Jarlskog invariant in Q(ω) and in F_p
    v, u, notprop = FL.protected_column(); tri, q, J2 = FL.magic_matrix()
    ok = v and u and notprop and tri and q and J2 == Q(1, 108) and all(FL.jarlskog_framed(p) for p in SHELLS + (CARRIER,))
    # 28:C10 (p28021), 28:X10 (p28034), 28:P8 (p28042)
    R.check("D2", "the shift P fixes (1, 1, 1) and no multiple of (2, −1, −1) (TM2, not TM1); the magic matrix F_jk = ω^{jk} "
            "is trimaximal, N(F_jk) = 1 (|F_jk/√3|² = 1/3), its rephasing invariant F₀₀F₁₁F̄₀₁F̄₁₀ = ω gives J² = (Im ω)²/81 "
            "= 1/108 in Q(ω), and 4(−νh²) = 3 (108 J² = 1) in F_p for p = 17, 53, 89, 2408561", ok,
            "J = 1/(6√3) maximal, the cube-root phase")

    # D2c [chart] the TM2 relation: |δ_CP| = 90.0°, 124.5°, 130.4°, 74.1° at θ₂₃ = 45°, 48.5°, 49°, 43.3°; the band over
    #     41°–50.6° is [49.6°, 155.9°], with the drive's sign (204°, 310°); the exact-TM2 solar 0.341 against 0.307
    at, (blo, bhi), (dlo, dhi), solar, (pos_sk, data_neg) = CFL.tm2_readings()
    ok = _within(at["45"], 90, "0.01") and _within(at["48.5"], "124.5", "0.1") and _within(at["49"], "130.4", "0.1") and _within(at["43.3"], "74.1", "0.1")
    ok &= _within(blo, "49.6", "0.2") and _within(bhi, "155.9", "0.2") and _within(dlo, 204, "0.5") and _within(dhi, 310, "0.5")
    ok &= _within(solar, "0.3409", "0.0001") and pos_sk and data_neg
    R.check("D2c", "[chart] the TM2 relation cos δ_CP = cot 2θ₂₃ (1 − 2s₁₃²)/(s₁₃√(2 − 3s₁₃²)) at θ₁₃ = 8.57°: |δ_CP| = 90.0°, "
            "124.5°, 130.4°, 74.1° at θ₂₃ = 45°, 48.5°, 49°, 43.3°; over the NuFIT 6.0 3σ range 41°–50.6° the band "
            "[49.6°, 155.9°], with the drive's sign (204°, 310°); cos δ_CP > 0 at the with-atmospheric best fit where the data "
            "prefer cos δ_CP < 0 (the live test); the exact-TM2 solar value 0.341 against 0.307", ok,
            "; ".join(f"θ₂₃ = {k}°: |δ| = {d:.1f}°" for k, d in at.items()) + f"; band [{blo:.1f}°, {bhi:.1f}°]; solar {solar:.4f}",
            kind="CHART")


# ------------------------------------------------------------------------------------------------------------
# block E: the seesaw (28:C11, C11b, X11, P5, Z2)
@R.block("E", BLOCK["E"])
def block_E():
    """Block E — the seesaw of circulants: E1, E2 exact, E2c chart."""
    # E1 circulants are closed under product, transpose and adjugate; m_D·adj(M_R)·m_Dᵀ is circulant; M·adj M = det M·1;
    #    with M_R = c m_D the seesaw collapses to c² det(m_D) m_Dᵀ; the transpose circulant has the eigenvalues λ_{−k}
    ok = True
    for _ in range(20):
        mD, MR = FL.random_circ(RNG), FL.random_circ(RNG)
        good, prod = FL.seesaw_closure(mD, MR); ok &= good
        ok &= FL.transpose_fixed_point(Q(RNG.randint(1, 9), RNG.randint(1, 5)), mD)
        ok &= FL.transpose_eigen(_rand_qomega(), _rand_qomega(), _rand_qomega())
    # 28:C11 (p28022), 28:X11 (p28035)
    R.check("E1", "the seesaw of circulants: products, transposes and adjugates of circulants are circulant, so m_D·adj(M_R)·m_Dᵀ "
            "is circulant (20 random rational pairs) and the light neutrinos are Koide-form; M·adj M = det M·1; with M_R = c m_D "
            "the seesaw is c² det(m_D) m_Dᵀ, a multiple of the transpose, whose eigenvalues are the Dirac eigenvalues λ_{−k}: "
            "r_ν = r_D = √2, Q_ν = 2/3", ok, "the transpose fixed point under the 126-bar alignment (28:Y1)")

    # E2 the signed Koide: 3Σa² = â₀² + 2N(â₁) for arbitrary signs of the amplitudes, in Q(ω) with negative rationals and
    #    in F_p; the signed amplitudes with 2N(b) = a² have Q = 2/3 at every phase (the Takagi reading)
    w = FL.OMEGA; ok = True
    for _ in range(40):
        a0, a1, a2 = (Q(RNG.randint(-9, 9), RNG.randint(1, 4)) for _ in range(3))
        h1 = a0 + a1 * w + a2 * w * w; h2 = a0 + a1 * w * w + a2 * w
        ok &= 3 * (a0 * a0 + a1 * a1 + a2 * a2) == (a0 + a1 + a2) ** 2 + 2 * h1.norm() and h1 * h2 == FL.QOmega(h1.norm())
    for p in SHELLS:
        S = FL.Shell(p); K = S.K
        for _ in range(20):
            a = [RNG.randrange(p) for _ in range(3)]
            h1 = K.add(K.add((a[0], 0), K.mul((a[1], 0), S.omega)), K.mul((a[2], 0), K.pow(S.omega, 2)))
            ok &= (3 * sum(x * x for x in a)) % p == (sum(a) ** 2 + 2 * K.norm(h1)) % p
    for _ in range(20):                                                 # the signed circulant: b with 2N(b) = a², any phase
        b = _rand_qomega(); a = FL.QOmega(1)
        if 2 * b.norm() == 0: continue
        lam = FL.eigenvalues(a, b, b.conj()); ls = [l.x for l in lam]
        ok &= (3 * sum(x * x for x in ls) == 2 * sum(ls) ** 2) == (2 * b.norm() == 1)
    # 28:C11b (p28050)
    R.check("E2", "the signed Koide identity: 3Σa² = â₀² + 2N(â₁) holds for amplitudes of either sign (40 draws in Q(ω) with "
            "negative rationals, 60 in F_p for p = 17, 53, 89), so the signed circulant with 2N(b) = a² has Q = 2/3 at every "
            "phase: the Takagi reading of the neutrino Koide value with one negative amplitude", ok,
            "the identity is sign-free; the sign is the Majorana phase")

    # E2c [chart] the signed circulant solves both orderings at NuFIT 6.0: normal δ_ν = 0.479, (0.36, 8.66, 50.13) meV,
    #     Σ = 59.2 meV; inverted δ_ν = 1.042, (2.92, 49.17, 49.92) meV, Σ = 102.0 meV; Q(signed) = 2/3, one negative amplitude
    no = CFL.signed_circulant(False); io = CFL.signed_circulant(True)
    ok = _within(no[0], "0.479", "0.002") and _within(no[1][0], "0.36", "0.02") and _within(no[1][1], "8.66", "0.02") and _within(no[1][2], "50.13", "0.02")
    ok &= _within(no[2], "59.2", "0.1") and _within(no[3], Q(2, 3), "1e-9") and no[5] < 0 and _within(no[4], "0.524", "0.005")
    ok &= _within(io[0], "1.042", "0.002") and _within(io[2], "102.0", "0.2") and _within(io[3], Q(2, 3), "1e-9") and io[5] < 0
    ok &= _within(io[1][0], "2.92", "0.02") and _within(io[1][1], "49.17", "0.05") and _within(io[1][2], "49.92", "0.05")
    R.check("E2c", "[chart] the signed r = √2 circulant solves both orderings exactly at NuFIT 6.0: normal δ_ν = 0.479, masses "
            "(0.36, 8.66, 50.13) meV, Σm_ν = 59.2 meV (the positive-root Koide 0.524); inverted δ_ν = 1.042, (2.92, 49.17, 49.92) "
            "meV, Σm_ν = 102.0 meV; in both Q(signed) = 2/3 with the one negative amplitude on the lightest state, so "
            "colourlessness fixes the signed invariant and not the ordering", ok,
            f"NO δ_ν = {no[0]:.3f}, Σ = {no[2]:.1f} meV; IO δ_ν = {io[0]:.3f}, Σ = {io[2]:.1f} meV", kind="CHART")


# ------------------------------------------------------------------------------------------------------------
# block F: the sixteen and the measured Koide value (28:C12, P1, X1)
@R.block("F", BLOCK["F"])
def block_F():
    """Block F — the sixteen (exact) and the measured Koide value (chart)."""
    # F1 the generation as the four-chart reflection algebra: 16 states, the fifth direction a bijection onto the even
    #    subsets of five, the split 1 + 10 + 5 by colour and weak content (the master's H1 computes the algebra itself)
    n16, bij, (one, ten, five) = FL.sixteen()
    # 28:C12 (p28024)
    R.check("F1", "the generation is the reflection algebra of the four charts: 2⁴ = 16 states, the quarter-turn as the fifth "
            "direction a bijection onto the even subsets of five (Λ•(C⁴) ≅ Λ^even(C⁵)), read 1 + 10 + 5 by colour and weak "
            "content with the singlet ν^c = Λ⁰ (the algebra's associativity and the 3 + 2 charges are the master's 00:G12, "
            "00:G11)", n16 and bij and (one, ten, five) == (1, 10, 5), f"1 + {ten} + {five} = 16")

    # F2 [chart] the measured charged-lepton Koide value and its circulant data
    Qv, dev, dQ, rho, angle, r, dl, a2 = CFL.koide_measured(); me_pred, _ = CFL.electron_prediction()
    ok = abs(Q(dev)) < Q(1, 100000) and _within(dev, "-6.2e-6", "0.2e-6") and _within(dQ, "5.6e-5", "0.1e-5")
    ok &= _within(rho, "0.707100", "0.000005") and _within(angle, "44.9997", "0.0002") and abs(Q(r) - Q(CFL.SQRT2)) < Q(1, 10000)
    ok &= _within(me_pred, "0.5106", "0.0001") and _within(CFL.lepton_spectrum_residual(), 0, "1e-9")
    # 28:P1 (p28036)
    R.check("F2", "[chart] the measured charged-lepton Koide value Q = 0.666661, Q − 2/3 = −6.2 × 10⁻⁶ (dQ/dm_τ = 5.6 × 10⁻⁵ per "
            "MeV, ±6.8 × 10⁻⁶ for the τ-mass uncertainty ±0.12 MeV), ρ = 0.707100 against 1/√2, the democratic angle 44.9997°, "
            "r = 1.41420 = √2 within 10⁻⁴; with r = √2 exactly the electron mass predicted from m_μ, m_τ is 0.5106 MeV against "
            "0.5110", ok, f"Q − 2/3 = {dev:.2e}, ρ = {rho:.6f}, r = {r:.5f}, m_e = {me_pred:.4f} MeV", kind="CHART")


# ------------------------------------------------------------------------------------------------------------
# block H: the neutrinos (28:P5, P6, P7, X11)
@R.block("H", BLOCK["H"])
def block_H():
    """Block H — the neutrinos: H1–H3 chart."""
    # H1 [chart] the m₁ = 0 floor at NuFIT 6.0: √Δm²₂₁ + √Δm²₃₁ = 58.8 meV, within the cosmological bound 120 meV
    tot, m2, m3 = CFL.neutrino_floor()
    ok = _within(tot, "58.8", "0.05") and _within(m2, "8.65", "0.01") and _within(m3, "50.13", "0.01") and tot < 120
    # 28:P6 (p28040)
    R.check("H1", "[chart] the m₁ = 0 floor of the normal-ordered sum at NuFIT 6.0 (Δm²₂₁ = 7.49 × 10⁻⁵, Δm²₃₁ = 2.513 × 10⁻³ eV²): "
            "Σm_ν = √Δm²₂₁ + √Δm²₃₁ = 8.65 + 50.13 = 58.8 meV, inside the cosmological bound 120 meV", ok,
            f"floor {tot:.2f} meV", kind="CHART")

    # H2 [chart] the normal ordering from Q_ν = 2/3, the two splittings and the boundary branch: the lightest state's
    #     amplitude −0.19, 0.22 rad from the quarter-turn zero on the normal root, −0.41 and 0.78 rad on the inverted
    no = CFL.signed_circulant(False); io = CFL.signed_circulant(True)
    ok = no[1][0] < 1 and _within(no[5], "-0.19", "0.01") and _within(no[6], "0.22", "0.01") and _within(io[5], "-0.41", "0.01") and _within(io[6], "0.78", "0.01")
    ok &= io[6] > 3 * no[6] and _within(no[0], "0.48", "0.005")
    # 28:P5 (p28039), 28:Z2 (p28047)
    R.check("H2", "[chart] the boundary branch selects the normal ordering: on the normal root the lightest amplitude is −0.19, "
            "0.22 rad from the quarter-turn zero, on the inverted −0.41 and 0.78 rad away (3.6 times farther); the lightest mass "
            "0.36 meV; the seesaw-effective phase δ_ν = 0.48 does not follow the charged-sector lock (28:Z2)", ok,
            f"NO: amplitude {no[5]:.3f} at {no[6]:.3f} rad; IO: {io[5]:.3f} at {io[6]:.3f} rad", kind="CHART")

    # H3 [chart] the effective Majorana mass at m₁ = 0: the terms 2.60 and 1.11 meV, the band [1.49, 3.71] meV over the
    #     relative Majorana phase; with the fitted m₁ = 0.36 meV and its own phase [1.24, 3.95]
    t1, t2, t3, lo, hi = CFL.majorana_band(0); _, _, _, lo2, hi2 = CFL.majorana_band(no[1][0])
    ok = _within(t2, "2.598", "0.005") and _within(t3, "1.110", "0.005") and _within(lo, "1.488", "0.005") and _within(hi, "3.708", "0.005")
    ok &= _within(lo2, "1.24", "0.01") and _within(hi2, "3.95", "0.01") and hi < 15
    # 28:P7 (p28041)
    R.check("H3", "[chart] the effective Majorana mass at m₁ = 0 on the normal ordering: c₁₃²s₁₂²m₂ = 2.60 meV and s₁₃²m₃ = 1.11 "
            "meV, so m_ββ lies in [1.49, 3.71] meV over the relative Majorana phase (the paper's 1.5–3.7); with the fitted "
            "m₁ = 0.36 meV and its own phase [1.24, 3.95] meV; far below the inverted-ordering scale 15–50 meV", ok,
            f"terms {t2:.3f}, {t3:.3f} meV; band [{lo:.2f}, {hi:.2f}] meV", kind="CHART")


# ------------------------------------------------------------------------------------------------------------
# block Z: the Ω-hard readings (28:Z1, Z3, Z4)
@R.block("Z", BLOCK["Z"])
def block_Z():
    """Block Z — the Ω-hard readings (chart): Z1, Z3, Z4, Z4b."""
    # Z1 [chart] the sub-horizon reading δ₀ = Q/3 = 2/9: δ_ℓ = 0.2222 against 2/9 within 10⁻³, 3δ_ℓ against Q within 10⁻⁴
    Qv, dev, dQ, rho, angle, r, dl, a2 = CFL.koide_measured()
    ok = _within(dl, Q(2, 9), "0.001") and abs(3 * Q(dl) - Q(Qv)) < Q(1, 10000)
    # 28:Z1 (p28046)
    R.check("Z1", "[chart] the lepton winding phase read from the masses, δ_ℓ = 0.2222 rad, against the sub-horizon reading "
            "δ₀ = Q/3 = 2/9 = 0.2222 (within 10⁻³; 3δ_ℓ = Q within 10⁻⁴): a confrontation, the value Ω-hard", ok,
            f"δ_ℓ = {dl:.5f}, 3δ_ℓ − Q = {3 * dl - Qv:.1e}", kind="CHART")

    # Z3 [chart] the scale transmutation: ln(M_P/v) = 38.4, y_t = 0.99, y_τ = 0.0102, the lepton scale a² = 314 MeV
    lnr, yt, ytau, a2 = CFL.scales()
    ok = _within(lnr, "38.4", "0.1") and abs(Q(yt) - 1) < Q(2, 100) and _within(ytau, "0.0102", "0.0001") and _within(a2, 314, 1)
    # 28:Z3 (p28048)
    R.check("Z3", "[chart] the overall scale as transmutation: v/M_P = e^{−38.4}, the trigger y_t = √2m_t/v = 0.99 within 0.02 "
            "of 1, y_τ = 0.0102, the lepton scale a² = (Σ√m_ℓ/3)² = 314 MeV; the value Ω-hard (master Z6)", ok,
            f"ln(M_P/v) = {lnr:.2f}, y_t = {yt:.4f}, a² = {a2:.1f} MeV", kind="CHART")

    # Z4 [chart] the coupling anchor: α_bare⁻¹ = 4π against the one-loop unified α_GUT⁻¹ ≈ 42 at α₁ = α₂ near 10¹³ GeV
    four_pi, agut, muU, dalpha, hier = CFL.alpha_anchor()
    ok = _within(four_pi, Q(CFL.FOUR_PI), "1e-12") and _between(agut, 40, 45) and _between(muU, "1e12", "1e14")
    ok &= Q(agut) > Q(four_pi) and _between(Q(agut) - Q(four_pi), 25, 35)
    # 28:Z4 (p28049)
    R.check("Z4", "[chart] the coupling anchor: α_bare⁻¹ = 4π = 12.57 against the unified α_GUT⁻¹ = 42.4 at the one-loop "
            "α₁ = α₂ scale 1.0 × 10¹³ GeV (the measured M_Z couplings, 27-fields' p1 data): the bare coupling is the stronger, "
            "the matching offset Δ(α⁻¹) ≈ 30 the open link; the value Ω-hard (master Z8)", ok,
            f"α_GUT⁻¹ = {agut:.1f} at {muU:.1e} GeV, Δ = {agut - four_pi:.1f}", kind="CHART")

    # Z4b [chart] the one-loop fermion sum from 4π: Δα⁻¹ = (b_em/2π) ln(M_P/m_e) ≈ 87, α⁻¹ ≈ 100, not 137; the EM/gravity
    #     hierarchy α(m_P/m_p)² = 1.24 × 10³⁶
    ok = _within(dalpha, 87, 1) and _between(Q(four_pi) + Q(dalpha), 95, 105) and _between(hier, "1e36", "2e36")
    R.check("Z4b", "[chart] the one-loop fermion sum from the 4π anchor adds Δα⁻¹ = (b_em/2π) ln(M_P/m_e) ≈ 87 with b_em = (4/3)·8, "
            "giving α⁻¹ ≈ 100 and not 137: the bare-to-measured connection is a matching (row AL5); the EM/gravity hierarchy "
            "α(m_P/m_p)² = 1.24 × 10³⁶", ok, f"Δα⁻¹ = {dalpha:.1f}, 4π + Δ = {four_pi + dalpha:.1f}, hierarchy {hier:.2e}", kind="CHART")


if __name__ == "__main__":
    want = [a.upper() for a in sys.argv[1:]] or sorted(BLOCK)
    bad = [b for b in want if b not in BLOCK]
    if bad: sys.exit(f"no block {', '.join(bad)}: the blocks are {', '.join(sorted(BLOCK))}")
    for b in want: R.run_block(b)
    sys.exit(0 if R.summary(write=False, expect=list(LEDGER) if want == sorted(BLOCK) else None) else 1)
