"""RUN-068 - BCODR LUC 07: root 131, candidate/germ alignment and mirror covariance.

BCODR-LUC-07 (2026-09-21) is a single document, without a package. It takes LUC 06's narrowing of the selected spine to
root 131, prints 131's nearest ray/155 pair, its IMBG meeting point (normalized and original) and T* = 0.0473333498919449,
and proves that a midpoint germ with T* > 0 is not the ray's point. It splits alignment into point, seed and structural
alignment; says Cycle 17's low-area candidate in 131 (A_cand = 0.8349862484449208) is recorded by value only, "not a
canonical parameter vector", so that the candidate's distances to the germ are a local obligation (CERT-07.1, 07.2);
proves that exact up/down symmetry makes a planar body achiral (S_x = R_pi S_y) and applies it to Paper 07's zero-
rotation barrier, whose symmetry it takes from the reconstruction (CERT-07.4 to replay); states mirror covariance of the
problem, of the support function, of the dual pressures and of the germ stiffness; and sends the work back to Paper 09C,
whose three secondary slivers it places at pi/2 and at pi -+ theta*. Here the printed vectors are traced and checked
against 50-digit values, the candidate's vector is read from the archive and its distances computed, the barrier's
symmetry is checked piece by piece, and the slivers are RUN-060's.

Checks
  A0 anchors      the statements below occur in the document as written
  W1 data         sec. 1: the printed pair, meeting point, T*, rho* and kappa against 50 digits, and where they come from
  W2 separation   sec. 3-4: the midpoint theorem and the printed distances
  W3 candidate    sec. 6, 18: Cycle 17's stored minimizer for 131 - its value, its place, its distances; the barrier in 131
  W4 symmetry     sec. 7-9, 11, CERT-07.4: S_x = R_pi S_y; the barrier's bodies and its support function under y -> -y
  W5 slivers      sec. 22: where the secondary slivers open along the critical velocity (RUN-060)
  W6 archive      sec. 0, 23: what the document builds on and what it says it ships
  P1 package      the document's bytes against the archive

Usage: python code/run068_bcodr_luc07.py [--drill] [--blind CID]
"""
import argparse
import copy
import hashlib
import inspect
import json
import re

import mpmath as mp

import gate
import run048_uesfcm_cycles_12_14 as r48
import run049_uesfcm_cycles_15_17 as r49
import run057_lesr_paper07 as r57
import run064_bcodr_luc02 as r64
import run065_bcodr_luc03 as r65
import run066_bcodr_luc04 as r66
from corpus import SOURCES, TREE, source_bytes, walk_sources

DOC = "main.zip!/BCODR/BCODR_LUC_07_Root131_Candidate_Germ_Alignment_and_Mirror_Covariance_v0.1.md"
LEDGER03 = r65.LEDGER
LOG = TREE / "data" / "gate-logs" / "run068-bcodr-luc07.json"
LOG60 = TREE / "data" / "gate-logs" / "run060-lesr-paper09b.json"
LOG67 = TREE / "data" / "gate-logs" / "run067-bcodr-luc05.json"
MANIFEST = TREE / "data" / "SOURCE_MANIFEST.v1.json"
CACHE = TREE / "data" / "cache" / "run068-searches.json"     # data/cache is not committed
DPS = 50
NUM = r"-?\d+\.\d+(?:e-?\d+)?"


def load_inputs():
    blobs = {n: source_bytes(n) for n in SOURCES}
    got = {leaf.id: d for leaf, d in walk_sources(blobs, keep=lambda l: l.id in (DOC, LEDGER03)) if d is not None}
    manifest = json.loads(MANIFEST.read_text(encoding="utf-8"))["leaves"]
    ms = r49.load_inputs()["minsearch"]
    k = list(ms["local_index"]).index(131)
    c11 = r48.load_inputs()
    return {"text": got[DOC].decode("utf-8"), "bytes": got[DOC], "manifest_row": next(r for r in manifest if r[0] == DOC),
            "luc_paths": sorted(r[0].split("BCODR/")[-1] for r in manifest if "BCODR_LUC_0" in r[0] and r[0].count("!/") <= 2),
            "ledger03": json.loads(got[LEDGER03]), "cand": {"sol": [float(x) for x in ms["sol"][k]], "value": float(ms["min_search"][k]),
                                                            "lowest": sorted((float(v), int(i)) for v, i in zip(ms["min_search"], ms["local_index"]))[:2]},
            "subroots": c11["subroots"], "root": c11["root"], "log60": json.loads(LOG60.read_text(encoding="utf-8")),
            "log67": json.loads(LOG67.read_text(encoding="utf-8"))}


