mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 22:45:39 -04:00
85fb289db582d842fc41dc059fa187bb992e76ea
1933 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9351b17f48 |
feat(phase-30 S46-2): the master IDXTAB/DESTPTR load map — and the tracker blind spot that hid it
Drew's S45 idea, delivered fleet-wide + wired into the permanent references.
- THE BLOCKER WAS OUR INSTRUMENT (R35, the 3rd time): the S45 plan ("require a
register-verified reference to the run's address") returns ZERO for both byte-proved
tables. They are read by gcc's indexed global-array form —
lui $at,0x8019 ; addu $at,$at,$a0 ; lh $v0,-0x2844($at) -> 0x8018D7BC
— where the address exists only as (lui imm, LOAD offset) with the index add between.
find_addr_refs killed the lui register at the addu, so the halves never rejoined and
the tables looked unreachable. Now it carries the hi half through the index add (still
strictly register-tracked, never window-paired) and labels those hits `-indexed`.
- tools/idxtab_map.py (NEW): fleet-wide payload -> owning binary -> load address.
Controls-gated (refuses to emit unless ov_SC01_000 0x8017EEC8/37 + *0x801A3234, and
ov_SC03_001 0x8018D7BC/5 + *0x801EBC68 reproduce from the images alone). Index space
DERIVED from the extracted tree (reproduces §S44's table independently). Process-pooled.
Rejects all-zero and majority-zero runs (132 of the first pass's 452 "tables" were that).
- RESULT: 213 binaries -> 143 with a referenced table (294), 141 with a DESTPTR (141/141
resolved from the binary's OWN image), 61 payloads. The two dominant tables are
fleet-wide CONSTANTS (5-entry and 37-entry, identical in all 141 overlays); the
per-binary variable is the destination (134 distinct).
- CORRECTION 1 (R14): §S45 p6's "the SC03 trio are owned by ov_SC03_001" is refuted —
that 5-entry table is identical in ALL 141 overlays. The byte-observed parts stand.
- CORRECTION 2 (P9): this route CANNOT settle MAIN/7+9. They are absent from all 294
tables — but so are MAIN/13/20/34/42/44, which are byte-proved to load. Absence here
means "not on this route", nothing more. Recorded so it is not re-derived as a finding.
- Confidence is stated per-claim in docs/idxtab-map.md: proven (controls) / high (283
fleet-wide-class tables) / low (3 named rare rows) / UNMEASURED (recall — no oracle
for "all tables" exists beyond the 2 controls).
- Wired in permanently: docs/idxtab-map.md (the how/when/limits), memory-map.md §S46,
cookbook §155c (the generalizable law: "no code references X" is a claim about your
DECODER until it is shown to recognise the forms the compiler emits), SETUP.md
tooling inventory (R21).
|
||
|
|
91c64ce92c |
fix(phase-30 S46-1): dedup_propagate — no silent skips, no unproven REVERTs
The S45p9 blocker: `[FAIL] ov_MAIN_012: 0x80156600 not instantiated — REVERTED`
92 minutes into a --auto-from run, naming no mechanism.
- FIRST, the honest finding (R14/R35): it does NOT reproduce at HEAD. A replay of
apply_plan's per-file site resolution over the exact 30-fn plan resolves
0x80156600 as a stub at line 7505, and def-range/stub-line overlaps = 0 (the
splice-swallow hypothesis refuted). The failing input state was not the committed
tree — most likely a concurrent writer mid-run. So this commit does not "fix" that
run; it makes the next occurrence name itself.
- SILENT SKIP -> LOUD (R32): an address resolving as neither the sp-regex stub nor a
def just stayed in `remaining`. apply_plan now records gaps={ov:[addrs]} and the
caller fails FIRST with a per-site diagnosis (whole-overlay find_site verdict,
in-sig, file list) instead of struct_check's terse late message.
- CAPABILITY GAP that produces exactly that skip: find_site returning 'stub' was
ignored (apply_plan acted only on 'def'), so a stub whose INCLUDE_ASM asm-subdir
!= its file stem was invisible to the stem-anchored sp regex AND unhandled. Now
placed ('macro' treated as already-placed). find_site's stub match is an exact
stub_line(ov,addr) compare against THIS file's text — it cannot cross files/TUs.
- INCOMPLETE REVERT (the §156 class, different path): struct_check restored only
`touched`, leaking every kept Part-B reconcile. New _abort() undoes touched AND
every kept reconcile, then diffs the worktree against a start-of-run baseline and
reports any residue. A tree dirty in a way nobody knows about makes every later
byte-gate report `near` — that is how S45p7 lost two batches.
- NEGATIVE CONTROL: neuter ov_MAIN_012's stub -> [GAP] fires naming the exact
condition (find_site=None, in-sig=True) -> "[revert] tree restored to baseline;
no residue" -> exit 1 (fail-closed). Restore -> tree clean.
|
||
|
|
5c61e00199 |
chore(phase-30 S45p9): track the two irreplaceable live load-maps
.run/attract_loadmap.jsonl (304s full attract cycle) and .run/sc03_hunt_loadmap.jsonl (the SC03 hunt + boot chains) are LIVE CAPTURES — not regenerable without another emulator session — so they fall under the R20/P27 curated-.run policy (irreplaceable recon tracked, regenerable bulk ignored). They are the evidence base for: - MAIN/7 + MAIN/9 absent across a complete attract cycle (the dead-code case) - the 7 routing-table addresses confirmed live (the R34 second oracle for S44) - the 0x801EF468 script-slot observation that cracked the SC03 trio docs/memory-map.md cites attract_loadmap.jsonl by name, so leaving it untracked would have left a doc pointing at a file a fresh clone does not have. Caught by Drew asking 'and you checkpointed everything?' -- my earlier git add had 2>/dev/null on it, which silenced the gitignore rejection. A silenced add is a silent skip (R32). |
||
|
|
e86e45320a |
chore(phase-30 S45p9): session close — 32-way parallel gate in dedup_propagate; banking deferred on a tool bug
PARALLEL GATE (landed, verdict-proven): dedup_propagate's byte-gate loop was serial --
one `make build BINARY=<ov>` at a time over up to 141 members per function. Measured: a
propagation ran 95 minutes at load 1.6 on a 32-core box (~5% utilisation). The Makefile
has parallelised extract-all/check-all since Phase 26 (xargs -P$(JOBS)), but this tool
predates that and drives the SINGLE-binary target from Python, so it never saw any of it.
- new gate_all(): ThreadPoolExecutor over distinct overlays, 32-way by default (JOBS env
overrides; deliberately NOT capped at the Makefile's conservative 16).
- SAFE by the same argument check-all relies on: byte_gate only runs `make build`, writing
solely to per-binary-disjoint build/<bin>/**; it mutates no source. Splice happens before,
restore after -- only the VERIFICATION is parallel.
- DETERMINISTIC: ThreadPoolExecutor.map preserves order, so the reported first failure is
the first in `changed` order -- identical verdict to the serial loop. Control run: same
verdict on a clean tree.
- Measured and NOT optimised: setup (sig load + registered_addrs) is 8.6s of a 5,700s run
= 0.15%. All the time is gating. Don't thread the setup.
BANKING DEFERRED on a genuine pre-existing tool bug (NOT the parallel change -- 0 gate
batches ran, it never reached that code):
[FAIL] ov_MAIN_012: 0x80156600 not instantiated -- REVERTED
Inputs verified sound at HEAD (in sig, find_site->stub, stub line matches), so the bug is
in apply_plan's multi-function edit path. Run #1 missed it because it launched before the
15 wave-3 banks were committed; they landed mid-flight, enlarging run #2's plan.
SECOND DEFECT: the failure exit printed REVERTED but left 38 files dirty incl.
src/shared/engine_core.h -- the same incomplete-restore class as the reconcile-ledger bug
(cookbook 156), on a different path. struct_check needs the same ledger treatment.
Not patching the fleet-shared writer at the end of a marathon session -- that is how the
next 141-binary incident happens. Tree clean, 44 banks safe, propagation is pure
multiplication and can run any time.
Checkpoint p9 carries: the fix-then-resume plan, the master-IDXTAB-map design (DESTPTR half
proven 14/14), wave guidance, and an 8-item error ledger with its single root cause.
|
||
|
|
97adcee709 |
chore(phase-30 S45p8): checkpoint — SC03 trio solved; Stage 1+2 landed; master-IDXTAB-map queued
- SC03/53/54/56 SOLVED: live script modules owned by ov_SC03_001 (IDXTAB @0x8018D7BC = 224/231/232/234/233) loaded via func_80128CFC into *DESTPTR 0x801EBC68 = 0x801EF468. Load BASE not yet proved — the byte-gate arbitrates on onboarding. - NEXT SESSION OPENER: the master IDXTAB map (Drew's idea). Feasibility PROVEN — the DESTPTR half extracted 14/14 sampled overlays first try and reproduces S44's one documented case exactly. Only the IDXTAB discriminator remains (require a register-verified code reference to the table address; validate against 2 known tables). - Carries the dirty-tree recovery procedure: a propagation was in flight at checkpoint. - 7 self-corrections logged with their single root cause, as a T5 rule candidate. |
||
|
|
537bd90a9a |
feat(phase-30 S45p6): SOLVED — the SC03 trio are ov_SC03_001's script modules (static decode)
Found the IDXTAB: ov_SC03_001 @0x8018D7BC holds 5 s16 entries, -1 terminated:
224, 231, 232, 234, 233 — i.e. the ENTIRE parked trio (SC03/53/54/56) plus its DATA
companion (SC03/55 = 233), in one table, in the binary whose *DESTPTR points at the
script-module slot the tracer watched load live an hour earlier.
THE CHAIN (every link register-verified or byte-observed):
ov_SC03_001 IDXTAB @0x8018D7BC -> indices 231/232/234 (+233 data, +224)
func_80128CFC (the S44 wrapper) -> cdFileLocTable[idx] -> {loc,size}
register-tracked: addiu->0x800AE830, lw[0x800AE834] size, lw[0x800AE830] loc
*DESTPTR @0x801EBC68 = 0x801EF468 -> the script slot
the ONLY occurrence of that word fleet-wide; read 8x by code, 2x from inside func_80128CFC
slot confirmed LIVE by tools/cdtrace.py: SC03/76 and SC03/34 both loaded there
and 0x801EF468 lies inside SC03/54's independently-derived base window [0x801EDED0..0x801EF6C8]
VERDICT: LIVE script modules owned by ov_SC03_001. Not dead code, not boss-gated, not
chapter-gated (that framing retired — scripts swap per SCENE). Every sweep missed them
because the SC03 scenes we visited run DIFFERENT overlays (124/125/051).
WHY THE EARLIER HUNTS COULD NOT WORK: the index never appears in CODE — it lives in a
per-overlay DATA table, and so does the destination. Both invisible to fleet-wide code
scans. That is the structural reason four value-scans and three payload-side oracles failed.
NOT PROVED: the exact load BASE within the slot (the three differ in size; none observed
loading). The byte-gate arbitrates — onboard at 0x801EF468 and let the first build decide.
New tool: tools/find_addr_refs.py — register-tracked absolute-address search (cookbook 155:
no window-pairing), self-tested against cdFileLocTable, with a STRICT addu-index rule
(full-address match, not page match — 342 loose hits -> 7 real ones).
METHOD: a runtime observation supplied ONE constant, and that made a previously-impossible
static decode trivial. Neither alone sufficed. Pair the oracles, don't choose between them.
|
||
|
|
de02dc750c |
feat(phase-30 S45p6): tools/cdtrace.py — a runtime CD-load oracle; 7 routing-table addresses confirmed live
Three static oracles failed to derive the parked payloads' load addresses this session. The runtime answer needed NO breakpoints, no Lua (no pcsx.lua wedge hazard) and no GDB stub: the loader mirrors its whole request in RAM (cdReq_curSector / cdReq_dest), and CdReadRequest's own MATCHED signature says cdlFile points INTO cdFileLocTable -- so (ptr-0x800AE830)/8 is the global file index and cdReq_dest is the destination. Both readable from the RAM-dump API we already had working. VALIDATED FIRST (R35): cdFileLocTable's live sizes reproduce our extractor's file sizes exactly for all five parked payloads. Then confirmed 7x against independently byte-proved addresses -- loadDestPtrTable slots [0]/[1]/[3], MAIN/10 (Phase-3 resident), MAIN/3 (S45-p2 md_MAIN_003), MAIN/12 (the resident's func_800CF94C row), and the LIST.CD bootstrap read from matched C. This is the R34 second oracle for the whole S44 routing table, which was static-only until now. FINDING: the script-module slot 0x801EF468 is live and GENERAL. SC03/76 AND SC03/34 both load there; 34 is outside the SC03/73-79 block, so S45's "chapter-2 period" label described one tenant, not the slot -- scripts swap PER SCENE. PRE-REGISTERED HYPOTHESIS (written before the test, kept honest): slot CONFIRMED (it lies inside SC03/54's independently-derived base window); "chapter-gated" WEAKENED (per-scene, not per-chapter); trio 0 sightings across 38 load events, 2 saves, multiple SC03 scenes. NEXT (static, no emulator): 0x801EF468 is now a concrete anchor. Register-track the code that loads into it and decode its scene->script-index SELECTOR -- answers all three at once instead of sweeping rooms. The correctly-scoped successor to the four refuted value-scans. Also lands the attract-cycle load map (.run/attract_loadmap.jsonl): MAIN/7 + MAIN/9 absent across a complete 304s cycle. |
||
|
|
bac3155abc |
fix(phase-30 S45p7): wave_snapshot must carry the GENERATED includes too
I claimed the .s snapshot alone fully decoupled a drafting wave from `make clean`. CHECKED — it does not. match_one does not merely compile: it ASSEMBLES (AS with -Iinclude, match_one.py:59), and the assembly step needs splat's generated include/macro.inc, labels.inc, gte_macros.inc and include_asm.h. `make clean` deletes all four. The gap was worse than a plain missing file: a wave would survive the clean right up until an agent hit a macro-using (e.g. GTE) function, then fail in a way that reads as a BAD DRAFT rather than a missing include — a phantom wall booked into the backlog. Snapshot now copies the whole include/ root (6 files; common.h and psyq/ are tracked and would survive anyway, copied so the snapshot is a self-contained -Iinclude root), and asserts the four generated ones are present, warning loudly if not (R32 — a half-populated include root must announce itself, not fail later as someone else's bug). Verified: all 4 present in a fresh snapshot; exit 0. |
||
|
|
fe399b4550 |
feat(phase-30 S45p7): Stage 2 — verify_worktree, a COMMIT-COMPLETENESS checker (not a concurrency device)
tools/verify_worktree.py: check a commit out into its own git worktree, provision the
untracked build deps (cc1 from the COMMITTED tarball, checksum-verified against the
COMMITTED record; .venv + extracted/ symlinked; maspsx submodule at the expected pin),
run make extract-all && check-all there, write .run/verify/<sha>.json with verdict +
toolchain provenance.
RESULTS
GREEN at HEAD: 213 passed / 0 failed, 86.6s wall.
NEGATIVE CONTROL PASSES: a throwaway commit splicing a deliberately corrupted body over
func_8014CBE8 went RED naming exactly ov_SC02_037 (212/1 of 213). The detector fires, so
its green means something (R35 — an unproven detector's green is not evidence).
TWO DESIGN CLAIMS CORRECTED BY CONTACT WITH REALITY
1. Sparse checkout (to save ~1GB of ghidra/) was proposed, and would have owed an R34
sparse-vs-full validation. Measured free space: 941 GB. Full checkout instead —
simpler AND strictly more trustworthy; the validation obligation disappears.
2. "A pristine checkout of exactly C's tracked content rebuilds byte-identical" is NOT
ACHIEVABLE here. Only 3 files under extracted/ are tracked; the 760MB of ROM payloads
are gitignored, so a pristine checkout extracts NOTHING (first honest run: 212/212
FAIL). No commit in this repo is self-sufficient, by design. The honest claim is
"the commit's TRACKED SOURCE, built against a supplied extraction" — corrected in the
docstring AND in the emitted `licenses` string, which is what actually gets quoted.
SCOPE, REFRAMED (Drew's challenge, and he was right)
I sold this partly on concurrency. At 86.6s, serializing R22 costs almost nothing, so the
concurrency argument is WEAK. What it actually buys is commit-completeness: the worktree's
src/ holds only committed content, so a source file someone forgot to `git add` fails BY
CONSTRUCTION — the documented "a clone of such a bank commit failed to build" class.
=> Run it at checkpoints and before pushing, NOT every batch. Plain in-tree check-all is
fine for routine verification.
=> The wave-vs-`make clean` blocker that started all this was already solved, more simply,
by tools/wave_snapshot.py. Neither the worktree nor path-parameterizing was needed for it.
=> STAGE 5 (verify coalescing / auto-bisect) IS CANCELLED: it existed to handle verify
lagging commits, which cannot happen at 87 seconds.
|
||
|
|
e0eaa16741 |
feat(phase-30 S45p7): Stage 1 complete — shared-state RW lock + 15 more banks (wave-3 revived)
STAGE 1 of docs/concurrency-design.md, landed and negative-control proven.
tools/shared_lock.py (NEW) — one reader/writer flock over the FLEET-SHARED state
(src/shared/*, config/overlays.mk, config/dedup.us.yaml, the overlay .c files
propagation rewrites). Per-binary resources keep gate_stage's existing per-binary flock.
- gate_stage takes it SHARED when the gate writes no shared state, EXCLUSIVE when it
does (propagate, or the arity pre-pass enabled) -- so distinct-binary gates still run
concurrently but can never overlap a writer.
- dedup_propagate and fix_arity_callers --apply take it EXCLUSIVE.
- NESTING-AWARE: gate_stage SPAWNS both writers, so a naive child lock would deadlock
against the parent. The holder exports BFM_SHARED_LOCK_HELD and children inherit.
NEGATIVE CONTROLS (all pass):
NC1 a held SHARED lock refuses a non-blocking exclusive writer, loudly, naming the lock
NC2 parent-holds/child-inherits does NOT deadlock (the real risk in this design)
NC3 two readers acquire concurrently (0.00s) -- phase-B parallelism preserved
bulk_harvest docstring CORRECTED: its "propagation is the ONLY writer of the shared
engine_core.h" claim was FALSE as written and had been asserted for phases (F1 -- the
arity pre-pass writes it from inside every worker). Now states what is actually true,
under which two conditions, plus the one-line assertion that detects a violation.
BANKS: wave-3's drafts re-gated on a CLEAN tree -> 15 of 20 banked. The same drafts
previously reported 0 banked / 20 near -- that verdict was 100% an artifact of the
broken tree, which is why they were held as UNJUDGED rather than accepted as failures.
check-all 213 passed / 0 failed. F1 bracketing assertion CLEAN.
Session total banked: 44 functions + func_8015C030 propagated x7.
|
||
|
|
a0236b2220 |
docs(phase-30 S45p7): correct the F1 misattribution — the cause was an orphaned reconcile
R14 correction to cookbook 156 + checkpoint p7. I blamed gate_stage's arity pre-pass (F1) for the 141/213 breakage. That was wrong: no arity journal from the session mentions func_80146A6C (74/26/4 entries checked) and the arity undo reported success in every log. The real cause was dedup_propagate --recover leaving an orphaned caller-extern reconcile (now fixed + proven, commit:1521 / commit:1522). F1 remains real, unguarded, and part of the remaining Stage-1 work -- it simply did not cause this incident. Generalizable law added to 156: a tool that deliberately leaves an edit on disk pending an outcome owes a LEDGER for it. 'Keep it if this succeeds' is half a transaction; the other half is undoing it on every path that can later invalidate the success, exit paths included. commit:1519's commit message keeps the wrong attribution (history not rewritten, corrected forward). |
||
|
|
0ef53c7b22 |
test(phase-30 S45p7): prove the reconcile-ledger undo — the owed negative control
The full-propagation control did not fire (that run succeeded), so the guarded path was never executed and the fix was committed honestly marked UNPROVEN. This proves it directly. Exercises the exact overlay+fn that broke the fleet (ov_SC07_010 / func_80146A6C): apply a REAL reconcile_caller_extern -> 35 edits across 18 files on disk drive the ledger undo as the fixed code does when a fn leaves the plan assert all 25 of the overlay's source files are byte-identical PASS. The orphaned caller-extern class that broke 141/213 cannot survive this path. The test restores what it edits and asserts it (tree clean after). |
||
|
|
fe946595fd |
fix(phase-30 S45p7): dedup_propagate leaves no orphaned reconcile on failure + func_8015C030 propagated x7
ROOT CAUSE of the 141/213 breakage earlier this session (correctly derived this time;
my first attribution to F1 was WRONG -- no arity journal ever touched func_80146A6C and
the arity undo reported success):
dedup_propagate --recover's Part B reconciles a conflicting caller extern and
DELIBERATELY leaves the edit on disk when it buys the byte-match ("keep the reconcile
on disk"). Correct while the fn survives -- but a fn can still be dropped by a LATER
iteration against a different overlay, and when the plan finally emptied, the
"all candidates dropped" sys.exit fired with NO restore. Reconciles kept for
ov_SC07_001..009 were orphaned: no-proto'd caller externs for functions that were
never propagated -> ov_SC07_010 "passing arg 2 of func_80146A6C makes pointer from
integer" -> 141 of 213 binaries failed check-all.
The byte-gate never mis-banked (it fails closed). The real cost was VERDICT VOIDING:
every subsequent gate reported "near" against the broken tree, so two whole batches
(4/4 and 20/20) were mis-read as draft failures when they measured the tree (R35).
FIX: a reconcile LEDGER. Every kept reconcile is recorded against its fn, undone the
moment that fn leaves the plan, and ALL outstanding reconciles are restored before the
failure exit -- so a failed propagation leaves the tree exactly as it found it.
HONESTY: the fix is IMPLEMENTED AND REVIEWED BUT NOT YET PROVEN. The negative control
aimed at the exact failing propagation SUCCEEDED instead (different tree state), so the
guarded path never executed. A targeted test of the ledger is still owed.
Also lands the propagation that control performed: func_8015C030 x7 overlays
(func_80168B70 excluded from 4 SC07 overlays, survived elsewhere). check-all 213/213.
|
||
|
|
0d05d91293 |
docs(phase-30 S45 p7): F1 confirmed live (cookbook 156) + the cheap-tier size cliff (157) + wave_snapshot
- cookbook 156: a FAILED draft can poison the fleet. gate_stage's arity pre-pass writes the shared engine_core.h before the gate; a rejected draft's caller-signature edit survived and broke 141/213 binaries. Byte-gate held (fail-closed). The trap: a broken tree makes every later gate report 'near' -- two batches of verdicts were void, not evidence. Standing practice: GATE_NO_ARITY=1, assert 'git status --porcelain src/shared config' empty after every batch, recover by revert+replay (deterministic). - cookbook 157: the cheap-tier size cliff, measured over two controlled waves. Haiku 4-27 ins 86% (~44k tok/match); >=50 ins 20% (~177k, 4x worse). The documented '<=50' band was optimistic. Agent honesty 63/63 claims true across 100 drafters. - tools/wave_snapshot.py: immutable sha1-manifested per-wave .s copy, so a running wave can no longer block R22's 'make clean'. Coverage-asserting (exit 2 on a missing target), negative-control proven. - docs/concurrency-design.md (Fable5): the lane contract, the false-bank correctness argument, and the finding that a worktree verify certifies the COMMIT -- strictly stronger than our main-tree R22, which also compiles untracked strays. - checkpoint p7. |
||
|
|
dcc76228b3 |
feat(phase-30 S45 p6): 29 novel functions banked from cheap-tier waves; R22 213/213
29 byte-gated matches into ov_SC02_037 (626 -> 597 live stubs), from two Haiku/Sonnet crack waves on the CORRECTED frontier (live INCLUDE_ASM stubs with cached seeds, not the already-banked reach-141 shared core). Gated with BOTH safety guards after a live F1 incident (see below): GATE_NO_ARITY=1 — no fleet-shared engine_core.h writes --no-propagate — propagation deferred to its own controlled step F1 bracketing assertion CLEAN (git status --porcelain src/shared config empty). R22 clean-fleet: make clean && extract-all && check-all -> 213 passed, 0 failed. F1 CONFIRMED IN PRODUCTION (docs/concurrency-design.md, found by the Fable5 design pass hours earlier): gate_stage's arity pre-pass (fix_arity_callers --apply) writes the fleet-shared header + caller externs; when a draft then FAILS to bank the edit can survive. func_80146A6C failed its gate yet left a caller signature behind, breaking 141 of 213 binaries (ov_SC07_010: 'passing arg 2 makes pointer from integer'). The byte-gate held throughout — nothing wrong was banked, it failed closed and loud. Recovered by revert-to-HEAD + deterministic replay from the on-disk drafts. Cost of the guard, measured: 2 banks (24 -> 22 on the wave-2 batch). MODEL-LADDER CALIBRATION (independently re-verified, not agent claims): Haiku 4-27 ins: 43/50 = 86% (~44k tokens/match) Haiku 30-49 ins: 14/25 = 56% Haiku >=50 ins: 5/25 = 20% (~177k tokens/match, 4x worse) => the documented 'Haiku <=50' band is optimistic; the cliff starts ~30, collapses at 50. Agent honesty across 100 drafters: 63 MATCH claims, 63 real, 0 false (one apparent false claim was MY verification missing --o0 on an -O0-cluster function). CARRIED: the 29 banks are x1 (propagation off); wave-3's 19 verified drafts are UNJUDGED — their gate ran against the F1-broken tree, so those verdicts were void. |
||
|
|
0f409249ba |
chore(phase-30 S45 p6): wave-1 banked 0 — the frontier DEFINITION was the bug; cookbook 155b
HONESTY LEDGER (the wave cost 2.5M tokens and banked nothing; root cause mine): - I FABRICATED the workflow args: after generating the real target list to args_light.json I hand-typed the array instead of reading it, inventing names and a descending nins run. ~40 of 50 agents got nonexistent targets. The agents refused to fabricate and returned accurate diagnoses -- the prompt's honesty rules held perfectly under a bad input. - I then misdiagnosed it twice with a broken check: corpus.stubs() is keyed by INTEGER ADDRESS and I compared string names (always False), producing two confident wrong claims. Pool was in fact 160/160 + 166/166 valid. -> cookbook 155b: check the TYPE your oracle returns; an exactly-0/N result is more often a type error than a discovery. R32/R35 assert coverage+correctness of a tool, but neither catches an INTERFACE mismatch at the call site. SOLID: 9 drafts independently re-verified MATCH by re-running match_one myself (not agent claims); all 9 are genuine INCLUDE_ASM stubs; kept at .run/s45p5/gate1. They did not bank (0/8 near/1 failed) -- but see the open instrument question. OPEN (do first): harvest_verify reports 619 live stubs where the single source .c holds 626 INCLUDE_ASM, and skipped a valid stub. Until explained, the 0-banked verdict is not evidence about the drafts (R35). CORRECTED FRONTIER: reach-141 identifies the most-DONE work (shared core, already DEFINE_ macros ~1,614/binary), not the most valuable. Derive targets from the build invariant (R33): INCLUDE_ASM in committed source. Big-3 = 1,799 draftable, 1,168 already seeded -- the real II.5 fuel. Tree restored: gate_stage left 659 files dirty; git checkout -- src/ config/ verified clean. |
||
|
|
0499c1ec88 |
docs(phase-30 S45 p5): exclusion proof needs a consumer-side instrument; 4th value-scan refuted
- exclusion_proof.py tried the proven S44 {u32 idx,u32 param} table shape; its R32
control FAILED (neither known resident table re-found) -> output void per R35.
- STANDING VERDICT: no value/shape-based scan can establish the exclusion. Small
indices (7,9) are indistinguishable from ordinary data; 4/4 attempts refuted.
Do not attempt a 5th (cookbook 155a).
- The sound instrument is CONSUMER-side: enumerate every register-tracked reference
to cdFileLocTable across all 213 binaries, resolve each index source, collect the
reachable index set. Bounded, but real work.
- Partial: the discriminating indices 231/234 appear in no pair-shaped table fleet-wide.
|
||
|
|
f5c73c51f9 |
chore(phase-30 S45 p5): checkpoint — the last 5 are static-unresolvable (proven); OPDEMO identified
Refreshes the session checkpoint before pausing (checkpoint-before-pause rule): - p3/p4's static-RE homework closed as a NEGATIVE with two independent legs of byte-grounded evidence (resourceIdMap refuted; payloads do not encode their base). - Two actionable by-products recorded: MAIN/7+9 = the OPDEMO (attract-demo) modules; the ~0x801Exxxx event-module region is runtime-allocated at per-scene bases. - Resume pointer now names the CD-read tracer + one targeted attract-mode capture as the correct next instrument, and warns off the three refuted oracles + the shape scan. |
||
|
|
0bd334c30d |
docs(phase-30 S45 p5): MAIN/7+9 identified as the OPDEMO modules; 3 base oracles refuted; the event-module region is runtime-allocated
- MAIN/7 (id 0x3A) and MAIN/9 (id 0x2D) carry 'C:\TIMPACK\OPDEMO0.PAT' /
'OPDEMO1.PAT' path strings -> they are the OPENING/ATTRACT-DEMO modules. S45 p2
checked 'OPENING' negative, so the live target is attract-mode (idle at title),
a different state. Turns a blind search into a targeted capture.
- THREE payload-side base oracles built and ALL refuted by their own controls
(R32/R35 assertions did their job; none of their answers were used):
derive_base 0/4 -- 'code follows the table' is false (MAIN/34: 0x208 gap)
vote_base 4/12 -- calls are outward + MIPS leaf fns have no prologue
vote_base2 0/4 -- self-jals 0/N: there are NO internal jal calls at all
The third is structural: a module's bytes do NOT encode its base, because its
functions are reached indirectly via the header pointer table (jalr), not jal.
- The one real constraint: SC03/54's 19 header pointers (0x801EF718..0x801EFEE8)
confine its base to [0x801EDED0..0x801EF6C8]. That window lies INSIDE SC02/9's
span (0x801E4C60+70784=0x801F60E0) -> SC02/9 + the SC03 trio are mutually
exclusive event modules sharing a ~0x801Exxxx region at DIFFERENT bases.
- => event-module destinations are per-scene/runtime-allocated, not a static slot.
This explains the empty resourceIdMap branch and why the emulator resolved SC02/9.
The CD-read tracer stays the correct instrument (R11 + Drew).
|
||
|
|
a3976d73e5 |
docs(phase-30 S45 p5): the resourceIdMap branch is REFUTED for all 5 parked payloads
- resourceIdMap @0x80063138 decoded from the EXE using the index math in our OWN matched C (ResourceGetCdLoc is byte-exact): exactly 162 6-byte records, 2 negative non-CD sentinels, streamIds >=0x100 -- self-consistent with the C in every field. - FINDING: its 98 distinct global indices include NONE of gi 7/9/231/232/234, so the five parked payloads cannot reach ResourceGetCdLoc/StreamLoadStateMachine/D_80068B60. The S44 'descriptor path' branch of the parked-dest disjunction is refuted; only the per-overlay IDXTAB/DESTPTR route survives. - R34 corroboration: loadDestPtrTable's 5 u32s re-derived independently and reproduce the S44 table exactly (0x800CEDF8/0x80128158/0x800CAE08/0x800CCB1C/0x800C7F08). - R14 CORRECTION to S44: 'IDXTAB ... same list fleet-wide' is wrong. The 37-entry list at 0x8017EEC8 is real for ov_SC01_000 only; 140 of 141 overlays hold unrelated bytes there. IDXTAB is per-overlay data at a per-overlay address; only the mechanism is shared. - NEGATIVE TOOLING RESULT (cookbook 155a): a shape-only IDXTAB scan passes its R32 coverage assertion and is still non-discriminating (664 'tables'; hits are (offset,count) pair data). Coverage != discrimination -- two different oracles (R34). Recorded so it is not repeated; next instrument is a register-tracked decode of func_80128CFC (155). |
||
|
|
7e9394f691 |
fix(phase-30 S45 p4): R14 correction — the MAIN/7/SC03-trio 'loader fn' leads were scanner phantoms
- the quick hi/lo sweep paired lui/lo16 WITHOUT tracking base registers -> phantom refs
(0x800AE868 read where the true target was 0x8018E868); register-tracked rescan: the ONLY
literal loc-table ref fleet-wide is SC02/9's (solved)
- standing truth: MAIN/7, MAIN/9, SC03/53/54/56 all load via table-INDEXED paths; homework
respecified (descriptor-data hunt + ResourceGetCdLoc/StreamLoad index math)
- fn 0x80161E08's real gate: currentLocationId vs {0x3012,0x3054,0x3079,0x3096} — the
'variable 0x800C3054' never existed; cookbook §155 (track the register)
|
||
|
|
788f33d523 |
feat(phase-30 S45 L3-p3): SC02/9 = the Steam Knight boss module — decoded, captured, retro-verified, onboarded; parked = 5
- the gate DECODED from matched C (func_8012832C case 0x300E -> func_80128998 -> streaming API with &cdFileLocTable[144]) -> scene arithmetic named the 1ST-BOSS arena -> ONE targeted load captured it at 0x801E4C60 - RETRO-VERIFIED: Phase-3's dumps/ram_castle.bin (2026-06-14) holds it at the SAME address, same 6,764-B exact prefix — R10 two independent datapoints two months apart; bossHp_SteamKnight (0x801E4398) lives inside this module's image - onboarded md_SC02_009 (id 0x3E, TLO 0x4): BYTE-IDENTICAL first build; fleet 213; R22 213/213; tools-health OK; audit-disc UNCLAIMED 6 -> 5, residue 0 - the last 5 (MAIN/7, MAIN/9, SC03/53/54/56) reclassified emulator->STATIC-RE targets with decoded leads (memory-map §S45 p3); loc-id map appended to docs/debug-menu-list.txt - negatives banked: pause menu, memory-box prompt, new-game intro, high/low game, Minku spawn (slot-A actor 0x15 = md_MAIN_015 candidate naming) |
||
|
|
fa7b9d4c71 |
feat(phase-30 S45 L3): the emulator tour — all 28 script modules + MAIN/3 onboarded; fleet 212, R22 212/212
- THE TOUR (Drew driving the retail debug menu; mode-7 hammer over the Redux web API): all 28 script modules captured live at four byte-verified per-chapter slots (SC03/73-79 @0x801EF468 ch2-period, SC03/132-138 @0x801E25E8 ch3, SC04/24-30 @0x801E7B28, SC05/23-29 @0x801ED988); the routing law: debug-menu AREA selects the chapter, each CITY interior streams its own module (member k <-> interior k). md_MAIN_011/DISELECT byte-proven 24,236/24,240 in RAM; slots A/B/boot R34-verified live. - MAIN/3 DISCOVERED: the main-menu module (id 0x39, 121,884 B), mis-bucketed as data by BOTH audit oracles; live byte-proven @0x800CEDF8 (42,632-B exact prefix); onboarded. - 29 onboardings BYTE-IDENTICAL on first build -> fleet 212; R22 212/212 after three md_MAIN_003 catches: the A4 DsMix leak; an extract-order-sensitive splat boundary (bytes: a 1-word data sentinel in .text + fn at +4 -> pinned in symbols file); corpus.stubs now treats D_*/jtbl_* INCLUDE_ASM as blob includes (mirrors progress.py) - module-id census (offline, disc-wide): 77 id-law code payloads, 0 further misses; SC03/55 = confirmed DATA. audit-disc: UNCLAIMED 34 -> 6, residue 0 — the 6 carry byte-checked negative evidence; next tier = the CD-read tracer - docs: memory-map §S45 (slots + routing + debug-menu ops), disc-completeness S45 addendum, decision-log R31 entry, docs/debug-menu-list.txt (Drew's transcription) - .run/s45 evidence allowlisted (tour logs/scripts/rosters); 104 ram dumps LOCAL-ONLY - new baseline: 93.8% instr / 95.68% fn / 87.2% distinct over 212 |
||
|
|
ae9d0833ba | docs(phase-30 S45): checkpoint — Part II delivered through II.3; frontier + L3 handoff | ||
|
|
14b115d8ba |
docs(phase-30 S45 II.3): metrics re-baseline + roadmap contract delta + decision-log (R31)
- roadmap §1.1: 183 onboarded binaries; the 100% claim's exclusion list = the 34-row parked-for-L3 ledger (28 script + SC02/9 + MAIN/7/9 + SC03/53/54/56 — 3 rows S44 never tiered); supersedes the '39 type-1 backlog' framing (43 of them now build byte-identical) - disc-completeness.md S45 section: what landed, the full parked list, the L3 resolution path - decision-log: the S45 entry — five instrument findings a 'mechanical' batch surfaced, each negative-control-proven; honest baseline 94.0% instr / 95.96% fn / 87.6% distinct over 183 |
||
|
|
a0f07d629e |
chore(phase-30 S45 II.2): retirements (R33) + SETUP module recipe
- DELETED: disc_code_sweep.py (superseded by disc_audit/make audit-disc), reconcile_decls.py (superseded by reconcile_tu; incumbent row removed from cdecl audit_differential — the differential existed to prove this deletion safe), rollout_801457a4_o0/rollout_whale_o0/ rollout_o0_cluster one-shots (rollout_o0.py is the live generic), ImportOverlay.java + VerifyOverlay.java (ghidra_import_raw.sh is the live path) - reference check first (R14): the plan's 'zero build refs' was wrong for 3 — comment refs annotated, the one LIVE import (cdecl) reworked; audit-cdecl + tools-health re-proven green - SETUP §6.7: module-class recipe (TEXT_LO derivation, paired-.rodata hdr carve, A4 symbol- window law, ELF-seeded sig-modules) + new_binary.sh inventory row + 3 RETIRED rows (R21); disc-completeness Reproduce marked retired |
||
|
|
4cadac4e11 |
feat(phase-30 S45 II.1c): module batch dedup-banked + verified — 408 banks, R22 183/183, audit-disc 75->34 (parked-only)
- dedup measure (R37 probe): 69/1,113 module fns h_exact-match matched corpus (~6%, LOW as
planned — modules are novel frontier); dedup_extend inapplicable (same-vram group model) ->
family_sweep --hseq --band all over the 57 matched-exemplar families: 408 member-matches
banked (182 into modules, 226 into the big 3 — families Part I's --only scoping missed),
169 failed + 77 STRUCT = genuine per-member frontier
- R22 clean-fleet 183/183 BYTE-IDENTICAL; audit-disc UNCLAIMED 75->34 residue 0 (34 = 31
parked-for-L3 + SC03/53,54,56 — 3 rows Discovery-3 never tiered, now parked with evidence)
- three instrument fixes, each negative-control-proven:
- family_sweep --hseq stub map derives ov_*+md_*+resident (was sig.ov_* glob -> module
members silently 'not-stub', R32 class) [committed earlier as commit:1506]
- sig-modules seeds from the built ELF's func_* symbols (bootstrap GLUES adjacent fns
around jtbl dispatch -> 24 false TRUNCATED; perturbed-sig control still bites)
- corpus.audit counts CODE lines only (module .s carries its header jtbl as .word lines);
progress.py buckets INCLUDE_RODATA symbols as blobs (unbucketed R32 hole)
- NEW HONEST BASELINE (183 binaries): 94.0% instr / 95.96% fn-count / 87.6% distinct;
tools-health OK, audit-digest OK
|
||
|
|
b1dbfcb572 |
fix(phase-30 S45): family_sweep --hseq stub map derives ov_*+md_*+resident (R32)
- the .run/sig.ov_*.jsonl glob had no md_ entries, so every module member fell into an empty stubs.get() and booked a silent 'not-stub' skip — the I.1d glob-widening class, missed because family_sweep sat on the audit's 'auto-OK' list - negative control: --only 0x80165b28 --stage-only staged 0 md members before, 32/32 after |
||
|
|
b15dae1077 |
feat(phase-30 S45 II.1b): SC07 module pair onboarded byte-identical at 0x801A00D8
- md_SC07_003 (345,132 B, text-lo 0xFC, 100 fns) + md_SC07_004 (365,152 B, text-lo 0x158, 315 fns) — both BYTE-IDENTICAL on first build at the header-derived own slot - independent first-prologue scan reproduced the plan's documented TLOs exactly |
||
|
|
85b526cddd |
feat(phase-30 S45 II.1a): all 38 MAIN modules onboarded byte-identical at the §S44 static addresses
- slot A 29/29 (md_MAIN_013..041 @ 0x800CAE08), slot B 6/6 (md_MAIN_042..047 @ 0x800CCB1C), boot trio 3/3 (md_MAIN_001 [=MAIN/0 twin], md_MAIN_008, md_MAIN_011 @ 0x800CEDF8) — every one BYTE-IDENTICAL on its FIRST build (byte-corroborating the §S44 loader table for slots A/B/boot) - TLO roster derived from the §154 id-word law (.run/s45/derive_tlo.py): 0x4 default; 011=0x7C, 025=0xC, 034=0x80, 039=0xC (first-prologue scan) - new_binary.sh: module hdr carve is now a dot-typed .rodata PAIRED with the c segment — a header can hold a function's jump table (md_MAIN_034), and standalone rodata emits .L locals that don't cross objects; bin links in the data block (both refuted by bytes) - A4 law: symbols.resident.txt dropped from the boot trio's stacks (windows inside the resident region; DsMix @0x800D1BD8 had minted a phantom fn boundary in md_MAIN_011) — re-extracted clean, all three byte-identical, phantom gone |
||
|
|
41ff2ba127 |
docs(phase-30 S44 I.3): checkpoint — Part I complete; fresh session resumes at Part II
- R22 clean-fleet 143/143; fleet 96.13% fn / 94.4% instr (honest grown denominator; pre-expansion line 95.00% on 140 kept for continuity) / 88.3% distinct. audit-binaries OK over 143. - make audit-disc: UNCLAIMED 78 -> 75 payloads (3,564,021 -> 2,038,104 B), residue 0 — the three claims flipped automatically via check.sha, exactly as the ledger was designed. - S44 session total: 5,126 member-functions banked into the 3 new overlays; the ~2,051 remaining stubs are the new frontier, visible to every tool via citizenship (no separate ledger rows — recorded as a deviation from plan I.2e, redundant by construction). - Part II handoff live in the plan file + the S44 checkpoint block. |
||
|
|
c1d5670f36 |
feat(phase-30 S44 I.2c2): the h_norm/template tier — +290 members banked into the new binaries
- family_sweep --hseq scoped by --only to the 637 families with a matched exemplar AND a member in the new 3 (2,232 stageable; avoids re-gating the swept-dry fleet). BANKED 290 / 81 failed / 6 skipped (unresolved immediates), every one whole-binary byte-gated; all three SHAs green. - Session total into the big 3: 4,836 h_exact + 290 template = 5,126 member-functions. - Remaining stubs 624+717+710 = 2,051 = the ~802 novel functions x instances + the genuinely failed/unstageable tier (the new frontier). |
||
|
|
ae62b743ab |
feat(phase-30 S44 I.2c): dedup-bank — 4,836 h_exact members extended into the big 3
- tools/dedup_extend.py over the clean tree (the prior run correctly REFUSED my uncommitted tree, H4 — that refusal was the tail I misread as a result; and my earlier '0 stubs left' was a single-file grep -c display artifact, caught before being reported). - BANKED 4,836 / 5,016 planned (1,612 DEFINE_func per binary; 180 skipped incl. 8/binary verbose-form). Each splice byte-gated; all three binaries remain BYTE-IDENTICAL (SHA re-checked per binary post-run). engine_core.h include added -> audit-binaries green again (R36). - Remaining stubs: ov_MAIN_012 712 · ov_SC02_037 822 · ov_SC03_107 802 = the h_norm-only tier + the ~802 novel functions (the new frontier). |
||
|
|
f6bbe7272a |
feat(phase-30 S44 I.2a): the big 3 onboarded BYTE-IDENTICAL — ov_MAIN_012, ov_SC02_037, ov_SC03_107
- Three uncompressed (PAC type-1) overlays at the standard 0x80128158 slot, onboarded via the new
tools/new_binary.sh, each byte-identical at 100% INCLUDE_ASM on the FIRST build:
ov_MAIN_012 d6b3e8b9 (383,783 B, 2,324 fns)
ov_SC02_037 b0c5394a (661,903 B, 2,434 fns)
ov_SC03_107 87d02b57 (474,087 B, 2,414 fns)
This also BYTE-PROVES the statically derived base (the §S44 loader table + the 500:1 h_exact
vote): a wrong vram could not have produced byte-identical images once symbols resolve.
- Fleet: 140 -> 143 binaries. audit-binaries currently FAILS on all three by design (no
engine_core.h include yet — the SC07-blindness check working as built); dedup_extend is the fix
and the next commit.
- Registered by the script: overlays.mk blocks, check.sha, symbols seeds, the 3 BINARIES dicts.
family map regenerated (3,577 target families / 279 with a matched sib — the new binaries'
members now visible).
|
||
|
|
f5ea0fdd49 |
feat(phase-30 S44 I.1e): tools/new_binary.sh — one onboarder for every flat-blob class
- Generalized from new_overlay.sh: ALIAS + PAYLOAD + VRAM + optional TEXT_LO (file offset of code). Class registry chosen by alias prefix (ov_* -> overlays.mk, md_* -> modules.mk; modules.mk created with its contract header on first use). Fixes the two places new_overlay.sh re-hardcoded the slot literal instead of $VRAM (:39 TEXTHI, :44 CODEEND). - TEXT_LO wires the §154 module-id law end-to-end: sig bootstrap gets --text-lo (else 0 functions on 75/78 payloads), and the splat yaml gets [0x0, rodata, hdr] + shifted code start (the resident's leading-word trick — ONE shared template, no second file, R33). _TEXT_LO lands in the mk block as a VRAM for make sig-modules. - The sentinel-anchored 3-dict registrar + check.sha/symbols/extract/build steps reused verbatim. - new_overlay.sh is now a 30-line WRAPPER (same CLI, docs preserved, H5); exec's new_binary.sh with the overlay defaults. |
||
|
|
369dd14f4f |
fix(phase-30 S44 I.1d): the module class reaches every enumerating consumer
- family_hseq: widened from src/ov_*+sig.ov_* to every non-main binary (resident + md_*); the map now carries 139 binaries incl. resident (was overlays-only — which is exactly why the R36 gate's CHECK 4 could never see them). Self-count uses the SAME widened globs (cannot drift). - progress --weighted :647 + audit_frontier :57: + sig.md_* globs. - corpus.sig_is_independent: md_* sigs are sig_image-signed => independent (R34 trust). - backlog alias regex + prefetch_fleet (md_* derived from splat configs) + dedup_propagate (reads modules.mk alongside overlays.mk — excluding modules would re-create the SC07 invisible-work bug one class over). - VERIFIED: family map regenerated with resident (139 binaries); audit-binaries OK over 140; all six tools parse. |
||
|
|
1826033fb0 |
fix(phase-30 S44 I.1c): the R36 citizenship gate is no longer blind to non-ov_ binary classes
- onboarded() derived from EVERY config/splat.<alias>.yaml (R33; templates + us.exe normalized) —
was splat.ov_*.yaml + a hand-set {main,resident}: the gate that exists to catch unwired binaries
was itself structurally blind to any class it did not know about.
- CHECK 4 widened: resident + modules must appear in the family map too (only main is exempt —
structurally barren, checked twice in S39). New honest warn: resident missing from the current
map (family_hseq widening lands next commit).
- NEGATIVE CONTROL: a planted config/splat.md_TEST.yaml FAILS check 1 ('MISSING md_TEST — invisible
to every derived tool'); removing it restores OK over the 140.
|
||
|
|
ec1a805766 |
feat(phase-30 S44 I.1b): Makefile learns the module class — modules.mk + sig-modules
- -include config/modules.mk (silent when absent, same contract as overlays.mk) and BINARIES += $(MODULE_BINARIES). Everything downstream of $(BINARIES) — prune, check-all, build-all, expected — is untouched and picks modules up automatically. - NEW sig-modules target: signs every module at ITS OWN vram with ITS OWN --text-lo (the §154 module-id-word law — bootstrap from offset 0 yields 0 functions on 75/78 payloads). Derived MODULE_SIG_JOBS from modules.mk (R33, the sig-overlays pattern). Wired into tools-health after sig-resident. Empty registry = clean no-op (verified). - NEGATIVE CONTROLS: make -n sig-modules iterates an empty list; main rebuilds 143dbb89 byte-identical with no modules.mk present. |
||
|
|
9ae1c9a743 |
fix(phase-30 S44 I.1a): family_remap derives vram per-alias from the splat config (R33)
- VRAM was a module constant (0x80128158) used in ALL offset math (reloc_targets :98, stream_words :160) — correct for the 138 shared-slot overlays, silently WRONG for every other class (resident 0x800CEDF8, the new md_* module slots): addr-VRAM would read garbage bytes without erroring, the R32 silent-skip shape in the tool the whole family engine stands on. - NEW vram_of(alias): read once from config/splat.<alias>.yaml (the jtbl_carve pattern; cwd-relative like img_path). Unregistered alias raises LOUD (R32, no default). - REGRESSION: the 0xECC-family remaps (ov_SC03_003/ov_SC04_021/ov_SC05_019) are byte-identical to the S43 banked drafts. Negative controls: resident derives 0x800CEDF8, overlays 0x80128158, unregistered alias raises. |
||
|
|
c697746462 |
docs(phase-30 S44 I.0): the static loader routing table + the full tool audit — knowledge captured
Plan-approved campaign (Fable5Max, ~/.claude/plans/optimized-squishing-engelbart.md). I.0 = capture
while hot (R30/R31), before any code:
- memory-map.md §"Phase 30 S44": the COMPLETE loader routing table, static-derived (G5) — the EXE's
loadDestPtrTable (0x80072C70: resident/overlay/slotA/slotB/type-7), the boot k-set {1,3,8,10,11},
the RESIDENT's index tables D_800D3764 (29x8, MAIN/13-41 -> 0x800CAE08) and D_800D384C (6x8,
MAIN/42-47 -> 0x800CCB1C), resident.c:641 (MAIN/12 -> 0x80128158), the SC07 pair's header-derived
0x801A00D8, gbase arithmetic (LIST.CD carries LBA+len ONLY), the slot-adjacency proof, the
module-id-word law (word0, dense 0x13..0x73, resident=0x36; MAIN/9-vs-39 duplicate flagged), and
"PAC type 1 = uncompressed overlay, type 4 = LZSS". SUPERSEDES P3-T5's "entries [1]+ are
runtime-indexed (no static xref)".
- disc-completeness.md: the "only knowable by runtime RE" doctrine REFUTED in place (H5, original
kept) — 46 of 78 addresses are static; the runtime-only remainder is 28 script modules + 4
stragglers, parked for L3 with evidence. Byte-sum correction (rows 3,406,325 B vs bucket
3,564,021 incl. PAC headers), MAIN/7 raw-path exception, MAIN/0≡1.
- tooling-audit.md §S44: EVERY tool classified with file:line — 8 must-change (family_remap VRAM
const, Makefile+modules.mk, sig-target generalization, audit_binaries de-ov_, family_hseq/
progress:647/audit_frontier globs, corpus.sig_is_independent), 7 one-line registrations, 5
retirements (disc_code_sweep superseded by disc_audit; reconcile_decls; 3 rollout one-shots;
ImportOverlay/VerifyOverlay.java), rest auto-OK/N-A. new_overlay.sh -> new_binary.sh design.
- decision-log (R31): the pivot entry — the emulator dependency dissolves; the "modules" mostly
dissolve into overlays (~75-77% h_exact-known; 802 novel fns); why the doctrine was missable for
30 phases (a confident negative doctrine is a claim like any other — date it, cite it, re-measure).
- cookbook §154 + index regen (454 sections): module-id word / dual base-voting (h_exact ~500:1 +
jal-alignment, must AGREE; thin votes => park, P9) / diff a mystery payload's head against classes
you already own before inventing a new one.
|
||
|
|
7473640838 |
fix(phase-30 S43): audit-disc listed only L1's code — the real backlog is 78 payloads, not 39
- MY BUG, found by reconciling against the old sweep (R14): when I introduced the two-oracle UNION I updated the BUCKET accounting but left the ledger's row-listing condition on L1 alone. So the byte total was already right (3,564,021) while the LIST under-reported — 34 rows instead of 78. Same "two code paths, one updated" shape as the day's other defects. Fixed: rows use the same union. - THE COMPLETION CONTRACT'S "39 type-1 modules" IS SUPERSEDED: the real backlog is **78 unclaimed code payloads / 3.56 MB** — MAIN.CD 42, SC03 18, SC05 7, SC04 7, SC07 2, SC02 2. The 39 came from disc_code_sweep, which reads only the RAW layer through a 4,096-WORD WINDOW and has no notion of a claim. Reconciled decisively: all 39 hash-checked against config/check.*.sha -> 0 of 39 claimed, so the new set strictly CONTAINS the old one. docs/disc-completeness.md updated, old text kept for provenance. - WORKED EXAMPLE of why the window mattered: SC07.CD FILE_003/1.1 is 345,132 B whose HEAD is code — the old window saw valid=100%, the whole-payload average is valid=0.571 (L1 says data), and L2 carves 3 real functions. Only the union gets it right, which is the entire argument for R34. - Partition still holds: residue 0 over 416,021,760 B, 1,291 payloads examined. |
||
|
|
964afdba4e |
feat(phase-30 S43): L2 second oracle — it found TWO L1 defects; unclaimed code 1.70 -> 3.56 MB
L2 (R34) is sig_image boundary carving: walk the payload cutting each function at the first `jr $ra`
at/after every forward branch target. Structurally different question from L1's statistical test
(valid>=0.90 AND jr>=0.01), so the two can ARGUE — and they did, 80 times, all one shape.
- L1 DEFECT 1 — A CLAIM OUTRANKED BY A HEURISTIC. A payload whose SHA1 equals a committed
config/check.<bin>.sha IS that onboarded binary (the build gates on that hash daily), but I let the
statistical verdict file it as classified-data. Onboarded bucket understated by 14.5 MB.
- L1 DEFECT 2 — WHOLE-PAYLOAD AVERAGING DILUTES CODE. A real location overlay is code followed by a
large data tail, so its whole-payload valid-ratio is ~0.87, under the 0.90 gate — while L2 carves
real functions from its head. The "classify the whole payload" fix for the old 4,096-word window had
traded a head-only bias for an averaging bias. 80 disagreements, every one this shape.
- RESOLUTION (bucket_of): a claim wins outright; otherwise take the UNION of both oracles. Union is
the conservative direction for this audit's question — over-reporting code yields a review queue,
under-reporting HIDES code, the exact failure that produced three "more code all along" surprises.
- RESULT: partition still holds, residue 0 over 416,021,760 B / 1,291 payloads.
onboarded-code 47,066,812 · UNCLAIMED-CODE 3,564,021 (34 payloads) · classified-data 134,265,572
· audio-video 184,338,000 · filesystem-metadata 46,787,355
Largest unclaimed: MAIN.CD sub-file 12 entry 1 type 1, 383,783 B; the rest small type-1, mostly MAIN.CD.
- The ledger now carries an explicit L2 REVIEW QUEUE section; L1=data/L2=code is flagged as the
DANGEROUS direction (missed code).
|
||
|
|
03794d91cd |
feat(phase-30 S43): make audit-disc — the disc PARTITION holds at residue 0; 34 UNCLAIMED code payloads
L1 of Drew's definitive disc audit ("we really need a full audit that definitively lists ALL code
that we need to decomp"). THE INVARIANT (R32): every byte on the disc belongs to exactly ONE bucket,
the buckets SUM TO THE DISC, and residue is a DEFECT — a partition with an asserted residue of zero
is a completeness proof; a longer list is only a longer list.
- WALKS THE DISC IMAGE, NOT OUR CONFIGS, classifies WHOLE payloads (no window), and decodes BOTH the
raw and LZSS layers — the three shapes that produced the three "more code all along" surprises
(the 0.4.dec glob missing 4 SC07 overlays; disc_code_sweep blind to COMPRESSED code, its type-4
row vacuous for 138 known binaries; a 4,096-word window reading only payload heads).
- CLAIMED-BY IS DERIVED (R33): config/check.<bin>.sha IS the SHA1 of that binary's disc payload, so
payload->binary is a hash lookup against the build's own byte-identity gate. It cannot drift.
- RESULT, 416,021,760 bytes, 1,291 payloads, RESIDUE 0:
onboarded-code 32,564,876 (7.83%) · UNCLAIMED-CODE 1,700,049 (0.41%) ·
classified-data 150,631,480 · audio-video 184,338,000 · filesystem-metadata 46,787,355
34 UNCLAIMED code payloads — largest a 383,783 B type-1 in MAIN.CD, the rest small type-1 entries.
These are the "there was more code all along" surprises, now ENUMERATED instead of stumbled into.
- MY OWN FIRST RUN FAILED THE PARTITION by -49,709,520 B, and the fail-closed exit is what caught it:
.DA entries' LBAs point PAST track 1 into the CD-DA tracks (double-counted against the whole-track
audio total), and .STR/.XA are MODE2 FORM2 (2324 user bytes/sector, not 2048). Both fixed.
- NOT wired into tools-health: it needs disks/, which a fresh clone does not have (H1).
- KNOWN GAP, stated not hidden: LIST.CD fails the TOC walk (it IS the TOC cache, not a container)
and is booked as data — correct today, worth a real classifier when L2 lands.
|
||
|
|
41a3de342d |
fix(phase-30 S43): family_remap now carries TYPEDEFS (transitive, brace-aware) — the §146/§152 gap closed
- ROOT CAUSE PINNED, and my first hypothesis was WRONG (R14, corrected in the log): I wrote that a gate transform ate a `/*` opener and turned comment prose into code. REFUTED — cast_call_sites, sig_unify and reconcile_tu each run with the gate's real --src-file all preserve it. The real cause is family_remap's preamble backscan, whose accept-set (blank/extern/comment/typedef) HALTS AT THE FIRST `#define` and never reaches typedefs above the macro block. `_carry_macros` then re-attaches the macros, which HIDES the truncation — the unit looks complete and is not. "parse error before 'unsigned'" was that failure surfacing at the next token (the following `extern unsigned char` line): a misleading label, not a second defect. - FIX: _carry_typedefs() — additive, TRANSITIVE (a carried typedef may name another; measured: carrying Vec8_80182FD4 alone then failed on SVECTOR_8016E7C8), and BRACE-AWARE (a `;`-terminated scan stops INSIDE the struct at its first member line, emitting a truncated unclosed typedef). Emits dependency-first for C89. Only types the unit actually names and does not already carry. - VERIFIED: the 0x80182FD4 unit now carries its Prim_8016E7C8 block complete; the 0xECC family's remaps now carry the four typedefs I had prepended BY HAND before gating them — i.e. the fix automates the exact workaround that banked those three siblings. Residual isolated-compile failure on SVECTOR_8016E7C8 is a match_one artifact: that type lives in src/shared/engine_types.h, which the real TU includes — the typedef gap is fatal ONLY when the target TU lacks the type, which is why this class failed loudly for some families and silently succeeded for others. |
||
|
|
5c84ad5ada |
feat(phase-30 S43): the 263x5 cluster BANKED 5/5 (+1,315 ins) — the SWEEP was corrupting correct drafts
- R22 CLEAN-FLEET: 140 passed, 0 failed of 140. Fleet 12,502,519/13,160,961 = 94.997% instr (+18,146 instructions this session, 23 functions). 393 instructions from the 95.000% bar. - REDO of the S43-9 retraction, done correctly through harvest_verify (splice/build/keep-iff- byte-identical/revert) instead of hand-building. 5/5 banked, each re-verified three ways: image SHA == locked SHA, stub gone, real definition present. ov_SC03_101/func_801814F8 · ov_SC03_104/func_80184934 · ov_SC04_003/func_8017E4F4 · ov_SC04_005/func_80181054 · ov_SC04_007/func_8017FF08 - THE DEFECT THIS PROVES: family_sweep --hseq reported this family 0/5 with "PLUMBING: parse error before 'unsigned'" — but the remapped drafts are byte-CORRECT. The only `unsigned` in the draft is INSIDE A COMMENT, so a gate-pipeline transform is eating a `/*` opener and turning comment text into code. Per-transform runs on the draft alone all preserve it, so it needs the gate's real invocation (--src-file) to reproduce. NOT YET PINNED — and it is silently costing banks in every sweep it touches. Next: run the three transforms with --src-file and diff. - Workaround that banked them: carry the exemplar's typedefs by hand (the family_remap _carry_macros gap, §146/§152) and gate directly, bypassing the sweep's recovery ladder. - Also killed a self-inflicted infinite poll: an `until ! pgrep -f "permuter_ils.py <fn>"` loop whose pattern matched its OWN bash command line, so the condition could never go false (spun 2h30m). Same family as the day's other defects: a check that cannot return the answer that ends it. |
||
|
|
37c60a5ff3 |
feat(phase-30 S43): R22 CONFIRMS ALL 18 BANKS 140/140 — fleet 94.99% instr; §147 refuted by the bytes
- ✅ R22 CLEAN-FLEET: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
Discharges the [R22 PENDING] caveats on commit:1486 (the 0xECC family x12) and commit:1487
(func_8018D98C). All 18 of today's banks are confirmed, not incremental artifacts (§130).
- FLEET: 96.63% fn-count / 94.99% instr-weighted (12,501,204/13,160,961) / 89.4% distinct-code.
Session +16,831 instructions, 18 functions. P30's 95% instr bar is 1,708 instructions away
(18,539 at session open). NOTE the report line rounds to "95.0%" — the bar is NOT yet met.
- THE 5th WAVE AGENT: func_8017CE58 is TWO bodies at one address (246 in SC02_000/003, 734 in
SC03_092). The 246 body is byte-identical to func_8017C294 — THE FUNCTION §147 WAS WRITTEN FROM —
so one draft covers 4 instances, and it went 12 (with a recorded "stop searching" verdict) -> 2.
- §147 CORRECTED IN PLACE (H5: original text preserved, correction appended):
* A "stratum 3, unreachable from C" is REFUTED — there is NO stratum 3. The frame is declared
locals then reload spill slots in pseudo-regno order; the mystery 0x108 slot is an ordinary
spill on a loop.c-created pseudo, reachable by writing the loop as an INDEX loop (a pointer
walk puts it at the bottom). Prior drafts faked it with volatile pEnd + dead[7]. (121 -> 54)
* B the unreferenced slots are combine-orphaned sign-extension intermediates (combine.c:10839),
not "?: on memory" frame cost.
* E the qty_compare tie IS breakable — §148-C's zero-emission ref slider. (30 -> 25)
* D applied properly (drop volatile out + the $24 pin, let a1 spill) remains: 54 -> 30.
- CONSEQUENCE: func_8017C294's 15 siblings were parked "until stratum 3 is explained" — that hold
is VOID. Both near-misses logged to the ledger with their measured closeness, not forced (P9).
- PROCESS LESSON in §147: a confident NEGATIVE verdict is a claim like any other — date it, name
its evidence, and re-measure it before letting it park work (same shape as §146).
|
||
|
|
dee33412db |
feat(phase-30 S43): func_8018D98C banked (710 ins) + §153 the address-rematerialisation launder [R22 PENDING]
- func_8018D98C (ov_SC06_033, 710 ins): MATCH, gated, carved into its own split
(src/ov_SC06_033/ov_SC06_033_jr_8018D98C.c); image matches its locked SHA; stub gone.
NOT a family — `find asm -name func_8018D98C.s` returns exactly one file, so this banks 1x710.
The prompt's "renderer sibling" premise was wrong: it is a 12-state entity state machine over
jtbl_801CF234; func_8017C6F4's C shares nothing with it. Structurally exact on the first draft.
- §153 THE ADDRESS-REMATERIALISATION LAUNDER (third zero-emission asm lever, after §148-C's allocno
numerator and §151's blocked scheduler tick): an `&SYM` used as an argument >=2x in ONE cse basic
block gets its pseudos unified (4 refs), so local-alloc.c:1080's remat path (needs reg_n_refs==2)
never fires and global.c:388 hands it a CALLEE-SAVED register, cascading a rename. 14 probes prove
no respelling reaches it (do/while splits cse1; cse2 puts it back). Cure, zero bytes, one per site
in its own block: `{ s32 _m = (s32)&SYM; __asm__ __volatile__("" : "=r"(_m) : "0"(_m)); f(x,_m,y); }`
— the volatile asm is never entered in cse's table AND sets _m, emptying the equivalence class.
Placement is load-bearing (#APP is a scheduling barrier); with two address args, launder BOTH.
- INTEGRATION CAUTION: the agent's TU-CONFORMED variant gated DIFF while the PLAIN one banked.
rtu_match MATCHing does not promise a decl-rewritten variant survives the real build — gate the
plain variant first.
- R22 clean-fleet still owed (one agent remains on asm/); this and the 12 family banks are
incremental-gated (§130) until it runs.
|
||
|
|
f5498c3c66 |
feat(phase-30 S43): the 0xECC family — ONE crack banks 12 overlays / 11,364 ins [R22 PENDING]
⚠️ R22 CLEAN-FLEET OWED (two agents still reading asm/, so `make clean` is unsafe). Each of the 12
was gated whole-binary AND independently re-checked against its own config/check.<bin>.sha (12/12),
stubs confirmed replaced — but incremental (§130). Treat as UNCONFIRMED until the clean run.
- THREE isolated cheap-Opus agents, briefed with §150/§151 + the mandatory all-drafts scan,
CONVERGED INDEPENDENTLY: func_8017C6F4's 947-ins body exists in 12 OVERLAYS under 5 DIFFERENT
NAMES at 6 DIFFERENT ADDRESSES, each differing by exactly TWO per-overlay symbols (screen-rect
helper + 64x64 cell table). Gated 12/12, 0 failed. 11,364 ins from this morning's single crack.
- WHY IT HID ~30 PHASES (cookbook §152): name-keyed grouping scattered it across 5 names,
address-keyed across 6 addresses (and the address collides with an unrelated 15-ins body in 3
other overlays), and h_seq-keyed scattered it too — which is why the Phase-26 sweeps missed it.
THE KEY IS BYTE SIZE: `grep -rl 'nonmatching .*, 0xECC' asm/*/nonmatchings/*/` returns exactly
the 12, reads the asm (cannot go stale like family_hseq.json), no false positives. Refines the
Phase-26 "h_seq is spent" finding: h_seq is worth exactly ONE size-keyed sweep behind each FRESH
core crack — here it paid 11:1.
- TWO CAUTIONS THAT TRAVEL WITH IT: (1) a MASKED tool cannot validate a remap — match_one and
rtu_match both mask jal/%hi/%lo, exactly the fields a remap edits, so a wrong symbol map still
reports MATCH; gate remaps by the whole-binary SHA only. (2) a stale residual is NOT evidence two
functions differ — I briefed "func_8017C59C scores 340, different body"; refuted in one command
(that 340 came from a pre-§150-fix draft, which scores nonzero against its own target too).
- OPEN TOOL DEFECT (R32): family_remap's unit backscan halts at the first #define, so it carried
16/16 gte macros and 0/10 typedefs, silently — the §146 gap from the other side.
- MY ERROR, RETRACTED IN THE LOG (S43-9): I reported the 263x5 cluster as "5 byte-identical, 1,315
ins". FALSE — the drafts had been reverted, so I measured the INCLUDE_ASM STUB BASELINE, which is
byte-identical by construction. R34's trap, self-inflicted by hand-building instead of using
harvest_verify. Nothing was banked there; the cluster is UNRESOLVED. ("41 behemoth drafts" was
likewise a file count — 79 files, 20 distinct functions.)
|
||
|
|
01d7d3276c |
feat(phase-30 S43): FABLE5 CRACKS func_8017EF68 (the 2-of-969 wedge); R22 CONFIRMS ALL FIVE BANKS 140/140
- func_8017EF68 MATCH 969/969, re-verified by me, gated: ov_SC06_000 byte-identical at da4a26ff.
- MECHANISM (from cc1's own -dR trace, not inferred): the r3000 machine description gives the
memory unit load-ready-cost 2 / store 1, so blockage(load,store)=2 — a LOAD CAN NEVER BE PICKED
IN THE TICK IMMEDIATELY AFTER A STORE PICK. sched2 therefore always wedges one ready ALU insn
between the lw and the sh, and the target's zero-wedge order is UNREACHABLE BY ANY STATEMENT
ORDER. That is why ~20 documented hand variants AND the repaired permuter both floored at 2.
The draft's own §49 sched1-LUID story was incomplete — real but secondary.
- THE LEVER (cookbook §151, "the ghost wedge"): a zero-emission tied in/out asm
`__asm__("" : "=r"(v) : "0"(v), "r"(rival));` — 0 bytes, but a schedulable insn that absorbs the
blocked tick, and it sets reg_n_sets(v)=2 which also kills sched1's birthing boost (one
instrument, both passes). Two measured fallouts: rival-read in the same asm (22->12), then a
second re-tie on a HIGH-REF host to restore allocno live-length parity (each in-loop insn is +1
live length for every loop-spanning allocno; a trio of invariant addresses sat exactly on
allocno_compare's integer-floor boundary). Host choice empirical: pkt=MATCH, ot=705, double=10.
- ✅ R22 CLEAN-FLEET: make clean && extract-all && check-all -> 140 passed, 0 failed of 140.
This DISCHARGES the [R22 PENDING] caveat on commit:1484 — all five banks are confirmed, not
incremental-build artifacts (§130).
- FLEET: 96.63% fn-count / 94.9% instr-weighted (12,489,130/13,160,961) / 89.2% distinct-code;
0 NON_MATCHING (G4); dedup 1919 groups. Session +4,757 ins from 2 cracks x 5 binaries.
Distance to P30's 95% instr bar: 13,782 ins (was 18,539 at session start).
|
||
|
|
25402b2eb4 |
feat(phase-30 S43): FABLE5 CRACKS func_8017C6F4 pin-free — banked ×4 (~3,788 ins) [R22 PENDING]
⚠️ R22 CLEAN-FLEET VERIFY IS OWED, NOT DONE. All four gates below were INCREMENTAL builds
(§130: an incremental build can report BYTE-IDENTICAL for a change a clean build cannot link).
Committed now only to protect the work — a second Fable5 agent is reading asm/, so `make clean`
would destroy its inputs mid-run. The clean-fleet run follows the moment that agent finishes;
treat these four banks as UNCONFIRMED until then.
- THE CRACK (Drew approved the Fable5 escalation, R27): byte-exact, PIN-FREE, 947 ins. My §147-E
"qty_compare tie, unreachable from source" diagnosis was WRONG. The residual was VARIABLE
IDENTITY: (1) the X-pass and Y-pass min/max intermediates are DIFFERENT variables (8, not 4
reused); (2) mnc/mxc do not exist — the cell clamps reuse the prim-loop mn/mx (X) and mny/my (Y).
Ablations: split-only 63, reuse-only 624, conjunction MATCH. That is also why S42's "separate
X vs Y variables" probe was filed as a failure (it was half the fix), and why every allocator
lever was inert — pins, §148-C sliders, declaration order and 14 permuter restarts cannot reach
a draft with the wrong NUMBER OF PSEUDOS.
- VERIFIED INDEPENDENTLY BEFORE BELIEVING IT (R14): I re-ran match_one -> MATCH (947 ins), then
the whole-binary gate per binary.
- BANKED ×4 (every 948-ins sibling of this body), each byte-identical:
ov_SC03_126 c48a8bb8 · ov_SC03_003 898bf52a · ov_SC04_021 33614234 · ov_SC05_019 3f5b4f13.
family_remap produced all three siblings cleanly.
- §146 SEEN AGAIN: all three siblings first failed with `PLUMBING: parse error before 'MTX_C6F4'`
— _carry_macros carries #defines but NOT typedefs; prepending the 9 typedef lines fixed all
three. That label is legible ONLY because of this session's classifier fix; before it, it read
"CC1-FAIL: make: *** Error N" and cost a manual splice-and-rebuild each.
- cookbook §150 (decode register ownership from the MATCHING diff regions before touching the
allocator; per-instance register asymmetry ⇒ per-instance variables; the deleted-self-move tell
and the global.c:719-vs-:729 death-before-store exemption behind it). §147-E corrected: it named
the wrong allocator — these are global.c allocnos, not local qty_compare quantities.
|