Factory.ai

What it Takes for Coding Agents to Complete Large Software Tasks

By Factory Research, Theo Luan - August 27, 2026 - 10 minute read

Research

Share

Held to a standard of completion they wrote themselves, agents rebuilt complex programs to near-parity.

Models have become very good at problems with compact, stable criteria for success. Much of the past year's progress in mathematics and constrained optimization falls into this category - machine-checked proofs of long-open Erdős problems, gold-medal performance at the IMO, new bounds on decades-old combinatorial problems. The search space can be enormous, but the result can ultimately be judged as a whole.

Large software tasks are different. A software specification can semantically cover the desired outcome without specifying what must be run, inspected, and compared before the work can be called complete. Requirements state what must be true. By themselves, they do not measure whether the work achieves it.

Without that measurement, an agent constructs one piecemeal as it works. It decomposes the task, validates each piece in the context that produced it, and eventually decides that it is finished. Every local judgment may be reasonable while parts of the whole remain unmeasured.

Humans currently close the loop by supervising the agent: holding the whole outcome and steering the agent back to it.

We wanted to know whether the model could close the loop on its own.

gdal, from scratch

To test this, we compared single-agent and multi-role runs across 24 selected ProgramBench tasks and three models. Take gdal. We asked Droid to rebuild it from scratch in two ways. In both runs, Droid could execute the reference program without limit, but could not access its source, tests, or the internet.

gdal · the reference program

gdal is the command-line tool of the GDAL project, the workhorse of geospatial data processing, and carries decades of functionality behind dozens of subcommands.

In development since 1998, GDAL sits beneath much of the world's mapping software - QGIS, ArcGIS, PostGIS - and reads more than two hundred raster and vector formats, from satellite imagery to navigation charts.

C/C++~2M lines upstream~600K reachable through the CLI

As a single agent, Droid implemented, checked its own work, and decided for itself when it was done. It wrote 17,000 lines of C++ and reproduced 36 percent of the program's behavior. The code was solid and the common paths worked, but most of the program was still missing. It did not run out of time or budget. It stopped because, by its own assessment, it was done.

We then arranged Droid into a system consisting of separate roles. Before any implementation, one role built an executable standard of completion - its own account of what the reimplementation must do and what evidence would prove it - and the implementation was then held to that standard. This run grew to 115,000 lines and reached 90 percent behavioral parity.

What the system run produced is its own program: it resembles the original in neither shape nor size - a fraction of GDAL's codebase, organized its own way.

This was not an outlier case. Across the 24 tasks, the same system took its 7-Zip recreation from 54 percent parity to 95 percent and its DuckDB recreation from 34 to 80 percent. Several recreations reached the upper 90s.

The frontier · best single agent vs best system, per task
single-agent frontiersystem frontier held by fable kimi sol opus
0255075100ffmpeg - single-agent frontier 10.7% - system frontier 40.3% (+29.6)+29.6ffmpeggromacs - single-agent frontier 15.1% - system frontier 30.6% (+15.6)+15.6gromacsctags - single-agent frontier 28.4% - system frontier 76.4% (+48.0)+48.0ctagscppcheck - single-agent frontier 30.3% - system frontier 54.2% (+23.9)+23.9cppcheckduckdb - single-agent frontier 34.2% - system frontier 80.0% (+45.9)+45.9duckdbdoxygen - single-agent frontier 37.5% - system frontier 60.7% (+23.2)+23.2doxygenpandoc - single-agent frontier 39.5% - system frontier 84.2% (+44.7)+44.7pandoclnav - single-agent frontier 43.5% - system frontier 83.9% (+40.4)+40.4lnavast-grep - single-agent frontier 58.0% - system frontier 86.8% (+28.7)+28.7ast-grepgdal - single-agent frontier 58.5% - system frontier 90.3% (+31.8)+31.8gdaltree-sitter - single-agent frontier 61.9% - system frontier 90.9% (+29.1)+29.1tree-sittersamtools - single-agent frontier 62.1% - system frontier 96.5% (+34.4)+34.4samtoolstypst - single-agent frontier 67.2% - system frontier 78.0% (+10.8)+10.8typstdelta - single-agent frontier 68.0% - system frontier 91.4% (+23.4)+23.4deltalazygit - single-agent frontier 69.6% - system frontier 93.2% (+23.6)+23.6lazygitsox - single-agent frontier 70.5% - system frontier 99.5% (+29.0)+29.0soxbedtools2 - single-agent frontier 75.2% - system frontier 98.2% (+23.0)+23.0bedtools2scc - single-agent frontier 78.0% - system frontier 88.4% (+10.3)+10.3scc7zip - single-agent frontier 78.2% - system frontier 94.9% (+16.7)+16.77zipsvgbob - single-agent frontier 83.3% - system frontier 93.4% (+10.2)+10.2svgbobsolar - single-agent frontier 87.0% - system frontier 89.9% (+2.9)+2.9solarpeco - single-agent frontier 92.4% - system frontier 99.6% (+7.2)+7.2pecostgit - single-agent frontier 93.3% - system frontier 96.9% (+3.6)+3.6stgitproj - single-agent frontier 97.3% - system frontier 99.4% (+2.1)+2.1projORDERED BY THE SINGLE-AGENT FRONTIER · HARDEST AT TOP
One row per task. The ring is the single-agent frontier: the best any single agent has achieved on the task, every public leaderboard entry plus our own singles — every ring is dashed because on these 24 tasks our own singles hold all of them. The dot is the system frontier, colored by the model that holds it, and the number is what closing the loop added.

