Commit Graph

11 Commits

Author SHA1 Message Date
Christopher Williams a38aa2603a phase9: recorded-negatives exclusion in sf3_triage (worker B, verified) + phase negatives index import
Worker B measured that recorded negatives cluster at the head of every
partition: 39 of the first 40 worklist rows and 57 of 271 tier-1 rows (21%)
were addresses an earlier session had already attempted and recorded. The
triage tool never read the negatives index, so every closed negative
returned to the queue head and workers rediscovered them.

Fix: sf3_triage reads the tracked config/near_match_negatives.tsv (a new
--negatives input) and excludes those rows as recorded_negative=69. The
tracked index was grown from 38 Phase-8 rows to 94 by importing 56 Phase-9
negatives from the workers' reports and the coordinator's absorption record
(filtered to unregistered; tracked rows win on conflict). Worklist
regenerated: the head is now genuinely fresh (0x800F9134, 0x80042D88,
0x800450C4, ...). 3 new synthetic tests; plan-level tests wired for the new
argument. The phase plan said extract negatives only at close; B's
measurement showed the harm is per-cycle, so the index is now a living
tracked input. Note for P9-T8: keep importing worker negatives each cycle.
2026-09-24 01:08:53 -04:00
Christopher Williams e523890b5f phase9: tracked worklist exclusions for the 0x80012A10 family and the maspsx-blocker row (0x8008A198) 2026-09-24 00:43:03 -04:00
Christopher Williams e7603dc531 phase9: merge cycle 2 progress — 246 regions / 237 distinct bodies
31 new regions merged and gated MATCH (whole-binary, SHA-1
e173426c157384ebf1b6caf8c6fea18a85a14af9), make check green
(regions=246 disagreements=0 AGREE, c_regions=246 MATCH).

Worker A took the tier-2 lead the rotation pointed at: 29 new framed
wrapper/call bodies incl. jalr-indirect rows, argument-swap wrappers, and a
statement-order-around-side-effect fix (0x800198C0). New levers recorded:
lui/lw symbol address arithmetic check (carry-adjusted %hi), named-local
ordering around a side-effect store.

Worker C closed two retry rows from the negatives index: 0x80036AD8
(commutative-operand-order, the 0x8002DEB4-class) and 0x800B5CB4 (deferred
--g_80122068 family hypothesis, using the gp symbols staged in cycle 1).

Worklist regenerated with the 0x80012A10-family exclusion (worker C
recommendation): --exclude 0x80012A10 --exclude 0x80012AE0, pool 1,666,
named exclusions 5; partitions re-proved disjoint (556/555/555).

Worker B rotated out (budget) with a clean handoff: 13 promoted claims, 18
negative entries in report.tsv, four named cheap closes for fresh context,
and a P9-T5 lead (trapping arithmetic in un-extented gaps, verified by the
coordinator: 275 gap words vs 661 in-extent words). No replacement session
available; the coordinator absorbs partition B per the plan's fallback.
2026-09-24 00:23:51 -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 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 673edb2ded phase6: add the symbol registry and per-region flag overrides, and register 0x8002D2A0 2026-09-23 20:54:10 -04:00
Christopher Williams defbf446eb phase5: cookbook, conventions, and verification record
P5-T6. Adds docs/MATCHING_COOKBOOK.md (nine byte-proven compiler/assembler
findings, each with basis and limit), docs/MATCHING_CONVENTIONS.md (what counts
as a match, registry format, source naming, duplicate sharing, symbols, the
verification procedure, the firewall) and docs/PHASE5_VERIFICATION.md (outcome,
clean gates, bounded negatives, milestone request).

Tooling: make test and make check targets; region objects are now
symbol-localized so the documented duplicate-sharing mechanism (N registry rows
-> 1 source) links, covered by a synthetic test (53 tests).

Clean gates: 53/53 tests; make clean/all/cmp/SHA-1 green; make gate with one C
region -> c_regions=1, 0 differing bytes, SHA-1 e173426c...; 57 tracked files, 0
under any prohibited root. Phase 5 is not closed until the milestone is
confirmed.
2026-09-23 20:43:33 -04:00
Christopher Williams f0237f1549 phase5: add the tracked matching harness and ordered-layout gate
P5-T4: tools/sf3_match provides range/plan/build/gate. It compiles a C candidate
with the identified toolchain (egcs-2.91.66 psx, -O2 -G0 -mno-split-addresses),
compares the exact instruction range byte-for-byte against the original, and
builds the address-ordered executable from the tracked registry config/regions.tsv
(header 0x800 + data gaps + C regions, LMA 0x800, metadata discarded).

Promotes the Phase 4 ordered workflow from an ignored experiment to tracked
tooling. Verified: make gate with an empty registry and with one real C region
both reproduce SHA-1 e173426c...; the Phase 3 baseline is unchanged and green;
the synthetic suite is now 50 tests including deliberate-corruption failures and
safe refusal of an existing destination. No ROM-derived material is tracked.
2026-09-23 20:32:11 -04:00
Christopher Williams 7b0879f8da phase3: add assembly baseline pipeline 2026-09-23 18:41:28 -04:00