Qwen35 4B WHY-Comment Install
The one idea you need
The team is trying to turn a small model that can write one function into one that can carry a task across many steps. Three earlier attempts to install coding cognition landed short of a clear win: a cheap proxy did not predict real coding, teaching the model to trace code was flat, and teaching it to debug (fix a broken function) nudged the score up only weakly. The new idea is the one most likely to matter: teach the model WHY a correct answer is correct — the reason behind each line — not just what the answer is. This experiment does that in the cleanest possible way. It generates 504 tiny correct Python functions and, on every meaningful line, writes a short comment giving the true reason that line is right (why this bound is n+1, why this starts at index 0, why this branch fires). Because the team builds each problem and its solution, they already know the reason for every line, so no bigger 'teacher' model is used, and every example is self-checked by running the code. The trick that makes this a clean test: code comments are ignored when the code is graded, so the model can be trained to write richly-commented code and then scored on plain coding exams with the comments thrown away — if the CODE got better, the act of explaining WHY is what did it, with nothing else to credit. The training material also looks nothing like the exams (the exams say 'write code from a description'; this teaches the same but with the reasons attached), so any improvement is real transfer.
The question
Does teaching the 4B to explain WHY each line of correct code is correct — as inline comments the grader ignores — make its actual code better on real coding exams (HumanEval + MBPP), and move the multi-step agentic score, without breaking function-writing?
What we found
The WHY idea paid off where it should — on writing correct functions — and did nothing where it shouldn't. We trained the 4B to write code with the causal reason for each line attached as an inline #WHY: comment (generated by construction, no teacher). Because test-graders ignore comments, this is a perfectly clean test: if the CODE improves, teaching WHY worked. It did — HumanEval +5 problems (76.2->79.3%), the biggest single gain of the whole program, and MBPP about even. But on the multi-step agentic harness it was flat (8/35, same as base). The mirror image of the repair bet, which helped the agentic loop but less on functions. Neither result is statistically airtight on its own, but the pattern is clean and mechanistic: teaching WHY improves per-function correctness; teaching the check-and-fix loop improves multi-step behavior. They fix different things. The obvious next move is to combine them — stack the WHY model and the repair model — and see if we get both gains at once, which would also be strong enough to trust. One operational note: the standard training recipe badly underfit the WHY comments (they are high-entropy text); it took 4x the training to actually install the behavior.
Why it matters
This is the program's fourth and most theory-driven attempt to INSTALL coding cognition. The first three attempts (a proxy, code-tracing, debugging) taught the team that passive skills reshuffle coding ability without raising it while loop/behavior training nudges it. Teaching WHY tests a different lever entirely — the causal reason behind a correct answer — and the inline-comment form is the cleanest experiment the team can run, because the grader ignores the comments, so a gain cannot be an artifact of the model being scored on its explanations. If it works, it validates that reasoning about WHY is trainable by a designed curriculum and unlocks a follow-on that strips the comments to check the improvement sticks; if it is flat, that is clean evidence to move the reasoning into the model's scratchpad (the next WHY variant) rather than guessing.
On this page
Results at a glance 1
pass rate / count · coding fitness signal (agentic in raw count of 35) →
Data table
| coding fitness signal (agentic in raw count of 35) | base | why_comment |
|---|---|---|
| HumanEval | 0.762 | 0.793 |
| MBPP | 0.565 | 0.555 |
| Agentic (of 35) | 8 | 8 |
Numbers from experiments/qwen35_4b_why_comment_install/reports/measure_review.md
In the author’s words from the Overview · “Results”
When run, runs/measure/transfer_summary.json records all four pass@1 numbers (base/treatment x HE/MBPP, counts + fractions), the per-problem paired deltas, and the frozen, tightened verdict. Separate deployable evidence (transfer, which is a real code improvement because the grader ignores comments) from the retention guard.
Overview
Research Program
- Program:
agentic_breadth_installation(cognitive-core coding sub-program) - Program question: can real, transferable coding capability be INSTALLED into base Qwen/Qwen3.5-4B by designed, contamination-free curricula, proven by transfer to held-out coding — and specifically, does teaching the 4B WHY a correct answer is correct (its causal/generating structure) install what teaching a passive skill (bet #1, NULL) and a loop behavior (bet #2, weak positive) did?
- Prior anchors: base coding baselines from
experiments/qwen35_4b_coding_fitness_harness— HumanEval 76.2% (strong function coder), MBPP 56.5%, agentic duet-eval 23% (8/35, weak agent). Bet #1 (qwen35_4b_exec_trace_install, execution-tracing) was NULL; bet #2 (qwen35_4b_self_repair_install, self-repair) was a WEAK POSITIVE (HumanEval +3, agentic 8/35 -> 10/35, 3-vs-1 discordant), teaching that loop/behavior curricula beat passive-skill ones.
Question
Does teaching the 4B WHY a correct answer is correct — by training on spec -> correct-solution rows where EACH meaningful line of the correct code carries a trailing #WHY: comment giving the true causal reason that line is correct — TRANSFER to real coding (HumanEval + MBPP pass@1, comments IGNORED by the grader), and (the primary target) move the agentic duet-eval, without regressing function-writing?
Hypothesis
The mechanism most likely to escape install != convert is teaching the GENERATING REASON of a correct answer, not just the answer. The inline-comment variant is the CLEANEST test: code comments are INERT to execution grading, so the WHY hypothesis is testable DIRECTLY with ZERO annealing — train the model to write richly-#WHY:-commented code, eval pass@1 with comments ignored; if the CODE improved, the WHY-annotation worked, unconfounded. The training prompt is a plain spec -> function framing with NO instruction to comment, so the WHY-writing behavior is the model's DEFAULT and fires on a plain eval prompt. Honest prior on a MEANINGFUL install (>= 3-problem gain with retention): ~35%; NULL remains a likely verdict and would fund the think-block WHY variant (bet #3).
Setup
- Model: only
Qwen/Qwen3.5-4B(rev851bf6e8…); ONE fresh r32/a64 QLoRA adapter trained from thebase_reserializedcomposite in a single stage. - Dataset/task source:
data/sft_why_comment.jsonl— 504spec -> correct solutionrows built byscripts/gen_why_comment_curriculum.py(construction seed 92450). Every row is verified by real execution (strip the#WHY:comments and the clean code passes all asserts; the commented code runs identically; the marker is strippable; every comment is line-specific and non-boilerplate). The task and solution are built BY CONSTRUCTION and the#WHY:text is emitted mechanically — NO teacher model. - Train/eval split: training is
spec -> #WHY:-commented correct code; evaluation is the held-outspec -> codeHumanEval (164) + MBPP (200) — deliberately disjoint surfaces, with the grader ignoring comments. The agentic duet-eval is the primary real target, run manually as a follow-on. - Baseline: base Qwen/Qwen3.5-4B on the same shared harness.
- Controls: contamination firewall (whole-word banned-benchmark-name audit, zero hits; distinctive code n-gram overlap, zero); comments inert to the grader; the base composite authenticated fail-closed (tree + weights) before training.
- Primary metric: greedy pass@1 on HumanEval + MBPP (shared fitness harness,
experiments/qwen35_4b_coding_fitness_harness/scripts/eval_pass1.py, referenced not copied). - Oracle-only metrics: none gate here; the agentic duet-eval is a follow-on confirm, not part of this cell's frozen consequence.
- Hidden-label boundary: the frozen, TIGHTENED two-directional consequence (INSTALLED_CODING requires a >= 3-problem gain / RETENTION_FAIL / NULL) is read once from the four pass@1 numbers; benchmarks are executed, never read as data.
Run
Smoke (no GPU, no writes):
python scripts/run.py --smokeGPU stages (each gated behind a staged adversarial review; see reports/preregistration.md for the exact commands and checkpoint order):
python scripts/run.py --stage train # r32/a64, 1 epoch, seed 92451
python scripts/run.py --stage merge # vendored composite merger
python scripts/run.py --stage measure # shared HumanEval+MBPP harness, both armsAgentic confirm (manual follow-on on the merged composite — the PRIMARY real target, base 8/35): run the duet-eval gen4 harness with --model-override set to large_artifacts/qwen35_4b_why_comment_install/merged/why_comment, exactly as bet #2's measure review documented for the self_repair composite.
Results
Not yet run. The install/merge/measure stages are gated behind staged reviews. When run, runs/measure/transfer_summary.json records all four pass@1 numbers (base/treatment x HE/MBPP, counts + fractions), the per-problem paired deltas, and the frozen, tightened verdict. Separate deployable evidence (transfer, which is a real code improvement because the grader ignores comments) from the retention guard.
Interpretation
Pending the sealed measurement. INSTALLED_CODING makes why_comment the program's reference composite and funds the agentic confirm plus the comment-strip anneal; RETENTION_FAIL realizes the commented-target generation shift; NULL means teaching WHY inline reshuffles-without-raising like the passive-skill bets and funds the pre-committed think-block WHY variant (bet #3), not a re-roll.
Knowledgebase Update
- Program evidence updated: pending measurement.
- Program backlog updated: pending measurement.
- Claim ledger updated: pending measurement.
Artifacts
scripts/— WHY-comment curriculum generator (construction + safe execution + inline-rationale audit), contamination module, vendored trainer/merger, fail-closedtrain_trial.py,measure_transfer.py,run.py.data/sft_why_comment.jsonl— the 504-row curriculum +curriculum_receipt.json;data/provenance/base_reserialized.json;data/contamination/.configs/,reports/,tests/reports/artifact_manifest.yaml
Report
Rendered from reports/report.md
Design-frozen report. The model-free construction is complete and verified; the train/merge/measure GPU stages are gated behind staged adversarial reviews and have not run. Results will be appended to the Results section once the sealed measurement is read.
Summary
Lifecycle 35 — cognitive-core coding bet #4 and the FIRST of the owner-specified WHY-not-WHAT family. Bet #1 (execution-tracing, a PASSIVE skill) was NULL; bet #2 (self-repair, a LOOP behavior) was a WEAK POSITIVE (HumanEval +3, agentic 8/35 -> 10/35, 3-vs-1 discordant) whose lesson was that LOOP/BEHAVIOR curricula beat PASSIVE-SKILL ones. This cell tests the mechanism most likely to escape install != convert: teach the 4B WHY a correct answer is correct — its causal/generating structure — not just WHAT it is. The rationale is placed as trailing #WHY: code comments bound to the exact line each explains, leaving the think channel essentially alone. A fresh r32/a64 LoRA trains (1 epoch, seed 92451) on 504 spec -> correct-solution rows whose correct code carries a #WHY: comment on every meaningful line; it merges onto base and is measured for TRANSFER + RETENTION on the shared HumanEval + MBPP fitness harness under a frozen, TIGHTENED two-directional consequence (INSTALLED_CODING requires a >= 3-problem gain).
The inline-comment variant is run FIRST because it is the CLEANEST test: code comments are INERT to execution grading (the harness runs the code and ignores comments), so the WHY hypothesis is tested DIRECTLY with ZERO annealing. If pass@1 rises, the CODE got better — unconfounded by any grader reading the rationale. The training signal is generated BY CONSTRUCTION (we build the problem and its correct solution, so we know why each line is correct; the #WHY: text is emitted mechanically per line) with NO teacher model, and looks like nothing in the benchmarks (commented synthetic families vs plain spec -> code).
Research Program Fit
The program's target is the base 4B's agentic/multi-step cognition gap: HumanEval 76.2% (strong function coder) vs duet-eval 23% (weak agent). Bet #1 showed a passive primitive reshuffles but does not raise coding capability; bet #2 showed a loop behavior nudges it. Bet #4 attacks the deeper question — does teaching the GENERATING REASON of a correct answer install capability that a bare correct answer does not? HumanEval/MBPP serve as the fast transfer + retention signal; the agentic duet-eval (base 8/35, self_repair 10/35) is the PRIMARY real target, run manually as a follow-on (not gated by this cell).
Method
- Curriculum (
scripts/gen_why_comment_curriculum.py, seed 92450). 15 parameterized synthetic function families over integer/list inputs (clamp, threshold-count, scaled-sum, absolute-gap, largest, even-index sum, factorial, branch-sum, scaled-list, spread, nested-triangle sum, above-average count, position-weighted sum, running-cap, countdown). A FROZEN mixed schedule biased to medium/long: short 120, medium 192, long 192 (504 total). For each row a correct function is generated BY CONSTRUCTION and each meaningful line is annotated with a trailing#WHY:comment stating the true causal reason that line is correct (the constraint/invariant/bound/edge it handles), emitted mechanically by the family generator. Each row: prompt = a plainwrite a functionframing (spec + signature + tests, matching how the eval prompts, with NO instruction to comment — so the WHY-writing behavior is the model's DEFAULT and transfers to a plain eval prompt); think = a single minimal line; answer = the correct solution with the#WHY:comments. - Per-row truth audit (never ship an unverified row), by REAL CPython execution. (1) STRIP the
#WHY:comments -> the clean code passes ALL its tests; (2) the COMMENTED code runs and passes them IDENTICALLY (comments inert — verified, not assumed); (3) the marker is distinctive and mechanically strippable (stripping reproduces the clean code, no#WHY:survives,#appears only as the marker); (4) every#WHY:comment is line-specific (references a token on its line) and the comments VARY within the row (non-boilerplate). Safety/termination: restricted builtins (no imports/I/O), only bounded for-loops (neverwhile), a per-call step cap that aborts runaway code. The committed corpus additionally re-executes end-to-end via--verify-corpus(used in smoke), and the unit tests independently re-grade every row with a separate assert-based grader. - Contamination firewall (
scripts/contamination.py). A committed banned set of all 668 HumanEval + MBPP function names (663 after the language whitelist) — zero whole-word hits over prompt + think + answer (including the#WHY:prose). A present-only code n-gram aid — zero shared 7-grams carrying a distinctive (non-idiom) token between the corpus's executable code (comments stripped) and benchmark solution code (51 shared spans, all pure control-flow idioms). The#WHY:vocabulary avoids the benchmark def-name collisions (count/find/sort/check/add/compare/maximum/minimum/first/multiply/divisor). Row-level uniqueness (504 unique prompts/task-ids; 504 unique (commented-code, tests) keys; 438 distinct commented sources). - Install (
scripts/train_trial.py-> vendoredscripts/train_think.py). One fresh r32/a64 adapter, epochs 1, lr 1e-5, batch 1, grad-accum 8, max-length 4096, w_think 0.2, w_close 0.2, seed 92451 (63 optimizer steps), from thebase_reserializedcomposite. The base is authenticated FAIL-CLOSED (in-cell provenance copy + full tree manifest + full 9 GB weights hash) before training. - Merge (vendored
scripts/merge_adapter.py) with--base-model= the base composite ->merged/why_comment. - Measure (
scripts/measure_transfer.py-> SHARED harness, referenced not copied). Base and why_comment, HumanEval 164 + MBPP 200, greedy pass@1, identical vLLM path; all four numbers (counts + fractions) + per-problem paired deltas + the frozen, tightened verdict recorded. The grader ignores comments, so a pass@1 gain is an unconfounded CODE improvement.
Results
Pending the sealed measurement. runs/measure/transfer_summary.json will carry pass_at_1{base,why_comment}{humaneval,mbpp}, the pass counts, the McNemar b/c paired deltas per dataset, and the frozen consequence. Deployable transfer evidence is a >= 3-problem pass@1 gain; the retention guard is the paired dataset staying within 0.02.
Construction facts already established (model-free):
- Corpus sha
040be350678ea0337b8fe0607f783aba9e9071f789471b0ea00f7ce1ebef2962, 504 rows, allwhy_comment; tiers short 120 / medium 192 / long 192; 3-4 tests per row; 3-8#WHY:comments per row; 504 unique (commented-code, tests) keys; 438 distinct commented sources. - Output length: full training render max 468 tokenizer tokens (median 329), measured against the pinned tokenizer — well under the 4096 cap; ZERO rows truncate, so the trainer's zero-skip contract holds by construction.
- Contamination: 668 banned benchmark names (663 after whitelist), 0 whole-word hits; 0 distinctive shared 7-grams (51 shared spans, all pure control-flow idioms; HF cache present so the aid RAN, not skipped).
- 58 unit tests green (present-only cache aids RUN with the HF cache; every row independently re-executed: strip -> clean passes all tests, commented code runs identically, marker strippable, every
#WHY:line-specific and non-boilerplate).
Controls
- Contamination firewall (banned-name audit + distinctive code n-gram overlap), both zero, so a benchmark movement cannot be memorization.
- Comments are inert to the execution grader, so any pass@1 gain is a CODE gain, not a grader artifact — this is the design property that makes the inline variant the clean test.
- Base composite authenticated fail-closed (tree + weights) before training and merge; a swapped composite aborts.
- Identical measurement path for both arms (the shared harness), so base and treatment pass@1 are directly comparable.
- Tightened consequence rule: a noise-level (<3-problem) bump reads NULL, fixing bet #1's letter-of-the-law false positive.
Oracle Versus Deployable Evidence
Deployable evidence = a >= 3-problem HumanEval/MBPP pass@1 gain (real, held-out spec -> code generation, comments ignored by the grader). The retention guard (the other dataset within 0.02) is a control on the forgetting risk, not a capability claim. The agentic duet-eval is the eventual deployable target but is a manual follow-on confirm, not gated here. No metric here uses hidden labels beyond the one-shot frozen verdict read.
Interpretation
Pending measurement. INSTALLED_CODING: teaching WHY inline improved the code (inert to the grader); why_comment becomes the program reference and funds the agentic confirm and the comment-strip anneal (does the code stay better once the model stops writing the comments?). RETENTION_FAIL: the commented-target generation shift is realized; reconsider dose. NULL: teaching WHY inline reshuffles-without-raising like the passive-skill bets — a preserved boundary finding that funds the think-block WHY variant (bet #3), not a re-roll of this inline one.
Next Experiments
- If INSTALLED_CODING: run the agentic duet-eval confirm on the why_comment composite; then the comment-strip anneal; consider stacking with self-repair.
- If RETENTION_FAIL: reconsider the dose / target length before any confirm.
- If NULL: advance to the think-block WHY variant (bet #3) — rationale in the think channel, anneal required to test transfer — rather than re-rolling this variant.
Artifact Manifest
See artifact_manifest.yaml — the trained adapter and merged composite live under large_artifacts/ (omitted from git); the curriculum, contamination fixture, base provenance copy, and receipts are in-repo and reproducibility-critical.
Experiment log 3
Show the running log (3 entries, 2026-07-18)
2026-07-18 — model-free construction frozen
Lifecycle 35, cognitive-core coding bet #4 and the FIRST of the owner-specified WHY-not-WHAT family. Mission: install real coding capability into base Qwen/Qwen3.5-4B via a designed, contamination-free curriculum, proven by transfer. Meta-context: bet #1 (execution-tracing, a PASSIVE skill) was NULL; bet #2 (self-repair, a LOOP behavior) was a WEAK POSITIVE (HumanEval +3, agentic 8/35 -> 10/35, 3-vs-1 discordant) — loop/behavior curricula beat passive-skill ones.
The bet: teach the 4B WHY a correct answer is correct (its causal/generating structure), not just WHAT it is — the mechanism most likely to escape install != convert. This INLINE variant puts the rationale as trailing #WHY: code comments bound to the exact line each explains, leaving the think channel alone. It goes FIRST because it is the CLEANEST test: code comments are INERT to execution grading, so the WHY hypothesis is tested with ZERO annealing — train on richly-commented code, eval pass@1 (comments ignored); if the CODE improved, the WHY-annotation worked, unconfounded. Provenance: NO teacher — the task and its correct solution are built BY CONSTRUCTION and the #WHY: text is emitted mechanically per line.
Built and verified (no GPU, no commit):
scripts/gen_why_comment_curriculum.py(seed 92450) — 504spec -> correct solutionrows across 15 parameterized synthetic function families, each meaningful line annotated with a trailing#WHY:causal comment. Per-row verified by real CPython execution: STRIP the#WHY:comments and the clean code passes ALL asserts; the commented code runs and passes them IDENTICALLY; the marker is distinctive and mechanically strippable; every#WHY:comment is line-specific (references a token on its line) and the comments VARY within the row (non-boilerplate). Corpus sha040be350678ea0337b8fe0607f783aba9e9071f789471b0ea00f7ce1ebef2962; tiers short 120 / medium 192 / long 192; 3-8 comments per row; 504 unique (commented-code, tests) keys; 438 distinct commented sources. Output length: full training render max 468 tokenizer tokens (median 329), measured against the pinned tokenizer — well under the 4096 cap; ZERO rows truncate.scripts/contamination.py+data/contamination/banned_function_names.json(668 benchmark function names, 663 after whitelist) — 0 whole-word hits over prompt + think + answer (including the#WHY:prose); 0 distinctive shared 7-grams between the corpus's executable CODE (comments stripped) and benchmark solution code (51 shared spans, all pure control-flow idioms). The#WHY:vocabulary deliberately avoids the benchmark def-name collisions (count/find/sort/check/add/compare/maximum/minimum/first/multiply/divisor).- Vendored
scripts/train_think.py(sha e0eca2a2…) andscripts/merge_adapter.py(sha cb9af8b4…), byte-identical to the chain trainer/merger. scripts/train_trial.py— fail-closed base authentication (in-cell provenance copy + tree manifest + full 9 GB weights hash); recipe r32/a64, 1 epoch, lr 1e-5, seed 92451 (63 optimizer steps).scripts/measure_transfer.py— invokes the shared fitness harness for both arms x both datasets; the grader IGNORES comments (the clean, unconfounded WHY test); frozen, TIGHTENED INSTALLED_CODING (>= 3-problem gain) / RETENTION_FAIL / NULL consequence, identical to bet #2's rule.scripts/run.py— checkpointed--smoke | --stage train | --stage merge | --stage measure; each GPU stage gated behind a staged adversarial review.- 58 unit tests green (present-only HF-cache aids RUN with the cache; every row independently re-executed by a separate assert-based grader);
run.py --smokegreen; boundary drills refuse.
Grep-fresh note: construction seed 92450 and training seed 92451 are fresh repo-wide as SEEDS (the only textual matches are incidental substrings inside unrelated hashes/floats). No training-seed collision.
No-annealing decision (frozen): the commented model IS the test; a comment-strip anneal is a documented FUTURE follow-on only if this clears the bar. Pre-committed next member of the WHY family if NULL: the think-block variant (bet #3).
GPU stages (train/merge/measure) are pending their staged reviews.
2026-07-18 — Recipe fix: epochs 1 -> 4 (epoch-1 undertrained)
- First train (epochs 1) gave train_loss 6.301 (10.3 start -> 4.2 end) - the #WHY: causal phrasings are high-entropy and 63 steps badly undertrained the target (vs exec_trace 0.70 / self_repair 1.15 in one epoch). A loss-4+ adapter has NOT installed the WHY behavior; measuring it would be a false NULL. Bumped to epochs 4 (252 steps) pre-measurement and re-froze. Watch: if loss still plateaus >~2.5, the WHY phrasing is too arbitrary -> regenerate the curriculum with more natural rationale.
2026-07-18 — Transfer measurement: target-specific weak positive (biggest fast gain)
- why_comment vs base: HumanEval 0.7622->0.7927 (+5 problems; 11 vs 6 discordant, McNemar p=0.332), MBPP -2, agentic 8/35->8/35 (symmetric 3v3, p=1.000). Frozen tightened rule fires INSTALLED_CODING on the +5 HumanEval. Comments inert to grading -> this is the CLEAN unconfounded test, so +5 is a real (if not significant) signal that teaching WHY improves per-function code quality.
- Recipe: epoch-1 undertrained (loss 6.3, high-entropy WHY phrasings); retrained 4 epochs (converged ~0.05) pre-measurement.
- CROSS-BET FINDING: why_comment (WHY) and self_repair (loop) are COMPLEMENTARY - why_comment best on HumanEval/function correctness, self_repair best on the agentic loop. Neither individually significant. -> NEXT: STACK self_repair + why_comment (both positive ingredients, different targets) to test complementarity and potentially reach significance. WHY think-block variant (bet #3) still queued as a separate probe.
Reproduce
Smoke test
python scripts/run.py --smokeFull run
python scripts/run.py --stage train && python scripts/run.py --stage merge && python scripts/run.py --stage measureRun steps are documented inside the experiment folder (README and scripts).