The underlying model did not change. But when held to its own standard of completion, it reproduced far more of each program's behavior.

Why the same agent stops early

Coding agents usually validate their own work as they go. They implement a piece, write or run a few checks, inspect the output, and decide whether to continue. For a small change, this works well: the task, implementation, and evidence fit in one view.

Large tasks have to be decomposed into features, subsystems, and successive rounds of work. As the agent reaches each piece, it also decides what evidence would count and whether that evidence is sufficient. These checks inherit the scope of the work that produced them. They can establish everything the agent thought to build, but exclude features, interactions, or constraints it never represented.

An agent can therefore make steady, locally correct progress and stop with much of the outcome absent. The problem is not necessarily that it could not implement the rest. It never established a complete account of what remained.

Define validation before the work

Establishing a whole outcome requires more than a list of requirements. The system needs an inventory of what must be established, procedures for establishing each part, and current evidence that those procedures pass against the artifact being shipped.

That standard should be derived from the requirements and relevant sources of truth before implementation narrows the task into individual work items. It need not remain frozen. Checks can be added, replaced, or refined as the system learns. But the standard of completion must not quietly collapse around whatever has already been built.

Why this is rarely done by humans

Separating requirements from evidence is not new. Safety-critical projects use requirements traceability and independent verification and validation. Standards bodies publish conformance suites that many implementations must pass. Product teams write acceptance tests.

What is unusual is deriving and maintaining a comprehensive standard for each project. A conformance suite can spread its cost across many implementations; a product team bears that cost again for each application, rewrite, or migration. Most teams therefore validate incrementally and rely on review, product feedback, and the continuity of the people involved to preserve the whole.

Agents change both sides of this tradeoff. They can produce work faster than humans can inspect it, making informal supervision the bottleneck. But the same capacity can be applied to the standard itself: inventorying the outcome, constructing checks, and rerunning them as the artifact changes.

ProgramBench represents a demanding limit case: the reference program is available, but the model must discover both the behavior space and how to measure it.

ProgramBench

ProgramBench is a cleanroom software-engineering benchmark. Each task provides a reference program, fixtures, and partial documentation. The reference is a black-box oracle: it may be run, but never read, decompiled, or traced.

The goal is to reproduce the observable behavior of the reference program from scratch. Each task is graded and scored against a hidden suite of behavioral checks.

Completeness of a black-box implementation is difficult to measure. Any single behavior is trivially verifiable by running the reference against the candidate, but the whole is not. The shipped documentation covers a slice of the interface; the rest of the program's behavior has to be discovered.

That leaves three questions:

  1. Can a frontier model construct its own measure of completeness for a large, unknown program?
  2. Can that measure remain useful through a long implementation?
  3. Does answering to it produce a better artifact?

Task selection

We selected 24 of the benchmark's hardest tasks, based on the current top leaderboard score.

