Commit Graph

6 Commits

Author SHA1 Message Date
Drew T 867f09221c feat(oracle): main gets its independent second oracle — contract §1.3 closed
The roadmap's completion contract requires both audit oracles green before any
100% claim on main, and main had none: audit-corpus covered overlays and
resident only, and R34 is explicit that the byte gate is a perfect CORRECTNESS
oracle and a NULL COVERAGE oracle — green whether a function was sliced right
or invented, because the .s pieces paste back either way.

sig_image gains multi-range signing, closing all three blockers
docs/second-oracle.md scoped:
  * the 0x800 PS-X EXE header -> --vram-base 0x8000F800 puts file offset 0 at
    vram, so the header falls below the first range
  * interleaved data + linked islands -> --segments derives 28 game-code ranges
    from the splat yaml's SEGMENT rows
  * one text range -> the signer loops ranges, bootstrapping INSIDE each, which
    is what stops the linear partition running through a data island and minting
    functions out of it (the detector manufacturing the class it detects)

INDEPENDENCE IS PRESERVED, NOT WORKED AROUND. Ranges come from segment TYPES,
never from splat's function boundaries; entries are still found by byte-derived
jal-closure. Seeding from splat's symbols would make every phantom look real —
the trap the design doc names. .run/sig.main.jsonl (the splat-SEEDED atlas sig)
is a different file and corpus.ORACLE_SIG keeps the audit off it.

RESULT: 986 functions signed. main audit = 0 PHANTOM, 0 TRUNCATED, 1 PAD-TAIL.
Fleet audit-corpus = 0 + 0, unchanged for resident and overlays.

NEW AUDIT CLASS, from the first real finding. func_80062144: splat .s 65 ins,
oracle 64 — the extra line is a nop one line BELOW endlabel. That is an
alignment pad the matching side already emits from C (§295; two S77 wave agents
did it on func_8005E13C and func_8005D538), not a mis-slice. Lumping it with
TRUNCATED would make the oracle's first finding look like a defect and bury the
class that is one.

COVERAGE ASSERTED both ways before trusting it (R32): all 30 game-code stubs
fall inside a range, and 0 of 199 addr-parseable LINKED stubs do.
2026-09-03 21:58:17 -06:00
Drew T 22eed7d78a feat(phase-31 T3): main enablement — sig-main at splat-true lengths + main streams
- sig_image: --seeds accepts '0xADDR NINS' (and jsonl nins); a seeded nins is
  authoritative ([addr, addr+4*nins), bypasses func_end whose heuristic mis-sliced
  3/40 main samples); R32 guard on seeded end > hi
- corpus: s_ins_count() factored from audit() (R33, one counter) + '--seed-ends'
  CLI emitting per-stub splat-true lengths
- make sig-main: 2,002 main stubs signed -> .run/sig.main.jsonl; FULL word
  cross-check 2,002/2,002 EXE slices == .s words (0 SLICE-SUSPECT; .s word field
  is byte-order hex, not LE — first checker draft misread 1,999 false suspects).
  Deliberately splat-SEEDED; main's independent second oracle stays deferred
  (second-oracle.md; sig_is_independent(main) stays False)
- family_remap: vram_of/img_path special-case 'main' derived from splat.us.exe.yaml
  (file0-vram = code-seg vram - start = 0x8000F800; target_path); stream_words
  ('main') verified 25/25 vs .s
- regression: sig-resident re-run byte-identical after the shared read_seeds change
- SETUP §6.3 rows (R21)
2026-08-14 17:48:51 -06:00
Drew T 41e454ec1f chore(phase-25): T0 — refresh sigs/surveys, regen worklist+backlog, fix sig_image h_norm doc
- housekeeping: deleted stale root gccdump.lreg (gcc default -da RTL dump, dumpbase
  "gccdump"; a one-off RTL-inspection run at root CWD, NOT a committed tool). Practice:
  RTL dumps go to a .run/ CWD or -dumpbase .run/gccdump (R12)
- make sig-overlays (134 sigs); worklist.py --refresh -> build_fuel_manifest + backlog
  render: docs/worklist.md + docs/backlog.md regenerated (stale Jun-26 ranking killed;
  the banked whale func_80144B9C dropped from backlog, P9)
- fix tools/sig_image.py docstring: h_norm is the live norm_stream normalizer, not a
  "T5 placeholder" (R21/R30)
