Lesson 150 of 170

Refactor without changing the contract

Martinez AI Studios Academy

Define a behavioral baseline, isolate structural changes, and produce before-and-after evidence that a refactor preserved gameplay behavior.

2168. Lesson identity

Module
5.7 — Refactoring
Lesson
Refactor without changing the contract
Title (EN)
Refactor without changing the contract
Title (ES)
Refactoriza sin cambiar el contrato
Academic type
Guided Build
Schema type
practical
Order
1
Estimated time
40–50 minutes
Content time
15–20 minutes
Practice time
25–30 minutes

This lesson treats refactoring as a controlled structural change. The implementation may be reorganized, renamed, or split, but the agreed gameplay behavior must remain observable and testable.

2169. Objetivo de aprendizaje

After this lesson, you can define a behavioral baseline, execute a staged refactor, and compare before-and-after evidence to determine whether the preserved contract still holds.

2170. Por qué es importante

A refactor can improve structure while quietly changing timing, costs, state transitions, or player-visible results. That risk increases when an AI tool edits several related files at once. A behavioral contract gives you a stable boundary for deciding whether the change is structural or actually changes the game. It also gives you evidence to review instead of relying on a clean build or an intuitive inspection of the diff.

2171. Conocimientos previos

You should have completed 5.6 L2 — Plan a staged multi-system change. You should be able to identify dependencies, divide a multi-system change into reviewable stages, and define evidence required before continuing. You should also be able to run the relevant project checks and inspect a Git diff.

2172. Core concept

A refactor changes how behavior is implemented without intentionally changing the behavior promised by the contract.

The contract must be stated in observable terms. It can include:

  • accepted inputs and required preconditions;
  • state changes and their order;
  • costs, rewards, and other values visible to the player;
  • emitted events or calls required by connected systems;
  • persistence expectations;
  • failure behavior and player-facing feedback.

The contract is not the current class layout, function name, file location, or internal data structure. Those are implementation details unless another system or an external tool depends on them.

A useful distinction is:

Question Structural refactor Gameplay behavior change
What changes? Organization, boundaries, names, duplication, or dependencies Rules, values, timing, state, or player-visible outcomes
What should remain stable? The behavioral contract Nothing is assumed stable without a new design decision
Required evidence Equivalent observations before and after New acceptance criteria and updated tests or evidence

2173. Mental model

Use the Baseline → Seam → One Move → Compare model:

  1. Baseline: Record the behavior that must remain stable before editing.
  2. Seam: Choose the smallest boundary where structure can change without redefining the contract.
  3. One Move: Make one coherent structural change, then stop and inspect it.
  4. Compare: Repeat the same observable checks and compare results with the baseline.

Represent the contract as a table before asking AI to edit:

Scenario Preconditions Action Expected state/result Evidence
Normal path What must already be true What the player or system does What remains true afterward Replay, test, log, or screenshot
Rejected path What makes the action invalid Invalid action State and feedback remain correct Test or captured output
Boundary path Relevant limit or transition Action at the boundary Limit behavior remains correct Test, log, or replay

A passing build is only one signal. It proves that the project compiles or loads; it does not prove that the contract survived.

2174. Concrete example

Suppose a reward calculation is currently mixed into a controller. The intended refactor is to move the calculation into a dedicated service and keep the controller responsible for orchestration.

Before the change, define observations such as:

  • a valid completion grants the same reward amount;
  • an invalid completion grants no reward;
  • the relevant progression state changes once, not twice;
  • the player-facing confirmation still appears under the same condition;
  • a repeated or boundary input does not create an extra reward.

The service extraction is structural if those observations remain true. Changing the reward amount, changing when progression advances, or changing the rejection message is not merely structural. Those are gameplay decisions and must be treated as a separate change with new acceptance criteria.

2175. AI-native workflow

