SWE Refactor Bench: Can Coding Agents Complete a Long-Horizon, Whole-Repository Stack Migration?
Organizations: Navers Lab, Einsia.AI · Tsinghua University
Abstract
Modern software systems accumulate technical debt over decades of development, which makes migration expensive and largely manual. As coding agents become increasingly capable at bug fixing, can they autonomously perform such migrations? Existing benchmarks cannot answer this question because they evaluate only behavioural correctness, not whether the migration actually occurred. This leads an easy hack: agents copy the original implementation to make tests pass. We call this Blindness. To address this problem, we introduce SWE Refactor Bench, a benchmark comprising 20 whole-repository migrations, covering 4 kinds of technical debt. A three-stage evaluation protocol measures both migration completeness and behavioural correctness. (1) Migration Audit verifies that the migration occurred. (2) Behavioural Tests measure correctness with a fixed test suite. (3) Agentic Verification uses 6 independent coding agents to generate targeted tests for hidden behavioural differences. Across 520 runs from 8 frontier models and 26 model-effort configurations, only 28 of 520 runs () pass all three stages, 13 of the 20 tasks receive no accepted solution, and the best model (claude-opus-5) scores . Migration completeness and behavioural correctness are distinct abilities: a few runs preserve behaviour by skipping the migration and are stopped at Migration Audit; most attempt it and break behaviour, and are stopped at Behavioural Tests. Agents cannot deliver a perfect migration: among the 340 runs that pass Migration Audit, reach of the fixed checks, yet only reach . Agent capability differs across migration categories: agents score on build toolchain rewrites but only on language rewrites. Together, these findings position SWE Refactor Bench as a rigorous testbed for developing coding agents for reliable whole-repository migrations.
Figures & tables
| Debt class | Representative migrations | Tasks | Source LoC | Budget | Criteria | Modules | Checks |
|---|---|---|---|---|---|---|---|
| (h) | (Stage I) | (Stage II) | (Stage II) | ||||
| Language | C Rust, C Java, Go Zig | 7 | 4.4 k–39.8 k | 12–30 | 60 | 117 | 59,771 |
| Framework | Flask Starlette, Gin chi, Vue React | 7 | 0.8 k–94.8 k | 6–16 | 39 | 79 | 55,852 |
| Platform | POSIX wasm32-wasi , Node V8 realm | 3 | 16.0 k–358.0 k | 6–10 | 19 | 31 | 6,725 |
| Build toolchain | Autotools CMake, Maven Gradle | 3 | 19.0 k–78.8 k | 6 | 18 | 37 | 7,770 |
| Total | 20 upstream projects, 20 tasks | 20 | 867,062 | 262 | 136 | 264 | 130,118 |
| Model | Harness | Effort | Behavioural pass | Score | Cost |
|---|---|---|---|---|---|
| % | out of 100 | USD / task | |||
| Claude Opus 5 | Claude Code | low | 92.5 | 20.5 | 34.8 |
| Claude Opus 5 | Claude Code | medium | 92.7 | 28.5 | 38.4 |
| Claude Opus 5 | Claude Code | high | 92.8 | 34.5 | 55.7 |
| Claude Opus 5 | Claude Code | xhigh | 92.8 | 47.0 | 74.9 |
| Claude Opus 5 | Claude Code | max | 91.9 | 31.0 | 72.4 |
| Migrated | All tests pass | Accepted | Broken | Blindness | Score | ||||
|---|---|---|---|---|---|---|---|---|---|
| Class | Tasks | Runs | % | % | mean | ||||
| Build toolchain | 3 | 78 | 63 | 80.8 | 36 | 6 | 82.4 | 2 | 31.4 |
| Platform port | 3 | 78 | 45 | 57.7 | 21 | 4 | 76.5 | 4 | 17.2 |
| Framework rewrite | 7 | 182 | 132 | 72.5 | 40 | 14 | 44.0 | 15 | 12.0 |
| Language rewrite | 7 | 182 | 100 | 54.9 | 21 | 4 | 66.7 | 9 | 5.6 |
| Migration Audit | Behavioural Tests | Agentic Verification | Final | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Category | Runs | % | % | % | Acc. | Score | |||
| Build toolchain | 78 | 63/78 | 80.8 | 34/63 | 54.0 | 6/34 | 17.6 | 6 | 31.4 |
| Platform port | 78 | 45/78 | 57.7 | 17/45 | 37.8 | 4/17 | 23.5 | 4 | 17.2 |
| Framework | 182 | 132/182 | 72.5 | 25/132 | 18.9 | 14/25 | 56.0 | 14 | 12.0 |
| Language | 182 | 100/182 | 54.9 | 12/100 | 12.0 | 4/12 | 33.3 | 4 | 5.6 |
| All | 520 | 340/520 | 65.4 | 88/340 | 25.9 | 28/88 | 31.8 | 28 | 13.4 |
| Called a real migration | Judge against human | ||||||
|---|---|---|---|---|---|---|---|
| Task | Class | runs | by human | by judge | agree | too strict | too lenient |
| lang01 (cmark) | Language | 26 | 7 | 6 | 25 | 1 | 0 |
| lang03 (sqlparse) | Language | 26 | 15 | 14 | 23 | 2 | 1 |
| fw02 (json-server) | Framework | 26 | 15 | 13 | 24 | 2 | 0 |
| fw06 (uploadserver) | Framework | 26 | 15 | 13 | 22 | 3 | 1 |
| pf02 (Stylus) | Platform | 26 | 14 | 12 | 24 | 2 | 0 |
| Benchmark | Unit of work | Starts failing | Stack changes | Migration criterion | Agentic verifier |
| SWE-bench [ 33 ] | one issue | ||||
| SWE-EVO [ 38 ] | one feature | ||||
| SWE-CI [ 10 ] | CI history | ||||
| Terminal-Bench [ 47 ] | one task | ||||
| TransCoder [ 53 ] | one function | ||||
| MigrationBench [ 44 ] | whole repository |
Appendix figures & tables3 assets
Supplementary material from the paper’s appendix.
Appendix
| Stage I — migration criteria | Stage II — test modules | |||||
| Criterion | What it asks | Required | Verdict | Module | What it measures | Pass rate |
| no-c-sources | has C left the build | pass | build | two link configurations | ||
| no-foreign-headers | is only cmark.h left | pass | structure | install tree, ABI | ||
| no-c-in-build | is no C compiled | pass | conformance | CommonMark corpus | ||
| rust-present | is Rust really there | pass | renderers | five output renderers | ||
| rust-is-primary | is Rust the implementation | fail | data-tables | entities, case folding | ||
| Migrated | All tests pass | Blindness | Accepted | Score | |||
| Stage I passed | Stage II perfect | passed, not migrated | all three passed | out of 100 | |||
| Task | Migration | mean | |||||
| Language rewrites | |||||||
| lang01 | C Rust | 26 | 6 | 5 | 5 | 0 | 0.00 |
| lang02 | C Java | 26 | 18 | 4 | 0 | 0 | 12.69 |
| lang03 | Python Go | 26 | 14 | 0 | 0 | 0 | 0.00 |
| Task | Upstream project | Source stack | Target stack | LoC | (h) | Criteria | Modules | Checks |
| Language rewrites—the implementation language moves, the artifact does not | ||||||||
| lang01 | cmark 0.31.1 | C11 | Rust 1.90 | 22,619 | 30 | 8 | 15 | 4,184 |
| lang02 | zlib 1.3.1 | C89 | Java 17 | 22,732 | 20 | 10 | 18 | 4,162 |
| lang03 | sqlparse 0.5.3 | Python | Go (stdlib) | 4,393 | 15 | 8 | 15 | 8,530 |
| lang04 | acorn 8.14.0 | JavaScript | Rust 1.90 | 9,571 | 30 | 7 | 13 | 16,039 |
| lang05 | go-yaml v3.0.1 | Go | Zig 0.14.1 | 11,967 | 20 | 8 | 22 | 10,271 |
Automated Software Engineering
Automated Software Engineering uses AI, search, and verification methods to automate tasks across the software development lifecycle.
See all 81 papers