Task selection · all 200 tasks by best public score
selected the other 176
0255075100← HARDEREASIER →ffmpeg - best public: 8.1%gromacs - best public: 10.4%pandoc - best public: 14.7%php-src - best public: 17.8%ctags - best public: 19.0%cppcheck - best public: 19.3%lnav - best public: 21.6%pueue - best public: 21.3%duckdb - best public: 22.9%ast-grep - best public: 32.7%proj - best public: 34.4%doxygen - best public: 34.5%gdal - best public: 39.0%samtools - best public: 39.0%ditaa - best public: 38.4%miller - best public: 38.9%chroma - best public: 41.7%typst - best public: 44.7%tree-sitter - best public: 46.5%scc - best public: 47.6%delta - best public: 47.7%quickjs - best public: 46.8%solar - best public: 48.1%stgit - best public: 48.7%bedtools2 - best public: 48.9%revive - best public: 48.3%yq - best public: 49.9%sox - best public: 51.6%svgbob - best public: 54.9%7zip - best public: 56.6%go-critic - best public: 56.8%jsonschema - best public: 57.1%chafa - best public: 58.4%zk - best public: 59.7%crowbook - best public: 60.3%rumdl - best public: 61.2%xh - best public: 61.5%lazygit - best public: 63.4%argc - best public: 62.0%lightningcss - best public: 63.1%oranda - best public: 66.1%treemd - best public: 66.7%broot - best public: 67.1%marmite - best public: 68.6%bat - best public: 70.2%zstd - best public: 70.8%sqlite - best public: 71.6%tui-journal - best public: 72.3%tinycc - best public: 72.4%atlas - best public: 72.5%serpl - best public: 72.9%masscan - best public: 73.2%dropbear - best public: 74.4%genact - best public: 74.9%age - best public: 76.0%fselect - best public: 76.4%mdbook - best public: 76.5%hyperfine - best public: 77.0%angle-grinder - best public: 77.7%dep-tree - best public: 77.8%cheat - best public: 78.1%flamelens - best public: 78.5%calcurse - best public: 78.7%git-trim - best public: 79.0%skeema - best public: 79.7%caps-log - best public: 79.7%fx - best public: 79.9%gdu - best public: 80.0%dsq - best public: 80.3%direnv - best public: 80.9%datasurgeon - best public: 80.9%gittype - best public: 81.1%seqtk - best public: 81.4%dirble - best public: 81.5%xplr - best public: 81.6%svd2rust - best public: 81.6%parqeye - best public: 81.6%rhit - best public: 81.8%luajit - best public: 82.4%dstask - best public: 82.5%bat-go - best public: 82.7%srgn - best public: 83.0%gotests - best public: 83.3%dust - best public: 83.4%nsh - best public: 83.9%ripgrep - best public: 84.0%gomplate - best public: 84.1%trdsql - best public: 84.1%oha - best public: 84.6%xz - best public: 84.7%fzf - best public: 84.9%monolith - best public: 85.0%rust-sloth - best public: 85.0%onefetch - best public: 85.1%lua - best public: 85.1%ascii-image-converter - best public: 85.4%tig - best public: 85.5%pipr - best public: 86.6%pls - best public: 86.7%tokei - best public: 86.9%yj - best public: 87.1%xq - best public: 87.6%figlet - best public: 87.8%peco - best public: 89.6%lz4 - best public: 88.0%chamber - best public: 88.0%quinn - best public: 88.1%jp2a - best public: 88.1%run - best public: 88.2%codesnap - best public: 88.6%hwatch - best public: 88.7%the_silver_searcher - best public: 88.8%ov - best public: 89.4%amber - best public: 89.4%goimports-reviser - best public: 89.7%statix - best public: 89.8%jq - best public: 90.1%zoxide - best public: 90.2%pixterm - best public: 90.2%felix - best public: 90.2%hush - best public: 90.3%ninja - best public: 90.5%melody - best public: 90.5%tparse - best public: 90.8%tex-fmt - best public: 90.8%tailspin - best public: 91.5%diffr - best public: 91.7%hashcards - best public: 92.6%dupl - best public: 92.8%curlie - best public: 92.9%igrep - best public: 92.9%rustowl - best public: 93.0%hostctl - best public: 93.0%duc - best public: 93.0%i3-style - best public: 93.3%ripsecrets - best public: 93.5%json-tui - best public: 93.5%richgo - best public: 93.6%fd - best public: 93.9%xsv - best public: 94.1%gron - best public: 94.2%miniserve - best public: 94.2%handlr - best public: 94.2%pier - best public: 94.2%ethabi - best public: 94.5%walk - best public: 94.6%pastel - best public: 94.7%jplot - best public: 94.7%keifu - best public: 94.7%pigz - best public: 94.9%gowsdl - best public: 94.9%gping - best public: 95.0%errcheck - best public: 95.0%brotli - best public: 95.5%entr - best public: 95.6%git-graph - best public: 95.6%halite - best public: 95.6%hexyl - best public: 95.9%parallel-disk-usage - best public: 95.9%bartib - best public: 96.0%fblog - best public: 96.0%html-to-markdown - best public: 96.2%caesium-clt - best public: 96.2%tty-clock - best public: 96.4%fasttext - best public: 96.5%muffet - best public: 96.6%thokr - best public: 96.6%shellharden - best public: 96.7%rnr - best public: 96.7%kiro-editor - best public: 96.8%deadnix - best public: 96.8%hck - best public: 97.2%sd - best public: 97.4%dutree - best public: 97.5%nomino - best public: 97.8%dog - best public: 97.9%htmlq - best public: 98.0%grex - best public: 98.1%blake3 - best public: 98.1%xcp - best public: 98.1%elfcat - best public: 98.2%tuc - best public: 98.2%nnn - best public: 98.3%dua-cli - best public: 98.3%eureka - best public: 98.5%eva - best public: 98.7%jot - best public: 98.7%pingu - best public: 98.9%loop - best public: 98.9%go-mod-outdated - best public: 98.9%clog-cli - best public: 99.1%htop - best public: 99.4%code-minimap - best public: 99.4%bore - best public: 99.5%csview - best public: 99.7%ngrrram - best public: 99.7%wrapcheck - best public: 99.8%zip-password-finder - best public: 99.9%cmatrix - best public: 100.0%hex - best public: 100.0%median 41.9 · selectedmedian 89.1 · the other 176OFFICIAL METRIC · 0–100
Every dot is one of ProgramBench’s 200 tasks, placed at the best score any public leaderboard entry has achieved on it. The ink dots are the 24 selected tasks; hover any dot for its name.

