Most of my writing is about the technical decisions and tradeoffs that shape long-lived systems: migrations, architecture, testing culture, technical debt, and how teams scale software over time. The posts below give a good sense of the problems and decisions I keep coming back to.
All blog posts were written without the assistance of AI.
Review your own AI-generated code
Why AI changes the value of code review and shifts attention toward plans and specs
Migration strategies in large codebases
How to move a large codebase forward without stopping feature development
Human factors in choosing technologies
Why adoption risk, onboarding cost, and team fit matter as much as technical merit
Third-party libraries are no party at all
A practical framework for evaluating the hidden costs of third-party dependencies
Shifting the testing culture: Motivation
How testing became part of engineering culture instead of an optional extra
Flywheel of tech debt
Why tech debt in shared infrastructure compounds faster than most teams expect