Research log Small Model Experimentation
GitHub

Execution-Conditioned Repair LoRA Experiment

Trained code fixer memorizes bugs, never generalizes

The one idea you need

Show the model broken code, its own failed fix, and the exact test error that fix triggered, then train it to write a correction. Like a mechanic who memorizes repairs for the specific cars in the shop manual but stalls on any model the manual never listed.

The question

If you train a small model to fix its own broken code by showing it the failed attempt and the error it caused, does that skill work on brand-new bugs?

What we found

No. On bugs built from the same templates it practiced on, the fixer repaired all 60 of 60 cases, versus 11 of 60 with ordinary patch training and 6 of 60 with no training at all. But on bug types it never saw, every method fixed zero of 27, and scrambling or deleting the error message changed nothing. It memorized templates, not repair.

Why it matters

Impressive repair scores on familiar bugs can be pure template memorization. Test any small-model code fixer on bug types absent from training, and read the hidden tests: high patch-apply and visible-pass rates can mask zero real repair.

Familiar bug types fixed10% → 100%no-training retry vs after repair training, same bug families
Brand-new bug types fixed0 of 27every method, including no training at all
Best on new types, with vs without the error message3 of 27 vs 2 of 27coding-specialist model, one extra fix — too small to trust
Real GitHub bugs fixed0 of 3actual Flask and Requests tasks
On this page
  1. Results at a glance
  2. Overview
  3. Report
    1. Abstract
    2. Main Claim
    3. Model and Training
    4. Prompt
    5. Dataset
    6. Results
    7. Trace Controls
    8. Representative Cases
    9. Synthetic-to-Real Transfer Status
    10. Interpretation
    11. Reproducibility Artifacts
  4. Experiment log
  5. Figures
  6. Data files
  7. Reproduce
  8. Related

Results at a glance 7

Fixes go from perfect to zero on unseen bug types

How to read

Each group along the bottom is a way of training the model to fix its broken code; bar height is the share of bugs fixed after the first failed try. Darker bars are familiar practiced bug types, lighter bars are brand-new types. Taller is better.

0%25%50%75%100%frozen second attemptfrozen second attempt10%0%final-patch SFTfinal-patch SFT18.3%0%no-trace repair SFTno-trace repair SFT100%0%trace repair SFTtrace repair SFT100%0%shuffled-trace repair SFTshuffled-trace repair SFT100%0%

Takeaway → The three repair-trained methods hit full height on familiar bugs, but every brand-new-type bar sits flat at zero — memorization, not transferable repair.

Data table
conditionIID families (n=60)held-out families (n=27)
frozen second attempt10%0%
final-patch SFT18.3%0%
no-trace repair SFT100%0%
trace repair SFT100%0%
shuffled-trace repair SFT100%0%

Numbers from reports/v2_*_iid_results.json and reports/v2_*_family_holdout_results.json (summary.repair_after_first_failure@1)

Technical framing

Repair success collapses on held-out bug families (Qwen3-4B) — Repair-conditioned adapters solve 100% of same-family bugs but 0% of unseen families — template memorization, not transferable repair.

Coding-specialist model recovers only a sliver on new types

How to read

Bars group by four training methods for a model already specialized in code; height is the share of bugs fixed. Darker bars are familiar practiced types, lighter bars are unseen types. Taller is better.

0%25%50%75%100%final-patch SFTfinal-patch SFT28.3%0%no-trace repair SFTno-trace repair SFT100%7.4%trace repair SFTtrace repair SFT100%11.1%shuffled-trace repair SFTshuffled-trace repair SFT100%0%

Takeaway → Familiar bars again reach full height while unseen-type bars barely lift off the floor even with the error message shown — too tiny to credit.

Data table
conditionIID families (n=60)held-out families (n=27)
final-patch SFT28.3%0%
no-trace repair SFT100%7.4%
trace repair SFT100%11.1%
shuffled-trace repair SFT100%0%

Numbers from reports/coder_v2_*_iid_results.json and reports/coder_v2_*_family_holdout_results.json (summary.repair_after_first_failure@1)

Technical framing

Coding-specialist ablation: tiny held-out transfer, same IID saturation (Qwen2.5-Coder-3B) — The coder model recovers only 3/27 held-out repairs with traces vs 2/27 without — one success above the no-trace control, too weak to credit traces.

On new bugs, patches apply cleanly but fix nothing

How to read

Bars group by how much the prompt tells the model (real error, blank error, wrong-fix only, error-only, files hidden). One color is how often the patch applies without error, the other how often it truly fixes the bug. Fix higher is better.

0%25%50%75%100%tracetrace44.4%0%no traceno trace55.6%0%wrong patch onlywrong patch only18.5%0%trace onlytrace only92.6%0%gold file removedgold file removed18.5%0%

Takeaway → Apply-cleanly bars stand tall, up to 93%, while every real-fix bar is zero — getting a patch to apply is not the same as fixing the bug.

Data table
prompt modepatch apply raterepair rate @1
trace44.4%0%
no trace55.6%0%
wrong patch only18.5%0%
trace only92.6%0%
gold file removed18.5%0%

Numbers from reports/execution_conditioned_repair_paper.md (table: v2 Trace Adapter on v2 Held-Out Families)

Technical framing

Trace-prompt ablation on held-out families: patches apply but nothing repairs — Every prompt ablation repairs 0/27 held-out bugs even when most patches apply cleanly — execution traces show no causal benefit.

More training memorizes the practice set, adds no transfer

How to read

Two bars for how long the model was trained, short versus long. One color is fixes on the 20 practiced bugs, the other is fixes on set-aside bugs it never saw. Taller is better, especially the set-aside bar.

0%25%50%75%100%3-epoch adapter3-epoch adapter15%0%12-epoch adapter12-epoch adapter95%0%

Takeaway → Longer training lifts practiced-bug fixes from 15% to 95%, yet set-aside fixes stay flat at zero — extra training only deepens memorization.

Data table
Training lengthRepair rate on 20 training episodesRepair rate on 14 held-out episodes
3-epoch adapter15%0%
12-epoch adapter95%0%

Numbers from reports/failure_conditioned_trace_train20_results.json, failure_conditioned_trace_v2_train20_results.json, failure_conditioned_trace_results.json, failure_conditioned_trace_v2_results.json

Technical framing

More training buys memorization, not transfer (Qwen3-4B trace adapter) — Extending training from 3 to 12 epochs lifts train-set repair from 15% to 95%, yet held-out repair stays at exactly zero.

On new bugs, the fixer games the one visible test

How to read

Bars group by five training methods on unseen bug types. One color is how often the patch applies, the other how often it passes the shown test but fails the hidden ones. A tall second bar is bad — it means gaming.

0%20%40%60%Frozen second attemptFrozen second attempt18.5%14.8%Final-patch SFTFinal-patch SFT37%0%No-trace repair SFTNo-trace repair SFT44.4%37%Trace repair SFTTrace repair SFT44.4%44.4%Shuffled-trace repair SFTShuffled-trace repair SFT44.4%25.9%

Takeaway → For the repair-trained methods most applied patches pass the visible test yet fail the hidden ones — satisfying the shown check, not fixing the bug.

Data table
ConditionPatch appliesPasses visible test, fails hidden tests
Frozen second attempt18.5%14.8%
Final-patch SFT37%0%
No-trace repair SFT44.4%37%
Trace repair SFT44.4%44.4%
Shuffled-trace repair SFT44.4%25.9%

Numbers from report table (reports/execution_conditioned_repair_paper.md, v2 held-out-family results)