# ---------------------------------------------------------------- rebuilt

def pair131(sub, root, rho_doc):
    """the exact nearest pair of the ray and 155 (as RUN-067), the midpoint, and the ray's point at the printed rho*"""
    s = lambda x: mp.nstr(x, 30)
    with mp.workdps(DPS):
        g, lo, hi, ql, qh = r66.frame(sub, root)

        def pair(r):
            p = r65.ray_n(g, r)
            q = [min(max(p[k], ql[k]), qh[k]) for k in range(5)]
            return sum((p[k] - q[k]) ** 2 for k in range(5)), p, q
        rs = mp.findroot(lambda r: mp.diff(lambda x: pair(x)[0], r), mp.mpf("0.00254068887"))
        d2, p, q = pair(rs)
        z = [(p[k] + q[k]) / 2 for k in range(5)]
        W = [2 * mp.mpf(root[1][k]) for k in range(5)]
        mid = [mp.mpf(root[0][k]) for k in range(5)]
        return {"r": s(rs), "T": s(mp.sqrt(d2) / 2), "p": [s(x) for x in p], "q": [s(x) for x in q], "z": [s(x) for x in z],
                "z_original": [s(mid[k] + W[k] * z[k]) for k in range(5)], "p_at_doc_rho": [s(x) for x in r65.ray_n(g, mp.mpf(rho_doc))]}


def candidate(sub, root, sol, z):
    """Cycle 17's stored minimizer for 131: its exact hull area; its normalized place in 131; its distances to the IMBG
    point, to the ray (0 <= rho <= 0.003) and to each prune box; the barrier (the ray at rho = 0) in 131, and its area"""
    s = lambda x: mp.nstr(x, 20)
    with mp.workdps(40):
        g, lo, hi, ql, qh = r66.frame(sub, root)
        lo, hi = r65.nbox(g, 131)
        W = [2 * mp.mpf(root[1][k]) for k in range(5)]
        mid = [mp.mpf(root[0][k]) for k in range(5)]
        zc = [(mp.mpf(sol[k]) - mid[k]) / W[k] for k in range(5)]
        dist = lambda a, b: mp.sqrt(sum((a[k] - b[k]) ** 2 for k in range(5)))
        f = lambda r: dist(zc, r65.ray_n(g, r))
        grid = [mp.mpf(0.003) * i / 600 for i in range(601)]
        k0 = min(range(601), key=lambda i: f(grid[i]))
        _, rr = r65.golden_max(lambda r: -f(r), grid[max(k0 - 1, 0)], grid[min(k0 + 1, 600)], (mp.sqrt(5) - 1) / 2, 120)
        boxes = {j: r65.nbox(g, j) for j in r64.PRUNE}
        barrier = r65.ray_n(g, mp.mpf(0))
    m0 = r57.hp_constants(DPS)["area"]
    return {"area": s(mp.mpf(r48.area(sol, 16384))), "z": [s(x) for x in zc], "margins": [s(min(zc[k] - lo[k], hi[k] - zc[k])) for k in range(5)],
            "d_germ": s(dist(zc, [mp.mpf(x) for x in z])), "d_ray": s(f(rr)), "rho_ray": s(rr),
            "d_prune": {str(j): s(mp.sqrt(sum(max(0, b[0][k] - zc[k], zc[k] - b[1][k]) ** 2 for k in range(5)))) for j, b in boxes.items()},
            "barrier_in_131": all(lo[k] <= barrier[k] <= hi[k] for k in range(5)), "barrier_faces": [k for k in range(5) if barrier[k] in (lo[k], hi[k])],
            "m0": m0[:30]}


