Test-driven, when it applies.
Write the test first. Watch it fail. Write the minimal code to pass. If you didn’t watch it fail, you don’t know it tests the right thing — tests written after code pass immediately, which proves nothing.
When it applies
Bug fixes (a failing test reproduces the bug, the fix makes it pass), behaviour changes, and feature work with clear inputs and outputs. Refactoring of already-tested code, where the existing suite is the safety net.
Where it doesn’t — and isn’t forced: exploratory spikes, framework or config scaffolding, one-off scripts, and documentation-only changes. When uncertain, the default is to write the test — the 30 seconds to find out usually costs less than debugging later.
Red · Green · Refactor
Red — one test, one behaviour, then watch it fail for the expected reason. Green — the simplest code that passes; no extra parameters “for the future.” Refactor — clean up only after green, with tests staying green throughout.
The task protocol’s implementation step expects this discipline; the optimize protocol’s frozen-paths hook physically prevents editing tests mid-experiment.