#!/usr/bin/env python3
r"""land_fixed_eps.py -- the ice-cream-cone landing FROM the off-slice lines (rows 15/17) ONTO the slice: the engine of icc-offslice-evaluate.py --land
(every object resolved beside this file under land/, the seeds and the parser one level up in the bundle).
The gauged (symmetric/antisymmetric + third-relation) nine-master connection A'_y(eps, y) of a line p12^2 = x (land_yx_symanti.py of record
on each line's raw symbolic-y A_point; the objects under line_m3/ and line_m2/ beside this file) has y = x as an APPARENT singular
point (the Frobenius certificate of record: integer indicials {-1 x2, 0 x6, +1 x1}, log_max 0). The physical solution is analytic there, so
its value AT y = x is the Cauchy mean of its values on a circle |y - x| = rho:  J(x) = (1/N) sum_k J(x + rho e^{i theta_k})  up to the aliasing
tail (rho/R)^N (R = the distance to the next singular point). THIS SCRIPT (leg A, the eps-graded landing):
  1. reads the off-slice AMFlow seed of record at (x, y0) (the bundle's eps_order-5 out ../line_m*/seed_e5.json, orders eps^-2..eps^1; the
     parser ../amf_result.py amf_laurent), REFUSES a seed whose point of record (seed_points.json by tag) is not (x, y0) of the line;
  2. applies the exact gauge T(y0) as the eps-Laurent convolution J' = T(eps) J (T_at_y0.json of the gauge run; the engine's --seed-transform form);
  3. marches the eps-graded system (kmin..kmax) with the numerics of the y-detour engine of record transport_gate_y_detour_amf.py
     (poly_shift / rat_taylor / taylor_step / the polyroots step control SAFETY x nearest-pole distance / the trailing-window tail bound,
     vendored VERBATIM below; provenance field 'engine') along y0 -> x - rho (real), then N nodes around the circle back to the start
     (the closed loop = the monodromy certificate), and, when asked, a second circle at rho/2 (the radius-independence certificate);
  4. lands: the Cauchy mean over the N nodes (the trapezoid; the (y-x)^{-1} and (y-x)^{+1} components of the local solution space average to
     zero exactly), the residue certificate mean((y-x) J) ~ 0 (the physical solution has no pole), the imaginary part ~ 0;
  5. maps the landed gauged vector onto the slice's masters by GATE_MAP_slice.json (J_sym/2 = M_slice for the two mirror pairs, unpaired = M_slice;
     the antisymmetric combinations and the third-relation master are derivatives at y = x with no slice record: named, excluded) and compares
     with the slice records fixed BEFORE this run (the AMFlow on-slice records; the served icc-evaluate.py icc_top values): relative digits
     agree_d = log10(max(|a|,|b|)/|a-b|) capped by the shorter string; floors with members; structural zeros (K below a master's lead order)
     named and excluded; 'identical (N)' = the count of byte-identical strings.
  6. CONTROLS: --plant perturbs one seed value by a relative 10^-p before the gauge (the landing must FAIL by name); --seed of a foreign point is
     REFUSED (rc 2); --certificate re-derives the Frobenius certificate at y = x on the gauged monomial system (detransport.frobenius_basis:
     integer indicials, log_max 0 asserted) before the march.
Leg B (--fixed-eps-leg, x = -3 only; needs the detransport package: --tools DIR): the detransport `land` form on the same gauged system with
the eps-order-22 deep-Laurent seed of record (line_m3/seed_e22.json): the fixed-eps seed vector = the e22 Laurent summed at eps0, gauged by T(y0) at d = 2 - 2 eps0
exactly, transported and matched onto the Frobenius basis at y = x (land(): LS match, residual, cond), the regular value at u = 0 read as the Cauchy
mean of the basis on a tiny circle; compared with leg A's landed Laurent summed at the same eps0 (truncation-limited by the four-order slice
Laurent: the expected floor is named, not a digit claim). rc: 0 PASS; 1 FAIL by name; 2 REFUSED; 3 input.
"""
import argparse, hashlib, json, math, os, subprocess, sys, time
from fractions import Fraction
from mpmath import mp, mpf, mpc, fabs, log10, polyroots
sys.dont_write_bytecode = True
HERE = os.path.dirname(os.path.abspath(__file__)); VENDOR = os.path.dirname(HERE)   # every object beside this file (land/) or one level up (the bundle's seeds and its parser amf_result.py)
sys.path.insert(0, VENDOR)
from amf_result import amf_laurent
def sha(p): return hashlib.sha256(open(p, 'rb').read()).hexdigest()
def stamp_now(): return subprocess.run(['date', '-u', '+%Y-%m-%dT%H:%M:%SZ'], capture_output=True, text=True).stdout.strip()
ENGINE = 'transport_gate_y_detour_amf.py'; ENGINE_SHA16 = 'd6fcff8dd6e895af'   # the y-detour engine of record (its sha256 prefix); its numerics are vendored VERBATIM below
def _o(*a): return os.path.join(HERE, *a)   # an object beside this file
LINES = {
 '-3': {'x': Fraction(-3), 'y0': Fraction(-4), 'gauge': _o('line_m3'), 'seed_tag': 'S34e5_g40', 'twin_tag': 'S34e5_g60', 'seed_file': os.path.join('line_m3', 'seed_e5.json'),
        'slice_refs': [('icc_xm3_g120_out (AMFlow on the slice, goal 120)', _o('line_m3', 'icc_xm3_g120_out.json'), 'amflow'),
                       ('P1517-X3_g100 (AMFlow on the slice, goal 100, eps^-2..eps^2)', _o('line_m3', 'P1517-X3_g100.json'), 'amflow'),
                       ('icc-evaluate.py icc_top dps 60 (the derived-boundary slice transport)', _o('line_m3', 'slice_icc_evaluate_x-3_dps60.json'), 'icc_top'),
                       ('icc-evaluate.py icc_top dps 90 (the derived-boundary slice transport)', _o('line_m3', 'slice_icc_evaluate_x-3_dps90.json'), 'icc_top')]},
 '-2': {'x': Fraction(-2), 'y0': Fraction(-3), 'gauge': _o('line_m2'), 'seed_tag': 'S23e5_g40', 'twin_tag': 'S23e5_g60', 'seed_file': os.path.join('line_m2', 'seed_e5.json'),
        'slice_refs': [('icc_xm2_g150_out (AMFlow on the slice, goal 150)', _o('line_m2', 'icc_xm2_g150_out.json'), 'amflow'),
                       ('icc-evaluate.py icc_top dps 60 (the derived-boundary slice transport)', _o('line_m2', 'slice_icc_evaluate_x-2_dps60.json'), 'icc_top')]},
}
# ---------------- the y-detour engine's numerics, VERBATIM (transport_gate_y_detour_amf.py L104-L145 of the copy of record) ----------------
def poly_shift(cs, x0, order):  # coefficients of p(x0 + h) in h up to 'order'
    out = [mpf(0)] * (order + 1); n = len(cs)
    for k in range(n):
        ck = cs[k]
        if ck == 0: continue
        b = mpf(1); p = x0 ** k
        for j in range(min(k, order) + 1):
            out[j] += ck * b * p
            if j < k: b = b * (k - j) / (j + 1); p = p / x0 if x0 != 0 else p
        if x0 == 0:
            out = [mpf(0)] * (order + 1); break
    if x0 == 0:
        for k in range(min(n - 1, order) + 1): out[k] = cs[k]
    return out