The set was hand-picked, weighted toward low best-public scores. Some hard-end candidates (php-src, pueue, ditaa, quickjs, chroma, miller) were dropped during screening for persistent safety blocks, single-agent saturation, or a score gated by one undocumented environment variable.

Experimental design

For each selected task and model panel, we ran one campaign in each of two conditions. The system condition added an independent measure of completion without replacing the implementer's ordinary development loop.

Single-agent campaignSystem campaign
Implementation loopAgent investigates, implements, runs checks, and judges its workImplementer investigates, implements, runs checks, and judges its work
Completion standardDevelops inside the same context as the candidateValidator constructs an independent instrument before implementation
Independent measurementNone during the campaignValidator measures successive candidates against its instrument
Information flowAgent sees all checks and resultsInstrument and raw results remain with the validator; clustered findings cross the wall
Campaign controlAgent chooses what to do next and when to stopOrchestrator adjudicates findings, issues directives, and decides when to ship

Both conditions began from the same task scaffold and fixtures. Within each non-substituted model panel, the single agent and all three system roles used the same model at the same reasoning level. Both conditions could execute the reference program without limit, but neither could read, decompile, or trace it, inspect the benchmark tests, or access the internet. Six disclosed Fable cells used Opus after Fable was safety-blocked.

Once launched, each campaign ran without human intervention. The campaigns were not compute-matched; each continued until the single agent or system orchestrator decided to ship.

Each cell represents one campaign, not an average across repeated runs. After a campaign ended, its final candidate was graded once using the official pb-1.2.0 metric.

How the system closed the loop

The instrument

Full behavioral parity is not directly measurable. A program can accept an effectively unbounded set of inputs, flags, file formats, combinations, and error conditions. Any practical validation strategy has to sample that space.

In our system, that sample is an instrument. Before implementation begins, a validator surveys the reference program and maps where its behavior lives. It then builds a weighted body of cases and the comparison rules needed to judge the candidate's output. We asked for the instrument only in outline. Everything inside it - which behaviors matter, how they are weighted, what counts as evidence - the validator decides.

Two cases from the instrument the validator built for gdal:

D('hillshade.combined', ['raster', 'hillshade', '--variant', 'combined', 'dem.tif', 'out.tif']),
D('contour.levels', ['raster', 'contour', '--levels', '120,150,180', 'dem.tif', 'out.geojson']),

Each case describes the invocation; the grading policy says how to judge the result:

Primary comparator: for every case, the runner executes oracle and candidate sequentially in the same absolute sandbox path (wiped between runs), same env, same fixture bytes and mtimes, and byte-compares four channels:

1. exit code
2. stdout bytes
3. stderr bytes
4. full work-tree delta: the set of files created/modified/deleted by the run, and the exact bytes of each (includes sidecars: .aux.xml, .ovr, .msk, shapefile companions, tile trees).

Byte identity is the default on every channel. A relaxation exists only as a named normalizer attached to specific cases, each carrying a license below.

The validator wrote hundreds of cases like these, and licensed exactly two relaxations across all of them - a masked heap address in debug traces, a date embedded in a file header - each with recorded evidence that the reference cannot produce stable bytes there.

The outer loop

The system consists of three roles: orchestrator, implementer, and validator. The orchestrator delegates to both the implementer, which builds the candidate program, and the validator, which measures it against its instrument.

