Safeguard
Security Guides•

Why a security fix should not ship inside a refactor

Mixing a refactor with a security fix hides the fix, slows review and complicates rollback. How to split them and keep both changes easy to verify.

Safeguard Security Team
4 min read

Ship the security fix on its own, and do any refactor in a separate change before or after it. A small, focused fix is easy to review, easy to backport and easy to revert. The same fix buried in a refactor is hard to see, hard to verify and hard to undo.

What the guidance says

Google's engineering guidance on small changes says the right size is one self-contained change that addresses a single thing. It adds that refactorings are generally best kept separate from feature or bug fix changes, and that tests belong in the same change as the logic they cover. Security fixes are bug fixes with higher stakes, so the advice applies with extra force.

Problems with mixing

The fix disappears. A reviewer reading three hundred lines of renamed variables and moved functions will not notice the four lines that actually close the hole. Or they will notice, and not be sure whether anything else changed.

Verification is harder. To prove a fix works you need a test that fails before and passes after. With a refactor in the same change, a failing test could be caused by either.

Backporting gets painful. Supported older versions may need the same fix. A four line patch applies cleanly. A refactor entangled with it does not, and you end up rewriting the fix by hand for each branch.

Rollback loses the wrong thing. If the refactor breaks something and you revert, you also revert the fix and reopen the vulnerability. Google's guidance notes that small changes are simpler to roll back, which only helps if the fix is its own change.

Records get muddled. Release notes, advisories and audit trails want a clear line: this change fixed this problem.

The order of work

You have two choices.

Refactor first. If the vulnerable code is hard to change safely, land a behavior preserving refactor, with tests proving behavior is unchanged. Then apply the small fix on top. This is good when time allows.

Fix first. If the vulnerability is urgent, patch it in the smallest way, ship it, and refactor later. Do not wait for a perfect design while the flaw is live. Leave a note or ticket for the cleanup.

When in doubt during an incident, fix first.

Checklist for the fix

  1. One change, one problem.
  2. A test that reproduces the issue, in the same change.
  3. A description that says what was wrong, who was affected and how the change addresses it. Do not publish exploit details before users can update.
  4. No unrelated formatting changes. Run the formatter in a separate change.
  5. A note on which supported versions need the fix.

When they are tangled

Sometimes the vulnerable design is the problem and a patch will not do. Then a larger change is justified. Even then, break it into stages, keep each reviewable, and put the behavior change in the smallest stage, ideally behind a switch you can turn off.

Dependency updates

The same principle applies to dependency work. Do not bundle a security update with an unrelated major upgrade. If the major upgrade breaks something, you want to be able to keep the security patch.

Safeguard's autonomous remediation opens fix pull requests for vulnerable dependencies. It is off by default with every category on Manual, so a person decides what merges. The free scan is at gold.safeguard.sh/scan.

Quick check

What if the fix is trivial but sits in messy code?

Still ship the fix alone. Clean the code afterward in a separate change.

Can the test and fix share a change?

Yes, and they should. Google's guidance puts tests in the same change as the logic they cover.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.