Inspired by Thoughtworks Sensible Defaults.
These are not rules. They're defaults — starting positions that should be followed unless you have a good reason not to, and where exceptions require explicit justification.
- Integrate frequently and continuously — If you're not integrating at least daily, you're accumulating merge risk.
- Code is written with test-driven development — Tests aren't written after; they're written first. This changes how you design, not just how you verify.
- Develop in pairs — See Pairing Guidance.
- Smallest value-oriented stories — Break work down until each card can be delivered and validated independently. Large cards hide risk.
- Security is automated in the SDLC — Security checks run in the pipeline, not as a quarterly audit.
- Every code change is monitored and observable — If you can't observe the behavior of your code in production, you don't know if it works.
- Build pipelines automate local development — The pipeline should remove friction from running the system locally, not just from CI.
- Technical change requires a value proposition — Refactors, upgrades, and rewrites need to be justified in terms of value delivered, not just technical preference.
- Deployment is decoupled from release — You can deploy any time. Whether users see the change is controlled separately, via feature flags or equivalent.
- Measure quality — Code coverage, static analysis, and other quality signals are tracked and visible.
Supporting Resources
- Continuous Integration — Martin Fowler
- Test-Driven Development — Martin Fowler
- On Pair Programming — Martin Fowler
- Feature Toggles — Martin Fowler
- Observability-Driven Development — Honeycomb
- Snyk CI/CD Integration