Use AI as an implementation assistant, not as the authority on contract preservation.

  1. Give the agent the stated contract, the baseline evidence, the intended seam, and explicit non-goals.
  2. Ask it to propose the smallest file and symbol set for the first structural move. Require it to identify behavior that could be affected.
  3. Review the proposal. Reject any step that changes rules, values, timing, or player-facing behavior without a deliberate decision.
  4. Ask for one bounded edit, not a broad cleanup. Instruct the agent to preserve public interfaces or provide an explicit compatibility layer where necessary.
  5. Inspect the diff before running the checks. Look for accidental changes to condition order, default values, event emission, error handling, and state ownership.
  6. Run the same evidence checks used for the baseline. Ask AI to compare the observations, but make the final judgment yourself.

A useful request is:

Refactor only the structure described below. Preserve every listed contract and non-goal. First propose the smallest staged edit. Do not change gameplay values, state-transition order, timing, failure behavior, or player-facing text. After the edit, list each contract and the evidence that should verify it.

Do not accept a statement such as “behavior should be unchanged” as evidence. Require a checkable observation.

2176. Git workflow

Create a reviewable boundary before the structural edit, using the repository workflow already established for the project. Keep the baseline evidence with the change record or in the project’s existing verification location. Then:

  • inspect the working tree before editing;
  • keep the first refactor stage narrow enough to review;
  • inspect the diff after each bounded move;
  • avoid mixing formatting churn, unrelated cleanup, and gameplay changes into the same change;
  • record which checks were run and whether they match the baseline;
  • preserve the option to revert the structural move without discarding unrelated work.

A commit or equivalent checkpoint is not proof of correctness. It is a recovery and review boundary.

2177. Common mistake

The common mistake is treating a passing build, unchanged screenshot, or small diff as proof that the contract was preserved. A refactor can compile while changing a default value, emitting an event twice, advancing state earlier, or altering an invalid-action path. Compare the same scenarios and observations before and after the edit.

Another common mistake is allowing the AI to combine refactoring with “helpful” gameplay cleanup. If the agent changes names, architecture, balance values, and edge-case rules in one pass, you can no longer tell which change caused a behavioral difference. Separate structural work from behavior changes.

2178. Guided practice

Perform a controlled refactor in a small, isolated part of the project or in an existing practice area.

Step 1 — Select the boundary

Choose one piece of code with a clear responsibility boundary and at least one caller. Do not choose a broad cleanup. Write one sentence describing the structural change, such as “move responsibility X behind boundary Y.”

Step 2 — Define the baseline

Complete a contract table with at least three scenarios:

  • one normal path;
  • one rejected or failure path;
  • one boundary, repeated-input, or state-transition path.

For each scenario, capture observable evidence. Use the project’s available tests, logs, replay steps, screenshots, or recorded state values. Record exact values where values matter.

Step 3 — Ask for a staged proposal

Give the contract and non-goals to AI. Ask for a proposal containing:

  • the smallest first edit;
  • files and symbols affected;
  • dependencies that must remain compatible;
  • possible contract risks;
  • the check to run immediately after the edit.

Choose whether to accept, narrow, or reject the proposal. Your decision is part of the exercise.

Step 4 — Execute one structural move

Apply only the accepted move. Preserve behavior-related values and conditions unless the move cannot be completed without changing them. If a behavior change appears necessary, stop and classify it as a separate design change rather than silently including it.

Step 5 — Compare evidence

Run the same scenarios from the baseline. Compare state, values, event counts, timing-sensitive observations where relevant, and player-facing feedback. Inspect the diff and note any discrepancy, even if it appears beneficial.

Step 6 — Decide the outcome

Classify the result as one of the following:

  • Preserved: all required observations match and the diff is within the stated structural boundary;
  • Needs correction: a contract observation differs or the diff contains an unintended behavior change;
  • Not a refactor: the requested change requires a new gameplay contract and should be replanned as behavior work.

If the result is not preserved, revert or repair the bounded move before attempting another structural change.

2179. Validation / evidence

Your work is complete when you can point to all of the following:

  • a written contract with at least three observable scenarios;
  • a recorded before-state or baseline for each scenario;
  • an AI proposal that identifies scope, risks, and non-goals;
  • a narrow diff showing the structural move;
  • after-state evidence from the same scenarios;
  • a comparison that states whether each contract item was preserved;
  • a decision explaining why the result is a preserved refactor, a correction, or a behavior change requiring separate planning.

