Notes
A knowledgebase of ideas, concepts, and mental models I keep coming back to — on software engineering, agile, AI, and building products.
AI Coding Tools Work Best Small and Supervised
The empirical pattern with AI coding tools is simple: the bigger and more end-to-end the ask, the worse the output. Slice the work small and keep a human directing it.
Books That Shaped How I Work
A short, personal list of the books that most shaped how I think about motivation, delivery, teams, and problem-solving — with a one-line reason to read each.
Breaking Dependencies in Legacy Code
Legacy code is code without tests. Find seams, get it under a harness, pin its current behavior with characterization tests, and use the Mikado Method for larger structural changes.
Continuous Integration, Delivery, Deployment, and DevOps
CI, continuous delivery, continuous deployment, and DevOps are related but not synonyms. Here is a precise definition of each and how they build on one another.
The Roles on a Delivery Team
The roles a delivery or consulting engagement needs covered, and what each one owns, framed as responsibilities that may be shared or shift between engagements rather than fixed job titles.
Seven Design Smells of Rotting Software
Design smells describe rot in a system's overall structure rather than in one snippet. Here are seven to watch for, and why design principles exist to remove them rather than decorate code.
A Quick Tour of Domain Design Patterns
A short, practical glossary of domain design patterns — Service, Aggregate, Factory, Repository, Unit of Work, and Functional Core Imperative Shell — each with a cue for when to reach for it.
How to Think About Engagement Models
Matching engagement models to work type: fixed fee for defined deliverables, T&M-with-cap for shifting scope, retainers for ongoing capacity. The reasoning, not the rates, and why the weekly demo is the trust mechanism.
Quiet Failure Modes of an Engineering Org
The structural gaps that quietly erode an engineering organization, from unstructured talent evaluation to blurred leadership boundaries, and the durable, systemic fixes for each.
How to Decide What to Test
Tests have a purpose and a boundary, and confusing the two is why testing terms are so muddled. Here is a step-by-step way to decide which tests a feature actually needs.
Matching Engineers to the Right Project
How to evaluate engineer-project fit using team and individual signals, set people up to succeed, and decide fairly when a change of project, or of role, is the right call.
Make Your Coding Standards Measurable
Vague standards like 'write clean code' don't change behavior. Measurable standards do, because they can be checked objectively and enforced in review and CI. Treat thresholds as conversation triggers.
Actually Measuring Whether AI Improves Productivity
How to measure whether AI tools are genuinely improving engineering productivity: define a clean adoption window, combine flow metrics with surveys, watch for rework, and converge multiple signals.
Norms for a Distributed Team
A template and guidance for distributed-team norms: who's where and in what timezone, core overlapping hours with etiquette, and a weekly meeting cadence where every meeting has an agenda and an outcome.
Promoting Engineers Fairly
Principles for fair, evidence-based engineer promotions: recognizing demonstrated capability across growth dimensions, corroborating it with peer signal, and avoiding tenure-only or surprise decisions.
Slicing a Wishlist Into an MVP
A practical method for cutting a full feature wishlist into Build Now, Future, and Backlog: keep the thinnest capability per area, ship cross-cutting platform basics, and defer polish.
Specification by Example and Living Documentation
Specification by Example helps you build the right product with just-enough living documentation. Derive scope from goals, keep specs maintainable, and lead with quality, not process labels.
Static vs Dynamic, Strong vs Weak Typing
Static versus dynamic is about when a type is associated; strong versus weak is about whether implicit conversions are allowed. They are independent axes, and confusing them causes endless arguments.
T-Shaped People vs Cross-Functional Teams
T-shaped describes an individual's mix of depth and breadth. Cross-functional describes a team that spans different kinds of work. Conflating the two leads to muddled staffing decisions.
The Case for Pair Programming
Pairing draws predictable objections about cost, autonomy, and skill matching. Here is the case against each, plus practical guidance on roles and when pairing is and is not worth it.
When (and Why) to Refactor
Refactoring means changing internal structure without changing observable behavior, in tiny steps. Here is when to do it, when to leave code alone, and why the case for it is economic.
Writing a Technical Estimate People Can Trust
How I write a technical estimate that holds up: stating assumptions explicitly, naming what moves the number up or down, surfacing risks with mitigations, and giving honest ranges instead of fake precision.
Product Mode vs. Consulting Mode
Consulting mode delivers what was scoped; product mode learns what to build next. Naming which one you're in is the difference between shipping on time and finding real users.
Why Small Stories Make Teams More Agile
Agility is the ability to change direction quickly and cheaply. Large stories make every pivot costly; small stories shrink the price of every option you might take.
What a Story Estimate Actually Represents
An estimate isn't a measure of hours. It bundles work, complexity, what you know, and what you don't, expressed relative to stories you've already sized.
Write Code for the Engineer Who Comes After You
Treat every commit as if a future engineer will have to make sense of it. That one act of empathy quietly drives most of what we call maintainability.
What It Means to Lead in Software
Technical leadership has little to do with authority. It's a blend of self-leadership, growing others, sound judgment, and a relentless bias toward delivery.
Adopting XP Practices: A Field Guide
A practical tour of Extreme Programming practices through a mindset-versus-mechanics lens, plus a rollout order that introduces the highest-leverage ones first.
Working Agreements Your Team Will Actually Use
A working agreement is a team-authored set of behavioral commitments that strengthens self-organization. Here's how to build one people actually honor.
A Six-Dimension Framework for Engineer Growth
Six dimensions and three proficiency levels give engineers and mentors a shared language for individualized growth, without reducing careers to a checklist.
Is It Actually Production-Ready?
A category-by-category rubric for judging whether an application is genuinely ready for production, covering monitoring, logging, security, testing, and recovery.
The Knowledge to Establish When You Join a Project
Joining a project is the highest-leverage moment to invest in understanding it. Three pillars of foundational knowledge set up both you and every future joiner for success.
SLOs and Error Budgets, Explained
Service level objectives and error budgets give reliability work a number to argue over. Here is how SLIs, SLOs, and budgets fit together and how to set targets that match what's at stake.
Right-Size Security by Data Sensitivity
Security effort should scale with the most sensitive data a system touches. Here is a tiered baseline of controls, when to add more, and the traps that quietly undermine all of it.
DORA Metrics and AI as an Amplifier
Recent DORA research frames AI as an amplifier of existing organizational health. Here is how the four delivery metrics still anchor everything and which capabilities decide whether AI helps.
Operating Production Is a Discipline, Not a Toolset
Good production operations come from durable practices, not from whichever incident tool you bought. Here is what stays constant, how to distribute ownership, and the traps that erode trust.
What AI Actually Is (and Isn't)
AI is just a way to get computers to accomplish tasks, but the term is muddied by hype. Here is a grounded look at what today's AI is, what LLMs really do, and when to reach for ML.
A Field Guide to AI Approaches and LLM Patterns
A quick-reference catalog of the major AI approaches and the modern LLM engineering patterns, with the typical use for each, so you can recognize the right tool when a problem shows up.
An AI Solution Decision Tree
A four-step framework for moving from a business goal to an AI architecture, covering goal, data, control, and best practices, with worked examples to show how the choices fit together.
Chatbot, Assistant, or Agent?
Chatbots, assistants, and agents differ mainly in how much autonomy you delegate. Here is how to tell them apart and how to pick the right one, with the guardrails each level demands.
MCP Explained: Why LLMs Need More Than an API
The Model Context Protocol bridges the gap between AI assistants and existing systems. Here is why a raw API isn't enough, how MCP is structured, and how it can double as a secure gateway.
What 'Training on Your Data' Really Means
Fears about training on your data often assume the model stores a retrievable copy. It doesn't. Here is what training actually does, which risks are real, and where output ownership stands.
Using AI Responsibly: The Environmental Footprint
Most of AI's carbon cost lives in training, not your daily usage. Here is how to think about the footprint honestly and a practical checklist for keeping everyday AI use efficient.