Does the installable hypothesize-and-verify skill move the structure wall?
The one idea you need
Show the model only before-and-after examples and ask it to reverse-engineer the hidden chain of operations that produced them: a two-step chain, then a three-step one. The taught routine is a chef's tasting drill: shortlist likely ingredients, imagine the dish, taste-check against the real one, revise.
The question
If a small model can't reverse-engineer three-step transformations from examples, can you fix that by teaching it a step-by-step guess-and-check routine for finding them?
What we found
No. Fine-tuning the model on 1,476 worked guess-and-check traces doubled its success at the two-step depth it practiced on (lists jumped from 37% to 70%), yet did nothing one step deeper: three-step success stayed near 5%, statistically flat and no better than an untaught model. The skill installed cleanly, then refused to stretch a single operation further.
Why it matters
Match training depth to deployment depth: a model drilled on N-step reasoning gets strong at exactly N steps and stays at the floor at N+1. Hand deeper cases to external search or more thinking budget, not a smarter prompt.
On this page
Results at a glance 3
How to read
Two bar groups: the practiced two-step depth and the deeper three-step depth. In each, an untaught model and the routine-trained model appear for list tasks and string tasks. Height is the share of tasks whose operation structure was proposed correctly — taller is better.
Takeaway → At two steps the trained bars roughly double the untaught ones; at three steps all four bars collapse to the floor together — the skill does not stretch across depth.
Data table
| condition | base (lists) | procedure-trained (lists) | base (strings) | procedure-trained (strings) |
|---|---|---|---|---|
| depth 2 (practiced) | 36.7% | 70% | 33.3% | 56.7% |
| depth 3 (one deeper) | 3.3% | 10% | 6.7% | 6.7% |
Numbers from runs/verdict.json (cells), runs/eval_{base,dsl_sft}.json
Technical framing
The taught search routine doubles structure proposal at its practiced depth -- and moves nothing one step deeper — QLoRA on 1,476 truth-blind hypothesize-and-verify traces (depths 1-2 only, think channel). Depth-2 proposal doubles with parse-rate 1.00 and zero depth-1 forgetting; the pooled depth-3 contrast is not significant (Holm p=0.55). Serial-strategy installs are depth-local.
How to read
One bar per approach to the three-step task: the untaught baseline, a prompt-only routine scaffold, a borrowed prior skill applied as-is, and full routine fine-tuning. Height is the share of three-step tasks solved with correct structure; higher is better.
Takeaway → Every bar sits within a few points of the low untaught baseline, and none clears the pre-set improvement bar — the three-step wall is untouched by how the routine is delivered.
Data table
| condition | pooled list+string depth-3 coverage@12 |
|---|---|
| base | 5% |
| + procedure scaffold (prompt only) | 8.3% |
| prior-skill adapter zero-shot | 3.3% |
| DSL procedure-SFT | 8.3% |
Numbers from runs/verdict.json (primary)
Technical framing
All three routes into the wall fail the pre-registered depth-3 contrast — One-sided paired bootstrap vs base, Holm-corrected: +0.033 (p=0.41), -0.017 (p=0.82), +0.033 (p=0.55). The wall replicates in-house (base no-think anchor at the historical floor; thinking@1024 alone does not clear it). The scaffold null is format-confounded (parse rate 0.89 -> 0.44-0.67).
How to read
Three task groups. First the borrowed skill on its own home task, paired against its known score. Then two new task types (list and string, two-step), each pairing that same skill against a plain untrained model. Height is accuracy; higher is better.
Takeaway → On home turf the skill matches its known score (92% vs 91%); on the new task types it drops to near zero, even below the untrained model — it interferes rather than transfers.
Data table
| condition | C45 adapter | reference (committed C45 headline / base model on DSLs) |
|---|---|---|
| own substrate (held-out family) | 92% | 90.5% |
| list depth-2 | 0% | 36.7% |
| string depth-2 | 6.7% | 33.3% |
Numbers from runs/gate_c45.json, runs/verdict.json (cells), meta_induction verdict_general.json (0.905)
Technical framing
The routine is substrate-local: the verified prior adapter interferes instead of transferring — First pair: the regenerated adapter (0.920) vs the COMMITTED C45 adapter headline (0.905) on its own held-out family -- the rebuild is faithful (gate-verified before the DSL eval was spent). DSL pairs: the same adapter vs the plain base model -- ~zero transfer, dragging list depth-2 below base with degraded parsing (0.70-0.79). 'General induction' was family-general, not substrate-general.
In the author’s words from the Overview · “Results”
stats in runs/verdict.json; saga in experiment_log.md. The wall holds (C36 hardens). No arm clears the pre-registered pooled depth-3 Holm contrast: dsl_sft +0.033 (p_holm 0.55), scaffold +0.033 (0.41), c45_zero −0.017 (0.82); base depth-3 probe-robust cov@12 = 0.05 (wall replicates at think@1024; no C44 frame-shift — base_think_clears_wall=false). Zero-or-one-trained-window stratum: +0.019, n.s. The procedure installs, dramatically, WITHIN taught depths. dsl_sft (1,476 truth-blind d1/d2 traces, think-channel) doubles depth-2 structure proposal: list 0.37→0.70, string 0.33→0.57; deployable greedy@1 list 0.10→0.37; parse 1.00; zero d1 forgetting (0.85→0.85). … Read the full result →
Overview
Research Program
- Program:
structured_execution_and_compilers(×posttraining_and_adaptation) - Program question: the structure-wall arc terminates in C36 ("the fixed 4B cannot PROPOSE deep op-structure — a model-level law across substrates"); the induction-install arc terminates in C45 ("a GENERAL hypothesize-and-verify serial strategy is installable and transfers to a held-out family"). These two terminal laws make OPPOSITE predictions about one untested cell: aim the strategy at the wall.
- Prior anchors: C32/C36 (
qwen35_4b_structure_or_values,qwen35_4b_crosssubstrate_structure— the wall + the behavioral skeleton metric), C45 (qwen35_4b_meta_induction— the installable strategy, committed train_general.jsonl), C44 (serial-compute law; CoT mandatory), C39 (execute-given-rule gate discipline), C25/C34 (guided search never beat brute — but guidance was logit-level, never a TAUGHT strategy).
Question
Can the model's own serial hypothesize-and-verify loop — elicited by prompt scaffold, transferred zero-shot from the C45 adapter, or installed by a small DSL-native reasoning-SFT dose — lift op-STRUCTURE proposal on the list/string DSL substrates where the wall was measured? C36 predicts no arm moves (the wall is a capability bound); C45's logic predicts the serial strategy converts proposal into enumerate-and-check, which the model CAN execute (C32: execution-given-structure ≈ 1.0).
Hypothesis
The wall arc never tested a TAUGHT serial strategy — its negatives are direct sampling (C17), logit-guided search (C25/C34), and steering (C20). C44 says the missing ingredient for induction is serial compute in the CoT channel; C45 says the loop template generalizes across (affine) families. If the wall is a proposal-PROCEDURE deficit, arms 1–3 climb (scaffold ≥ some lift; DSL-native SFT most); if it is a hypothesis-SPACE deficit (the model cannot even enumerate candidate op-types against I/O evidence), all arms stay at base and C36 hardens. Falsifiers are asymmetric and both informative: any significant lift breaks C36's "un-installable" reading; a flat result with a passing trap-gate scopes C45's strategy to retrieval-adjacent families.
Setup
- Model: Qwen3.5-4B; QLoRA r32/α64 for SFT arms (C45 recipe: bs 2 + grad-accum 8, 2 epochs).
- Dataset/task source: contamination-free procedural DSL identification tasks from the C36
families.py(byte-identical copy): list (16 prims) and string (13 prims) families; behavioral min-depth verification rejects shallower-equivalent compositions (C13 discipline). - Train/eval split: frozen eval set, committed (
data/eval_tasks.jsonl): n=30 tasks per family × depth {2,3} (120 total), generated once (seed 71), each with 8 visible + 6 hidden examples. SFT-arm training tasks are depth-1/2 compositions with op-composition dedup vs ALL eval tasks (0 leakage, verified at build time). The C45-adapter arm trains only on the committed digit-affinetrain_general.jsonl(different substrate entirely — zero leakage by construction). Arms (shared eval; matched K=12 think samples at budget 1024, identical decode params; the ONLY variable is strategy provenance):
- base: C36's
ident_promptunchanged — the sample-more baseline (known: skeleton-coverage
falls off a cliff by depth; replicates the wall).
- scaffold (training-free, the pure-elicitation arm): same task rendering + an explicit
enumerate-and-verify procedure in the prompt ("shortlist candidate op types consistent with the I/O evidence; compose a candidate pipeline; mentally execute it on example 1; check against example 2; revise; only then write the function").
- c45_zero: C45 adapter (regenerated from committed train_general.jsonl), zero-shot on the
DSLs with the base prompt — does the installed meta-skill transfer across substrates?
- dsl_sft: reasoning-SFT on ~1,500 PROGRAMMATIC hypothesize-and-verify CoT traces (C45's
trace-template method — interpreter-generated, no teacher model) on depth-1/2 list+string tasks disjoint from eval; deploy think-mode. The install ceiling.
- base: C36's
- Baseline to beat: base arm at matched K (sample-more); secondary anchor: rand-skelfill@R (random skeletons + value-fill at matched interpreter budget — C32's value-fungibility control, CPU-only).
Controls / gates (pre-registered, run.py hard-stops):
- Trap gate (C43-mandatory): oracle-skelfill (true skeleton + value search) must solve
≥ 0.85 of eval tasks per family×depth — otherwise a proposal null is uninterpretable. 2. Skill-installed gate for dsl_sft: the trained model must reproduce the taught trace format on ≥ 0.8 of held-out depth-1 tasks AND its depth-1 correctness must not collapse vs base in the deploy channel (C29/C43 forgetting check) — else the arm tests a failed install. 3. c45_zero regen-sanity gate: the regenerated C45 adapter must reproduce C45's committed headline (held-out a7 induction-via-generation 0.905; gate = historical − 2×SE at n=200 → 0.87; initially miscalibrated to 0.95 from C44's shift number, corrected — see log) BEFORE its DSL eval is spent — else a flat arm is a failed rebuild, not evidence. Measured: 0.920. 4. Leakage: dedup at op-TYPE-SEQUENCE (skeleton) level between all SFT training tasks and all eval tasks (0 exact-skeleton overlap at any depth, verified at build); depth-3 window overlap is stratified, not excluded (see decision rule). 5. Smoke path with
_smokeartifact suffixes throughout (smoke can never poison a full run); run.py setsPYTORCH_CUDA_ALLOC_CONF=expandable_segments:Trueitself; launch with pipefail per docs/compute_environment.md. 6. Base-arm anchors: a cheap NO-think base pass ties this frozen eval to C36's historical numbers, with a pre-registered branch: if base-THINK@1024 itself clears the historical wall (skeleton-coverage@K ≥ 0.25 at depth 3), the experiment's frame shifts from "can the strategy move the wall" to "serial-compute dose already moves it" (a C44 result) and arm contrasts are interpreted against that elevated base. Decode pinned in configs/default.yaml (temperature 0.8/top_p 0.95 sampling, greedy pass separate; answer_max 512).- Primary metric: probe-robust skeleton-coverage@K per cell — ≥1 of K samples structure-correct under a MIMICRY-ROBUST extension of the C36 metric (review must-fix): some fill of the TRUE skeleton must reproduce the model program's behavior on the 8 visible inputs AND on 6 fresh probe INPUTS (labels never shown to the model) — lookup-table/hardcoded programs match visible but diverge on probes and are counted as a per-arm mimicry rate, reported alongside the legacy C36 metric for continuity. Secondary (characterization only, non-verdictive): greedy skeleton@1, full-solve coverage@K, per-family cells, depth-2 cells, code-parse rate per arm (a null with parse-rate far below base is pre-registered as "format-confounded", not "no transfer").
- Decision rule (pre-registered; power-corrected per review): PRIMARY contrast = each arm vs base on probe-robust skeleton-coverage@K, pooled list+string at depth 3 (n=60 tasks/arm; min detectable ~0.067, power 0.90 at true +0.15), one-sided paired bootstrap, Holm-corrected across the 3 arm-vs-base contrasts. C36's "un-installable/un-elicitable" reading falsified iff any corrected contrast has CI lower bound > 0 AND point diff ≥ +0.10 — with depth-3 results STRATIFIED by trained-window overlap (both/one/zero depth-2 sub-skeletons of the eval task seen in dsl_sft training): the falsification claim requires lift in the zero-or-one-window stratum (both-windows lift = composition of banked shallow structure, C24/C28 territory, reported as such). C45 scoped iff no corrected contrast moves (honestly: "no effect ≥ ~0.15 detectable") with all gates passing. Scaffold lift without SFT lift = elicitation-sufficient; SFT-only lift = installable-only (noting the pre-registered asymmetry: dsl_sft carries vocabulary+strategy, the scaffold strategy only). Prior-art conditioning: C28/C33 already installed depth-3 structure FROM oracle depth-3 content; the novel cell here is PROCEDURE-only transfer across depth (traces are depth-1/2 only; C21 is the negative prior for answer-banking across depth).
- Compute-parity (review must-fix): report per-arm mean prompt tokens, generated tokens/sample, total tokens/task, forced-close rate; base is additionally re-presented at K′ matched to the scaffold arm's total generated tokens. Pre-committed contingency: if a NULL arm shows forced-close > 50% at depth 3, run a budget-2048 probe on the depth-3 subset before concluding.
- Treatment freezing (review must-fix): the scaffold prompt text is checked in VERBATIM at
configs/scaffold_prompt.txt(zero op names / substrate hints — C30/C31 hint-leak discipline; includes an explicit do-not-hardcode instruction) and the dsl_sft trace generator implements the SAME factorized procedure: evidence extraction (length/sign/order/duplicate deltas) → per-stage candidate SHORTLIST from a fixed truth-independent feature→candidate rulebook → compose from shortlists in fixed order → mentally execute on example 1 with intermediate states → on failure localize the divergent stage and revise → verify on examples 2–3 → only then emit code. Traces are truth-BLIND by construction (candidate order and shortlists are pure functions of visible I/O; verified at build time by regenerating with the oracle blinded and byte-comparing); tasks the blind procedure cannot solve within the trace budget are dropped (C45 cot→None pattern, drop rate reported); kept traces' final candidate must also solve the hidden set (train-data purity filter, C45-standard). Traces train into the THINK channel with the final code block as the answer (bank-the-thoughtstrain_lora_thinkpattern — a stated recipe change vs C45, which aligns train and deploy channels). - Oracle-only metrics: oracle-skelfill gate, purity/leakage checks, rand-skelfill anchor. No oracle signal reaches any arm's prompt, training data selection, or decoding.
- Hidden-label boundary: hidden examples grade full-solve only; skeleton metric uses visible behavior + the true skeleton (evaluation-side oracle, standard for the wall arc).
- Known limits (pre-registered): single LoRA seed per SFT arm; K=12/n=30 resolves ~0.25 effects, not 0.10 subtleties; budget 1024 may truncate deep enumerate loops (report forced-close rates — C45 needed ≥400 tokens, C47 saw 99% truncation still work); register family deferred.
Run
Smoke:
python scripts/run.py --smokeFull (measured ~6 h main pipeline + ~3 h budget-2048 contingency probes on the RTX 4090; pre-run estimate was 9–11 h):
python scripts/run.py # idempotent; safe to re-run after interruption
python scripts/analyze.pyResults
Full narrative in reports/report.md; stats in runs/verdict.json; saga in experiment_log.md.
- The wall holds (C36 hardens). No arm clears the pre-registered pooled depth-3 Holm contrast: dsl_sft +0.033 (p_holm 0.55), scaffold +0.033 (0.41), c45_zero −0.017 (0.82); base depth-3 probe-robust cov@12 = 0.05 (wall replicates at think@1024; no C44 frame-shift —
base_think_clears_wall=false). Zero-or-one-trained-window stratum: +0.019, n.s. - The procedure installs, dramatically, WITHIN taught depths. dsl_sft (1,476 truth-blind d1/d2 traces, think-channel) doubles depth-2 structure proposal: list 0.37→0.70, string 0.33→0.57; deployable greedy@1 list 0.10→0.37; parse 1.00; zero d1 forgetting (0.85→0.85). Flat at depth-3 (0.10/0.07 vs 0.03/0.07): serial-strategy installs are depth-local — C21's cross-depth negative extends from banked answers to banked procedures.
- C45's skill is substrate-local. The regenerated adapter beats its own in-family headline (0.920 vs 0.905) yet transfers at ~zero to the DSLs, with active interference (list d2 0.37→0.00) and degraded parsing (0.70–0.79).
- Scaffold null is format-confounded (pre-registered reading): parse collapses to 0.44–0.67 vs base ~0.89 while coverage matches/edges base — the treatment text disrupts formatting more than it elicits search.
- Guards: mimicry ≤0.014 everywhere (probe-robust metric armed, barely needed); oracle-skelfill 1.00 all cells; rand-skelfill ≤0.07; traces byte-verified truth-blind; 0 task-level skeleton leakage (51/1,476 trace found-pipelines coincide with eval d2 skeletons, 0 with d3).
- Budget-2048 contingency (pre-committed): the d3 wall is partially BUDGET-limited for everyone. c45_zero 0.017 (null doubly confirmed); scaffold 0.150 — but the post-hoc base@2048 control doubles too (0.05→0.10, forced-close 0.84→0.75), and the paired matched-budget scaffold edge is +0.050 (CI-lo +0.000, p 0.043–0.051 across seeds — borderline, post-hoc, not verdict-grade). Serial-compute dose is the operative depth-3 margin; a small procedure margin beyond dose is unresolved at this n; even 2048 truncates 75–100% of thinking (dose-curve unfinished).
Interpretation
The wall is not a missing procedure. The model demonstrably learns and executes the full hypothesize-shortlist-check-revise loop (that is what 0.37→0.70 at parse 1.00 with zero forgetting means) and gains nothing one composition step past where the loop was practiced. With C21 (answers don't climb), C24 (diversity is in-depth dose), and C44 (induction is serial-compute limited): depth itself is the resource, and neither answers, diversity, nor procedure banks it across. C36 survives its strongest challenger; C45 gains a regime clause (family-general within its substrate, zero across substrates). Deployable takeaway: DSL-native procedure-SFT is the strongest in-depth structure-proposal lever measured on this substrate; the depth frontier still belongs to external search (C34/C35).
Knowledgebase Update
- Program evidence updated:
structured_execution_and_compilers×posttraining_and_adaptation - Claim ledger updated: C48 (this experiment); C21 annotated (cross-depth negative extends to procedures); C45 annotated (substrate-local scope clause)
Artifacts
src/—families.py(byte-identical C36 copy),gen_lib.py(C36 copy + the torch-2.12OOM_ERRORSAcceleratorError patch fromqwen35_4b_verifier_free_banking)scripts/—make_tasks.py(frozen eval + SFT-train tasks, leakage check),gen_traces.py(programmatic DSL hypothesize-and-verify CoT),train_lora.py(C45 recipe),eval_arms.py(shared K-sample eval + skeleton metric),run.py(orchestrator, gates),analyze.pydata/— frozen eval sets, SFT training pairs, trace corpusruns/— adapters (moved external before commit), eval JSONs, verdictreports/— design_review.md, report.md, artifact_manifest.yaml
Report
Rendered from reports/report.md
Summary
The wall holds — and the way it holds is the finding. Aimed the C45 hypothesize-and-verify serial strategy at the C32/C36 structure-proposal wall via three routes (training-free prompt scaffold, zero-shot C45-adapter transfer, DSL-native reasoning-SFT). No arm clears the pre-registered pooled depth-3 contrast (Holm-corrected; dsl_sft +0.033 p=0.55, scaffold +0.033 p=0.41, c45_zero −0.017 p=0.82; base depth-3 probe-robust coverage 0.05 — the wall replicates in-house at think@1024). But the install itself is dramatic within taught depths: DSL-native SFT on 1,476 truth-blind procedure traces (depths 1–2 only) lifts depth-2 structure proposal from 0.37→0.70 (list) and 0.33→0.57 (string) at parse-rate 1.00, deployable greedy 0.10→0.37 (list) — with zero depth-1 forgetting (0.85→0.85) and full trace-format adoption (1.00). The strategy is installable but depth-local: it does not extend one composition step beyond its training depth. C21's cross-depth negative (banked answers don't climb) now extends to banked procedures. And C45's skill is substrate-local: the regenerated adapter (0.920 on its own held-out family, above its 0.905 headline) transfers at ~zero to the DSLs and actively interferes (list d2 0.37→0.00). Both terminal laws survive with new scope clauses: the wall is not a missing procedure (C36 hardens); the installable-induction result is a within-regime skill, not a transferable faculty (C45 scoped).
Research Program Fit
structured_execution_and_compilers × posttraining_and_adaptation: the single cell where the program's two most mature terminal laws — C36 ("the fixed 4B cannot propose deep op-structure, a model-level law") and C45 ("a general hypothesize-and-verify strategy is installable serial compute") — made opposite predictions. Either outcome had to rewrite a law's scope; both got rewritten narrower.
Method
Frozen eval (committed, seed 71): list + string DSL identification tasks (byte-identical C36 families.py), 30 tasks per family × depth {2,3} = 120, each 8 visible + 6 hidden examples + 6 fresh probe INPUTS (labels never in any prompt), behavioral min-depth verified. Four arms at matched K=12 think@1024 samples (temp 0.8/top_p 0.95, answer_max 512) + 1 greedy pass; a no-think K=8 base anchor ties to C36's historical decode. Arms: base (C36 ident_prompt), scaffold (the same + a verbatim-frozen evidence→shortlist→compose-and-check procedure text, configs/scaffold_prompt.txt, zero op vocabulary), c45_zero (C45 adapter regenerated from its committed digit-affine train_general.jsonl, seed-pinned; gated at 0.920 ≥ historical 0.905 on 200 held-out-a7 episodes before its DSL eval was spent), dsl_sft (QLoRA r32/α64 on 1,476 programmatic hypothesize-and-verify traces — evidence extraction → truth-independent feature→candidate shortlists → fixed-order compose → mentally-executed checks with intermediate states → revise-at-first-divergence — generated on depth-1/2 tasks only, op-type-sequence-deduped vs ALL eval tasks (0 overlap at the task level; 51/1,476 traces' behaviorally-equivalent FOUND pipelines coincide with eval depth-2 skeletons, 0 with depth-3 — the primary d3 contrast is clean), truth-BLIND by construction (byte-verified by regenerating with the oracle fields deleted), trained into the THINK channel). Primary metric: probe-robust skeleton-coverage@K (the C36 behavioral metric hardened against lookup-table mimicry: the same true-skeleton fill must reproduce the model program's behavior on visible AND probe inputs). Decision rule: pooled list+string depth-3 (n=60), one-sided paired bootstrap, Holm across the 3 arm-vs-base contrasts; falsification requires CI>0 AND diff ≥ +0.10 in the zero-or-one trained-window stratum. Gates: trap (oracle-skelfill), c45 regen-sanity, install (format + no d1 collapse). Pre-committed contingency: budget-2048 depth-3 re-probe for any null arm with forced-close > 50%.
Results
1. The wall replicates and holds (C36 hardens). Base depth-3 probe-robust coverage@12 = 0.033 (list) / 0.067 (string); pooled 0.05. No arm's Holm-corrected pooled contrast is significant and none reaches the +0.10 falsification bar (dsl_sft +0.033, CI-lo −0.033; scaffold +0.033, CI-lo 0.000, p_holm 0.41; c45_zero −0.017). The pre-registered zero-or-one-window stratum for dsl_sft: +0.019 (p=0.42). c36_falsified_for_content_free_installs = false.
2. The procedure INSTALLS — massively — within its taught depths. dsl_sft depth-2 probe-robust coverage: list 0.367→0.700, string 0.333→0.567; full-solve (hidden set) list 0.333→0.700; deployable greedy@1 list 0.100→0.367, string 0.067→0.200; parse-rate 1.00; install gate: trace-format 1.00, depth-1 correctness 0.85 vs base 0.85 (zero forgetting — the think-channel recipe avoids C43's answer-only collapse entirely). The same model that runs the taught loop to a doubled depth-2 proposal rate gains nothing at depth-3 (0.10/0.07 vs base 0.03/0.07). The procedure does not compose one step past its training depth.
3. C45's skill is substrate-local and negatively transferring. c45_zero, whose regenerated adapter beats its own source headline in-family (0.920 vs 0.905), scores 0.00–0.07 across all DSL cells — below base at list depth-2 (0.37→0.00) — with parse-rate degraded to 0.70–0.79. The "general" in C45 was family-general (affine a∈{1,3,9}→7), not substrate-general.
4. The scaffold null is format-confounded (pre-registered reading). Scaffold parse-rate collapses to 0.44–0.67 vs base 0.86–0.91; its coverage still matches or edges base (list d3 0.10 vs 0.03, greedy d2 up to 0.20 vs 0.07 on string). Per pre-registration this arm reads "the scaffold disrupts output formatting", not "elicitation fails"; per-parsed-sample rates and the 2048-budget re-probe (below) qualify it further.
5. Pre-committed budget-2048 contingency: the depth-3 wall is partially BUDGET-limited — for everyone. The forced-close trigger (>50% at d3) fired for two of the three null arms (scaffold and c45_zero, both 1.00; dsl_sft 0.32 did not trigger; base was 0.84). At budget 2048 on the depth-3 subset (K=12): c45_zero 0.017 (was 0.033) — null doubly confirmed. Scaffold 0.150 (was 0.083) — which prompted a post-hoc base@2048 control: base itself doubles, 0.050 → 0.100 (forced-close 0.84 → 0.75, still truncation-bound). Paired at matched 2048 budget the scaffold edge is +0.050 (one-sided CI-lo +0.000, p 0.043–0.051 across bootstrap seeds — runs/verdict.json contingency_b2048) — borderline and post-hoc, not verdict-grade in either direction. Reading: serial-compute DOSE moves depth-3 coverage (a C44-consistent softening: 2× budget ≈ 2× coverage, from a very low floor); whether the taught procedure adds a small margin beyond dose is unresolved at this n. Even 2048 truncates 75–100% of thinking — the depth-3 budget dose-curve (4096+) is unfinished business, not settled wall.
6. Mimicry guard: armed, unneeded. Mimicry rates ≤ 0.014 in every cell — the lookup-table leak the design review predicted did not materialize at these budgets, but legacy-vs-probe-robust gaps (base list d2 0.43 vs 0.37) show the guard did catch real instances.
7. Compute parity. Scaffold costs more per sample (prompt 523 vs 286 tokens; gen 1459 vs 1195 at d2) and still doesn't move depth-3; K′-matched base (K′=14, capped at stored K=12) leaves base d3 at 0.05 — no accounting trick closes the dsl_sft d2 gap (dsl_sft traces are also shorter at deploy, parse 1.00, making its d2 win compute-favorable).
Controls
Trap gate: oracle-skelfill 1.00 in all four cells (a proposal null is interpretable; C39/C43 discipline), rand-skelfill@12 ≤ 0.07 (structure is not value-searchable by luck at this budget). Blindness: traces byte-identical when regenerated with oracle fields deleted. Leakage: 0 op-type-sequence overlaps between SFT tasks and eval; depth-3 window-overlap stratified instead of excluded. Regen-sanity: the c45 gate initially FAILED at a miscalibrated 0.95 threshold (C44's shift number, not C45's 0.905 headline) — corrected to historical−2SE (0.87) with the measurement (0.920) unchanged; lesson codified. No-think anchor: base no-think d2 0.07–0.10, d3 0.00–0.03 — consistent with C36's historical floor; think@1024 alone does NOT clear the wall (no C44 frame-shift; base_think_clears_wall=false).
Oracle Versus Deployable Evidence
Oracle appears only in: eval grading, the trap gate, trace purity filtering (C45-standard programmatic generation), and probe labels computed at eval time. Deployable evidence: the dsl_sft depth-2 gains are fully deployable (greedy@1 0.10→0.37 list at parse 1.00 with no oracle at inference); the depth-3 null is measured under the same deployable protocol.
Interpretation
The wall is not a missing procedure — it is not fixable by teaching the model how to search. The dsl_sft arm proves the model can learn, format, and execute the full hypothesize-shortlist-check-revise loop (doubling proposal exactly where the loop was practiced) while gaining nothing one composition step deeper. Combined with C21 (banked answers don't climb), C24 (gains scale with in-depth diversity), and C44 (induction is serial-compute-limited), the sharpest available statement is: serial-strategy training buys depth-local competence; depth itself is the resource that neither answers, nor diversity, nor procedure can bank across. C45's "general induction is installable" survives only with a regime clause — general across families within a substrate and depth regime, zero across substrates (and negative-transfer prone). For deployment: DSL-native procedure-SFT is the best in-depth structure-proposal lever measured to date on this substrate (d2 coverage 0.70 vs banking-era numbers), but the depth frontier still belongs to external search (C34/C35 brute dominance) — among model-side levers only raw serial- compute BUDGET moved depth-3 at all (0.05→0.10 at 2× budget, Result 5), and that dose-curve, not any taught procedure, is the remaining open edge.
Next Experiments
- Depth-3 budget dose-curve: base coverage doubled 1024→2048 and thinking is still 75–100% truncated — run 4096/8192 on the d3 subset (all arms cheap at n=60) to learn whether the wall asymptotes or keeps yielding to serial compute (this would sharpen both C36 and C44).
- Depth-curriculum probe: traces at depths 1–3 (oracle content at d3, C28-style) vs depths 1–2 — is the depth-locality about practice at depth or about d3 procedure traces being ungeneratable blind? (The blind rulebook keeps 45–46% of d2 tasks after the purity filter — blind solve ≈51%; measure its d3 yield first, CPU-only.)
- Scaffold format repair: the scaffold arm's parse collapse (0.44–0.67) is mechanical — a format-hardened scaffold (explicit "end with the code block" + one worked example) isolates elicitation from formatting; cheap single-arm rerun.
- The C46 next-test still standing: skeleton-level P(True) ranking + judge-pruned beam at depth 4–5 (proposal is walled; RECOGNITION of partial structure is untested — forest-review option B).
- Cross-substrate install transfer: train the trace procedure on list, eval on string (and register) — is procedure-SFT substrate-local like C45's adapter, or does within-DSL transfer hold at matched depth?
Artifact Manifest
runs/verdict.json (primary contrasts, cells, strata, parity, gates), runs/eval_*.json (5 arms
- 3 budget-2048 probes: 2 pre-committed contingency + 1 post-hoc base control),
runs/gate_*.json,data/(frozen eval with probe inputs, 1,476 traces,
SFT tasks, gate tasks — all committed), configs/scaffold_prompt.txt (verbatim frozen treatment), analysis/hypothesize_verify_wall.png, reports/design_review.md (3-lens pre-registration review), experiment_log.md (full saga: gate miscalibration stop, recovery-path empty_cache crash, both codified). Adapters (lora_dsl, lora_c45, ~182 MB each) moved external — see reports/artifact_manifest.yaml.
Experiment log 8
Show the running log (8 entries, 2026-07-08 → 09)
Scaffold
Created as a new experiment scaffold.
2026-07-08 design + adversarial review (pre-GPU)
Selected from the post-C47 forest-review workflow (4 lenses, 13 candidates): the collision cell where C36 (wall is un-proposable structure) and C45 (hypothesize-and-verify is installable serial compute) make opposite predictions. Assets recon'd: C36 skeleton metric is behavioral (model_structure_correct), C45 traces committed (train_general.jsonl, adapter regenerable), scaffold arm confirmed novel repo-wide. Three-lens design review (reports/design_review.md): sound_with_fixes. Must-fixes applied to README: (1) mimicry-robust primary metric -- lookup-table code passes the legacy C36 metric by construction; probe-input extension + per-arm mimicry rate; (2) POOLED depth-3 primary contrast with Holm (per-cell n=30 has power 0.35 at +0.10 -- vacuous as pre-registered); (3) factorized evidence-pruned procedure (whole-pipeline enumeration covers <0.5% of skeleton space in 1024 tokens -- null by construction); (4) traces train into the THINK channel (C45's no-think recipe would make a flat SFT arm format noise); (5) truth-blind trace generator, byte-verified with oracle blinded; (6) c45_zero regen-sanity gate; (7) window-overlap stratification of depth-3 (C28/C33 already installed structure FROM oracle depth-3 content -- the novel cell is PROCEDURE-only transfer across depth, C21 negative prior); (8) compute- parity reporting + K' presentation; (9) scaffold text frozen verbatim (configs/scaffold_prompt.txt, zero op vocabulary per C30/C31 hint discipline); (10) no-think base anchor + pre-registered branch if base-think itself clears the wall (C44 dose result). Next: build scripts, smoke, run.
2026-07-08 full run, gate stop #1: c45 regen gate was miscalibrated, not the rebuild
Pipeline ran clean through trap gate (oracle-skelfill 1.0 all cells), trace-gen, dsl_sft train, and c45 regen train, then hard-stopped at the regen-sanity gate: a7 induction-via-generation 0.920 vs required 0.95. The 0.95 came from C44's SHIFT-experiment number (1.00); C45's actual historical held-out-a7 headline is 0.905 (meta_induction/runs/verdict_general.json). The regenerated adapter at 0.920 EXCEEDS its source. Corrected the gate to 0.87 (historical minus 2x binomial SE at n=200), re-judged the stored measurement (no GPU re-burn), relaunched. Lesson for the playbook: calibrate reproduction gates to the SOURCE experiment's committed artifact number, never to a neighboring claim's headline from memory.
2026-07-08 full run, crash #2: empty_cache raised INSIDE the OOM-recovery path
The OOM_ERRORS batch-halving patch WORKED (caught the scaffold-arm OOM at batch 48), but torch.cuda.empty_cache() on the recovery path itself raised torch.AcceleratorError and killed eval_arms mid-sweep. Fixes: (1) _safe_empty_cache() in gen_lib -- cleanup is retried once after 5s and never allowed to raise; (2) think-eval batch 48 -> 32 (scaffold prompts add ~200 input tokens x K=12 x budget-1024 KV). base + base_nothink evals survived on disk; pipeline resumes at scaffold. Compute-doc lesson at landing: wrap the CLEANUP call in OOM recovery, not just the generate call.
2026-07-08 RESULTS: the wall holds -- C36 hardens; the procedure installs in-depth but does not climb
PIPELINE COMPLETE (343.8 min + 2 recovered crashes). Pre-registered pooled d3 Holm contrasts: ALL ns (scaffold +0.033, c45_zero -0.017, dsl_sft +0.033; base d3 probe-cov 0.05 pooled -- wall replicates at think@1024, no C44 frame shift). THE RESULT: dsl_sft depth-2 probe-robust cov 0.37->0.70 (list) / 0.33->0.57 (string), parse 1.00 -- the taught factorized hypothesize-and-verify procedure ~doubles in-depth structure proposal -- but depth-3 flat (0.10/0.07 vs base 0.03/0.07). Procedure banking does not cross depth (C21's law extends from answers to PROCEDURES). c45_zero: zero substrate transfer, active interference (list d2 0.37->0.00, parse 0.70). Scaffold: format-confounded null per pre-registration (parse 0.44-0.67 vs base 0.89). Mimicry ~0.01 everywhere (metric guard held, unused). Strata (characterization): d3 zero-windows +0.14 (n=21) vs one-window -0.06 (n=32) -- non-monotone, noise. verdict.json + PNG written. Write-up next: claim ~C48 (wall is not a missing procedure; serial-strategy installs are depth-local), playbook + compute-doc lessons (safe empty_cache, gate calibration to source artifacts), adapters out, landing order.
2026-07-09 pre-committed budget-2048 contingency: c45_zero confirmed dead; scaffold flagged BUDGET-LIMITED
The forced-close contingency (>50% at d3 for null arms; actual ~0.83-1.00) fired for scaffold and c45_zero. Results @2048, d3 subset, K=12: c45_zero 0.017 (was 0.033) -- null confirmed, closed. scaffold 0.150 (was 0.083; base@1024 0.05), parse still 0.50, forced-close STILL 1.00 -- the scaffold null is budget-limited, not settled, and 2048 is still not enough budget for the taught loop. Confound: base was never run @2048 (serial-compute dose, C44). Launched the missing post-hoc control (base@2048, d3 subset) before concluding Result 5. Branches: base@2048 ~0.15 -> pure dose effect (wall softens with budget; scaffold adds nothing beyond dose); base@2048 ~0.05 -> the procedure text does real d3 work given budget (softens the headline). Primary pre-registered verdict (@1024) unaffected either way.
2026-07-09 base@2048 control: the scaffold's 2048 jump was DOSE, not procedure
base@2048 d3 = 0.100 (2x its 1024 value 0.05; forced-close 0.84->0.75). Paired matched-budget scaffold-vs-base @2048: +0.083, one-sided CI-lo +0.000, p=0.058 -- suggestive, post-hoc, n.s. [CORRECTED 2026-07-09: task_id pairing bug; true paired value +0.050, p 0.043-0.051 -- see the audit entry below] Verdict unchanged; Result 5 finalized: serial-compute dose moves d3 coverage for everyone (C44-consistent softening from a very low floor), the taught procedure adds no significant margin beyond dose, and even 2048 truncates 75-100% of thinking. The d3 budget dose-curve (4096+) is now the sharpest open edge on the wall. Write-up complete; adapters out; audit + landing next.
2026-07-09 numbers audit caught MY contingency-contrast bug; analyze.py now owns the computation
Three-agent adversarial audit (69+68+95 checks): every pre-registered @1024 number re-derives exactly, but my ad-hoc paired contrast for the b2048 probes was WRONG (+0.083): task_ids collide across families (30 unique ids for 60 d3 rows) and my dict pairing matched list-scaffold rows to string-base rows. The main analysis was safe (keys on (family, depth, task_id)). Fix: analyze.py now computes the contingency block itself with the correct key -- canonical: scaffold-vs-base@2048 diff +0.050, CI-lo +0.000, p 0.043-0.051 across seeds (borderline, post-hoc, not verdict-grade). Also fixed per audit: rulebook d2 yield ~51% solved/45-46% kept (was "48-60%"); trigger sentence (two of THREE null arms; d3 forced-close base 0.84, nulls 1.00, dsl_sft 0.32); leakage clause (51/1,476 trace found-pipelines coincide with eval d2 skeletons, 0 with d3 -- primary clean); viz chart-3 reference attribution (0.905 is the committed C45 headline, not base); gate_c45.json threshold field 0.87; manifest full_command includes the base control probe. Lesson (playbook- grade): never hand-compute a published statistic -- extend the committed analyzer; and never key task pairing on bare task_id (ids are only unique within family).
Figures 2
Data files 8
Result tables and metrics copied from the experiment folder — preview inline or open the raw file.
runs/eval_base_b2048.json158 kBruns/eval_base_nothink_smoke.json11 kBruns/eval_base_smoke.json11 kBruns/eval_c45_zero_b2048.json158 kBruns/eval_c45_zero_smoke.json11 kBruns/eval_dsl_sft_smoke.json11 kBruns/eval_scaffold_b2048.json158 kBruns/eval_scaffold_smoke.json11 kB
Reproduce
Smoke test
python scripts/run.py --smokeFull run
python scripts/run.py && python scripts/eval_arms.py --arm scaffold --budget-override 2048 --depths-only 3 --out-suffix _b2048 && python scripts/eval_arms.py --arm c45_zero --adapter runs/lora_c45 --budget-override 2048 --depths-only 3 --out-suffix _b2048 && python scripts/eval_arms.py --arm base --budget-override 2048 --depths-only 3 --out-suffix _b2048 && python scripts/analyze.pyRun steps are documented inside the experiment folder (README and scripts).