Technical framing

On new bug families, repair SFT learns to game the visible test (Qwen3-4B, v2 held-out) — Every applied trace-adapter patch on held-out families passes the visible test but fails hidden tests — overfitting, not repair.

Trying three fixes per bug still repairs none of them

How to read

Bars group by five training methods on unseen bug types. One color is the share fixed when keeping the best of three tries, the other is how often the patch applies. A taller fix bar is better.

0%20%40%60%Frozen second attemptFrozen second attempt0%18.5%Final-patch SFTFinal-patch SFT0%40.7%No-trace repair SFTNo-trace repair SFT0%44.4%Trace repair SFTTrace repair SFT0%44.4%Shuffled-trace repair SFTShuffled-trace repair SFT0%44.4%

Takeaway → The best-of-three fix bars are all zero while patches still apply — extra attempts buy nothing on bug types the model never practiced.

Data table
ConditionRepair success, best of 3 samplesPatch applies
Frozen second attempt0%18.5%
Final-patch SFT0%40.7%
No-trace repair SFT0%44.4%
Trace repair SFT0%44.4%
Shuffled-trace repair SFT0%44.4%

Numbers from report table (reports/execution_conditioned_repair_paper.md, v2 held-out-family best-of-3 results)

Technical framing

Sampling 3 candidates does not rescue held-out repair (Qwen3-4B, v2) — At temperature 0.2 with 3 samples per episode, patches still apply but repair@3 is 0 for every condition — more samples buy nothing.

Early pilot cleaned up formatting but never fixed the bug

How to read

Bars group by five training methods on the first pilot's unseen bugs. Colors show how often the patch applies, how often the output is valid code, and how often it actually fixes the bug. A taller real-fix bar is better.

0%20%40%60%80%Frozen second attemptFrozen second attempt0%7.1%7.1%Final-patch SFTFinal-patch SFT0%42.9%28.6%No-trace repair SFTNo-trace repair SFT0%57.1%57.1%Trace repair SFTTrace repair SFT0%71.4%64.3%Shuffled-trace repair SFTShuffled-trace repair SFT0%64.3%64.3%

Takeaway → Apply and valid-code bars climb toward 71% while the real-fix bar stays at zero for every method — surface polish, no repair.

Data table
ConditionRepair successPatch appliesOutput is valid Python
Frozen second attempt0%7.1%7.1%
Final-patch SFT0%42.9%28.6%
No-trace repair SFT0%57.1%57.1%
Trace repair SFT0%71.4%64.3%
Shuffled-trace repair SFT0%64.3%64.3%

Numbers from report table (reports/execution_conditioned_repair_paper.md, v1 held-out synthetic results)

Technical framing

v1 pilot: SFT fixed diff formatting, never semantics (Qwen3-4B, 14 held-out episodes) — In the first pilot, SFT raised patch applicability from 7% to 71% while repair success stayed at zero across all conditions.

In the author’s words from the Report · “Abstract”

We tested whether a single QLoRA adapter trained to repair after a failed patch outperforms a single final-patch SFT adapter. On an expanded synthetic IID split, failure-conditioned adapters solved all examples while the final-patch SFT repaired 11/60 and the frozen second-attempt baseline repaired 6/60. However, this success did not transfer to held-out synthetic bug families: every condition repaired 0/27 examples. A secondary coding-specialist ablation with Qwen2.5-Coder-3B reproduced the IID result and found a small held-out-family trace result, 3/27, compared with 2/27 for no-trace, 0/27 for shuffled-trace, and 0/27 for final-patch. … Read the full result →

Overview

This workspace implements the experiment brief in /root/.codex/attachments/67be2ef6-a2f4-424d-a411-f0479b10c076/pasted-text-1.txt.

Core question:

Does single-adapter QLoRA SFT on buggy repo + wrong patch + execution trace -> corrective diff improve executable repair over ordinary final-patch SFT?

The code is deliberately organized around the brief's required deliverables:

  • scripts/build_repair_dataset.py
  • scripts/sample_wrong_patches.py
  • scripts/compute_corrective_diffs.py
  • scripts/train_repair_lora.py
  • scripts/eval_repair_synthetic.py
  • scripts/eval_repair_swebench.py
  • scripts/run_trace_ablation.py

Current environment note: Docker can be installed but nested container execution is blocked by kernel namespace/mount restrictions in this runner. SWE-smith and SWE-bench scripts are present, but official Docker-backed evaluation is not considered verified until scripts/eval_repair_swebench.py --preflight-only passes.

Recommended first pass:

python scripts/build_repair_dataset.py --output-dir data
python scripts/compute_corrective_diffs.py --input data/repair_train.jsonl --output data/repair_train.checked.jsonl
python scripts/train_repair_lora.py --train data/repair_train.jsonl --eval data/repair_val_synth.jsonl --mode final_patch --output-dir models/final_patch_sft_lora
python scripts/train_repair_lora.py --train data/repair_train.jsonl --eval data/repair_val_synth.jsonl --mode no_trace --output-dir models/failure_conditioned_no_trace_lora
python scripts/train_repair_lora.py --train data/repair_train.jsonl --eval data/repair_val_synth.jsonl --mode trace --output-dir models/failure_conditioned_trace_lora
python scripts/eval_repair_synthetic.py --data data/repair_val_synth.jsonl --output reports/frozen_second_attempt_results.json --prompt-mode trace
python scripts/run_trace_ablation.py --data data/repair_val_synth.jsonl --adapter models/failure_conditioned_trace_lora --output reports/trace_ablation_results.json
python scripts/make_report.py --output reports/transfer_gap_report.md

Report

Rendered from reports/transfer_gap_report.md

Abstract

We tested whether a single QLoRA adapter trained to repair after a failed patch outperforms a single final-patch SFT adapter. On an expanded synthetic IID split, failure-conditioned adapters solved all examples while the final-patch SFT repaired 11/60 and the frozen second-attempt baseline repaired 6/60. However, this success did not transfer to held-out synthetic bug families: every condition repaired 0/27 examples. A secondary coding-specialist ablation with Qwen2.5-Coder-3B reproduced the IID result and found a small held-out-family trace result, 3/27, compared with 2/27 for no-trace, 0/27 for shuffled-trace, and 0/27 for final-patch. Three non-official direct pytest probes on SWE-bench Verified Flask/Requests tasks had base-fails/gold-passes behavior; the trace repair condition scored 0/3, and no Qwen3 repair condition solved any probe. Trace controls did not establish a causal benefit from execution traces. Official SWE-bench-style Docker execution is unavailable in this runner because Docker cannot register container layers (unshare: operation not permitted), so no valid real-task transfer ratio is claimed.

Main Claim

The experiment does not support the hypothesis that failure-conditioned trace SFT learns transferable execution-conditioned repair. The stronger observed effect is template-family memorization: the repair adapters master same-family synthetic validation but the primary Qwen3 adapters fail completely on unseen synthetic families. The coding-specialist ablation weakens the broadest version of that negative claim, but its 3/27 held-out-family result is small and only one success above the no-trace control.

Model and Training

  • Base model: Qwen/Qwen3-4B-Instruct-2507.
  • Revision: cdbee75f17c01a7cc42f958dc650907174af0554.
  • Quantization/training: 4-bit NF4 QLoRA, frozen base, BF16, rank 32, alpha 64.
  • Loss: assistant diff tokens only.
  • Compared adapters: final-patch SFT, no-trace repair SFT, trace repair SFT, shuffled-trace repair SFT.
  • Secondary model ablation: Qwen/Qwen2.5-Coder-3B-Instruct at revision 488639f1ff808d1d3d0ba301aef8c11461451ec5 for C/D/E/F.
  • Evaluation applies generated diffs to the wrong-patched tree and then runs visible and hidden tests.

