#!/usr/bin/env python3
r"""eec-nnlo-n4-elliptic-evaluate.py -- FULL elliptic part F^ell(zeta) of the
two-point NNLO N=4 sYM energy-energy correlation:

    F^ell(zeta) = F^K1(zeta) + F^R2(zeta) + F^red1(zeta)

the finite elliptic two-fold residual of eq.(19) of Henn-Sokatchev-Yan-
Zhiboedov, arXiv:1903.05314, on the Gamma_1(6) equal-mass-sunrise curve
(Phase 0 of this work, proven).  The three-piece FINITE decomposition is
this work's closure of record (CLOSURE_FINAL.json, sha256
135e163d00ac21d5..., and CLOSURE.json, sha256 043bd76b55dd272c...): the
K2 elliptic kernel alone is GENUINELY divergent (proven two ways), so the
correct finite split is K1-kernel piece + full R2 term + reducible-R1
term; the split is gated >= 40 d at the angles 3/11, 5/13, which were
never used in the construction.

WHAT EACH PIECE IS, AND WHERE ITS NUMBERS COME FROM
===================================================
  F^K1   irreducible elliptic K1 sub-integral, evaluated by the OP3
         SYMBOLIC WORD FORM (159 derived words, ZERO fitted); engine and
         fail-closed gate design ported from fk1-evaluate.py (sha256
         1ae3fc29efaf5979... as shipped 2026-09-03 -- numeric engine
         unchanged since the OP3 closure of record; original gates
         59 d @ 1/3, 51 d @ 1/2, 55 d @ the never-used point 2/7).  The word data
         file fk1_words.json is THE SAME pinned file (sha256
         77dfc3a3b80e1774..., checked on every load, every worker); this
         script vendors no copy of it.
  F^R2   full R2 term (elliptic K2 + its inseparable reducible remainder),
         evaluated by the closed Moebius-mirror ONE-FOLD of this work's
         record (close5_fr2_onefold.py + close5_fr2_gate.json,
         sha256 769a369ca32611e6...):
            F^R2 = int_0^1 dzb [ (a2/sqrt(disc2)) (J2(s+)-J2(s-)) + T_red ],
            disc2 = (zb-1)^4 Q(zb/(zb-1); zeta)   [SAME Gamma_1(6) curve],
            z(s+-) = 1/zb exactly,  int_0^1 dzb/sqrt(disc2) = varpi_0.
         Recorded gates: 38.0/37.6 d at 1/3, 1/2; NEVER-USED 32.47 d (3/11),
         32.72 d (5/13); K1-machinery positive control 40.0 d.
  F^red1 reducible-R1 piece, evaluated by the recorded machine truth
         (close9_red1_analytic.py + close9_red1_gate.json,
         sha256 8916c6a24a20e505...): the one-fold
            F^red1 = int_0^1 dzb int_0^zb dt red1 * P1(z(t,zb),zb),
            red1 = zb(1-ze)/den = kappa/(t - tstar)  (rational kernel,
            NO elliptic content -- constructive proof),
         whose exact t-fold IS the 112-GPL-word representation
            int_0^zb red1*P1 dt = kappa * sum_{112 words} c_w G(t*,w;zb)
         over the rational alphabet {0, zb, 1, t6, t*}.  The 112 words
         with their EXACT coefficients are vendored below (from
         close9_red1_form.json, sha256 b22a21c33e7b632d..., self-pinned)
         and re-gated LIVE each run: Phi(t) = sum_w c_w G(w;t) is
         evaluated by a spectral-panel GPL integrator and compared to
         P1(z(t),zb) pointwise (the recorded gatephi design; recorded worst
         59.7 d, Arb-certified).  Recorded value gates: 40.06/40.05 d at
         1/3, 1/2, NEVER-USED 40.03 d (3/11), 40.12 d (5/13).
  SUM    F^ell = F^K1 + F^R2 + F^red1, plain sum, no extra prefactors
         (CLOSURE_FINAL.json conventions; each piece carries its own
         normalization internally).  The sum IS independently gated: the
         this work recorded a DIRECT two-fold quadrature oracle of the full
         eq.(19) elliptic integrand (oracle_zeta_*_dps50.json at 1/7,
         1/5, 1/3, 1/2, 2/3, 4/5 and oracle_zeta_{3_11,5_13}_dps100.json
         at the never-used angles) that never touches the decomposition;
         the live sum must match it at the run bar, fail-closed.

HONEST STATUS (result CLOSED; the genuinely-open side items, exactly)
=======================================================================
  The final F^ell is closed in known functions (the page/paper of
  record): 159-word F^K1 with derived coefficients, closed F^R2
  one-fold, exact 112-word F^red1 -- the second-kind content closes on
  exact relations and T0/T2 do NOT enter the final form.  What remains
  open, honestly:
  * The two F^K1 moment constants T0, T2 remain OPEN: archived 100-digit
    PSLQ searches saturate honestly with no closed form (CLOSURE_FINAL
    open_constants).  Nothing here claims them.
  * The F^red1 symbolic zeta-GPL lift (zeta-alphabet {ze,1-ze,2-ze}
    derived; fibration engine) remains open; the 112-word t-fold above is
    the exact recorded machine truth for the zb-integrand.
  * L_sun[F^ell] does NOT close in the weight-<=3 NLO alphabet (honest
    negative, CLOSURE_REPORT.md); the eMPL/modular source basis is the
    open route.  This script EVALUATES the certified pieces; it closes
    no new constants.

FAIL-CLOSED CERTIFICATION (per run)
===================================
  (a) sha256 pin of fk1_words.json on EVERY load (absent = exit 4,
      mutated = exit 2) -- primary tamper gate of the F^K1 data; the
      vendored F^R2 rational (PF_R.json A2_reducible) and the vendored
      112-word F^red1 form are self-pinned in-file the same way.
  (b) F^K1: per-run LIVE spot gate of the 12-block form vs certified
      quadrature of the K1 integrand (4 spot zb, bar max(dps+2, 32) d)
      + two-height ledger escalation (agree >= dps+2 d) + exact
      M-identity closure -- the fk1-evaluate.py design, ported intact.
  (c) F^R2: split-vs-combined pointwise identity, PF pointwise identity
      (outer*R2 == a2/D_K2 + red2), z(s+-)=1/zb, Moebius period identity
      int_0^1 dzb/sqrt(disc2) == int_{-inf}^0 du/sqrt(Q(u)) (all live),
      + two-height outer ledger + value gate vs the recorded oracle.
  (d) F^red1: exact sympy identities of the t-fold (red1 kernel, -z and
      1-z factorizations, dlog z) + LIVE 112-word gate Phi == P1 at
      recorded spot points (two-resolution spectral GPL certificate)
      + two-height outer ledger + value gate vs the recorded oracle.
  (e) SUM gate vs the recorded direct F^ell oracle (independent leg).
  Every gate misses = named refusal, nonzero exit, no value printed.

EXIT CODES (named refusals)
===========================
  0  all gates passed;  2  data-pin refusal (byte-level mutation of
  pinned/vendored data);  3  gate/certificate refusal (a numeric gate or
  fail-closed loop missed its bar);  4  missing data (fk1_words.json
  absent, or --point without a recorded oracle).

INTERFACE
=========
  --point P/Q   one of the recorded kinematic points 1/7, 1/5, 1/3, 1/2,
                2/3, 4/5, 3/11, 5/13 (default 1/3; 3/11 and 5/13 were
                never used in the construction; at 4/5 only --piece fr2/fred1
                are served -- outside the F^K1 word hull, exit 4
                otherwise).  Other points are refused
                (exit 4): every printed digit here is gated against a
                recorded oracle, and no oracle exists elsewhere.
  --dps D       the certified-digit crank (default 14; --dps 28
                reproduces the deeper pre-2026-09-03 default).  All
                internal bars scale with D; the reference-oracle gate
                bar is min(D-2, cap-4) with cap the per-point reference
                depth quoted in BANK below.
  Usage errors (malformed flags, --dps < 12) exit 1 (plain argparse/
  SystemExit) -- outside the named 2/3/4 refusal contract by design.
  --piece X     fk1 | fr2 | fred1 | all (default all; 'all' also gates
                the sum).
  --workers N   parallel workers (default min(16, cpu)).
  --raw         print full working precision instead of the <=10-digit
                certified-print policy.
  --check [S]   crank test: rerun at dps D+S (default +8) and require
                >= D-digit value agreement per piece, fail-closed.
  --selftest    mutation controls ONLY (one dent per piece, in-memory,
                disk untouched, each dent must be CAUGHT) + positive
                controls; then exit.

MEASURED WALLS (2026-07-27, 16 workers, at the then-default dps 28)
===================================================================
  F^K1 word path      49-69 s/point  (incl. 4-spot live gate; two-height
                                      ledgers 21-27 s each)
  F^R2 one-fold       18-26 s/point  (incl. exact identities; ledgers
                                      7-10 s each, md 7)
  F^red1 one-fold     105-111 s/pt   (dominated by the 112-word GPL gate
                                      ~80 s + sympy exact stage ~20 s;
                                      the value ledgers are 7-9 s each)
  full default run    173-205 s/pt   (gate_full_{1_3,1_2}_d28.log,
                                      recorded)
  --selftest          82 s
  Every piece is far under the 10-min/point stop bar.  dps-14
  probes: fk1 17 s, fr2 5 s, fred1 61 s.  dps 40+ multiplies the inner
  folds several-fold (md 8) -- measure before you commit.

MEASURED WALLS AT THE CURRENT DEFAULT (dps 14, 2026-09-03 run, log
stamps 04:47:33Z..04:54:51Z UTC, ~5.8x CPU-oversubscribed machine)
===================================================================
  full default run    430.1 s wall / 369.7 s user CPU under that load
                      (per piece: fr2 38.0 s, fk1 91.0 s, fred1
                      298.9 s); the near-idle dps-14 piece probes above
                      sum to ~83 s.  The first gated value (F^R2)
                      printed at 31-38 s even under load.
  --dps 28 --point 1/3  1190.4 s wall under the same load (near-idle
                      2026-07-27 record: 173-205 s/pt); reproduces the
                      pre-2026-09-03 default output values exactly.
  --selftest          536.3 s under that load (82 s near-idle,
                      2026-07-27).

PROVENANCE OF EVERY RECORDED NUMBER EMBEDDED BELOW (sha256 of the sources)
==========================================================================
  CLOSURE.json                    043bd76b55dd272cae15bca3
    (F^K1, F^R2 dps50 values at 1/7,1/5,1/3,1/2,2/3,4/5)
  gate_3_11_dps40.json            c6e051fe94774d8eee054705
  gate_5_13_dps40.json            13cca2402ffb5882ad9df47e
    (never-used-point F^K1, F^R2 at dps40/md7)
  close8_red1_targets.json        957175de9d7c6d7f07cbfdae
  Fred1_dps50.json                6c479510a68bc9720179c00b
    (F^red1 recorded targets incl. the never-fitted 3/11, 5/13)
  oracle_values.json              a6bcf4abe27c7c23a244c177
  oracle_zeta_1_3_dps50.json      72d9a8709afe431c7824246c
  oracle_zeta_1_2_dps50.json      0148bda621c43b8bd1830780
  oracle_zeta_3_11_dps100.json    f45cdae121c8684dd4991526
  oracle_zeta_5_13_dps100.json    fea750881c6aa0d78dfaa2f8
    (direct F^ell oracle; dps100 at the never-used angles)
  PF_R.json                       7db5b37d9a45dd03446a7016
    (A2_reducible rational, verified to 8.3e-51 in-bank)
  close9_red1_form.json           b22a21c33e7b632d0eae062d
    (the 112 phi words, coefficients EXACT in Q[C0,CB1,CB2,CL2,CL3,CS12])
  close5_fr2_gate.json            769a369ca32611e6c6824c99
    (F^R2 one-fold recorded gates 38.0/37.6/32.47/32.72 d)
  close9_red1_gate.json           8916c6a24a20e505e110f463
    (F^red1 gatef 40d incl. the never-used angles; gatephi 59.7d worst;
     exact stage)
  blog/files/eec/fk1-evaluate.py                1ae3fc29efaf5979afc3f8f8
    (the ported F^K1 word engine + gate design -- OP3 closure of record;
     sha refreshed 2026-09-03: page-speed default + liveness edit, then a
     comment-only vocabulary edit; numeric engine unchanged)
  blog/files/eec/fk1_words.json                 77dfc3a3b80e1774c79fa314
    (pinned OP3 word data, REUSED in place, never duplicated)
  (the shas above identify the source files wherever they sit; the same
   content accompanies the papers as ancillary material.  Recorded values
   are embedded verbatim -- transcribed, never re-derived.)

Changelog:
  2026-07-27  created: single-file F^ell assembly of the
              three certified pieces, per-piece recorded-oracle gates,
              live 112-word GPL gate, mutation selftests, exit-code
              refusal contract.
  2026-09-03  page-speed default (no numeric path touched): default dps
              28 -> 14 and the pieces now run cheapest first (fr2, fk1,
              fred1), so the first gated value prints inside a minute;
              stdout line-buffered at startup; runtime gate labels
              gate labels renamed to recorded- (text only).  --dps 28
              --point 1/3 reproduces the old default's printed values
              and gate digits exactly (verified against a pre-change
              run, 2026-09-03).  All bars, gates, refusal exits, and
              --selftest semantics unchanged.
"""
import argparse
import hashlib
import json
import math
import multiprocessing
import os
import re
import sys
import time
from fractions import Fraction

