Jump to content

The Principia Machina/TPC-PY/gen hold corpus.py: Difference between revisions

From The Invariance Itself
TPC-PY source gen_hold_corpus.py (-), SHA-256 2fcf9a53688f0124; conformed TPS 0.3.0; PROPOSED, not declared (CO-8)
 
m 1 revision imported
(No difference)

Revision as of 04:32, 28 September 2026

# -*- coding: utf-8 -*-
"""Generator for tpc/vectors/hold_corpus.json (the hold-scope function,
D111.1; charter CO-21; 0.2.0: the HOLD record's bibliography list, D171
(j), tpm_biblio_resolution 0.1.0 section 6.14). Expectations are written
literally below and hand-derived from tpm_hold_scope 0.1.0: block scopes
counted on paper, closures traced by hand, refusals named from the spec's
edge-case table. Every digest is SHA-256 over the preimage the case
shows, computed with an external sha256sum, never by the module.
Deterministic: no randomness. The generator refuses to write the corpus
if the module disagrees. At 0.2.0 every hold_preimage, hold_record and
release_record case carries "biblio" ([] for the re-issued 0.1.0 cases,
whose digests moved with HOLD_FORM "2"; the hold_scope, held_closure and
tpx_allocate cases are unchanged) and new cases carry a non-empty list.
Run: cd tpc && python3 gen_hold_corpus.py (Windows: py ...)."""
import json, os, sys
HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
import tpc_strike as S
import tpc_hold as H

cases = []


def case(cid, fn, inp, expect, **extra):
    c = {"id": cid, "fn": fn, "input": inp}
    c.update(extra)
    c["expect"] = expect
    cases.append(c)


def B(n, canary=None):
    return {"block_id": "B%d" % n, "canary": canary}


def hist(blocks, adm="B1", account="acct"):
    return {"account": account, "admission_block": adm, "blocks": blocks}


# ============================================================================
# hold_scope: the held block set
# ============================================================================
# the typical span: two canary intervals of four blocks, the anchoring block held
H11 = hist([B(1), B(2, "PASS"), B(3), B(4), B(5), B(6), B(7, "PASS"), B(8), B(9), B(10), B(11), B(12, "FAIL")])
case("scope/eleven-blocks", "hold_scope", {"history": H11, "lookback_passes": 2},
     "[OK,[B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12],PASS,B2,2]",
     note="two intervals of four blocks: the anchoring pass's block is held (D111.1 Option 1), eleven blocks")
case("scope/no-passes", "hold_scope",
     {"history": hist([B(1), B(2), B(3), B(4, "FAIL")]), "lookback_passes": 2},
     "[OK,[B1,B2,B3,B4],ADMISSION,B1,0]", note="no passed canary: back to the first block after admission")
case("scope/one-pass", "hold_scope",
     {"history": hist([B(1), B(2, "PASS"), B(3), B(4), B(5, "FAIL")]), "lookback_passes": 2},
     "[OK,[B1,B2,B3,B4,B5],ADMISSION,B1,1]", note="fewer passes than LOOKBACK PASSES: back to admission")
case("scope/two-passes-adjacent", "hold_scope",
     {"history": hist([B(1), B(2, "PASS"), B(3, "PASS"), B(4, "FAIL")]), "lookback_passes": 2},
     "[OK,[B2,B3,B4],PASS,B2,2]", note="the two passes are adjacent; the earlier one anchors")
case("scope/two-passes-spread", "hold_scope",
     {"history": hist([B(1), B(2, "PASS"), B(3), B(4), B(5, "PASS"), B(6), B(7, "FAIL")]), "lookback_passes": 2},
     "[OK,[B2,B3,B4,B5,B6,B7],PASS,B2,2]")
H3P = hist([B(1, "PASS"), B(2), B(3, "PASS"), B(4), B(5, "PASS"), B(6, "FAIL")])
case("scope/three-passes-lookback-2", "hold_scope", {"history": H3P, "lookback_passes": 2},
     "[OK,[B3,B4,B5,B6],PASS,B3,2]", note="the oldest pass, B1, lies outside the scope and is not held")
case("scope/lookback-1", "hold_scope", {"history": H3P, "lookback_passes": 1},
     "[OK,[B5,B6],PASS,B5,1]", note="the function is parameterized; the declared value is 2")
case("scope/lookback-3", "hold_scope", {"history": H3P, "lookback_passes": 3},
     "[OK,[B1,B2,B3,B4,B5,B6],PASS,B1,3]")
case("scope/lookback-3-fewer", "hold_scope",
     {"history": hist([B(1), B(2, "PASS"), B(3, "PASS"), B(4, "FAIL")]), "lookback_passes": 3},
     "[OK,[B1,B2,B3,B4],ADMISSION,B1,2]")
case("scope/anchor-is-admission-block", "hold_scope",
     {"history": hist([B(1, "PASS"), B(2, "PASS"), B(3, "FAIL")]), "lookback_passes": 2},
     "[OK,[B1,B2,B3],PASS,B1,2]", note="the second pass back is the admission block itself: kind PASS")