The validator builds the instrument first. Once implementation starts, the loop goes:

  1. The orchestrator chooses what should be measured.
  2. The validator tests the current candidate and interprets the failures.
  3. The orchestrator decides which findings are real and what work should happen next.
  4. The implementer investigates the reference and advances the candidate.

When the instrument stops revealing meaningful differences between successive candidates, the orchestrator can ask the validator to expand a weak area or begin targeted differential testing against the reference.

The system · three roles and the wall
THE WALLREFERENCE PROGRAMrunnable, never readableboth roles hold it and may query it without limitIMPLEMENTERwrites the candidatenever sees the instrumentORCHESTRATORadjudicates each measurementdecides what happens nextVALIDATORsurveys the reference, measures the candidateclusters what failsTHE INSTRUMENTa weighted sample of the referencecases, plus the rules for a matchauthored, held and run heredirectivecandidatecandidatemeasurementthe last candidate shipsHIDDEN SUITE · graded once, after the runsamples the same behavior space
Both roles are the same model at the same reasoning level, and both hold the reference program, so keeping the instrument on the measuring side costs no information — only a shortcut. The candidate and the findings cross the wall; the instrument does not. Grading happens once, outside the loop, and is the source of every score in this post.

The wall

In ProgramBench, the standard required an additional boundary because its cases were only a sample of a much larger behavior space.

The boundary holds in both directions. The validator can expand the instrument as it learns more about the reference, but cannot weaken or revise it to accommodate what the candidate happens to contain. And the implementer never authors it, runs it, or sees its cases or raw output: once a sparse sample becomes visible, it becomes the target, and passing it establishes those cases, not the space they were meant to represent.

The validator runs the instrument against the current candidate and groups failures by root cause. The orchestrator reviews those findings, rejects noise or invalid measurements, and turns the remaining problems into a directive at the level of missing features, subsystems, or behavior. The implementer receives the directive, investigates the reference independently, and decides how to change the candidate.

Here is part of a directive from the gdal run:

## 1. Stub frontier (dominant mass, ~60 verbs)

Ordered by measured weight (approximate case mass in brackets). Probe each against the oracle first, as always.

- vgrid: all 11 grid methods [14]
- mdim group on multidim VRT + classic-input pins [12]
- sozip: create / list / validate / optimize [11]
- DEM suite [~30]: contour [7], hillshade incl. variants [6], aspect [6], slope [4], viewshed [4], roughness, tpi, tri [1-3 each]
- rasterize [7], pixel-info [7], calc [7], mosaic [6] + stack, tile [5], footprint [5]

The directive tells the implementer where the candidate is weak without giving away the sample.

Results

We ran the experiment with three frontier models - Fable 5, Kimi K3, and GPT 5.6 Sol.

Every score here comes from the benchmark's hidden suite - a sample of the same behavior space that no role ever saw. The gains transferred from the instrument the system built to an independent measure.

Results · single agent → system, one panel per model

Fable 5xhigh