import mpmath as mp
from mpmath.calculus.quadrature import TanhSinh

EXIT_OK, EXIT_PIN, EXIT_GATE, EXIT_MISSING = 0, 2, 3, 4


class PinRefusal(RuntimeError):
    """Byte-level mutation of pinned/vendored data (exit 2)."""


class GateRefusal(RuntimeError):
    """A numeric gate or fail-closed loop missed its bar (exit 3)."""


class MissingRefusal(RuntimeError):
    """Required data absent: words file or recorded oracle (exit 4)."""


# CertFail = the ported fk1-evaluate.py fail-closed loop refusal; it is a
# gate-class failure here (exit 3)
class CertFail(GateRefusal):
    """Fail-closed refusal: a loop could not certify its bound."""


# ---------------------------------------------------------------------------
# recorded kinematic points and gate references (copied unchanged from
# this work's record; provenance + shas in the module docstring).  Each entry
# is (value_string, cap) where cap = conservative recorded reference depth in
# digits; the gate bar at run depth D is min(D-2, cap-4).  F^K1/F^R2 real
# parts of the recorded complex values (Im ~ 1e-57..1e-66, pure quadrature
# noise); F^red1 and F^ell recorded real.
# ---------------------------------------------------------------------------
BANK = {
    "1/7": {
        "fk1": ("-1.8501222165679207988504438815196576813233425252049", 44),
        "fr2": ("0.030142704931329996620356768548236208460021534071593", 40),
        "fred1": ("2.1033233900541537917326659431025873564490918917462", 42),
        "fell": ("0.28334387841756298950257883013116588358577090061286", 46),
    },
    "1/5": {
        "fk1": ("-1.5886382204050879840808939283042024165727970526932", 44),
        "fr2": ("0.047762734172337599119431126224156944076896991924527", 40),
        "fred1": ("1.9018414376175887555300245677046721076999459381177", 42),
        "fell": ("0.36096595138483837056856176562462663520404587734904", 46),
    },
    "1/3": {
        "fk1": ("-1.1746496805608017006717615421736623125712374328952", 44),
        "fr2": ("0.087671112274538582629535731935491777536423761934332", 40),
        "fred1": ("1.5909194986349630932669143647842740558331739880641", 42),
        "fell": ("0.50394093034869997522468855454610352079836031710327", 46),
    },
    "1/2": {
        "fk1": ("-0.81575599140003673860308067682440555079447250566943", 44),
        "fr2": ("0.11962440573525472075833071057272225572567805263509", 40),
        "fred1": ("1.2985865457881284124050564280122418345751455464298", 42),
        "fell": ("0.60245496012334639456030646176055853950635109339545", 46),
    },
    "2/3": {
        "fk1": ("-0.52914792874792107774527159925013989699185800216906", 44),
        "fr2": ("0.11319639862505364981227865992053773908338132041595", 40),
        "fred1": ("0.99456533556376978990605342979628477414516857963689", 42),
        "fell": ("0.57861380544090236197306049046668261623669189788378", 46),
    },
    "4/5": {
        "fk1": ("-0.32219701832521983773272694629865578521623564378218", 44),
        "fr2": ("0.068842468520610184142743105160008307447733609000059", 40),
        "fred1": ("0.66880944669274589036539538075576380372733290107142", 42),
        "fell": ("0.4154548968881362367754115396171163259588308662893", 45),
    },
    # angles never used in the construction (never fitted anywhere)
    "3/11": {
        "fk1": ("-1.340792572448219742092414623141291431382", 36),
        "fr2": ("0.07031216088774001383028986387109094863082", 36),
        "fred1": ("1.7159125143626220665373846721910710158530919213687923768",
                  48),
        "fell": ("0.4454321028021423382752599129208705331014328251062582584341"
                 "175737626516507664254747776226077543465159", 90),
    },
    "5/13": {
        "fk1": ("-1.052214967577320721580928961416556067032", 36),
        "fr2": ("0.1004562802068244759454861909282185995333", 36),
        "fred1": ("1.4963540116415285321286321852386982887965755042558987894",
                  48),
        "fell": ("0.5445953242710322864931894147503608212981702428124586701313"
                 "642328065173411374207205459191305734098615", 90),
    },
}

# ---------------------------------------------------------------------------
# vendored F^R2 reducible rational: PF_R.json "A2_reducible" (sha256
# 7db5b37d9a45dd03..., in-bank PF verification 8.3e-51).  Embedded verbatim;
# self-pinned below and re-verified pointwise EVERY run by the PF identity
# outer*R2 == a2/D_K2 + red2 (selftest bar 1e-35 at wp 50).
# ---------------------------------------------------------------------------
RED2_STR = (
    "(-t**2*zb**2*zeta**2 + t**2*zb**2*zeta + 2*t**2*zb*zeta**2 - "
    "2*t**2*zb*zeta + t*zb**3*zeta**2 - t*zb**3*zeta - 2*t*zb**2*zeta**2 + "
    "3*t*zb**2*zeta - t*zb**2 - t*zb*zeta**2 + t*zb*zeta + zb**2*zeta**2 - "
    "2*zb**2*zeta + zb**2)/(t**4*zb**2*zeta**2 - 2*t**4*zb*zeta**2 + "
    "t**4*zeta**2 - 2*t**3*zb**3*zeta**2 + 2*t**3*zb**3*zeta + "
    "2*t**3*zb**2*zeta**2 - 4*t**3*zb**2*zeta + 2*t**3*zb*zeta**2 + "
    "2*t**3*zb*zeta - 2*t**3*zeta**2 + t**2*zb**4*zeta**2 - "
    "2*t**2*zb**4*zeta + t**2*zb**4 + 2*t**2*zb**3*zeta**2 - 2*t**2*zb**3 - "
    "6*t**2*zb**2*zeta**2 + 6*t**2*zb**2*zeta + t**2*zb**2 + "
    "2*t**2*zb*zeta**2 - 4*t**2*zb*zeta + t**2*zeta**2 - 2*t*zb**4*zeta**2 + "
    "4*t*zb**4*zeta - 2*t*zb**4 + 2*t*zb**3*zeta**2 - 6*t*zb**3*zeta + "
    "4*t*zb**3 + 2*t*zb**2*zeta**2 - 2*t*zb**2 - 2*t*zb*zeta**2 + "
    "2*t*zb*zeta + zb**4*zeta**2 - 2*zb**4*zeta + zb**4 - 2*zb**3*zeta**2 + "
    "4*zb**3*zeta - 2*zb**3 + zb**2*zeta**2 - 2*zb**2*zeta + zb**2)"
)

# ---------------------------------------------------------------------------
# vendored F^red1 112-word t-fold (close9_red1_form.json "phi_words", sha256
# b22a21c33e7b632d... of the source file; the compact word dict below is
# self-pinned by RED1_PHI_SHA and refuses on any byte change).  Letters:
# '0'->0, 'b'->zb, '1'->1, 's'->t6=-zb(1-ze)/ze, 'p'->tstar=(1-ze)zb/(zb-ze).
# Constants: C0=log(ze/(1-ze)), CB1=log zb, CB2=log(1-zb), CL2=Li2(1-zb),
# CL3=Li3(1-zb), CS12=S12(1-zb).  EXACT rational-linear coefficients.
# ---------------------------------------------------------------------------
RED1_PHI_JSON = (
    '{"":"-C0**2*CB1/8 - C0*CB1*CB2/4 - C0*CL2/2 + CB1**3/24 + CB1**2*CB2/8 '
    '+ CB1*CL2/4 - CB2*CL2/4 + 3*CL3/4 + CS12/4","0":"-C0*CB1/4 - CB1*CB2/4 '
    '- CL2/2","00":"-CB1/4","01":"-C0/4","010":"-1/4","011":"-1/4",'
    '"01b":"-1/4","01p":"1/2","01s":"-1/4","0b":"-CB1/4","0p":"C0/4 + CB1/4",'
    '"0p0":"1/4","0p1":"1/4","0pb":"1/4","0pp":"-1/2","0ps":"1/4",'
    '"0s":"-C0/4","0s0":"-1/4","0s1":"-1/4","0sb":"-1/4","0sp":"1/2",'
    '"0ss":"-1/4","1":"C0**2/8 + C0*CB2/4 - CB1**2/8 - CB1*CB2/4 - CL2/4",'
    '"10":"C0/4 + CB2/4","100":"1/4","10b":"1/4","10p":"-1/4",'
    '"11":"CB1/4 + CB2/4","111":"-1/4","11p":"1/4","11s":"-1/4",'
    '"1b":"C0/4 + CB2/4","1b0":"1/4","1bb":"1/4","1bp":"-1/4",'
    '"1p":"-C0/4 - CB1/4 - CB2/2","1p0":"-1/4","1p1":"1/4","1pb":"-1/4",'
    '"1ps":"1/4","1s":"CB1/4 + CB2/4","1s1":"-1/4","1sp":"1/4","1ss":"-1/4",'
    '"b":"-C0*CB1/4 - CB1*CB2/4 - CL2/2","b0":"-CB1/4","b1":"-C0/4",'
    '"b10":"-1/4","b11":"-1/4","b1b":"-1/4","b1p":"1/2","b1s":"-1/4",'
    '"bb":"-CB1/4","bp":"C0/4 + CB1/4","bp0":"1/4","bp1":"1/4","bpb":"1/4",'
    '"bpp":"-1/2","bps":"1/4","bs":"-C0/4","bs0":"-1/4","bs1":"-1/4",'
    '"bsb":"-1/4","bsp":"1/2","bss":"-1/4",'
    '"p":"-C0**2/8 + C0*CB1/4 - C0*CB2/4 + CB1**2/8 + CB1*CB2/2 + 3*CL2/4",'
    '"p0":"-C0/4 + CB1/4 - CB2/4","p00":"-1/4","p0b":"-1/4","p0p":"1/4",'
    '"p1":"C0/4 - CB1/4 - CB2/4","p10":"1/4","p11":"1/2","p1b":"1/4",'
    '"p1p":"-3/4","p1s":"1/2","pb":"-C0/4 + CB1/4 - CB2/4","pb0":"-1/4",'
    '"pbb":"-1/4","pbp":"1/4","pp":"CB2/2","pp1":"-1/2","ppp":"1/2",'
    '"pps":"-1/2","ps":"C0/4 - CB1/4 - CB2/4","ps0":"1/4","ps1":"1/2",'
    '"psb":"1/4","psp":"-3/4","pss":"1/2",'
    '"s":"C0**2/8 + C0*CB2/4 - CB1**2/8 - CB1*CB2/4 - CL2/4",'
    '"s0":"C0/4 + CB2/4","s00":"1/4","s0b":"1/4","s0p":"-1/4",'
    '"s1":"CB1/4 + CB2/4","s11":"-1/4","s1p":"1/4","s1s":"-1/4",'
    '"sb":"C0/4 + CB2/4","sb0":"1/4","sbb":"1/4","sbp":"-1/4",'
    '"sp":"-C0/4 - CB1/4 - CB2/2","sp0":"-1/4","sp1":"1/4","spb":"-1/4",'
    '"sps":"1/4","ss":"CB1/4 + CB2/4","ss1":"-1/4","ssp":"1/4","sss":"-1/4"}'
)
RED1_PHI_SHA = ("81697031d795c717303671442c9a2ebe"
                "30cbb39be51ce03adaa5970861abf368")
# self-pin of RED2_STR above (sha256 of the embedded string; the SOURCE
# file PF_R.json has its own sha in the provenance table)
RED2_SHA = ("7588a028385ac2b108f29720f7a2184a"
            "e327382a646fab0f3ca8a7675f188dc6")


