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).
This commit is contained in:
Drew T
2026-08-07 18:51:10 -06:00
parent 0ef53c7b22
commit a0236b2220
2 changed files with 44 additions and 9 deletions
+25 -8
View File
@@ -10597,17 +10597,34 @@ for this repo: `corpus.stubs` is address-keyed — convert with
is far more often a type error than a discovery. Real negatives are usually ragged. When a check
comes back perfectly empty, verify the comparison before believing the conclusion (R14/R37).
### §156 — a FAILED draft can still poison the fleet: the arity pre-pass residue (S45 p6)
### §156 — an ORPHANED reconcile poisons the fleet: `dedup_propagate`'s kept edit (S45 p6/p7)
`gate_stage`'s arity pre-pass (`fix_arity_callers --apply`, `gate_stage.py:316`) rewrites **caller
externs in the fleet-shared `src/shared/engine_core.h`** *before* the byte-gate runs. When the draft
then FAILS to bank, that edit can survive the undo — so a function that was **rejected** leaves a
changed signature behind, and every overlay that calls it stops compiling.
> **ATTRIBUTION CORRECTED (R14).** This section first blamed `gate_stage`'s arity pre-pass (finding
> **F1** of `docs/concurrency-design.md`). **That was wrong.** No arity journal from that session
> mentions `func_80146A6C` (checked: 74/26/4 entries), and the arity undo reported success in every
> log. F1 is real and still worth guarding — it just did not cause this. The commit message on
> `commit:1519` carries the same wrong attribution; corrected forward here, history not rewritten.
Observed live (S45 p6): `func_80146A6C` failed its gate, and its caller signature survived →
**The real mechanism.** `dedup_propagate --recover`'s Part B reconciles an overlay's conflicting
caller extern and, when that buys the byte-match, **deliberately leaves the edit on disk**
(`dedup_propagate.py`, "keep the reconcile on disk"). That is correct *while the function survives*.
But a function can still be dropped by a **later** iteration against a different `fail_ov`, and when
`plan` finally empties, the `sys.exit("[error] all candidates dropped …")` fired with **no restore**.
Observed live: reconciles kept for `ov_SC07_001..009`, then everything dropped, then exit — leaving
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**. This is finding **F1** of `docs/concurrency-design.md`, reproduced in production the same
day it was predicted.
failed check-all**.
**Fix (landed):** a **reconcile ledger** — every kept reconcile is recorded against its function,
undone the moment that function leaves `plan`, and all outstanding reconciles are restored before the
failure exit. Proved by `tools/test_reconcile_ledger.py`: applying a real reconcile for the exact
overlay+fn (35 edits across 18 files) then driving the ledger undo restores all 25 files
byte-identical.
**The generalizable law:** *a tool that deliberately leaves an edit on disk pending an outcome owes
a ledger for it.* "Keep it if this succeeds" is only half a transaction — the other half is undoing
it on every path that can later invalidate the success, **including the exit paths**.
**What it does NOT do:** it cannot false-bank. The gate compares against `config/check.<bin>.sha`
(the original retail bytes, written by no pipeline stage) and `INCLUDE_ASM` pastes the original
+19 -1
View File
@@ -190,7 +190,25 @@ stub on a named wall/behemoth/queue ledger** — 140/140 byte-identical througho
`--no-propagate`. F1 bracketing assertion CLEAN. **The 29 are ×1** — propagation is
deliberately OFF and is its own controlled step (see below).
## 🔴 F1 CONFIRMED IN PRODUCTION — read `docs/concurrency-design.md` before any parallel gating
## 🔴 THE 141/213 BREAKAGE — root cause CORRECTED (it was NOT F1)
**Cause: `dedup_propagate --recover` orphaned a kept caller-extern reconcile.** Part B keeps its
reconcile on disk when it buys the byte-match; a fn dropped by a LATER iteration (or the final
"all candidates dropped" exit) left that edit behind → no-proto'd externs for functions never
propagated → `ov_SC07_010: passing arg 2 of func_80146A6C makes pointer from integer` → 141/213 fail.
- **My first attribution to F1 was WRONG** (R14): no arity journal touched func_80146A6C (74/26/4
entries checked) and the arity undo reported success in every log. `commit:1519`'s commit message
carries the wrong attribution — corrected forward in cookbook §156, history not rewritten.
- **FIXED + PROVEN** (`commit:1521`, `commit:1522`): a reconcile LEDGER — every kept reconcile recorded
against its fn, undone when the fn leaves `plan`, all outstanding restored before the failure exit.
`tools/test_reconcile_ledger.py` applies a real reconcile for the exact overlay+fn (35 edits /
18 files) then asserts all 25 files byte-identical after the undo. PASS.
- **The trap that cost the most:** a broken tree makes EVERY later gate report `near`. Two batches
(4/4, 20/20) were void, not verdicts about the drafts. **A gate result on an unverified tree is
not evidence (R35).**
- **F1 is still real and still unguarded** — it just didn't cause this. Its guard (`GATE_NO_ARITY=1`
+ the bracketing assertion) remains the rest of Stage 1.
## 🔵 F1 (still open) — read `docs/concurrency-design.md` before any parallel gating
`gate_stage`'s arity pre-pass (`fix_arity_callers --apply`) writes the fleet-shared
`engine_core.h` + caller externs BEFORE the gate; when a draft **fails**, the edit can survive.
`func_80146A6C` failed its gate and left a caller signature behind → **141 of 213 binaries