case("scope/failing-block-is-admission-block", "hold_scope",
     {"history": hist([B(1, "FAIL")]), "lookback_passes": 2},
     "[OK,[B1],ADMISSION,B1,0]", note="the first block after admission fails: one block held")
case("scope/passes-before-admission-do-not-anchor", "hold_scope",
     {"history": hist([B(0, "PASS"), B(1, "PASS"), B(2), B(3, "PASS"), B(4, "FAIL")], adm="B2"), "lookback_passes": 2},
     "[OK,[B2,B3,B4],ADMISSION,B2,1]",
     note="B0 and B1 belong to a lapsed certificate (a re-admission): outside the scope, their passes not counted")
case("scope/failure-before-admission-ignored", "hold_scope",
     {"history": hist([B(0, "FAIL"), B(1), B(2, "PASS"), B(3, "FAIL")], adm="B1"), "lookback_passes": 2},
     "[OK,[B1,B2,B3],ADMISSION,B1,1]", note="an earlier failure under the lapsed certificate was its own hold")
case("scope/lookback-parameter-large", "hold_scope", {"history": H11, "lookback_passes": 100},
     "[OK,[B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11,B12],ADMISSION,B1,2]")
# refusals: the edge cases of the spec note, section 5
case("scope/refused/last-block-passed", "hold_scope",
     {"history": hist([B(1), B(2, "PASS")]), "lookback_passes": 2},
     "[REFUSED,history: the last block is not the failing block]",
     note="a pass in the failing block is impossible by construction: a block carries one canary outcome")
case("scope/refused/last-block-no-canary", "hold_scope",
     {"history": hist([B(1, "FAIL"), B(2)]), "lookback_passes": 2},
     "[REFUSED,history: the last block is not the failing block]")
case("scope/refused/earlier-failure-in-scope", "hold_scope",
     {"history": hist([B(1), B(2, "FAIL"), B(3), B(4, "FAIL")]), "lookback_passes": 2},
     "[REFUSED,history: block B2 failed a canary inside the scope; an earlier failure is its own hold]")
case("scope/refused/canary-value", "hold_scope",
     {"history": hist([B(1, "MAYBE"), B(2, "FAIL")]), "lookback_passes": 2},
     "[REFUSED,history: block B1: canary is not null, PASS or FAIL]")
case("scope/refused/canary-two-outcomes", "hold_scope",
     {"history": hist([B(1), B(2, ["PASS", "FAIL"])]), "lookback_passes": 2},
     "[REFUSED,history: block B2: canary is not null, PASS or FAIL]",
     note="a block carries at most one canary outcome")
case("scope/refused/empty-history", "hold_scope", {"history": hist([]), "lookback_passes": 2},
     "[REFUSED,history: blocks is not a non-empty list]")
case("scope/refused/duplicate-block", "hold_scope",
     {"history": hist([B(1), B(1, "FAIL")]), "lookback_passes": 2},
     "[REFUSED,history: duplicate block B1]")
case("scope/refused/admission-unknown", "hold_scope",
     {"history": hist([B(1), B(2, "FAIL")], adm="B9"), "lookback_passes": 2},
     "[REFUSED,history: admission block B9 is not in blocks]")
case("scope/refused/lookback-zero", "hold_scope", {"history": H11, "lookback_passes": 0},
     "[REFUSED,LOOKBACK PASSES is not an integer of at least 1]")
case("scope/refused/lookback-bool", "hold_scope", {"history": H11, "lookback_passes": True},
     "[REFUSED,LOOKBACK PASSES is not an integer of at least 1]")
case("scope/refused/lookback-string", "hold_scope", {"history": H11, "lookback_passes": "2"},
     "[REFUSED,LOOKBACK PASSES is not an integer of at least 1]")
case("scope/refused/block-id-not-text", "hold_scope",
     {"history": hist([{"block_id": 7, "canary": "FAIL"}]), "lookback_passes": 2},
     "[REFUSED,history: block_id is not a name]")
case("scope/refused/block-id-hidden-character", "hold_scope",
     {"history": hist([{"block_id": "B1\u202e", "canary": "FAIL"}]), "lookback_passes": 2},
     "[REFUSED,history: block_id is not a name]", note="text safety (zone schemas 6): refused, not echoed raw")
case("scope/refused/history-not-object", "hold_scope", {"history": "x", "lookback_passes": 2},
     "[REFUSED,history is not an object]")
case("scope/refused/account-missing", "hold_scope",
     {"history": {"admission_block": "B1", "blocks": [B(1, "FAIL")]}, "lookback_passes": 2},
     "[REFUSED,history: account is not a name]")

# ============================================================================
# held_closure: the HELD set of one register
# ============================================================================
def R(rid, block, author, cites=(), assumptions=(), kind="RESULT", status="PROVISIONAL", **flags):
    r = {"id": rid, "block_id": block, "author": author, "cites": list(cites),
         "assumptions": list(assumptions), "kind": kind, "status": status}
    r.update(flags)
    return r