opus fallbackmedian 56.7 89.3gap closed 73%on the clock 8.5h 96h
0255075100SINGLE AGENTone campaign runSYSTEMone campaign runpeco single: official 92.4% (1123/1215) · raw 85.4% → peco system: official 99.6% (1210/1215) · raw 92.2%peco 92100sox single: official 70.5% (843/1196) · raw 69.3% — Opus substitute (fable safety-killed / compile-failed) → sox system: official 99.5% (1190/1196) · raw 97.0% — Opus substitute (fable safety-killed / compile-failed)sox (opus) 70100proj single: official 97.3% (5176/5319) · raw 72.4% → proj system: official 99.4% (5288/5319) · raw 74.0%proj 9799bedtools2 single: official 74.2% (781/1053) · raw 72.9% — Opus substitute (fable safety-killed / compile-failed) → bedtools2 system: official 98.2% (1034/1053) · raw 96.3% — Opus substitute (fable safety-killed / compile-failed)bedtools2 (opus) 7498stgit single: official 93.3% (1388/1488) · raw 89.7% → stgit system: official 96.9% (1442/1488) · raw 92.1%stgit 9397samtools single: official 62.1% (885/1425) · raw 53.7% — Opus substitute (fable safety-killed / compile-failed) → samtools system: official 96.5% (1375/1425) · raw 95.0% — Opus substitute (fable safety-killed / compile-failed)samtools (opus) 62967zip single: official 54.4% (567/1043) · raw 53.5% → 7zip system: official 94.9% (990/1043) · raw 92.8%7zip 5495svgbob single: official 83.3% (393/472) · raw 83.1% → svgbob system: official 93.4% (441/472) · raw 93.5%svgbob 8393lazygit single: official 46.4% (397/855) · raw 51.8% → lazygit system: official 93.2% (797/855) · raw 89.9%lazygit 4693delta single: official 68.0% (645/949) · raw 69.7% → delta system: official 91.4% (867/949) · raw 89.2%delta 6891tree-sitter single: official 55.4% (682/1232) · raw 63.8% — Opus substitute (fable safety-killed / compile-failed) → tree-sitter system: official 90.9% (1120/1232) · raw 90.7% — Opus substitute (fable safety-killed / compile-failed)tree-sitter (opus) 5591gdal single: official 35.8% (235/657) · raw 43.5% → gdal system: official 90.3% (593/657) · raw 89.8%gdal 3690scc single: official 72.6% (337/464) · raw 71.4% → scc system: official 88.4% (410/464) · raw 86.8%scc 7388ast-grep single: official 58.0% (509/877) · raw 57.8% → ast-grep system: official 86.8% (761/877) · raw 86.6%ast-grep 5887solar single: official 71.9% (1422/1978) · raw 76.6% → solar system: official 85.7% (1695/1978) · raw 88.1%solar 7286pandoc single: official 19.0% (991/5214) · raw 19.0% — Opus substitute (fable safety-killed / compile-failed) → pandoc system: official 84.2% (4389/5214) · raw 82.3% — Opus substitute (fable safety-killed / compile-failed)pandoc (opus) 1984lnav single: official 38.2% (378/989) · raw 34.2% → lnav system: official 83.9% (830/989) · raw 74.4%lnav 3884duckdb single: official 34.2% (1931/5649) · raw 23.0% → duckdb system: official 80.0% (4522/5649) · raw 55.6%duckdb 3480typst single: official 67.2% (1158/1724) · raw 67.4% → typst system: official 78.0% (1344/1724) · raw 77.5%typst 6778ctags single: official 14.3% (322/2258) · raw 17.7% → ctags system: official 76.4% (1726/2258) · raw 76.8%ctags 1476doxygen single: official 37.5% (86/229) · raw 41.0% → doxygen system: official 60.7% (139/229) · raw 62.1%doxygen 3861cppcheck single: official 30.3% (644/2126) · raw 30.6% → cppcheck system: official 54.2% (1152/2126) · raw 50.7%cppcheck 3054ffmpeg single: official 9.0% (273/3041) · raw 9.0% → ffmpeg system: official 40.3% (1225/3041) · raw 31.9%ffmpeg 940gromacs single: official 13.9% (172/1234) · raw 13.1% — Opus substitute (fable safety-killed / compile-failed) → gromacs system: official 30.3% (374/1234) · raw 30.5% — Opus substitute (fable safety-killed / compile-failed)gromacs (opus) 1430

Kimi K3high