# ===========================================================================
# SECTION 1: F^K1 -- OP3 symbolic word form + live quadrature oracle layer.
# Ported from fk1-evaluate.py (sha256 1ae3fc29efaf5979... as shipped
# 2026-09-03; numeric engine unchanged since the OP3 closure of record);
# same formulas, same panel structure, same fail-closed design.
# ===========================================================================
WORDS_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                          "fk1_words.json")
WORDS_SHA256 = ("77dfc3a3b80e1774c79fa3144cf93726"
                "c43311e5b6ad3062d22d773eb893cc77")
# evidence-gated hull of the word form (fk1-evaluate.py 8-point battery,
# 2026-07-07: >= 30 d at 1/10, 1/7, 3/11, 1/3, 5/13, 1/2, 3/5, 3/4,
# measured 36.0-41.6 d).  Every BANK point lies inside it EXCEPT 4/5:
# there F^K1/full-sum runs are refused (named, exit 4) and only
# --piece fr2 / fred1 are served.
WORD_ZLO, WORD_ZHI = Fraction(1, 10), Fraction(3, 4)
WORD_SPOT_ZB = ("0.19", "0.53", "0.81", "0.97")   # 0.97 = panel regime
WORD_MUT_EXP = 32
WORD_GUARD = 10
WP_EXTRA = 12
DEPTH_EXTRA = 5
INNER_DROP = 2
G_ORC = 6

W_BLOCK_MONOS = [(2, 1, 0, 0, 0), (2, 0, 0, 0, 0), (1, 1, 0, 0, 0),
                 (1, 0, 1, 0, 0), (1, 0, 0, 0, 0), (0, 3, 0, 0, 0),
                 (0, 2, 0, 0, 0), (0, 1, 0, 0, 0), (0, 0, 1, 0, 0),
                 (0, 0, 0, 1, 0), (0, 0, 0, 0, 1), (0, 0, 0, 0, 0)]


def digits(a, b):
    """-log10 |a-b|/|b|: measured agreement in decimal digits."""
    if a == b:
        return float('inf')
    return float(-mp.log10(abs((a - b) / b)))


def _mpq(fr):
    return mp.mpf(fr.numerator) / fr.denominator


_TS = None


def _rule():
    global _TS
    if _TS is None:
        _TS = TanhSinh(mp.mp)
    return _TS


def cert_quad(f, a, b, tol_exp, wp, tag=""):
    """Certified quadrature: refine-until-bound, fail-closed (ported)."""
    prec = int(wp * 3.3333) + 10
    with mp.workprec(prec):
        a, b = mp.convert(a), mp.convert(b)
        if a == b:
            return mp.mpf(0), mp.mpf(0), 0
        tol = mp.mpf(10) ** (-tol_exp)
        rule = _rule()
        cap = max(rule.guess_degree(prec), 3) + DEPTH_EXTRA
        results, agr = [], None
        for depth in range(1, cap + 1):
            nodes = rule.get_nodes(a, b, depth, prec)
            I = rule.sum_next(f, nodes, depth, prec, results)
            results.append(I)
            if not (mp.isfinite(mp.re(I)) and mp.isfinite(mp.im(I))):
                raise CertFail(
                    "[%s] certified quadrature FAILED (fail-closed): "
                    "non-finite level sum at depth %d on [%s, %s]" %
                    (tag, depth, mp.nstr(a, 8), mp.nstr(b, 8)))
            if depth >= 2:
                agr = abs(results[-1] - results[-2])
                if agr <= tol:
                    return results[-1], agr, depth
        raise CertFail(
            "[%s] certified quadrature FAILED (fail-closed): agreement %s "
            ">= tol %s at depth cap %d (wp %d) on [%s, %s]" %
            (tag, mp.nstr(agr, 3), mp.nstr(tol, 3), cap, wp,
             mp.nstr(a, 8), mp.nstr(b, 8)))


def _S12(x):
    """Nielsen S_{1,2}(x)."""
    return (-mp.polylog(3, 1 - x) + mp.log(1 - x) * mp.polylog(2, 1 - x)
            + mp.mpf(1) / 2 * mp.log(x) * mp.log(1 - x) ** 2 + mp.zeta(3))


def D_K(t, zb, zeta):
    return (1 - t) * (1 - zb) * zb + zeta * (t - zb) * (1 - t - zb)


def _zb_consts(zb):
    """zb-constant HPL block shared by P1 (both prefactors) and P2."""
    S12_1zb = _S12(1 - zb)
    Li2_1zb = mp.polylog(2, 1 - zb)
    return (-mp.log(zb),                                # H1_1zb
            -mp.log(1 - zb),                            # H1zb
            Li2_1zb,                                    # H2_1zb
            mp.polylog(3, 1 - zb),                      # H3_1zb
            mp.log(zb) ** 2 / 2,                        # H11_1zb
            -mp.log(zb) * Li2_1zb - 2 * S12_1zb,        # H12_1zb
            S12_1zb,                                    # H21_1zb
            -mp.log(zb) ** 3 / 6)                       # H111_1zb


def make_inner_P1(zb, zeta):
    """ORACLE-layer P1(z(t,zb),zb) with hoisted zb-HPLs; returns f(t) ->
    (z, P1) or (None, 0) at endpoint-rounded nodes.  Transcribed from
    fk1-evaluate.py make_inner_K1 (P1 body identical; the prefactor is
    applied by the wrappers below so F^K1 and F^red1 share one layer)."""
    (H1_1zb, H1zb, H2_1zb, H3_1zb, H11_1zb, H12_1zb, H21_1zb,
     H111_1zb) = _zb_consts(zb)

    def f(t):
        if t <= 0 or t >= zb:
            return None, mp.mpf(0)
        # cancellation-free den (fk1-evaluate.py form)
        den = zeta * (t - zb) + zb * (1 - t)
        z = zeta * t * (t - zb) / den
        H0mz = mp.log(-z)
        L1z = mp.log(1 - z)
        H1z = -L1z
        H2z = mp.polylog(2, z)
        H3z = mp.polylog(3, z)
        H11z = L1z ** 2 / 2
        H21z = _S12(z)
        H111z = -L1z ** 3 / 6
        p1 = -(
            H0mz ** 2 * (H1z - H1_1zb)
            + 4 * H0mz * (-H2z + H2_1zb)
            + 2 * H1zb * (-(H1z * H1_1zb) + H0mz * (-H1z + H1_1zb)
                          + H2z - H2_1zb + H11z + H11_1zb)
            + 2 * (3 * H3z - 3 * H3_1zb + H1_1zb * H11z
                   - H1z * (H2_1zb + H11_1zb)
                   + H12_1zb + H21z + H21_1zb - H111z + H111_1zb)
        ) / 8
        return z, p1
    return f


def make_inner_K1(zb, zeta):
    """K1-piece inner integrand (a1/D_K)*P1 (the fk1-evaluate.py oracle)."""
    a1 = -zb * (zb - 1) * (zeta - 1)
    P1f = make_inner_P1(zb, zeta)

    def f(t):
        z, p1 = P1f(t)
        if z is None:
            return mp.mpf(0)
        return a1 / D_K(t, zb, zeta) * p1
    return f


def make_inner_red1(zb, zeta):
    """F^red1 inner integrand red1*P1, red1 = zb(1-ze)/den (the recorded
    close9_red1_analytic.py machine truth; rational kernel, no elliptic
    content)."""
    P1f = make_inner_P1(zb, zeta)

    def f(t):
        z, p1 = P1f(t)
        if z is None:
            return mp.mpf(0)
        den = zeta * (t - zb) + zb * (1 - t)
        return zb * (1 - zeta) / den * p1
    return f


def P1_deriv_layer(z, zb):
    """SECOND, independent transcription of P1 (from the source
    derivative layer dintegrand2._P1_d2); cross-checked pointwise vs the
    oracle layer every run."""
    L1 = mp.log(1 - z)
    Li2 = mp.polylog(2, z)
    Li3 = mp.polylog(3, z)
    H0mz = mp.log(-z)
    H1z = -L1
    H2z = Li2
    H3z = Li3
    H11z = L1 ** 2 / 2
    H21z = _S12(z)
    H111z = -L1 ** 3 / 6
    H1_1zb = -mp.log(zb)
    H1zb = -mp.log(1 - zb)
    H2_1zb = mp.polylog(2, 1 - zb)
    H3_1zb = mp.polylog(3, 1 - zb)
    H11_1zb = mp.log(zb) ** 2 / 2
    H12_1zb = -mp.log(zb) * mp.polylog(2, 1 - zb) - 2 * _S12(1 - zb)
    H21_1zb = _S12(1 - zb)
    H111_1zb = -mp.log(zb) ** 3 / 6
    return -(
        H0mz ** 2 * (H1z - H1_1zb) + 4 * H0mz * (-H2z + H2_1zb)
        + 2 * H1zb * (-(H1z * H1_1zb) + H0mz * (-H1z + H1_1zb)
                      + H2z - H2_1zb + H11z + H11_1zb)
        + 2 * (3 * H3z - 3 * H3_1zb + H1_1zb * H11z
               - H1z * (H2_1zb + H11_1zb)
               + H12_1zb + H21z + H21_1zb - H111z + H111_1zb)
    ) / 8


def Qquartic(u, zeta):
    return (u ** 4 - 2 * u ** 3 + (4 * zeta ** 2 - 2 * zeta + 1) * u ** 2
            - (4 * zeta ** 2 - 2 * zeta) * u + zeta ** 2)


def fk1_direct(fr, D, guard, tag):
    """Certified two-fold F^K1(zeta): the independent oracle route
    (ported verbatim)."""
    wp = D + guard + WP_EXTRA
    inner_exp = D + guard + INNER_DROP
    with mp.workprec(int(wp * 3.3333) + 10):
        zeta = _mpq(fr)
        floor = mp.mpf(10) ** (-(wp - 6))

        def outer(zb):
            if zb <= floor or 1 - zb <= floor:
                return mp.mpf(0)
            f = make_inner_K1(zb, zeta)
            v, _, _ = cert_quad(f, mp.mpf(0), zb, inner_exp, wp,
                                tag=tag + ".inner")
            return v

        val, agr, depth = cert_quad(outer, 0, 1, D + guard, wp, tag=tag)
        bound = (agr + mp.mpf(10) ** (-inner_exp) + abs(mp.im(val))
                 + mp.mpf(10) ** (-(wp - 6)) * max(mp.mpf(1), abs(val)))
        return mp.re(val), bound, depth


# ---- word data: exact Fraction-polynomial parser (ported) ------------------
class _WPoly(object):
    __slots__ = ("d",)

    def __init__(self, d):
        self.d = {k: v for k, v in d.items() if v != 0}

    @staticmethod
    def _as(o):
        if isinstance(o, _WPoly):
            return o
        return _WPoly({(0, 0, 0, 0, 0): Fraction(o)})

    def __add__(self, o):
        o = self._as(o)
        d = dict(self.d)
        for k, v in o.d.items():
            d[k] = d.get(k, Fraction(0)) + v
        return _WPoly(d)
    __radd__ = __add__

    def __neg__(self):
        return _WPoly({k: -v for k, v in self.d.items()})

    def __sub__(self, o):
        return self + (-self._as(o))

    def __rsub__(self, o):
        return self._as(o) + (-self)

    def __mul__(self, o):
        o = self._as(o)
        d = {}
        for k1, v1 in self.d.items():
            for k2, v2 in o.d.items():
                k = tuple(a + b for a, b in zip(k1, k2))
                d[k] = d.get(k, Fraction(0)) + v1 * v2
        return _WPoly(d)
    __rmul__ = __mul__

    def __truediv__(self, o):
        if isinstance(o, _WPoly):
            if list(o.d.keys()) != [(0, 0, 0, 0, 0)]:
                raise PinRefusal("word data parse: division by non-constant")
            o = o.d[(0, 0, 0, 0, 0)]
        return self * Fraction(1, 1) * Fraction(o) ** -1

    def __pow__(self, n):
        n = int(Fraction(n))
        out = _WPoly({(0, 0, 0, 0, 0): Fraction(1)})
        for _ in range(n):
            out = out * self
        return out


def _parse_block_coeff(s):
    env = {"__builtins__": {}, "F": Fraction}
    for i, name in enumerate(("lz", "l1", "La2", "La3", "Si12")):
        e = [0, 0, 0, 0, 0]
        e[i] = 1
        env[name] = _WPoly({tuple(e): Fraction(1)})
    expr = re.sub(r"(?<![\w.])(\d+)(?![\w.])", r"F(\1)", s)
    val = eval(expr, env)                     # sha-pinned data only
    val = _WPoly._as(val)
    return [(v, k) for k, v in sorted(val.d.items())]


