Files
BFM-decomp/cookbook/C0485.md
T

4.6 KiB

§436 ★★★ — TWO TOOLS THAT READ THE WRONG SOURCE OF TRUTH, AND THE SHAPE THEY SHARE (P31 S74; both fixed + negative-controlled)

Three independent agents hit both of these in one session, on the tools that certify and undo the work they were doing. Neither is exotic: each tool read a source of truth that describes a DIFFERENT world than the one it was asked about.

A. split_indicator attributed a jump table by the STUB'S DIRECTORY PATH, and make extract does not prune a re-homed subseg's old directory. After a correct, byte-green split, both nonmatchings/<old-subseg>/func_X.s and nonmatchings/<new-subseg>/func_X.s exist, so the tool saw one subseg owning both spans and printed NEEDS SPLIT for a split that was already correct. Only rm -rf asm/<bin> && make extract cleared it. jtbl_carve.func_subseg documents this exact hazard (a §8b isolation leaves the same debris) and defends against it by deriving the owner from the CONFIG, by address. split_indicator.owners() now does the same (R33), and any leftover stub is NAMED in a note: line — which now prints on an OK verdict too, because a note reports what the verdict does not cover and hiding it behind st != OK is the same defect in the other direction.

B. jtbl_carve --revert did git checkout -- on the WHOLE splat yaml. The carve owns only the trailing data/.rodata region; the c pieces above it are source configuration the tool never writes. A blunt checkout cannot tell "carve state I just added" from "the §431 split someone added to the same uncommitted file", so the revert step silently un-split the overlay — each agent recovered only because they had backed the yaml up by hand. It now splices back only its own region (the same surgical discipline revert() already applied to the SHARED config/overlays.mk, for the same reason), refuses loudly if the committed region carves onto a subseg the current config no longer defines, and says how many uncommitted c pieces it preserved. jtbl_family_bank.revert carried the same blunt checkout for the isolation's code pieces and now keeps whatever pre-dated the attempt, naming anything it drops — it uses the keep_regions signal the tool already trusted for src/, because an isolation region and a §431 split piece are both named <ov>_jr_<addr> and no name test can tell them apart.

C. jtbl_rodata_pads._s_rodata_span measured a .s span by its DATA and ignored a trailing .align. A file ending .asciz "r" + .align 2 occupies 4 bytes; the walker said 2, so the island walk landed mid-object and --derive aborted with C table entry 0 at 0x801A00DA ... island layout drift — a true statement about a span that was never the real one, and (because the Makefile pipes md_*/main through --derive without set -o pipefail) it could silently yield a short object instead of failing. Three lines: round hi up to the trailing align. Byte-neutral controls: md_SC07_003 clean rebuild BYTE-IDENTICAL, gate_main --assert-baseline BASELINE GREEN.

D. A GATE THAT CARVES LEAVES asm/ STALE, AND THE NEXT TOOL TO READ THE CORPUS REFUSES. An isolation writes INCLUDE_ASM(".../<new-subseg>", fn) into a NEW TU and parallel_gate commits that TU — but those .s files do not exist until a re-extract, so corpus.stubs correctly reports "the tree and the source disagree" and every later gate on that binary dies before it starts. Measured: ov_SC03_105 was left in exactly that state by its own SUCCESSFUL gate, and the next job reported only corpus refused in worktree — a true sentence naming nothing. Two fixes, both landed: the refusal now carries corpus's own message, and the merge step re-extracts any binary whose carve created a new source file, shouting if it is still unreadable afterwards. This is the R22 corollary (a config change needs a make extract, not just a make check) firing INSIDE a tool's own commit.

Found the way all three of these were found: an agent ran its own GATE REJECT to ground instead of respelling the body. That is the habit worth copying — a reject whose cause you have not named is not evidence about the C. Two of the three defects here were discovered by a drafting agent that refused to accept "the gate said no" as a fact about its own work.

The shared shape, worth checking in any tool you own: ask what the tool's answer is ABOUT (the current config), then ask what it READS (an asm tree, or a whole file it only partly owns). Where those differ, the tool will one day report a true fact about a world that no longer exists — and it will be believed, because it is the tool whose job is to be trusted.