HELD_BLOCKS = ["B2", "B3", "B4"]
SEEDS = {"account": "acct", "blocks": HELD_BLOCKS}
REG = [
    R("RR-1", "B1", "acct"),                              # the account's, before the scope
    R("RR-2", "B2", "acct", status="ESTABLISHED"),        # seed
    R("RR-3", "B3", "other"),                             # another account's, in a held block
    R("RR-4", "B4", "acct", cites=["RR-3"]),              # seed
    R("RR-5", "B9", "other", cites=["RR-2"]),             # depends on a seed
    R("RR-6", "B9", "other", cites=["RR-5"]),             # transitively
    R("RR-7", "B9", "other", cites=["RR-1"]),             # depends on unheld work only
]
case("closure/seeds-and-dependents", "held_closure", {"records": REG, "seeds": SEEDS},
     "[OK,[[RR-2,ESTABLISHED],[RR-4,PROVISIONAL],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],[RR-2,RR-4]]",
     note="RR-1 is older work (reviewed, not held); RR-3 is another account's; RR-7 reaches no held record")
case("closure/no-seeds", "held_closure", {"records": REG, "seeds": {"account": "nobody", "blocks": HELD_BLOCKS}},
     "[OK,[],[]]")
case("closure/blocks-empty", "held_closure", {"records": REG, "seeds": {"account": "acct", "blocks": []}},
     "[OK,[],[]]")
A_REG = [
    R("A-1", "B2", "acct", kind="ASSUMPTION"),            # an assumption record the account allocated
    R("RR-8", "B9", "other", assumptions=["A-1", "TFK-A"]),   # ASSUMPTIONS closure reaches it; TFK-A is not a record
    R("RR-9", "B9", "other", assumptions=["TFK-A"]),
]
case("closure/assumptions-propagate", "held_closure", {"records": A_REG, "seeds": SEEDS},
     "[OK,[[A-1,PROVISIONAL],[RR-8,PROVISIONAL]],[A-1]]",
     note="an ASSUMPTIONS citation propagates; an identifier outside the register (the TFK's) is ignored")
CYC = [
    R("RR-1", "B2", "acct", cites=["RR-2"]),
    R("RR-2", "B9", "other", cites=["RR-1"]),
    R("RR-3", "B9", "other", cites=["RR-3"]),             # cites itself, unheld
]
case("closure/cycle-does-not-loop", "held_closure", {"records": CYC, "seeds": SEEDS},
     "[OK,[[RR-1,PROVISIONAL],[RR-2,PROVISIONAL]],[RR-1]]")
CORR = [
    R("RR-1", "B9", "other"),
    R("CO-1", "B3", "acct", cites=["RR-1"], kind="CORROBORATION"),                 # supplied in a held block
    R("CO-2", "B3", "TPX", cites=["RR-1"], kind="CORROBORATION", supplied_by="acct"),   # TPX-written on a ledger MATCH
    R("CO-3", "B1", "acct", cites=["RR-1"], kind="CORROBORATION"),                 # supplied before the scope
    R("CO-4", "B3", "other", cites=["RR-1"], kind="CORROBORATION"),                # another account's
]
case("closure/corroborations-supplied", "held_closure", {"records": CORR, "seeds": SEEDS},
     "[OK,[[CO-1,PROVISIONAL],[CO-2,PROVISIONAL]],[CO-1,CO-2]]",
     note="a corroboration the account supplied is held whether its author field is the account or TPX; RR-1, which it corroborates, is not")
RET = [
    R("RR-1", "B7", "co", vetted_by="acct", vetted_in="B3"),     # carried by a RETURN the account vetted as AI-LEAD, incorporated in B3
    R("RR-2", "B7", "co", vetted_by="acct", vetted_in="B8"),     # vetted outside the scope
    R("RR-3", "B3", "co", vetted_by="acct"),                     # vetted_in absent: the record's own block
    R("RR-4", "B3", "co", vetted_by="lead2"),                    # vetted by another lead
    R("RR-5", "B9", "other", cites=["RR-1"]),
]
case("closure/returns-vetted", "held_closure", {"records": RET, "seeds": SEEDS},
     "[OK,[[RR-1,PROVISIONAL],[RR-3,PROVISIONAL],[RR-5,PROVISIONAL]],[RR-1,RR-3]]")
STAT = [
    R("RR-1", "B2", "acct", status="HELD"),               # already held by another hold: listed with prior HELD
    R("RR-2", "B2", "acct", status="REFUTED"),
    R("RR-3", "B9", "other", cites=["RR-2"], status="ESTABLISHED"),
]
case("closure/prior-status-kept", "held_closure", {"records": STAT, "seeds": SEEDS},
     "[OK,[[RR-1,HELD],[RR-2,REFUTED],[RR-3,ESTABLISHED]],[RR-1,RR-2]]",
     note="the prior status is whatever the record carries; a RELEASE restores it")
