Published Work · Blog Posts
Shorter, sharper pieces published on Medium between 2014—2026 and migrated to Substack, plus a run of posts on DEV — test-driven development and mutation testing, refactoring and legacy code, delivery flow and batch size, hypermedia architecture, and what changes when the machine writes the implementation.
Written since the arrival of capable LLMs — what changes when implementation becomes a commodity, what doesn't, and why judgment gets more valuable rather than less.
March 13, 2026
The founding charter of the AI Craftspeople Guild. AI expands what a professional can produce and raises the burden of judgment at the same time — speed without discipline invites fragility, capability without responsibility invites harm.
March 10, 2026
When software can change itself, architecture has to govern how change is allowed to happen. Proposes a change architecture layer that constrains how AI-generated code evolves, holding off specification drift without giving up the speed.
February 8, 2026
Notes from the second AI Roundtable session, tracing a ten-year arc from the brittle chatbots of 2016 through ChatGPT to the agentic tooling of 2026 — what to expect from it, and what to steer clear of.
January 5, 2026
A response to the 'software industrial revolution' framing. Bolting a steam engine onto a sailing ship produced an awkward hybrid, not a steamship; borrowing the old paradigm wholesale is how we misread a genuinely new abundance.
December 28, 2025
With essentially all public digitized knowledge now assimilated and trillions being spent, the question shifts from whether AI is intelligent to who gets to use that knowledge — and why sitting passively on the sidelines is the losing move.
November 28, 2025
An extraordinary Viennese layer cake as an argument about composition: can anything genuinely bespoke be built without leaning on reusable commodities, or is 'AI-native' just a new arrangement of familiar layers?
September 27, 2025
Von Neumann asked why anyone would want more than machine code. Seventy years of profession-building later, code has gone from the scarce asset that justified the job to the liability that gets in the way of it.
July 23, 2025
Schrödinger said consciousness is a singular of which the plural is unknown. An excursion into what that 1958 claim means for how we think about individual minds — and, by extension, machine ones.
May 13, 2025
A verbatim meta-dialog with an AI about its own blind spot: it learned from finished repositories, so it has seen countless destinations and almost none of the journeys that produced them.
April 20, 2025
Applies the Permaculture by Succession model to AI-driven development. Every design is a throwaway design — the best one available given current knowledge — so the question is whether AI can be trusted to keep replacing its own.
March 13, 2025
The compiler was the first AI: it translated English-like statements into binary and programmers stopped checking its output. LLMs are the next rung on that same ladder, and the same trust question applies.
February 25, 2025
A confessed React sceptic builds a React course anyway, using a neural net as instructor — and finds the machine a better teacher than expected on tech he still doesn't much like.
February 19, 2025
If machines write the implementation, code design and maintainability stop being the developer's scarce skill. What remains scarce is the ability to state precisely what the code is supposed to do.
February 1, 2025
Implementation code is now a commodity; testing skill is not. LLMs are weak at formulating good expectations, which makes the most-avoided discipline in software suddenly the most valuable one.
November 21, 2024
Human intelligence is localized — trapped in one three-dimensional body. Machine intelligence is dimensionless, distributed, and decentralized, and we keep trying to reason about it using the only kind we know.
September 30, 2024
A short standing prediction: the industry shifts wholesale from boring 'concierge apps' to 'butler apps' that act on your behalf rather than waiting for you to operate them.
September 28, 2024
Telephone operators once made every call expensive; automation collapsed that cost to nothing. Software implementation is entering the same curve, and pricing built on scarce implementation labour goes with it.
August 24, 2023
If AGI emerges and genuinely surpasses us, we would not be able to detect it — a dog cannot assess its owner's intelligence. Which makes most AGI scenario-spinning a waste of breath.
The practice at the centre of everything else: writing the expectation first, keeping feedback fast, and finding out whether a green suite means anything at all.
March 25, 2025
Lambda functions are awkward to test well. Walks through mocking them declaratively rather than imperatively, so the tests state what is expected instead of scripting how the mock behaves.
October 16, 2024
Software developers inherited a mystical aura and got cocky with it. Manual verification is a choice to burn an employer's money on chores a machine would do for free.
October 3, 2024
Teams that adopt TDD often carve out an exception for prototypes. TDD is not a quality ritual you can skip when quality doesn't matter — it is the faster way to build, which is exactly what a prototype needs.
September 27, 2024
Function first, form second. Establish the expectation as an executable test, and the shape of the implementation follows from it — reverse the order and you get premature optimization.
September 23, 2024
The system clock and the database are inputs your design pretends aren't there. Anything fetched from ambient infrastructure is a hidden input, and hidden inputs are what make behaviour impossible to pin down in a test.
February 29, 2024
A short note on test design: objects carry identity, values don't. That impartiality is what makes values the better abstraction to assert against.
March 17, 2023
Ports the cat-door mutation testing example from C# to JavaScript and Node, showing how to add mutation testing to a project whose team already thinks its TDD practice is in good shape.
March 16, 2023
Why 'monolith' and 'testable' pull against each other, worked through a border-crossing and emergency-ward example where nothing can be exercised without dragging in everything else.
November 23, 2022
Programming began with manual rewiring and punched cards, where the only way to know anything was to run it. Argues the profession never actually left that feedback-first model — it just forgot it was in one.
October 29, 2022
In a world where everything runs on code, code must be maintained forever. Tests containing imperative logic are code that needs its own tests — delete them and state expectations declaratively instead.
September 28, 2022
An in-depth guide to leaner code through failing fast, using iteration against a measurable test — the same technique that finds a square root by refining wrong guesses.
September 27, 2022
TDD modelled on natural selection: spontaneous variation plus a selection pressure produces a working solution without anyone designing it up front. Worked hands-on, one refinement at a time.
September 27, 2022
Value isn't an entity, it's a flow — which is why it's called a value stream. Since nobody volunteers feedback, failure is the mechanism that solicits it, and DevOps culture depends on welcoming it.
August 19, 2022
A career retrospective from FORTRAN onward, and an account of why hand-cranking code — however skilled you get at it — is worse than letting tests drive the work.
March 11, 2022
Code-as-text means the machine stays silent while you change it, so damage is done before you learn of it. Slow tests barely shorten that lag; only very fast tests close it.
February 25, 2022
The hard part of adopting TDD isn't the tooling, it's abandoning large batches. The smallest possible batch is a single expectation — start there and the rest of the practice follows.
February 23, 2022
The epiphany that changes how you write code: create the consumer that is ready to use the code before the code exists. A test is exactly that consumer, arriving first.
February 23, 2022
Separates exploratory testing, which deliberately disrupts the status quo, from automated testing, which underwrites continuous delivery — and shows why only the deterministic kind can gate a pipeline.
February 10, 2022
A short index post pointing to the five-part Opensource.com mutation testing series, in reading order.
Getting code to work is the easy part. These are about the other ninety percent — keeping a system soft enough that the next change is still affordable.
April 17, 2025
Getting something to work is the easy part; keeping it maintainable is the job. Estimates that upwards of 90% of quality software work is refactoring, and that every best practice exists to make refactoring cheaper.
June 13, 2024
Isolate the code that changes often from the code that rarely does. Skip that and coupling hardens the system until software stops being soft.
June 8, 2024
Deadlines are manufactured urgency, a symptom of management not trusting the team to deliver. A team on genuine continuous delivery ships several times a day, and the concept of a deadline simply evaporates.
June 5, 2023
Behaviour and structure are inseparable, but only behaviour is visible to the business — which is why structure gets starved. Caring less about specific details is what lets a system keep evolving.
June 2, 2023
A Twitter argument worked out properly: a brittle system is easy to break and hard to restore. Natural systems break easily too but recover — the difference is coupling, and coupling is bought with ambiguity.
February 16, 2022
Thirty-one years of modifying legacy code distilled into a habit: skim rather than fully comprehend, find the relevant region, then extract methods to make it safe to touch.
On batch size, unfinished work, estimates, and the difference between emptying your plate and being done.
August 8, 2026
Why change software in an environment where the change isn't running? Darklang showed a third way — touch production code and it becomes a draft, flip the flag and it publishes — which is where Draft Flag Driven Development came from.
April 7, 2026
Kent Beck's line that a plan going perfectly means nothing was learned. Competing only on already-proven practice hands your competition the same tools and leaves you racing to the bottom on price.
December 11, 2024
After 23 years, Agile is being loudly declared dead. Argues the backlash comes from people who never wanted to work with other people, for whom Agile never stood a chance.
October 25, 2024
A point-by-point reply to a thoughtful objection: forgotten branches, duplicates, and completed spikes are not exceptions to the rule, because finished work belongs shipped, not shelved.
October 23, 2024
Every branch is unfinished work, and most branches on most teams are stale — sometimes by a year. Never start an item you cannot carry to delivery without interruption.
September 23, 2024
Rewatching his own Agile talk a year on, and finding that the feedback it drew was overwhelmingly emotional. Something about the word touches a raw nerve well beyond the practices it names.
September 14, 2024
The recurring challenges of running and growing an operation, starting with the one nobody can answer honestly: how long is this change going to take?
April 25, 2024
Two organizational models: the chastity-belt shop in maintenance mode where every change reads as a threat to stability, and the promiscuous one that invites change in.
June 8, 2023
A reply to 'enough theory, show us the goods'. Rejects the silo it assumes — thinkers over here, doers over there — and the idea that a system ever arrives at a finished state.
May 19, 2023
We use logic to predict the future and mistake inference for knowledge. Where documentation-driven work assumes the prediction holds, feedback-driven work goes and checks.
March 24, 2023
Software is like furniture — move it around enough and something breaks. DFDD keeps code where it already runs, hiding work behind a draft flag until it is genuinely ready to publish.
February 28, 2023
Agility comes down to two factors: dependencies and options. Illustrated by a home baking business that prints flyers, waits for orders, and learns what a dependency actually costs.
January 19, 2023
A board and sticky notes are easy; knowing what to put on them is the hard part. POPCORN Flow tracks the problems, options, and experiments rather than just the tickets.
January 13, 2023
Walk east and no amount of speed or stamina gets you to a beach that lies west. The first step sets the direction, which makes it worth more scrutiny than everything that follows.
November 8, 2022
The fixed-price standoff from both sides: the buyer fears an open-ended cash cow, the crew knows the estimate is fiction. Examines whether estimation is answering the question anyone actually has.
April 28, 2022
Roadmaps assume predictable terrain and hazard-free travel. In a VUCA world a sea chart is the honest instrument — it shows the hazards and leaves the route to the navigator.
March 16, 2022
Customers pay for functionality, so everything else is non-functional — except availability, performance, and security clearly affect every customer. Works out where the line actually falls.
March 9, 2022
The cliché is used to shut down enthusiasm. Examined properly — via a weight-loss analogy — it says something more useful about what can and cannot be bought with a single change.
March 2, 2022
Lessons from being CTO of a dotcom that ran out of funding in April 2001. Clearing the plate is not the same as finishing, and mistaking one for the other is how departments burn through runway.
March 1, 2022
Building a feature without a hypothesis is shooting in the dark. An MVP is not a small product, it is an experiment — and market leaders have largely stopped running projects at all.
February 15, 2022
People routinely use the two words interchangeably. A visual walk-through of why iterating and incrementing are genuinely different processes with different failure modes.
REST, hypermedia, hexagonal architecture, and a running argument that the web already solved problems we keep re-solving badly.
July 30, 2024
Prompted by FastHTML, a defence of hypermedia against the reflex to paper over it. HTML is the most widespread hypermedia implementation there is, and the industry keeps treating it as something to hide.
June 15, 2024
For an idea to get from your head into the computer it must pass through someone else's hands. On modelling as the real work of programming, and the keyboard as the least interesting part of it.
May 31, 2024
Rich client-side logic is what users now expect, but the browser remains an untrusted computing environment. Every increment of front-end expressiveness buys a security headache.
May 31, 2024
A throwaway post about abstract thinking drew 116,000 views and a fight. Digs into why the word 'abstract' provokes so much heat among people who spend all day doing it.
November 25, 2023
HATEOAS explained: hypertext carries content that implies action, and action implies a state change. Late binding is the payoff — clients stop needing advance knowledge of server structure.
January 12, 2023
REST without the jargon, built up from the idea of a protocol as formal communication, for readers who need to understand the model rather than implement it.
August 16, 2022
Computing infrastructure is a commodity now, but old habits treat it as an achievement. Moving complexity out of the program and into the logistics doesn't reduce it — it just hides it.
September 4, 2021
Alistair Cockburn's pizza parlour, worked through: two windows, one facing customers and one facing the kitchen, and the parlour doesn't care who is standing at either.
September 6, 2017
Shared mutable state is universally condemned; mutable components get a pass they haven't earned. Objects, services, and actors all hold state, and all benefit from being cattle rather than pets.
April 11, 2017
The web arrived late because perfectionism stalled it, and won because it was good enough. Reads REST as bureaucratic machinery — forms, standard responses, and no memory of you between visits.
June 17, 2015
Two modes of writing code, usually chosen unconsciously: starting from a metaphysical premise about how the world is, or starting from what can actually be observed and tested.
April 1, 2014
Procedural code asks then decides; object-oriented code tells objects to act. But where does the telling code get the information guiding it? An examination of why imperative programming is the naive model.
Teams, heroes, mob programming, and the parts of the job that have nothing to do with code.
October 25, 2025
The people who shaped his thinking, starting with getting booed off his own stage by engineers shouting about Kent Beck and some crazy new fad called Extreme Programming.
August 15, 2025
An hour with Paul Hammond on what quality software actually requires — Extreme Programming, TDD, the particular difficulty of front-end TDD, and feedback-driven development.
August 1, 2025
Giraffes did not stretch their necks. Dawkins' Climbing Mount Improbable applied to software: the counterintuitive, undirected process is the one that reliably produces good design.
November 22, 2024
A man drives to the motor vehicle branch, pays for parking, waits 45 minutes, and tells the teller he has nothing to report. A parable about the systems developers design without noticing.
November 12, 2024
Nobody takes a software job expecting to work alone, and no non-trivial system survives a solo maintainer. So why does everyone start hiding their work the moment they join the team?
October 14, 2024
A podcast leads to an introduction, which leads to a CTO interview, which reveals exactly how much appetite a self-described progressive fintech has for technical excellence.
June 27, 2024
Surround yourself with smarter people, the advice goes. But collective IQ falls as the group grows, which makes the whole premise harder to act on than it sounds.
June 15, 2024
From numerical ecology research to software, chasing less regimented ground. The lesson that stuck: people hate being convinced, so persuasion is a bad business to be in.
June 13, 2024
An $87 price tag that rings up over $100. On the economy of lies, how little white lies compound into audacious ones, and what comes after the sharing economy.
June 7, 2024
A short personal introduction — what he's about, professionally and otherwise.
March 12, 2024
On belonging to no organization and no ideology — a man of no rank — and the freedom that comes from reserving the right not to adopt a view at all.
August 26, 2023
Announcing a book. After years in the field, an attempt to set down a more compassionate and approachable way to do software development than the one the profession keeps defaulting to.
May 12, 2023
Teams should work one user story at a time. Quality requires shared information, sharing requires collaboration, and the best collaboration is real-time and face to face.
February 10, 2023
Woody Zuill on the origins of mob programming, including the 1998 team that called itself a team while doing nothing that resembled teamwork — and the fifteen years spent fixing that.
January 29, 2023
Most mid-size and large organizations run on a shadow estate of linked spreadsheets and Access apps, built by people who gave up waiting on the Ivory Tower. Fix those before the ambitious project.
September 1, 2017
Software professionals are phenomenally good at producing bloat. The root cause is treating code as a lovingly crafted precious snowflake, which is also what justifies its price.
May 12, 2017
Life is one long improvisation — we make the map and follow it at the same time. Which of trial-and-error and careful planning actually suits building software.
An earlier arc, from 2014 to 2017, on interfaces, bots, and the argument that self-serve was a bad deal we agreed to without noticing.
August 29, 2017
Canned software commoditized the common cases and left customization stranded. Argues software has to stop being a product you buy and become a relationship you maintain.
July 25, 2017
Mainstream society used to be the bottleneck on adopting innovation, for economic, cultural, and plain inertial reasons. That bottleneck is moving, and the patterns around it are worth watching.
June 29, 2017
Slides from the Apps World Evolution talk in London, arguing the self-serve era gives way to digital experts acting on the user's behalf.
December 8, 2016
From rewiring to punched cards to text, because language is how humans actually communicate. A defence of the textual interface against the graphical one that displaced it.
July 12, 2016
Twenty-six years with a utility company and essentially zero interactions — no user experience whatsoever, and an outstanding service. Sometimes the best interface is one you never have to use.
April 9, 2016
Automation retired the operators, the agents, and the tellers, then quietly handed their work to us. Self-serve was sold as liberation and delivered a second job; bots are how that work gets taken back.
March 2, 2016
Punched cards to terminals to the desktop metaphor — and the GUI ending up as arcane as the syntax it replaced. Text was always the intuitive part; the graphics were training wheels.
Written through late 2020, alongside the WorkSafeBC Technical Blog run — complexity, simulation, the real economics of reading code, and how to tell from a repo whether it was genuinely built test-first.
December 31, 2020
From Smalltalk and Forth to COBOL in 1990, when the prevailing sentiment held that real pros write code on paper and only dilettantes check whether it works. Forty years later the sentiment is inverted: the engineers worth following make micro changes and run everything immediately, because the trick is to never let the code not be working.
December 16, 2020
Three kinds of complexity, only one of which is anyone's fault. Essential complexity belongs to the domain and cannot be whittled down — if a claim takes fifteen policy steps it takes fifteen steps — and it is the reason the job exists at all. Accidental and incidental are the ones we inflict on ourselves.
December 9, 2020
Every other engineering discipline runs on simulation: cars, aircraft, drugs, spacecraft, pandemic models. Software is alone in raising eyebrows at the suggestion that a solution be simulated before it is built, which is a Stone Age habit dressed up as pragmatism.
December 6, 2020
A test is the first customer of a service that does not exist yet, and the only way that customer can state an expectation is to fabricate the value. Kent Beck's fake-it step explained as a customer-first move rather than a beginner's shortcut.
December 5, 2020
A question from a TDD Dojo: can you tell from the repo? Code-first work has a smell — tests coupled to the structure of the shipping code, larger tests, almost no microtests, and a noticeably higher share of surviving mutants.
November 7, 2020
The Lump of Coding Fallacy: everyone assumes developers spend the day writing code, and almost none of them do. The hours go to scanning opaque code and geek-at-keyboard activity, which is where the cost is actually hiding.
October 30, 2020
Uncertainty, ambiguity, incompleteness, and confusion — underwritten by Heisenberg, Wittgenstein, Gödel, and the second law of thermodynamics. Maps an inverted pyramid of uncertainty running from mathematical certainty up to the genuinely unknowable.
October 29, 2020
Whether a comment is an asset depends on which philosophy you hold. XP teams read one as a reminder that the code is not finished; zero-tolerance-for-rework teams treat stopping to improve already-written code as a detour off the trajectory.
October 3, 2020
A project where severity-one production bugs drew a shrug and a polite request to try again. The tacit unlimited-retries clause — extended even to re-entrant bugs — is what lets accountability evaporate entirely.
The full archives, including posts not listed here, live on my Substack archive and my DEV profile.
The writing is the cheapest way to pressure-test how I think before putting anything on a calendar.
Book a Diagnostic →