Refactor Prompt — the Behavior Preservation Contract
"Refactor this code" invites silent behavior changes. The refactoring contract preserves business rules, outputs, and side effects — and flags uncertainty instead of deciding it.
Pattern matching, records, nullable annotations, async done right — a C# modernization scope with the rule that matters: modern equivalents are rarely exact equivalents.
C# has changed enough that pre-C# 8 code reads like a different language — but modernization is a behavior minefield: LINQ changes evaluation laziness, async changes timing, records change equality semantics. This prompt sets a concrete C# modernization scope: pattern matching and switch expressions over conditional chains, records for immutable data carriers, nullable reference annotations where the project enables them, LINQ only where it stays readable, async/await over raw continuations and never blocking with .Result. The modernization goal's warning does the safety work: check null handling, error behavior, and lazy-vs-eager evaluation before swapping anything.
Scope the features
A named list — patterns, records, nullable annotations, async hygiene — not a vague "make it modern".
Swap with suspicion
Each replacement is checked against documented behavior differences: null handling, laziness, equality.
Verify edge cases per API
Old and new calls must agree where it hurts — empty sequences, nulls, exceptions — not just the happy path.
The prompt is built to prevent that. Its known-failure-mode warning says "modern equivalents are rarely exact equivalents — check null handling, error behavior, lazy vs eager evaluation, and culture/locale defaults before swapping," and validation verifies each API replacement against documented edge cases. "If achieving the goal and preserving behavior conflict, behavior wins." It generates the refactor prompt; you run it and regression-test the diff yourself.
It leaves that code alone and says why. The objective reads "If a transformation cannot be made safely with the available information, leave that code unchanged and say why," and skipped transformations land under "Suggested but not applied" with the information that would unlock them. Blocking on async with .Result, for instance, is only untangled when the call graph is clear. You review before applying.
"Refactor this code" invites silent behavior changes. The refactoring contract preserves business rules, outputs, and side effects — and flags uncertainty instead of deciding it.
For code that ships weekly: a refactoring prompt where regression avoidance outranks improvement depth, log lines stay intact, and every step is rollback-friendly.
Generated code duplicates instead of extracting, wraps without deciding, and defends against impossible states. This prompt hunts those exact failure modes — without preserving bugs as behavior.
"Review this code" gets shallow comments. The review contract gets findings with severities, a checklist, and a verdict.
getByRole over CSS chains, auto-wait over sleep, web-first assertions — Playwright tests written the way Playwright wants.
"Fix this error" gets guesses. The investigation contract gets a ten-stage diagnosis: facts separated from assumptions, alternatives weighed, fixes justified.
Build behavior-preserving refactor prompts — goal, risk level, and code context turn into a safe refactoring contract.