FoundationsGENERALCONTESTED

Changeability Is the Goal

Design has no intrinsic virtue. Every structural claim in this domain has to cash out as a change that got cheaper, or it is decoration.

The requirement, the obvious build, and why it breaks

Every lesson starts where the work starts: someone asked for something, and the first implementation that comes to mind survives until the requirement changes.

The question

How do I tell a good design argument from an aesthetic preference?

The requirement

A code review comment says "this should use the repository pattern". The author asks why. The reviewer says it is cleaner.

The obvious build

Follow established principles. SOLID, clean architecture and the patterns exist because they work; disagreeing with them is inexperience.

Why it breaks

Principles are compressed advice for situations. Applied outside the situation that produced them they are frequently wrong, and appealing to authority hides that.

How it breaks as requirements change
  • Principles are compressed advice for situations. Applied outside the situation that produced them they are frequently wrong, and appealing to authority hides that.
  • "Cleaner" is not a shared standard. Two engineers can hold opposite structural preferences and both cite the same principles honestly.
  • It also makes disagreement unresolvable, so it gets settled by seniority — which is how codebases acquire structure nobody can defend and nobody may question (Tone, Disagreement and Receiving Review).
  • And it is empirically shaky. Many of the strongest claims in this field have never been demonstrated to reduce anything measurable (How SOLID Gets Misused).
RequirementConstraintsInvariantsResponsibilitiesBoundariesInterfacesStateDependenciesFailureImplementationTestsFeedbackEvolution

What limits the solution, and what must never stop being true

This domain leads with these two. A design that ignores its constraints is not a design, and an invariant nobody named is one nothing is protecting.

Constraints
  • Both people are acting in good faith and neither has a shared standard to appeal to.
  • The change is small; the discussion is about to cost more than the code.
Invariants
  • A design claim must be falsifiable. If no possible observation would change it, it is a preference and should be labelled as one.

Who owns what, and where the seams fall

Responsibilities decide boundaries; boundaries decide what an interface has to say.

Responsibilities
  • Whoever proposes a structure owns naming the change it makes cheaper.
  • Whoever resists owns naming what it costs. Both are falsifiable claims and both can be wrong.
Boundaries
  • The line between design argument and preference is exactly whether a specific future change is named. Everything else follows from that.

Two versions of the same review comment

The difference is not politeness or seniority. One version can be answered with evidence and the other can only be agreed or resented.

A review comment on a service that calls the database directly
Not arguable
"This should use the repository pattern — it's cleaner
 and follows separation of concerns."

The author can:
  - agree (and learn nothing)
  - disagree (and it becomes about them)

Nothing would settle it either way.
Arguable
"Three services now build this same tenant-scoping
 clause inline. If we get scoping wrong in one, it's a
 data leak across tenants. A repository puts that clause
 in one place and lets us test it once.

 Cost: an indirection, and it will leak the moment we
 need a query with a join. Worth it for the scoping;
 I wouldn't add it for a single caller."

The author can now answer:
  - "there's only one caller, the other two are different"
  - "scoping is already enforced by a policy in the driver"
  - "agreed, and let's keep the join escape hatch"

The second names the invariant at risk (tenant isolation), the specific change it makes cheap (scoping in one place), and its own cost (leaks on joins). All three are things the author can accept or refute with facts about this codebase, which means the discussion can actually end.

The question that terminates the argument

One question does most of the work, and it is worth asking of your own proposals before anyone else has to: what change does this make cheaper, and how would I know if I were wrong?

Three answers are legitimate and only one of them is a design argument. Being clear which one you are making is most of the value.

  • The second option is the strongest and the most under-used: present evidence beats predicted futures every time.
  • The third is where this standard is weakest, and the honest response is to admit that rather than force it into the first category.
  • A proposal that cannot be placed in any of these five is usually pattern-matching on a book (Pattern Overuse).
Someone proposes a structure. What kind of claim is it?

What would make this proposal wrong?

A named future change

when "So we can add a second provider without touching checkout."

cost A design argument. Refutable by showing the change will not come, or that it is cheap without the structure. Argue it on the merits.

