diff --git a/docs/accelerators.md b/docs/accelerators.md index 3c60b0530..f9a491996 100644 --- a/docs/accelerators.md +++ b/docs/accelerators.md @@ -357,3 +357,29 @@ So at every session/phase close, review the tooling against the idioms learned t *which scanner's denominator just got wider?* — the answer converts new knowledge into free banks. S68's own §332 sweep is the worked example: one idiom review, ten functions / 1,027 instructions reclassified from "hard" to "not bankable at all", and one in-flight escalation stopped mid-spend. + +## #16 — A "VERIFIED, JUST BANK IT" CLAIM MUST NAME THE COMPILATION IT SURVIVED (P31 S69) + +**What happened.** A session closed with "32 FREE BANKS ARE WAITING", 10 of them personally verified +with `match_one` at closeness 0. The next session gated them: **0 of 28**. Not one failure was a +codegen miss — every one was a declaration conflict inside the real translation unit. + +**Why the claim looked true.** `match_one` compiles the draft ALONE, with its own externs. The TU the +function must actually live in already carries a forward declaration written for a call site, and the +draft's real signature conflicts with it. **Closeness 0 is a statement about the BODY. Banking is a +statement about the TU.** They are different oracles and only one of them was consulted. + +**Why this belongs in a NEW decomp's day-one kit.** The trap is structural, not local to this project: +any per-function matching oracle compiles in isolation, and every real bank compiles in context. So: + +* every "already matches" claim ships with **which compilation it survived** (isolated / whole-TU / + whole-binary), the way every rate ships with its denominator (R41); +* the isolated oracle's output is a **GATE-FIRST candidate**, never a bank; +* budget for the integration lever, because it is the one that actually pays: 8 of those 28 banked the + moment the missing lever existed (the self-caller cast, cookbook §378), including one in `main` — + the project's most expensive binary — for **zero agent tokens**. + +**The corollary that cost the most time.** Fixing the first declaration error only REVEALS the second: +no-proto the conflicting decl and the draft's own definition becomes the prototype in scope, so the +same call site now fails with `too few arguments`. A class can look dead after one fix and be three +mechanical steps from banking. Drive the chain to a byte verdict before writing anything off. diff --git a/docs/next-session-triage-ladder.md b/docs/next-session-triage-ladder.md index 339114a49..06e5b08c5 100644 --- a/docs/next-session-triage-ladder.md +++ b/docs/next-session-triage-ladder.md @@ -1,4 +1,32 @@ -# NEXT SESSION — build the TRIAGE LADDER (spec, written S68 with full context) +# THE TRIAGE LADDER — **BUILT AND SHIPPED (P31 S69)** + +> **Status: DONE.** The tool is `tools/triage_ladder.py`. It is wired into `wave_args.py` (draw time) +> and `tools/workflows/escalate_fable.js` (escalation time), documented in `docs/SETUP.md` and +> `docs/wave-playbook.md` §4b, and its acceptance harness is green over the whole corpus: +> **false-skip 0/1367 open stubs · recall 426/426 matched · wall tier fires on exactly the 10 +> enumerated walls (0 extra, 0 missing)**. Run `tools/triage_ladder.py --acceptance` to re-verify. +> +> **Three things in the spec below were WRONG, and the corrections are the valuable part:** +> +> 1. **"32 FREE BANKS ARE WAITING" was not free.** 4 had already banked; the other 28 gated **0/28**. +> Every failure was a declaration conflict inside the real TU. `match_one` compiles the draft +> ALONE — a standalone closeness of 0 proves the BODY and says nothing about the TU accepting the +> SIGNATURE (cookbook **§376**). 8 of the 28 banked once the missing lever existed (**§378**, the +> self-caller cast, `tools/cast_self_callers.py`); the remaining 20 are on a named ledger at +> `.run/S69_class376_ledger.json`. +> 2. **The autodecl arm is WORSE in-tree than the raw draft** — the `extern` it adds to satisfy the +> standalone probe is a second conflicting declaration. Gate the raw draft. +> 3. **The spec conflated PRE and POST.** `residual_rules_b` needs a draft and runs `match_one`, so +> it cannot run at DRAW time. Only the target-side tiers (BANKED · WALL-332 · PARKED) can — and +> those are the ones that save a whole agent rather than one iteration. The tool splits them. +> +> One more, added by building it: **the ladder must not classify on a moving tree.** A merging gate +> makes the stub oracle wrong in BOTH directions (§377), which manufactures the exact false skip the +> ladder exists to prevent. It refuses unless the tree is quiescent. + +--- + +## The original spec, kept as written (S68) > Written deliberately so a session with NONE of S68's context can build this. The companion tool, > `tools/neighbor_ref.py` (retrieval), is already BUILT and committed — this is the other half.