Commit Graph

67 Commits

Author SHA1 Message Date
Christopher Williams da972a6fe2 phase9: ledger — cycle-4 363 bodies, rare-epilogue model confirmed, bad-claim isolation 2026-09-24 02:07:11 -04:00
Christopher Williams c738b97698 phase9: ledger — rare-epilogue consequence corrected (worker B falsified the skip; three-way model) 2026-09-24 02:04:04 -04:00
Christopher Williams 942beee61c phase9: ledger — rare-epilogue class census: 47 tier-2 rows (definitive) 2026-09-24 02:01:42 -04:00
Christopher Williams ce1e2f83fb phase9: ledger — cycle-4 352 bodies, F22/F23 findings 2026-09-24 01:58:05 -04:00
Christopher Williams 8300f855a5 phase9: ledger — cycle-4 349 bodies, gate-incident and F19 recurrences 2026-09-24 01:52:48 -04:00
Christopher Williams a23222dcfb phase9: ledger — hygiene catch (registry sources must be committed) 2026-09-24 01:47:03 -04:00
Christopher Williams 99626648b3 phase9: ledger — context rotation plan, maspsx limitation 2026-09-24 01:46:02 -04:00
Christopher Williams 523b901eb3 phase9: ledger — rare-epilogue census (16 sites, library band) 2026-09-24 01:40:23 -04:00
Christopher Williams e149ad1880 phase9: ledger — cycle-4 337 bodies at the tier-2 pivot 2026-09-24 01:35:10 -04:00
Christopher Williams 0a41a5ded6 phase9: ledger — cycle-4 tier-2 three-way volume 2026-09-24 01:31:38 -04:00
Christopher Williams 7f06726154 phase9: ledger — cycle-4 tier-2 pivot validated as the efficiency rule 2026-09-24 01:27:07 -04:00
Christopher Williams afa690aea4 phase9: ledger — cycle-4 two-matcher state, pool difficulty confirmed 2026-09-24 01:16:13 -04:00
Christopher Williams cca1d901be phase9: ledger — cycle-4 queue-fix effect and absorption negatives 2026-09-24 01:14:47 -04:00
Christopher Williams 91d6bb2b10 phase9: ledger — cycle-3 queue fix and absorption update 2026-09-24 01:10:50 -04:00
Christopher Williams aa92ed22ea phase9: ledger — ADDI class extension and empty call-shape slice 2026-09-24 01:05:12 -04:00
Christopher Williams 06121cd072 phase9: ledger — cycle 3 worker-B re-engagement, absorption negatives 2026-09-24 01:02:09 -04:00
Christopher Williams 85ae47d4a1 phase9: P9-T5 bounded investigation — route (a) closed, gap census + library-code evidence recorded 2026-09-24 00:46:59 -04:00
Christopher Williams 43201fa603 phase9: ledger — cycle-2 close, P9-T4 checkpoint crossed, all workers rotated 2026-09-24 00:44:15 -04:00
Christopher Williams 08a261d29e phase9: ledger — cycle 2 closed, full audit green, collision policy recorded 2026-09-24 00:26:58 -04:00
Christopher Williams 6e8c3df7a7 phase9: ledger — cycle 2 totals, P9-T5 gap-measurement verification, partition-B absorption 2026-09-24 00:24:06 -04:00
Christopher Williams ce75bee419 phase9: record worker B budget rotation; coordinator absorbs partition B 2026-09-24 00:21:33 -04:00
Christopher Williams 318e73ab75 phase9: record cycle 1 detail, GTE map correction, and negative census in the ledger 2026-09-24 00:16:17 -04:00
Christopher Williams 706c5455cd phase9: record cycle-1 dispatch numbers in the ledger 2026-09-23 23:54:31 -04:00
Christopher Williams 54af82aa95 phase9: ledger, delay-slot exclusion, and the promoted instruction-diff tool
P9-T1: create CURRENT_PHASE.md as the phase ledger; baseline revalidated
clean (cmp + SHA-1 e173426c157384ebf1b6caf8c6fea18a85a14af9, make check
regions=158 disagreements=0 c_regions=158 MATCH); three workers probed and
recruited (01a0d180-ea72/-efdd/-f513); 3-way partitions generated and proved
disjoint (3x575 rows, pairwise intersections 0, union == worklist).

