The Working Set of a Coding Agent: Coherence Debt in Repository-Scale Tasks
Organizations: Max Planck Institute for Software Systems · EPFL · Apple · Aarhus University
Abstract
Repository-scale coding requires an agent to keep tests, imports, configuration, and migration rules consistent within a bounded context window. We model this as reconstructing a coupled-fact graph: at each edit, a required fact comes from recent context or parametric memory, and the facts covered by neither form coherence debt. We supply and withhold each channel and inject faults across seven models and five harnesses. As expected, no model completes a task on an unseen API with both channels empty, and putting the facts in the prompt restores success. When a rename defeats what models memorized about a real library, all seven fail in the same place, passing and missing the same tests. Availability decides the outcome and distance does not: withholding a fact costs exactly the work it supports, and a supplied fact works as well far from the edit as next to it. Harnesses pay unequal prices for it: configurations that all pass every test differ more than tenfold in tokens consumed because they rebuild the same content at different rates, and spending more recovers nothing when facts are withheld. A missing fact produces wrong work rather than absent work: an agent asked to act acts, fabricating the file or guessing the value, so instruments built on reads look for a hole already filled. How often it says it is blocked instead is a property of the model, from every trial to none. Availability does not settle every edit: where standard and code disagree, agents follow the standard even when it prescribes the worse code, so a stale convention file costs more than no file. Because parametric memory substitutes for reading, on SWE-bench, where models likely know the repositories, reads no longer predict success. Harnesses should keep the facts an edit depends on available when the agent writes, and check that availability against what the agent produces rather than what it reads.
Figures & tables
| Event | Required payload | Role in coverage analysis |
|---|---|---|
| file_read | path, observed repository/file version, byte range | What source reached an actor; asserts no semantic extraction by itself. |
| fact_extracted | fact identifier/value, source span and version, acquisition mode | Adds a versioned fact to the actor ledger by reading, prompt supply, or handoff. |
| edit_intent | target/base version, required facts, relied-on fact versions, proposed transformation | Records the actor’s claimed pre-write support set, which exposes missing and stale dependencies before the outcome but requires external validation. |
| test_feedback | command, oracle result, diagnostics, contradicted intents | Ties environmental evidence to the edits it validates or invalidates. |
| revert | restored content/version, reverted intent, triggering feedback | An explicit compensating write, not a reversal inferred from a later diff. |
| Experiment | Channel state | Outcome | Result | |
|---|---|---|---|---|
| Novel closed-book | , task-specific | 154 | complete migration | ; every trial |
| Novel front-load | exact rules/source supplied in | 300 | at least requirements | ; mean cell scores – |
| Pydantic closed-book | public API available mainly through | 32 of 36 | passed-test identity | same tests; pairwise Jaccard |
| Renamed closed-book | lexical access to prior defeated | 66 of 70 | passed-test identity | same tests across seven families; Jaccard |
| Condition | Claude | Codex |
|---|---|---|
| Lean migration | 2/3 | 2/3 |
| Standalone document bloat | 2/3 | 3/3 |
| In-file code bloat | 1/6 | 2/6 |
| Renamed in-file bloat | 0/3 | 2/3 |
| Coupled, decomposition on | 1/6 | 2/6 |
| Coupled, decomposition off | 1/3 | 3/3 |
Appendix figures & tables9 assets
Supplementary material from the paper’s appendix.
Appendix
| Workload | Migration-rule summary |
|---|---|
| Sprocket (Rust) | Attribute handler(async) async_handler ; builder Route::builder() Route::spec() ; add context type and marker. |
| Grimwire (Go) | Open(dsn) Connect(ctx, dsn) ; thread context.Context through create/read/update/delete (CRUD) methods; move orm to v2/orm ; add marker. |
| Kestrix (Python) | Schema kestrix.Model ; strict = True mode = ’strict’ ; factory call Foo.spawn() ; add marker. |
| Zynet (JavaScript) | defineSchema Schema.declare ; required req ; add ’sync’ to validateOn ; add marker. |
| Flareforge (JavaScript) | Partial-idiom Result<T,E> migration: throwOnError resultMode ; add marker. |
| Pydantic (Python) | Real v1 v2 migration on two FastAPI apps: BaseSettings, validators, root validators, JSON encoders, and ConfigDict; 79 tests. |
| Block | Design | Tested prediction | |
|---|---|---|---|
| A | 36 | Claude, Codex 5 bloat conditions Pydantic | Placement matters over volume. |
| B | 12 | Claude, Codex 6 workloads | Residency AUC across independent workloads. |
| C | 18 | Claude, Codex {lean, overlay, troubleshoot} | Overlay inverts residency-success sign for Claude. |
| D | 3 | Claude-Haiku on Pydantic | Capacity floor changes failure shape. |
| E | 3 | Claude shell-only on Pydantic | Tool-surface swap changes edit interface. |
| F | 27 | 4 harnesses Pydantic | Cross-harness failure-shape divergence. |
| Sweep | Parameter varied | |
|---|---|---|
| Fault injection | 30 | motifs withheld, , six per level |
| Invariant retention | 7 | trajectory length, 24 to 96 tasks |
| Symbol rename | 52 | symbols renamed, , two subset rules |
| Conflicting source | 39 | polarity and conflict count, four agent configurations |
| Scenario | Identifying prefix before the common fail/revert suffix |
|---|---|
| Missing read | edit intent requires a fact for which no worker has a current extraction ( ) |
| Stale read | actor extracts source version 1; another edit advances the source to version 2; actor edits from version 1 ( ) |
| Handoff gap | lead extracts the current fact; run manifest assigns a delegate; no handoff extraction reaches that delegate ( ) |
| Scaled simulator check | Result |
|---|---|
| Runs containing all five event types | 300/300 |
| Offline coverage replay agreement | 900/900 edits |
| Injected cause recovered | 300/300 |
| Diagnosis available before failed test | 300/300 |
| Feedback-linked revert and passing retry | 300/300 |
| Ambiguous from event counts alone | 300/300 |
| Arm | Model | Separation | Solved |
|---|---|---|---|
| Agent, tools | Sonnet | withheld | 0/24 |
| Agent, tools | Sonnet | source readable | 24/24 |
| Agent, tools | Sonnet | 0–128K chars | 24/24 each |
| Closed book | DeepSeek | withheld | 0/80 |
| Closed book | DeepSeek | 0–200K chars | 80/80 each |
| Closed book | DeepSeek | 0–200K, 32 facts | 192/192 each |
| Representation | MRR | Recall@5 | File@12K | Symbol@12K |
|---|---|---|---|---|
| Directory/file | .833 | .967 | .256 | .778 |
| Import-only | .833 | 1.000 | .256 | .778 |
| Semantic | .750 | 1.000 | .567 | .883 |
| Baseline | AUC (lean bloat, ) |
|---|---|
| Residency (coverage) | 0.83 |
| Distinct files edited (coverage) | 0.82 |
| Number of reads (volume) | 0.58 |
| Number of tool calls (volume) | 0.53 |
| Number of edits (volume) | 0.49 |
| Wall time (effort) | 0.33 |
| Condition | Claude bytes | Codex bytes |
|---|---|---|
| lean | 35,497 | 104,551 |
| document bloat | 21,214 | 50,992 |
| code bloat | 24,200 | 152,270 |
| code bloat, single agent | 11,774 | 501,605 |
| renamed twin | 8,843 | 151,173 |
Repository-Level Code Generation
Repository-level code generation builds or modifies software across files using project context, dependencies, and requirements.
See all 43 papers