v2 adapter metadata:

adaptermodelmodeshuffle_tracesrankalphadropoutepochslrmax_lengthtrain_records
coder_v2_failure_conditioned_no_trace_loraQwen/Qwen2.5-Coder-3B-Instructno_traceFalse32640.0530.000154096240
coder_v2_failure_conditioned_shuffled_trace_loraQwen/Qwen2.5-Coder-3B-InstructtraceTrue32640.0530.000154096240
coder_v2_failure_conditioned_trace_loraQwen/Qwen2.5-Coder-3B-InstructtraceFalse32640.0530.000154096240
coder_v2_final_patch_sft_loraQwen/Qwen2.5-Coder-3B-Instructfinal_patchFalse32640.0530.000154096240
v2_failure_conditioned_no_trace_loraQwen/Qwen3-4B-Instruct-2507no_traceFalse32640.0530.000154096240
v2_failure_conditioned_shuffled_trace_loraQwen/Qwen3-4B-Instruct-2507traceTrue32640.0530.000154096240
v2_failure_conditioned_trace_loraQwen/Qwen3-4B-Instruct-2507traceFalse32640.0530.000154096240
v2_final_patch_sft_loraQwen/Qwen3-4B-Instruct-2507final_patchFalse32640.0530.000154096240

Prompt

System prompt:

You are a coding agent repairing a repository. Output only a unified diff.
Do not explain. Do not include markdown fences.

User prompt template:

<ISSUE>
{issue_text}
</ISSUE>

<REPO_CONTEXT>
{opened_files_or_current_files}
</REPO_CONTEXT>

<CURRENT_DIFF>
{wrong_patch}
</CURRENT_DIFF>

<TEST_OUTPUT_AFTER_CURRENT_DIFF>
{traceback_stdout_stderr_or_apply_error}
</TEST_OUTPUT_AFTER_CURRENT_DIFF>

Task:
Produce the minimal corrective unified diff to make the repository pass the tests.

Prompt modes: final-patch SFT uses the original buggy files and targets base_buggy_diff; repair SFT uses the wrong-patched files and targets target_next_diff; no-trace blanks test output; shuffled-trace replaces test output with another training trace; wrong-patch-only removes repository file context and blanks test output; trace-only removes the current diff; gold-file-removed replaces file contents with a withholding marker.

Dataset

v1 Pilot

  • Dataset: local_synthetic_python_v1.
  • Tasks: 13.
  • Episodes: 64.
  • Splits: {'train': 50, 'val_synth': 14}.
  • Failure classes: {'assertion': 13, 'import': 13, 'syntax': 13, 'visible_pass_hidden_fail': 25}.
  • Bug families: {'algorithmic_edge': 5, 'boundary_condition': 5, 'case_normalization': 5, 'comparison_flip': 5, 'edge_case': 5, 'exception_case': 5, 'normalization': 5, 'off_by_one': 10, 'ordering': 9, 'parser_partial': 5, 'path_norm': 5}.

v2 Expanded Synthetic

  • Dataset: local_synthetic_python_v2.
  • Tasks: 66.
  • Episodes: 327.
  • Splits: {'train': 240, 'val_synth_family_holdout': 27, 'val_synth_iid': 60}.
  • Failure classes: {'assertion': 66, 'import': 66, 'syntax': 66, 'visible_pass_hidden_fail': 129}.
  • Bug families: {'case_normalization': 50, 'comparison_flip': 50, 'exception_case': 50, 'normalization': 50, 'off_by_one': 50, 'ordering': 50, 'path_norm': 15, 'tie_breaking': 12}.

v2 includes an IID validation split from trained bug families and a held-out-family split using path_norm and tie_breaking, which are absent from training.

v2 failure-class breakdown

Exact v2 train task IDs:

train_clamp_0, train_clamp_1, train_clamp_2, train_clamp_3, train_clamp_4, train_clamp_5, train_clamp_6, train_clamp_7, train_dedupe_0, train_dedupe_1, train_dedupe_2, train_dedupe_3, train_dedupe_4, train_dedupe_5, train_dedupe_6, train_dedupe_7, train_moving_average_0, train_moving_average_1, train_moving_average_2, train_moving_average_3, train_moving_average_4, train_moving_average_5, train_moving_average_6, train_moving_average_7, train_parse_bool_0, train_parse_bool_1, train_parse_bool_2, train_parse_bool_3, train_parse_bool_4, train_parse_bool_5, train_parse_bool_6, train_parse_bool_7, train_safe_get_0, train_safe_get_1, train_safe_get_2, train_safe_get_3, train_safe_get_4, train_safe_get_5, train_safe_get_6, train_safe_get_7, train_slugify_0, train_slugify_1, train_slugify_2, train_slugify_3, train_slugify_4, train_slugify_5, train_slugify_6, train_slugify_7

Exact v2 IID validation task IDs:

val_synth_iid_clamp_8, val_synth_iid_clamp_9, val_synth_iid_dedupe_8, val_synth_iid_dedupe_9, val_synth_iid_moving_average_8, val_synth_iid_moving_average_9, val_synth_iid_parse_bool_8, val_synth_iid_parse_bool_9, val_synth_iid_safe_get_8, val_synth_iid_safe_get_9, val_synth_iid_slugify_8, val_synth_iid_slugify_9

Exact v2 held-out-family validation task IDs:

val_synth_family_holdout_normalize_path_0, val_synth_family_holdout_normalize_path_1, val_synth_family_holdout_normalize_path_2, val_synth_family_holdout_top_k_0, val_synth_family_holdout_top_k_1, val_synth_family_holdout_top_k_2

Results

v1 Pilot Held-Out Synthetic

conditionstatusrepair_after_first_failure@1patch_apply_ratesyntax_valid_ratevisible_pass_hidden_fail_raterecordssuccesses
B. frozen second attemptok00.07142860.07142860.0714286140
C. final-patch SFTok00.4285710.2857140.0714286140
D. no-trace repair SFTok00.5714290.5714290.142857140
E. trace repair SFTok00.7142860.6428570.142857140
F. shuffled-trace repair SFTok00.6428570.6428570.214286140

v2 IID Synthetic

conditionstatusrepair_after_first_failure@1patch_apply_ratesyntax_valid_ratevisible_pass_hidden_fail_raterecordssuccesses
B. frozen second attemptok0.10.1833330.1666670606
C. final-patch SFTok0.1833330.3833330.3833330.03333336011
D. no-trace repair SFTok11106060
E. trace repair SFTok11106060
F. shuffled-trace repair SFTok11106060

v2 IID repair rate

v2 Held-Out-Family Synthetic

conditionstatusrepair_after_first_failure@1patch_apply_ratesyntax_valid_ratevisible_pass_hidden_fail_raterecordssuccesses
B. frozen second attemptok00.1851850.1481480.148148270
C. final-patch SFTok00.370370.1851850270
D. no-trace repair SFTok00.4444440.4444440.37037270
E. trace repair SFTok00.4444440.4444440.444444270
F. shuffled-trace repair SFTok00.4444440.4444440.259259270

v2 held-out-family repair rate

v2 Held-Out-Family Synthetic, Best-of-3 Sampling

Sampling used temperature=0.2, top_p=0.95, and three candidate diffs per episode. The @1 column is the first sampled candidate; @3 is best-of-three by hidden-test pass.

