Multiple construction paths the agent scans in parallel to confirm field initialization is consistent across them. Behavioral preservation on every field-related edit requires verifying every path, multiplying the agent's context-window load by path count and the retrieval cost of pulling each construction body into context.
One construction path the agent reads to know what a fully-initialized object looks like; all other paths are one-line delegations the agent skips past during reasoning. The agent's context window holds the canonical constructor; the reasoning step count drops because field-set drift is impossible by construction, and verifying any one path verifies the family.
Before the refactoring
class Loan {static newTermLoan(commitment, customer, maturity) {const loan = new Loan();if (commitment < 0) throw new Error('commitment must be non-negative');loan.commitment = commitment;loan.customer = customer;loan.maturity = maturity;loan.expiry = null;loan.unusedPercentage = 0.0;return loan;}static newRevolver(commitment, customer, expiry) {const loan = new Loan();if (commitment < 0) throw new Error('commitment must be non-negative');loan.commitment = commitment;loan.customer = customer;loan.maturity = null;loan.expiry = expiry;loan.unusedPercentage = 1.0;return loan;}static newAdvisedLine(commitment, customer, expiry) {const loan = new Loan();if (commitment < 0) throw new Error('commitment must be non-negative');loan.commitment = commitment;loan.customer = customer;loan.maturity = null;loan.expiry = expiry;loan.unusedPercentage = 0.5;return loan;}}
After the refactoring
class Loan {constructor(commitment, customer, expiry, maturity, unusedPercentage) {if (commitment < 0) throw new Error('commitment must be non-negative');this.commitment = commitment;this.customer = customer;this.expiry = expiry;this.maturity = maturity;this.unusedPercentage = unusedPercentage;}static newTermLoan(commitment, customer, maturity) {return new Loan(commitment, customer, null, maturity, 0.0);}static newRevolver(commitment, customer, expiry) {return new Loan(commitment, customer, expiry, null, 1.0);}static newAdvisedLine(commitment, customer, expiry) {return new Loan(commitment, customer, expiry, null, 0.5);}}
N construction paths × M fields = N×M cells the agent verifies match on every field-related edit. Field additions cascade across all paths; per-path duplication consumes context budget that could be spent on the calling code. The agent's verification-surface cost multiplies with path count, and a partial update produces a half-initialized object that targeted tests may not exercise.
A long canonical parameter list is itself a token cost tax — the agent remembers positional argument order on every reading of a delegating factory. Wrong-position bugs become subtler than missing-field bugs; the agent's completeness-check cost rises during the consolidation itself because every existing call site must be confirmed to route through the canonical constructor.
Each variant constructor delegates to the canonical one; adding a new field touches the canonical constructor once and every variant inherits the change, and tests against the canonical body cover all variants transitively. The agent's reasoning-step cost per field edit collapses to one path, and verification surface contracts from N paths to one.
The canonical constructor grows into a many-parameter signature where the agent loses track of which combinations are legal. Context cost moves from per-path duplication to per-parameter combination explosion; a parameter object or named-argument shape becomes overdue, and context-window load rises with each new parameter added without a name boundary.