ORD = [
    R("RR-10", "B2", "acct"), R("RR-2", "B2", "acct"), R("RR-1", "B9", "other", cites=["RR-10"]),
]
case("closure/sorted-by-code-point", "held_closure", {"records": ORD, "seeds": SEEDS},
     "[OK,[[RR-1,PROVISIONAL],[RR-10,PROVISIONAL],[RR-2,PROVISIONAL]],[RR-10,RR-2]]",
     note="identifiers sort in code point order: RR-1, RR-10, RR-2")
case("closure/refused/duplicate-id", "held_closure",
     {"records": [R("RR-1", "B2", "acct"), R("RR-1", "B3", "acct")], "seeds": SEEDS},
     "[REFUSED,records: duplicate id RR-1]")
case("closure/refused/missing-field", "held_closure",
     {"records": [{"id": "RR-1", "block_id": "B2", "author": "acct", "kind": "RESULT"}], "seeds": SEEDS},
     "[REFUSED,records: RR-1: status is not a name]")
case("closure/refused/cites-not-list", "held_closure",
     {"records": [dict(R("RR-1", "B2", "acct"), cites="RR-2")], "seeds": SEEDS},
     "[REFUSED,records: RR-1: cites is not a list of names]")
case("closure/refused/cites-hidden-character", "held_closure",
     {"records": [R("RR-1", "B2", "acct", cites=["RR-2\u200b"])], "seeds": SEEDS},
     "[REFUSED,records: RR-1: cites is not a list of names]")
case("closure/refused/records-not-list", "held_closure", {"records": "x", "seeds": SEEDS},
     "[REFUSED,records is not a list]")
case("closure/refused/seeds-blocks", "held_closure", {"records": REG, "seeds": {"account": "acct"}},
     "[REFUSED,seeds: blocks is not a list of names]")
case("closure/refused/seeds-account", "held_closure", {"records": REG, "seeds": {"blocks": HELD_BLOCKS}},
     "[REFUSED,seeds: account is not a name]")
case("closure/refused/optional-flag-type", "held_closure",
     {"records": [R("RR-1", "B2", "acct", vetted_by=5)], "seeds": SEEDS},
     "[REFUSED,records: RR-1: vetted_by is not a name]")

# ============================================================================
# tpx_allocate: the reserved range for TPX-written records
# ============================================================================
case("allocate/first", "tpx_allocate", {"range": {"prefix": "RR", "low": 900001, "high": 999999, "next": 900001}},
     "[OK,RR-900001,[RR,900001,999999,900002]]")
case("allocate/last", "tpx_allocate", {"range": {"prefix": "RR", "low": 900001, "high": 900003, "next": 900003}},
     "[OK,RR-900003,[RR,900001,900003,900004]]")
case("allocate/refused/exhausted", "tpx_allocate", {"range": {"prefix": "RR", "low": 900001, "high": 900003, "next": 900004}},
     "[REFUSED,range: the reserved range RR 900001-900003 is exhausted]")
case("allocate/refused/next-below-low", "tpx_allocate", {"range": {"prefix": "RR", "low": 10, "high": 20, "next": 9}},
     "[REFUSED,range: next is not an integer at or above low]")
case("allocate/refused/bounds", "tpx_allocate", {"range": {"prefix": "RR", "low": 20, "high": 10, "next": 20}},
     "[REFUSED,range: low and high are not integers with 1 <= low <= high]")
case("allocate/refused/prefix", "tpx_allocate", {"range": {"prefix": "R R", "low": 1, "high": 9, "next": 1}},
     "[REFUSED,range: prefix is not an identifier]")
case("allocate/refused/next-bool", "tpx_allocate", {"range": {"prefix": "RR", "low": 1, "high": 9, "next": True}},
     "[REFUSED,range: next is not an integer at or above low]")

# ============================================================================
# hold_record: the HOLD record and its digest
# ============================================================================
CAUSE = {"canary_id": "C-77", "account": "acct", "snapshot": "model-2026-01-01", "failing_block": "B4",
         "anchor_kind": "PASS", "anchor_block": "B2", "lookback_passes": 2, "held_blocks": HELD_BLOCKS}
HELD = [["RR-2", "ESTABLISHED"], ["RR-4", "PROVISIONAL"], ["RR-5", "PROVISIONAL"], ["RR-6", "PROVISIONAL"]]
SEED_IDS = ["RR-2", "RR-4"]
PRE_HOLD = ("8:TPC-HOLD1:24:C-774:acct16:model-2026-01-012:B44:PASS2:B21:21:32:B22:B32:B41:24:RR-24:RR-41:4"
            "4:RR-211:ESTABLISHED4:RR-411:PROVISIONAL4:RR-511:PROVISIONAL4:RR-611:PROVISIONAL1:0")
D_HOLD = "e0ae4de0810e8ce5c94a3fe8286c4d7782b3bd358fe0d28797e32b4fd32ae82b"   # sha256sum of PRE_HOLD (form 2)
case("hold/preimage", "hold_preimage", {"cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": []}, "[OK," + PRE_HOLD + "]",
     note="netstring of [tag, form, canary, account, snapshot, failing block, anchor kind, anchor block, "
          "lookback, n blocks, blocks..., n seeds, seeds..., n held, (id, status)..., n biblio, (bib_id, check)...]; "
          "hold_id is the address, outside it; form 2 (0.2.0) with an empty bibliography list")
