Modernization starts with a safety baseline

Modernizing a legacy module does not begin with a rewrite. First, record how the module behaves today: its inputs, observable outputs, side effects, integrations, and failure paths. A baseline protects against silently changing the contract under the guise of a technical improvement.

A baseline is not a claim that current behavior is correct. It is a recorded comparison point that can be reviewed after each small step and separately compared with business expectations.

What belongs in the baseline

LayerWhat to recordEvidence anchor
Contractpublic inputs, outputs, errors, and messagesAPI, public methods, integration contract
Statestate changes, writes, events, and timestampstests, persistence code, logs
Dependenciesexternal clients, configuration, and feature flagsimports, config, environment, callers
Checksexisting tests, build, static checks, and manual scenarioscommand + actual result
Recoveryrollback point, stop condition, and decision ownerGit baseline, runbook, review decision

Invariants and characterization candidates

  • the external API and result format do not change without a separate scope decision;
  • error codes, messages, and important side effects remain consistent;
  • the operation order is preserved when it affects money, data, or retry behavior;
  • each characterization candidate has a concrete input, observable output, and evidence anchor;
  • unknown behavior is marked as unknown rather than filled in with an assumption.

Preparation sequence

  1. Choose one module or business flow that belongs in the modernization slice.
  2. Read the current-state map, tests, configuration, callers, and external boundaries.
  3. Describe inputs, outputs, side effects, failure paths, and invariants.
  4. Run available focused checks, or mark them unknown if they cannot be run.
  5. Save the baseline and rollback point.
  6. Ask a reviewer to check whether the baseline describes actual behavior rather than the desired architecture.

When you must not move on to changes

Do not move on to refactoring if the scope covers several unrelated flows, there is no way to observe the result, or it is unclear who makes the business decision. Missing safety net is a reason to collect evidence first, not a reason to make the patch larger.

Rollback must be a practical action: a clear checkpoint, a bounded diff, and a check that returning does not leave partially moved state.

Canonical lesson source · JavaRush

Open JavaRush material