def rat_taylor(num, den, x0, order):
    nn, dd = poly_shift(num, x0, order), poly_shift(den, x0, order)
    q = [mpf(0)] * (order + 1); d0 = dd[0]
    for n in range(order + 1):
        s = nn[n] - sum(dd[m] * q[n - m] for m in range(1, n + 1))
        q[n] = s / d0
    return q
def taylor_step(yv, x0, h, order, ns, polys, entries):
    T = {key: rat_taylor(num, den, x0, order) for key, (num, den) in polys.items()}
    A = [list(yv)]
    for n in range(order):
        nxt = [mpf(0)] * ns
        for (r, c, key) in entries:
            Tk = T[key]; s = mpf(0)
            for m in range(n + 1): s += Tk[m] * A[n - m][c]
            nxt[r] += s
        A.append([v / (n + 1) for v in nxt])
    out = [mpf(0)] * ns; hp = mpf(1); tail = mpf(0)
    for n, an in enumerate(A):
        for r in range(ns): out[r] += an[r] * hp
        hp *= h
    win = A[-8:]; hb = h ** (order - 7)
    for an in win:
        tail = max(tail, max(fabs(v) for v in an) * fabs(hb)); hb *= h
    return out, tail / 3
# ---------------- the system (the gauged connection's coef_y: eps-Taylor coefficients at d = 2 - 2 eps, rational in y) ----------------
class GaugedSystem:
    def __init__(self, conn_path, kmin, kmax, seeds, safety):
        C = json.load(open(conn_path)); self.conn_path = conn_path; self.conn_sha = sha(conn_path)
        self.coef = C['coef_y']; self.masters = [tuple(m) for m in C['masters']]; self.N = len(self.masters); self.meaning = C.get('masters_new_basis_meaning')
        self.x = Fraction(C['point']['x']); self.kmin, self.kmax = kmin, kmax; self.safety = safety
        self.lead = {m: min(K for (mm, K) in seeds if mm == m) for m in self.masters if any(mm == m for (mm, K) in seeds)}
        missing = [m for m in self.masters if m not in self.lead]
        if missing: print('SEED MISSING for masters:', missing); sys.exit(3)
        self.state = [(i, K) for i in range(self.N) for K in range(kmin, kmax + 1) if K >= self.lead[self.masters[i]]]
        self.idx = {s: n for n, s in enumerate(self.state)}
        self.entries = []
        for key in self.coef:
            i, j, k = map(int, key.split(','))
            for K in range(kmin, kmax + 1):
                if (i, K) in self.idx and (j, K - k) in self.idx: self.entries.append((self.idx[(i, K)], self.idx[(j, K - k)], key))
        self.polys = {key: ([mpf(c) for c in v['num']], [mpf(c) for c in v['den']]) for key, v in self.coef.items()}
        import numpy as np
        roots = []
        for key, (num, den) in self.polys.items():
            if len(den) > 1:
                try: rs = [mpc(r) for r in polyroots(list(reversed(den)), maxsteps=100, extraprec=40)]
                except Exception: rs = [mpc(complex(r)) for r in np.roots([float(c) for c in reversed(den)])]
                roots.extend(rs)
        self.roots = list({(round(float(r.real), 9), round(float(abs(r.imag)), 9)): r for r in roots}.values())
        xs = mpc(mpf(self.x.numerator) / self.x.denominator)
        self.roots_other = [r for r in self.roots if fabs(r - xs) > mpf('1e-6')]
        self.R_next = min([fabs(r - xs) for r in self.roots_other] or [mpf('inf')])   # the distance from y = x to the next singular point
        self.pole_at_x_present = any(fabs(r - xs) <= mpf('1e-6') for r in self.roots)
    def nearest_dist(self, z): return min([fabs(mpc(z) - r) for r in self.roots] or [mpf('inf')])
    def march(self, yv, nodes, order, dps, progress=None):
        """the engine's transport() loop over an arbitrary node list (complex waypoints; straight chords), returning the state at EVERY node"""
        x = mpc(nodes[0]); nstep = 0; tail_total = mpf(0); at_nodes = [list(yv)]; t0 = time.time()
        for tgt in nodes[1:]:
            tgt = mpc(tgt)
            while x != tgt:
                r = self.nearest_dist(x); dist = abs(tgt - x); step = min(self.safety * r, dist)
                if step < mpf(10) ** (-(dps + 5)): print(f'step collapsed at y={x}: a singular point of the connection lies on the path'); sys.exit(5)
                final = step >= dist; h = tgt - x if final else (tgt - x) / dist * step
                yv, tb = taylor_step(yv, x, h, order, len(self.state), self.polys, self.entries); tail_total += tb; nstep += 1
                x = tgt if final else x + h   # CURE 2026-09-06 (rc 5 at the real-axis node): after the final chord the landing point is the node itself, not x + h with its rounding residue (~1e-44 left the loop live and collapsed the step)
                if progress and nstep % 20 == 1: print(f'[progress] step {nstep} y=({float(x.real):.6f},{float(x.imag):.6f}) step={float(step):.3e} t={time.time()-t0:.1f}s', flush=True)
                if nstep > 100000: print('step limit'); sys.exit(4)
            at_nodes.append(list(yv))
        return at_nodes, nstep, tail_total