- CURRENT_PHASE.md: Phase-25 plan-of-record + T0 frontier survey (R14): h_norm 2,764
  multi-member families / 11.1 MB; 46% of large solo monsters (3,989/8,670) are family
  members; reach-134 h_exact warm-up = 130 classes / 4.11 MB
2026-07-08 01:02:58 -06:00
Drew T f672c709c1 feat(phase-11): T6 — sign the 134 overlays; cross-report spans 136 binaries (milestone report half)
- sig_image overlay discovery: linear partition (split contiguous code at jr+delay boundaries) +
  detect_code_end (first run of invalid instrs = the code->data transition; overlay code decodes
  ~100% valid, data drops to 43-95%). BFS dead-ended — overlays dispatch via function-pointer
  tables, not jal — so call-graph BFS found ~2 fns; linear partition recovers the whole code prefix
- Makefile: sig-overlays: signed 134 overlays -> .run/sig.ov_*.jsonl signs all 134 SCxx 0.4.dec @ 0x80128158 -> .run/sig.ov_*.jsonl (27s)
- dup_report --cross: ingest the overlay sigs (sig.ov_* convention) + main/resident; condensed
  source header (overlay set-sha for reproducibility); cap top-200 per subsection + state totals;
  compact member sample + #bin column
- RESULT (docs/duplicates.cross.md): h_exact 9366 cross-binary groups / 28.5 MB collapsible; h_norm
  8957 / 38.3 MB. Top group = a 770-instruction function BYTE-IDENTICAL in all 134 overlays (one
  match credits the whole fleet) — 'one match unlocks many' quantified; the Phase-12/13 work queue
- dedup-check green; committed per-binary digests byte-stable; report deterministic (sorted glob,
  no Date/random); the EXE<->resident pair still shares nothing (overlay<->overlay dominates)
2026-06-16 01:26:49 -06:00
Drew T 81e33c7a1e feat(phase-11): T5 — sig_image self-consistent h_norm + h_seq (scope-guard D2)
- norm_stream(): mask address-sensitive fields so structurally-identical functions at different
  addresses normalize equal — j/jal 26-bit targets, lui highs, and hi/lo-paired I-type address-los
  (a consistent lui->reg pending-hi tracker); KEEP registers, true constants, PC-relative branch
  offsets. h_seq = mnemonic sequence. Self-consistent within sig_image (the overlay fleet).
- validated on the resident vs the Ghidra oracle: h_exact equivalence classes 6/6 == Ghidra;
  h_norm reproduces 7/9 Ghidra structural groups — the 2 disagreements are BENIGN (differ only in
  masked address-low / jump targets; Ghidra's own reference analysis is inconsistent there). Any
  h_norm candidate is byte-gated (its sole acceptance, per the roadmap).
- DEVIATION D2: self-consistent h_norm, NOT a Ghidra-byte-exact normToken replica. Byte-reality
  makes cross-tool structural matching low-value (EXE<->resident share nothing; overlays share with
  each other via h_exact at the same vram, and CALL not embed the resident). h_exact is the
  format-independent cross-tool workhorse; full normToken replica is a documented future refinement.
  Scope-guard pre-approved in the plan.
2026-06-16 01:15:07 -06:00
Drew T 685e35fdc6 feat(phase-11): T4 — sig_image.py, Ghidra-free h_exact signer + boundary detection
- tools/sig_image.py: linear rabbitizer disassembler that signs a flat image (overlay 0.4.dec /
  resident 1.1) at a vram base, JSONL field-identical to DumpFunctionSignatures.java. h_exact =
  SHA1 of raw bytes (format-independent — the cross-binary workhorse; overlays share the same vram
  so same-offset dups are byte-identical). Seeded + jal-closure bootstrap entry discovery.
- boundary rule: a function ends at the first 'jr $ra'(+delay) at/after every forward branch/jump
  target — handles early-return jr AND ignores the trailing orphan jr;nop (double-epilogue)
- VALIDATED vs the resident Ghidra oracle: 100% h_exact on the contiguous/non-GTE subset (140/140),
  ZERO UNEXPLAINED (whenever nbytes agrees, h_exact agrees) — the byte pipeline is exact; 98.6%
  overall. The 2 misses are non-contiguous Ghidra bodies (D5, inherent to a linear sweep)
- h_norm/h_seq emitted as conservative placeholders (= h_exact -> zero false structural matches)
  until T5 calibrates the normToken/mnemonic replica; overlays aren't signed until T6 (post-T5)
2026-06-16 01:07:28 -06:00