P9-T2 (tooling half): promote worker B's scratch instruction diff into
tools/sf3_diff, hardened per the plan: PS-X LOAD read from the header,
objdump path derived from the repo, temp files under the caller's work dir,
resolver printing ready-to-paste symbol names. 17 synthetic tests.

sf3_triage: new counted exclusion excluded_delay_slot_start=5, implemented
after independent verification of worker B's finding (a branch/jump always
executes its delay slot, so no function starts at X+4; 0 of 158 registered
regions does). Worklist regenerated: 1725 eligible rows, tiers 355/1365/5.
3 new synthetic tests; existing triage fixture extended.
2026-09-23 23:52:58 -04:00
Christopher Williams 48dca3e271 phase9: add the worker-identification procedure to the plan
With four fresh sessions in one repository the coordinator must be able to tell
which peers are its workers without assuming: list the sessions in this cwd
excluding itself, probe each, recruit the responders up to three, never charter a
session that has not answered, and record the recruited ids in the ledger so a
later cycle or a replacement coordinator can tell who is who. This also covers the
case where an extra session (a planning session left open) is live in the repo.
2026-09-23 23:40:30 -04:00
Christopher Williams d9a43975d4 phase9: draft the scaled coordinated plan with a 500-body target
Developer goal: 500 distinct matched bodies (from 149, so >=351 new), run
unattended overnight by one coordinator and three workers.

The plan reuses the Phase 8 protocol verbatim - it is the contract that just
closed a successful phase - and adds only what scale requires: 3-way disjoint
partitions regenerated every cycle, an explicit autonomy loop the coordinator
repeats without developer input, planned worker rotation (a fresh session is a
fixed resource and one phase can consume one, with an absorb-it-yourself
fallback), and a verification ladder that gates every cycle and audits every
third.

The pool is measured and the risk is stated rather than assumed: 1730 eligible
candidates remain, but the easy tier-1 leaves are largely already matched, so the
phase works mostly tier-2 bodies where Phase 8 measured 5/12 in the 56-64 byte
band. 200-300 new bodies is the realistic band and 351 is the stretch, so the
target is staged at 180/230/290/400/500 with explicit stop conditions - including
"three consecutive cycles add fewer than 5 bodies" - so an unattended run cannot
spin without producing evidence. On any stop the registry must be green first.

One structural task: the trapping-arithmetic class, 50 bodies that no available
compiler emits and the best current lead on the unresolved library-versus-game
question. Its route (b) - a documented per-region transform - is flagged as a
developer convention decision, not the coordinator's to take.

Also records the coordinated workflow in the README's methodology section, which
is what the developer asked for.
2026-09-23 23:39:37 -04:00
Christopher Williams 2e7daf5329 phase8: close the phase with the verification milestone
Developer-confirmed milestone: 149 distinct byte-identical bodies across 158
registered regions, up from 34 / 39 at Phase 7 close - 115 new bodies against a
target of 70, produced by three sessions working one worktree under a written
protocol.

Adds PhaseEnd_Phase8.md and the digest entry, archives CURRENT_PHASE.md as
logs/Phase8.md, and completes docs/PHASE8_PROTOCOL.md with the retrospective the
developer asked for: which rules were load-bearing (worker/coordinator file
ownership, candidate-first merging, worklist regeneration, self-contained
charters), where the protocol needed a decision, the four failure modes seen with
their mitigations, and reusable CHARTER and worker-report templates so the next
coordinated phase does not pay the cost of writing them again.

Final gates: 203 tests; make clean, make all, cmp and SHA-1 e173426c...; make
check green at c_regions=158 with 0 differing bytes and regions=158
disagreements=0; registry audit 0 violations; no untracked file in src/; 244
tracked files, none under a prohibited root.
2026-09-23 23:36:58 -04:00
Christopher Williams ea6841d307 phase8: consolidate at 158 regions / 149 bodies and record the verification gate
All gates exit 0 from a clean state: make clean, make all, cmp, both files SHA-1
e173426c..., and make check (203 tests, regions=158 disagreements=0, c_regions=158,
0 differing bytes). The registry audit reports 0 violations across 158 ordered,
non-overlapping regions whose every extent is graded exact and whose every source
exists. The worklist regenerates with excluded_already_registered=158, equal to
the registry. 244 tracked files, none under a prohibited root, and no unmatched
draft survives in src/.