case("hold/record", "hold_record", {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": []},
     "[OK,[RR-900001,HOLD,C-77,acct,model-2026-01-01,B4,PASS,B2,2,[B2,B3,B4],[RR-2,RR-4],"
     "[[RR-2,ESTABLISHED],[RR-4,PROVISIONAL],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],[]," + D_HOLD + "]]")
case("hold/record-unsorted-input-sorted-output", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": ["RR-4", "RR-2"], "held": list(reversed(HELD)), "biblio": []},
     "[OK,[RR-900001,HOLD,C-77,acct,model-2026-01-01,B4,PASS,B2,2,[B2,B3,B4],[RR-2,RR-4],"
     "[[RR-2,ESTABLISHED],[RR-4,PROVISIONAL],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],[]," + D_HOLD + "]]",
     note="the same HOLD, so the same digest, whatever order the lists arrive in")
CAUSE_ADM = dict(CAUSE, anchor_kind="ADMISSION", anchor_block="B1", held_blocks=["B1", "B2", "B3", "B4"], lookback_passes=2)
PRE_ADM = ("8:TPC-HOLD1:24:C-774:acct16:model-2026-01-012:B49:ADMISSION2:B11:21:42:B12:B22:B32:B41:14:RR-21:1"
           "4:RR-211:ESTABLISHED1:0")
D_ADM = "41d4d393186fa61a0b78a0ee77af2e7843f6615d4f352cefec2362fcbcfd4316"   # sha256sum of PRE_ADM (form 2)
case("hold/preimage-admission-anchor", "hold_preimage",
     {"cause": CAUSE_ADM, "seeds": ["RR-2"], "held": [["RR-2", "ESTABLISHED"]], "biblio": []}, "[OK," + PRE_ADM + "]")
case("hold/record-admission-anchor", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE_ADM, "seeds": ["RR-2"], "held": [["RR-2", "ESTABLISHED"]], "biblio": []},
     "[OK,[RR-900001,HOLD,C-77,acct,model-2026-01-01,B4,ADMISSION,B1,2,[B1,B2,B3,B4],[RR-2],[[RR-2,ESTABLISHED]],[]," + D_ADM + "]]")
# 0.2.0: the bibliography list (D171 (j)); the list comes from tpc_biblio.biblio_hold_list
BIB = [["RR-BIB2", "NOT FOUND"], ["RR-BIB5", "FIELDS DIFFER"], ["RR-BIB10", "LOOKUP FAILED"]]
PRE_BIB = ("8:TPC-HOLD1:24:C-774:acct16:model-2026-01-012:B44:PASS2:B21:21:32:B22:B32:B41:24:RR-24:RR-41:4"
           "4:RR-211:ESTABLISHED4:RR-411:PROVISIONAL4:RR-511:PROVISIONAL4:RR-611:PROVISIONAL1:3"
           "8:RR-BIB1013:LOOKUP FAILED7:RR-BIB29:NOT FOUND7:RR-BIB513:FIELDS DIFFER")
D_BIB = "37d6e097c9334d5c1d4738673e9c2b5b6fe92274e28e0cd084083daaad2e9d7e"   # sha256sum of PRE_BIB
case("hold/preimage-bibliography", "hold_preimage", {"cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": BIB},
     "[OK," + PRE_BIB + "]",
     note="the bibliography list after the held pairs: count, then (bib_id, check) pairs sorted by bib_id in code point order "
          "(RR-BIB10 before RR-BIB2); entries are not HELD (D171 (j))")
case("hold/record-bibliography", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": BIB},
     "[OK,[RR-900001,HOLD,C-77,acct,model-2026-01-01,B4,PASS,B2,2,[B2,B3,B4],[RR-2,RR-4],"
     "[[RR-2,ESTABLISHED],[RR-4,PROVISIONAL],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],"
     "[[RR-BIB10,LOOKUP FAILED],[RR-BIB2,NOT FOUND],[RR-BIB5,FIELDS DIFFER]]," + D_BIB + "]]")
case("hold/record-bibliography-unsorted-input", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": list(reversed(BIB))},
     "[OK,[RR-900001,HOLD,C-77,acct,model-2026-01-01,B4,PASS,B2,2,[B2,B3,B4],[RR-2,RR-4],"
     "[[RR-2,ESTABLISHED],[RR-4,PROVISIONAL],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],"
     "[[RR-BIB10,LOOKUP FAILED],[RR-BIB2,NOT FOUND],[RR-BIB5,FIELDS DIFFER]]," + D_BIB + "]]",
     note="the same HOLD, so the same digest, whatever order the list arrives in")
case("hold/refused/biblio-confirmed", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": BIB + [["RR-BIB1", "CONFIRMED"]]},
     "[REFUSED,biblio: entry RR-BIB1 is CONFIRMED; the list holds what is not]",
     note="D171 (j): the HOLD lists the entries whose re-run CHECK is not CONFIRMED")