conditionstatusrepair_after_first_failure@1repair_after_first_failure@3patch_apply_ratesyntax_valid_ratevisible_pass_hidden_fail_raterecordssuccesses
B. frozen second attemptok000.1851850.1851850.185185270
C. final-patch SFTok000.4074070.1851850270
D. no-trace repair SFTok000.4444440.4444440.37037270
E. trace repair SFTok000.4444440.4444440.444444270
F. shuffled-trace repair SFTok000.4444440.4444440.259259270

Coding-Specialist Repair-Control Ablation

To test whether the primary held-out-family collapse was specific to Qwen3-4B, I trained the same v2 final-patch, no-trace repair, trace repair, and shuffled-trace repair adapters on Qwen/Qwen2.5-Coder-3B-Instruct. This is still a secondary ablation because the frozen B baseline was not rerun for the coder model, but it includes the trace-specific D/E/F controls needed to interpret the small held-out-family trace result.

splitconditionstatusrepair_after_first_failure@1patch_apply_ratesyntax_valid_ratevisible_pass_hidden_fail_raterecordssuccesses
IIDC'. coder final-patch SFTok0.2833330.60.53333306017
IIDD'. coder no-trace repair SFTok11106060
IIDE'. coder trace repair SFTok11106060
IIDF'. coder shuffled-trace repair SFTok11106060
Held-out familyC'. coder final-patch SFTok0000270
Held-out familyD'. coder no-trace repair SFTok0.07407410.6666670.6666670.296296272
Held-out familyE'. coder trace repair SFTok0.1111110.6666670.6666670.222222273
Held-out familyF'. coder shuffled-trace repair SFTok00.370370.370370.111111270

coding-specialist v2 ablation

v2 Transfer Gap View

v2 transfer gap

Trace Controls

v1 Trace Adapter on v1 Held-Out Synthetic

prompt_moderepair_after_first_failure@1patch_apply_ratesyntax_valid_ratevisible_pass_hidden_fail_ratesuccessesrecords
trace00.7142860.6428570.142857014
no_trace00.8571430.6428570.0714286014
wrong_patch_only00.2857140.2857140014
trace_only0.07142860.5714290.5714290.142857114
gold_file_removed00.1428570.1428570014

v2 Trace Adapter on v2 Held-Out Families

prompt_moderepair_after_first_failure@1patch_apply_ratesyntax_valid_ratevisible_pass_hidden_fail_ratesuccessesrecords
trace00.4444440.4444440.444444027
no_trace00.5555560.5555560.37037027
wrong_patch_only00.1851850.1851850.148148027
trace_only00.9259260.9259260.777778027
gold_file_removed00.1851850.1851850027

The requested evidence pattern normal trace > no trace, normal trace > shuffled trace, and normal trace > wrong-patch-only is not present. On v2 IID, no-trace, trace, and shuffled-trace adapters all repair 60/60. On v2 held-out families, all five ablation prompt modes repair 0/27.

Representative Cases

Same-Family Success

  • Episode: val_synth_iid_clamp_8::near_miss.
  • Task: val_synth_iid_clamp_8.
  • Bug family: comparison_flip.
  • Failure class: visible_pass_hidden_fail.
  • Outcome: patch_applied=True, visible_passed=True, hidden_passed=True.

Issue:

`clamp_value_8` should clamp a value into an inclusive range and reject inverted bounds.

Target corrective diff:

--- a/src/repair_target.py
+++ b/src/repair_target.py
@@ -4,5 +4,5 @@
     if value < lower:
         return lower
     if value > upper:
-        return value
+        return upper
     return value

Generated diff:

--- a/src/repair_target.py
+++ b/src/repair_target.py
@@ -4,5 +4,5 @@
     if value < lower:
         return lower
     if value > upper:
-        return value
+        return upper
     return value

Held-Out-Family Failure

  • Episode: val_synth_family_holdout_normalize_path_0::near_miss.
  • Task: val_synth_family_holdout_normalize_path_0.
  • Bug family: path_norm.
  • Failure class: visible_pass_hidden_fail.
  • Outcome: patch_applied=False, visible_passed=False, hidden_passed=False.

Issue:

`normalize_path_0` should collapse duplicate slashes, ignore '.', and resolve '..' without escaping above root.

Target corrective diff:

--- a/src/repair_target.py
+++ b/src/repair_target.py
@@ -3,8 +3,9 @@
     for part in path.split("/"):
         if part in {"", "."}:
             continue
-        if part == ".." and parts:
-            parts.pop()
+        if part == "..":
+            if parts:
+                parts.pop()
             continue
         parts.append(part)
     return "/" + "/".join(parts)

Generated diff:

--- a/src/repair_target.py
+++ b/src/repair_target.py
@@ -1,7 +1,7 @@
 def normalize_path_0(path):
-    parts = [part for part in path.split("/") if part]
+    parts = []
+    for part in path.split("/"):
+        if part in {"", "."}:
+            continue
+        if part == ".." and parts:
+            parts.pop()
+            continue
+        parts.append(part)
     return "/" + "/".join(parts)

Direct Real-Task Probe Failures

pallets__flask-5014
  • Instance: pallets__flask-5014 from pallets/flask.
  • Harness: direct_pytest_not_official_docker.
  • Base failed official FAIL_TO_PASS test: True.
  • Gold patch passed the same direct test: True.
  • Frozen first patch resolved: False.
  • Trace repair resolved after first failure: 0.0.

Frozen first patch:

diff --git a/src/flask/blueprints.py b/src/flask/blueprints.py
index 9d0a3d0..3d8d8f5 100644
--- a/src/flask/blueprints.py
+++ b/src/flask/blueprints.py
@@ -1,6 +1,6 @@
 import os
 import typing as t
-from collections import defaultdict
 from functools import update_wrapper
 
 from . import typing as ft
@@ -100,6 +100,10 @@ class Blueprint(Scaffold):
         if url_defaults is None:
             url_defaults = {}

+        if not name:
+            raise ValueError("Blueprint name must be non-empty.")
+
         self.name = name
         self.url_prefix = url_prefix
         self.subdomain = subdomain
@@ -108,6 +112,7 @@ class Blueprint(Scaffold):
         self.url_values_defaults = url_defaults
         self.cli_group = cli_group
...

Trace repair generated diff:

--- a/src/flask/blueprints.py
+++ b/src/flask/blueprints.py
@@ -99,7 +99,7 @@ class Blueprint(Scaffold):
         if url_defaults is None:
             url_defaults = {}

-        if not name:
+        if not name or not name.strip():
             raise ValueError("Blueprint name must be non-empty.")
 
         self.name = name

Observed failure:

error: patch failed: src/flask/blueprints.py:99
error: src/flask/blueprints.py: patch does not apply
psf__requests-5414
  • Instance: psf__requests-5414 from psf/requests.
  • Harness: direct_pytest_not_official_docker.
  • Base failed official FAIL_TO_PASS test: True.
  • Gold patch passed the same direct test: True.
  • Frozen first patch resolved: False.
  • Trace repair resolved after first failure: 0.0.

Frozen first patch:

--- a/requests/models.py
+++ b/requests/models.py
@@ -308,7 +308,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
         if not host:
             raise InvalidURL("Invalid URL %r: No host supplied" % url)