median 45.1 75.4gap closed 42%on the clock 9.0h 64h
0255075100SINGLE AGENTone campaign runSYSTEMone campaign runpeco single: official 78.5% (954/1215) · raw 77.1% → peco system: official 98.3% (1195/1215) · raw 91.4%peco 7998bedtools2 single: official 75.2% (792/1053) · raw 73.2% → bedtools2 system: official 94.0% (990/1053) · raw 92.4%bedtools2 7594solar single: official 87.0% (1721/1978) · raw 88.5% → solar system: official 89.9% (1779/1978) · raw 91.3%solar 8790proj single: official 44.4% (2363/5319) · raw 33.1% → proj system: official 88.1% (4684/5319) · raw 65.5%proj 4488stgit single: official 37.0% (551/1488) · raw 33.9% → stgit system: official 87.7% (1305/1488) · raw 85.5%stgit 3788scc single: official 78.0% (362/464) · raw 76.5% → scc system: official 87.3% (405/464) · raw 85.5%scc 7887svgbob single: official 69.7% (329/472) · raw 69.6% → svgbob system: official 82.0% (387/472) · raw 81.9%svgbob 70827zip single: official 76.3% (796/1043) · raw 75.0% → 7zip system: official 80.9% (844/1043) · raw 79.3%7zip 7681typst single: official 66.5% (1147/1724) · raw 66.6% → typst system: official 77.5% (1336/1724) · raw 77.3%typst 6777sox single: official 51.8% (619/1196) · raw 51.4% → sox system: official 76.3% (913/1196) · raw 74.8%sox 5276lazygit single: official 43.2% (369/855) · raw 48.4% → lazygit system: official 74.4% (636/855) · raw 75.9%lazygit 4374tree-sitter single: official 45.7% (563/1232) · raw 56.3% → tree-sitter system: official 73.5% (906/1232) · raw 77.8%tree-sitter 4674gdal single: official 56.8% (373/657) · raw 65.5% → gdal system: official 71.5% (470/657) · raw 75.2%gdal 5772pandoc single: official 31.6% (1645/5214) · raw 31.1% → pandoc system: official 70.5% (3674/5214) · raw 68.8%pandoc 3270lnav single: official 18.2% (180/989) · raw 17.1% → lnav system: official 66.2% (655/989) · raw 57.8%lnav 1866ctags single: official 28.2% (636/2258) · raw 34.1% → ctags system: official 58.4% (1318/2258) · raw 60.8%ctags 2858duckdb single: official 31.1% (1756/5649) · raw 22.1% → duckdb system: official 41.2% (2328/5649) · raw 29.5%duckdb 3141doxygen single: official 35.4% (81/229) · raw 39.0% → doxygen system: official 36.7% (84/229) · raw 40.2%doxygen 3537gromacs single: official 15.1% (186/1234) · raw 14.1% → gromacs system: official 30.6% (378/1234) · raw 28.1%gromacs 1531ffmpeg single: official 8.7% (264/3041) · raw 8.3% → ffmpeg system: official 13.0% (395/3041) · raw 11.6%ffmpeg 913eval timeout: cppcheck single: official 11.9% (253/2126) · raw 11.4% — evaluation timed out; score is a floor — graded 269/2126, 253 passedcppcheck system: official 4.1% (88/2126) · raw 5.8%eval timeout: ast-grep system: official 0.0% (0/877) · raw 0.0% — evaluation hung twice; 0 of 877 graded — no bound; delta system: official 13.1% (124/949) · raw 24.8% — evaluation timed out; score is a floor — graded 128/949, 124 passedast-grep single: official 56.6% (496/877) · raw 56.6%delta single: official 50.0% (475/949) · raw 55.8%ast-grep 57 → eval timeoutcppcheck eval timeout → 4delta 50 → eval timeout

GPT-5.6-solmax

median 48.6 66.2gap closed 25%on the clock 1.5h 24h
0255075100SINGLE AGENTone campaign runSYSTEMone campaign runpeco single: official 77.0% (935/1215) · raw 74.4% → peco system: official 95.5% (1160/1215) · raw 89.3%peco 77957zip single: official 78.2% (816/1043) · raw 76.9% → 7zip system: official 93.6% (976/1043) · raw 91.6%7zip 7894proj single: official 26.6% (1413/5319) · raw 19.9% → proj system: official 89.8% (4778/5319) · raw 66.9%proj 2790stgit single: official 77.5% (1154/1488) · raw 78.8% → stgit system: official 84.3% (1255/1488) · raw 86.0%stgit 7884bedtools2 single: official 75.2% (792/1053) · raw 73.7% → bedtools2 system: official 83.2% (876/1053) · raw 81.8%bedtools2 7583svgbob single: official 71.8% (339/472) · raw 71.7% → svgbob system: official 78.0% (368/472) · raw 78.1%svgbob 7278samtools single: official 43.7% (623/1425) · raw 38.8% → samtools system: official 74.2% (1057/1425) · raw 72.2%samtools 4474solar single: official 49.5% (979/1978) · raw 58.6% → solar system: official 74.0% (1463/1978) · raw 78.0%solar 4974lazygit single: official 69.6% (595/855) · raw 72.5% → lazygit system: official 72.3% (618/855) · raw 74.6%lazygit 7072scc single: official 66.6% (309/464) · raw 65.3% → scc system: official 71.5% (332/464) · raw 70.2%scc 6772sox single: official 48.6% (581/1196) · raw 48.1% → sox system: official 66.2% (792/1196) · raw 65.2%sox 4966ast-grep single: official 34.0% (298/877) · raw 34.4% → ast-grep system: official 64.2% (563/877) · raw 64.3%ast-grep 3464typst single: official 54.8% (945/1724) · raw 55.3% → typst system: official 62.1% (1071/1724) · raw 62.4%typst 5562pandoc single: official 39.5% (2060/5214) · raw 38.9% → pandoc system: official 59.0% (3074/5214) · raw 57.7%pandoc 4059tree-sitter single: official 61.9% (762/1232) · raw 68.0% → tree-sitter system: official 56.7% (699/1232) · raw 64.6%tree-sitter 6257ctags single: official 28.4% (642/2258) · raw 34.5% → ctags system: official 46.2% (1043/2258) · raw 50.1%ctags 2846doxygen single: official 37.5% (86/229) · raw 41.0% → doxygen system: official 38.9% (89/229) · raw 42.2%doxygen 3839duckdb single: official 29.7% (1678/5649) · raw 21.7% → duckdb system: official 29.4% (1662/5649) · raw 21.2%duckdb 3029lnav single: official 43.5% (430/989) · raw 38.6% → lnav system: official 20.6% (204/989) · raw 18.4%lnav 4321ffmpeg single: official 10.7% (325/3041) · raw 9.9% → ffmpeg system: official 17.1% (521/3041) · raw 27.6%ffmpeg 1117cppcheck single: official 4.8% (103/2126) · raw 6.9% → cppcheck system: official 6.8% (144/2126) · raw 8.6%cppcheck 57eval timeout: delta single: official 13.2% (125/949) · raw 24.9% — evaluation timed out; score is a floor — graded 128/949, 125 passedeval timeout: delta system: official 13.3% (126/949) · raw 35.1% — evaluation timed out; score is a floor — graded 128/949, 126 passeddelta eval timeout → eval timeout
Each panel is one model, run twice on the same 24 tasks: on the left as a single agent, on the right as the full system. Every line is one task, placed at its official score from the benchmark's hidden suite. Lines that fall are drawn dashed. A handful of cells have no score at all, a test hung during evaluation, so grading never completed. These are placed at the foot of the panel. The rail on the left filters the tasks by difficulty, the best public score per task, on the same 0-100 scale.