def symmetry():
    """the zero-rotation barrier K = conv(D, B3 + (x3*, 0), B5 + (x5*, 0)): its 17 support pieces (the disc, B3's three
    corners and arcs, B5's five corners and arcs) at 50 digits; whether y -> -y maps the corner sets onto themselves;
    and |h_K(theta) - h_K(-theta)| over 1440 angles"""
    with mp.workdps(DPS):
        pi = mp.pi
        c = r57.hp_constants(DPS)
        x3, x5 = mp.mpf("-0.01215883209899") - mp.mpf("0.00882"), mp.mpf(c["x5"])
        R3, R5 = 1 / mp.sqrt(3), 1 / (2 * mp.cos(pi / 10))
        V = [(x3 + R3 * mp.cos(2 * pi * k / 3), R3 * mp.sin(2 * pi * k / 3)) for k in range(3)]
        Wc = [(x5 + R5 * mp.cos(2 * pi * k / 5), R5 * mp.sin(2 * pi * k / 5)) for k in range(5)]
        pieces = [((mp.mpf(0), mp.mpf(0)), mp.mpf(1) / 2, None)] + [(V[k], 0, None) for k in range(3)] + \
                 [(V[k], 1, (2 * pi * k / 3 + pi, pi / 6)) for k in range(3)] + [(Wc[k], 0, None) for k in range(5)] + \
                 [(Wc[k], 1, (2 * pi * k / 5 + pi, pi / 10)) for k in range(5)]

        def h(t):
            best = None
            for cc, r, rg in pieces:
                if rg is not None and abs(mp.fmod(t - rg[0] + 3 * pi, 2 * pi) - pi) > rg[1]:
                    continue
                v = cc[0] * mp.cos(t) + cc[1] * mp.sin(t) + r
                best = v if best is None or v > best else best
            return best
        mirrored = lambda P: max(min(abs(a[0] - b[0]) + abs(-a[1] - b[1]) for b in P) for a in P)
        dev = max(abs(h(2 * pi * i / 1440 + mp.mpf("1e-7")) - h(-(2 * pi * i / 1440 + mp.mpf("1e-7")))) for i in range(1440))
        half = max(abs(h(pi - t) - h(t + pi)) for t in [2 * pi * i / 360 + mp.mpf("1e-7") for i in range(360)])
        return {"corners_B3": mp.nstr(mirrored(V), 5), "corners_B5": mp.nstr(mirrored(Wc), 5), "even": mp.nstr(dev, 5), "half_turn": mp.nstr(half, 5)}


def _key(fn, extra=""):
    digest = hashlib.sha256(inspect.getsource(fn).encode())
    for helper in (r66.frame, r65.nbox, r65.ray_n, r65.golden_max, r64.grid_boxes, r64.ray_units, r57.hp_constants, r48.area):
        digest.update(inspect.getsource(helper).encode())
    digest.update(f"{DPS} {r64.X30} {r64.S} {r64.X5} {r64.U} {r64.V}".encode())
    digest.update(extra.encode())
    return digest.hexdigest()


def searches(inputs, rho_doc):
    cached = json.loads(CACHE.read_text(encoding="utf-8")) if CACHE.exists() else {}
    out = {}
    sub, root = inputs["subroots"], inputs["root"]
    tag = json.dumps([sub, root, inputs["cand"]["sol"], rho_doc], sort_keys=True)
    jobs = (("pair", pair131, lambda: pair131(sub, root, rho_doc)), ("candidate", candidate, lambda: candidate(sub, root, inputs["cand"]["sol"], out["pair"]["z"])),
            ("symmetry", symmetry, symmetry))
    for name, fn, call in jobs:
        key = _key(fn, tag)
        if cached.get(name, {}).get("key") != key:
            cached[name] = {"key": key, "value": json.loads(json.dumps(call()))}
            CACHE.parent.mkdir(parents=True, exist_ok=True)
            CACHE.write_text(json.dumps(cached, indent=1) + "\n", encoding="utf-8")
        out[name] = cached[name]["value"]
    return out


def printed(text):
    """the vectors and numbers sec. 1 and 4 print"""
    vec = lambda name: [float(x) for x in re.findall(NUM, re.search(name + r"\s*=\s*\(([^)]*)\)", text).group(1))]
    blocks = re.findall(r"\$\$\s*(p_\{131\}\^\{\\star\}|q_\{155\}\^\{\\star\}|z_\{131\}\^\{\\star\})\s*=\s*\(([^)]*)\)", text)
    out = {}
    for name, body in blocks:
        out.setdefault(name, []).append([float(x) for x in re.findall(NUM, body)])
    sec4 = text[text.index("# 4. Consequence for Root 131"):text.index("# 5. Provenance Alignment")]
    dist = re.findall(r"\\approx\s*(0\.\d{11,})", sec4)
    return {"p": out[r"p_{131}^{\star}"][0], "q": out[r"q_{155}^{\star}"][0], "z": out[r"z_{131}^{\star}"][0], "z_original": out[r"z_{131}^{\star}"][1],
            "rho": re.search(r"\\rho_\{131\}\^\{\\star\}\s*=\s*(0\.\d+)", text).group(1), "distances": [float(x) for x in dist[-3:]]}