Practical scoring checklist

Score each criterion from 0–2: 0 = missing, 1 = incomplete or weakly supported, 2 = complete and supported by observable evidence.

  • Baseline completeness: includes the required normal, rejected or failure, and boundary or repeated-input scenarios.
  • Scope discipline: states the structural boundary and non-goals, with no unrelated cleanup or behavior work.
  • One-move staging: applies one coherent structural move and stops for review.
  • Before-and-after equivalence: repeats the same checks and shows whether each contract observation matches.
  • Diff review: identifies relevant changes and checks for unintended values, conditions, events, state transitions, and player-facing effects.
  • Rollback readiness: preserves a clear recovery boundary and can revert the move without discarding unrelated work.
  • Decision quality: classifies the result as preserved, needing correction, or requiring replanning, and supports that decision with evidence.

A satisfactory submission scores at least 12 of 14 points and receives 2 points for before-and-after equivalence. If equivalence is not demonstrated, the refactor is not yet validated regardless of the total score.

The strongest evidence combines automated checks with at least one observation of actual runtime or player-facing behavior when the refactor affects a runtime path. A clean build alone is insufficient.

2180. Key takeaways

  • A refactor is structural only when its behavioral contract remains stable.
  • Define observable baseline evidence before changing the structure.
  • Make one bounded move at a time and inspect the diff before continuing.
  • AI can propose and implement the move; the developer must define the contract and judge the evidence.
  • Gameplay changes discovered during refactoring should be separated and replanned, not hidden inside the cleanup.

2181. Next lesson

Next, continue to 5.7 L2 — Refuse an attractive but unsafe abstraction, where you will use contract evidence to decide when a proposed abstraction should be narrowed, postponed, or rejected.

2182. Knowledge check

Answer these items for yourself before reading the answers.

Which item belongs in a behavioral baseline for a refactor?

  • A. The current folder name, regardless of its effect on behavior.
  • B. The exact number of lines in each source file.
  • C. An observable result for a defined scenario, such as a state change or reward.
  • D. The AI agent's preferred class design.
Show answer and feedback

Answer: An observable result for a defined scenario, such as a state change or reward.

Why: A behavioral baseline records what can be observed and compared before and after the change. File layout and agent preference are implementation details, not proof of preserved behavior.

What is the safest first request to make to an AI agent during this refactor?

  • A. Ask it to propose the smallest edit, its risks, and the check that should follow.
  • B. Ask it to clean up every related file in one pass.
  • C. Ask it to change gameplay values if they seem inconsistent.
  • D. Ask it to decide whether the contract was preserved without running checks.
Show answer and feedback

Answer: Ask it to propose the smallest edit, its risks, and the check that should follow.

Why: A small proposal with explicit risks and follow-up evidence keeps the change reviewable and prevents unrelated behavior changes from being bundled into the refactor.

A refactor compiles, but a repeated input now grants the reward twice. How should this result be classified?

  • A. Preserved, because compilation succeeded.
  • B. Needs correction, because an observable contract item changed.
  • C. Preserved, because the diff is small.
  • D. Not a contract issue if the player does not notice immediately.
Show answer and feedback

Answer: Needs correction, because an observable contract item changed.

Why: The repeated-input scenario is part of the observable baseline. Granting the reward twice changes behavior, so the bounded move needs correction before the refactor continues.

Which change should be separated from a behavior-preserving refactor?

  • A. Moving a calculation behind a dedicated boundary while preserving its results.
  • B. Renaming an internal symbol without changing its interface or behavior.
  • C. Changing the reward amount and the condition that advances progression.
  • D. Splitting one implementation into two internal helpers with equivalent results.
Show answer and feedback

Answer: Changing the reward amount and the condition that advances progression.

Why: Changing reward values or progression conditions changes gameplay rules. It requires a separate behavior decision and updated acceptance criteria rather than being hidden inside a structural refactor.

Support