What this prompt does
This prompt drives a careful refactor from callback-style code to a modern async style while preserving observable behavior exactly. It frames the assistant as a senior [language] engineer and supplies four context variables — [language], [target_style], [preserve] (the behavior that must not change), and the [legacy_code] itself. The deliverables include the refactored code, preserved error propagation and cancellation as described, unchanged public signatures wherever feasible (with any forced change flagged), tests proving error paths behave identically before and after, a CHANGES note listing every subtle difference, and a short migration tip for callers.
The structure works because the real danger in this kind of rewrite isn't syntax — it's silently dropping an error path or altering cancellation timing during the conversion. By making [preserve] an explicit variable ("error propagation, cancellation semantics, retry timing"), the prompt names exactly what must survive the refactor. The demand for identical-behavior tests turns "trust me" into something verifiable, and the CHANGES note forces the model to disclose every subtle behavioral difference instead of hiding it inside a clean-looking diff.
When to use it
- Modernizing callback-hell code that nobody fully remembers anymore
- Converting nested callbacks to async/await or promises safely
- When error propagation and cancellation absolutely must be preserved
- When the code has callers you can't easily change, so signatures must stay stable
- When you need an auditable record of what changed before you trust the diff
- When a previous refactor silently broke an error path and you want guardrails
Example output
You get the refactored code in [target_style], a test suite that proves error paths behave the same before and after, and a CHANGES note enumerating every subtle behavioral difference the rewrite introduced. Public signatures stay intact where possible, with any unavoidable change called out explicitly so callers aren't surprised. A short migration tip for callers rounds it out, giving you something concrete to paste into a pull request description. The CHANGES note is the artifact to read first, because a refactor that looks clean in the diff can still have shifted timing or swallowed an error in a way only that note will admit.
Pro tips
- Be exhaustive in
[preserve]— list error propagation, cancellation, and retry timing explicitly so nothing slips through - Scan the CHANGES note before the diff; that's where dropped error paths and timing shifts get disclosed
- Keep
[legacy_code]to one cohesive unit so the behavior-preservation tests stay focused - If a public signature change is flagged, weigh whether you can avoid it before accepting it
- Use the migration tip to update callers in the same pass, not as a separate afterthought
- When in doubt about cancellation semantics, ask the model to walk through them step by step