# ---------------- seeds ----------------
def amflow_values(path):
    d = json.load(open(path)); out = {}
    with mp.workdps(max(mp.dps, 140)):
        for r in d['result']:
            m = tuple(r['integral']['indices']); lau = amf_laurent(r)
            for K, v in lau.items(): out[(m, int(K))] = (mpf(v.real), mpf(v.imag))
    return out
def gauge_seed(seeds, TJ, masters):
    N = len(masters); assert [tuple(m) for m in TJ['masters']] == masters, 'seed-transform masters != connection masters'
    Te = [[[Fraction(v) for v in TJ['T_eps'][i][j]] for j in range(N)] for i in range(N)]
    orders = sorted({K for (_, K) in seeds}); new = {}; q = lambda f: mpf(f.numerator) / mpf(f.denominator)
    for K in orders:
        for i in range(N):
            re_ = mpf(0); im_ = mpf(0); hit = False
            for j in range(N):
                for k, ck in enumerate(Te[i][j]):
                    if ck == 0: continue
                    v = seeds.get((masters[j], K - k))
                    if v is None: continue
                    re_ += q(ck) * v[0]; im_ += q(ck) * v[1]; hit = True
            if hit: new[(masters[i], K)] = (re_, im_)
    return new
def sig_digits(s):
    s = s.strip().lstrip('[').split(' +/-')[0]; s = s.split('e')[0].split('E')[0]
    return len([c for c in s.lstrip('-').lstrip('0').lstrip('.') if c.isdigit()])
