The Restraint Principle: YAGNI for Agents
The Restraint Principle: YAGNI for Agents
An agent's default failure mode is not laziness. It is eagerness.
Ask for a config loader and you get a plugin system. Ask for one endpoint and you get a service layer, a repository interface, and a utils/ package. The code runs, the tests pass, and every line is defensible in isolation — yet the feature is three times the size it needed to be. This is the same drift described in Losing Control: When the Agent Goes Off-Plan, viewed through a narrower lens: not wrong code, but too much code.
The cost is real and compounding. Every unnecessary abstraction is a thing a human must now read, a thing the next agent must now hold in context, and a thing that can break. Over-building is a tax on the compounding layer — it makes the next feature more expensive, not less.
The decision ladder
Restraint is not a vibe; it is a gate evaluated before code is generated. Each rung is a question. Stop at the first one that answers the need.
flowchart TD
Need[A need arises] --> Q1{Does this need<br/>to exist at all?}
Q1 -->|No| Skip[Skip it]
Q1 -->|Yes| Q2{Already in<br/>the codebase?}
Q2 -->|Yes| Reuse[Reuse it]
Q2 -->|No| Q3{Standard library<br/>has it?}
Q3 -->|Yes| Std[Use stdlib]
Q3 -->|No| Q4{Native platform<br/>feature?}
Q4 -->|Yes| Native[Use native]
Q4 -->|No| Q5{Existing dependency<br/>already does it?}
Q5 -->|Yes| Dep[Use the dep]
Q5 -->|No| Q6{One-liner<br/>solves it?}
Q6 -->|Yes| Line[Write the one-liner]
Q6 -->|No| Write[Write the minimum<br/>necessary code]
The order matters. Most over-building happens because the agent skips straight to the bottom rung — writing new code — when a rung higher up already answered the need. The ladder forces the cheap answers to be ruled out first.
What restraint is not
Restraint is about necessity, not brevity. The goal is not fewer tokens or clever one-liners; golfed code is its own failure. The result is small because it is necessary, and no smaller.
Four things are never cut in the name of restraint:
- Input validation. Trusting unvalidated input is not minimalism, it is a bug.
- Error handling. A dropped error is a silent failure waiting to surface as a discovery-phase cost.
- Security. Auth checks, escaping, and secret handling are load-bearing.
- Accessibility. Semantic markup and labels are part of "necessary," not decoration.
The line is precise: cut the abstraction, not the safety.
Where it fits in the workflow
The Restraint Principle is a lens, applied at two phases of the Spec-Driven Workflow:
- Plan review. Before any code is written, the reviewed plan is the place to catch "does this need to exist?" A plan that proposes a new package to hold one function has already failed the ladder.
- Verify. Add necessity as an explicit dimension in Trust but Verify. Alongside "is it correct?" ask "is any of this unnecessary?" — new abstraction with a single caller, a dependency added for one line, a config knob nobody requested.
Recurring over-building is a constitution candidate: once "no new package for a single function" is a written rule, it stops being a judgment call and becomes a gate every future agent inherits.
Intensity
Restraint is a dial, not a switch. Match it to the stakes:
- Lite — nudge away from obvious over-building; leave judgment calls to the author.
- Full — enforce the ladder on every new construct; flag single-caller abstractions.
- Ultra — justify every new file, dependency, and layer against the ladder in the plan itself.
Prototypes tolerate more; load-bearing production code less. The dial lets one principle serve both.
Attribution
The decision ladder, the "necessity not brevity" framing, the never-cut safety floor, and the intensity levels are adapted from ponytail by Dietrich Gebert — an agent skill that applies YAGNI before code generation. Source: https://github.com/DietrichGebert/ponytail. On real projects its authors measured roughly half the code produced with safety held constant — evidence that restraint is a wall-clock win, not a stylistic preference.
The best code an agent writes is the code it was talked out of writing.