Choosing Refactoring Work Alongside a Committed Feature
An anonymous engineering engagement reserving recurring refactoring capacity and prioritizing frequently changed code while keeping behavior and roadmap decisions...
Make the maintenance decision beside the feature
A team wanted to improve a difficult codebase while continuing product work. Earlier concentrated cleanup efforts had not produced a lasting maintenance habit. Test feedback, duplicated code and difficulty navigating the application were among the concerns described in the account.
Ampity's work on this anonymous engagement used recurring refactoring capacity alongside feature development. Engineers selected maintenance items and prioritized frequently changed code. This was a choice about how to keep improvement in the work queue, not proof that a fixed allocation preserved feature throughput or that every cleanup deserved immediate implementation.
Decide which behavior is supposed to stay the same
Martin Fowler's definition of refactoring distinguishes changes to internal structure from changes to observable behavior. That gives a proposed refactor an acceptance boundary. A change that intentionally alters an output or permission needs its own behavior decision, even when the same edit also makes code easier to understand.
For a feature touching a difficult area, identify the supported inputs, results, failures and external effects before restructuring it. Existing output can reveal an undocumented obligation, but it can also contain a defect. An owner must decide whether a difference is a regression, an intended correction or UNKNOWN. Matching an older answer without that decision can preserve the wrong behavior.
Keep the preparatory structural change distinguishable from the new feature. Separate reviewable steps can make the explanation clearer, but the number of commits alone proves nothing. A reviewer still needs to know which step preserves behavior and which step intentionally changes it.
Use change frequency as a clue, not a permission rule
The recorded prioritization favored code engineers repeatedly visited. That connects maintenance to work the team expects to perform, rather than selecting a rewrite because a component looks old. It does not establish that every frequently edited area is the best next investment.
Rarely changed code can still contain an important security, data-integrity or recovery obligation. Its low change count is not evidence that leaving it alone is safe. Conversely, a busy file may reflect harmless formatting or shared configuration rather than a costly business dependency. Inspect why the code changes and what the proposed intervention would remove.
Fowler's opportunistic-refactoring discussion describes preparatory changes and warns about following improvements too far from the current task. It also ties refactoring to regression checks. That supports keeping a bounded maintenance item reviewable; it does not supply a universal capacity percentage or exemption from a team's release rules.
Select work using a small change card
Assume a fictional team is adding an export option. The rows below are alternative proposed maintenance items, not this engagement's backlog, tests or outcomes. Each supplies a reason for investigation and leaves the authorized owner to decide whether the item belongs with the feature.
| Proposed item | Supplied fictional evidence | What must remain separate | Planning decision |
|---|---|---|---|
| Extract repeated export formatting | The feature touches both copies of an agreed formatting rule | Structural consolidation and the new export option | Candidate for preparatory refactoring after preserving the existing accepted outputs |
| Change invoice rounding while consolidating helpers | Current and proposed rounding rules differ | Intended financial behavior and internal cleanup | Hold the behavior change for the domain owner; do not hide it inside the refactor |
| Inspect a rarely touched authorization check | A security owner has raised an unresolved permission concern | Change frequency and risk responsibility | Route the concern through its security process instead of dismissing it as stable code |
| Replace an export dependency with unknown consumers | The caller inventory is incomplete | A local code edit and compatibility across its consumers | Mark scope UNKNOWN and obtain the missing inventory before expanding the change |
For example, the first item may be useful because the feature must already pass through both formatting paths. That does not prove the paths agree today. Preserve representative accepted examples and ask the product owner about discrepancies before choosing a shared implementation. The second item requires a different decision because it would deliberately change the calculation.
Reuse the card with the feature, maintenance hypothesis, observed friction, affected consumers, required behavior, unresolved risk, acceptance owner and a scope limit. Record what product work it displaces. A maintenance label does not create additional engineering capacity.
Compare allocation choices without promising a constant pace
The engagement considered a feature freeze and selected ongoing maintenance alongside delivery. A bounded cleanup period can still be appropriate when a risk cannot be contained within ordinary work. Deferring an item can also be reasonable when its consequence and revisit condition are understood. Neither choice should be judged only by how many tickets it closes.
Product and engineering owners need to agree which commitments remain feasible as maintenance work is selected. A recurring allowance makes that tradeoff visible; it does not guarantee unchanged delivery. Unexpected compatibility work should return to the planning decision instead of silently consuming the next feature's scope.
An engineer's estimate of a small task is not authority to skip approval. Security, data, external-contract and deployment responsibilities still apply. This case does not prescribe an automatic size threshold, a standard sprint split or an organization-wide rule against planned cleanup.
Bound an exercise before relying on it
Begin with authorized read-only inspection of the proposed change, existing consumer records and retained regression results. The account does not provide a completed test packet for these recommendations. A passing current check also covers only the behavior it actually examines.
Any later executable comparison needs an explicitly approved isolated environment, synthetic or approved sanitized inputs, scoped identities and non-delivering billing, export and notification receivers. Define a bounded change, the observations that would reject it and a recovery owner before dispatch. No live customer export, authorization change or production rewrite is needed to fill the planning card.
Stop if the fixture can reach a live destination, the permitted identity changes, required behavior differs or the work expands beyond its agreed boundary. Retain the original result and classify the difference. Do not weaken the check or broaden the cleanup to make the current patch appear complete.
Returning to an earlier code artifact does not itself reconcile accepted writes, exported data or downstream actions. The service and data owners must establish the actual recovery boundary before treating a structural change as reversible.
Scope retained without a throughput result
The case supports recurring refactoring work, engineer-selected items and change-frequency prioritization alongside ongoing feature commitments. It does not establish a test-runtime reduction, less duplication, a feature count, unchanged velocity or a completed delivery period. Those observations would require their own definitions and comparable records.
The technical-debt reduction playbook owns execution after an intervention is approved. This case's narrower decision is which maintenance item to admit alongside the next feature, and when to return it for a separate scope or risk decision.
Next action: select or hold one maintenance item explicitly
Take the next committed feature and fill a change card for one proposed refactor. Identify the behavior it must preserve and the first unresolved consumer or risk owner. Have product and engineering agree whether to include it, fund it separately or hold it with a revisit condition. Leave intentional behavior changes visible as separate decisions.
Technical reference
Fowler's definition and opportunistic-refactoring discussion were checked on 18 October 2026 for the limited behavior-preservation, preparatory-change and scope-control distinctions linked above. They do not establish this engagement's allocation records, regression coverage, executed tests, rollout behavior or results. All change-card rows are synthetic.