Making Technical Decisions When There Is No Perfect Answer
Every option is wrong in a different way and the team is waiting. A way to decide, record the reasoning, and stay able to change your mind later.
Read articleLead Software Engineer
I build software end to end - the interface, the services behind it, and the cloud it runs on - and I lead the teams that ship it. My focus is speed that survives contact with production: accelerated by AI wherever it removes friction, and held to a standard wherever it counts.
Interfaces, APIs, services, infrastructure, pipelines and the monitoring around all of it. Whatever the problem needs, that is the part I go and learn well enough to own.
Front to back and out to the edge - component architecture, API design, data flow, cloud infrastructure. The boundaries between those layers are where most bugs live, so I make a point of not treating any of them as somebody else’s problem.
AI-assisted development removes the mechanical work - scaffolding, boilerplate, refactors, first-draft tests - and that time goes straight back into design and review. A shorter path from idea to production, without a longer list of things to fix later.
Cutting scope into work people can genuinely own. Holding a review standard without becoming the bottleneck. Making sure the newest engineer in the room understands why, not just what to type.
Designing for the traffic you will actually get - caching layers, query cost, pagination, queues and graceful degradation - then proving it with structured events, performance budgets and alerts that fire on real failures instead of noise.
AI has genuinely changed how quickly software can be built - but only for people who already knew what good looked like. I use it hard on the mechanical half of the job and not at all on the half that requires judgment. That combination is what makes short timelines survivable.
Scaffolding, boilerplate, repetitive refactors, first-pass tests, migration scripts, documentation drafts, unfamiliar syntax. Hours of typing compressed into minutes.
Architecture, trade-offs, security, data modelling, performance, and every line that reaches production. Generated code is a proposal - reviewing it is still the job.
I am not precious about typing every line by hand. I am extremely precious about understanding every line that ships. Pick one to see where it actually sits in my day.
The one I reach for when the question spans a whole repository rather than a single file. Multi-file refactors, architecture reviews, and the second opinion that catches what I stopped seeing three hours ago.
Used daily · reviewed line by line before anything is merged
Breadth rather than depth. Unfamiliar APIs, a rough idea turned into a concrete plan, and throwaway prototypes that answer a question in ten minutes instead of a day.
Used daily · treated as a starting point, never a specification
A different model reading the same problem. When an answer matters and I do not want to trust the first thing I hear, a second opinion from a different family of models is genuinely useful.
Used for verification · disagreement between models is a signal worth chasing
The lowest-friction layer. Inline completion where the intent is already obvious from context, and repo-aware edits across several files without ever leaving the editor.
Always on · accepted only when I would have written the same thing
Open models running on my own machine, for anything that is not allowed to leave it. No request limits, no network dependency, and nothing leaving the laptop.
I wrote a full setup guide — see the Ollama article
Not one of these decides architecture, approves a security choice, or merges its own work. They generate; I decide, verify and stay accountable. That line is the entire reason speed does not turn into rework.
The tools changed the pace. They did not change who is responsible.
Using AI to build faster is one thing. Building software that has intelligence inside it is a separate discipline - and most of it turns out to be ordinary engineering problems wearing a new hat. Latency, failure modes, cost, trust.
Token-by-token rendering, cancellation and partial state - plus the undo, retry and edit paths that let someone correct an answer rather than abandon it.
Chunking, embeddings, ranking - and the citation UI that lets someone verify an answer instead of being asked to trust it.
Input validation, enforced output shapes, moderation, and a defined path for the moment the model returns something useless. It will.
Queueing, concurrency limits, backpressure and graceful degradation, so a spike in traffic slows the feature down instead of taking the product with it.
Caching, model routing, prompt-size discipline, and knowing what a single request actually costs before ten thousand users make it.
Test cases, regression checks and a way to tell whether a prompt change genuinely improved things or simply changed them.
A demo needs a good prompt. A product needs error states, rate limits, observability, a cost model and a way to roll back. The second list is the one I am useful for.
Regulated hiring, health insurance, multi-tenant healthcare SaaS, consumer well-being. These are the ones I have gone deep in, not the full list. The subject matter is context I pick up; the engineering underneath is what I actually bring.
A hiring platform for Australia’s care sector, where nobody starts work until their clearances check out.
02 InsurancePrimary care, dental and vision cover sold to individuals, companies and their employees — with the commercial machinery behind it.
03 Healthcare SaaSA multi-tenant SaaS platform running yearly membership programs for hospital chains. Live in production, with more than ten clients.
04 Consumer healthA personalised platform helping people build healthier habits across six dimensions of well-being.
Format, validate, repair, diff and convert - a hundred and eighty developer tools that run entirely inside the browser tab. Nothing you paste is uploaded, logged or stored.
Not a fixed menu - just the requests that come up most often. If yours looks different, that is usually the more interesting conversation.
A product that does not exist yet. I set the architecture, the delivery pipeline and the conventions early - and size the data model and infrastructure for the scale you are aiming at, so the second year is not spent undoing the first.
02A working system that has become slow, fragile or frightening to change, usually because it outgrew the shape it was built in. I find the real bottleneck and make it fast and safe to change again, without a rewrite nobody can afford.
03Owning scope, architecture, review standards and release readiness for a team - and being the person who resolves the ambiguity before it turns into three weeks of rework.
04Reviewing an architecture, auditing a codebase, setting up observability, or working with engineers who want to get better faster than trial and error allows.
Instead of a wall of logos, the stack is a searchable console: filter by category, type to narrow it down, and see what each tool actually does in practice rather than that I have heard of it.
Long-form notes on the things that actually cost teams time - technical debt, observability, authentication, URL design and search. Written for engineers, not for a keyword.
Every option is wrong in a different way and the team is waiting. A way to decide, record the reasoning, and stay able to change your mind later.
Read articleProduction is broken and the sprint is half done. How to triage, who to pull in, what to tell the client, and how to protect the rest of the team.
Read articleThe deploy failed, the vendor feed is late, the estimate moved. How to explain a technical problem so a client stays confident rather than alarmed.
Read articleHanding over work without hovering, and without discovering three days later that it went somewhere you never intended. What to specify and what to leave open.
Read articleRolling AI tooling out across a team is a standards problem, not a licensing one. What to agree on before everyone starts generating code.
Read articleDropped into two hundred thousand lines you did not write. How to use AI to build an accurate mental model fast, and where it will confidently mislead you.
Read articleTenant isolation, shared schemas, per-client configuration and the blast radius of a bad deploy. The decisions you cannot cheaply reverse later.
Read articleCold starts, timeouts, concurrency and payload limits, explained as the things that actually show up in your interface rather than as cloud trivia.
Read articleYou do not need to be a cloud engineer, but you do need to know where your request goes. The AWS surface a senior frontend engineer is expected to reason about.
Read articleFeature one hundred is where most React codebases stop being fun. The habits that keep a large application changeable rather than merely working.
Read articleA practical path through a production incident across the browser, API Gateway, Lambda, AppSync and the services behind them, in the order that narrows it down.
Read articleModule boundaries, permissions, API layers and shared components: the structural decisions that decide whether year three of a codebase is pleasant or painful.
Read articleA concrete workflow for Claude, ChatGPT and coding assistants: what to hand over, what to never hand over, and how review keeps speed from becoming rework.
Read articleNobody hands you a manual. What genuinely changes about planning, delegation, decisions and code review the week you start leading a team.
Read articleThe bug reproduces for one user, on one day, and never on your machine. A methodical way to corner intermittent failures instead of guessing at them.
Read articleOne codebase, many brands. How tenant resolution, theming, custom domains and configuration fit together without forking the product per client.
Read articleSearch stopped being a list of links and became a single answer. Here is how content earns its place inside that answer.
Read articleWhether it is an architecture you want a second opinion on, a codebase that has stopped being fun to work in, or a role you think fits - I read every message myself.