2183. Lesson identity
2184. Learning objective
After this lesson, you can explain why an AI-proposed refactor should be narrowed, postponed, or rejected by evaluating its complexity, ownership boundaries, and abstraction cost.
2185. Why this matters
AI-generated refactors often look professional because they reduce repeated code and introduce reusable interfaces. That appearance is not evidence that the abstraction matches the game. An abstraction can hide important differences, spread ownership across unrelated systems, and make future behavior harder to reason about. Refusing a refactor is a technical decision when the proposed design creates more risk than value.
2186. Prior knowledge
You should be able to:
- identify a behavior contract before changing code;
- compare observable behavior before and after a refactor;
- distinguish a local cleanup from a change in ownership or responsibility;
- use the previous lesson's principle: refactor without changing the contract.
2187. Core concept
An abstraction is justified by stable shared behavior, not by superficial similarity.
Two pieces of code may look alike while representing different rules, having different owners, or changing for different reasons. Generalizing them too early creates an abstraction tax: additional concepts, indirection, configuration, and coordination that every future change must pay. A safe refactor preserves the contract and keeps responsibility legible. If the proposed abstraction does not meet those conditions, narrow it, postpone it, or reject it.
A useful evaluation asks four questions:
| Question | Evidence to seek |
|---|---|
| What behavior is genuinely shared? | The same inputs, outputs, invariants, and failure rules |
| Who owns the behavior? | A clear system or module responsible for changing it |
| What future change is being anticipated? | A concrete, likely variation rather than a hypothetical one |
| What complexity does the abstraction add? | New interfaces, parameters, indirection, configuration, and tests |
2188. Mental model
The abstraction-cost test
Treat a proposed abstraction as a decision, not as an automatic improvement:
Observed duplication → Shared contract? → Shared owner? → Lower total complexity? → Accept, narrow, postpone, or reject
Use this decision table:
| Finding | Decision |
|---|---|
| Behavior and ownership are stable, and the abstraction removes more complexity than it adds | Accept a small abstraction |
| Some behavior is shared, but important details differ | Narrow the abstraction or extract only the stable core |
| The similarity is likely temporary or the future variation is speculative | Postpone generalization |
| The abstraction mixes unrelated responsibilities or obscures the contract | Reject it |
The standard is not “Can this be made generic?” The standard is “Will this make the next correct change easier to make and verify?”
2189. Concrete example
An AI reviews two local systems in a game prototype:
- A pickup interaction checks whether the player is close enough, grants an item, and removes the pickup.
- A door interaction checks whether the player is close enough, verifies an access condition, and changes the door state.
The AI proposes a generic Interactable framework with a shared interface, interaction queue, context object, result enum, event bus, and configurable validation pipeline. The proposal is attractive: both systems have an interaction prompt and both respond to player proximity.
The proposal should not be accepted as written. The visible similarity is narrow, while the rules and ownership differ. Pickup inventory logic belongs with item acquisition; door access and door state belong with the door or access system. A shared prompt or distance check might be a useful narrow extraction if it has a stable contract. The queue, event bus, and generalized result model are not justified by the example alone.
A sound response to the AI could be:
“Do not introduce the generic interaction framework. Keep pickup and door rules separate. First extract only the repeated proximity check if its inputs and failure behavior are identical. Record the remaining duplication as a deliberate follow-up, and validate that the interaction contract is unchanged.”
This is not a refusal to improve the code. It is a refusal to add speculative ownership and indirection.
2190. AI-native workflow
Use AI as a proposal generator and critic, not as the authority that decides whether generalization is safe.
- Ask the AI to state the current contracts, owners, and differences between the candidate systems.
- Ask it to separate verified duplication from speculative future requirements.
- Ask for the smallest possible refactor and a list of complexity added by the larger abstraction.
- Compare the proposal with the actual code and the behavior baseline from the previous lesson.
- Choose one decision: accept a narrow extraction, postpone generalization, or reject the abstraction.
- If you implement a change, make it a bounded change and re-run the relevant behavioral checks. Do not accept a broad framework merely because the generated code compiles.
A useful prompt is:
“Analyze this proposed abstraction as a risk review. List the shared contract, distinct rules, ownership of each rule, new indirection, new configuration, and tests required. Recommend accept, narrow, postpone, or reject. Do not write code until the recommendation is justified.”
2191. Common mistake
The common mistake is treating duplicated syntax as duplicated responsibility. Developers often accept a generic base class, manager, or event system because it makes the current diff shorter. That can move decision-making away from the system that owns the rule. The result is code that is more abstract but less clear, with behavior controlled by flags and callbacks instead of direct contracts.
Another mistake is using “we may need this later” as proof that the abstraction is needed now. A possible future feature is not a current requirement. Preserve a clear local design until a real second case demonstrates a stable shared contract.
2192. Practical assessment
Case-study decision memo
The quiz is a formative knowledge check. This decision memo is the scored practical assessment for the lesson.
Review the following proposal:
“The game has three systems with a
canActivate()check: a healing station, a locked gate, and a quest trigger. Create anActivatablebase class with a universalcondition,cost,onActivate, andonFailurecallback. Route all activation through oneActivationManagerso future devices can be added without new code.”
Write a short decision memo with these five parts:
- Shared behavior: Identify what is truly common and what only looks common.
- Ownership: Name the system that should own each rule: healing, access, or quest progression.
- Abstraction cost: List at least three costs introduced by the base class and manager.
- Decision: Choose accept narrowly, postpone, or reject, and justify the choice with evidence from the case.
- Safe next step: Specify the smallest change, if any, that can be implemented and verified without changing behavior.
Your decision must include one concrete reason, not only a preference about code style.
2193. Validation / evidence
Score the memo on six criteria, with 0–2 points per criterion:
| Criterion | 0 points | 1 point | 2 points |
|---|---|---|---|
| Shared-contract evidence | Assumes similarity is sufficient | Identifies some shared behavior | Compares inputs, outputs, invariants, or failure rules and distinguishes shared shape from shared rules |
| Ownership | Omits owners or centralizes every rule | Names owners without explaining the boundary | Assigns healing, access, and quest rules to clear owners and explains why |
| Abstraction cost | Gives no concrete cost | Names one or two costs | Names at least three relevant costs, such as indirection, configuration, coordination, or additional tests |
| Decision justification | States only a preference | Gives a general reason | Selects accept narrowly, postpone, or reject and supports it with case evidence |
| Bounded next step | Proposes a broad rewrite or no next step | Suggests a change without a clear boundary | Defines the smallest safe change, or explicitly records why no change should be made |
| Validation evidence | Provides no behavioral check | Names a vague check | Names the existing contract and the specific checks or observations that would confirm unchanged behavior |
The practical assessment is complete at 9 of 12 points, with at least 1 point in both decision justification and validation evidence. Record the memo, criterion scores, total score, assessor feedback, and status as complete or revise.
A strong answer may accept a small shared primitive such as a verified proximity check while rejecting the universal activation framework. The quality of the answer depends on the reasoning and boundaries, not on choosing rejection for its own sake.
2194. Key takeaways
- Similar syntax does not prove a shared contract or a shared owner.
- Abstraction cost includes indirection, configuration, coordination, and verification burden.
- Generalize stable behavior, not speculative future features.
- A narrow extraction, postponement, or rejection can be the correct refactoring decision.
- AI can expose options and risks; the developer must judge whether the abstraction fits the game.
2195. Next lesson
Next: continue to 5.8 — AI code review, where you will apply disciplined review criteria to AI-assisted changes.
2196. Knowledge check
Answer these items for yourself before reading the answers.
What is the strongest reason to reject a proposed generic activation framework?
Show answer and feedback
Answer: The framework would mix rules with different owners and add indirection without a stable shared contract.
Why: An abstraction becomes unsafe when it obscures distinct responsibilities and adds complexity without a stable shared contract. The language mechanism, file count, and generation speed do not determine whether the design fits.
When is postponing generalization the most defensible choice?
Show answer and feedback
Answer: When the proposed future variation is hypothetical and the shared contract has not stabilized.
Why: Postponement is appropriate when the design is being shaped around an imagined future and the common behavior has not been demonstrated. Waiting for a real second case can reveal the correct boundary.
What should the developer ask the AI to do before accepting a broad refactor?
Show answer and feedback
Answer: Review the shared contract, distinct rules, ownership, added indirection, and verification burden.
Why: The developer needs a risk review before implementation. Examining contracts, ownership, indirection, and verification makes the abstraction's cost visible and supports a bounded decision.