Cursor

Verified against Cursor · 2026-08-10

Force Cursor's Agent mode to prove a refactor changed nothing observable before calling it done

A pure-structure refactor brief that requires a characterization test capturing current behavior, bugs included, before any code moves, and forbids any change that isn't reachable purely by renaming, extracting, or reorganizing — so a refactor stays a refactor instead of quietly becoming an unannounced behavior change.

Cursor 2.24 fillable variables

The prompt

Ready to copy — highlighted parts are example details you can swap.

REFACTOR TARGET
lib/billing/invoiceGenerator.ts

GOAL STRUCTURE
Split the 400-line generateInvoice function into separate lineItemCalculator, taxCalculator, and formatter modules, each independently testable.

KNOWN QUIRKS TO PRESERVE, NOT FIX
Tax-exempt orders currently still show a $0.00 tax line instead of omitting it — downstream PDF template relies on that line always being present.

This is a structural refactor only — the observable behavior of lib/billing/invoiceGenerator.ts must be identical before and after, for every input a real caller could pass. If reaching GOAL STRUCTURE would require changing behavior anywhere, stop and name the conflict rather than refactoring through it.

STEP 1 — CAPTURE CURRENT BEHAVIOR
Before touching any code, write characterization tests against the current implementation covering: Every branch in the current tax-calculation logic (domestic, international, tax-exempt), rounding behavior at each step, and the exact line-item ordering in the final output.. These tests describe what the code does today, not what it should do — if something looks like a bug, capture it as current behavior anyway and flag it separately in your notes. Do not silently correct it while writing the test; that would mean testing against a target you already changed.

STEP 2 — REFACTOR
Restructure the code toward GOAL STRUCTURE using only moves that don't change behavior — extract, inline, rename, reorder, split, merge. If getting to the target shape genuinely requires a behavior difference somewhere, stop before making it and say so instead of quietly deciding the tradeoff yourself.

STEP 3 — CONFIRM
Run the Step 1 characterization tests against the refactored code, unmodified. Every one must still pass exactly as written. If a test needs to change to keep passing, that is evidence behavior changed, not evidence the test was wrong — report it as a break, not as a test fix.

WHAT NOT TO DO
- Do not fix a bug you flagged in Step 1 as part of this pass, even though you're already in the code.
- Do not rename anything not required to reach GOAL STRUCTURE just because you noticed a better name while in there — a drive-by rename is still an unannounced change to anyone reviewing this diff by intent, not by line count.
- Do not delete or loosen a characterization test that turns out to be inconvenient after the refactor; if it fails, the refactor is the thing in question, not the test.

WHEN DONE
State the number of characterization tests written, the number passing unmodified after the refactor, and every flagged-but-not-fixed quirk as a separate follow-up item, not folded into this change.

Customize

Optional — swap in your own details for the highlighted parts above.

Why this works

A model asked to refactor code will often quietly conflate "restructure" with "improve," because its training rewards output that looks better along every visible axis at once, and fixing a bug or renaming an awkward variable it notices along the way reads as strictly positive — but a refactor's entire value as a reviewable unit of work depends on the diff being behavior-neutral, and any snuck-in fix inside that diff makes it impossible for a reviewer to tell which lines are structural and which quietly changed what the system does. Requiring characterization tests written against current behavior, bugs and all, before any code moves converts the existing contract from something trusted to memory into something pinned down in an executable, checkable form, and explicitly instructing the model to capture a known bug as current behavior rather than fix it while it's right there closes the most common version of this conflation, where a genuine correctness fix hides inside what's presented as a pure restructure and becomes essentially unreviewable as a result, since a reviewer scanning a "just a refactor" diff has no reason to scrutinize logic for correctness the way they would a feature change. The instruction that a failing characterization test after refactor means the refactor is wrong, not the test, closes a related and easy-to-miss loophole: a model under pressure to make its own tests pass again will edit the test if that's the path of least resistance, which quietly redefines "unchanged" as whatever the new code happens to produce rather than what the old code actually did — the entire point of writing the test first is that it isn't allowed to move once behavior is supposed to be fixed.

What you get back

Step 1: wrote 14 characterization tests covering domestic/international/tax-exempt branches, rounding at each subtotal step, and line-item ordering. Flagged: tax-exempt orders emit a $0.00 tax line rather than omitting it — captured as-is per KNOWN QUIRKS, not fixed.

Step 2: split generateInvoice into lineItemCalculator.ts, taxCalculator.ts, and formatter.ts. No behavior-changing moves made; one planned extraction (memoizing the tax lookup) was skipped because it would have changed rounding order — flagged instead of made.

Step 3: all 14 characterization tests pass unmodified against the refactored code. 14/14 passing, 0 changed, 1 quirk logged as a separate follow-up (not fixed here).

Verified against

Cursor 2.2 · 2026-08-10

Changelog

  • 2026-08-10 — Initial publish, verified against Cursor 2.2 Agent mode on a structural refactor with characterization tests.

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
Brief Cursor's Agent mode to build a multi-file feature without wandering into untouched filesA Composer/Agent-mode brief that names the files in scope, the data contract between them, the codebase's existing conventions, and what to leave alone, plus a forced pre-edit plan, so an autonomous multi-file build stays inside the feature you actually asked for instead of expanding into whatever the semantic index surfaces as related.Cursor 2.22026-08-05Force Cmd+K to change only the highlighted lines, not the whole block around themA Cmd+K inline-edit instruction that states the transformation, an explicit byte-identical preserve list, and a fallback rule for when the transformation can't be done cleanly, tuned for the selection-scoped inline editor rather than a whole-file Agent pass.Cursor 2.22026-07-22Point Cursor BugBot at the actual risk in a PR instead of a generic pass over the diffA PR description written for BugBot, Cursor's automated PR-review agent, that states risk areas and known trade-offs up front and defines exactly how findings must be classified and cited, so its comment thread concentrates on real logic and security risk instead of restating the diff or re-litigating a deliberate choice.Cursor BugBotCursor 2.22026-07-30Write a Background Agent brief that survives running with nobody watchingA self-contained task brief for Cursor's Background Agents — the async, remote-run agent mode — with success criteria, a conservative-default policy for ambiguity, and a reviewable-PR requirement, since no one answers follow-up questions while it works in an isolated container.Cursor Background AgentsCursor 2.22026-08-02
All Cursor prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY