#!/usr/bin/env python3 """tools/restruct.py — the struct/declaration rewrite engine (Phase 37 T3, 2026-09-12; the T2 probe form kept inside it). tools/restruct.py --plan --rung S|D|L [--batch N] [--headers] [--only X …] # what the next batch would touch (no writes) tools/restruct.py --apply --rung S|D|L --batch N --label [--headers] [--only X …] [-j N] # judge every unit of the batch's files, KEEP the winning # texts in place (the outer gate — R22 — follows), ledger every site (rung D with `--redraw KEY`: lifted decl units with no lying declaration left get a superseding DECL-NONE row; --plan reports them, P3.39 T1) tools/restruct.py --apply --rung D --callee F --signature "void F(s32 a)" --label # a definition-side signature change: the definition's # TU + every TU declaring F, one judged unit (the 24 parked patches) tools/restruct.py --restore # every in-flight file back from inflight.json (never git checkout, R102) tools/restruct.py --status # the ledger's totals per rung tools/restruct.py --status --rung L --only … # the HEAD-FOLD rows (latest per unit): verdict -> cause -> units (rung L with `--only …` = HEAD-FOLD mode, P38 T4: same-size other-layout definitions -> `typedef ;` + renames) tools/restruct.py --check-ledger # every MEMBER site still a leaf of its (current) canonical type tools/restruct.py --rung S --residue --label [--only X …] [--forms P,X] # T3.c7: a no-edit RESIDUAL() row per body with uncovered # sites (ledger only); T10.c1: a body with a latest S row gets a # MERGED copy of it + one RESIDUAL entry per uncovered site tools/restruct.py --check-residue [--only X …] [--forms P,X] # census sites (default ov_*, forms P,X; I,M accepted) not covered # per site (form, normalised base, off; multiset) by a RESIDUAL # entry of the body's latest S row; exit 1 if any residue causes: FILE-SCOPE, NO-TYPE-IN-MAP, TYPE-NOT-CANONICAL, TYPE-NOT-VISIBLE, else site_class's (MISALIGNED, NO-EDIT, …); I/M forms add ABS-ADDR (bclass abs: a fixed address), GADDR (bclass gaddr: `&D_x` reinterpreted) and GLOBAL (bclass global: a global's storage reinterpreted) tools/restruct.py --plan|--apply --rung S --forms I,M [--only X …] --batch N --label # T5.c2: ONLY the bodies with uncovered # I/M sites on a global base (gaddr/global); the R ladder # on them (no struct spelling); the body's latest S row merged I/M ladder causes (RESIDUAL(), the most specific refusal): R1/R2/R3-NOT-GLOBAL, R3-NOT-CARVED, R-STILL-RAW (the cast respelled, not removed), R2-HEADER-EXTERN (no extern in the TU), R2/R3-NO-SCALAR-EXTERN, R3-NO-BODY, R2-MISALIGNED, R2-WIDTH (the site's width != the extern's), R3-NOT-CONTIGUOUS, R-NO-EDIT, R-REKEYS (another raw/macro site's key would move), R- (judged: DIFFERS, COMPILE-ERROR …) tools/restruct.py --audit-types # the naming invariant over the canonical type files (struct_layout.audit_definition) tools/restruct.py --write-types --top N | --type NAME … [--space ov] # the WRITER: canonical definitions rendered from the struct map (a preview) tools/restruct.py --selftest [--real] # the fixture (a stub oracle); --real adds the calibration + known-true controls tools/restruct.py --try TU FN [--base bclass:name] [--recipes] # T2's rung 1 on one body (local P37S_ type) + S2 + S+A [+ the R recipes] tools/restruct.py --probe | --probe-decls | --probe-defs | --audit-layouts | --fanout-cost # the T2 probes (unchanged) THE RUNGS (deterministic first; every verdict on the bytes through tools/delever_oracle.py — whole-object equality against the fleet run's snapshot, then the LINKED mode when only the relocation spelling moved — R110): S struct spelling on EVERY typed base of a body: `*(u16 *)(a0 + 0x3C)` -> `((Unkstruct_X *)a0)->unk3C` (or `a0->unk3C` when a0 is already declared `Unkstruct_X *`; `D_x.unk3C` when the global is declared with the type). The type comes from the struct map and must be a CANONICAL definition visible to the TU (`--apply`); `--try` builds T2's body-local `P37S_` type from the map's layout. A site the type cannot hold is SKIPPED and counted (no-field / width / sign / index / negative / pointee / overlap) — T5's authoring residue. S2 the member spelling DIFFERS -> the minimal set of sites that must stay casts (leave-one-out, then cumulative revert in source order, then minimise — delever's rung-B shape, <= 2n+1 compiles); the kept casts are ledgered KEPT with their residual and a pass HINT (X). S+A a lever-bearing body: the struct-spelled text run through delever's ladder (rung A strip-all, rung B greedy) — the struct hypothesis; survivors keep/receive their `// !FAKE:` marker attributed `(P37 S+A