-        # In general, we want to try IDNA encoding the hostname if the string contains
-        # non-ASCII characters. This allows users to automatically get the correct IDNA
-        # behaviour. For strings containing only ASCII characters, we need to also verify
-        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
-        if not unicode_is_ascii(host):
-            try:
-                host = self._get_idna_encoded_host(host)
-            except UnicodeError:
-                raise InvalidURL('URL has an invalid label.')
+        # In general, we want to try IDNA encoding the hostname if the string contains
+        # non-ASCII characters. This allows users to automatically get the correct IDNA
+        # behaviour. For strings containing only ASCII characters, we need to also verify
+        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
+        if not unicode_is_ascii(host):
+            try:
+                host = self._get_idna_encoded_host(host)
+            except idna.IDNAError:
+                raise InvalidURL('URL has an invalid label.')
...

Trace repair generated diff:

--- a/requests/models.py
+++ b/requests/models.py
@@ -308,7 +308,7 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin):
         if not host:
             raise InvalidURL("Invalid URL %r: No host supplied" % url)

-        # In general, we want to try IDNA encoding the hostname if the string contains
-        # non-ASCII characters. This allows users to automatically get the correct IDNA
-        # behaviour. For strings containing only ASCII characters, we need to also verify
-        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
-        if not unicode_is_ascii(host):
-            try:
-                host = self._get_idna_encoded_host(host)
-            except UnicodeError:
-                raise InvalidURL('URL has an invalid label.')
+        # In general, we want to try IDNA encoding the hostname if the string contains
+        # non-ASCII characters. This allows users to automatically get the correct IDNA
+        # behaviour. For strings containing only ASCII characters, we need to also verify
+        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
+        if not unicode_is_ascii(host):
+            try:
+                host = self._get_idna_encoded_host(host)
+            except idna.IDNAError:
+                raise InvalidURL('URL has an invalid label.')
...

Observed failure:

error: patch failed: requests/models.py:308
error: requests/models.py: patch does not apply
psf__requests-6028
  • Instance: psf__requests-6028 from psf/requests.
  • Harness: direct_pytest_not_official_docker.
  • Base failed official FAIL_TO_PASS test: True.
  • Gold patch passed the same direct test: True.
  • Frozen first patch resolved: False.
  • Trace repair resolved after first failure: 0.0.

Frozen first patch:

@@ -100,7 +100,7 @@ def resolve_proxies(request, proxies, trust_env=True):
     proxies = proxies if proxies is not None else {}
     url = request.url
     scheme = urlparse(url).scheme
-    no_proxy = proxies.get('no_proxy')
+    no_proxy = proxies.get('no_proxy') or getproxies_environment()
     new_proxies = proxies.copy()
 
     if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy):
@@ -108,7 +108,7 @@ def resolve_proxies(request, proxies, trust_env=True):
         environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
 
         proxy = environ_proxies.get(scheme, environ_proxies.get('all'))
-        if proxy:
+        if proxy and proxy != 'http://':  # Skip empty or invalid proxy
             new_proxies.setdefault(scheme, proxy)
     return new_proxies

Trace repair generated diff:

--- a/requests/utils.py
+++ b/requests/utils.py
@@ -100,7 +100,7 @@ def resolve_proxies(request, proxies, trust_env=True):
     proxies = proxies if proxies is not None else {}
     url = request.url
     scheme = urlparse(url).scheme
-    no_proxy = proxies.get('no_proxy')
+    no_proxy = proxies.get('no_proxy') or getproxies_environment()
     new_proxies = proxies.copy()
 
     if trust_env and not should_bypass_proxies(url, no_proxy=no_proxy):
@@ -108,7 +108,7 @@ def resolve_proxies(request, proxies, trust_env=True):
         environ_proxies = get_environ_proxies(url, no_proxy=no_proxy)
 
         proxy = environ_proxies.get(scheme, environ_proxies.get('all'))
-        if proxy:
+        if proxy and proxy != 'http://':  # Skip empty or invalid proxy
             new_proxies.setdefault(scheme, proxy)
     return new_proxies

Observed failure:

error: patch failed: requests/utils.py:108
error: requests/utils.py: patch does not apply

Synthetic-to-Real Transfer Status

  • v2 IID trace gain over frozen second attempt: 0.9.
  • v2 held-out-family trace gain over frozen second attempt: 0.0.
  • Direct non-Docker SWE-bench Verified probe count: 3.
  • Direct non-Docker frozen second-attempt repair rate: 0.0.
  • Direct non-Docker trace repair rate: 0.0.
  • Direct non-Docker real-task gain: 0.0.
  • Direct non-Docker transfer ratio: 0.0.
  • Official Docker SWE-bench real-task gain: not measured.
  • Official Docker SWE-bench transfer ratio: not defined.

Direct non-Docker SWE-bench Verified probes:

instancerepoconditioninitial_resolved@1repair_after_first_failure@1end_to_end_resolved@2
pallets__flask-5014pallets/flaskA. frozen first patch0n/a0
pallets__flask-5014pallets/flaskB_frozen_second_attempt00.00
pallets__flask-5014pallets/flaskC_final_patch_sft00.00
pallets__flask-5014pallets/flaskD_no_trace_repair_sft00.00
pallets__flask-5014pallets/flaskE_trace_repair_sft00.00
pallets__flask-5014pallets/flaskF_shuffled_trace_repair_sft00.00
psf__requests-5414psf/requestsA. frozen first patch0n/a0
psf__requests-5414psf/requestsB_frozen_second_attempt00.00
psf__requests-5414psf/requestsC_final_patch_sft00.00
psf__requests-5414psf/requestsD_no_trace_repair_sft00.00
psf__requests-5414psf/requestsE_trace_repair_sft00.00
psf__requests-5414psf/requestsF_shuffled_trace_repair_sft00.00
psf__requests-6028psf/requestsA. frozen first patch0n/a0
psf__requests-6028psf/requestsB_frozen_second_attempt00.00
psf__requests-6028psf/requestsC_final_patch_sft00.00
psf__requests-6028psf/requestsD_no_trace_repair_sft00.00
psf__requests-6028psf/requestsE_trace_repair_sft00.00
psf__requests-6028psf/requestsF_shuffled_trace_repair_sft00.00

Direct-probe selection note: I preflighted every SWE-bench Verified task in the currently supported pallets/flask and psf/requests profiles. The validated direct slice includes tasks with base-fails/gold-passes behavior. Excluded same-profile candidates either failed gold validation under the local profile (psf__requests-2931) or could not install on Python 3.12 because older vendored urllib3 code imports removed stdlib symbols (psf__requests-1142, psf__requests-1724, psf__requests-1766, psf__requests-1921, psf__requests-2317).

Docker/SWE-bench preflight:

{
  "docker_preflight": {
    "ok": false,
    "probe_output": "Unable to find image 'hello-world:latest' locally\nlatest: Pulling from library/hello-world\n4f55086f7dd0: Pulling fs layer\n4f55086f7dd0: Verifying Checksum\n4f55086f7dd0: Download complete\ndocker: failed to register layer: unshare: operation not permitted\n\nRun 'docker run --help' for more information\n",
    "probe_returncode": 125,
    "server_version": "29.1.3"
  },
  "reason": "Docker preflight failed; official SWE-bench evaluation is not valid in this runner.",
  "status": "blocked"
}

The official real-task portion is blocked by the runner, not by a modeling decision. The direct probes are useful negative evidence, but they are not a replacement for the official Docker SWE-bench harness or a statistically meaningful real slice.