Phase 8 went from 34 distinct bodies / 39 regions to 149 / 158 against a target of
70, with three pi sessions working one worktree under a written protocol. Adds the
verification record, the open-negatives index (addresses, sizes, statuses and class
labels only - no bytes, no instruction text), and the README status.

Worker B's last act is recorded as a result rather than a footnote: it tested
worker A's mirrored-layout lever against its own two bounded negatives and
produced a decision rule instead of a match - the lever applies when the
instruction count is already correct and the block order is wrong, so where the
count is wrong and the order right it only trades one defect for another.
2026-09-23 23:32:20 -04:00
Christopher Williams 591923a32f phase8: exclude the trapping-arithmetic class and record the shape tells
Worker C found the strongest structural signal of the phase and asked me to act
on it rather than merely record it. I re-derived the census independently before
acting: 50 of the 1,937 exact extents contain trapping add/sub (funct 0x20/0x22,
410 instructions) and 0 of the 144 then-registered regions does. All four
unmatched duplicate groups are inside the class. Ten cc1 builds plus the real
CC1PSX 4.0-4.6 over ~30 C shapes and 15 flags never emit the trapping forms, and
-ftrapv is rejected by all of them.

tools/sf3_triage now detects the class and excludes it by default
(excluded_trapping_arith=50, --allow-trapping to list it), with three synthetic
tests, so no worker can spend budget on it by accident. Recorded as cookbook
finding 26 with the neg-macro clue that points at a macro-print-style difference
rather than a source difference. The class is now the best candidate for part of
the unresolved library-versus-game-code boundary - a hypothesis, not a claim.

Also recorded: worker A's maspsx load-delay defect (its predicate tests whether
the next instruction loads FROM the register, not whether it reads it at all, so
a load followed by a store of that register gets no delay nop), four mechanical
layout tells, and the struct-assignment lever for the base-in-register class.
Finding 22 is refined with worker C's third spelling: the written order of the +
operands decides the emitted addu order.

Cycle 5 merge: 65 claims, 8 accepted, 57 skipped, 0 rejected. Candidate gate
c_regions=152, 0 differing bytes; promoted; make check green at 203 tests.
Distinct matched bodies: 143.
2026-09-23 23:23:33 -04:00
Christopher Williams 18e784df39 phase8: record cycle 3, the SDK-shape verdict, and the worker negative results
Cycle 3 merged 22 claims (worker A's 8 new plus 9 gp rows, worker C's 6 pure-C
rows) at 137 regions / 128 distinct bodies, and closed every near-miss that
Phases 5-7 recorded in the reachable set: 0x800F3160, 0x800F8AEC, 0x800F8B58/6C,
0x800F8FE4, 0x80102B10 (maspsx=off), 0x800F7FB4 x3 (a cc1 loop-shape artifact),
0x8009E8D0 x2 (ordinary matching).

Worker C's SDK-shape investigation refuted its own premise: the COP2 shapes are
reachable, the blocker was never the missing SDK headers, and the stack accessor
needs no asm at all. The 8 COP2/syscall regions are parked pending the
developer's inline-asm convention decision.

Recorded as results, not footnotes: three rules that were tested and bounded. The
commutative-operand rule's direction is right but its trigger fails for a literal
base in a counted loop; the do/while loop rewrite does not transfer to
0x800FBF5C; and the reorg class is a cc1 reorder thread-fill decision that no
assembler can perform for a conditional branch, so it is a bounded negative
rather than a harness gap.
2026-09-23 23:16:08 -04:00
Christopher Williams e98aa102e4 phase8: rules check after P8-T4 2026-09-23 23:07:30 -04:00
Christopher Williams 270cb6201a phase8: record cycles 1-2 and the two harness mechanisms
Control record updated with both verified cycles, the two per-region overrides
that came out of worker findings (maspsx=off and gp=-NAME, with the byte evidence
for each of the six anomaly-class regions), and the coordinator findings: the
stale worklist caught before dispatch, the candidate-first merge that contained a
bad cycle, Ghidra's COP2 pseudo-op collapsing, and the two $gp thunk halves.

