3 Commits

Author SHA1 Message Date
Drew T cdd535e45b fix(tools): reconcile_tu's cc1 premise, the &-cast arms, and the worktree sig gap
The S74 checkpoint's "one unfixed defect that is actively costing banks"
(reconcile_tu manufacturing declaration conflicts), run to ground — plus the
harness gap that produced a false carve-corruption verdict.

reconcile_tu.py — three defects, measured against the real gcc-2.7.2 front end
(cdecl._cc1_accepts, the oracle cdecl.compatible was validated with; R33):
  * The premise "a decl BELOW still conflicts" is TRUE at file scope and FALSE
    at block scope. cc1 ACCEPTS a block-scope extern against a TU decl below it
    (pedwarn "type mismatch with previous external decl"); conforming it is
    destructive, because the TU's decl names the TU's TYPE and a type declared
    below the splice point is not in scope AT it -- the emitted result gets
    "syntax error before 'D_x'". Byte-witnessed on resident:func_800D06E8 (344
    ins), whose block-scoped `extern Blk80078E78` became `extern
    Struct80078E78`, typedef 388 lines lower. That construct is what this
    ladder's OWN scope_demote_drafts (§8d) rung emits on purpose, and three
    already-banked functions in that TU use it: one rung undoing another.
  * The cast pass rewrote COMMENT PROSE -- 8 rewrites inside one header comment,
    including inside a quoted cc1 diagnostic. Now matches on cdecl._mask
    (length-preserving, so a mask offset is a source offset) and splices into
    the original.
  * `&sym` emitted `&` applied to a cast: legal for the scalar arm, `invalid
    lvalue in unary '&'` (measured) for the array/fnptr/fnptr_array arms. `&`
    now selects a pointer form and consumes itself -- but ONLY with no trailing
    subscript, because `&sym[i]` is the address of ELEMENT i and the old code
    had that case right. That last clause exists because the R39 negative
    control caught the fold as a regression in the first cut of this fix.

gate_stage.py — `--skip-stages` / `GATE_SKIP_STAGES` (loud when used). Stage 0
gates raw drafts first, so a broken rung can only cost a RECOVERY, which is
exactly what makes it invisible: the function it destroys was already failing,
so its DIFF reads as a fact about the function.

verify_worktree.py / jr_isolate_all.py / parallel_gate.py — provision() now
symlinks every .run/sig.*.jsonl (main clone 259, provisioned worktree 0), the
third member of the class holding extracted/ and .run/obj40. parallel_gate was
fixed for this identical bug in S69: two provisioners, no shared list, found
twice; they now cross-reference each other. jr_isolate_all no longer swallows
the resulting FileNotFoundError into `except: continue` -- that turned a missing
index into a confident carve-CORRUPTION verdict over 2,603 of 2,603 functions
(R54). Adds _assert_scan_covered: attempted == raised means the scan measured
nothing, so its zero is an artifact, not a finding (R32).

Verification:
  * 4 cc1 probes (the table above), each run on the pinned front end.
  * R39 negative control over the stored-draft corpus: 661 adjudicated, 652
    IDENTICAL, 9 CHANGED and every one an intended class. 4,173 of 4,864 drafts
    unadjudicable (filenames that are not func_<ADDR>) -- stated, not hidden.
  * jr_isolate_all ov_SC03_105 --dry-run: unchanged in the main tree.
  * make clean/extract/build BINARY=resident -> 8e17e02f... BYTE-IDENTICAL.

Docs ship with the change (R21): cookbook §442/§443, index regenerated (1,112
sections), 3 docs/SETUP.md rows, CURRENT_PHASE S75 log.
2026-09-02 20:30:22 -06:00
Drew T e7ebb1cd45 docs+rules(S58): R42 commit-banked-work-immediately, R43 refuse-unsupported-input
R42: gate_main reverted 61 byte-proven overlay banks it could not distinguish from its own
substitution (sweep_parallel gates commit=False by design). Fixed by committing overlay banks
before the main batch, chunking main at 8 to bound bisect cost, and replacing every blind
'git checkout -- src/ config/' with commit-or-refuse in ox_campaign and idiom_serial.

R43: sweep_parallel had an explicit branch admitting main, which cannot be gated incrementally
— wave ab banked 0/105 main cards while its non-main cards banked 94/115 (82%), and the wave
read as a drafting failure. sweep_parallel now refuses main and names gate_main.py.

Also: validate_targets now prefers the card's own addr field (named symbols like SYS_OBJ_F00
were MALFORMED and discarded whole 220-card waves); ox_campaign deals model lanes by
smallest-ratio scheduling (a 73-card wave had put 73 shards on ox and 0 on deepseek);
docs/accelerators.md gains the four vacuous-check defects.
2026-08-23 12:59:59 -06:00
Drew T 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.
2026-08-07 19:06:15 -06:00