# ---------------------------------------------------------------- checks

ANCHORS = {"A0": [r"\text{BCODRIMBGmeetingpoint}\neq\text{analytic-rayseedpoint}", r"T_{131}^{\star}=0.0473333498919449",
                  r"\rho_{131}^{\star}=0.00254068891729192.", r"\kappa_{131}=0.454649807778291>0.", r"z^\star\nep^\star,\qquadz^\star\neq^\star.",
                  r"\|p_{131}^{\star}-q_{155}^{\star}\|\approx0.09466669978536,", r"A_{\rmcand}\approx0.8349862484449208.",
                  "However the canonical Cycle-17 paper records the candidate value, not a canonical parameter vector sufficient by itself".replace(" ", ""),
                  r"S_x=R_\pi\circS_y.", r"S_yK=K\Longrightarrow K\text{isnotchiralasanunmarkedplanarbody.}".replace(" ", ""),
                  r"h_{S_xK}(\theta)=h_K(\pi-\theta).", r"h_{S_yK}(\theta)=h_K(-\theta).", r"\kappa_{\rmgerm}^\sigma=\kappa_{\rmgerm}.",
                  r"$$\pi-\theta_\star;$$", r"$$\pi+\theta_\star.$$", "ROOT131CYCLE17CANDIDATEPARAMETER:NEEDCANONICALEXPORT",
                  "ThecompanionJSONschemaandverifierinthispackageintentionallyseparate:"]}
CLAIMS = {
    # the printed vectors are LUC 03's ledger values, off the exact pair by up to 5e-7; T* is right
    "data_claim": {"from_luc03": [True, True, True, True], "off_exact": {"p": 5e-07, "q": 6e-08, "z": 2e-07, "z_original": 6e-09}, "p_vs_ray_at_printed_rho": 5e-07,
                   "luc03_rho": 0.002540676056935806, "q_carries_z": [True, True, True], "T": 6e-17, "rho": 4.2e-11, "kappa_run067": "0.45464980777815"},
    "separation_claim": {"printed_distances": [True, True, True], "printed_pair_over_exact": 1.5e-12, "exact_midpoint": [True, True]},
    # the vector sec. 6 says is not recorded is in Cycle 17's diagnostic; 131's corner, the barrier, is 1.379e-7 lower
    "candidate_claim": {"value": 0.8349862484449208, "printed": True, "exact_area": True, "lowest": 131, "inside_131": True, "least_margin": 6.6e-06,
                        "d_germ": 0.1091, "d_ray": [0.000773, 0.000167], "nearest_box": ["155", 0.1243], "barrier": [True, [1, 2, 4]], "below": 1.379e-07},
    "symmetry_claim": {"Sx_is_Rpi_Sy": True, "corners": [True, True], "even": True, "half_turn": True},
    "slivers_claim": {"slivers": [["B5a3", 0.454], ["D", 1.571], ["B5a2", 5.829]], "corners_at_pi_pm_theta": False},
    "archive_claim": {"luc07_files": ["BCODR_LUC_07_Root131_Candidate_Germ_Alignment_and_Mirror_Covariance_v0.1.md"], "luc06_files": [],
                      "packages": ["01", "02", "03", "04", "05"]},
    "package_claim": {"manifest": True, "size": [23127, 23127], "delimiters": [], "ends": True},
}


def sig(x, n=2):
    return float(f"{float(x):.{n - 1}e}")


def maxdev(a, b):
    return max(abs(mp.mpf(x) - mp.mpf(y)) for x, y in zip(a, b))