case("hold/refused/biblio-duplicate", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": BIB + [["RR-BIB2", "LOOKUP FAILED"]]},
     "[REFUSED,biblio: duplicate entry RR-BIB2]")
case("hold/refused/biblio-shape", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": [["RR-BIB2"]]},
     "[REFUSED,biblio: entry is not [bib_id, check]]")
case("hold/refused/biblio-not-list", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": "RR-BIB2"},
     "[REFUSED,biblio is not a list]")
case("hold/refused/biblio-hidden-character", "hold_preimage",
     {"cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": [["RR-BIB2\u200b", "NOT FOUND"]]},
     "[REFUSED,biblio: entry is not [bib_id, check]]")
case("hold/refused/empty", "hold_record", {"hold_id": "RR-900001", "cause": CAUSE, "seeds": [], "held": [], "biblio": []},
     "[REFUSED,nothing to hold: the held list is empty]",
     note="a HOLD is never written empty; a failing block that landed nothing holds nothing")
case("hold/refused/failing-block-mismatch", "hold_record",
     {"hold_id": "RR-900001", "cause": dict(CAUSE, failing_block="B9"), "seeds": SEED_IDS, "held": HELD, "biblio": []},
     "[REFUSED,cause: failing_block is not the last held block]")
case("hold/refused/anchor-mismatch", "hold_record",
     {"hold_id": "RR-900001", "cause": dict(CAUSE, anchor_block="B3"), "seeds": SEED_IDS, "held": HELD, "biblio": []},
     "[REFUSED,cause: anchor_block is not the first held block]")
case("hold/refused/anchor-kind", "hold_record",
     {"hold_id": "RR-900001", "cause": dict(CAUSE, anchor_kind="PARROT"), "seeds": SEED_IDS, "held": HELD, "biblio": []},
     "[REFUSED,cause: anchor_kind is not PASS or ADMISSION]", note="a passed parrot is not an anchor (handoff 4.5)")
case("hold/refused/seed-not-held", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": ["RR-2", "RR-9"], "held": HELD, "biblio": []},
     "[REFUSED,seed RR-9 is not in the held list]")
case("hold/refused/held-shape", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": [["RR-2"]], "biblio": []},
     "[REFUSED,held: entry is not [id, prior_status]]")
case("hold/refused/held-duplicate", "hold_record",
     {"hold_id": "RR-900001", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD + [["RR-2", "PROVISIONAL"]], "biblio": []},
     "[REFUSED,held: duplicate id RR-2]")
case("hold/refused/cause-missing", "hold_record",
     {"hold_id": "RR-900001", "cause": {"account": "acct"}, "seeds": SEED_IDS, "held": HELD, "biblio": []},
     "[REFUSED,cause: canary_id is not a name]")
case("hold/refused/lookback", "hold_record",
     {"hold_id": "RR-900001", "cause": dict(CAUSE, lookback_passes=0), "seeds": SEED_IDS, "held": HELD, "biblio": []},
     "[REFUSED,cause: lookback_passes is not an integer of at least 1]")
case("hold/refused/hold-id", "hold_record", {"hold_id": "", "cause": CAUSE, "seeds": SEED_IDS, "held": HELD, "biblio": []},
     "[REFUSED,hold_id is not a name]")

# ============================================================================
# release_record: the RELEASE record
# ============================================================================
HOLD = dict(CAUSE, hold_id="RR-900001", seeds=SEED_IDS, held=HELD, biblio=[], digest=D_HOLD)
HOLD_BIB = dict(CAUSE, hold_id="RR-900001", seeds=SEED_IDS, held=HELD, biblio=BIB, digest=D_BIB)
REG_REL = [
    R("RR-1", "B1", "acct"),
    R("RR-2", "B2", "acct", status="HELD"),
    R("RR-3", "B3", "other"),
    R("RR-4", "B4", "acct", cites=["RR-3"], status="HELD"),
    R("RR-5", "B9", "other", cites=["RR-2"], status="HELD"),
    R("RR-6", "B9", "other", cites=["RR-5"], status="HELD"),
    R("RR-7", "B9", "other", cites=["RR-1"]),
]
IND = {"account": "other", "snapshot": "model-2026-02-02", "origin": "REPRODUCTION BLOCK"}


def rep(matched, kind="REPRODUCTION", rid="B12", **ind):
    i = dict(IND)
    i.update(ind)
    return {"kind": kind, "id": rid, "independence": i, "matched": matched}


PRE_REL_2 = ("11:TPC-RELEASE1:29:RR-90000164:" + D_HOLD + "12:REPRODUCTION3:B125:other16:model-2026-02-021:3"
             "4:RR-211:ESTABLISHED4:RR-511:PROVISIONAL4:RR-611:PROVISIONAL1:14:RR-41:0")
D_REL_2 = "e2bf9d00ad4e81c3f04f574cafaa6c22866328ff70137eabc43c013454fd13d0"   # sha256sum of PRE_REL_2 (form 2)
case("release/seed-and-dependents", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2"]), "records": REG_REL},
     "[OK,[RR-900002,RELEASE,RR-900001," + D_HOLD + ",REPRODUCTION,B12,other,model-2026-02-02,"
     "[[RR-2,ESTABLISHED],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],[RR-4],[]," + D_REL_2 + "]]",
     note="RR-2 reproduced: RR-5 and RR-6, held only through it, are released with it; RR-4 stays held. "
          "Preimage: " + PRE_REL_2)