The system runs were far longer and more expensive; for gdal, 14 times the credits and 13 times the wall time. But budget was not what separated the conditions. Every single-agent campaign ended because the agent decided to end it. Additional compute does not help an agent that will not spend it. What our approach changed was the judgment of completion; the compute followed from that judgment.

Every task, every model

· SINGLE 35.8 → SYSTEM 90.3
0255075100current leaderboard · best score by any model: 39%SINGLE AGENTone campaign runSYSTEMone campaign runfable 3690kimi 57725736
UPSTREAMC++ · ~1.9M loc
SINGLESYSTEM×
score35.890.3
credits216M3.00B14×
wall15.0h196.9h13×
IMPLEMENTER
languagecppcpp
core loc17k115k6.7×
core files481042.2×
file edits6035,4509.0×
credits216M2.92B14×
VALIDATOR
instrumentnot archived
credits53M
SYSTEM SPEND
impl 97% · val 2% · orch 1%
Every task, every model, every receipt: the selector sorts by any model’s system score, a score cell opens that model’s page with the run’s timeline, a task name opens the three-model comparison, and arrow keys walk the grid.

Method notes

Reasoning levels. Fable ran at xhigh, Kimi at high, Sol at max, applied uniformly to the single agent and to all three roles in the system.

One run per cell. Every number here is a single run. Nothing was repeated to average it, so no cell carries a variance estimate, and none of these figures should be read as a mean.

Headline runs. The gdal, 7-Zip, and DuckDB numbers in the opening section are Fable 5 runs.

Scale. GDAL upstream is roughly two million lines of C/C++ (1.9 million after removing bundled third-party libraries). The subset reachable through the gdal CLI as configured in the task - eleven drivers, no GEOS - is roughly 600 thousand. The recreation matched 90 percent of that surface's measured behavior in 115 thousand lines.

Opus substitutes. Six cells in the Fable panel are Opus runs standing in for Fable ones that were safety-blocked, either in the single-agent or system run: bedtools2, gromacs, pandoc, samtools, sox and tree-sitter.

Coverage. 141 of the 144 cells have been graded. The remaining three system runs - gdal and gromacs on Sol, samtools on Kimi - were interrupted and not rerun before publication; they carry no score.

Grading. Every score is the official metric from the hidden suite, pinned at pb-1.2.0 and computed identically for single-agent and system artifacts.

Conclusion

The single agent didn't lack skill. It lacked a standard of completion. An independent standard, authored by the same model, drove the implementation much closer to behavioral parity with the reference.

ProgramBench gave that standard a particular shape: an inventory and weighted sample recovered from a black-box reference.

Other tasks draw their standard from different sources. A product task may draw on user-approved flows and designs; a migration, on the system being replaced.

What generalizes to real software work is the need for an external, executable standard of completion - one derived from the outcome, before implementation narrows attention, and kept current until the work meets it.

We are building this structure into the next generation of Missions.

To get on the waitlist, contact Factory or contact your Factory account team.

Ready to build the software of the future?

Start building

Arrow Right Icon