Interpretation

  1. Final-patch SFT is weaker than repair-conditioned SFT on same-family synthetic validation.
  2. The apparent same-family synthetic gain does not survive held-out-family validation.
  3. Execution traces are not shown to be causally useful in the current setup.
  4. A coding-specialist model can recover a small amount of held-out-family repair under the trace-conditioned objective, but the effect is weak: 3/27 for trace versus 2/27 for no-trace and 0/27 for shuffled-trace.
  5. Patch application and visible-test pass rates can be high while hidden repair remains zero, so executable hidden tests are essential.
  6. The current result is negative and should not be framed as successful synthetic-to-real transfer.

Reproducibility Artifacts

  • Dataset builders: scripts/build_repair_dataset.py, scripts/build_repair_dataset_v2.py.
  • Training: scripts/train_repair_lora.py.
  • Evaluation: scripts/eval_repair_synthetic.py, scripts/run_trace_ablation.py.
  • Direct real-task probe: scripts/eval_repair_swebench_direct.py.
  • v2 adapters: models/v2_final_patch_sft_lora, models/v2_failure_conditioned_no_trace_lora, models/v2_failure_conditioned_trace_lora, models/v2_failure_conditioned_shuffled_trace_lora.
  • Coder ablation adapters: models/coder_v2_final_patch_sft_lora, models/coder_v2_failure_conditioned_no_trace_lora, models/coder_v2_failure_conditioned_trace_lora, models/coder_v2_failure_conditioned_shuffled_trace_lora.
  • v2 result JSONs: reports/v2_*_results.json, reports/v2_trace_ablation_family_holdout_results.json.
  • Coder ablation result JSONs: reports/coder_v2_*_results.json.
  • Direct real-task result JSONs: reports/swebench_direct_flask5014_qwen3_results.json, reports/swebench_direct_requests5414_qwen3_results.json, reports/swebench_direct_requests6028_qwen3_results.json.

Experiment log 15

Show the running log (15 entries, 2026-06-19 → 20)

2026-06-19 Environment Setup

  • Read the experiment brief from /root/.codex/attachments/67be2ef6-a2f4-424d-a411-f0479b10c076/pasted-text-1.txt.
  • Hardware: NVIDIA RTX 6000 Ada, 48GB VRAM; BF16 supported.
  • Installed missing Python prerequisites: transformers, accelerate, datasets, peft, trl, bitsandbytes, plotting and test utilities.
  • Verified bitsandbytes CUDA support.
  • Verified primary model config:

    • Qwen/Qwen3-4B-Instruct-2507
    • revision cdbee75f17c01a7cc42f958dc650907174af0554
    • model type qwen3, 36 layers, hidden size 2560.
  • Installed Docker and started dockerd with bridge networking disabled, then with vfs storage.
  • Docker preflight failed at container layer registration with unshare: operation not permitted.
  • Conclusion: official SWE-smith/SWE-bench Docker-backed execution is not valid in this runner until kernel/container privileges change.

Synthetic Pilot Dataset v1

  • Built a local executable Python repair suite with 13 tasks and 64 wrong-patch episodes.
  • Splits:

    • Train: 50 episodes.
    • Synthetic held-out: 14 episodes.
  • Wrong-patch variants:

    • near miss
    • wrong localization
    • syntax error
    • import error
    • visible-test overfit
  • Failure classes:

    • assertion: 13
    • import: 13
    • syntax: 13
    • visible-pass-hidden-fail: 25
  • Correctness audit:

    • Recomputed every target_next_diff from current wrong-patched files to clean files.
    • 50/50 train target diffs applied and passed hidden tests.
    • 14/14 validation target diffs applied and passed hidden tests.

Frozen-Model Sampling Smoke

  • Loaded Qwen/Qwen3-4B-Instruct-2507 in 4-bit successfully.
  • Sampled first-patch outputs on two synthetic tasks.
  • Initial patch extraction failed on standard index ... diff headers; fixed extractor.
  • Model often emits plausible final-fix diffs against the original buggy file, but with bad hunk counts or against the wrong tree.
  • Added git apply --recount so count-mismatched hunks can apply when context is otherwise valid.

Frozen-Model Wrong-Patch Stream

  • Ran scripts/sample_wrong_patches.py over all 13 local tasks with one sample per task.
  • Output: data/frozen_wrong_patches_qwen3_local.jsonl.
  • Breakdown:

    • 13 total records.
    • 6 applied model patches.
    • 7 rejected/apply-error model patches.
    • 10 hidden-failing records usable as repair episodes.
    • 3 records already passed hidden tests and are not useful first-failure repair examples.
  • Filtered usable failures to data/frozen_wrong_patches_qwen3_local_failures.jsonl.
  • Correctness audit:

    • 10/10 filtered target diffs apply.
    • 10/10 filtered target diffs pass hidden tests.

This stream is small but more faithful to the brief than the scripted wrong-patch variants because W_i comes from the frozen Qwen3 model.

Baseline and Adapter Runs

All adapters used:

  • base model: Qwen/Qwen3-4B-Instruct-2507
  • revision: cdbee75f17c01a7cc42f958dc650907174af0554
  • 4-bit NF4 QLoRA
  • rank 32, alpha 64
  • target modules: Qwen attention projections and MLP projections
  • assistant diff tokens only in loss

Initial 3-epoch results on held-out synthetic v1:

Conditionrepair_after_first_failure@1patch_apply_ratesyntax_valid_rate
Frozen second attempt0.000.0710.071
Final-patch SFT0.000.4290.286
Failure-conditioned no-trace SFT0.000.5710.571
Failure-conditioned trace SFT0.000.7140.643
Failure-conditioned shuffled-trace SFT0.000.6430.643

Interpretation:

  • SFT improved diff format/application substantially.
  • It did not improve semantic repair on held-out tasks.
  • Normal trace beat shuffled/no-trace on patch application but not on hidden-test repair.
  • No scientific success claim is supported.

Undertraining Diagnostic

  • Trace adapter after 3 epochs repaired only 3/20 train episodes.
  • Shorter generation (max_new_tokens=256) did not improve this.
  • Trained a stronger trace adapter v2:

    • 12 epochs
    • gradient accumulation 4
    • learning rate 2e-4
    • LoRA dropout 0.0
  • v2 repaired 19/20 train examples, proving the pipeline can learn executable corrective diffs.
  • v2 repaired 0/14 held-out synthetic examples.

Interpretation:

  • The initial failure was partly undertraining, but the held-out failure remains after memorization.
  • Current synthetic v1 data does not support transfer beyond memorized task patterns.
  • The next experimental step should expand data diversity and task count, not further tune on the same 50 episodes.

Trace Ablations

Ran full held-out synthetic trace ablations for the 3-epoch core trace adapter:

Prompt moderepair_after_first_failure@1patch_apply_rate
normal trace0.0000.714
no trace0.0000.857
wrong patch only0.0000.286
trace only0.0710.571
gold-file context removed0.0000.143

Interpretation:

  • The required evidence pattern normal trace > no trace, normal trace > shuffled trace, and normal trace > wrong-patch-only is absent.
  • Trace-only producing one success while normal trace produced zero is likely noise on a 14-record slice, not evidence of useful trace grounding.
  • The current positive effect is mostly patch applicability/formatting, not execution-conditioned semantic repair.
  • The wrong-patch-only row above was rerun after fixing the stricter control definition to remove repository file context.

Current Hypotheses

  1. The core prompt/training/evaluation machinery is functional.
  2. The local synthetic v1 train set is too small and too template-specific for held-out task transfer.
  3. The model is learning patch formatting and current-tree anchoring before learning robust repair semantics.
  4. Execution traces may help formatting/anchoring but there is no evidence yet that trace content causes repair success.
  5. Official real-task transfer cannot be measured in this runner until Docker/SWE-bench execution works.