_WORDS_CACHE = {}


def load_word_data():
    """sha-pinned load of fk1_words.json.  Absent = exit 4 (missing);
    any byte-level mutation = exit 2 (pin).  Checked on EVERY load, in
    every worker process."""
    if "blocks" in _WORDS_CACHE:
        return _WORDS_CACHE["blocks"], _WORDS_CACHE["meta"]
    if not os.path.exists(WORDS_FILE):
        raise MissingRefusal(
            "word data MISSING (fail-closed): %s is ABSENT. The F^K1 "
            "word form cannot run without the pinned OP3 data file "
            "(sha256 %s...)." % (WORDS_FILE, WORDS_SHA256[:16]))
    raw = open(WORDS_FILE, "rb").read()
    sha = hashlib.sha256(raw).hexdigest()
    if sha != WORDS_SHA256:
        raise PinRefusal(
            "word data REFUSED (fail-closed): sha256 of %s is %s, pinned "
            "OP3 value is %s. The file was modified -- re-vendor it from "
            "the OP3 closure of record." % (WORDS_FILE, sha, WORDS_SHA256))
    d = json.loads(raw.decode())
    if len(d["words"]) != 159 or not d["meta"].get("no_fitted_coefficients"):
        raise PinRefusal("word data REFUSED: structure check failed "
                         "(need 159 words, no_fitted_coefficients=true)")
    monos = [tuple(b["mono"]) for b in d["blocks"]]
    if monos != W_BLOCK_MONOS:
        raise PinRefusal("word data REFUSED: block monomial order mismatch")
    blocks = [_parse_block_coeff(b["coeff"]) for b in d["blocks"]]
    _WORDS_CACHE["blocks"] = blocks
    _WORDS_CACHE["meta"] = d["meta"]
    return blocks, d["meta"]


# ---- tanh-sinh / Gauss-Legendre node machinery (ported verbatim) ----------
def w_ts_nodes(h, tmax, wcut):
    out = []
    k = 0
    while True:
        tk = mp.mpf(k) * h
        if tk > tmax:
            break
        sh = mp.pi / 2 * mp.sinh(tk)
        ch = mp.cosh(sh)
        w = h * (mp.pi / 4) * mp.cosh(tk) / ch ** 2
        ex = mp.exp(-2 * sh)
        xm = 1 / (1 + ex)
        xm_c = ex / (1 + ex)
        if k == 0:
            out.append((mp.mpf("0.5"), mp.mpf("0.5"), w))
        else:
            if w > wcut:
                out.append((xm, xm_c, w))
                out.append((xm_c, xm, w))
        if w < wcut and k > 8:
            break
        k += 1
    return out


_W_GL_CACHE = {}