def agree(a, b, cap):
    d = fabs(a - b); m = max(fabs(a), fabs(b))
    if d == 0: return float(cap), True
    return min(float(log10(m / d)), float(cap)), False
# ---------------- the slice references ----------------
def load_slice_ref(path, kind):
    """{(slice master, K): (mpf value, significant digits, string)}"""
    out = {}
    if kind == 'amflow':
        d = json.load(open(path))
        with mp.workdps(200):
            for r in d['result']:
                m = tuple(r['integral']['indices']); lau = amf_laurent(r)
                for c in r['coefficients']:
                    K = int(c['order']); s = c['value']['re']; out[(m, K)] = (mpf(lau[K].real), sig_digits(s), s)
    else:
        d = json.load(open(path)); capd = int(d['dps']) + 5   # CURE v3: the evaluator prints at dps + 5; an exact value prints short ('1.0', '-4.0') and is NOT a 2-digit reference
        with mp.workdps(200):
            for key, s in d['values'].items():
                mstr, K = key.split('|'); m = tuple(json.loads(mstr)); out[(m, int(K))] = (mpf(s), capd, s)
    return out
def slice_comparison(mean_by_key, lead, masters, meaning, GMp, slice_refs, kmin, kmax, dps, bar):
    """the landed gauged vector (real parts by (master, K)) mapped onto the slice by the gate map and compared with every fixed slice reference"""
    GM = json.load(open(GMp)); refs = {lab: (load_slice_ref(p, kind), p, sha(p)) for (lab, p, kind) in slice_refs if os.path.exists(p)}
    refs_missing = [lab for (lab, p, kind) in slice_refs if not os.path.exists(p)]
    rows = []; excluded = []; structural_zero = []; identical = 0
    mapped_state = {tuple(r['state_master']) for r in GM['rows']}
    for i, m in enumerate(masters):
        if m not in mapped_state: excluded.append({'master': list(m), 'meaning': meaning[i] if meaning else None, 'why': 'no slice record (a derivative combination at y = x: antisymmetric pair / third relation)'})
    for r in GM['rows']:
        sm, gm, f = tuple(r['state_master']), tuple(r['gate_master']), Fraction(r['factor']); fac = mpf(f.numerator) / f.denominator
        for K in range(kmin, kmax + 1):
            if K < lead[sm]:
                structural_zero.append({'master': list(sm), 'order': K, 'why': f'below the lead order {lead[sm]} (absent in the seed and in every record)'}); continue
            v = mean_by_key[(sm, K)] * fac
            for lab, (RF, p, s) in refs.items():
                if (gm, K) not in RF: continue
                rv, cap, rs = RF[(gm, K)]; capd = min(cap, dps + 5)
                dg, ident = agree(v, rv, capd); identical += int(ident)
                rows.append({'state_master': list(sm), 'slice_master': list(gm), 'factor': str(f), 'order': K, 'reference': lab, 'landed_x_factor': mp.nstr(v, 30), 'reference_value': mp.nstr(rv, 30), 'agree_d': round(dg, 2), 'cap_d': capd, 'identical': ident})
    worst = min(rows, key=lambda r: r['agree_d']) if rows else None
    per_order = {}
    for r in rows:
        k = str(r['order']); c = per_order.setdefault(k, {'min': None, 'member': None, 'n': 0, 'max': None})
        c['n'] += 1
        if c['min'] is None or r['agree_d'] < c['min']: c['min'], c['member'] = r['agree_d'], {'master': r['slice_master'], 'reference': r['reference']}
        if c['max'] is None or r['agree_d'] > c['max']: c['max'] = r['agree_d']
    per_ref = {}
    for r in rows:
        c = per_ref.setdefault(r['reference'], {'min': None, 'member': None, 'n': 0})
        c['n'] += 1
        if c['min'] is None or r['agree_d'] < c['min']: c['min'], c['member'] = r['agree_d'], {'master': r['slice_master'], 'order': r['order']}
    fails = [r for r in rows if r['agree_d'] < bar]
    return {'rows': rows, 'excluded': excluded, 'structural_zero': structural_zero, 'identical': identical, 'worst': worst, 'per_order': per_order, 'per_ref': per_ref, 'fails': fails}, refs, refs_missing
