Skip to content

devlog/agent-loops/a-2000-line-file-one-agent-patch-at-a-time-670.md

A 2,000-Line File, One Agent Patch at a Time

A 2,000-Line File, One Agent Patch at a Time

The dangerous prompt is also the tempting one: “Clean up this file.” Give a coding agent 2,000 lines containing request parsing, database access, retries, and response formatting, and it can produce a beautiful diff that quietly changes production behavior.

My default for 2026 is less dramatic: map the file, pin its behavior, and extract one responsibility per patch. Bigger context windows help an agent understand the mess. They do not make a giant rewrite easier to review.

Map the file before authorizing edits

Start with a clean working tree or a checkpoint commit that preserves your existing work. Ask the agent for a read-only inventory: entry points, exported symbols, mutable state, side effects, and callers. Have it inspect repository instructions and the actual test commands rather than guessing from the language.

For a TypeScript request handler, my first prompt looks like this: “Inspect src/requests.ts and its direct callers. Identify three extraction seams, rank their behavioral risk, and name the tests covering each. Do not edit files.”

Verify that map yourself. Search for dynamic imports, initialization side effects, and callers outside the obvious directory. An agent’s confident dependency summary is still a hypothesis.

Pin behavior around the first extraction seam

Choose a boring seam first: a deterministic formatter or argument normalizer, not the retry loop holding three implicit invariants together. Before moving it, add characterization tests that describe what the code does today, including awkward behavior you might eventually want to change.

  • Cover missing values, empty inputs, and representative error paths.
  • Capture externally visible outputs rather than private implementation details.
  • Control clocks, random values, and network calls where necessary.
  • Run the new tests against unchanged code before extraction.

If you discover a bug, record it separately. Mixing a behavior fix into a structural move makes failures harder to explain and rollback harder to trust.

Give each agent patch a written boundary

A useful slice fits in one sentence: “Move response normalization into its own module without changing the exported API.” The acceptance criteria should be equally narrow.

I use this prompt shape: “Extract normalizeResponse into src/response-normalization.ts. Preserve signatures, error messages, ordering, and mutation behavior. Update only necessary imports and focused tests. Do not add dependencies or reformat unrelated code. Stop and explain if preserving behavior requires a wider change.”

Ask for a plan before edits when the seam crosses modules. Set a review budget, perhaps roughly 150 changed lines excluding mechanical moves. That is a warning threshold, not a quota: a tiny diff can still change transaction semantics.

Gate every slice in the terminal

After each patch, inspect git diff --stat, then the full diff. Run the focused tests, type checker, and relevant lint checks. Run the broader suite before merging, and sooner whenever shared state or module initialization changes.

Watch especially for altered await placement, lost method binding, changed exception boundaries, and newly introduced circular imports. Passing tests are evidence, not proof. If a check fails, keep the repair inside the current slice instead of starting the next extraction.

Commit each verified slice with a message naming the responsibility moved. Keep a short repository note listing completed extractions, remaining risks, and exact verification commands. That makes a fresh agent session useful without replaying the entire conversation.

Keep model switching separate from code changes

For the agent runtime, Fluxo provides one key and one base URL, https://api.fluxorelay.com, for Claude, GPT, Gemini, DeepSeek, Kimi, GLM, Qwen, Grok, and more. It works with Claude Code, Codex, Gemini CLI, and any OpenAI SDK. Keep tool configuration outside the refactoring diff.

You could use Claude Sonnet 5.5 for an extraction and GPT-6.1 Sol for an independent review, giving the reviewer the contract and diff rather than the author’s assurances. A second model is another reviewer, not a correctness oracle.

Fluxo bills per real token, including cache reads and writes, with no monthly fee; track total usage instead of assuming repeated context is free. Users also earn a referral share when people they invite pay. If that setup fits your terminal workflow, consider creating a Fluxo account.

The finish line is not fewer lines in the original file. It is clearer ownership, preserved behavior, and a chain of patches you can explain or revert independently.

Next in the buffer

Sign up in a minute and get credit to try every model mentioned here. Sign up →