A named present problem

when "This rule is in four places and one of them is already wrong."

cost The strongest kind — evidence, not prediction. Should usually win.

Comprehensibility

when "I could not follow this without asking you."

cost Legitimate and hard to measure. Treat the reviewer's confusion as the evidence it is, rather than requiring them to prove it.

Consistency

when "The other six modules do it this way."

cost Honest and often sufficient. Say it plainly rather than dressing it as a principle — and notice when it means propagating something you would not choose again.

Aesthetics

when "This is cleaner."

cost Not a design argument. Fine as a preference, and it should not outrank the author's judgement on its own. If it is about formatting, a tool should be settling it (What to Automate Out of Review).

How to build it

Most important first.

  • State the change. "This should be a repository so we can swap Postgres for DynamoDB" is arguable; "this is cleaner" is not.
  • Ask whether that change is plausible. If nobody expects to swap the database, the argument has been made and lost, honestly (The Cost of Change).
  • Name what it costs — indirection, a leaky abstraction over transactions, a boundary that will not survive contact with a query that needs a join (When the Repository Is Just Indirection in Backend).
  • Accept preference as preference. Consistency is a legitimate reason; "we do it this way here" is honest in a way that "cleaner" is not.
  • Let tooling settle the aesthetics so review can spend its attention on the parts that are actually arguable (What to Automate Out of Review).

What the next change costs

The field this whole domain exists for. A structure is only better if it makes the change after this one cheaper — and it is worth saying which changes it does not help.

Cost of the next change
  • The standard itself costs a sentence per design discussion. It saves the recurring, unresolvable argument, which in most teams is a substantial share of review time.
  • It also changes what gets built: structures that cannot name their change tend not to get built, which is the intended effect.
What the recommended approach costs
  • Demanding falsifiability slows down experienced engineers whose instincts are usually right, and some of that friction is genuinely wasted.
  • Not every good structure has a nameable change. Some are about comprehensibility, which is real and much harder to argue about — and this standard is weakest exactly there.

What can go wrong

Failure modes
  • The standard becomes a weapon — demanding a named change for every suggestion turns review into an interrogation and is its own kind of unpleasant.
  • Falsifiability is used selectively, applied to other people's proposals and not one's own.
  • It collapses into "never change anything without a ticket", which is the opposite failure and just as expensive.
Dependencies, and their direction
  • This lesson depends on being able to price a change, which is why it comes after cost-of-change rather than opening the domain.
Misreads
  • "So principles are useless." They are compressed experience and often right. The point is that they are evidence in an argument, not the conclusion of one.
  • "So only measurable things matter." Comprehensibility matters enormously and resists measurement. The demand is for a *named* consequence, not a metric.
  • "This means juniors can veto senior design." It means both have to make an argument. That is usually good for the design and always good for the team.

Testing it, and how it ages

What to test, and at which boundary
  • The strongest version of a design argument is a test that would be easy under the proposal and is hard now. If nobody can write that test, the claim is weaker than it sounded (Testing as Design Feedback).
How this design ages
  • A named change also gives the structure an expiry: when it becomes clear the change will never arrive, the structure can be removed with the same argument that justified it (Revisit Triggers).
  • This is how a codebase sheds structure, which almost none of them do, because nothing ever gives permission.

Where this applies

This domain's advice is contested more than most. These labels say what each claim is specific to — and where CONTESTED appears, the note gives the strongest form of the opposing view rather than a caricature.

  • GENERALRequiring a design claim to name a consequence is a standard of argument, so it applies wherever design is discussed, independent of stack.
  • CONTESTEDThe strongest opposing view: much of what makes a codebase good is taste that cannot be decomposed into named future changes, and demanding justification for each move privileges the articulate over the skilled while slowly eroding standards nobody can defend on the spot. That is a real cost, and it is why "consistency with the surrounding code" should be accepted as a complete answer.

Where the depth lives

This domain teaches the codebase-level structure and hands the rest off.

Domains that do not exist yet
  • Testing & Reliability Engineering — "what test would this make easy" is often the sharpest form of a design argument, because it turns a structural claim into something you can write down and run.