# ---------------- leg A ----------------
def leg_A(a):
    LN = LINES[a.line]; X, Y0 = LN['x'], LN['y0']; G = LN['gauge']
    conn = f'{G}/A_prime_y.json'; TJp = f'{G}/T_at_y0.json'; GMp = f'{G}/GATE_MAP_slice.json'; MONO = f'{G}/A_prime_y_eps_monomial.json'; ROUTE = f'{G}/ROUTE.json'
    for p in (conn, TJp, GMp, MONO, ROUTE): assert os.path.exists(p), p
    TJ = json.load(open(TJp)); assert Fraction(TJ['y0']) == Y0 and Fraction(TJ['x']) == X and TJ['third_relation_applied'], (TJ['y0'], TJ['x'])
    # the seed and its point of record (REFUSE a foreign point)
    SP = json.load(open(f'{HERE}/seed_points.json')); seed_path = a.seed or f'{VENDOR}/{LN["seed_file"]}'
    tag = SP['files'].get(os.path.relpath(os.path.abspath(seed_path), VENDOR), os.path.basename(seed_path).split('.')[0])
    PTS = SP['points']; pref = tag[:3]
    if pref not in PTS: print(f'REFUSED: seed {tag} has no point of record in seed_points.json'); sys.exit(2)
    pt = PTS[pref]
    if Fraction(pt['p12sq']) != X or Fraction(pt['p34sq']) != Y0 or pt['line'] != a.line:
        print(f"REFUSED: seed {tag} is at (p12^2, p34^2) = ({pt['p12sq']}, {pt['p34sq']}) on the {pt['line']} line, not the (x, y0) = ({X}, {Y0}) of the --line {a.line} landing (a foreign point)"); sys.exit(2)
    mp.dps = a.dps + 10; order = int(-(-17 * a.dps // 10)) + 20
    seeds_raw = amflow_values(seed_path); planted = None
    if a.plant:
        ms, K, p = a.plant.split('|'); m = tuple(json.loads(ms)); K = int(K); p = int(p); v = seeds_raw[(m, K)]
        seeds_raw[(m, K)] = (v[0] * (1 + mpf(10) ** (-p)), v[1]); planted = {'master': list(m), 'order': K, 'relative_perturbation': f'1e-{p}'}
    seeds = gauge_seed(seeds_raw, TJ, [tuple(m) for m in json.load(open(conn))['masters']])
    S = GaugedSystem(conn, a.kmin, a.kmax, seeds, mpf(Fraction(a.safety).numerator) / Fraction(a.safety).denominator)
    assert S.x == X and S.pole_at_x_present, 'the gauged connection carries no pole at y = x (the route census says it survives)'
    rho = Fraction(a.rho); rho_m = mpf(rho.numerator) / rho.denominator; N = a.nodes; xs = mpc(mpf(X.numerator) / X.denominator)
    alias = float(rho_m / S.R_next) ** N
    cert = None
    if a.certificate:
        if a.tools: sys.path.insert(0, a.tools)
        try: from detransport import load_monomial_json, frobenius_basis
        except ImportError: print('CERTIFICATE REFUSED: the detransport package is not importable (pass --tools DIR, the directory holding it); the certificate of record is carried by landed_record.json beside this file'); sys.exit(2)
        t0 = time.time(); desys = load_monomial_json(MONO, dps_check=20)
        fb = frobenius_basis(desys, Fraction(a.eps0_cert), X, 20, 6, cluster_tol=1e-40)
        with mp.workdps(20):
            ind = [complex(v) for v in fb['indicial']]; near_int = all(abs(z.imag) < 1e-15 and abs(z.real - round(z.real)) < 1e-15 for z in ind)
            cert = {'eps0': a.eps0_cert, 'x_sing': str(X), 'dps': 20, 'kmax': 6, 'indicial': [str(v) for v in fb['indicial']], 'indicial_integer_multiset': sorted(int(round(z.real)) for z in ind), 'all_integer': near_int,
                    'log_max': fb['log_max'], 'sheared': fb['sheared'], 'n_shears': fb.get('n_shears'), 'clusters': [[str(e), int(m_)] for e, m_ in fb['clusters']], 'wall_s': round(time.time() - t0, 2),
                    'monomial_json': {'file': os.path.relpath(MONO, HERE), 'sha256': sha(MONO)}, 'route_of_record': {'file': os.path.relpath(ROUTE, HERE), 'sha256': sha(ROUTE)},
                    'verdict': ('APPARENT: integer indicials + log_max 0' if (near_int and fb['log_max'] == 0) else 'NOT apparent in this gauge')}
        assert cert['all_integer'] and cert['log_max'] == 0, cert
        print('CERTIFICATE re-derived:', cert['indicial_integer_multiset'], 'log_max', cert['log_max'], 'sheared', cert['sheared'], f"{cert['wall_s']} s", flush=True)
    # the initial state vector (the engine's form) and the path
    yv = [mpf(0)] * len(S.state)
    for n, (i, K) in enumerate(S.state):
        v = seeds.get((S.masters[i], K)); yv[n] = v[0] if v else mpf(0)
    y0m = mpc(mpf(Y0.numerator) / Y0.denominator)
    def circle_nodes(r):
        th0 = mp.pi if (y0m.real < xs.real) else mpf(0)
        return [xs + r * mp.exp(mpc(0, 1) * (th0 + 2 * mp.pi * k / N)) for k in range(N + 1)]
    t0 = time.time(); circ = circle_nodes(rho_m)
    print(f'MARCH line {a.line}: dps {a.dps} order {order} state {len(S.state)} entries {len(S.entries)} roots {len(S.roots)} R_next {mp.nstr(S.R_next, 6)} rho {rho} N {N} alias (rho/R)^N ~ {alias:.2e}', flush=True)
    appr, n1, tail1 = S.march(yv, [y0m, circ[0]], order, a.dps, progress=True); t_appr = time.time() - t0
    at_nodes, n2, tail2 = S.march(appr[-1], circ, order, a.dps, progress=True); t_circ = time.time() - t0 - t_appr
    def land_from(at_nodes, r):
        vals = at_nodes[:N]; ns = len(S.state)
        mean = [sum(v[n] for v in vals) / N for n in range(ns)]
        resid = [sum(v[n] * (circ_r[k] - xs) for k, v in enumerate(vals)) / N for n in range(ns)] if False else None
        return mean
    ns = len(S.state); circ_pts = circ
    mean = [sum(at_nodes[k][n] for k in range(N)) / N for n in range(ns)]
    resid = [sum(at_nodes[k][n] * (circ_pts[k] - xs) for k in range(N)) / N for n in range(ns)]
    norm = max(fabs(v) for v in mean)
    mono = max(fabs(at_nodes[N][n] - at_nodes[0][n]) for n in range(ns)) / norm
    res_rel = max(fabs(v) for v in resid) / (norm * rho_m); im_rel = max(fabs(v.imag) for v in mean) / norm
    second = None
    if a.second_radius:
        t1 = time.time(); circ2 = circle_nodes(rho_m / 2); appr2, n3, tail3 = S.march(appr[-1], [circ[0], circ2[0]], order, a.dps); nodes2, n4, tail4 = S.march(appr2[-1], circ2, order, a.dps)
        mean2 = [sum(nodes2[k][n] for k in range(N)) / N for n in range(ns)]
        second = {'rho': str(rho / 2), 'nodes': N, 'steps': n3 + n4, 'tail_bound_total': float(tail3 + tail4), 'wall_s': round(time.time() - t1, 2),
                  'two_radius_agree_d_worst': min(agree(mean[n], mean2[n], a.dps + 10)[0] for n in range(ns) if fabs(mean[n]) > norm * mpf(10) ** (-(a.dps))),
                  'monodromy_rel': float(max(fabs(nodes2[N][n] - nodes2[0][n]) for n in range(ns)) / norm)}
    wall = time.time() - t0
    landed = {f'{list(S.masters[i])}|{K}': {'re': mp.nstr(mean[n].real, a.dps + 5), 'im': mp.nstr(mean[n].imag, 8), 'residue_re': mp.nstr(resid[n].real, 6), 'meaning': (S.meaning[i] if S.meaning else None)} for n, (i, K) in enumerate(S.state)}
    # ---- the slice comparison through the gate map (the function; recompare_landing.py re-runs it on a saved landing)
    mean_by_key = {(S.masters[i], K): mean[n].real for n, (i, K) in enumerate(S.state)}
    CMP, refs, refs_missing = slice_comparison(mean_by_key, S.lead, S.masters, S.meaning, GMp, LN['slice_refs'], a.kmin, a.kmax, a.dps, a.bar)
    rows, excluded, structural_zero, identical, worst, per_order, per_ref, fails = (CMP[k] for k in ('rows', 'excluded', 'structural_zero', 'identical', 'worst', 'per_order', 'per_ref', 'fails'))
    bar = a.bar
    cert_ok = (mono < mpf(10) ** (-(bar)) and res_rel < mpf(10) ** (-(bar)) and im_rel < mpf(10) ** (-(bar)))
    verdict = 'PASS' if (rows and not fails and cert_ok) else ('FAIL' if rows else 'NO_ROWS')
    out = {'receipt': f'item60 leg A: the eps-graded landing of the p12^2 = {a.line} line onto the slice at p34^2 = p12^2 = {X} by the Cauchy mean around the apparent singular point of the gauged (third-relation) connection', 'stamp_utc': stamp_now(),
           'line': a.line, 'x': str(X), 'y0': str(Y0), 'dps': a.dps, 'mp_dps': mp.dps, 'order': order, 'kmin': a.kmin, 'kmax': a.kmax, 'safety': a.safety, 'rho': str(rho), 'nodes': N, 'R_next_singular_point': mp.nstr(S.R_next, 12), 'alias_bound_(rho_over_R)^N': alias,
           'steps': {'approach': n1, 'circle': n2}, 'tail_bound_total': {'approach': float(tail1), 'circle': float(tail2)}, 'wall_s': {'approach': round(t_appr, 2), 'circle': round(t_circ, 2), 'total': round(wall, 2)},
           'n_state': len(S.state), 'n_entries': len(S.entries), 'n_roots': len(S.roots), 'lead_orders': {str(list(m)): k for m, k in S.lead.items()},
           'certificates': {'monodromy_rel': float(mono), 'residue_rel': float(res_rel), 'imag_rel': float(im_rel), 'reading': 'monodromy = |J(after the closed loop) - J(start)| / max|J|; residue = |mean((y-x) J)| / (rho max|J|) ~ the (y-x)^{-1} content of the landed solution (the physical solution has none); imag = |Im mean| / max|J| (the slice values are real)', 'second_radius': second},
           'frobenius_certificate_rederived': cert, 'seed': {'file': os.path.relpath(seed_path, VENDOR), 'sha256': sha(seed_path), 'tag': tag, 'point_of_record': pt, 'points_file': {'file': 'seed_points.json', 'sha256': sha(f'{HERE}/seed_points.json')}, 'orders_present': sorted({K for (_, K) in seeds_raw}), 'planted': planted},
           'gauge': {'connection': {'file': os.path.relpath(conn, HERE), 'sha256': S.conn_sha}, 'T_at_y0': {'file': os.path.relpath(TJp, HERE), 'sha256': sha(TJp)}, 'gate_map': {'file': os.path.relpath(GMp, HERE), 'sha256': sha(GMp)}, 'route': {'file': os.path.relpath(ROUTE, HERE), 'sha256': sha(ROUTE)}, 'masters': [list(m) for m in S.masters], 'masters_new_basis_meaning': S.meaning},
           'landed_gauged_vector_at_y_eq_x': landed, 'slice_references': {lab: {'file': os.path.relpath(p, HERE), 'sha256': s, 'n_values': len(RF)} for lab, (RF, p, s) in refs.items()}, 'slice_references_missing': refs_missing,
           'comparison': {'metric': 'agree_d = log10(max(|a|,|b|)/|a-b|) on the real parts, capped by the shorter string (cap_d); identical strings count as the cap', 'bar': bar, 'n_rows': len(rows), 'worst': worst, 'per_order_floor_with_member': per_order, 'per_reference_floor_with_member': per_ref, 'identical_strings': identical,
                          'excluded_masters_no_slice_record': excluded, 'structural_zeros_excluded': structural_zero, 'fails_by_name': fails, 'rows': rows},
           'verdict': verdict, 'PROVENANCE': {'engine': {'name': ENGINE, 'sha256_prefix_of_record': ENGINE_SHA16, 'vendored': 'poly_shift / rat_taylor / taylor_step / the polyroots step control (SAFETY x nearest-pole distance) / the trailing-window tail bound, verbatim; the seed parser oracle_harness.amf_laurent and the --seed-transform convolution, verbatim'},
                                              'extension': 'an arbitrary complex node list (the closed circle), the Cauchy mean at the apparent singular point, the monodromy / residue / imaginary certificates, the gate map onto the slice with the fixed references, the planted-digit and foreign-point controls, the certificate re-derivation',
                                              'detransport_land_form': 'the queue names detransport.land (fixed eps); leg B (--fixed-eps-leg) runs it on the same gauged system with the eps-order-22 seed; leg A is the eps-graded landing the slice records can be compared with at their own depth',
                                              'script': {'file': os.path.basename(__file__), 'sha256': sha(__file__)}, 'stamp_source': 'date -u'}}
    tagp = (a.out_tag or '') + ('_planted' if planted else '')
    outp = a.out or f'LANDING_A_line{a.line}_dps{a.dps}{tagp}_{out["stamp_utc"].replace("-", "").replace(":", "")}.json'
    fd = os.open(outp, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o444); os.write(fd, json.dumps(out, indent=1).encode()); os.close(fd)
    print(f"LANDED line {a.line} dps {a.dps}: {len(rows)} rows, worst {worst['agree_d'] if worst else None} d ({worst['slice_master'] if worst else None} eps^{worst['order'] if worst else None} vs {worst['reference'] if worst else None}), identical {identical}, monodromy {float(mono):.2e}, residue {float(res_rel):.2e}, imag {float(im_rel):.2e}, steps {n1}+{n2}, wall {wall:.1f} s -> {outp}")
    if fails: print('FAIL by name:', '; '.join(f"{r['slice_master']} eps^{r['order']} vs {r['reference']}: {r['agree_d']} d < bar {bar}" for r in fails))
    print('VERDICT', verdict, f'({outp})')
    return 0 if verdict == 'PASS' else 1
def main():
    ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
    ap.add_argument('--line', required=True, choices=['-3', '-2']); ap.add_argument('--dps', type=int, default=60); ap.add_argument('--rho', default='1/16'); ap.add_argument('--nodes', type=int, default=64)
    ap.add_argument('--kmin', type=int, default=-2); ap.add_argument('--kmax', type=int, default=1); ap.add_argument('--safety', default='1/4'); ap.add_argument('--seed', default=None); ap.add_argument('--plant', default=None, help='"[master]|K|p": multiply the seed value by (1 + 10^-p) before the gauge (control: FAIL by name)')
    ap.add_argument('--bar', type=float, default=30.0); ap.add_argument('--certificate', action='store_true'); ap.add_argument('--eps0-cert', default='1/97'); ap.add_argument('--second-radius', action='store_true'); ap.add_argument('--out', default=None); ap.add_argument('--out-tag', default=None)
    ap.add_argument('--fixed-eps-leg', action='store_true'); ap.add_argument('--eps0', default='1e-8'); ap.add_argument('--kmax-frob', type=int, default=40); ap.add_argument('--landing', default=None, help='leg A LANDING json to compare the fixed-eps value with'); ap.add_argument('--tools', default=None, help='the directory holding the detransport package (for --certificate and --fixed-eps-leg)')
    a = ap.parse_args()
    if a.fixed_eps_leg:
        from land_fixed_eps_legB import leg_B
        return leg_B(a, LINES, HERE, sha, stamp_now, amflow_values)
    return leg_A(a)
if __name__ == '__main__': sys.exit(main())
