mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-10-01 15:43:06 -04:00
chore(phase-36): CLOSE — levers off to the measured floor: 53,234 → 4,010 register pins + asm statements (−92.5 %), every survivor marked with its pass and its instrument and named for the structs phase; the GTE idiom in one header; 16,759 lying call declarations repaired; the lever and readability series published; 218/218 at every step (v2.2.0)
This commit is contained in:
@@ -58,3 +58,10 @@ rule R98 DK-81 a third-party hand-off file is proven through that party's own to
|
||||
rule R99 DK-81 the public tree's contents decided before the flip; a retired document gets its Archive-index row and is deleted in the same commit — DK-81 fact (2) IS this rule
|
||||
accelerator P36 S99 DK-61 the search harness whose target was a disassembly — a known-true case (a body the tree already matches) read before any verdict; DK-61
|
||||
accelerator P36 S105 DK-69 a generator's refusals are an unaudited population — the tests that pass by construction; a negative-control corpus per generator; DK-69
|
||||
rule R100 DK-64 one source per shared function, a duplicate a defect the health chain asserts — the dedup shape of DK-64 (readability at bank time) and the S1 gate; RECORD carries the P35 PhaseEnd
|
||||
rule R101 DK-59 every task-advancing commit carries its log line and the checkpoint headline — DK-59 (the checkpoint is written to be replayed): a checkpoint older than HEAD is a dead session's
|
||||
rule R102 DK-66 a tool restores from its own snapshot, never git checkout on a tree it did not commit — DK-66 (the restore path is part of the instrument)
|
||||
rule R103 DK-69 a failure-cause extractor is negative-controlled against the compiler's real message forms — DK-69 (the tests that pass by construction)
|
||||
rule R104 DK-9 build the disagreeing oracle before the batch runs and measure the disagreement first — DK-9 (the differential-oracle harness) with DK-61's known-true case
|
||||
rule R105 DK-70 a registry lists a member only after the gate spoke for it; a listed member whose site does not share is a named defect — DK-70 (the health suite asserts the work was done)
|
||||
rule R106 DK-71 a policy taken on a remembered precedent is a belief — read the target project's tree — DK-71 (what earns belief)
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 52 and column 78.
|
@@ -46,7 +46,15 @@ Three sessions (S94–S96) / 48 commits: every shared body one plain-C header un
|
||||
8.8 MB macro header gone), the five twins from one source directory, the same-address backlog 1,099 classes / 4,755 copies → 51 ledgered
|
||||
/ 160, a new `h_text` registry tier for 38 byte-variant functions, S1 a tools-health gate with a second oracle, 14 macro-era tools frozen +
|
||||
4 retired behind a guard, the published counts corrected (+459 functions; REAL 360,744 → 350,533 with EMPTY up the same). R96–R99 ratified;
|
||||
candidates (a)–(g) proposed. **Gen3 continues at Phase 36 — pins off** (Drew's order dedup → pins → structs → names). The open paragraph:
|
||||
candidates (a)–(g) proposed. **Phase 36 CLOSED 2026-09-11 (v2.2.0; `PhaseEnd_Phase36.md`) — Gen3's second phase, LEVERS OFF to the measured floor:** nine sessions
|
||||
(S97–S105) / 575 commits; the census found **53,234** compiler-forcing sites (37,720 register pins + 15,514 asm statements) in 15,679
|
||||
bodies; a byte oracle on the build's own recipes, a mechanical strip (−37 %), one GTE header for 9,102 per-TU macro definitions, recipes, a
|
||||
permuter rung, an object-scored guided search and ~200 agent readings of gcc 2.7.2's source (one per class, then one per TU; 56 of 56 in
|
||||
the last session) took them to **4,010** (−92.5 %), every survivor marked with its pass and its instrument, 218/218 at every step; the
|
||||
milestone AMENDED at S104 by Drew (the unclosed sites named for the structs phase: signatures with patches, struct types, a carve, one GTE
|
||||
spelling, 1,548 singleton sites); 16,759 lying call declarations repaired; the lever and readability series published; the doctrine "ban
|
||||
the silence, not the lever". R100–R106 ratified; candidates (a)–(k) proposed. **Gen3 continues at Phase 37 — the structs phase.** The
|
||||
Phase-35 open paragraph:
|
||||
*Phase 35 OPEN (2026-09-08, S94; gate 1 in plan mode at Max)*
|
||||
Drew set the Gen3 order dedup → pins → structs → names (one phase each, planned one at a time). The phase converts the 3,516 distinct
|
||||
`DEFINE_func_` macro bodies (5,147 define lines) into per-function plain-C headers under `src/shared/<space>/` included at each member's
|
||||
@@ -208,6 +216,19 @@ defects fixed at their cause; T5b the `h_text` tier (38 classes / 2,030 sites);
|
||||
in tools-health, the digest corrected; T8 the record (wiki, cookbook §453, decision log). Close: R22 218/218; S1 10,180/10,180, 0
|
||||
violations; fleet clean-run 157 s → 84–90 s. Rules: R96–R99 ratified; candidates (a)–(g).
|
||||
|
||||
**P36 (2026-09-11, v2.2.0) LEVERS OFF — every compiler-forcing construct out of the matched C, to its measured floor.** 9 sessions
|
||||
(S97–S105) / 575 commits. T1 the self-asserting lever census: 53,234 sites (37,720 pins + 15,514 asm) in 15,679 bodies, 2,227 distinct; T1b
|
||||
44 whole-body assembly routines inside C shells (22 per-overlay stack-switch trampolines + 8 Sony renderers PERMANENT/SDK, 11 DECOMPILE-NOW,
|
||||
3 UNCERTAIN) — the manifest 5 → 49 rows; T2 the oracle (4,284 recipes by `make -n -W`, in-place compiles, whole-object equality, 177/177
|
||||
calibration) + a 283-body probe; T3 `delever.py` + the cycle; T4 the mechanical strip in 15 batches → 33,625 (−36.8 %); T5 `include/
|
||||
gte_inline.h` (50 macros for 9,102 definitions; 629/699 `"memory"` variants byte-neutral); T6 rung R (134/134 on a known shape, 0/300 on
|
||||
unknown) and rung D (5/16; two prior campaigns had scored a disassembly, §454); S101 rung G, the object-scored guided search (33,427 →
|
||||
30,358, no tokens; lane B's residual→move map); T7 the agent lane — S102 (→ 24,119; the call-signature turn: 16,759 lying declarations
|
||||
repaired; the baseline snapshot; the burst of 20), S103 (→ 5,097; 56 draws; `delever_regen`; the minimum-lever pivot), S104 (→ 4,152; ~105
|
||||
draws in TU batches; Drew's four rulings read against sotn-decomp; the milestone amended), S105 (→ 4,010; 56/56 closes; generators
|
||||
R44–R46; R22 found blind three ways; caps 2 → 1 → none); T8 the census rung in tools-health + attribution 4,026/4,026; T9 the record
|
||||
(cookbook §454–§457, METHOD steps 1–25, 30,138 stale `@stuck:` notes retagged). Rules: R100–R106 ratified; candidates (a)–(k).
|
||||
|
||||
## 3. Every rule, in full (transcribe these at session start; P/G/H/X are in PROJECT_CONTEXT.md)
|
||||
- **R1 — H1 relaxed while private.** ROM-derived content (`asm/`, `assets/`, `extracted/`, decompressed `.CD`) MAY be
|
||||
committed while the repo is private; accidental inclusion is not a violation. The raw multi-GB disc dump stays ignored
|
||||
@@ -401,6 +422,26 @@ never from its last line; a step that hands a file to a third party is proven th
|
||||
before the owner's browser session, and the proving tool writes the paste; what a public tree carries is decided before the flip, and a
|
||||
retired document gets its Archive-index row and is deleted in the same commit).
|
||||
|
||||
**R100–R106 — RATIFIED at Phase 36 gate 1 (Drew, 2026-09-09; the PhaseEnd_Phase35 candidates (a)–(g), operated through P35):**
|
||||
- **R100 — A shared body has exactly one source; a duplicate copy is a defect the health chain asserts, and its count is published with
|
||||
its rule.** The P35 invariant (S1), a `tools-health` gate; 1,099 classes / 4,755 copies → 51 / 160, every remainder ledgered.
|
||||
- **R101 — Every commit that advances a task — an intra-task bank included — carries its log line and the 🛑 headline; a checkpoint older
|
||||
than HEAD is a dead session's checkpoint.** S94 died at 91 % with two bank commits carrying no log line.
|
||||
- **R102 — A tool that restores files restores from its own snapshot, never `git checkout` on a tree it did not commit.** `share_body`'s
|
||||
first bisect wiped ~50 uncommitted sites and returned green.
|
||||
- **R103 — A failure-cause extractor is negative-controlled against the compiler's real message forms, not against the word "error".**
|
||||
gcc 2.7.2 prints errors without it and exits 33; 254 of 303 rejection lines read "Error 33".
|
||||
- **R104 — Build the disagreeing oracle before the batch runs, and measure its disagreement before believing either side** (R34 operated).
|
||||
- **R105 — A registry lists a member only after the gate has spoken for it; a listed member whose site does not share is a defect the
|
||||
check names.** 788 members were extended wholesale; 317 were private after the run.
|
||||
- **R106 — A policy taken on a remembered precedent is a belief — read the target project's tree.** The 2026-09-02 dedup deferral
|
||||
rested on one parenthetical; sotn's tree said the opposite.
|
||||
**Phase 36 proposed candidates (a)–(k) for Phase 37 gate 1** (the table in `PhaseEnd_Phase36.md` §Rules: ban the silence, not the
|
||||
lever; a generator ships with a negative-control corpus and reports its refusal reasons; run every registered family on the agent's start
|
||||
text at every landing; a scorer's target is the tree's own bytes, never a disassembly; scratch keyed by the unit of work; a gate's baseline
|
||||
is a snapshot; a lever's marker names its pass and its instrument; a ledger's "done" is per body; an unattended run is detached; a marked
|
||||
ordinary-C fake is counted apart and an invented construct is never banked; a "stalling?" question is answered with the residue bucketed).
|
||||
|
||||
**R96–R99 — RATIFIED at Phase 35 gate 1 (Drew, 2026-09-08; the PhaseEnd_Phase34 candidates (a)–(d), operated through P34):**
|
||||
- **R96 — A scratch prune is an instrument change:** every tool that writes under a pruned tree is re-run before the prune is called
|
||||
done. `cdecl --audit` wrote its probe under the pruned `.run/audit/`; the refusal read as four parser defects (P34 run 1 of the close chain).
|
||||
@@ -426,6 +467,9 @@ the OpenRouter-era `automation-runbook.md` is archived) · `docs/effort-map.md`
|
||||
`docs/disc-ledger.md` · `docs/backlog.md` (near-miss ledger) · `docs/gen3-handoff.md` + `docs/gen3-standards.md` (Gen3) ·
|
||||
`docs/tool-index.md` (every tool keyed by
|
||||
the need it answers; generated) · **Phase 35:** `docs/wiki/The-dedup-engine.md` (the shared-source model), `tools/share_census.py` (the S1
|
||||
census and gate), `tools/share_body.py` (the share tool), `config/dedup_exceptions.tsv` (the ledger), cookbook §453 · **`decomp-architect/`** (the day-one kit: three dictionaries, DK-1–81, G1–67; its wiki page
|
||||
census and gate), `tools/share_body.py` (the share tool), `config/dedup_exceptions.tsv` (the ledger), cookbook §453 · **Phase 36:** `docs/levers.md` + `docs/lever-progress.tsv` (the lever series), `docs/readability.md` + `docs/readability-progress.tsv`
|
||||
(the readability series), `tools/lever_census.py` (the census, a tools-health rung), `tools/delever.py` (the engine + the generator registry
|
||||
R2–R46), `tools/delever_search.py --try` (the agents' scorer), `.run/P36/agents/METHOD_S103.md` (the agents' method), cookbook §454–§457,
|
||||
`include/gte_inline.h`, `config/verbatim_manifest.json` (49 rows) · **`decomp-architect/`** (the day-one kit: three dictionaries, DK-1–81, G1–67; its wiki page
|
||||
`docs/wiki/Start-a-new-decomp-project.md`; `make kit-corpus` regenerates, tools-health asserts) · `config/wave_exclude.txt` (pinned walls) · `config/verbatim_manifest.json` · `phase-ends/logs/` (on demand only, R19) · `.run/`
|
||||
(scratch; allowlisted subtrees are tracked — e.g. `.run/P32/t3/` drafts/ledger; the rules are on the conventions page).
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
# PhaseEnd — Phase 36: Levers off — every compiler-forcing construct out of the matched C, to its measured floor
|
||||
**Date:** 2026-09-11 · **Project Version:** 2.2.0 · **Phase Status:** Complete (milestone as AMENDED at S104, confirmed by Drew at gate 2 — 2026-09-11, "confirmed for phaseend") · **Generation:** Gen3 (the second phase; Drew's order dedup → **pins** → structs → names)
|
||||
|
||||
> Chartered at gate 1 (S97, 2026-09-09, plan mode, Max) from `docs/gen3-handoff.md` §5–§7 and `docs/gen3-standards.md`, widened by
|
||||
> Drew at the gate from "pins off" to **every lever class** — register pins, `asm` statements of every kind (barriers, launders,
|
||||
> keep-alives, hand-placed instructions, the GTE coprocessor idiom), volatile levers, bare `register` — with decision 2 "grind to zero"
|
||||
> and the marking rule "ban the silence, not the lever". Ran **nine sessions (S97–S105, 2026-09-09 → 2026-09-11)** and **575 commits**
|
||||
> (`63b886626..db212f167` on the baseline `e6d98dd1d`, Drew's P35 close; 320 of them are single-function banks through the whole-object
|
||||
> gate). The granular trail — every batch's verify line, every agent landing with its pass and `file:line`, every instrument defect
|
||||
> with its cause — is at **`phase-ends/logs/Phase36.md`** (R19, on demand; ≈3,300 lines). Owner decisions (Drew): gate 1's three forks
|
||||
> (scope A–D now, E–G deferred; grind to zero; byte-needed `volatile`/`register` kept unmarked and ledgered) and the verbatim
|
||||
> confirmation; T1b (the in-function verbatim form, "confirmed per your recommendations"); T7's start rule ("dont start ultra code wave
|
||||
> for reshaping without my direct approval"); the T7 operating procedure ("always have an agent running … prove the rule, harvest the
|
||||
> idiom, start a new agent"); the burst of 20; the cap 5 → 2 → 1 → none; the S104 rulings read against sotn-decomp (do-while and dead
|
||||
> initialisers stay as marked ordinary C; GTE deferred; every site reducible to C, the unclosed ones carried to the structs phase — the
|
||||
> **milestone amended** from "0 pins, 0 asm" to "every survivor marked, counted, attributed and named for the structs phase"); the
|
||||
> S105 close ("confirmed per your recommendation. wait for the last agent to finish, then do all the things and no more agents this phase").
|
||||
|
||||
## Build Log
|
||||
|
||||
**The phase in one line:** the census found **53,234** compiler-forcing sites (37,720 register pins + 15,514 asm statements) in 15,679
|
||||
matched function bodies; a deterministic ladder — a byte oracle on the build's own recipes, a mechanical strip, the GTE header, shape
|
||||
recipes, a permuter rung, a guided search — and then one-agent-per-translation-unit readings of the compiler's own source took them to
|
||||
**4,010** (2,141 pins + 1,869 asm in 1,980 bodies, −92.5 %), every step proven by the 218 hashes from a clean rebuild, every survivor
|
||||
marked with the compiler pass that needs it and the instrument that judged it, and the remainder bucketed by what it needs (a signature,
|
||||
a struct, a carve, a GTE macro decision) for the structs phase.
|
||||
|
||||
**Files created/changed and complete — do not recreate** (category summaries; the per-commit list is `git log e6d98dd1d..db212f167` and
|
||||
the archived log):
|
||||
|
||||
- **The instruments (T1–T3, extended through T7).** `tools/lever_census.py` (the self-asserting census: every `asm`/`register`/
|
||||
`volatile`/`__builtin_*`/`__attribute__` token roled once, per-line coverage against the raw text, four known-true controls keyed on
|
||||
their T1 hashes, the `// !FAKE:` split, orphan-marker detection, cross-file macro names, the src stamp, `--check` / `--check --strict`,
|
||||
`--sites`, `--selftest`; a `make tools-health` rung since T8); `tools/delever_oracle.py` (every object's exact build command captured
|
||||
once by `make -n -W`, candidates compiled IN PLACE with the output redirected, whole-object byte equality against the fleet run's
|
||||
object; `--calibrate` 177/177 + a positive control; COMPILE-CRASH apart from COMPILE-ERROR, R103; `--snapshot-baseline` — the baseline
|
||||
under `.run/P36/delever/baseline/`, so a clean fleet rebuild can run beside scoring agents); `tools/delever.py` (the engine: positional
|
||||
rewrites per lever class with a token-mismatch REFUSAL, rung A strip-all, rung B greedy, the file as the write unit and its final
|
||||
compile as the proof, the ledger keyed by body hash before/after, `inflight.json` as the only restore (R102), `--scrub`, `--apply-body`,
|
||||
`--propagate` (class remap by address, the allowance derived from the exemplar's surviving markers), `--port-scan`, `--recipes` (rung
|
||||
R, TU-parallel), `--repair-nhash`, `--selftest`; **the generator registry R2–R46** — every family with a selftest fixture and a
|
||||
known-true run on the body it came from); `tools/delever_cycle.sh` (the unattended batch cycle with FINISH and REDRAW modes, the stale
|
||||
`.git/index.lock` wait); `tools/gte_consolidate.py` (T5: the signature engine on the build's own tail, one canonical text per
|
||||
signature, Sony's names, lever variants `_m`/`_v`, `--sweep`, `--remark`); `tools/delever_permute.py` (rung D: the permuter on a
|
||||
lever-free draft with the tree's own body as `target.o` and a positive control); `tools/delever_search.py` (rung G: the object-scored
|
||||
beam search with a reloc-masked edit distance, the residual classifier, `--explain`, `--try` — the agents' scorer, per-function scratch,
|
||||
parallel-safe); `tools/delever_regen.py` (the read-only regen of newly harvested families over the whole residue, forked worker
|
||||
processes, `--bank`); `tools/delever_pack.py` (the agent packs: `neighbours.txt`, `related.txt`, `best_body.c`, `ORDER.tsv`);
|
||||
`tools/argcheck.py` + `tools/decl_repair.py` (S102: the lying call declarations — 16,759 repaired byte-identically across 3,439 units;
|
||||
K&R definitions read since S103); `tools/localalloc_sim.py` (c26's local-alloc simulator, promoted after 0 mismatches over 150 blocks;
|
||||
the three-quantity switch modelled at S104); `tools/alloc_table.py` (gcc's truncated integer priority, TIE flags); `tools/cc1_dumps_tu.sh`
|
||||
(`-dt -dJ -dd`, `-Isrc/shared`, takes a `.c`); `tools/lever_progress.py` + `docs/levers.md` + `docs/lever-progress.tsv` (the series, 78
|
||||
milestone rows, rendered as state transitions); `tools/readability_progress.py` + `docs/readability.md` + `docs/readability-progress.tsv`
|
||||
(the second Gen3 series); `tools/verbatim_check.py` (the in-function form, `--update` keeping order and UTF-8, `--strict` in tools-health).
|
||||
- **The tree.** `include/gte_inline.h` (50 GTE macros under Sony's names for what were 9,102 per-TU definitions; 8,951 deleted, 629 of
|
||||
699 `"memory"`-clobber variants proven byte-neutral and dropped, 70 kept as marked `_m` levers; 575 direct GTE statements as
|
||||
canonical calls); `config/verbatim_manifest.json` (49 rows: 27 PERMANENT-VERBATIM incl. the 22 per-overlay scratchpad stack-switch
|
||||
trampolines the file-scope detector never saw, 8 SDK-VERBATIM libgs renderers, 11 DECOMPILE-NOW, 3 UNCERTAIN — T1b's finding that "every
|
||||
game-code function is C" had been measured by file-scope instruments); **`src/`: 53,234 → 4,010 lever sites** — the survivors marked
|
||||
`// !FAKE: <kind> <detail> — <pass, file:line> (P36 <rung|agent>)`, 2,693 files' stale `@stuck:` header notes retagged `@unstuck(P36):`
|
||||
(30,138 notes, comment-only), 16,759 call declarations made honest, four `do { } while (0)` and dead-initialiser fakes marked per sotn's
|
||||
rule; the ledger `.run/P36/delever/ledger.jsonl` (one row per judgement, the rung, the calibration id, every site's verdict).
|
||||
- **The record.** Cookbook **§454** (rungs D/R: the instrument lessons — a disassembly is not a target), **§455** (rung G, the object-scored
|
||||
search), **§456** (S104's move catalog under ~205 levers), **§457** (S105's catalog: the loop family, cse's address fold, sched1's
|
||||
birthing boost in both directions, combine's narrow-load split, local-alloc arithmetic, the parameter shapes), §197-A superseded;
|
||||
`docs/decision-log.md` P36 S99 / S101 / S104 / S105; `docs/accelerators.md` P36 S99 / S101 / S105; `.run/P36/agents/METHOD_S103.md`
|
||||
(the agents' method, steps 1–25, every emitter and register-order move with its `file:line`); `docs/SETUP.md` P36 rows for every tool;
|
||||
the wiki (`Where-the-project-goes-next` item 2 + the table row) and the Gen3 charter pages date-stamped; `docs/tool-index.md` + the kit
|
||||
corpus regenerated; `config/kit_coverage_map.tsv` (the P36 accelerator entries dispositioned); 333 agent packs with `mechanism.md`.
|
||||
- **Evidence (`.run/P36/`, allowlisted text):** `baseline/` (every R22 log), `census/`, `probe/`, `delever/` (batch records, apply logs,
|
||||
the calibration), `permuter/`, `engine/` (run logs, outcomes, traces, `residual_moves.md` — lane B's 58-row residual → source-move map
|
||||
with its verification ledger), `regen/`, `s103/` `s104/` `s105/` (per-session R22 logs, bank lists, known-true candidates, the picker,
|
||||
the briefs, `attribution_check.py`, `unstrippable.json`, the tools-health logs), `agents/` (the packs).
|
||||
|
||||
**Tools/packages installed:** none external (no apt/pip). `tools/reference/sotn-decomp` shallow-cloned (ignored; X2 — data) at S104 to
|
||||
read Drew's four questions against its tree (R106).
|
||||
|
||||
**Verification results (literal, at close — S105, HEAD `db212f167`, tree clean):**
|
||||
- R22 from clean after the last `src/` change (`fe4a62420`, the comment-only retag): `extract-all: 217 extracted, 0 failed of 217 (+ main,
|
||||
serial)` · **`check-all: 218 passed, 0 failed of 218`** · `real 1m27.146s` · `exit=0` (`.run/P36/s105/r22_l.log`); every batch of the phase
|
||||
— 15 T4 batches, 3 T5 batches, every rung-D/R/G run, every agent bank — carried the same line.
|
||||
- **`lever_census --check: 4,010 pin/asm sites, 4,010 marked !FAKE, 0 UNMARKED — OK`** (exit 0; orphans 0; GTE levers 450 inside the
|
||||
number; `--strict` NOT claimed — by the S104 amendment "0 pins, 0 asm" is the structs phase's finish line). `verbatim_check --strict`:
|
||||
no drift (49 rows).
|
||||
- **`make tools-health: OK — sigs fresh; corpus(+resident) + cdecl + binaries + report(lint+dedup) + cookbook-index all green.`** (run 4,
|
||||
`.run/P36/s105/tools_health_t8d.log`; the new rung inside it; S1 10,180 / 10,180, 0 violations; sdk-dual OK; kit_coverage OK; runs 1–3
|
||||
were red on the day's own record — three Reference-index rows, one kit_lint LEAK, two undispositioned accelerator entries — each fixed).
|
||||
- **Attribution (milestone item 2):** `.run/P36/s105/attribution_check.py` → `4026 counted lever sites, 4026 attributed {rung B 2,620 ·
|
||||
S103 933 · T5 450 · S105 22 · S104 1}, 0 without an instrument` (measured at 4,026, before f11's last 16 rung-B sites came off).
|
||||
- Published (R75): README line 30 `Levers off (Phase 36, snapshot 2026-09-11): 2,141 register pins and 1,869 asm statements remain in
|
||||
1,980 functions (674 distinct bodies), 4,010 of them marked …`; `docs/progress.json` `counts.levers`; `docs/levers.md` (78 rows,
|
||||
`lever_progress --check: OK`); `docs/readability.md` (33 lying declarations left in 25 pinned bodies, from 461 in 314 at S102).
|
||||
- `delever --selftest: OK` · `lever_census --selftest: OK — 24 sites, 2 defs, 2 asm macros` · `share_census --selftest 7/7` · `doc_links
|
||||
--strict: OK` · `kit_lint: OK` · `kit_coverage: OK` · `tool_census --check: OK` · `cookbook-index OK (1,175 sections)`.
|
||||
- The headless Ghidra MCP was never used (no RE work) and was stopped cleanly at the S105 close ("Save succeeded", R23).
|
||||
|
||||
**Milestone achieved (gate 2 — Drew, 2026-09-11; each item with its literal output above):** (1) as AMENDED at S104 — every surviving
|
||||
register pin and asm statement outside the GTE header is marked, counted and named for the structs phase: `lever_census --check` 4,010 /
|
||||
4,010 / 0 UNMARKED, the counts published with the dated snapshot, the manifest unchanged; (2) the ledger names, for every site, the rung
|
||||
and the instrument that judged it — 4,026 of 4,026 attributed; (3) `check-all: 218 passed, 0 failed of 218` from clean, `make tools-health`
|
||||
OK with the new rung, the GTE macros in one header (314 per-TU asm macro definitions remain, each tied to a surviving marked lever or an
|
||||
`h_text` homonym — stated at T5's close, not zero); (4) the record written, this PhaseEnd, the DIGEST append, the log archived; v2.2.0.
|
||||
|
||||
**Next:** **Phase 37 — the structs phase** (Drew's Gen3 order; R95's canonical type layer is its core). Open a fresh session in **plan
|
||||
mode, Max** (Tier 1) from `docs/gen3-handoff.md` (item 4, the types doctrine) + `docs/gen3-standards.md`, with this phase's residue as its
|
||||
acceptance test: 4,010 sites = 1,548 drawable singletons (472 classes) + 691 in 24 parked classes (six signature changes with ready
|
||||
patches — func_800385C0, func_80029D3C, func_80180FA4, func_80180A54, func_80188DF4, func_80183CC4, func_801A1E94/func_801A5C44, func_80035210,
|
||||
func_800384A8, func_80188A30, func_8017FC5C/func_80180200, func_80185578, func_80157D20, func_80168828; the carve change func_80186CE0; the
|
||||
proven-irreducible heads func_8013CF68 ×134, func_80178970 ×127 + four same-shape families, func_8013F350's head) + ~1,150 minimum-lever
|
||||
survivors in five head classes (func_8013D9B0 ×125 — the `gte_stORGB` respelling question of T5; func_80177B5C, func_80140958, func_8012E364,
|
||||
func_8013F350) + 450 GTE clobber variants + 94 `$4`–`$7`-only pins (the missing-parameter shape, ~158 estimated across `src/`). d10's
|
||||
register-union proof (func_8017EF88), a18's `extern u16 X[]` close, f10's three type closes and f3's `s16[3]` finding are the phase's
|
||||
evidence FOR the struct hypothesis; `tools/argcheck.py` (98,648 lying declarations over 1,609 callees) and the raw-cast census
|
||||
(411,850 against 177,902 struct member reads) are its starting instruments. Inherited by name: the kit split, xsig v2, the §396(a)
|
||||
correction owed since S104 (the refuting body was not identified — R14), the 15 remaining UNSTRIPPABLE packs (one-off instructions,
|
||||
macro-carried and multi-output launders), a refusal-reason histogram for `delever_regen`, a "local vs global" column for `alloc_table`.
|
||||
|
||||
## Roadmap delta (what Phase 36 changed about the road ahead)
|
||||
|
||||
- **Gen3 item 2 is at its measured floor, and the floor has a shape.** The phase did not reach zero and says so: the last third of the
|
||||
residue is not a codegen problem the pin lane can read its way out of — it is wrong signatures (a `(void)` function that reads `$a0`, a
|
||||
`void` one that returns `$v0`), missing struct types (the compiler's own alias tests, `sched.c:837-863`, `expr.c:4568-4577`, decide by
|
||||
`MEM_IN_STRUCT_P`), carved data that a struct copy would address in one relocation, and one GTE macro spelling. Each is the structs phase's
|
||||
by construction, and the phase leaves it a list with patches, readings and byte proofs rather than a number.
|
||||
- **The doctrine is written where the next project starts:** `docs/levers.md` §5 — "ban the silence, not the lever": a lever is allowed only
|
||||
marked, ledgered and published from the first bank, with a one-compile bank-time trial ("does it still match without this?") that would
|
||||
have refused 37 % of this population while the context was hot; blanket prevention would have stalled Phase 18. The kit's DK entries and
|
||||
the wiki carry it.
|
||||
- **The compiler map grew by a catalog of moves with their passes** (§454–§457, METHOD steps 1–25): the loop family's biv law, cse's address
|
||||
fold and its inverse, sched1's birthing boost in both directions, combine's narrow-load split, local-alloc's arithmetic (`find_free_reg`'s
|
||||
lowest-free rule, `update_equiv_regs` doubling a constant's life, the three-quantity birth order), the call-signature class (a truncated
|
||||
declaration DELETES an instruction). Every entry names its `file:line` in gcc 2.7.2 and its byte witness.
|
||||
- **What the readability series now measures for the structs phase:** the struct debt (411,850 raw cast dereferences vs 177,902 struct
|
||||
member reads) and the declaration debt (98,648 lying declarations, 33 of them still in pinned bodies).
|
||||
- **Scale, honestly (R41):** the plan priced the mechanical floor at 3 sessions and called T7 "open-ended, to zero"; the phase took 9 sessions,
|
||||
575 commits, ~200 agent draws (S102 22, S103 56, S104 ~105, S105 11 TU batches of 4–7 classes) and roughly 15–20 M agent tokens across
|
||||
the three agent sessions (S105 measured ≈3.5 M for 56 classes). The mechanical rungs took 37 % of the sites for ~20 CPU-hours and no
|
||||
tokens; the search engine took another 6 % for ~5 CPU-hours and no tokens; the agents took the rest — and the closes per agent rose from
|
||||
1 (S102) to 4–7 (S104–S105) as the TU batch and the method file matured.
|
||||
|
||||
## Deviations
|
||||
|
||||
| Item | Plan (gate-1 plan) | Actual | Reason |
|
||||
|---|---|---|---|
|
||||
| The milestone | 0 register pins, 0 asm statements outside the GTE header (decision 2, "grind to zero") | **amended at S104 by Drew:** every surviving site marked, counted, attributed and named for the structs phase; 4,010 remain | S103/S104 read the head classes to proven irreducibility in plain C, and Drew's (c)/(d) rulings — read against sotn-decomp, which keeps `INCLUDE_ASM` stubs rather than pins — moved the unclosed sites to the structs phase |
|
||||
| T7's shape | Ultracode waves (Workflow fan-out), prompted | the Agent tool, one agent per residue class, then one per TU with 4–7 classes; caps 5 → 2 → 1 → none | Drew's rule "one agent at a time so the methodology is honed at each landing" (S101), then his cap retunes; a Workflow was never the right unit for a reading |
|
||||
| T6's permuter rung | the residue exemplars through the permuter, time-boxed | 5 of 16 closed (0.69 h); its two prior campaigns were the instrument (a disassembly is not a target, §454); rung R closed 134/134 of the class it found, then 0 of 300 on the residue | the permuter is a replication engine after a shape is known, not a discovery engine; the guided search (rung G) replaced it |
|
||||
| Sessions | mechanical floor 3; T7 open-ended | 9 (S97–S105) | T7 was 5 of the 9 |
|
||||
| The call-signature turn | not planned | `argcheck` + `decl_repair`: 16,759 lying declarations repaired byte-identically in 3,439 units (S102); R19/R25 generators | six independent agent cracks in one burst were the same class — a truncated declaration deletes an instruction the pin then faked |
|
||||
| The minimum-lever bank | not planned | the S103 pivot: the best honest plain-C body plus only the marked lever(s) it cannot do without, `allow_residue`, propagation deriving the allowance from the exemplar's markers | four 130-copy classes at 4–34 levers per copy became 1–2 |
|
||||
| The in-function verbatim form (T1b) | 5 PERMANENT file-scope rows | 49 manifest rows; 22 per-overlay trampolines + 8 SDK renderers + 11 DECOMPILE-NOW + 3 UNCERTAIN | the census's structural detector found what the file-scope detector never had (P9: the P32 "every game-code function is C" was blind to it) |
|
||||
| Rules | R100–R106 ratified at gate 1 | R100–R106 ratified; **eleven** candidates proposed below | the phase generated governance from its instrument failures, as every phase has |
|
||||
| The §396(a) correction | owed at T9 (S104) | **not written** — carried by name | the refuting body was not identified from the record; a correction needs its bytes (R14) |
|
||||
|
||||
## What we believed, what failed, and what we would do sooner (for the retrospective; the detail is in `docs/decision-log.md` P36)
|
||||
|
||||
- **Believed (gate 1):** the pins would come off mechanically, family-batched, because Phase 32's last four functions had. **The strip took
|
||||
37 % of the sites and freed 20 % of the bodies; the rest was 1,803 distinct shapes**, each a reading of a compiler pass. **Sooner:** the
|
||||
probe (T2) said exactly this on day one — price the residue by distinct SHAPES, never by bodies.
|
||||
- **Believed (S99–S100):** the permuter and a recipe sweep would discover shapes. **They replicate, they do not discover** (134/134 on a
|
||||
known shape, 0/300 on unknown ones); and two permuter campaigns had scored against a disassembly that was not a target (24 wrong words
|
||||
from `move` vs `or`). **Sooner:** a known-true case — the tree's own body must score 0 — before any campaign; the guided search with the
|
||||
object as the scorer.
|
||||
- **Believed (S101):** a wider search would close the head. **112,216 compiles bought 62 bodies**; the head needed readings. **Sooner:** the
|
||||
lane B map (the gcc source read for residual → move) before the wide search, and agents on the head from the first day of T7.
|
||||
- **Believed (S102, the night of three agents):** one agent at a time meant one agent, then a sweep, then the next. **It meant learning
|
||||
between landings, not an empty slot** — six of eight hours had no agent running. **Sooner:** Drew's rule as written at S102: the slot is
|
||||
refilled in seconds; sweeps never stand between two agents; one writer.
|
||||
- **Believed (S102–S104):** every `NO-CANDIDATE` was a property of the population. **R22 was refusing for three unrelated regex reasons for
|
||||
two sessions**, found only when agents closed by its own move and the generator was run on their start text. **Sooner:** a negative-
|
||||
control corpus per generator; refusal reasons as a histogram; the known-true run at every landing.
|
||||
- **Believed (S102):** the pins were codegen. **The biggest single class was a wrong DECLARATION** — a truncated `(void)` deletes an
|
||||
instruction the pin was hired to fake; 16,759 of them were repaired in an afternoon for zero bytes. **Sooner:** `argcheck` at Phase 17
|
||||
(the canonical type layer, R95) — the same lesson the S91-b hindsight recorded, now with a number.
|
||||
- **Believed (S104):** the residue could be ground to zero by more agents. **The residue's last third is signatures, structs, carves and one
|
||||
GTE spelling** — the structs phase's material; the drawable rest is singletons at ~3 sites each. **Sooner:** the bucketing that S105 did
|
||||
on Drew's "stalling?" question, done at every wave close as the stop-rule's input.
|
||||
- **Cost:** the phase's real expense was the agent sessions (S102–S105, ~15–20 M tokens for ~200 draws) and the coordinator's landing
|
||||
loop; the instruments were cheap and paid every day — a calibration line after every commit, a positive control in every scorer, a
|
||||
selftest with a known-true run in every generator. The mistakes that cost the most were each a scorer that read the wrong thing (a
|
||||
disassembly, another agent's object, a stale baseline) and each was caught by a check that read the artifact rather than the intent.
|
||||
|
||||
## Commit Message
|
||||
```
|
||||
(Phase 36 landed as 575 commits 63b886626..db212f167, 2026-09-09 → 2026-09-11 (S97–S105). This close = the archived log + this
|
||||
PhaseEnd + the DIGEST update + the kit's record copies, Drew's milestone-close commit, then the v2.2.0 tag.)
|
||||
|
||||
chore(phase-36): CLOSE — levers off to the measured floor: 53,234 → 4,010 register pins + asm statements (−92.5 %), every survivor
|
||||
marked with its pass and its instrument and named for the structs phase; the GTE idiom in one header; 16,759 lying call declarations
|
||||
repaired; the lever series and the readability series published; 218/218 at every step (v2.2.0)
|
||||
|
||||
- PhaseEnd_Phase36.md written; CURRENT_PHASE.md archived to phase-ends/logs/Phase36.md (R19); DIGEST §0/§2/§3 appended (step 3b)
|
||||
- T0–T10 across S97–S105: the census (T1/T1b, 49 verbatim rows), the oracle + probe (T2), the engine + cycle (T3), the mechanical
|
||||
campaign (T4, 15 batches, −36.8 %), the GTE header (T5), rungs R/D (T6), rung G + the agent lane at caps 5→2→1 (T7, ~200 draws,
|
||||
generators R15–R46, the call-signature turn, the minimum-lever pivot), the gate rung + attribution (T8), the record (T9)
|
||||
- close: check-all 218/218 from clean; lever_census --check 4,010 / 0 UNMARKED (exit 0); make tools-health OK (run 4); attribution
|
||||
4,026/4,026; tools-health, doc_links, kit_lint, kit_coverage, tool_census all OK
|
||||
- rules: R100–R106 ratified at gate 1; candidates (a)–(k) proposed for Phase 37 gate 1
|
||||
- v2.1.0 -> v2.2.0
|
||||
```
|
||||
|
||||
## Rules Added This Phase
|
||||
|
||||
**Ratified at gate 1 (2026-09-09):** **R100–R106** (the PhaseEnd_Phase35 candidates (a)–(g)); full text in `phase-ends/DIGEST.md` §3.
|
||||
|
||||
**Candidates recorded in the log, for Drew to accept, modify or reject at Phase 37 gate 1 (P10):**
|
||||
|
||||
| Rule | Reason |
|
||||
|---|---|
|
||||
| **(a) Ban the silence, not the lever:** a compiler-forcing construct is allowed in a banked body only marked, ledgered and published from the first bank, with a one-compile bank-time trial of the body without it. | `docs/levers.md` §5: 37 % of 53,234 sites came off with no understanding at all once tried; the levers propagated with every family remap (1,758 distinct bodies became 12,578) because nothing ever asked. |
|
||||
| **(b) A generator ships with a negative-control corpus of real bodies where it must fire, and a regen pass reports its refusal reasons as a histogram.** | R22 refused three ways for two sessions (`&&` as `&p`, the literal base, a cast store as a set); every `NO-CANDIDATE` had been read as a property of the population (accelerators P36 S105). |
|
||||
| **(c) At every landing, run every registered family on the agent's START text before banking** — a close by a move the registry claims is the cheapest instrument check in the loop. | It found all three R22 defects and banked shared headers IDENTICAL on 141 objects each. |
|
||||
| **(d) A scorer's target is the tree's own bytes compiled by the build's own tail, never a disassembly** — a known-true case (the tree's body scores 0) before any campaign. | Two permuter campaigns scored 28 for a byte-identical body: `objdump`'s `move` assembled as `or`, resolved `%hi/%lo` pairs (§454). |
|
||||
| **(e) Scratch is keyed by the unit of work, never by a worker tag or a file** (R48 extended). | Nine burst agents shared one scratch object and two scored candidates against another agent's function; the search's `g0.o` was keyed by a worker index. |
|
||||
| **(f) A gate's baseline is a snapshot, not the build directory** — a clean rebuild never runs where a live scorer reads `build/`. | `--try` scored against half-written objects during a fleet gate until `--snapshot-baseline` (S102). |
|
||||
| **(g) A lever's marker names its PASS and its INSTRUMENT** (R65 for markers), asserted by an attribution check at the close. | 4,026 of 4,026 sites attributed; the S103 minimum-lever markers and the T5 remark were the only way a later reader knows which compiler decision each survivor stands for. |
|
||||
| **(h) A ledger's "done" is per body (unit, function, after-hash), never by text alone.** | The T4 preflight drew 2,204 files where 2,583 were owed: every fleet-wide copy of an all-NEEDED exemplar passed as done by its text hash. |
|
||||
| **(i) A long unattended run is DETACHED with a progress log, never a harness background task** (R55 operated). | The harness's low-memory guard killed the batch cycle mid-apply and two 30-byte waiters with 22–27 GB free; a SIGKILL skips a restore. |
|
||||
| **(j) A marked ordinary-C fake (do-while, dead initialiser) is counted apart from levers and never an orphan; an invented condition, a dead store or a dummy reassignment is never banked.** | Drew's S104 ruling (a), read against sotn's `docs/STYLE.md`; a14/d20/c9/c13 refused on exactly this line. |
|
||||
| **(k) A "stalling?" question is answered with the residue bucketed by what each bucket needs before any plan is proposed.** | S105: 1,548 drawable singletons / 691 parked / ~1,150 proven / 450 GTE / 94 missing-parameter — the close decision took one message. |
|
||||
|
||||
*(Techniques stay in the cookbook §454–§457 and METHOD steps 1–25; strategy in `docs/decision-log.md` (R31) and `docs/accelerators.md`;
|
||||
the portable form is for the kit at its split.)*
|
||||
|
||||
## PhaseEnd Changelog
|
||||
**v2.1.0 → v2.2.0 — Phase 36 complete (Gen3's second phase).** The compiler-forcing constructs in the matched C — register pins, asm
|
||||
barriers, launders, keep-alives, hand-placed instructions, the GTE coprocessor idiom — were censused with a self-asserting instrument
|
||||
(53,234 sites in 15,679 bodies; 44 whole-body assembly routines inside C shells found on the way and put in the verbatim manifest), then
|
||||
taken off in a ladder that never changed a byte: a byte oracle on the build's own recipes, a mechanical strip (−37 %), one GTE header for
|
||||
9,102 per-TU macro definitions, recipes, a permuter rung, an object-scored guided search (−6 %, no tokens), and ~200 agent readings of gcc
|
||||
2.7.2's own source (one agent per class, then per translation unit) that closed 56 of 56 in the last session. 4,010 remain (−92.5 %), each
|
||||
marked with the pass that needs it and the instrument that judged it, and bucketed for the structs phase: wrong signatures with ready
|
||||
patches, missing struct types, a carve, one GTE spelling, and 1,548 singleton sites. On the way: 16,759 lying call declarations repaired
|
||||
byte-identically, the lever series and the readability series published, the generator registry R2–R46 with a known-true run for each, and
|
||||
the doctrine "ban the silence, not the lever" written for the next project's day one. R100–R106 ratified; eleven candidates proposed.
|
||||
|
||||
## Plain-English Recap
|
||||
When this decompilation reached 100 %, thousands of its functions still carried little hacks — instructions to the compiler that forced
|
||||
a particular register or ordering so the bytes would match — that a real programmer in 1998 never wrote. This phase counted them
|
||||
honestly (fifty-three thousand), then removed them in stages while re-checking every one of the 218 game files byte for byte after every
|
||||
step. A third came off just by asking the compiler "do you still produce the same bytes without this?". The rest needed understanding:
|
||||
first a search program that scores each candidate rewrite against the real object, then agents reading the compiler's own source code to
|
||||
find WHY the original bytes came out the way they did — a wrong function signature, a missing struct type, a loop written a different way
|
||||
— and spelling the C the way the original author plausibly had. About four thousand hacks remain, each now labelled with the exact
|
||||
compiler decision that needs it, and sorted by what would remove it. Most of those need the next phase's work — real struct types and
|
||||
correct function signatures — which is why the phase stops here rather than grinding on. The count over time is published as a chart, and
|
||||
the lesson for the next project is written down: allow such hacks only when they are marked and counted from the first day.
|
||||
|
||||
## 🛑 Stop Here
|
||||
PhaseEnd written; `CURRENT_PHASE.md` archived → `phase-ends/logs/Phase36.md` (R19, via `git mv`); `phase-ends/DIGEST.md` §0/§2/§3
|
||||
appended (step 3b); R100–R106 dispositioned in `config/kit_coverage_map.tsv` (kit_coverage OK); the timeline regenerated (76 rows, the
|
||||
P36 row); the kit's record corpus regenerated (`make kit-corpus`, `tool_census --check: OK`) — **all left uncommitted for Drew's milestone-close commit**
|
||||
(R6 gate-2 sign-off; the message is above). The Phase-36 work is committed across the sessions (`63b886626..db212f167`; not pushed). The
|
||||
headless Ghidra MCP is stopped (R23); nothing under `ghidra/` is tracked. **Drew, from the repository root:**
|
||||
|
||||
```
|
||||
git add -A phase-ends decomp-architect config/kit_coverage_map.tsv docs/story-timeline.md docs/story-timeline.svg
|
||||
git commit -m "chore(phase-36): CLOSE — levers off to the measured floor: 53,234 → 4,010 register pins + asm statements (−92.5 %), every survivor marked with its pass and its instrument and named for the structs phase; the GTE idiom in one header; 16,759 lying call declarations repaired; the lever and readability series published; 218/218 at every step (v2.2.0)"
|
||||
git tag -a v2.2.0 -m "v2.2.0 — Phase 36: levers off to the measured floor (53,234 → 4,010); 218 binaries byte-identical"
|
||||
git push origin main --tags
|
||||
```
|
||||
|
||||
Gen3 continues — do **NOT** start Phase 37 here. Start a **fresh session** (effort **Max**, **plan mode**) for **Phase 37 — the structs
|
||||
phase**, planning from `docs/gen3-handoff.md` and `docs/gen3-standards.md` with this PhaseEnd's residue list as the acceptance test. Keep
|
||||
this file forever.
|
||||
@@ -91,6 +91,6 @@
|
||||
| 2026-09-07 | 61 | P33 (v1.32.0) | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | — |
|
||||
| 2026-09-08 | 76 | P33.5 (v1.32.1), P34 (v2.0.0), P35 (v2.1.0) | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | — |
|
||||
| 2026-09-09 | 64 | | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | — |
|
||||
| 2026-09-11 | 359 | | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | — |
|
||||
| 2026-09-11 | 366 | P36 (v2.2.0) | 218 | 100.0% | 100.0% | 100.0% | 100.0% | 0 | — |
|
||||
|
||||
76 dated rows · phase ticks from the 36 PhaseEnds · the chart: `docs/story-timeline.svg`.
|
||||
76 dated rows · phase ticks from the 37 PhaseEnds · the chart: `docs/story-timeline.svg`.
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<line x1="949.0" y1="360" x2="949.0" y2="352" stroke="#888"/>
|
||||
<line x1="949.0" y1="360" x2="949.0" y2="352" stroke="#888"/>
|
||||
<line x1="949.0" y1="360" x2="949.0" y2="352" stroke="#888"/>
|
||||
<line x1="980.0" y1="360" x2="980.0" y2="352" stroke="#888"/>
|
||||
<line x1="452.8" y1="30" x2="452.8" y2="360" stroke="#c33" stroke-dasharray="4,3"/><text x="456.8" y="44" font-size="11" fill="#c33">2026-07-22: main enters the denominators</text>
|
||||
<polyline fill="none" stroke="#1f77b4" stroke-width="2" points="339.1,169.4 349.4,152.3 359.8,149.5 370.1,133.5 380.4,135.5 390.8,125.8 401.1,122.1 411.5,111.7 421.8,108.2 432.1,102.6 442.5,102.5 452.8,100.5 463.1,98.1 473.5,96.3 483.8,94.1 494.2,90.4 504.5,81.5 514.8,74.4 525.2,72.3 535.5,68.9 545.8,65.8 556.2,55.0 576.9,50.8 587.2,48.1 597.5,46.5 607.9,49.7 618.2,50.5 649.2,48.7 659.6,47.0 669.9,46.0 680.2,45.9 690.6,45.5 700.9,44.8 711.2,44.6 721.6,43.6 731.9,42.9 783.6,42.8 804.3,38.6 814.6,34.9 824.9,34.2 845.6,33.6 856.0,33.3 866.3,32.1 876.6,31.6 887.0,31.0 897.3,30.9 907.6,30.1 918.0,30.0 928.3,30.0 938.7,30.0 949.0,30.0 959.3,30.0 980.0,30.0"/><text x="70" y="352" font-size="12" fill="#1f77b4">instruction-weighted (all binaries)</text>
|
||||
<polyline fill="none" stroke="#2ca02c" stroke-width="2" points="339.1,263.2 349.4,230.9 359.8,225.5 370.1,197.6 380.4,196.8 390.8,184.2 401.1,181.7 411.5,159.9 421.8,152.9 432.1,140.5 442.5,140.4 452.8,136.8 463.1,136.7 473.5,136.7 483.8,134.8 494.2,131.5 504.5,114.5 514.8,106.2 525.2,103.4 535.5,100.4 545.8,94.4 556.2,77.8 576.9,69.5 587.2,65.5 597.5,64.8 607.9,70.9 618.2,72.4 649.2,69.1 659.6,65.6 669.9,63.7 680.2,63.3 690.6,62.7 700.9,61.3 711.2,60.8 721.6,58.5 731.9,57.0 783.6,56.9 804.3,47.8 814.6,40.3 824.9,38.8 845.6,37.9 856.0,37.4 866.3,34.8 876.6,33.8 887.0,32.2 897.3,32.0 907.6,30.3 918.0,30.1 928.3,30.0 938.7,30.0 949.0,30.0 959.3,30.0 980.0,30.0"/><text x="70" y="338" font-size="12" fill="#2ca02c">distinct code (each body once)</text>
|
||||
|
||||
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.9 KiB |
+46
-2
@@ -46,7 +46,15 @@ Three sessions (S94–S96) / 48 commits: every shared body one plain-C header un
|
||||
8.8 MB macro header gone), the five twins from one source directory, the same-address backlog 1,099 classes / 4,755 copies → 51 ledgered
|
||||
/ 160, a new `h_text` registry tier for 38 byte-variant functions, S1 a tools-health gate with a second oracle, 14 macro-era tools frozen +
|
||||
4 retired behind a guard, the published counts corrected (+459 functions; REAL 360,744 → 350,533 with EMPTY up the same). R96–R99 ratified;
|
||||
candidates (a)–(g) proposed. **Gen3 continues at Phase 36 — pins off** (Drew's order dedup → pins → structs → names). The open paragraph:
|
||||
candidates (a)–(g) proposed. **Phase 36 CLOSED 2026-09-11 (v2.2.0; `PhaseEnd_Phase36.md`) — Gen3's second phase, LEVERS OFF to the measured floor:** nine sessions
|
||||
(S97–S105) / 575 commits; the census found **53,234** compiler-forcing sites (37,720 register pins + 15,514 asm statements) in 15,679
|
||||
bodies; a byte oracle on the build's own recipes, a mechanical strip (−37 %), one GTE header for 9,102 per-TU macro definitions, recipes, a
|
||||
permuter rung, an object-scored guided search and ~200 agent readings of gcc 2.7.2's source (one per class, then one per TU; 56 of 56 in
|
||||
the last session) took them to **4,010** (−92.5 %), every survivor marked with its pass and its instrument, 218/218 at every step; the
|
||||
milestone AMENDED at S104 by Drew (the unclosed sites named for the structs phase: signatures with patches, struct types, a carve, one GTE
|
||||
spelling, 1,548 singleton sites); 16,759 lying call declarations repaired; the lever and readability series published; the doctrine "ban
|
||||
the silence, not the lever". R100–R106 ratified; candidates (a)–(k) proposed. **Gen3 continues at Phase 37 — the structs phase.** The
|
||||
Phase-35 open paragraph:
|
||||
*Phase 35 OPEN (2026-09-08, S94; gate 1 in plan mode at Max)*
|
||||
Drew set the Gen3 order dedup → pins → structs → names (one phase each, planned one at a time). The phase converts the 3,516 distinct
|
||||
`DEFINE_func_` macro bodies (5,147 define lines) into per-function plain-C headers under `src/shared/<space>/` included at each member's
|
||||
@@ -208,6 +216,19 @@ defects fixed at their cause; T5b the `h_text` tier (38 classes / 2,030 sites);
|
||||
in tools-health, the digest corrected; T8 the record (wiki, cookbook §453, decision log). Close: R22 218/218; S1 10,180/10,180, 0
|
||||
violations; fleet clean-run 157 s → 84–90 s. Rules: R96–R99 ratified; candidates (a)–(g).
|
||||
|
||||
**P36 (2026-09-11, v2.2.0) LEVERS OFF — every compiler-forcing construct out of the matched C, to its measured floor.** 9 sessions
|
||||
(S97–S105) / 575 commits. T1 the self-asserting lever census: 53,234 sites (37,720 pins + 15,514 asm) in 15,679 bodies, 2,227 distinct; T1b
|
||||
44 whole-body assembly routines inside C shells (22 per-overlay stack-switch trampolines + 8 Sony renderers PERMANENT/SDK, 11 DECOMPILE-NOW,
|
||||
3 UNCERTAIN) — the manifest 5 → 49 rows; T2 the oracle (4,284 recipes by `make -n -W`, in-place compiles, whole-object equality, 177/177
|
||||
calibration) + a 283-body probe; T3 `delever.py` + the cycle; T4 the mechanical strip in 15 batches → 33,625 (−36.8 %); T5 `include/
|
||||
gte_inline.h` (50 macros for 9,102 definitions; 629/699 `"memory"` variants byte-neutral); T6 rung R (134/134 on a known shape, 0/300 on
|
||||
unknown) and rung D (5/16; two prior campaigns had scored a disassembly, §454); S101 rung G, the object-scored guided search (33,427 →
|
||||
30,358, no tokens; lane B's residual→move map); T7 the agent lane — S102 (→ 24,119; the call-signature turn: 16,759 lying declarations
|
||||
repaired; the baseline snapshot; the burst of 20), S103 (→ 5,097; 56 draws; `delever_regen`; the minimum-lever pivot), S104 (→ 4,152; ~105
|
||||
draws in TU batches; Drew's four rulings read against sotn-decomp; the milestone amended), S105 (→ 4,010; 56/56 closes; generators
|
||||
R44–R46; R22 found blind three ways; caps 2 → 1 → none); T8 the census rung in tools-health + attribution 4,026/4,026; T9 the record
|
||||
(cookbook §454–§457, METHOD steps 1–25, 30,138 stale `@stuck:` notes retagged). Rules: R100–R106 ratified; candidates (a)–(k).
|
||||
|
||||
## 3. Every rule, in full (transcribe these at session start; P/G/H/X are in PROJECT_CONTEXT.md)
|
||||
- **R1 — H1 relaxed while private.** ROM-derived content (`asm/`, `assets/`, `extracted/`, decompressed `.CD`) MAY be
|
||||
committed while the repo is private; accidental inclusion is not a violation. The raw multi-GB disc dump stays ignored
|
||||
@@ -401,6 +422,26 @@ never from its last line; a step that hands a file to a third party is proven th
|
||||
before the owner's browser session, and the proving tool writes the paste; what a public tree carries is decided before the flip, and a
|
||||
retired document gets its Archive-index row and is deleted in the same commit).
|
||||
|
||||
**R100–R106 — RATIFIED at Phase 36 gate 1 (Drew, 2026-09-09; the PhaseEnd_Phase35 candidates (a)–(g), operated through P35):**
|
||||
- **R100 — A shared body has exactly one source; a duplicate copy is a defect the health chain asserts, and its count is published with
|
||||
its rule.** The P35 invariant (S1), a `tools-health` gate; 1,099 classes / 4,755 copies → 51 / 160, every remainder ledgered.
|
||||
- **R101 — Every commit that advances a task — an intra-task bank included — carries its log line and the 🛑 headline; a checkpoint older
|
||||
than HEAD is a dead session's checkpoint.** S94 died at 91 % with two bank commits carrying no log line.
|
||||
- **R102 — A tool that restores files restores from its own snapshot, never `git checkout` on a tree it did not commit.** `share_body`'s
|
||||
first bisect wiped ~50 uncommitted sites and returned green.
|
||||
- **R103 — A failure-cause extractor is negative-controlled against the compiler's real message forms, not against the word "error".**
|
||||
gcc 2.7.2 prints errors without it and exits 33; 254 of 303 rejection lines read "Error 33".
|
||||
- **R104 — Build the disagreeing oracle before the batch runs, and measure its disagreement before believing either side** (R34 operated).
|
||||
- **R105 — A registry lists a member only after the gate has spoken for it; a listed member whose site does not share is a defect the
|
||||
check names.** 788 members were extended wholesale; 317 were private after the run.
|
||||
- **R106 — A policy taken on a remembered precedent is a belief — read the target project's tree.** The 2026-09-02 dedup deferral
|
||||
rested on one parenthetical; sotn's tree said the opposite.
|
||||
**Phase 36 proposed candidates (a)–(k) for Phase 37 gate 1** (the table in `PhaseEnd_Phase36.md` §Rules: ban the silence, not the
|
||||
lever; a generator ships with a negative-control corpus and reports its refusal reasons; run every registered family on the agent's start
|
||||
text at every landing; a scorer's target is the tree's own bytes, never a disassembly; scratch keyed by the unit of work; a gate's baseline
|
||||
is a snapshot; a lever's marker names its pass and its instrument; a ledger's "done" is per body; an unattended run is detached; a marked
|
||||
ordinary-C fake is counted apart and an invented construct is never banked; a "stalling?" question is answered with the residue bucketed).
|
||||
|
||||
**R96–R99 — RATIFIED at Phase 35 gate 1 (Drew, 2026-09-08; the PhaseEnd_Phase34 candidates (a)–(d), operated through P34):**
|
||||
- **R96 — A scratch prune is an instrument change:** every tool that writes under a pruned tree is re-run before the prune is called
|
||||
done. `cdecl --audit` wrote its probe under the pruned `.run/audit/`; the refusal read as four parser defects (P34 run 1 of the close chain).
|
||||
@@ -426,6 +467,9 @@ the OpenRouter-era `automation-runbook.md` is archived) · `docs/effort-map.md`
|
||||
`docs/disc-ledger.md` · `docs/backlog.md` (near-miss ledger) · `docs/gen3-handoff.md` + `docs/gen3-standards.md` (Gen3) ·
|
||||
`docs/tool-index.md` (every tool keyed by
|
||||
the need it answers; generated) · **Phase 35:** `docs/wiki/The-dedup-engine.md` (the shared-source model), `tools/share_census.py` (the S1
|
||||
census and gate), `tools/share_body.py` (the share tool), `config/dedup_exceptions.tsv` (the ledger), cookbook §453 · **`decomp-architect/`** (the day-one kit: three dictionaries, DK-1–81, G1–67; its wiki page
|
||||
census and gate), `tools/share_body.py` (the share tool), `config/dedup_exceptions.tsv` (the ledger), cookbook §453 · **Phase 36:** `docs/levers.md` + `docs/lever-progress.tsv` (the lever series), `docs/readability.md` + `docs/readability-progress.tsv`
|
||||
(the readability series), `tools/lever_census.py` (the census, a tools-health rung), `tools/delever.py` (the engine + the generator registry
|
||||
R2–R46), `tools/delever_search.py --try` (the agents' scorer), `.run/P36/agents/METHOD_S103.md` (the agents' method), cookbook §454–§457,
|
||||
`include/gte_inline.h`, `config/verbatim_manifest.json` (49 rows) · **`decomp-architect/`** (the day-one kit: three dictionaries, DK-1–81, G1–67; its wiki page
|
||||
`docs/wiki/Start-a-new-decomp-project.md`; `make kit-corpus` regenerates, tools-health asserts) · `config/wave_exclude.txt` (pinned walls) · `config/verbatim_manifest.json` · `phase-ends/logs/` (on demand only, R19) · `.run/`
|
||||
(scratch; allowlisted subtrees are tracked — e.g. `.run/P32/t3/` drafts/ledger; the rules are on the conventions page).
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
# PhaseEnd — Phase 36: Levers off — every compiler-forcing construct out of the matched C, to its measured floor
|
||||
**Date:** 2026-09-11 · **Project Version:** 2.2.0 · **Phase Status:** Complete (milestone as AMENDED at S104, confirmed by Drew at gate 2 — 2026-09-11, "confirmed for phaseend") · **Generation:** Gen3 (the second phase; Drew's order dedup → **pins** → structs → names)
|
||||
|
||||
> Chartered at gate 1 (S97, 2026-09-09, plan mode, Max) from `docs/gen3-handoff.md` §5–§7 and `docs/gen3-standards.md`, widened by
|
||||
> Drew at the gate from "pins off" to **every lever class** — register pins, `asm` statements of every kind (barriers, launders,
|
||||
> keep-alives, hand-placed instructions, the GTE coprocessor idiom), volatile levers, bare `register` — with decision 2 "grind to zero"
|
||||
> and the marking rule "ban the silence, not the lever". Ran **nine sessions (S97–S105, 2026-09-09 → 2026-09-11)** and **575 commits**
|
||||
> (`63b886626..db212f167` on the baseline `e6d98dd1d`, Drew's P35 close; 320 of them are single-function banks through the whole-object
|
||||
> gate). The granular trail — every batch's verify line, every agent landing with its pass and `file:line`, every instrument defect
|
||||
> with its cause — is at **`phase-ends/logs/Phase36.md`** (R19, on demand; ≈3,300 lines). Owner decisions (Drew): gate 1's three forks
|
||||
> (scope A–D now, E–G deferred; grind to zero; byte-needed `volatile`/`register` kept unmarked and ledgered) and the verbatim
|
||||
> confirmation; T1b (the in-function verbatim form, "confirmed per your recommendations"); T7's start rule ("dont start ultra code wave
|
||||
> for reshaping without my direct approval"); the T7 operating procedure ("always have an agent running … prove the rule, harvest the
|
||||
> idiom, start a new agent"); the burst of 20; the cap 5 → 2 → 1 → none; the S104 rulings read against sotn-decomp (do-while and dead
|
||||
> initialisers stay as marked ordinary C; GTE deferred; every site reducible to C, the unclosed ones carried to the structs phase — the
|
||||
> **milestone amended** from "0 pins, 0 asm" to "every survivor marked, counted, attributed and named for the structs phase"); the
|
||||
> S105 close ("confirmed per your recommendation. wait for the last agent to finish, then do all the things and no more agents this phase").
|
||||
|
||||
## Build Log
|
||||
|
||||
**The phase in one line:** the census found **53,234** compiler-forcing sites (37,720 register pins + 15,514 asm statements) in 15,679
|
||||
matched function bodies; a deterministic ladder — a byte oracle on the build's own recipes, a mechanical strip, the GTE header, shape
|
||||
recipes, a permuter rung, a guided search — and then one-agent-per-translation-unit readings of the compiler's own source took them to
|
||||
**4,010** (2,141 pins + 1,869 asm in 1,980 bodies, −92.5 %), every step proven by the 218 hashes from a clean rebuild, every survivor
|
||||
marked with the compiler pass that needs it and the instrument that judged it, and the remainder bucketed by what it needs (a signature,
|
||||
a struct, a carve, a GTE macro decision) for the structs phase.
|
||||
|
||||
**Files created/changed and complete — do not recreate** (category summaries; the per-commit list is `git log e6d98dd1d..db212f167` and
|
||||
the archived log):
|
||||
|
||||
- **The instruments (T1–T3, extended through T7).** `tools/lever_census.py` (the self-asserting census: every `asm`/`register`/
|
||||
`volatile`/`__builtin_*`/`__attribute__` token roled once, per-line coverage against the raw text, four known-true controls keyed on
|
||||
their T1 hashes, the `// !FAKE:` split, orphan-marker detection, cross-file macro names, the src stamp, `--check` / `--check --strict`,
|
||||
`--sites`, `--selftest`; a `make tools-health` rung since T8); `tools/delever_oracle.py` (every object's exact build command captured
|
||||
once by `make -n -W`, candidates compiled IN PLACE with the output redirected, whole-object byte equality against the fleet run's
|
||||
object; `--calibrate` 177/177 + a positive control; COMPILE-CRASH apart from COMPILE-ERROR, R103; `--snapshot-baseline` — the baseline
|
||||
under `.run/P36/delever/baseline/`, so a clean fleet rebuild can run beside scoring agents); `tools/delever.py` (the engine: positional
|
||||
rewrites per lever class with a token-mismatch REFUSAL, rung A strip-all, rung B greedy, the file as the write unit and its final
|
||||
compile as the proof, the ledger keyed by body hash before/after, `inflight.json` as the only restore (R102), `--scrub`, `--apply-body`,
|
||||
`--propagate` (class remap by address, the allowance derived from the exemplar's surviving markers), `--port-scan`, `--recipes` (rung
|
||||
R, TU-parallel), `--repair-nhash`, `--selftest`; **the generator registry R2–R46** — every family with a selftest fixture and a
|
||||
known-true run on the body it came from); `tools/delever_cycle.sh` (the unattended batch cycle with FINISH and REDRAW modes, the stale
|
||||
`.git/index.lock` wait); `tools/gte_consolidate.py` (T5: the signature engine on the build's own tail, one canonical text per
|
||||
signature, Sony's names, lever variants `_m`/`_v`, `--sweep`, `--remark`); `tools/delever_permute.py` (rung D: the permuter on a
|
||||
lever-free draft with the tree's own body as `target.o` and a positive control); `tools/delever_search.py` (rung G: the object-scored
|
||||
beam search with a reloc-masked edit distance, the residual classifier, `--explain`, `--try` — the agents' scorer, per-function scratch,
|
||||
parallel-safe); `tools/delever_regen.py` (the read-only regen of newly harvested families over the whole residue, forked worker
|
||||
processes, `--bank`); `tools/delever_pack.py` (the agent packs: `neighbours.txt`, `related.txt`, `best_body.c`, `ORDER.tsv`);
|
||||
`tools/argcheck.py` + `tools/decl_repair.py` (S102: the lying call declarations — 16,759 repaired byte-identically across 3,439 units;
|
||||
K&R definitions read since S103); `tools/localalloc_sim.py` (c26's local-alloc simulator, promoted after 0 mismatches over 150 blocks;
|
||||
the three-quantity switch modelled at S104); `tools/alloc_table.py` (gcc's truncated integer priority, TIE flags); `tools/cc1_dumps_tu.sh`
|
||||
(`-dt -dJ -dd`, `-Isrc/shared`, takes a `.c`); `tools/lever_progress.py` + `docs/levers.md` + `docs/lever-progress.tsv` (the series, 78
|
||||
milestone rows, rendered as state transitions); `tools/readability_progress.py` + `docs/readability.md` + `docs/readability-progress.tsv`
|
||||
(the second Gen3 series); `tools/verbatim_check.py` (the in-function form, `--update` keeping order and UTF-8, `--strict` in tools-health).
|
||||
- **The tree.** `include/gte_inline.h` (50 GTE macros under Sony's names for what were 9,102 per-TU definitions; 8,951 deleted, 629 of
|
||||
699 `"memory"`-clobber variants proven byte-neutral and dropped, 70 kept as marked `_m` levers; 575 direct GTE statements as
|
||||
canonical calls); `config/verbatim_manifest.json` (49 rows: 27 PERMANENT-VERBATIM incl. the 22 per-overlay scratchpad stack-switch
|
||||
trampolines the file-scope detector never saw, 8 SDK-VERBATIM libgs renderers, 11 DECOMPILE-NOW, 3 UNCERTAIN — T1b's finding that "every
|
||||
game-code function is C" had been measured by file-scope instruments); **`src/`: 53,234 → 4,010 lever sites** — the survivors marked
|
||||
`// !FAKE: <kind> <detail> — <pass, file:line> (P36 <rung|agent>)`, 2,693 files' stale `@stuck:` header notes retagged `@unstuck(P36):`
|
||||
(30,138 notes, comment-only), 16,759 call declarations made honest, four `do { } while (0)` and dead-initialiser fakes marked per sotn's
|
||||
rule; the ledger `.run/P36/delever/ledger.jsonl` (one row per judgement, the rung, the calibration id, every site's verdict).
|
||||
- **The record.** Cookbook **§454** (rungs D/R: the instrument lessons — a disassembly is not a target), **§455** (rung G, the object-scored
|
||||
search), **§456** (S104's move catalog under ~205 levers), **§457** (S105's catalog: the loop family, cse's address fold, sched1's
|
||||
birthing boost in both directions, combine's narrow-load split, local-alloc arithmetic, the parameter shapes), §197-A superseded;
|
||||
`docs/decision-log.md` P36 S99 / S101 / S104 / S105; `docs/accelerators.md` P36 S99 / S101 / S105; `.run/P36/agents/METHOD_S103.md`
|
||||
(the agents' method, steps 1–25, every emitter and register-order move with its `file:line`); `docs/SETUP.md` P36 rows for every tool;
|
||||
the wiki (`Where-the-project-goes-next` item 2 + the table row) and the Gen3 charter pages date-stamped; `docs/tool-index.md` + the kit
|
||||
corpus regenerated; `config/kit_coverage_map.tsv` (the P36 accelerator entries dispositioned); 333 agent packs with `mechanism.md`.
|
||||
- **Evidence (`.run/P36/`, allowlisted text):** `baseline/` (every R22 log), `census/`, `probe/`, `delever/` (batch records, apply logs,
|
||||
the calibration), `permuter/`, `engine/` (run logs, outcomes, traces, `residual_moves.md` — lane B's 58-row residual → source-move map
|
||||
with its verification ledger), `regen/`, `s103/` `s104/` `s105/` (per-session R22 logs, bank lists, known-true candidates, the picker,
|
||||
the briefs, `attribution_check.py`, `unstrippable.json`, the tools-health logs), `agents/` (the packs).
|
||||
|
||||
**Tools/packages installed:** none external (no apt/pip). `tools/reference/sotn-decomp` shallow-cloned (ignored; X2 — data) at S104 to
|
||||
read Drew's four questions against its tree (R106).
|
||||
|
||||
**Verification results (literal, at close — S105, HEAD `db212f167`, tree clean):**
|
||||
- R22 from clean after the last `src/` change (`fe4a62420`, the comment-only retag): `extract-all: 217 extracted, 0 failed of 217 (+ main,
|
||||
serial)` · **`check-all: 218 passed, 0 failed of 218`** · `real 1m27.146s` · `exit=0` (`.run/P36/s105/r22_l.log`); every batch of the phase
|
||||
— 15 T4 batches, 3 T5 batches, every rung-D/R/G run, every agent bank — carried the same line.
|
||||
- **`lever_census --check: 4,010 pin/asm sites, 4,010 marked !FAKE, 0 UNMARKED — OK`** (exit 0; orphans 0; GTE levers 450 inside the
|
||||
number; `--strict` NOT claimed — by the S104 amendment "0 pins, 0 asm" is the structs phase's finish line). `verbatim_check --strict`:
|
||||
no drift (49 rows).
|
||||
- **`make tools-health: OK — sigs fresh; corpus(+resident) + cdecl + binaries + report(lint+dedup) + cookbook-index all green.`** (run 4,
|
||||
`.run/P36/s105/tools_health_t8d.log`; the new rung inside it; S1 10,180 / 10,180, 0 violations; sdk-dual OK; kit_coverage OK; runs 1–3
|
||||
were red on the day's own record — three Reference-index rows, one kit_lint LEAK, two undispositioned accelerator entries — each fixed).
|
||||
- **Attribution (milestone item 2):** `.run/P36/s105/attribution_check.py` → `4026 counted lever sites, 4026 attributed {rung B 2,620 ·
|
||||
S103 933 · T5 450 · S105 22 · S104 1}, 0 without an instrument` (measured at 4,026, before f11's last 16 rung-B sites came off).
|
||||
- Published (R75): README line 30 `Levers off (Phase 36, snapshot 2026-09-11): 2,141 register pins and 1,869 asm statements remain in
|
||||
1,980 functions (674 distinct bodies), 4,010 of them marked …`; `docs/progress.json` `counts.levers`; `docs/levers.md` (78 rows,
|
||||
`lever_progress --check: OK`); `docs/readability.md` (33 lying declarations left in 25 pinned bodies, from 461 in 314 at S102).
|
||||
- `delever --selftest: OK` · `lever_census --selftest: OK — 24 sites, 2 defs, 2 asm macros` · `share_census --selftest 7/7` · `doc_links
|
||||
--strict: OK` · `kit_lint: OK` · `kit_coverage: OK` · `tool_census --check: OK` · `cookbook-index OK (1,175 sections)`.
|
||||
- The headless Ghidra MCP was never used (no RE work) and was stopped cleanly at the S105 close ("Save succeeded", R23).
|
||||
|
||||
**Milestone achieved (gate 2 — Drew, 2026-09-11; each item with its literal output above):** (1) as AMENDED at S104 — every surviving
|
||||
register pin and asm statement outside the GTE header is marked, counted and named for the structs phase: `lever_census --check` 4,010 /
|
||||
4,010 / 0 UNMARKED, the counts published with the dated snapshot, the manifest unchanged; (2) the ledger names, for every site, the rung
|
||||
and the instrument that judged it — 4,026 of 4,026 attributed; (3) `check-all: 218 passed, 0 failed of 218` from clean, `make tools-health`
|
||||
OK with the new rung, the GTE macros in one header (314 per-TU asm macro definitions remain, each tied to a surviving marked lever or an
|
||||
`h_text` homonym — stated at T5's close, not zero); (4) the record written, this PhaseEnd, the DIGEST append, the log archived; v2.2.0.
|
||||
|
||||
**Next:** **Phase 37 — the structs phase** (Drew's Gen3 order; R95's canonical type layer is its core). Open a fresh session in **plan
|
||||
mode, Max** (Tier 1) from `docs/gen3-handoff.md` (item 4, the types doctrine) + `docs/gen3-standards.md`, with this phase's residue as its
|
||||
acceptance test: 4,010 sites = 1,548 drawable singletons (472 classes) + 691 in 24 parked classes (six signature changes with ready
|
||||
patches — func_800385C0, func_80029D3C, func_80180FA4, func_80180A54, func_80188DF4, func_80183CC4, func_801A1E94/func_801A5C44, func_80035210,
|
||||
func_800384A8, func_80188A30, func_8017FC5C/func_80180200, func_80185578, func_80157D20, func_80168828; the carve change func_80186CE0; the
|
||||
proven-irreducible heads func_8013CF68 ×134, func_80178970 ×127 + four same-shape families, func_8013F350's head) + ~1,150 minimum-lever
|
||||
survivors in five head classes (func_8013D9B0 ×125 — the `gte_stORGB` respelling question of T5; func_80177B5C, func_80140958, func_8012E364,
|
||||
func_8013F350) + 450 GTE clobber variants + 94 `$4`–`$7`-only pins (the missing-parameter shape, ~158 estimated across `src/`). d10's
|
||||
register-union proof (func_8017EF88), a18's `extern u16 X[]` close, f10's three type closes and f3's `s16[3]` finding are the phase's
|
||||
evidence FOR the struct hypothesis; `tools/argcheck.py` (98,648 lying declarations over 1,609 callees) and the raw-cast census
|
||||
(411,850 against 177,902 struct member reads) are its starting instruments. Inherited by name: the kit split, xsig v2, the §396(a)
|
||||
correction owed since S104 (the refuting body was not identified — R14), the 15 remaining UNSTRIPPABLE packs (one-off instructions,
|
||||
macro-carried and multi-output launders), a refusal-reason histogram for `delever_regen`, a "local vs global" column for `alloc_table`.
|
||||
|
||||
## Roadmap delta (what Phase 36 changed about the road ahead)
|
||||
|
||||
- **Gen3 item 2 is at its measured floor, and the floor has a shape.** The phase did not reach zero and says so: the last third of the
|
||||
residue is not a codegen problem the pin lane can read its way out of — it is wrong signatures (a `(void)` function that reads `$a0`, a
|
||||
`void` one that returns `$v0`), missing struct types (the compiler's own alias tests, `sched.c:837-863`, `expr.c:4568-4577`, decide by
|
||||
`MEM_IN_STRUCT_P`), carved data that a struct copy would address in one relocation, and one GTE macro spelling. Each is the structs phase's
|
||||
by construction, and the phase leaves it a list with patches, readings and byte proofs rather than a number.
|
||||
- **The doctrine is written where the next project starts:** `docs/levers.md` §5 — "ban the silence, not the lever": a lever is allowed only
|
||||
marked, ledgered and published from the first bank, with a one-compile bank-time trial ("does it still match without this?") that would
|
||||
have refused 37 % of this population while the context was hot; blanket prevention would have stalled Phase 18. The kit's DK entries and
|
||||
the wiki carry it.
|
||||
- **The compiler map grew by a catalog of moves with their passes** (§454–§457, METHOD steps 1–25): the loop family's biv law, cse's address
|
||||
fold and its inverse, sched1's birthing boost in both directions, combine's narrow-load split, local-alloc's arithmetic (`find_free_reg`'s
|
||||
lowest-free rule, `update_equiv_regs` doubling a constant's life, the three-quantity birth order), the call-signature class (a truncated
|
||||
declaration DELETES an instruction). Every entry names its `file:line` in gcc 2.7.2 and its byte witness.
|
||||
- **What the readability series now measures for the structs phase:** the struct debt (411,850 raw cast dereferences vs 177,902 struct
|
||||
member reads) and the declaration debt (98,648 lying declarations, 33 of them still in pinned bodies).
|
||||
- **Scale, honestly (R41):** the plan priced the mechanical floor at 3 sessions and called T7 "open-ended, to zero"; the phase took 9 sessions,
|
||||
575 commits, ~200 agent draws (S102 22, S103 56, S104 ~105, S105 11 TU batches of 4–7 classes) and roughly 15–20 M agent tokens across
|
||||
the three agent sessions (S105 measured ≈3.5 M for 56 classes). The mechanical rungs took 37 % of the sites for ~20 CPU-hours and no
|
||||
tokens; the search engine took another 6 % for ~5 CPU-hours and no tokens; the agents took the rest — and the closes per agent rose from
|
||||
1 (S102) to 4–7 (S104–S105) as the TU batch and the method file matured.
|
||||
|
||||
## Deviations
|
||||
|
||||
| Item | Plan (gate-1 plan) | Actual | Reason |
|
||||
|---|---|---|---|
|
||||
| The milestone | 0 register pins, 0 asm statements outside the GTE header (decision 2, "grind to zero") | **amended at S104 by Drew:** every surviving site marked, counted, attributed and named for the structs phase; 4,010 remain | S103/S104 read the head classes to proven irreducibility in plain C, and Drew's (c)/(d) rulings — read against sotn-decomp, which keeps `INCLUDE_ASM` stubs rather than pins — moved the unclosed sites to the structs phase |
|
||||
| T7's shape | Ultracode waves (Workflow fan-out), prompted | the Agent tool, one agent per residue class, then one per TU with 4–7 classes; caps 5 → 2 → 1 → none | Drew's rule "one agent at a time so the methodology is honed at each landing" (S101), then his cap retunes; a Workflow was never the right unit for a reading |
|
||||
| T6's permuter rung | the residue exemplars through the permuter, time-boxed | 5 of 16 closed (0.69 h); its two prior campaigns were the instrument (a disassembly is not a target, §454); rung R closed 134/134 of the class it found, then 0 of 300 on the residue | the permuter is a replication engine after a shape is known, not a discovery engine; the guided search (rung G) replaced it |
|
||||
| Sessions | mechanical floor 3; T7 open-ended | 9 (S97–S105) | T7 was 5 of the 9 |
|
||||
| The call-signature turn | not planned | `argcheck` + `decl_repair`: 16,759 lying declarations repaired byte-identically in 3,439 units (S102); R19/R25 generators | six independent agent cracks in one burst were the same class — a truncated declaration deletes an instruction the pin then faked |
|
||||
| The minimum-lever bank | not planned | the S103 pivot: the best honest plain-C body plus only the marked lever(s) it cannot do without, `allow_residue`, propagation deriving the allowance from the exemplar's markers | four 130-copy classes at 4–34 levers per copy became 1–2 |
|
||||
| The in-function verbatim form (T1b) | 5 PERMANENT file-scope rows | 49 manifest rows; 22 per-overlay trampolines + 8 SDK renderers + 11 DECOMPILE-NOW + 3 UNCERTAIN | the census's structural detector found what the file-scope detector never had (P9: the P32 "every game-code function is C" was blind to it) |
|
||||
| Rules | R100–R106 ratified at gate 1 | R100–R106 ratified; **eleven** candidates proposed below | the phase generated governance from its instrument failures, as every phase has |
|
||||
| The §396(a) correction | owed at T9 (S104) | **not written** — carried by name | the refuting body was not identified from the record; a correction needs its bytes (R14) |
|
||||
|
||||
## What we believed, what failed, and what we would do sooner (for the retrospective; the detail is in `docs/decision-log.md` P36)
|
||||
|
||||
- **Believed (gate 1):** the pins would come off mechanically, family-batched, because Phase 32's last four functions had. **The strip took
|
||||
37 % of the sites and freed 20 % of the bodies; the rest was 1,803 distinct shapes**, each a reading of a compiler pass. **Sooner:** the
|
||||
probe (T2) said exactly this on day one — price the residue by distinct SHAPES, never by bodies.
|
||||
- **Believed (S99–S100):** the permuter and a recipe sweep would discover shapes. **They replicate, they do not discover** (134/134 on a
|
||||
known shape, 0/300 on unknown ones); and two permuter campaigns had scored against a disassembly that was not a target (24 wrong words
|
||||
from `move` vs `or`). **Sooner:** a known-true case — the tree's own body must score 0 — before any campaign; the guided search with the
|
||||
object as the scorer.
|
||||
- **Believed (S101):** a wider search would close the head. **112,216 compiles bought 62 bodies**; the head needed readings. **Sooner:** the
|
||||
lane B map (the gcc source read for residual → move) before the wide search, and agents on the head from the first day of T7.
|
||||
- **Believed (S102, the night of three agents):** one agent at a time meant one agent, then a sweep, then the next. **It meant learning
|
||||
between landings, not an empty slot** — six of eight hours had no agent running. **Sooner:** Drew's rule as written at S102: the slot is
|
||||
refilled in seconds; sweeps never stand between two agents; one writer.
|
||||
- **Believed (S102–S104):** every `NO-CANDIDATE` was a property of the population. **R22 was refusing for three unrelated regex reasons for
|
||||
two sessions**, found only when agents closed by its own move and the generator was run on their start text. **Sooner:** a negative-
|
||||
control corpus per generator; refusal reasons as a histogram; the known-true run at every landing.
|
||||
- **Believed (S102):** the pins were codegen. **The biggest single class was a wrong DECLARATION** — a truncated `(void)` deletes an
|
||||
instruction the pin was hired to fake; 16,759 of them were repaired in an afternoon for zero bytes. **Sooner:** `argcheck` at Phase 17
|
||||
(the canonical type layer, R95) — the same lesson the S91-b hindsight recorded, now with a number.
|
||||
- **Believed (S104):** the residue could be ground to zero by more agents. **The residue's last third is signatures, structs, carves and one
|
||||
GTE spelling** — the structs phase's material; the drawable rest is singletons at ~3 sites each. **Sooner:** the bucketing that S105 did
|
||||
on Drew's "stalling?" question, done at every wave close as the stop-rule's input.
|
||||
- **Cost:** the phase's real expense was the agent sessions (S102–S105, ~15–20 M tokens for ~200 draws) and the coordinator's landing
|
||||
loop; the instruments were cheap and paid every day — a calibration line after every commit, a positive control in every scorer, a
|
||||
selftest with a known-true run in every generator. The mistakes that cost the most were each a scorer that read the wrong thing (a
|
||||
disassembly, another agent's object, a stale baseline) and each was caught by a check that read the artifact rather than the intent.
|
||||
|
||||
## Commit Message
|
||||
```
|
||||
(Phase 36 landed as 575 commits 63b886626..db212f167, 2026-09-09 → 2026-09-11 (S97–S105). This close = the archived log + this
|
||||
PhaseEnd + the DIGEST update + the kit's record copies, Drew's milestone-close commit, then the v2.2.0 tag.)
|
||||
|
||||
chore(phase-36): CLOSE — levers off to the measured floor: 53,234 → 4,010 register pins + asm statements (−92.5 %), every survivor
|
||||
marked with its pass and its instrument and named for the structs phase; the GTE idiom in one header; 16,759 lying call declarations
|
||||
repaired; the lever series and the readability series published; 218/218 at every step (v2.2.0)
|
||||
|
||||
- PhaseEnd_Phase36.md written; CURRENT_PHASE.md archived to phase-ends/logs/Phase36.md (R19); DIGEST §0/§2/§3 appended (step 3b)
|
||||
- T0–T10 across S97–S105: the census (T1/T1b, 49 verbatim rows), the oracle + probe (T2), the engine + cycle (T3), the mechanical
|
||||
campaign (T4, 15 batches, −36.8 %), the GTE header (T5), rungs R/D (T6), rung G + the agent lane at caps 5→2→1 (T7, ~200 draws,
|
||||
generators R15–R46, the call-signature turn, the minimum-lever pivot), the gate rung + attribution (T8), the record (T9)
|
||||
- close: check-all 218/218 from clean; lever_census --check 4,010 / 0 UNMARKED (exit 0); make tools-health OK (run 4); attribution
|
||||
4,026/4,026; tools-health, doc_links, kit_lint, kit_coverage, tool_census all OK
|
||||
- rules: R100–R106 ratified at gate 1; candidates (a)–(k) proposed for Phase 37 gate 1
|
||||
- v2.1.0 -> v2.2.0
|
||||
```
|
||||
|
||||
## Rules Added This Phase
|
||||
|
||||
**Ratified at gate 1 (2026-09-09):** **R100–R106** (the PhaseEnd_Phase35 candidates (a)–(g)); full text in `phase-ends/DIGEST.md` §3.
|
||||
|
||||
**Candidates recorded in the log, for Drew to accept, modify or reject at Phase 37 gate 1 (P10):**
|
||||
|
||||
| Rule | Reason |
|
||||
|---|---|
|
||||
| **(a) Ban the silence, not the lever:** a compiler-forcing construct is allowed in a banked body only marked, ledgered and published from the first bank, with a one-compile bank-time trial of the body without it. | `docs/levers.md` §5: 37 % of 53,234 sites came off with no understanding at all once tried; the levers propagated with every family remap (1,758 distinct bodies became 12,578) because nothing ever asked. |
|
||||
| **(b) A generator ships with a negative-control corpus of real bodies where it must fire, and a regen pass reports its refusal reasons as a histogram.** | R22 refused three ways for two sessions (`&&` as `&p`, the literal base, a cast store as a set); every `NO-CANDIDATE` had been read as a property of the population (accelerators P36 S105). |
|
||||
| **(c) At every landing, run every registered family on the agent's START text before banking** — a close by a move the registry claims is the cheapest instrument check in the loop. | It found all three R22 defects and banked shared headers IDENTICAL on 141 objects each. |
|
||||
| **(d) A scorer's target is the tree's own bytes compiled by the build's own tail, never a disassembly** — a known-true case (the tree's body scores 0) before any campaign. | Two permuter campaigns scored 28 for a byte-identical body: `objdump`'s `move` assembled as `or`, resolved `%hi/%lo` pairs (§454). |
|
||||
| **(e) Scratch is keyed by the unit of work, never by a worker tag or a file** (R48 extended). | Nine burst agents shared one scratch object and two scored candidates against another agent's function; the search's `g0.o` was keyed by a worker index. |
|
||||
| **(f) A gate's baseline is a snapshot, not the build directory** — a clean rebuild never runs where a live scorer reads `build/`. | `--try` scored against half-written objects during a fleet gate until `--snapshot-baseline` (S102). |
|
||||
| **(g) A lever's marker names its PASS and its INSTRUMENT** (R65 for markers), asserted by an attribution check at the close. | 4,026 of 4,026 sites attributed; the S103 minimum-lever markers and the T5 remark were the only way a later reader knows which compiler decision each survivor stands for. |
|
||||
| **(h) A ledger's "done" is per body (unit, function, after-hash), never by text alone.** | The T4 preflight drew 2,204 files where 2,583 were owed: every fleet-wide copy of an all-NEEDED exemplar passed as done by its text hash. |
|
||||
| **(i) A long unattended run is DETACHED with a progress log, never a harness background task** (R55 operated). | The harness's low-memory guard killed the batch cycle mid-apply and two 30-byte waiters with 22–27 GB free; a SIGKILL skips a restore. |
|
||||
| **(j) A marked ordinary-C fake (do-while, dead initialiser) is counted apart from levers and never an orphan; an invented condition, a dead store or a dummy reassignment is never banked.** | Drew's S104 ruling (a), read against sotn's `docs/STYLE.md`; a14/d20/c9/c13 refused on exactly this line. |
|
||||
| **(k) A "stalling?" question is answered with the residue bucketed by what each bucket needs before any plan is proposed.** | S105: 1,548 drawable singletons / 691 parked / ~1,150 proven / 450 GTE / 94 missing-parameter — the close decision took one message. |
|
||||
|
||||
*(Techniques stay in the cookbook §454–§457 and METHOD steps 1–25; strategy in `docs/decision-log.md` (R31) and `docs/accelerators.md`;
|
||||
the portable form is for the kit at its split.)*
|
||||
|
||||
## PhaseEnd Changelog
|
||||
**v2.1.0 → v2.2.0 — Phase 36 complete (Gen3's second phase).** The compiler-forcing constructs in the matched C — register pins, asm
|
||||
barriers, launders, keep-alives, hand-placed instructions, the GTE coprocessor idiom — were censused with a self-asserting instrument
|
||||
(53,234 sites in 15,679 bodies; 44 whole-body assembly routines inside C shells found on the way and put in the verbatim manifest), then
|
||||
taken off in a ladder that never changed a byte: a byte oracle on the build's own recipes, a mechanical strip (−37 %), one GTE header for
|
||||
9,102 per-TU macro definitions, recipes, a permuter rung, an object-scored guided search (−6 %, no tokens), and ~200 agent readings of gcc
|
||||
2.7.2's own source (one agent per class, then per translation unit) that closed 56 of 56 in the last session. 4,010 remain (−92.5 %), each
|
||||
marked with the pass that needs it and the instrument that judged it, and bucketed for the structs phase: wrong signatures with ready
|
||||
patches, missing struct types, a carve, one GTE spelling, and 1,548 singleton sites. On the way: 16,759 lying call declarations repaired
|
||||
byte-identically, the lever series and the readability series published, the generator registry R2–R46 with a known-true run for each, and
|
||||
the doctrine "ban the silence, not the lever" written for the next project's day one. R100–R106 ratified; eleven candidates proposed.
|
||||
|
||||
## Plain-English Recap
|
||||
When this decompilation reached 100 %, thousands of its functions still carried little hacks — instructions to the compiler that forced
|
||||
a particular register or ordering so the bytes would match — that a real programmer in 1998 never wrote. This phase counted them
|
||||
honestly (fifty-three thousand), then removed them in stages while re-checking every one of the 218 game files byte for byte after every
|
||||
step. A third came off just by asking the compiler "do you still produce the same bytes without this?". The rest needed understanding:
|
||||
first a search program that scores each candidate rewrite against the real object, then agents reading the compiler's own source code to
|
||||
find WHY the original bytes came out the way they did — a wrong function signature, a missing struct type, a loop written a different way
|
||||
— and spelling the C the way the original author plausibly had. About four thousand hacks remain, each now labelled with the exact
|
||||
compiler decision that needs it, and sorted by what would remove it. Most of those need the next phase's work — real struct types and
|
||||
correct function signatures — which is why the phase stops here rather than grinding on. The count over time is published as a chart, and
|
||||
the lesson for the next project is written down: allow such hacks only when they are marked and counted from the first day.
|
||||
|
||||
## 🛑 Stop Here
|
||||
PhaseEnd written; `CURRENT_PHASE.md` archived → `phase-ends/logs/Phase36.md` (R19, via `git mv`); `phase-ends/DIGEST.md` §0/§2/§3
|
||||
appended (step 3b); R100–R106 dispositioned in `config/kit_coverage_map.tsv` (kit_coverage OK); the timeline regenerated (76 rows, the
|
||||
P36 row); the kit's record corpus regenerated (`make kit-corpus`, `tool_census --check: OK`) — **all left uncommitted for Drew's milestone-close commit**
|
||||
(R6 gate-2 sign-off; the message is above). The Phase-36 work is committed across the sessions (`63b886626..db212f167`; not pushed). The
|
||||
headless Ghidra MCP is stopped (R23); nothing under `ghidra/` is tracked. **Drew, from the repository root:**
|
||||
|
||||
```
|
||||
git add -A phase-ends decomp-architect config/kit_coverage_map.tsv docs/story-timeline.md docs/story-timeline.svg
|
||||
git commit -m "chore(phase-36): CLOSE — levers off to the measured floor: 53,234 → 4,010 register pins + asm statements (−92.5 %), every survivor marked with its pass and its instrument and named for the structs phase; the GTE idiom in one header; 16,759 lying call declarations repaired; the lever and readability series published; 218/218 at every step (v2.2.0)"
|
||||
git tag -a v2.2.0 -m "v2.2.0 — Phase 36: levers off to the measured floor (53,234 → 4,010); 218 binaries byte-identical"
|
||||
git push origin main --tags
|
||||
```
|
||||
|
||||
Gen3 continues — do **NOT** start Phase 37 here. Start a **fresh session** (effort **Max**, **plan mode**) for **Phase 37 — the structs
|
||||
phase**, planning from `docs/gen3-handoff.md` and `docs/gen3-standards.md` with this PhaseEnd's residue list as the acceptance test. Keep
|
||||
this file forever.
|
||||
Reference in New Issue
Block a user