A 2,000-Line File, Two Agent Refactoring Workflows
A 2,000-Line File, Two Agent Refactoring Workflows
The file is billing_service.ts: roughly 2,000 lines of request handling, pricing rules, database calls, and receipt formatting. Every change sends me scrolling. A coding agent can help untangle it, but the useful comparison is not which model writes prettier modules. It is whether I can verify the patch before merging it.
Here is a worked comparison of two approaches to the same job: ask for the whole refactor, or extract one responsibility at a time. The target stays identical: smaller modules, unchanged public exports, and no intentional behavior changes.
The Same Billing File, Two Different Agent Prompts
One-shot approach: “Refactor billing_service.ts into focused modules. Preserve behavior, update imports, and run the tests.” That sounds reasonable. It also delegates module boundaries, execution order, error handling, and test interpretation in one request. The resulting patch may be coherent while remaining expensive to review.
Small-slice approach: “Inspect billing_service.ts without editing. Identify pure helpers, side effects, public exports, and callers. Propose an extraction order, starting with the lowest-risk responsibility.” I review that map before authorizing edits. Inspection is a separate task, not a preamble the agent can rush past.
For example, I might use Claude Sonnet 5.5 for the dependency map and GPT-6 Astra for a second review. Through Fluxo, those requests share one key and one base URL, https://api.fluxorelay.com. Keeping the task and acceptance checks fixed makes changing models less disruptive.
First Patch: A Module Tree or One Receipt Formatter
One-shot approach: the agent moves pricing, persistence, and formatting together. Now a failed receipt test could come from a changed rounding rule, a different database response, or the formatter itself. The patch has multiplied the possible explanations.
Small-slice approach: extract receipt formatting first, provided inspection confirms it has no hidden dependencies. Before moving it, capture existing outputs for an ordinary invoice, a zero-value invoice, and a rounding boundary. These are characterization tests: they document current behavior, including quirks I might dislike.
My edit prompt is narrow: “Move receipt formatting into receipt_formatter.ts. Keep signatures, output strings, and exports unchanged. Do not rename symbols or fix unrelated issues. Stop after this extraction and report checks run.”
- Keep database access and pricing calculations outside this first patch.
- Preserve the original import path through a temporary re-export.
- Add focused tests before moving logic with undocumented edge cases.
- Reject unrelated cleanup even when the proposed cleanup looks sensible.
Terminal Checks: One Final Gate or Repeated Checkpoints
One-shot approach: run the full suite after everything moves. A green result is useful, but it cannot prove behavior the suite never exercised. A red result leaves a large search area.
Small-slice approach: establish a baseline first. Record existing failures, then run the focused tests, type checker, and relevant integration tests after each extraction. In a typical TypeScript repository, that might mean npm test -- receipt_formatter, npm run typecheck, and git diff --check. Use the repository’s actual commands, not commands invented by the agent.
I then inspect git diff --stat and git diff. If a formatter extraction changes SQL or retry handling, the slice has escaped its boundary. Once verified, commit it. The next extraction gets a fresh checkpoint and a smaller debugging surface.
Agent Context: The Whole File or the Next Boundary
One-shot approach: fewer prompts, but a broad task can trigger repeated reading and speculative fixes. Small-slice approach: more handoffs, each carrying the current goal, allowed files, preserved invariants, and exact verification results. Neither approach is automatically cheaper.
Fluxo works with Claude Code, Codex, Gemini CLI, and any OpenAI SDK, with access to Claude, GPT, Gemini, DeepSeek, Kimi, GLM, Qwen, Grok, and more. Billing follows real tokens, including cache reads and writes, with no monthly fee. Track those costs alongside review time rather than assuming smaller patches always consume fewer tokens.
The Verdict: Extract, Verify, Commit, Then Continue
Small slices win for this billing refactor. They make mistakes easier to locate, patches easier to review, and rollback less destructive. A one-shot rewrite remains useful for an exploratory branch, but I would not make it the default merge path for behavior-sensitive code.
If this fits your editor-and-terminal workflow, consider creating a Fluxo account. Invited users’ payments also earn you a referral share. The important habit, regardless of tool, is simpler: never let the agent’s next edit outrun your ability to verify the last one.