How our agent plans multi-file changes
A look under the hood at the planning loop that lets Arshas reason across your entire codebase — from indexing and retrieval to diff generation and self-verification.
When you hand the Arshas agent a task like “add rate limiting to the public API”, the hard part isn’t writing the code. It’s deciding which code to write, where, and in what order — across a repository the model has never fully read. This post walks through the planning loop that makes that work.
Start with retrieval, not generation
The naive approach — stuff as many files as fit into the context window and ask for a diff — fails in interesting ways. The model edits plausible-looking code that isn’t actually on the request path, or misses the one middleware file where the change really belongs.
So the loop starts with retrieval. The codebase index gives us embeddings and a symbol graph for every file. From the task description we retrieve two distinct sets: files that are semantically related to the task, and files that are structurally coupled to them — callers, implementers, tests. The union, ranked and trimmed, becomes the planning context.
Plans are a contract, not a suggestion
The agent then drafts an explicit plan: the list of files it will create or modify, with a one-line intent for each. This plan isn’t decoration — it is a contract the execution phase is held to. Edits outside the plan are rejected by the harness and force a re-plan, which turns out to be one of the strongest quality levers we have. Hallucinated side quests get caught before they touch a file.
Plans are also where the human fits in. You review the plan before anything runs, which is a far cheaper intervention point than reviewing a thousand-line diff after the fact.
Execute, verify, revise
Execution walks the plan file by file, re-retrieving fresh context for each edit — the state of the world changes as edits land, and stale context is the main source of contradictory diffs. After each file, the agent runs the cheapest available verification: type checks first, then the tests that the symbol graph says are affected.
Failures loop back into the plan. A failed test doesn’t just trigger a retry of the last edit; it can revise the plan itself, adding a file the agent now realizes it needs to touch. In practice most tasks converge in one or two revisions.
What we measure
Our north-star metric is first-pass acceptance: the fraction of agent diffs accepted without the user editing a single hunk. Plan-contract enforcement moved it more than any model upgrade in the same period. The lesson repeats everywhere in this space — structure around the model beats raw capability more often than you’d think.