def w_gl_nodes(n):
    key = (n, mp.mp.dps)
    if key in _W_GL_CACHE:
        return _W_GL_CACHE[key]
    old = mp.mp.dps
    mp.mp.dps = old + 12
    nodes = []
    for i in range(1, n // 2 + 1):
        x = mp.cos(mp.pi * (i - mp.mpf(1) / 4) / (n + mp.mpf(1) / 2))
        dp = mp.mpf(1)
        for _ in range(60):
            p0, p1 = mp.mpf(1), x
            for k in range(2, n + 1):
                p0, p1 = p1, ((2 * k - 1) * x * p1 - (k - 1) * p0) / k
            dp = n * (x * p1 - p0) / (x ** 2 - 1)
            dx = p1 / dp
            x -= dx
            if abs(dx) < mp.mpf(10) ** (-(old + 8)):
                break
        w = 2 / ((1 - x ** 2) * dp ** 2)
        nodes.append((x, w))
        nodes.append((-x, w))
    if n % 2:
        x = mp.mpf(0)
        p0, p1 = mp.mpf(1), x
        for k in range(2, n + 1):
            p0, p1 = p1, ((2 * k - 1) * x * p1 - (k - 1) * p0) / k
        dp = n * (x * p1 - p0) / (x ** 2 - 1)
        nodes.append((x, 2 / dp ** 2))
    mp.mp.dps = old
    nodes = [(mp.mpf(x), mp.mpf(w)) for x, w in nodes]
    _W_GL_CACHE[key] = nodes
    return nodes


_W_TS_CACHE = {}


def w_ts_cached(h_denom, wcut_exp):
    key = (h_denom, wcut_exp, mp.mp.dps)
    if key not in _W_TS_CACHE:
        _W_TS_CACHE[key] = w_ts_nodes(mp.mpf(1) / h_denom, mp.mpf("7.5"),
                                      mp.mpf(10) ** (-wcut_exp))
    return _W_TS_CACHE[key]


_W_HARM = [mp.mpf(0)]


def _w_harm(n):
    while len(_W_HARM) <= n:
        _W_HARM.append(_W_HARM[-1] + mp.mpf(1) / len(_W_HARM))
    return _W_HARM[n]


def w_S12_neg(zv):
    X = 1 - zv
    Lx = mp.log(X)
    ix = 1 / X
    ReLi2X = mp.pi ** 2 / 3 - Lx ** 2 / 2 - mp.polylog(2, ix)
    ReLi3X = mp.polylog(3, ix) - Lx ** 3 / 6 + mp.pi ** 2 * Lx / 3
    return (mp.zeta(3) - ReLi3X + Lx * ReLi2X + mp.log(-zv) * Lx ** 2 / 2)


def w_polyset(mz, nterms):
    zv = -mz
    L0 = mp.log(mz)
    L1 = mp.log1p(mz)
    if mz < mp.mpf("0.35"):
        s2 = mp.mpf(0)
        s3 = mp.mpf(0)
        s12 = mp.mpf(0)
        zk = mp.mpf(1)
        for k in range(1, nterms + 1):
            zk *= zv
            t2 = zk / k ** 2
            s2 += t2
            s3 += t2 / k
            if k >= 2:
                s12 += _w_harm(k - 1) * t2
        return (L0, L1, s2, s3, s12)
    return (L0, L1, mp.polylog(2, zv), mp.polylog(3, zv), w_S12_neg(zv))


def w_stable_consts(zbv, eps):
    if zbv < mp.mpf("0.5"):
        lz = mp.log(zbv)
        l1 = mp.log1p(-zbv)
    else:
        lz = mp.log1p(-eps)
        l1 = mp.log(eps)
    if eps <= mp.mpf("0.5"):
        La2 = mp.polylog(2, eps)
        La3 = mp.polylog(3, eps)
    else:
        La2 = mp.pi ** 2 / 6 - lz * l1 - mp.polylog(2, zbv)
        La3 = (mp.zeta(3) + lz ** 3 / 6 + mp.pi ** 2 * lz / 6
               - lz ** 2 * l1 / 2 - mp.polylog(3, zbv)
               - mp.polylog(3, 1 - 1 / zbv))
    Si = (-mp.polylog(3, zbv) + lz * mp.polylog(2, zbv)
          + l1 * lz ** 2 / 2 + mp.zeta(3))
    return lz, l1, La2, La3, Si


def w_coeff_vector(zbv, eps, blocks):
    consts = w_stable_consts(zbv, eps)
    out = []
    for terms in blocks:
        c = mp.mpf(0)
        for q, e in terms:
            m = mp.mpf(q.numerator) / q.denominator
            for v, k in zip(consts, e):
                for _ in range(k):
                    m *= v
            c += m
        out.append(c)
    return out


def w_panel_params(dps):
    if dps > 40:
        return 64, 64, 32
    return 48, 32, 24


def w_inner_vector(zbv, eps, zev, nodes_in, gl_fine, gl_tiny, ts_first_den):
    B = [mp.mpf(0)] * 12
    nterms = int(mp.mp.dps * 2.3) + 8

    def acc(mz, fac):
        vals = w_polyset(mz, nterms)
        for j, e in enumerate(W_BLOCK_MONOS):
            m = fac
            for v, p in zip(vals, e):
                for _ in range(p):
                    m *= v
            B[j] += m

    if eps > mp.mpf("0.05"):
        for s, sc, w in nodes_in:
            dd = sc * (1 - zev) + s * eps
            DKr = eps * (sc + s * eps) + zev * sc * (s - eps * (1 + s))
            mz = zev * s * sc * zbv / dd
            acc(mz, w / DKr)
        return B

    Mv = -zbv * eps + zev * (2 * zev - 1)
    sqQ = mp.sqrt(Mv ** 2 + 4 * zev ** 3 * (1 - zev))
    bKv = zev - zbv * eps
    cKv = zbv * eps * (1 - zev)
    tmv = -2 * cKv / (bKv + sqQ)
    Rv = zbv - tmv
    a = zbv * eps ** 2 / (zev * Rv)
    half = zbv / 2
    fine = eps > mp.mpf("1e-8")
    gl = w_gl_nodes(gl_fine if fine else gl_tiny)
    ts_first = w_ts_cached(ts_first_den, mp.mp.dps + 10)

    def fA(tv):
        den = tv * (zev - zbv) + (1 - zev) * zbv
        mz = zev * tv * (zbv - tv) / den
        DK = zev * (zbv + a - tv) * (tv - tmv)
        return mz, 1 / DK

    def fB(v):
        den = v * (1 - zev - eps) + zbv * eps
        mz = zev * (zbv - v) * v / den
        return mz, 1 / (zev * (a + v) * (Rv - v))

    for f, scale in ((fA, -8 * tmv), (fB, 8 * a)):
        p1 = min(scale, half)
        for s, sc, w in ts_first:
            x = p1 * s
            mz, dk = f(x)
            acc(mz, w * p1 * dk)
        p = p1
        while p < half:
            q = min(4 * p, half)
            c1 = (q - p) / 2
            c0 = (q + p) / 2
            for x, w in gl:
                mz, dk = f(c0 + c1 * x)
                acc(mz, w * c1 * dk)
            p = q
    return B


W_MOMENTS = ("S0", "S1", "S2", "SM")


def _word_task(arg):
    wp = arg["wp"]
    mp.mp.dps = wp
    blocks, _ = load_word_data()
    zev = mp.mpf(arg["p"]) / arg["q"]
    m_shift = 2 * zev ** 2 - zev
    glf, glt, tsd = w_panel_params(wp)
    wcut = mp.mpf(10) ** (-(wp + 12))
    no = w_ts_nodes(mp.mpf(1) / arg["h"], mp.mpf("7.5"), wcut)
    mine = no[arg["shard"]::arg["nshard"]]
    t0 = time.time()
    S = {k: mp.mpf(0) for k in W_MOMENTS}
    for zbv, eps, w in mine:
        B = w_inner_vector(zbv, eps, zev, no, glf, glt, tsd)
        C = w_coeff_vector(zbv, eps, blocks)
        kb = mp.fsum(C[j] * B[j] for j in range(12))
        S["S0"] += w * kb
        S["S1"] += w * zbv * kb
        S["S2"] += w * zbv * zbv * kb
        S["SM"] += w * (zbv * zbv - zbv + m_shift) * kb
    return {"n_mine": len(mine), "n_total": len(no),
            "sec": time.time() - t0,
            "moments": {k: mp.nstr(S[k], wp + 8) for k in W_MOMENTS}}


def word_ledger(fr, D, h, workers, verbose=True):
    wp = D + WORD_GUARD
    tasks = [{"p": fr.numerator, "q": fr.denominator, "wp": wp, "h": h,
              "shard": i, "nshard": workers} for i in range(workers)]
    t0 = time.time()
    if workers <= 1:
        res = [_word_task(a) for a in tasks]
    else:
        with multiprocessing.Pool(workers) as pool:
            res = pool.map(_word_task, tasks, chunksize=1)
    with mp.workprec(int(wp * 3.3333) + 10):
        S = {k: mp.mpf(0) for k in W_MOMENTS}
        for r in res:
            for k in W_MOMENTS:
                S[k] += mp.mpf(r["moments"][k])
    n = sum(r["n_mine"] for r in res)
    if n != res[0]["n_total"]:
        raise CertFail("word ledger shard accounting broken: %d != %d"
                       % (n, res[0]["n_total"]))
    if verbose:
        print("[fk1 ]      ledger h=1/%d (%d outer nodes, wp %d, %d workers):"
              " wall %.1f s" % (h, n, wp, workers, time.time() - t0))
    return S, n


def word_spot_gate(fr, D, verbose=True, blocks_override=None, spots=None,
                   bar_override=None):
    """Per-run LIVE gate of the pinned word data vs certified quadrature
    of the K1 integrand (ported; parametrized only so the --selftest
    mutation control can inject an in-memory dent)."""
    Dspot = bar_override if bar_override is not None else max(D + 2,
                                                             WORD_MUT_EXP)
    wp = Dspot + 14
    old_dps = mp.mp.dps
    worst = float("inf")
    try:
        mp.mp.dps = wp
        blocks, _ = load_word_data()
        if blocks_override is not None:
            blocks = blocks_override
        glf, glt, tsd = w_panel_params(wp)
        zev = mp.mpf(fr.numerator) / fr.denominator
        ni = w_ts_nodes(mp.mpf(1) / 28, mp.mpf("7.5"),
                        mp.mpf(10) ** (-(wp + 10)))
        for zb_s in (spots or WORD_SPOT_ZB):
            zbv = mp.mpf(zb_s)
            eps = 1 - zbv
            B = w_inner_vector(zbv, eps, zev, ni, glf, glt, tsd)
            C = w_coeff_vector(zbv, eps, blocks)
            K = mp.fsum(C[j] * B[j] for j in range(12))
            f = make_inner_K1(zbv, zev)
            v, _, _ = cert_quad(f, mp.mpf(0), zbv, Dspot + 4, wp,
                                tag="fk1.spot(zb=%s)" % zb_s)
            a1 = -zbv * (zbv - 1) * (zev - 1)
            Kref = mp.re(v) / a1
            d = digits(K, Kref)
            worst = min(worst, d)
            if d < Dspot:
                raise CertFail(
                    "F^K1 word SPOT GATE FAILED (fail-closed) at zb=%s, "
                    "zeta=%s: block-form K agrees with the live certified "
                    "quadrature to only %.1f d (bar %d d)."
                    % (zb_s, fr, d, Dspot))
    finally:
        mp.mp.dps = old_dps
    if verbose:
        print("[fk1 ]      spot gate: block-form K(zb) vs LIVE quadrature "
              "at %d spots: worst %.1f d (bar %d) -- PASS"
              % (len(spots or WORD_SPOT_ZB), worst, Dspot))
    return worst


def word_eval(fr, D, workers, verbose=True):
    """Word-form F^K1 at >= D certified digits (ported: two-height
    escalation + exact M-identity closure)."""
    wp = D + WORD_GUARD
    h0 = max(10, int(math.ceil((D + 4) / 2.0)))
    schedule = [h0, int(math.ceil(1.3 * h0)), int(math.ceil(1.69 * h0))]
    prev = None
    with mp.workprec(int(wp * 3.3333) + 10):
        zev = mp.mpf(fr.numerator) / fr.denominator
        for li, h in enumerate(schedule):
            S, n = word_ledger(fr, D, h, workers, verbose=verbose)
            fk1 = (zev - 1) * (S["S1"] - S["S2"])
            fk1_M = (zev - 1) * ((2 * zev ** 2 - zev) * S["S0"] - S["SM"])
            resid = abs(fk1 - fk1_M) / abs(fk1)
            if resid > mp.mpf(10) ** (-(D + 2)):
                raise CertFail(
                    "F^K1 word M-identity FAILED (fail-closed) at h=1/%d: "
                    "rel resid %s > 1e-%d" % (h, mp.nstr(resid, 3), D + 2))
            if prev is not None:
                agr = digits(fk1, prev)
                if verbose:
                    print("[fk1 ]      two-height agreement h=1/%d vs 1/%d: "
                          "%.1f d (bar %d); M-identity resid %s"
                          % (schedule[li - 1], h, agr, D + 2,
                             mp.nstr(resid, 2)))
                if agr >= D + 2:
                    return fk1, agr
            prev = fk1
    raise CertFail(
        "F^K1 word ledger FAILED (fail-closed): heights %s exhausted "
        "without two successive levels agreeing to %d d at zeta=%s."
        % (schedule, D + 2, fr))


# ===========================================================================
# SECTION 2: F^R2 -- the closed Moebius-mirror one-fold (the recorded
# close5_fr2_onefold.py closure of record).  Exact identities:
#   D_K2 = zb*ze*(t-s+)(t-s-),  s+- = (zb^2 ze - zb + ze +- sqrt(disc2))
#                                       / (2 zb ze)  [sign of -B],
#   disc2 = (zb-1)^4 * Q(zb/(zb-1); ze)   [same sunrise quartic],
#   1/D_K2 = (1/sqrt(disc2)) [1/(t-s+) - 1/(t-s-)],  z(s+-) = 1/zb exact.
# One-fold: Inner2 = (a2/sqrt(disc2))[J2(s+)-J2(s-)] + T_red; the split
# pieces are individually ~C/(1-zb)^2 at zb->1, the sum only ~log(1-zb):
# split form on eps=1-zb > FR2_DELTA, combined outer*R2*P2 on the tail
# (same pointwise integrand; hybrid evaluation only -- recorded design).
# ===========================================================================
FR2_DELTA = "0.01"       # split/combined hybrid boundary (record used 1e-3;
                         # 1e-2 costs ~4 cancellation digits, absorbed by
                         # the +12 working-precision guard, and keeps the
                         # sqrt-kernel split exercised on 99% of the range)
PIECE_GUARD = 12         # working dps = D + PIECE_GUARD on the ledgers


def disc2f(zb, ze):
    return (zb**4*ze**2 - 2*zb**3*ze - 2*zb**2*ze**2 + 4*zb**2*ze + zb**2
            - 2*zb*ze + ze**2)


def roots_s(zb, ze):
    """s+- with D_K2 = zb*ze*(t-s+)(t-s-) (transcribed)."""
    B = -zb**2*ze + zb - ze
    sq = mp.sqrt(disc2f(zb, ze))
    return (-B + sq)/(2*zb*ze), (-B - sq)/(2*zb*ze), sq


def a2f(zb, ze):
    return -zb*(ze - 1)/(zb - 1)**2


def zfun(t, zb, ze):
    return ze*t*(t - zb)/(t*(ze - zb) + (1 - ze)*zb)


def DK2f(t, zb, ze):
    return t**2*zb*ze - t*zb**2*ze + t*zb - t*ze + zb*ze - zb


def make_inner_P2(zb, ze):
    """ORACLE-layer P2(z(t,zb),zb) with hoisted zb-HPLs (transcribed from
    the source oracle_K2.make_inner_K2); returns f(t) -> (z, P2)."""
    Pi2 = mp.pi**2
    H1_1zb = -mp.log(zb)
    H1zb = -mp.log(1 - zb)
    H2_1zb = mp.polylog(2, 1 - zb)
    H3_1zb = mp.polylog(3, 1 - zb)
    H11_1zb = mp.log(zb)**2 / 2
    H111_1zb = -mp.log(zb)**3 / 6

    def f(t):
        if t <= 0 or t >= zb:
            return None, mp.mpf(0)
        den = ze * (t - zb) + zb * (1 - t)      # cancellation-free form
        z = ze * t * (t - zb) / den
        H0mz = mp.log(-z)
        L1z = mp.log(1 - z)
        H1z = -L1z
        H2z = mp.polylog(2, z)
        H3z = mp.polylog(3, z)
        H12z = -L1z * H2z - 2 * _S12(z)
        p2 = -(
            (2 * Pi2 * H1_1zb) / 3
            + (2 * Pi2 * H1zb) / 3
            + 2 * H0mz**2 * (-H1z - H1_1zb + H1zb)
            + 8 * H1zb * H2z
            - 8 * H1zb * H2_1zb
            - (4 * H0mz * (Pi2 + 3 * H1z * H1_1zb + 3 * H1_1zb * H1zb
                           - 6 * H2z + 6 * H2_1zb)) / 3
            - 16 * H3z - 16 * H3_1zb
            - H1z * ((2 * Pi2) / 3 + 8 * H1_1zb * H1zb + 8 * H2_1zb
                     - 4 * H11_1zb)
            - 4 * H1zb * H11_1zb
            - 8 * H12z
            + 4 * H111_1zb
        ) / 8
        return z, p2
    return f


def P2_deriv_layer(z, zb):
    """SECOND, independent transcription of P2 (source derivative layer
    dintegrand2._P2_d2); cross-checked pointwise vs the oracle layer."""
    Pi2 = mp.pi**2
    L1 = mp.log(1 - z)
    Li2 = mp.polylog(2, z)
    Li3 = mp.polylog(3, z)
    H0mz = mp.log(-z)
    H1z = -L1
    H2z = Li2
    H3z = Li3
    H12z = -L1 * Li2 - 2 * _S12(z)
    H1_1zb = -mp.log(zb)
    H1zb = -mp.log(1 - zb)
    H2_1zb = mp.polylog(2, 1 - zb)
    H3_1zb = mp.polylog(3, 1 - zb)
    H11_1zb = mp.log(zb)**2 / 2
    H111_1zb = -mp.log(zb)**3 / 6
    return -(
        (2 * Pi2 * H1_1zb) / 3 + (2 * Pi2 * H1zb) / 3
        + 2 * H0mz**2 * (-H1z - H1_1zb + H1zb) + 8 * H1zb * H2z
        - 8 * H1zb * H2_1zb
        - (4 * H0mz * (Pi2 + 3 * H1z * H1_1zb + 3 * H1_1zb * H1zb
                       - 6 * H2z + 6 * H2_1zb)) / 3
        - 16 * H3z - 16 * H3_1zb
        - H1z * ((2 * Pi2) / 3 + 8 * H1_1zb * H1zb + 8 * H2_1zb
                 - 4 * H11_1zb)
        - 4 * H1zb * H11_1zb - 8 * H12z + 4 * H111_1zb
    ) / 8


_RED2_LAMBDA = {}


def red2_eval(t, zb, ze):
    """reducible2(t, zb, zeta): the vendored PF_R.json rational, sympy-
    parsed and lambdified once per process (sympy is used ONLY here and
    in the exact-identity selftests)."""
    key = "f"
    if key not in _RED2_LAMBDA:
        check_vendored_pins()
        import sympy as sp
        ts, zbs, zes = sp.symbols("t zb zeta")
        expr = sp.parse_expr(RED2_STR,
                             local_dict={"t": ts, "zb": zbs, "zeta": zes})
        _RED2_LAMBDA[key] = sp.lambdify((ts, zbs, zes), expr,
                                        modules="mpmath")
    return _RED2_LAMBDA[key](t, zb, ze)


def fr2_inner_split(zbv, ze, md):
    """Inner2(zb) by the recorded split: (a2/sqrt(disc2))[J2(s+)-J2(s-)]
    + T_red, each fold a t-quadrature capped at maxdegree md."""
    P2f = make_inner_P2(zbv, ze)
    sp_, sm_, sq = roots_s(zbv, ze)
    a2 = a2f(zbv, ze)

    def J2(tau):
        return mp.quad(lambda t: P2f(t)[1] / (t - tau), [0, zbv],
                       maxdegree=md)
    kern = a2 / sq * (J2(sp_) - J2(sm_))
    tred = mp.quad(lambda t: red2_eval(t, zbv, ze) * P2f(t)[1], [0, zbv],
                   maxdegree=md)
    return kern + tred


def fr2_inner_comb(zbv, ze, md):
    """Inner2(zb) by the combined form outer*R2*P2 (same pointwise
    integrand; used on the zb->1 tail where the split pieces cancel)."""
    P2f = make_inner_P2(zbv, ze)

    def f(t):
        z, p2 = P2f(t)
        if z is None:
            return mp.mpf(0)
        den = ze * (t - zbv) + zbv * (1 - t)
        outer = (ze - 1) / den
        R2 = z**2 * zbv / ((1 - z)**2 * (1 - z * zbv))
        return outer * R2 * p2
    return mp.quad(f, [0, zbv], maxdegree=md)


# ===========================================================================
# SECTION 3: F^red1 -- one-fold of the recorded machine truth (inner
# integrand red1*P1, the recorded close9_red1_analytic.py gatef design) + the
# vendored 112-word exact t-fold, re-gated live (gatephi design).
# ===========================================================================
def piece_md(D):
    """Inner-fold tanh-sinh degree cap vs run depth (recorded calibration:
    dps35/md6 -> 32.5 d, dps40/md7 -> 38 d; measured here: md6 caps the
    two-height ledger agreement at ~25.5 d, so md steps at D=18/30/40)."""
    if D <= 18:
        return 6
    if D <= 30:
        return 7
    if D <= 40:
        return 8
    return 9


def _piece_task(arg):
    """Worker: one shard of the F^R2 or F^red1 outer tanh-sinh ledger."""
    wp = arg["wp"]
    mp.mp.dps = wp
    ze = mp.mpf(arg["p"]) / arg["q"]
    md = arg["md"]
    kind = arg["kind"]
    delta = mp.mpf(FR2_DELTA)
    floor = mp.mpf(10) ** (-(wp - 6))
    no = w_ts_nodes(mp.mpf(1) / arg["h"], mp.mpf("7.5"),
                    mp.mpf(10) ** (-(wp + 12)))
    mine = no[arg["shard"]::arg["nshard"]]
    t0 = time.time()
    S = mp.mpf(0)
    for zbv, eps, w in mine:
        if zbv <= floor or eps <= floor:
            continue
        if kind == "fred1":
            v = mp.quad(make_inner_red1(zbv, ze), [0, zbv], maxdegree=md)
        else:
            if eps > delta:
                v = fr2_inner_split(zbv, ze, md)
            else:
                v = fr2_inner_comb(zbv, ze, md)
        S += w * v
    # S is mpc: the HPL layers carry S12(z<0) etc. whose imaginary parts
    # cancel in the physical combination up to quadrature noise (the
    # recorded oracles show the same ~1e-50 residual Im); re/im returned
    # separately, the real part is the value.
    return {"n_mine": len(mine), "n_total": len(no),
            "sec": time.time() - t0,
            "Sre": mp.nstr(mp.re(S), wp + 8),
            "Sim": mp.nstr(mp.im(S), wp + 8)}


def piece_ledger(kind, fr, D, h, workers, verbose=True):
    """One full outer ledger of F^R2 / F^red1 at height h."""
    wp = D + PIECE_GUARD
    md = piece_md(D)
    tasks = [{"kind": kind, "p": fr.numerator, "q": fr.denominator,
              "wp": wp, "h": h, "md": md, "shard": i, "nshard": workers}
             for i in range(workers)]
    t0 = time.time()
    if workers <= 1:
        res = [_piece_task(a) for a in tasks]
    else:
        with multiprocessing.Pool(workers) as pool:
            res = pool.map(_piece_task, tasks, chunksize=1)
    with mp.workprec(int(wp * 3.3333) + 10):
        S = mp.mpf(0)
        for r in res:
            S += mp.mpf(r["Sre"])
    n = sum(r["n_mine"] for r in res)
    if n != res[0]["n_total"]:
        raise CertFail("%s ledger shard accounting broken: %d != %d"
                       % (kind, n, res[0]["n_total"]))
    if verbose:
        print("[%-4s]      ledger h=1/%d (%d outer nodes, wp %d, md %d, "
              "%d workers): wall %.1f s"
              % (kind, h, n, wp, md, workers, time.time() - t0))
    return S, n


def piece_eval(kind, fr, D, workers, verbose=True):
    """F^R2 / F^red1 at the run depth: two-height outer escalation, the
    successive-ledger agreement is the value-level certificate (bar D;
    the inner folds are depth-capped adaptive quadratures, so the final
    recorded-oracle gate is the binding certificate -- fail-closed)."""
    h0 = max(10, int(math.ceil((D + 4) / 2.0)))
    schedule = [h0, int(math.ceil(1.3 * h0)), int(math.ceil(1.69 * h0))]
    prev = None
    wp = D + PIECE_GUARD
    with mp.workprec(int(wp * 3.3333) + 10):
        for li, h in enumerate(schedule):
            S, n = piece_ledger(kind, fr, D, h, workers, verbose=verbose)
            val = mp.re(S)
            if prev is not None:
                agr = digits(val, prev)
                if verbose:
                    print("[%-4s]      two-height agreement h=1/%d vs 1/%d: "
                          "%.1f d (bar %d)"
                          % (kind, schedule[li - 1], h, agr, D))
                if agr >= D:
                    return val, agr
            prev = val
    raise CertFail(
        "%s ledger FAILED (fail-closed): heights %s exhausted without two "
        "successive levels agreeing to %d d at zeta=%s."
        % (kind, schedule, D, fr))


def check_vendored_pins():
    """Self-pin of the in-file vendored data (checked before first use):
    any byte change to the embedded blobs is a refusal, exit 2."""
    sha = hashlib.sha256(RED1_PHI_JSON.encode()).hexdigest()
    if sha != RED1_PHI_SHA:
        raise PinRefusal(
            "vendored F^red1 112-word data REFUSED (fail-closed): sha256 "
            "of the embedded phi-word blob is %s, pinned close9 value is "
            "%s. The embedded data was modified." % (sha, RED1_PHI_SHA))
    sha2 = hashlib.sha256(RED2_STR.encode()).hexdigest()
    if sha2 != RED2_SHA:
        raise PinRefusal(
            "vendored F^R2 reducible2 rational REFUSED (fail-closed): "
            "sha256 %s vs pin %s. The embedded PF_R data was modified."
            % (sha2, RED2_SHA))


# ---- spectral-panel GPL evaluator (for the live 112-word gate) ------------
_CC_CACHE = {}


def _cc_cum(N):
    """Chebyshev-Lobatto nodes y_j = cos(pi j/N) (j=0..N) and the
    cumulative-integration matrix CUM with
        F(y_i) = sum_j CUM[i][j] f(y_j),   F(-1) = 0,
    F the antiderivative of the degree-N interpolant.  Cached per
    (N, dps)."""
    key = (N, mp.mp.dps)
    if key in _CC_CACHE:
        return _CC_CACHE[key]
    ys = [mp.cos(mp.pi * j / N) for j in range(N + 1)]
    # C: values -> plain Chebyshev coefficients a_k (f = sum a_k T_k)
    C = [[mp.mpf(0)] * (N + 1) for _ in range(N + 1)]
    for k in range(N + 1):
        for j in range(N + 1):
            w = mp.cos(mp.pi * k * j / N) * 2 / N
            if j in (0, N):
                w /= 2
            if k in (0, N):
                w /= 2
            C[k][j] = w
    # B: a -> antiderivative coefficients b (b_0 fixed by F(-1)=0).
    # b_k = (c_{k-1} - c_{k+1})/(2k) in the HALVED-c_0 convention, i.e.
    # the k=1 row picks up the plain a_0 with weight 1, not 1/2.
    B = [[mp.mpf(0)] * (N + 1) for _ in range(N + 1)]
    for k in range(1, N + 1):
        B[k][k - 1] += mp.mpf(1) / (2 * k) * (2 if k == 1 else 1)
        if k + 1 <= N:
            B[k][k + 1] -= mp.mpf(1) / (2 * k)
    for k in range(1, N + 1):
        sgn = -1 if k % 2 else 1
        for j in range(N + 1):
            B[0][j] -= sgn * B[k][j]
    # T: b -> values at nodes
    T = [[mp.cos(mp.pi * k * i / N) for k in range(N + 1)]
         for i in range(N + 1)]

    def matmul(A1, A2):
        n1, n2, n3 = len(A1), len(A2), len(A2[0])
        return [[mp.fsum(A1[i][k] * A2[k][j] for k in range(n2))
                 for j in range(n3)] for i in range(n1)]
    CUM = matmul(T, matmul(B, C))
    _CC_CACHE[key] = (ys, CUM)
    return ys, CUM


def gpl_all_words(words, letters_num, x, N, xmin_exp):
    """All G(w; x) for the word list by left-to-right spectral-panel
    marching of the coupled dlog system dG(a::w)/dt = G(w;t)/(t-a).
    Letters lie OFF the open path (0, x) (checked); pure-zero words by
    closed form log^k t / k!.  IC at x_min = 10^-xmin_exp: G(w;x_min)=0
    for mixed words (error O(x_min log^2 x_min), below every gate)."""
    ys, CUM = _cc_cum(N)
    for ch, av in letters_num.items():
        if ch != "0" and mp.mpf(0) < av < x:
            raise CertFail("GPL letter %s=%s lies ON the path (0,%s)"
                           % (ch, mp.nstr(av, 8), mp.nstr(x, 8)))
    sufs = set()
    for w in words:
        for i in range(len(w)):
            sufs.add(w[i:])
    sufs = sorted(sufs, key=len)
    xmin = mp.mpf(10) ** (-xmin_exp)
    ratio = mp.mpf(3) / 2      # panel [a, 1.5a]: Bernstein rho ~ 9.9 for
    edges = [x]                # the t=0 log singularity -> per-panel error
    while edges[-1] > xmin:    # ~ rho^-N, uniform (self-similar geometry)
        edges.append(edges[-1] / ratio)
    edges = edges[::-1]                      # left -> right
    carry = {w: mp.mpf(0) for w in sufs}
    for pi in range(len(edges) - 1):
        a, b = edges[pi], edges[pi + 1]
        half = (b - a) / 2
        mid = (b + a) / 2
        ts = [mid + half * y for y in ys]    # ts[0]=b (right), ts[N]=a
        V = {"": [mp.mpf(1)] * (N + 1)}
        for w in sufs:
            if set(w) == {"0"}:
                k = len(w)
                V[w] = [mp.log(t) ** k / math.factorial(k) for t in ts]
                carry[w] = V[w][0]
                continue
            av = letters_num[w[0]]
            rest = V[w[1:]]
            f = [rest[j] / (ts[j] - av) for j in range(N + 1)]
            cw = carry[w]
            V[w] = [cw + half * mp.fsum(CUM[i][j] * f[j]
                                        for j in range(N + 1))
                    for i in range(N + 1)]
            carry[w] = V[w][0]
    return carry


def red1_word_gate(D, verbose=True, phi_override=None, spots=None,
                   bar_override=None):
    """LIVE gate of the vendored 112-word t-fold: Phi(t) = sum c_w G(w;t)
    vs the independent P1(z(t,zb),zb) transcription, at recorded gatephi
    spot points (recorded worst 59.7 d, Arb-certified; here the GPL side is
    a two-resolution spectral-panel evaluation, bar min(D,25) d,
    fail-closed with one resolution escalation)."""
    check_vendored_pins()
    bar = bar_override if bar_override is not None else min(D, 25)
    wp = bar + 16
    phi = json.loads(RED1_PHI_JSON)
    if phi_override:
        phi = dict(phi)
        phi.update(phi_override)
    if len(phi) != 112:
        raise PinRefusal("vendored phi-word count %d != 112" % len(phi))
    # recorded gatephi points A and C (close9_red1_analytic.py GATEPHI_PTS)
    spots = spots or [(Fraction(3, 20), Fraction(2, 5), Fraction(1, 3)),
                      (Fraction(1, 5), Fraction(3, 10), Fraction(1, 2))]
    worst = float("inf")
    old = mp.mp.dps
    try:
        mp.mp.dps = wp
        for (tq, zbq, zeq) in spots:
            tv, zbv, zev = _mpq(tq), _mpq(zbq), _mpq(zeq)
            letters = {"0": mp.mpf(0), "b": zbv, "1": mp.mpf(1),
                       "s": -zbv * (1 - zev) / zev,
                       "p": (1 - zev) * zbv / (zbv - zev)}
            cv = {"C0": mp.log(zev / (1 - zev)), "CB1": mp.log(zbv),
                  "CB2": mp.log(1 - zbv), "CL2": mp.polylog(2, 1 - zbv),
                  "CL3": mp.polylog(3, 1 - zbv), "CS12": _S12(1 - zbv)}
            env = {"__builtins__": {}}
            env.update(cv)
            coeffs = {}
            for w, cs in phi.items():
                c = eval(cs, env)            # self-pinned data only
                coeffs[w] = mp.mpf(c) if not isinstance(c, mp.mpf) else c
            words = [w for w in phi if w]
            prev_phi = None
            val_phi = None
            for N in (32, 44, 56):
                G = gpl_all_words(words, letters, tv, N, bar + 8)
                tot = coeffs[""] + mp.fsum(coeffs[w] * G[w] for w in words)
                if prev_phi is not None and digits(tot, prev_phi) >= bar + 2:
                    val_phi = tot
                    break
                prev_phi = tot
            if val_phi is None:
                raise CertFail(
                    "F^red1 112-word gate FAILED (fail-closed): spectral "
                    "resolutions N=32/44/56 did not stabilize to %d d at "
                    "spot (t=%s, zb=%s, ze=%s)" % (bar + 2, tq, zbq, zeq))
            den = zev * (tv - zbv) + zbv * (1 - tv)
            zv = zev * tv * (tv - zbv) / den
            p1 = P1_deriv_layer(zv, zbv)
            d = digits(mp.re(val_phi), mp.re(p1))
            worst = min(worst, d)
            if d < bar:
                raise CertFail(
                    "F^red1 112-word gate FAILED (fail-closed) at spot "
                    "(t=%s, zb=%s, ze=%s): Phi vs P1 agree to only %.1f d "
                    "(bar %d). The vendored word data or its transcription "
                    "is corrupt." % (tq, zbq, zeq, d, bar))
    finally:
        mp.mp.dps = old
    if verbose:
        print("[fred1]     112-word gate: Phi(t) vs independent P1 at %d "
              "recorded spots: worst %.1f d (bar %d) -- PASS"
              % (len(spots), worst, bar))
    return worst


# ===========================================================================
# SECTION 4: runtime selftests, per-piece drivers, recorded-oracle gates,
# assembly, mutation controls, CLI.
# ===========================================================================
XLAYER_EXP = 38          # cross-transcription detection floor (the two P1
                         # and two P2 layers are independent transcriptions
                         # of the same ancillary HPL combinations; measured
                         # agreement is ~bit-exact, see fk1-evaluate.py)


def selftest_transcription(verbose=True):
    """Oracle layer vs derivative layer, P1 AND P2, pointwise -- RAISE on
    disagreement above the detection floor (ported design)."""
    worst = mp.mpf(0)
    with mp.workprec(int(50 * 3.3333) + 10):
        ze = mp.mpf(1) / 3
        pts = [(mp.mpf("0.11"), mp.mpf("0.6")),
               (mp.mpf("0.05"), mp.mpf("0.3")),
               (mp.mpf("0.31"), mp.mpf("0.44"))]
        for (t, zb) in pts:
            z1, p1_a = make_inner_P1(zb, ze)(t)
            p1_b = P1_deriv_layer(z1, zb)
            z2, p2_a = make_inner_P2(zb, ze)(t)
            p2_b = P2_deriv_layer(z2, zb)
            for nm, a, b in (("P1", p1_a, p1_b), ("P2", p2_a, p2_b)):
                rel = abs(a - b) / max(1, abs(a))
                worst = max(worst, rel)
                if rel > mp.mpf(10) ** -XLAYER_EXP:
                    raise CertFail(
                        "selftest FAILED: the two independent %s "
                        "transcriptions disagree at (t,zb)=(%s,%s): rel %s "
                        "> 1e-%d" % (nm, t, zb, mp.nstr(rel, 4), XLAYER_EXP))
    if verbose:
        print("[self]      P1/P2 oracle-vs-derivative transcriptions agree "
              "to %s rel (floor 1e-%d) -- PASS"
              % ("0 (bit-exact)" if worst == 0 else mp.nstr(worst, 3),
                 XLAYER_EXP))
    return worst


def fr2_identity_gate(fr, verbose=True, dent_a2=False):
    """Live exact-identity gates of the F^R2 one-fold (recorded selftest
    design of close5_fr2_onefold.py; dent_a2 is the --selftest mutation
    hook, in-memory only)."""
    res = {}
    with mp.workprec(int(50 * 3.3333) + 10):
        ze = _mpq(fr)
        a2loc = (lambda zb: a2f(zb, ze) * (1 + mp.mpf(10) ** -6)) \
            if dent_a2 else (lambda zb: a2f(zb, ze))
        # (a) PF pointwise: outer*R2 == a2/D_K2 + red2
        worst_pf = mp.mpf(0)
        for (tv, zbv) in [(mp.mpf("0.11"), mp.mpf("0.6")),
                          (mp.mpf("0.4"), mp.mpf("0.85"))]:
            den = tv * (ze - zbv) + (1 - ze) * zbv
            z = ze * tv * (tv - zbv) / den
            R2 = z**2 * zbv / ((1 - z)**2 * (1 - z * zbv))
            lhs = (ze - 1) / den * R2
            rhs = a2loc(zbv) / DK2f(tv, zbv, ze) + red2_eval(tv, zbv, ze)
            worst_pf = max(worst_pf, abs(lhs - rhs) / abs(lhs))
        res["pf_rel"] = worst_pf
        if worst_pf > mp.mpf(10) ** -35:
            raise CertFail(
                "F^R2 PF identity FAILED (fail-closed): outer*R2 vs "
                "a2/D_K2 + red2 rel resid %s > 1e-35 -- the vendored "
                "reducible2 rational or the kernel is corrupt"
                % mp.nstr(worst_pf, 3))
        # (b) z(s+-) = 1/zb and (c) disc2 = (zb-1)^4 Q(zb/(zb-1))
        worst_zs = mp.mpf(0)
        worst_d2 = mp.mpf(0)
        for zbv in (mp.mpf("0.37"), mp.mpf("0.81")):
            sp_, sm_, sq = roots_s(zbv, ze)
            for s in (sp_, sm_):
                worst_zs = max(worst_zs,
                               abs(zfun(s, zbv, ze) - 1 / zbv) * zbv)
            mob = (zbv - 1) ** 4 * Qquartic(zbv / (zbv - 1), ze)
            worst_d2 = max(worst_d2,
                           abs(disc2f(zbv, ze) - mob) / abs(mob))
        res["zs_rel"] = worst_zs
        res["disc2_rel"] = worst_d2
        if worst_zs > mp.mpf(10) ** -40 or worst_d2 > mp.mpf(10) ** -40:
            raise CertFail(
                "F^R2 curve identities FAILED (fail-closed): z(s+-)=1/zb "
                "rel %s / disc2-Moebius rel %s > 1e-40"
                % (mp.nstr(worst_zs, 3), mp.nstr(worst_d2, 3)))
    # (d) split == combined pointwise-in-zb (the eps-cancellation check)
    with mp.workprec(int(34 * 3.3333) + 10):
        ze = _mpq(fr)
        worst_sc = mp.mpf(0)
        for zbv in (mp.mpf("0.5"), mp.mpf("0.9")):
            a = fr2_inner_split(zbv, ze, 6)
            b = fr2_inner_comb(zbv, ze, 6)
            worst_sc = max(worst_sc, abs(a - b) / abs(b))
        res["splitcomb_rel"] = worst_sc
        if worst_sc > mp.mpf(10) ** -18:
            raise CertFail(
                "F^R2 split-vs-combined FAILED (fail-closed): rel %s > "
                "1e-18 at md 6" % mp.nstr(worst_sc, 3))
    # (e) Moebius period identity: int_0^1 dzb/sqrt(disc2) ==
    #     int_{-inf}^0 du/sqrt(Q(u))  (the recorded varpi_0 statement's
    #     change-of-variables backbone, live)
    with mp.workprec(int(36 * 3.3333) + 10):
        ze = _mpq(fr)
        A = mp.quad(lambda zb: 1 / mp.sqrt(disc2f(zb, ze)), [0, 1],
                    maxdegree=8)
        Bv = mp.quad(lambda u: 1 / mp.sqrt(Qquartic(u, ze)),
                     [-mp.inf, 0], maxdegree=8)
        dper = digits(mp.re(A), mp.re(Bv))
        res["period_digits"] = dper
        if dper < 25:
            raise CertFail(
                "F^R2 Moebius period identity FAILED (fail-closed): "
                "int dzb/sqrt(disc2) vs int du/sqrt(Q) agree to only "
                "%.1f d (bar 25)" % dper)
    if verbose:
        print("[fr2 ]      exact identities: PF %s | z(s+-)=1/zb %s | "
              "disc2-Moebius %s | split=comb %s | period %.1f d -- PASS"
              % (mp.nstr(res["pf_rel"], 2), mp.nstr(res["zs_rel"], 2),
                 mp.nstr(res["disc2_rel"], 2),
                 mp.nstr(res["splitcomb_rel"], 2), res["period_digits"]))
    return res


def red1_exact_gate(verbose=True):
    """Exact sympy identities of the F^red1 t-fold (ported from the
    recorded close9_red1_analytic.py stage_exact; all residuals must be
    IDENTICALLY zero)."""
    import sympy as sp
    t, zb, ze = sp.symbols("t zb ze", positive=True)
    den = t * (ze - zb) + (1 - ze) * zb
    zB = ze * t * (t - zb) / den
    tstar = (1 - ze) * zb / (zb - ze)
    t6 = -zb * (1 - ze) / ze
    kappa = zb * (1 - ze) / (ze - zb)
    checks = [
        ("red1_eq_kernel", sp.simplify(zb * (1 - ze) / den
                                       - kappa / (t - tstar))),
        ("mz_fact", sp.simplify(-zB - (ze / (1 - ze)) * t * (1 - t / zb)
                                / (1 - t / tstar))),
        ("omz_fact", sp.simplify(1 - zB - (1 - t) * (1 - t / t6)
                                 / (1 - t / tstar))),
        ("dlogz", sp.simplify(sp.diff(zB, t) / zB
                              - (1 / t + 1 / (t - zb) - 1 / (t - tstar)))),
    ]
    for nm, v in checks:
        if v != 0:
            raise CertFail("F^red1 exact identity %s FAILED (fail-closed): "
                           "residual %s != 0" % (nm, v))
    if verbose:
        print("[fred1]     exact t-fold identities (red1 kernel, -z, 1-z, "
              "dlog z): 4/4 sympy-zero -- PASS")
    return True


def bank_gate(piece, key, val, D, verbose=True):
    """Gate a live value against its recorded oracle reference.  Bar =
    min(D-2, cap-4); a miss is a fail-closed refusal (exit 3)."""
    ref_s, cap = BANK[key][piece]
    with mp.workprec(int((cap + 20) * 3.3333) + 10):
        ref = mp.mpf(ref_s)
        d = digits(val, ref)
    bar = min(D - 2, cap - 4)
    if d < bar:
        raise GateRefusal(
            "%s GATE FAILED (fail-closed) at zeta=%s: live value agrees "
            "with the recorded oracle to only %.1f d (bar %d, cap %d). No "
            "value is printed." % (piece, key, d, bar, cap))
    if verbose:
        print("[%-5s]     recorded-oracle gate at zeta=%s: %.1f d (bar %d, "
              "ref cap %d) -- PASS" % (piece, key, d, bar, cap))
    return d, bar


def print_value(label, val, gated_d, raw, wp):
    """Certified-digit print policy: <=10 digits by default, never more
    than were gated; --raw prints the full working precision."""
    with mp.workprec(int(wp * 3.3333) + 10):
        if raw:
            print("    %s = %s   (raw, %.1f gated d)"
                  % (label, mp.nstr(val, wp), gated_d))
        else:
            n = max(1, min(10, int(gated_d)))
            print("    %s = %s   (%d certified digits printed; gated %.1f d)"
                  % (label, mp.nstr(val, n), n, gated_d))


def run_fk1(fr, key, D, workers, raw, verbose=True):
    t0 = time.time()
    blocks, meta = load_word_data()
    if verbose:
        print("[fk1 ]      pinned OP3 data OK: 159 derived words, 12 "
              "blocks, no fitted coefficients (sha256 %s...)"
              % WORDS_SHA256[:16])
    spot = word_spot_gate(fr, D, verbose=verbose)
    val, cert = word_eval(fr, D, workers, verbose=verbose)
    gd, bar = bank_gate("fk1", key, mp.re(val), D, verbose=verbose)
    sec = time.time() - t0
    print("== F^K1 (word form) at zeta = %s, dps %d ==" % (key, D))
    print_value("F^K1  ", mp.re(val), min(gd, cert), raw, D + WORD_GUARD)
    print("    certificates: two-height %.1f d | spot gate %.1f d | recorded "
          "gate %.1f d (bar %d) | %.1f s" % (cert, spot, gd, bar, sec))
    return mp.re(val), {"gate_d": gd, "cert_d": cert, "spot_d": spot,
                        "sec": sec}


def run_fr2(fr, key, D, workers, raw, verbose=True):
    t0 = time.time()
    check_vendored_pins()
    fr2_identity_gate(fr, verbose=verbose)
    val, cert = piece_eval("fr2", fr, D, workers, verbose=verbose)
    gd, bar = bank_gate("fr2", key, val, D, verbose=verbose)
    sec = time.time() - t0
    print("== F^R2 (Moebius-mirror one-fold) at zeta = %s, dps %d ==" %
          (key, D))
    print_value("F^R2  ", val, min(gd, cert), raw, D + PIECE_GUARD)
    print("    certificates: two-height %.1f d | exact identities PASS | "
          "recorded gate %.1f d (bar %d) | %.1f s" % (cert, gd, bar, sec))
    return val, {"gate_d": gd, "cert_d": cert, "sec": sec}


def run_fred1(fr, key, D, workers, raw, verbose=True):
    t0 = time.time()
    check_vendored_pins()
    red1_exact_gate(verbose=verbose)
    wordg = red1_word_gate(D, verbose=verbose)
    val, cert = piece_eval("fred1", fr, D, workers, verbose=verbose)
    gd, bar = bank_gate("fred1", key, val, D, verbose=verbose)
    sec = time.time() - t0
    print("== F^red1 (reducible-R1 one-fold) at zeta = %s, dps %d ==" %
          (key, D))
    print_value("F^red1", val, min(gd, cert), raw, D + PIECE_GUARD)
    print("    certificates: two-height %.1f d | 112-word gate %.1f d | "
          "exact identities PASS | recorded gate %.1f d (bar %d) | %.1f s"
          % (cert, wordg, gd, bar, sec))
    return val, {"gate_d": gd, "cert_d": cert, "word_d": wordg, "sec": sec}


def run_all(fr, key, D, workers, raw, verbose=True):
    # cheapest piece first (measured dps-14 probes: fr2 5 s < fk1 17 s <
    # fred1 61 s near-idle), so the first gated value lands early; the
    # sum below is the same three-term expression regardless of order.
    vals = {}
    stats = {}
    vals["fr2"], stats["fr2"] = run_fr2(fr, key, D, workers, raw, verbose)
    print()
    vals["fk1"], stats["fk1"] = run_fk1(fr, key, D, workers, raw, verbose)
    print()
    vals["fred1"], stats["fred1"] = run_fred1(fr, key, D, workers, raw,
                                              verbose)
    print()
    wp = D + PIECE_GUARD
    with mp.workprec(int(wp * 3.3333) + 10):
        fell = vals["fk1"] + vals["fr2"] + vals["fred1"]
    gd, bar = _sum_gate(key, fell, D)
    print("== F^ell = F^K1 + F^R2 + F^red1 at zeta = %s ==" % key)
    print_value("F^ell ", fell, gd, raw, wp)
    print("    SUM gate vs the recorded DIRECT two-fold F^ell oracle "
          "(independent of the decomposition): %.1f d (bar %d) -- PASS"
          % (gd, bar))
    vals["fell"] = fell
    stats["fell"] = {"gate_d": gd}
    return vals, stats


def _sum_gate(key, fell, D):
    ref_s, cap = BANK[key]["fell"]
    with mp.workprec(int((cap + 20) * 3.3333) + 10):
        ref = mp.mpf(ref_s)
        d = digits(fell, ref)
    bar = min(D - 2, cap - 4)
    if d < bar:
        raise GateRefusal(
            "SUM GATE FAILED (fail-closed) at zeta=%s: F^K1+F^R2+F^red1 "
            "agrees with the recorded direct F^ell oracle to only %.1f d "
            "(bar %d). A sign/prefactor slip in the assembly, or a piece "
            "below its bar, poisons the sum -- no value is printed."
            % (key, d, bar))
    return d, bar


# ---------------------------------------------------------------------------
# --selftest: mutation controls (one dent per piece, in-memory, disk
# untouched; every dent must be CAUGHT by the gate that guards that piece)
# ---------------------------------------------------------------------------
def mutation_selftest(workers):
    t00 = time.time()
    print("== --selftest: mutation controls (in-memory dents; disk "
          "untouched) ==")
    ok = True
    fr = Fraction(1, 3)

    # positive baseline: pins + transcriptions + exact identities
    check_vendored_pins()
    selftest_transcription()
    red1_exact_gate()
    print()

    # (1) F^K1: dent one decoded block coefficient by 1e-6 rel -> the live
    # spot gate (block form vs certified quadrature) must FAIL
    blocks, _ = load_word_data()
    dent = [list(b) for b in blocks]
    q0, e0 = dent[0][0]
    dent[0][0] = (q0 * Fraction(1000001, 1000000), e0)
    t0 = time.time()
    spot = word_spot_gate(fr, 12, verbose=False, spots=("0.53",),
                          bar_override=24)
    print("[mut ] fk1 positive control: spot gate clean blocks %.1f d "
          "(bar 24) PASS  (%.0f s)" % (spot, time.time() - t0))
    t0 = time.time()
    try:
        word_spot_gate(fr, 12, verbose=False, blocks_override=dent,
                       spots=("0.53",), bar_override=24)
        print("[mut ] fk1 DENT NOT CAUGHT -- FAIL")
        ok = False
    except CertFail:
        print("[mut ] fk1 dent (blocks[0] * (1+1e-6)) CAUGHT by spot gate "
              "(%.0f s)" % (time.time() - t0))

    # (2) F^R2: dent the a2 kernel by 1e-6 rel -> the PF identity gate
    # must FAIL
    fr2_identity_gate(fr, verbose=False)
    print("[mut ] fr2 positive control: exact identities clean PASS")
    try:
        fr2_identity_gate(fr, verbose=False, dent_a2=True)
        print("[mut ] fr2 DENT NOT CAUGHT -- FAIL")
        ok = False
    except CertFail:
        print("[mut ] fr2 dent (a2 * (1+1e-6)) CAUGHT by PF identity gate")

    # (3) F^red1: dent one vendored word coefficient -> the live 112-word
    # gate (Phi vs P1) must FAIL
    spots1 = [(Fraction(3, 20), Fraction(2, 5), Fraction(1, 3))]
    t0 = time.time()
    wg = red1_word_gate(24, verbose=False, spots=spots1, bar_override=22)
    print("[mut ] fred1 positive control: 112-word gate clean %.1f d "
          "(bar 22) PASS  (%.0f s)" % (wg, time.time() - t0))
    t0 = time.time()
    phi = json.loads(RED1_PHI_JSON)
    dented = {"p": "(" + phi["p"] + ") + 1/1000000"}
    try:
        red1_word_gate(24, verbose=False, phi_override=dented,
                       spots=spots1, bar_override=22)
        print("[mut ] fred1 DENT NOT CAUGHT -- FAIL")
        ok = False
    except CertFail:
        print("[mut ] fred1 dent (word 'p' + 1e-6) CAUGHT by 112-word "
              "gate (%.0f s)" % (time.time() - t0))

    # (4) SUM: assembly-convention control against the record (recorded pieces
    # must reconstruct the recorded F^ell; a flipped F^R2 sign must be
    # caught by the sum gate)
    with mp.workprec(int(70 * 3.3333) + 10):
        key = "1/3"
        s = (mp.mpf(BANK[key]["fk1"][0]) + mp.mpf(BANK[key]["fr2"][0])
             + mp.mpf(BANK[key]["fred1"][0]))
        d = digits(s, mp.mpf(BANK[key]["fell"][0]))
        if d < 36:
            print("[mut ] sum positive control FAILED: recorded pieces "
                  "reconstruct recorded F^ell to only %.1f d" % d)
            ok = False
        else:
            print("[mut ] sum positive control: recorded pieces reconstruct "
                  "recorded F^ell to %.1f d PASS" % d)
        s_bad = (mp.mpf(BANK[key]["fk1"][0]) - mp.mpf(BANK[key]["fr2"][0])
                 + mp.mpf(BANK[key]["fred1"][0]))
        try:
            _sum_gate(key, s_bad, 28)
            print("[mut ] sum DENT NOT CAUGHT -- FAIL")
            ok = False
        except GateRefusal:
            print("[mut ] sum dent (F^R2 sign flip) CAUGHT by sum gate")

    print("\n--selftest: %s  (%.0f s total)"
          % ("ALL DENTS CAUGHT, ALL CONTROLS PASS" if ok
             else "FAILURE (see above)", time.time() - t00))
    if not ok:
        raise GateRefusal("--selftest mutation controls FAILED")


def main():
    ap = argparse.ArgumentParser(
        description="Certified evaluator of the FULL elliptic part "
                    "F^ell = F^K1 + F^R2 + F^red1 of the 2-point NNLO N=4 "
                    "EEC (HSYZ 1903.05314 eq.19 residual; Gamma_1(6) "
                    "sunrise curve).  See module docstring.")
    ap.add_argument("--point", metavar="P/Q", default="1/3",
                    help="recorded kinematic point (default 1/3): one of "
                         + ", ".join(sorted(BANK)))
    ap.add_argument("--dps", type=int, default=14,
                    help="certified-digit crank (default 14; --dps 28 "
                         "reproduces the deeper pre-2026-09-03 default)")
    ap.add_argument("--piece", choices=["fk1", "fr2", "fred1", "all"],
                    default="all", help="evaluate one piece or all + sum")
    ap.add_argument("--workers", type=int,
                    default=min(16, multiprocessing.cpu_count()))
    ap.add_argument("--raw", action="store_true",
                    help="print full working precision (default <=10 "
                         "certified digits)")
    ap.add_argument("--check", nargs="?", const=-1, type=int,
                    metavar="STEP",
                    help="crank test: rerun at dps+STEP (default +8), "
                         "values must agree to >= dps digits, fail-closed")
    ap.add_argument("--selftest", action="store_true",
                    help="mutation controls only (one in-memory dent per "
                         "piece, each must be caught); then exit")
    args = ap.parse_args()
    try:   # liveness (2026-09-03): line-buffered stdout so the first gated
        sys.stdout.reconfigure(line_buffering=True)   # value lands as soon
    except Exception:                                 # as it is certified
        pass
    T00 = time.time()

    if args.selftest:
        mutation_selftest(args.workers)
        print("Total wall time: %.1f s" % (time.time() - T00))
        return

    D = args.dps
    if D < 12:
        raise SystemExit("--dps must be >= 12")
    fr = Fraction(args.point)
    key = "%d/%d" % (fr.numerator, fr.denominator)
    if key not in BANK:
        raise MissingRefusal(
            "zeta=%s has NO recorded oracle (fail-closed): every digit this "
            "script prints is gated against the recorded references, which "
            "exist only at %s. Exit 4." % (key, ", ".join(sorted(BANK))))
    if args.piece in ("fk1", "all") and not (WORD_ZLO <= fr <= WORD_ZHI):
        raise MissingRefusal(
            "zeta=%s is outside the evidence-gated F^K1 word-form hull "
            "[%s, %s]; F^K1 (and the full sum) are refused here. "
            "--piece fr2 / fred1 remain available at this recorded point."
            % (key, WORD_ZLO, WORD_ZHI))

    check_vendored_pins()
    selftest_transcription()
    print()

    def one_run(Drun):
        if args.piece == "fk1":
            v, s = run_fk1(fr, key, Drun, args.workers, args.raw)
            return {"fk1": v}, {"fk1": s}
        if args.piece == "fr2":
            v, s = run_fr2(fr, key, Drun, args.workers, args.raw)
            return {"fr2": v}, {"fr2": s}
        if args.piece == "fred1":
            v, s = run_fred1(fr, key, Drun, args.workers, args.raw)
            return {"fred1": v}, {"fred1": s}
        return run_all(fr, key, Drun, args.workers, args.raw)

    vals, stats = one_run(D)

    if args.check is not None:
        step = args.check if args.check != -1 else 8
        print("\n[check] crank: rerunning at dps %d (fail-closed value "
              "agreement >= %d d per piece)..." % (D + step, D))
        vals2, _ = one_run(D + step)
        ok = True
        with mp.workprec(int((D + step + 30) * 3.3333)):
            for k in vals:
                ad = digits(vals[k], vals2[k])
                ok = ok and ad >= D
                print("[check] %s: dps %d vs %d agree to %.1f d "
                      "(need >= %d)" % (k, D, D + step, ad, D))
        if not ok:
            raise GateRefusal("--check crank FAILED: value pair below the "
                              "%d d bar" % D)
        print("[check] crank CONSISTENT")

    walls = {k: round(s.get("sec", 0), 1) for k, s in stats.items()}
    print("\n[walls]     %s   total %.1f s"
          % (json.dumps(walls), time.time() - T00))
    print("[honest]    T0/T2 moment constants remain OPEN (archived PSLQ "
          "saturates honestly); F^red1 zeta-GPL lift open; word-form "
          "F^K1 gates of record 59/51/55 d (OP3). This run certifies "
          "the printed digits only, at the depth actually run.")


if __name__ == "__main__":
    try:
        main()
    except PinRefusal as e:
        print("\nREFUSED (data pin, exit %d): %s" % (EXIT_PIN, e))
        sys.exit(EXIT_PIN)
    except MissingRefusal as e:
        print("\nREFUSED (missing data, exit %d): %s" % (EXIT_MISSING, e))
        sys.exit(EXIT_MISSING)
    except GateRefusal as e:
        print("\nREFUSED (gate, exit %d): %s" % (EXIT_GATE, e))
        sys.exit(EXIT_GATE)