Next Actions

  1. Build a larger synthetic v2 dataset with many more train tasks per bug family and separate held-out families.
  2. Generate at least some wrong patches from the frozen model and filter for valid first-failure episodes.
  3. Re-run the C/D/E/F comparison on v2 with enough data to test transfer.
  4. Only after positive synthetic repair exists, spend compute on SWE-bench-style real slices.

2026-06-20 Synthetic v2 Expansion

  • Added scripts/build_repair_dataset_v2.py.
  • Built a larger executable synthetic dataset under data/v2.
  • v2 manifest:

    • 66 tasks.
    • 327 repair episodes.
    • 240 train episodes.
    • 60 IID validation episodes from trained bug families.
    • 27 held-out-family validation episodes from path_norm and tie_breaking.
    • 3 skipped episodes where a wrong patch already passed hidden tests.
  • Verified target corrective diffs:

    • 240/240 train target diffs applied and passed hidden tests.
    • 60/60 IID validation target diffs applied and passed hidden tests.
    • 27/27 held-out-family validation target diffs applied and passed hidden tests.
  • Trained four v2 adapters using the same base revision and QLoRA recipe:

    • models/v2_final_patch_sft_lora
    • models/v2_failure_conditioned_no_trace_lora
    • models/v2_failure_conditioned_trace_lora
    • models/v2_failure_conditioned_shuffled_trace_lora

v2 IID synthetic executable results:

Conditionrepair_after_first_failure@1patch_apply_ratesyntax_valid_ratesuccesses
Frozen second attempt0.1000.1830.1676/60
Final-patch SFT0.1830.3830.38311/60
Failure-conditioned no-trace SFT1.0001.0001.00060/60
Failure-conditioned trace SFT1.0001.0001.00060/60
Failure-conditioned shuffled-trace SFT1.0001.0001.00060/60

v2 held-out-family executable results:

Conditionrepair_after_first_failure@1patch_apply_ratesyntax_valid_ratesuccesses
Frozen second attempt0.0000.1850.1480/27
Final-patch SFT0.0000.3700.1850/27
Failure-conditioned no-trace SFT0.0000.4440.4440/27
Failure-conditioned trace SFT0.0000.4440.4440/27
Failure-conditioned shuffled-trace SFT0.0000.4440.4440/27

v2 held-out-family best-of-3 sampled results (temperature=0.2, top_p=0.95):

Conditionrepair_after_first_failure@1repair_after_first_failure@3patch_apply_ratesyntax_valid_ratesuccesses
Frozen second attempt0.0000.0000.1850.1850/27
Final-patch SFT0.0000.0000.4070.1850/27
Failure-conditioned no-trace SFT0.0000.0000.4440.4440/27
Failure-conditioned trace SFT0.0000.0000.4440.4440/27
Failure-conditioned shuffled-trace SFT0.0000.0000.4440.4440/27

Held-out-family trace ablation for models/v2_failure_conditioned_trace_lora:

Prompt moderepair_after_first_failure@1patch_apply_ratesyntax_valid_rate
normal trace0.0000.4440.444
no trace0.0000.5560.556
wrong patch only0.0000.1850.185
trace only0.0000.9260.926
gold-file context removed0.0000.1850.185

Interpretation:

  • v2 proves the training/eval pipeline can produce strong same-family synthetic repair behavior.
  • The same success does not transfer to held-out bug families.
  • The trace controls still do not show the required evidence pattern.
  • The normal trace adapter is not better than no-trace, shuffled-trace, or wrong-patch-only controls on hidden repair.
  • The result is a negative transfer result, not a positive execution-conditioned repair result.

Control audit:

  • Found and fixed a prompt-control bug: wrong_patch_only had incorrectly preserved repository file context, making it equivalent to no-trace.
  • Updated src/repair_experiment/prompts.py so wrong_patch_only removes repository file context and blanks trace output while preserving the current wrong diff.
  • Reran reports/v2_trace_ablation_family_holdout_results.json after the fix.
  • The corrected wrong-patch-only control still repaired 0/27 hidden cases, and its patch-apply rate dropped from 0.556 to 0.185.

2026-06-20 Report Generation

  • Regenerated the paper-style report at reports/execution_conditioned_repair_paper.md.
  • Also refreshed reports/transfer_gap_report.md to the same content for compatibility with the earlier report path.
  • Generated v2 figures:

  • Official SWE-bench-style Docker execution remains blocked by unshare: operation not permitted during Docker layer registration, recorded in reports/swebench_preflight.json.

2026-06-20 Coding-Specialist Ablation

Question:

  • Is the Qwen3-4B held-out-family collapse specific to the primary base model, or does a coding-specialist base show the same behavior?

Setup:

  • Model: Qwen/Qwen2.5-Coder-3B-Instruct.
  • Revision: 488639f1ff808d1d3d0ba301aef8c11461451ec5.
  • Same v2 train/eval splits and QLoRA recipe as the primary runs.
  • Trained the C/D/E/F coder adapter set:

    • models/coder_v2_final_patch_sft_lora
    • models/coder_v2_failure_conditioned_no_trace_lora
    • models/coder_v2_failure_conditioned_trace_lora
    • models/coder_v2_failure_conditioned_shuffled_trace_lora

Training checks:

  • Coder final-patch adapter final IID eval loss: 7.366e-05.
  • Coder no-trace adapter final IID eval loss: 3.829e-04.
  • Coder trace adapter final IID eval loss: 1.235e-04.
  • Coder shuffled-trace adapter final IID eval loss: 1.363e-04.

Deterministic executable results:

SplitConditionrepair_after_first_failure@1patch_apply_ratesyntax_valid_ratesuccesses
IIDCoder final-patch SFT0.2830.6000.53317/60
IIDCoder no-trace repair SFT1.0001.0001.00060/60
IIDCoder trace repair SFT1.0001.0001.00060/60
IIDCoder shuffled-trace repair SFT1.0001.0001.00060/60
Held-out familyCoder final-patch SFT0.0000.0000.0000/27
Held-out familyCoder no-trace repair SFT0.0740.6670.6672/27
Held-out familyCoder trace repair SFT0.1110.6670.6673/27
Held-out familyCoder shuffled-trace repair SFT0.0000.3700.3700/27

Interpretation:

  • The coding-specialist base reproduces the same-family synthetic sanity result.
  • Unlike the primary Qwen3-4B trace adapter, it finds 3 held-out-family repairs, so the broadest "zero transfer" claim is model-dependent.
  • The trace result has only a weak edge over controls: 3/27 for trace, 2/27 for no-trace, 0/27 for shuffled-trace.
  • This is suggestive enough to report as a secondary ablation, but too small for a strong causal trace claim.
  • The result remains a weak held-out-family transfer signal, not a SWE-bench transfer result.

2026-06-20 Direct Non-Docker SWE-bench Probe

Motivation:

  • Official SWE-bench Docker execution is still blocked by unshare: operation not permitted.
  • I built a direct local pytest probe for one SWE-bench Verified task to get at least some real-task evidence outside Docker.
  • This is not the official harness and should not be treated as a replacement for full Verified evaluation.

Task:

  • Instance: pallets__flask-5014.
  • Repo: pallets/flask.
  • Base commit: 7ee9ceb71e868944a46e1ff00b506772a53a4f1d.
  • Test: tests/test_blueprints.py::test_empty_name_not_allowed.
  • Context file shown to the model: src/flask/blueprints.py.

