Jump to content

The Principia Machina/TPC-PY/verify lr7 hunks.py

From The Invariance Itself
Revision as of 15:43, 27 September 2026 by BFP Rauch (talk | contribs) (TPC-PY source verify_lr7_hunks.py (0.1.0), SHA-256 0f7d967a2cbd113c; conformed TPS 0.3.0; PROPOSED, not declared (CO-8))
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
"""verify_lr7_hunks 0.1.0: replays landing round 7's hunk sets with
hunk_apply in both residences (MEASURED). For each hunks_<target>.json in
SRC: the delivered target is reverse-applied (new -> old) to rebuild the
baseline, whose SHA-256 must equal the recorded baseline_sha256; the
forward application (old -> new) of the rebuilt baseline must give the
delivered target byte for byte; the PHP residence must give the same
SHA-256 for both directions. A set whose reverse application is refused
is reported as such (the PMP-TPM set: four hunks' new texts were amended
after the hunks by the verification fixes of LR7 9.3, so they no longer
occur in 0.12.0). Usage: python3 verify_lr7_hunks.py [SRC]. SRC defaults
to hunk_inputs/lr7_request beside this file, which holds the request set
only (GEN-PATHS, 2026-09-27); the PHP stub and its input are written to a
temporary folder outside the tree and removed; tpc_hunk.php is read from
../tpc_php (the layout since increment 9)."""
import hashlib, json, os, shutil, subprocess, sys, tempfile
here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, here)
from tpc_hunk import hunk_apply
SRC = sys.argv[1] if len(sys.argv) > 1 else os.path.join(here, "hunk_inputs", "lr7_request")
SETS = [("hunks_record.json", None), ("hunks_pmp.json", None),
        ("hunks_request.json", None), ("hunks_readme.json", "README_current_versions.txt")]
PHP = r'''<?php
declare(strict_types=1);
require $argv[1];
$in = json_decode(file_get_contents($argv[2]), false, 512, JSON_THROW_ON_ERROR);
$r = tpc_hunk_apply($in->base, $in->hunks);
echo json_encode($r['status'] === 'OK' ? ['status' => 'OK', 'sha256' => $r['sha256']] : $r);
'''
TMP = tempfile.mkdtemp(prefix="tpc_verify_lr7_")
php_path = os.path.join(TMP, "_verify_lr7.php")
open(php_path, "w", encoding="utf-8").write(PHP)
def php_apply(base, hunks):
    inp = os.path.join(TMP, "_verify_lr7_in.json")
    json.dump({"base": base, "hunks": hunks}, open(inp, "w", encoding="utf-8"), ensure_ascii=False)
    out = subprocess.run(["php", php_path, os.path.join(here, "..", "tpc_php", "tpc_hunk.php"), inp], capture_output=True, text=True, check=True).stdout
    return json.loads(out)
for name, target_name in SETS:
    path = os.path.join(SRC, name)
    if not os.path.exists(path):
        print(name, "NOT FOUND"); continue
    d = json.load(open(path, encoding="utf-8"))
    tname = target_name or d["target"]
    target = open(os.path.join(SRC, tname), encoding="utf-8", newline="").read()
    hs = d["hunks"]
    rev = hunk_apply(target, [{"old": h["new"], "new": h["old"]} for h in hs])
    if rev["status"] != "OK":
        print("%s: %d hunks; reverse application REFUSED %s at hunk %d (n=%s, anchor=%s)" % (
            name, len(hs), rev["reason"], rev["hunk"], hs[rev["hunk"] - 1]["n"], hs[rev["hunk"] - 1]["anchor"]))
        continue
    base = rev["text"]
    bsha = hashlib.sha256(base.encode("utf-8")).hexdigest()
    fwd = hunk_apply(base, [{"old": h["old"], "new": h["new"]} for h in hs])
    php_rev = php_apply(target, [{"old": h["new"], "new": h["old"]} for h in hs])
    php_fwd = php_apply(base, [{"old": h["old"], "new": h["new"]} for h in hs])
    tsha = hashlib.sha256(target.encode("utf-8")).hexdigest()
    print("%s: %d hunks; baseline sha256 %s recorded %s %s; forward %s target %s %s; php reverse %s forward %s" % (
        name, len(hs), bsha[:16], d["baseline_sha256"][:16], "MATCH" if bsha == d["baseline_sha256"] else "MISMATCH",
        fwd["sha256"][:16], tsha[:16], "BYTE-IDENTICAL" if fwd["status"] == "OK" and fwd["text"] == target else "DIFFERENT",
        "MATCH" if php_rev.get("sha256") == bsha else "MISMATCH", "MATCH" if php_fwd.get("sha256") == tsha else "MISMATCH"))
shutil.rmtree(TMP)