PRE_REL_ALL = ("11:TPC-RELEASE1:29:RR-90000164:" + D_HOLD + "12:LEDGER_MATCH5:LE-405:other16:model-2026-02-021:4"
               "4:RR-211:ESTABLISHED4:RR-411:PROVISIONAL4:RR-511:PROVISIONAL4:RR-611:PROVISIONAL1:01:0")
D_REL_ALL = "00c2a3056442721e10adbb22c9fbd05581822c491d5fddee75256b85892fc0fc"   # sha256sum of PRE_REL_ALL (form 2)
case("release/ledger-match-all", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2", "RR-4"], kind="LEDGER_MATCH", rid="LE-40"),
      "records": REG_REL},
     "[OK,[RR-900002,RELEASE,RR-900001," + D_HOLD + ",LEDGER_MATCH,LE-40,other,model-2026-02-02,"
     "[[RR-2,ESTABLISHED],[RR-4,PROVISIONAL],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],[],[]," + D_REL_ALL + "]]",
     note="a community-ledger MATCH counts on the same independence check (handoff 5.3, 13.3). Preimage: " + PRE_REL_ALL)
# 0.2.0: a RELEASE carries the HOLD's bibliography list unchanged, before its digest
PRE_REL_BIB = ("11:TPC-RELEASE1:29:RR-90000164:" + D_BIB + "12:REPRODUCTION3:B125:other16:model-2026-02-021:3"
               "4:RR-211:ESTABLISHED4:RR-511:PROVISIONAL4:RR-611:PROVISIONAL1:14:RR-41:3"
               "8:RR-BIB1013:LOOKUP FAILED7:RR-BIB29:NOT FOUND7:RR-BIB513:FIELDS DIFFER")
D_REL_BIB = "5ee5a938bb21ff1902f8d50532a7dbb79d302ce2b8bd3775a64fa5f088b8f18d"   # sha256sum of PRE_REL_BIB
case("release/bibliography-carried", "release_record",
     {"release_id": "RR-900002", "hold": HOLD_BIB, "reproduction": rep(["RR-2"]), "records": REG_REL},
     "[OK,[RR-900002,RELEASE,RR-900001," + D_BIB + ",REPRODUCTION,B12,other,model-2026-02-02,"
     "[[RR-2,ESTABLISHED],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],[RR-4],"
     "[[RR-BIB10,LOOKUP FAILED],[RR-BIB2,NOT FOUND],[RR-BIB5,FIELDS DIFFER]]," + D_REL_BIB + "]]",
     note="the HOLD's list is carried unchanged: entries are not held and none is released. Preimage: " + PRE_REL_BIB)
case("release/bibliography-unsorted-in-hold", "release_record",
     {"release_id": "RR-900002", "hold": dict(HOLD_BIB, biblio=list(reversed(BIB))), "reproduction": rep(["RR-2"]), "records": REG_REL},
     "[OK,[RR-900002,RELEASE,RR-900001," + D_BIB + ",REPRODUCTION,B12,other,model-2026-02-02,"
     "[[RR-2,ESTABLISHED],[RR-5,PROVISIONAL],[RR-6,PROVISIONAL]],[RR-4],"
     "[[RR-BIB10,LOOKUP FAILED],[RR-BIB2,NOT FOUND],[RR-BIB5,FIELDS DIFFER]]," + D_REL_BIB + "]]")
case("release/refused/hold-missing-biblio", "release_record",
     {"release_id": "RR-900002", "hold": {k: v for k, v in HOLD.items() if k != "biblio"}, "reproduction": rep(["RR-2"]),
      "records": REG_REL},
     "[REFUSED,hold: missing field biblio]", note="a form-1 HOLD object is not read at 0.2.0 (no UWC exists; fixtures only)")
case("release/refused/hold-biblio-confirmed", "release_record",
     {"release_id": "RR-900002", "hold": dict(HOLD_BIB, biblio=BIB + [["RR-BIB1", "CONFIRMED"]]), "reproduction": rep(["RR-2"]),
      "records": REG_REL},
     "[REFUSED,hold: biblio: entry RR-BIB1 is CONFIRMED; the list holds what is not]")
case("release/refused/hold-biblio-digest-moved", "release_record",
     {"release_id": "RR-900002", "hold": dict(HOLD_BIB, biblio=BIB[:2]), "reproduction": rep(["RR-2"]), "records": REG_REL},
     "[REFUSED,hold: digest does not match its fields]", note="the list is inside the HOLD's digest")
case("release/dependent-matched-stays-held", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-5"]), "records": REG_REL},
     "[REFUSED,no held record is released by this reproduction]",
     note="RR-5 reproduced but its derivation cites RR-2, still held: nothing is released")