def w1_data(w):
    """the printed p*, q*, z* (normalized and original) are LUC 03's ledger values for 131, to the last bit; against the
    exact pair they are off by up to 5e-7, because they belong to LUC 03's rho (0.0025406761) and not to the printed rho*
    (LUC 05's), at which the ray's point differs from the printed p* by as much; q* carries z*'s y3 and x5, not p*'s; T* is
    right to all its digits, rho* to 4e-11, kappa as RUN-067"""
    with mp.workdps(DPS):
        pr, pa, row = w["printed"], w["search"]["pair"], next(r for r in w["ledger03"]["rows"] if r["parent"] == 131)
        same = lambda a, b: max(abs(x - y) for x, y in zip(a, b)) < 1e-15        # sec. 1 prints LUC 03's -0.24999999999999983 as -0.25
        got = {"from_luc03": [same(pr["p"], row["ray_point_normalized"]), same(pr["q"], row["prune_projection_normalized"]), same(pr["z"], row["meeting_point_normalized"]),
                              same(pr["z_original"], row["meeting_point_original"])],
               "off_exact": {k: sig(maxdev(pr[k], pa[k]), 1) for k in ("p", "q", "z", "z_original")},
               "p_vs_ray_at_printed_rho": sig(maxdev(pr["p"], pa["p_at_doc_rho"]), 1), "luc03_rho": row["ray_rho"],
               "q_carries_z": [pr["q"][1] == pr["z"][1], pr["q"][3] == pr["z"][3], pr["q"][1] != pr["p"][1]],
               "T": sig(abs(mp.mpf("0.0473333498919449") - mp.mpf(pa["T"])), 1), "rho": sig(abs(mp.mpf(pr["rho"]) - mp.mpf(pa["r"])), 2),
               "kappa_run067": w["log67"]["w3"]["kappa"][0]}
    w["w1"] = got
    return [] if got == w["data_claim"] else [f"the data: {got}"]


def w2_separation(w):
    """the theorem is immediate: a midpoint at T* > 0 is T* from both seeds; the three printed distances are those of the
    printed vectors, and the printed |p* - q*| is 1.5e-12 longer than the exact pair, 2 T*"""
    with mp.workdps(DPS):
        pr, pa = w["printed"], w["search"]["pair"]
        P, Q, Z = ([mp.mpf(x) for x in pr[k]] for k in ("p", "q", "z"))
        d = lambda a, b: mp.sqrt(sum((a[k] - b[k]) ** 2 for k in range(5)))
        mine = [d(P, Q), d(P, Z), d(Q, Z)]
        ex = [mp.mpf(x) for x in pa["p"]], [mp.mpf(x) for x in pa["q"]], [mp.mpf(x) for x in pa["z"]]
        got = {"printed_distances": [abs(a - b) < 5e-15 for a, b in zip(mine, pr["distances"])], "printed_pair_over_exact": sig(mine[0] - 2 * mp.mpf(pa["T"]), 2),
               "exact_midpoint": [abs(d(ex[0], ex[2]) - mp.mpf(pa["T"])) < 1e-28, abs(d(ex[1], ex[2]) - mp.mpf(pa["T"])) < 1e-28]}
    w["w2"] = got
    return [] if got == w["separation_claim"] else [f"the separation: {got}"]


def w3_candidate(w):
    """Cycle 17's 68-cell min-search diagnostic stores the minimizer of 131 - the parameter vector sec. 6 says is not
    recorded - with exactly the printed area; it lies in 131, 6.6e-6 from its lower y3 face; it is 7.7e-4 from the ray
    (near rho = 1.7e-4), 0.109 from the IMBG point and 0.124 from 155, its nearest box. And it is not 131's lowest point:
    131's corner is the barrier itself, the ray's start, at m0 = 0.83498611055922, 1.379e-7 lower"""
    with mp.workdps(DPS):
        c, cand = w["search"]["candidate"], w["cand"]
        dp = {j: mp.mpf(v) for j, v in c["d_prune"].items()}
        got = {"value": cand["value"], "printed": cand["value"] == 0.8349862484449208, "exact_area": abs(mp.mpf(c["area"]) - mp.mpf(cand["value"])) < 1e-15,
               "lowest": cand["lowest"][0][1], "inside_131": min(mp.mpf(x) for x in c["margins"]) > 0, "least_margin": sig(min(mp.mpf(x) for x in c["margins"]), 2),
               "d_germ": sig(c["d_germ"], 4), "d_ray": [sig(c["d_ray"], 3), sig(c["rho_ray"], 3)], "nearest_box": [min(dp, key=lambda j: dp[j]), sig(min(dp.values()), 4)],
               "barrier": [c["barrier_in_131"], c["barrier_faces"]], "below": sig(mp.mpf(cand["value"]) - mp.mpf(c["m0"]), 4)}
    w["w3"] = got
    return [] if got == w["candidate_claim"] else [f"the candidate: {got}"]


