Skip to content

The Drift Log · Audit, then actually repair

Harvesting Load-Bearing Logic Before Authorising a Rewrite

1 September 2026 · 3 min read · 641 words · opinion

A repository drawn as stacked file strata with a blue scanning plane sweeping through

Total rewrites fail because legacy code silently encodes edge cases. Extract and verify deterministic domain logic before authorising new plumbing.

Every engineering team eventually pitches a total rewrite. The argument is always familiar: the current codebase is brittle, the original authors left years ago, the framework is two major versions behind, and feature velocity has flatlined.

Starting from a blank slate feels cheaper than understanding the mess. Management signs off because reading legacy code is slow, grinding work, while greenfield estimates always look clean on a roadmap.

Six months in, the greenfield project stalls. It stalls because the legacy code was not just poorly formatted. It was an unindexed record of five years of production edge cases.

What Disappears in a Rewrite

When you discard a legacy codebase wholesale, you do not just eliminate technical debt. You delete:

  • The custom parsing workaround for a third-party API that quietly drops payload headers on weekends.
  • The backoff and retry timing tuned after a cascading database outage two years ago.
  • The state reconciliation step that prevents duplicate charges when a webhook fires twice.
  • The date-math adjustment that accounts for historical schema migrations.

These are not bugs. They are load-bearing adaptations. They exist because real traffic broke simplistic assumptions.

When you start over, you do not bypass those edge cases. You simply schedule them to fail in production again, one incident at a time, until your new architecture becomes just as defensive and cluttered as the system you replaced.

The Harvesting Posture

The alternative to a ground-up rewrite is not endless, passive patching. It is capability harvesting.

Before authorising a rewrite, run a targeted code reuse audit. The objective is not to preserve the architecture. The architecture may well be broken beyond repair. The objective is to identify, isolate, and extract the deterministic domain logic that makes the system work.

Every legacy subsystem breaks down into three distinct layers:

  1. Plumbing: Transport logic, database drivers, framework glue, and serialization. This is what you want to modernise.
  2. Accidental complexity: Dead branches, defensive null checks against phantom bugs, and abandoned abstraction layers. This is what you want to delete.
  3. Load-bearing logic: The transformation rules, invariant calculations, state machines, and business rules. This is what you want to harvest.

A standard repository audit looks for security vulnerabilities or style infractions. A harvesting audit looks for pure capabilities trapped inside dirty wrappers.

When you extract those capabilities first, the migration posture changes completely. Instead of attempting to rewrite complex business logic from memory or incomplete documentation, you build the new system around verified, existing routines.

Isolating Invariants Before Replacing Plumbing

Harvesting requires mechanical separation. You cannot reuse logic that is physically bound to an active database handle or an HTTP context.

The process follows a strict sequence:

  1. Identify the boundary. Locate the entry point where external data enters the subsystem and where transformed data leaves it.
  2. Sever side effects. If a pricing calculator fetches exchange rates inside a loop, pass those rates in as an explicit parameter. Convert the routine into a pure function that accepts inputs and returns values.
  3. Capture historical test fixtures. Pull sanitized, historical production payloads and record the expected output matrix, especially the edge cases that look wrong but reflect deliberate business rules.
  4. Wrap and verify. Once the function runs independently of the legacy framework, treat it as an owned internal module with an explicit contract.

This turns high-risk refactoring into deterministic extraction. You are no longer guessing what the legacy code was supposed to do under pressure.

To prove the extracted routine is correct before cutting over any plumbing, run a shadow gauntlet. Pipe a sample of live or replayed production payloads through both the legacy code path and the isolated routine simultaneously. Compare the outputs byte-for-byte. Every discrepancy exposes either an unhandled side effect or an edge case your isolation missed. Do not touch the surrounding infrastructure until the divergence rate is zero.

This post supports the longer argument in Closing the Loop from Repository Audit to Merged Repair.

Keep reading

Next in the log

The Strategic Master Library · written and reviewed under the house's own epistemic rules: nothing claimed that we cannot show.