case("release/refused/same-account", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2"], account="acct"), "records": REG_REL},
     "[REFUSED,reproduction by the held account is not independent]")
case("release/refused/same-model-flag", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2"], same_model=True), "records": REG_REL},
     "[REFUSED,reproduction is SAME-MODEL]")
case("release/refused/same-snapshot", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2"], snapshot="model-2026-01-01"), "records": REG_REL},
     "[REFUSED,reproduction is SAME-MODEL]", note="the reproducing snapshot equals the original's (D42)")
case("release/refused/same-block-origin", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2"], origin="SAME BLOCK"), "records": REG_REL},
     "[REFUSED,reproduction origin is not REPRODUCTION BLOCK]")
case("release/refused/matched-not-held", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2", "RR-7"]), "records": REG_REL},
     "[REFUSED,matched record RR-7 is not in the hold]")
case("release/refused/kind", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2"], kind="PARROT"), "records": REG_REL},
     "[REFUSED,reproduction: kind is not REPRODUCTION or LEDGER_MATCH]")
case("release/refused/hold-digest", "release_record",
     {"release_id": "RR-900002", "hold": dict(HOLD, digest="0" * 64), "reproduction": rep(["RR-2"]), "records": REG_REL},
     "[REFUSED,hold: digest does not match its fields]", note="a HOLD whose fields moved since its digest is refused")
case("release/refused/hold-field-missing", "release_record",
     {"release_id": "RR-900002", "hold": {k: v for k, v in HOLD.items() if k != "seeds"}, "reproduction": rep(["RR-2"]),
      "records": REG_REL},
     "[REFUSED,hold: missing field seeds]")
case("release/refused/held-record-missing", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2"]), "records": REG_REL[:4]},
     "[REFUSED,held record RR-5 is not in records]")
case("release/refused/independence-missing", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": {"kind": "REPRODUCTION", "id": "B12", "matched": ["RR-2"]},
      "records": REG_REL},
     "[REFUSED,reproduction: independence is not an object]")
case("release/refused/same-model-not-bool", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2"], same_model="no"), "records": REG_REL},
     "[REFUSED,reproduction: independence same_model is not a boolean]")
case("release/refused/matched-duplicate", "release_record",
     {"release_id": "RR-900002", "hold": HOLD, "reproduction": rep(["RR-2", "RR-2"]), "records": REG_REL},
     "[REFUSED,reproduction: matched is not a list of distinct names]")


def dispatch(fn, i):
    if fn == "hold_scope":
        return H.hold_scope(i["history"], i["lookback_passes"])
    if fn == "held_closure":
        return H.held_closure(i["records"], i["seeds"])
    if fn == "tpx_allocate":
        return H.tpx_allocate(i["range"])
    if fn == "hold_preimage":
        return H.hold_preimage(i["cause"], i["seeds"], i["held"], i["biblio"])
    if fn == "hold_record":
        return H.hold_record(i["hold_id"], i["cause"], i["seeds"], i["held"], i["biblio"])
    if fn == "release_record":
        return H.release_record(i["release_id"], i["hold"], i["reproduction"], i["records"])
    raise KeyError(fn)


if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] == "--preimages":
        for name, pre in (("PRE_HOLD", PRE_HOLD), ("PRE_ADM", PRE_ADM), ("PRE_BIB", PRE_BIB), ("PRE_REL_2", PRE_REL_2),
                          ("PRE_REL_ALL", PRE_REL_ALL), ("PRE_REL_BIB", PRE_REL_BIB)):
            print(name, pre)
        sys.exit(0)
    bad = 0
    for c in cases:
        got = S.canon(dispatch(c["fn"], c["input"]))
        if got != c["expect"]:
            bad += 1
            print("MISMATCH", c["id"], "\n  expect", c["expect"], "\n  got   ", got)
    if bad:
        sys.exit("refusing to write: %d mismatches" % bad)
    corpus = {
        "meta": {
            "name": "tpc_hold_corpus", "version": "0.2.0",
            "status": "RE-ISSUED 2026-09-26 at HOLD_FORM 2 (D171 (j), taken by delegation; D111.1; charter CO-21); "
                      "awaiting the supervisor's verification",
            "conforms_tps": "0.1.0 revision 4; the hold of D111.1 (2026-09-23), text owed at revision 5 (3.3, 4.4, 5.14, 5.17); "
                            "the bibliography list of D171 (j), text owed",
            "module": "tpc_hold 0.2.0 (tpc_digest 0.1.0, tpc_zone 0.4.0)",
            "note": ("Expectations hand-derived from tpm_hold_scope 0.1.0: scopes counted on paper, closures traced by "
                     "hand, refusals from the edge-case table. Every digest is an external sha256sum over the preimage "
                     "its case shows. Deterministic; no randomness. Both residences MUST reproduce every expect.")
        },
        "cases": cases,
    }
    open(os.path.join(HERE, "vectors", "hold_corpus.json"), "w", encoding="utf-8").write(
        json.dumps(corpus, indent=1, ensure_ascii=True) + "\n")
    print("wrote", len(cases), "hold cases; all match literal expectations")