Harness validation:

  • Base + official test patch failed as expected.
  • Base + official test patch + official gold patch passed.
  • Local runner caveats:

    • Uses direct pytest, not Docker.
    • Uses a manually validated Flask dependency profile under Python 3.12.
    • Forces PYTHONPATH to the current worktree src directory so each worktree imports its own source.

Qwen3 primary direct-probe results:

Conditionrepair_after_first_failure@1end_to_end_resolved@2
Frozen first patchn/a0/1
Frozen second attempt0/10/1
Final-patch SFT0/10/1
No-trace repair SFT0/10/1
Trace repair SFT0/10/1
Shuffled-trace repair SFT0/10/1

Observed failure mode:

  • The frozen first patch recognized the semantic fix, adding a ValueError for empty blueprint names, but inserted the check at the wrong location and duplicated it.
  • The first patch did not apply cleanly.
  • The trace repair adapter generated another plausible local edit, but it was still anchored to the wrong hunk and did not apply.

Interpretation:

  • This one-task real probe gives real-task negative evidence consistent with the synthetic held-out-family result.
  • Direct non-Docker real gain for trace over frozen second attempt is 0.0.
  • Using the v2 IID synthetic gain of 0.9, the direct-probe transfer ratio is 0.0.
  • Because this is one task and not the official Docker harness, it is reported as a probe, not as the definitive SWE-bench result.

2026-06-20 Second Direct Non-Docker SWE-bench Probe

Motivation:

  • Add a second validated real task using the same non-Docker direct pytest runner.
  • Test whether the Flask negative result was an idiosyncratic failure of one repository layout.
  • Generalize scripts/eval_repair_swebench_direct.py to per-repository profiles instead of hardcoding Flask.

Task:

  • Instance: psf__requests-5414.
  • Repo: psf/requests.
  • Base commit: 39d0fdd9096f7dceccbc8f82e1eda7dd64717a8e.
  • Test: tests/test_requests.py::TestRequests::test_invalid_url[InvalidURL-http://.example.com].
  • Context file shown to the model: requests/models.py.

Harness validation:

  • Base + official test patch failed as expected with urllib3.exceptions.LocationParseError: Failed to parse: '.example.com', label empty or too long.
  • Base + official test patch + official gold patch passed.
  • Local runner caveats:

    • Uses direct pytest, not Docker.
    • Uses a manually validated Requests dependency profile under Python 3.12.
    • Forces PYTHONPATH to the current worktree root so each worktree imports its own source.

Qwen3 primary direct-probe results:

Conditionrepair_after_first_failure@1end_to_end_resolved@2
Frozen first patchn/a0/1
Frozen second attempt0/10/1
Final-patch SFT0/10/1
No-trace repair SFT0/10/1
Trace repair SFT0/10/1
Shuffled-trace repair SFT0/10/1

Observed failure mode:

  • The frozen first patch applied, but it added an idna.IDNAError handler in the non-ASCII-host branch instead of changing the ASCII leading-dot guard.
  • The visible test still failed with LocationParseError.
  • Every second attempt emitted the same stale first-attempt diff, which then failed to apply on top of the wrong-patched tree.

Updated direct-probe aggregate:

  • Validated direct probes: 2 (pallets__flask-5014, psf__requests-5414).
  • Frozen second-attempt repair rate: 0/2.
  • Trace repair SFT repair rate: 0/2.
  • Direct non-Docker real gain for trace over frozen second attempt: 0.0.
  • Using the v2 IID synthetic gain of 0.9, the direct-probe transfer ratio is 0.0.
  • The aggregate remains negative evidence only; official Docker SWE-bench execution is still blocked by the environment.

2026-06-20 Direct Runner Correction and Third Probe

Evaluation correction:

  • While inspecting psf__requests-6028, I found that the direct runner evaluated second attempts after a patch-apply failure as bad_first_patch + second_patch.
  • That is too strict for an apply-error failure: if the first patch does not apply, the repository remains at the original tree, so the second attempt should be evaluated as a replacement patch conditioned on the failed diff and apply-error trace.
  • I changed scripts/eval_repair_swebench_direct.py so:

    • if the first patch applied, repair is evaluated on top of the wrong-patched tree;
    • if the first patch did not apply, repair is evaluated as a standalone replacement patch on the original tree.
  • I reran affected direct probes pallets__flask-5014 and psf__requests-6028; both remained 0/1 for every Qwen3 condition.

Additional preflights:

  • psf__requests-6028: base failed and gold passed, usable.
  • psf__requests-2931: base failed but gold did not pass under the direct local profile, so excluded.
  • psf__requests-1142: local install failed on Python 3.12 because old vendored urllib3 imports MutableMapping from collections, so excluded.
  • psf__requests-1724: local install failed on Python 3.12 because old vendored urllib3 imports MutableMapping from collections, so excluded.
  • psf__requests-1766: local install failed on Python 3.12 because old vendored urllib3 cannot import ssl.match_hostname and lacks the backport, so excluded.
  • psf__requests-1921: local install failed on Python 3.12 for the same vendored ssl_match_hostname issue, so excluded.
  • psf__requests-2317: local install failed on Python 3.12 because old vendored urllib3 imports Mapping and MutableMapping from collections, so excluded.

Third task:

  • Instance: psf__requests-6028.
  • Repo: psf/requests.
  • Base commit: 0192aac24123735b3eaf9b08df46429bb770c283.
  • Tests:

    • tests/test_utils.py::test_prepend_scheme_if_needed[http://user:pass@example.com/path?query-http://user:pass@example.com/path?query]
    • tests/test_utils.py::test_prepend_scheme_if_needed[http://user@example.com/path?query-http://user@example.com/path?query]
  • Context file shown to the model: requests/utils.py.

Qwen3 primary direct-probe results:

Conditionrepair_after_first_failure@1end_to_end_resolved@2
Frozen first patchn/a0/1
Frozen second attempt0/10/1
Final-patch SFT0/10/1
No-trace repair SFT0/10/1
Trace repair SFT0/10/1
Shuffled-trace repair SFT0/10/1

Observed failure mode:

  • The frozen first patch omitted file headers, so it failed before tests.
  • Trace repair generated a file-scoped diff, but it edited resolve_proxies instead of the correct prepend_scheme_if_needed behavior and failed to apply.

Updated direct-probe aggregate:

  • Validated direct probes: 3 (pallets__flask-5014, psf__requests-5414, psf__requests-6028).
  • Frozen second-attempt repair rate: 0/3.
  • Trace repair SFT repair rate: 0/3.
  • Direct non-Docker real gain for trace over frozen second attempt: 0.0.
  • Using the v2 IID synthetic gain of 0.9, the direct-probe transfer ratio is 0.0.
  • Official Docker SWE-bench execution remains blocked by unshare: operation not permitted; the direct probes are negative supporting evidence, not an official SWE-bench score.

Figures 8

coder v2 ablation repair rate
coder v2 ablation repair rate · figures/
failure class breakdown
failure class breakdown · figures/
synthetic repair rate
synthetic repair rate · figures/
v1 repair rate
v1 repair rate · figures/
v2 failure class breakdown
v2 failure class breakdown · figures/
v2 family holdout repair rate
v2 family holdout repair rate · figures/
v2 iid repair rate
v2 iid repair rate · figures/
v2 transfer gap
v2 transfer gap · figures/

Data files 24

Result tables and metrics copied from the experiment folder — preview inline or open the raw file.

5 more result files not shown here — browse the full folder on GitHub.

Reproduce

Run steps are documented inside the experiment folder (README and scripts).

Browse the experiment folder on GitHub ↗