def w4_symmetry(w):
    """S_x = R_pi S_y as matrices; at the barrier the disc, B3 (corners at 0, 2 pi/3, 4 pi/3) and B5 (corners at
    2 pi k/5) are each mapped onto themselves by y -> -y, so h_K is even to the working precision, and h_K(pi - t) =
    h_K(t + pi): the half-turn is the witness"""
    sy = w["search"]["symmetry"]
    Sx, Sy, Rpi = [[-1, 0], [0, 1]], [[1, 0], [0, -1]], [[-1, 0], [0, -1]]
    prod = [[sum(Rpi[i][k] * Sy[k][j] for k in range(2)) for j in range(2)] for i in range(2)]
    got = {"Sx_is_Rpi_Sy": prod == Sx, "corners": [float(sy["corners_B3"]) < 1e-45, float(sy["corners_B5"]) < 1e-45], "even": float(sy["even"]) < 1e-45,
           "half_turn": float(sy["half_turn"]) < 1e-45}
    w["w4"] = got
    return [] if got == w["symmetry_claim"] else [f"the symmetry: {got}"]


def w5_slivers(w):
    """sec. 22 puts B5's two corner slivers at pi -+ theta*, as Paper 09B did; along the critical velocity they open at
    B5's arcs a3 and a2, at theta* and 2 pi - theta*, with the disc's at pi/2 (RUN-060)"""
    s = w["log60"]["w4"]["slivers"]["1e-05"]
    got = {"slivers": [[a, round(b, 3)] for a, b, _ in s], "corners_at_pi_pm_theta": w["log60"]["w4"]["corners_at_pi_pm_theta"]}
    w["w5"] = got
    return [] if got == w["slivers_claim"] else [f"the slivers: {got}"]


def w6_archive(w):
    """the archive holds LUC 01-05 as packages and LUC 07 as this one file: no LUC 06 (whose narrowing to 131 sec. 0 cites),
    and none of the "companion JSON schema and verifier" sec. 23 describes"""
    got = {"luc07_files": [p for p in w["luc_paths"] if "LUC_07" in p], "luc06_files": [p for p in w["luc_paths"] if "LUC_06" in p],
           "packages": sorted({re.search(r"LUC_(\d\d)", p).group(1) for p in w["luc_paths"] if "Package" in p})}
    w["w6"] = got
    return [] if got == w["archive_claim"] else [f"the archive: {got}"]


def p1_package(w):
    body = w["bytes"].decode("utf-8")
    got = {"manifest": w["manifest_row"][2] == hashlib.sha256(w["bytes"]).hexdigest(), "size": [w["manifest_row"][1], len(w["bytes"])],
           "delimiters": sorted(set(re.findall(r"\\\(|\\\)|\\\[|\\\]", body))), "ends": body.rstrip().endswith("===END===")}
    w["p1"] = got
    return [] if got == w["package_claim"] else [f"the document: {got}"]


def a0_anchors(w):
    text = gate.squash(w["text"])
    return [f"anchor not found: {a[:60]}" for a in ANCHORS["A0"] if a not in text]


CHECKS = {"A0": a0_anchors, "W1": w1_data, "W2": w2_separation, "W3": w3_candidate, "W4": w4_symmetry, "W5": w5_slivers, "W6": w6_archive, "P1": p1_package}
DEPENDS = {"A0": {"text"}, "W1": {"printed", "search", "ledger03", "log67", "data_claim"}, "W2": {"printed", "search", "separation_claim"},
           "W3": {"search", "cand", "candidate_claim"}, "W4": {"search", "symmetry_claim"}, "W5": {"log60", "slivers_claim"}, "W6": {"luc_paths", "archive_claim"},
           "P1": {"bytes", "manifest_row", "package_claim"}}