Also excludes 0x80108034 and 0x8010804C from the worklist: they are the two halves
of a $gp-switch thunk and are not matchable as C regions.

Milestone met at 109 distinct bodies (target 70).
2026-09-23 23:06:54 -04:00
Christopher Williams 5f07614247 phase8: open the control record, revalidate the baseline, and hand off to two workers
P8-T1 of the coordinated multi-session phase. Baseline re-run green: make clean,
make all, cmp, SHA-1 e173426c..., 168 synthetic tests, extents agreement 39/39,
and the ordered gate at c_regions=39 with 0 differing bytes. No tracked path
under a prohibited root.

Both peers were probed rather than assumed: 01a0d143 and 01a0d145 are live in
this repository at HEAD 42c9b1d with shell and a full tool set, but neither had
read the project docs, so both charters are self-contained. Hard rules were
restated with the probe: the tracked registries, build/ and all writing git
commands are coordinator-only, and only new src/*.c files inside a worker's own
partition may be created.

Before dispatching, the partitions were checked against config/regions.tsv and
the tracked worklist was found STALE -- it was generated in P7-T4 with only 12
regions registered, so it still listed 23 candidates Phase 7 later matched.
Regenerating it gives 1893 listed with 39 excluded as already registered, which
is exactly the 39 regions. Partitions are now 947/946 rows, disjoint
(intersection 0), union equal to the worklist. Worker B's charter was corrected
immediately because it quoted the old bounds.

The charters carry a standing safety net: a worker that finds a row already in
config/regions.tsv must skip it and report, because that means the file went
stale again.
2026-09-23 22:48:25 -04:00
Christopher Williams 42c9b1d9bc phase8: draft the coordinated multi-session plan
Phase 7 made matching possible at scale; Phase 8 makes it parallel. Three pi
sessions in one worktree, coordinated over pi-intercom: one coordinator that
dispatches charters, merges claims and independently verifies them, and two
workers that match concurrently.

The plan's centre of gravity is concurrency safety, because three sessions share
one worktree: src/*.c is partitioned disjointly so no two sessions can write the
same file, the tracked registries and build/ and git are coordinator-only, and
worker deliverables stage in ignored paths. The safety property is that a
worker's claim is never trusted -- the coordinator's own clean make gate over the
whole 1,886,208-byte executable is the only authority, so a fabricated match
breaks the SHA-1, and make extents-verify stops a hand-chosen end address.

Target: at least 70 distinct bodies (from 34), staged across three cycles so a
stall shows up early, plus one bounded investigation into the SDK-header shapes
Phase 7 deferred.

Draft, awaiting approval. Decisions flagged for the developer: this session
coordinates, workers match while the coordinator verifies, the two already-live
peers (01a0d143, 01a0d145) are probed rather than assumed, and the target size.
2026-09-23 22:42:52 -04:00
Christopher Williams 2f05e821fc phase7: close the phase with the verification milestone
Developer-confirmed milestone: 34 distinct byte-identical function bodies across
39 registered regions, up from 11 / 12 at Phase 6 close. Every region end is now
derived from control flow and enforced by make check, duplicate bodies are
censused, match targets come from a ranked worklist, and cross-references no
longer need hand-written symbol rows.

Adds PhaseEnd_Phase7.md and the digest entry, and archives CURRENT_PHASE.md as
logs/Phase7.md.

Final gates: 168 synthetic tests; make clean, make all, cmp and SHA-1
e173426c...; make check green at c_regions=39 with 0 differing bytes and
regions=39 disagreements=0. 121 tracked files, none under a prohibited root.
2026-09-23 22:40:26 -04:00
Christopher Williams 0e3ff39ea9 phase7: record the verification gate and the new conventions
Phase 7 closes the milestone: 34 distinct byte-identical bodies across 39
registered regions, up from 11 bodies / 12 regions at Phase 6 close, with every
region end derived from control flow instead of by hand.

New cookbook findings, each byte-proven:

- 13: a store-only function leaves its constant in v0 as scratch. Writing
  `return 1` costs an instruction in the delay slot (0x8003636C: 12 vs 16 bytes).
- 14: the gp-relative offsets proved so far, with the global each one names.
- 15: shapes plain C cannot reach without SDK headers (GTE/COP2 code, BIOS
  syscall wrappers, stack-pointer accessors).

Conventions updated: a region end comes from config/function_extents.tsv and is
enforced by make check; the duplicate check is the tracked census rather than a
manual search; the worklist is the ranked queue; and address-named symbols
resolve implicitly while anything else fails loudly.

Clean-state gates all exit 0: make clean, make all, cmp, both files SHA-1
e173426c..., and make check (168 tests, regions=39 disagreements=0,
c_regions=39, 0 differing bytes). 121 tracked files, none under a prohibited
root. Milestone confirmation requested before any PhaseEnd.
2026-09-23 22:37:16 -04:00
Christopher Williams 399da98a83 phase7: resolve address-named symbols implicitly and fail loudly otherwise
Every cross-reference used to need a hand-written config/symbols.tsv row, which
does not scale to a batch. A symbol whose name is an address now resolves to that
address with no row: func_XXXXXXXX, D_XXXXXXXX, g_XXXXXXXX, lbl_XXXXXXXX. This is
the convention the registry already used, applied without the row.

The names come from the object's own undefined-symbol list (nm -u), not from a
guess about the source, so a name the source defines but never references is
never mistaken for one needing resolution. A registry row still wins, which is
how a gp marker or a real name is attached. Anything neither registered nor
address-shaped now fails before the link with a message naming the symbol and the
fix, instead of a bare ld diagnostic.

First match from the worklist: func_800F8F9C (36 bytes, worklist rank 3), a
duplicate-group representative with a frame and a call. It matched on the first
attempt and is registered twice (0x800F8F9C, 0x80109314) against one source, so
two functions were matched for one body. Its callee needed no registry row.
Ghidra's independent body agrees with the derived extent.

make gate: c_regions=14, 0 differing bytes, SHA-1 e173426c. 168 synthetic tests.
2026-09-23 22:26:08 -04:00
Christopher Williams a6af8b3cd2 phase7: replace hand-picked targets with a ranked, reproducible worklist
Phase 6 chose match targets by eye from the boundary inventory. tools/sf3_triage
now ranks every eligible candidate by (tier, size, address) from tracked inputs
alone and records why everything else was excluded.

Eligibility: an exact or fallthrough extent, a non-degenerate body, not already
registered, not the header entry, not named by --exclude. indirect, escape,
outside, runaway, contained and standalone are excluded and counted.

Tiers: 0 duplicate-group representative (one match, several addresses), 1 exact
leaf (no cross-references, so no symbol rows), 2 exact non-leaf, 3 fallthrough.

Result: 1916 listed (tier 0: 9, tier 1: 509, tier 2: 1394, tier 3: 4), with 252
degenerate bodies, 88 low-confidence grades, 12 registered, 1 header entry and
2 named near-misses excluded. The nine tier-0 entries are the real duplicate
groups: matching those nine bodies registers 22 function addresses.

The two deferred near-misses are excluded by name in the Makefile so the
exclusion stays visible rather than buried in the tool. 160 synthetic tests pass.
2026-09-23 22:19:39 -04:00
Christopher Williams 2000cc4101 phase7: census duplicate bodies and expose a zero band of false positives
Matching conventions require a duplicate check before registering, because a
shared body is matched once and registered once per address. Phase 6 did that
check by hand and found one 12-byte pair. tools/sf3_dupes now hashes every
derived extent body and groups exact duplicates.

Results: 2284 extents, 65 multi-address groups, 2104 singletons. Only 10 groups
contain code (24 addresses, all exact-graded); 55 are all-zero bodies. The
hand-found pair 0x800262E0/0x800262EC is reproduced as g0002, which is the check
that the census measures what it claims. The largest real groups are 712 bytes
(0x8001084C/0x800189E8) and 436 bytes.

The zero groups are a real finding: 252 extents have all-zero bodies, 245 inside
the zero band 0x80147000..0x80170000. The cause is the inventory's jal grade,
which decodes every word as an instruction -- in a data region a word with
opcode 3 is graded as a call whose target lands in the zero band. The census
flags those groups rather than hiding them, and the worklist must exclude
degenerate bodies.

The census is tracked rather than ignored as the plan said, because it holds
addresses, sizes and grades only (the same class as the tracked inventory and
extents tables) and the worklist must be reproducible from tracked inputs. The
content hash is computed and never written.
2026-09-23 22:15:51 -04:00
Christopher Williams 6988ca96b0 phase7: derive evidence-graded function extents from control flow
Phase 6 graded function starts and left every end to be derived by hand. This
adds tools/sf3_extents, which explores all reachable control flow from each hard
start (jal/entry) and reports an extent plus how far it can be trusted.

Measured decisions, not stylistic ones:

- Soft starts are not walk boundaries. A body's second instruction can satisfy
  the prologue grade exactly (0x800152AC is lw v1,8(gp) / addiu sp,sp,-176, so
  0x800152B0 looks like a start). Enforcing soft boundaries stopped 155 of 416
  walks inside a real body.
- The walk is a full reachability computation, not a first-terminal search: a
  function whose paths return at different addresses must report the whole body.

Grades: exact 1940 (1666 packed, gap=0), fallthrough 256, indirect 73,
escape 15, contained 153, standalone 438; 63.8% of the payload covered.

Verification: all 12 registered regions reproduce exactly (make extents-verify,
now part of make check), 29 new synthetic tests (115 total), byte-identical
across two runs, and Ghidra's independent body for FUN_80017ad4 agrees. Two
defects were caught by writing the tests first and are recorded: reach had to be
an exclusive end, and a terminal j's delay slot must not continue linearly.

The table holds addresses, sizes, grades and site addresses only -- no bytes.
2026-09-23 22:12:31 -04:00
Christopher Williams 97ee078142 phase7: open the phase control record, revalidate the baseline, and triage the open items
Approved plan: phase-ends/Phase7_PLAN.md. Goal is scale -- evidence-graded
function extents and a duplicate-body census first, then a batch that takes the
project past thirty distinct byte-identical functions.

P7-T1 re-ran every entry gate green: 86 synthetic tests, clean make all with
cmp exit 0 and both files SHA-1 e173426c..., make gate at c_regions=12 with 0
differing bytes. No tracked path under a prohibited root.

Triage splits the Phase 6 open items into four class blockers (missing function
ends, unknown duplicate bodies, no candidate ranking, per-function symbol-row
cost) and the deferred or unresolved single items (0x8005DEF8, 0x800F3160, the
numeric -G, the CRT entry, library versus game code).

Also ignore .pi/, the agent harness's local task-log state, which was untracked
but not ignored.
2026-09-23 21:59:37 -04:00
Christopher Williams 6ca8ac1a3c phase6: close the phase with the verification milestone 2026-09-23 21:51:44 -04:00
Christopher Williams ce43b7b42b phase6: document the Ghidra-draft workflow and record the verification gate 2026-09-23 21:50:03 -04:00
Christopher Williams 2507994ac3 phase6: correct the compiler to PsyQ 4.0 (gcc-2.7.2-psx) and register the framed batch 2026-09-23 21:37:15 -04:00
Christopher Williams 8ece49c130 phase6: register the leaf/gp batch and record the framed-function blocker 2026-09-23 21:24:15 -04:00
Christopher Williams d951e49b1d phase6: add the evidence-graded function-boundary inventory 2026-09-23 21:12:54 -04:00
Christopher Williams d379b84ec3 phase6: reproduce a gp-relative function and record the small-data evidence 2026-09-23 21:09:07 -04:00
Christopher Williams 4688662cf4 phase6: wire maspsx and link-time symbols, resolving the ASPSX la form 2026-09-23 21:01:20 -04:00
Christopher Williams 673edb2ded phase6: add the symbol registry and per-region flag overrides, and register 0x8002D2A0 2026-09-23 20:54:10 -04:00
Christopher Williams 73e8cd9a2e phase6: open the phase control record and triage the open items 2026-09-23 20:48:15 -04:00