def drill_cases(base):
    def edit(obj, fn):
        x = copy.deepcopy(obj)
        fn(x)
        return x

    text, s = base["text"], base["search"]
    return [
        ("K0-unmodified", "control", {}, set()),
        ("K1-crlf", "control", {"text": text.replace("\n", "\r\n")}, set()),
        ("K2-ledger-keys-sorted", "control", {"ledger03": json.loads(json.dumps(base["ledger03"], sort_keys=True))}, set()),
        ("M1-text-area", "mutation", {"text": text.replace("0.8349862484449208.", "0.8349862484449209.")}, {"A0"}),
        ("M2-printed-z", "mutation", {"printed": edit(base["printed"], lambda x: x["z"].__setitem__(2, -0.4202264))}, {"W1", "W2"}),
        ("M3-luc03-row", "mutation", {"ledger03": edit(base["ledger03"], lambda x: next(r for r in x["rows"] if r["parent"] == 131).update(ray_rho=0.0025406889))}, {"W1"}),
        ("M4-distance", "mutation", {"printed": edit(base["printed"], lambda x: x["distances"].__setitem__(0, 0.0946666997839))}, {"W2"}),
        ("M5-stored-value", "mutation", {"cand": edit(base["cand"], lambda x: x.update(value=0.83498624844492))}, {"W3"}),
        ("M6-barrier", "mutation", {"search": edit(s, lambda x: x["candidate"].update(barrier_in_131=False))}, {"W3"}),
        ("M7-even", "mutation", {"search": edit(s, lambda x: x["symmetry"].update(even="1e-20"))}, {"W4"}),
        ("M8-corners", "mutation", {"search": edit(s, lambda x: x["symmetry"].update(corners_B5="0.01"))}, {"W4"}),
        ("M9-sliver", "mutation", {"log60": edit(base["log60"], lambda x: x["w4"]["slivers"]["1e-05"][0].__setitem__(1, 2.6876))}, {"W5"}),
        ("M10-luc06", "mutation", {"luc_paths": base["luc_paths"] + ["BCODR_LUC_06_Package_v0.1.zip!/BCODR_LUC_06_STATE_v0.1.json"]}, {"W6"}),
        ("M11-bytes", "mutation", {"bytes": base["bytes"] + b" "}, {"P1"}),
    ]


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--drill", action="store_true")
    ap.add_argument("--blind", metavar="CID")
    args = ap.parse_args()
    inputs = load_inputs()
    pr = printed(inputs["text"])
    base = {**inputs, "printed": pr, "search": searches(inputs, pr["rho"])}

    def build():
        return {**copy.deepcopy(base), **copy.deepcopy(CLAIMS)}

    if args.blind:
        CHECKS[args.blind] = lambda w: []
        args.drill = True
    w = build()
    results = {}
    for c, fn in CHECKS.items():
        try:
            results[c] = fn(w)
        except KeyError as e:
            results[c] = [f"claim missing: {e}"]
    for c, f in results.items():
        print(f"{c} {'PASS' if not f else 'FAIL'}", *(f"\n     {x}" for x in f[:6]))
    for key in ("w1", "w2", "w3", "w4", "w5", "w6", "p1"):
        print(key, "=", json.dumps(w.get(key), default=str, ensure_ascii=False))
    if not args.drill:
        return
    cases = drill_cases(base)
    if args.blind:
        cases = [c for c in cases if args.blind in c[3]]
    d = gate.run_drill(build, CHECKS, DEPENDS, cases)
    summ = gate.summarize(d, CHECKS)
    print(gate.report_drill(summ))
    for x in d:
        if not x["ok"]:
            print("   DRILL FAIL", x)
    if args.blind:
        n = sum(1 for x in d if args.blind in x["expected"] and args.blind not in x["tripped"])
        print(f"blind {args.blind}: drill reported it blind in {n} cases (nothing written)")
        return
    log = {"run": "RUN-068", "subject": "BCODR LUC 07: root 131, candidate/germ alignment and mirror covariance", "document": DOC,
           "checks": {c: {"pass": not f, "failures": f} for c, f in results.items()},
           **{k: w.get(k) for k in ("w1", "w2", "w3", "w4", "w5", "w6", "p1")}, "drill": summ}
    LOG.write_text(json.dumps(log, ensure_ascii=False, indent=1, default=float) + "\n", encoding="utf-8")


if __name__ == "__main__":
    main()
