Twenty years, from infrastructure to the screen
The measure of invisible work is that it is judged only when it fails. I learned that for twenty years, then moved to the visible side.
Careers look tidy in hindsight. They are not tidy while lived: each period begins with a problem the previous one could not solve.
This piece is about four periods. But it is not a CV — it is about which habit proved useful in the next layer, and which one had to be dropped.
2005–2013 — Enterprise infrastructure
Servers, storage, backup, uptime.
If this period taught one thing it is this: a working system is invisible for as long as it works. Backups do not enter anyone's agenda for years. Then one day they are needed, and that day is the exam for everything done up to it.
The professional consequence is strange. Well-executed infrastructure work does not produce praise, only silence. Praise arrives only when something fails and recovery is fast — which means your most visible moment is your worst day.
The habit that carried over: write the recovery scenario before the setup. The first question when building a system is not "how will it work" but "how do we get back when it breaks". A backup existing is not enough; the restore has to have been rehearsed. An untested backup is not a backup.
2013–2019 — Networks and security
Routing, firewalls, access.
Network work teaches you to see a system as a topology. Not individual boxes but the relationships between them. Where a packet travels, which rule stops it, why one path is preferred over another.
The most lasting lesson of this period is not about security but about visibility: the precondition for solving a problem is being able to see it. Most network faults are not mysterious; they are simply unmeasured. Put a counter at the right point and the mystery dissolves.
The second lesson is about defaults. Firewall rules accumulate over time; each was needed once, none was ever removed. Five years later nobody can explain the whole list. A team that does not write down why a rule exists can never delete it.
That is why the code comments I write today explain "why it is this way", not "what it does". What it does is already in the code.
2019–2024 — Identity and M365
Active Directory, migrations, cloud identity. Order at the scale of thousands of accounts.
Identity work is a lesson in scale. Ten accounts you can manage by hand. At thousands of accounts, everything done by hand turns into inconsistency sooner or later — because manual work is not repeatable.
The habit that carried over: an exception is not a solution, it is a debt. A special rule opened for one user stays in the system long after that user has left. At scale the right answer is not to record the exception but to rewrite the rule so the exception becomes unnecessary.
Migration projects add their own lesson: a migration without a rollback plan is not a migration, it is a bet. And the rollback plan has to be rehearsed before the migration, not after.
2024 — today
AI-powered web applications and web technologies. Models and agents, turned toward the screen with the same discipline.
The transition here is less sharp than it looks. A modern web application is distributed-systems problems in miniature: state management, consistency, error recovery, observability. The names change, the questions stay.
The AI layer, meanwhile, rewards infrastructure habits in an unexpected way. A language model is an uncertain component: it can return different output for the same input, it can be silently wrong, and it fails without producing an error message. That is exactly the class of fault worked on for years — only the layer changed.
So the questions I ask when writing an agent are the same as when building a server: Where am I measuring? How will I know it answered wrongly? How far back can I roll when it breaks?
The difference sharpens at one point. When a server breaks, it tells you: the service drops, monitoring alerts, a line lands in a log file. When a language model breaks, it produces a fluent sentence. The failure is silent, and worse, persuasive.
The practical consequence is that classic monitoring is not enough. For a server, "is it up" suffices; for a model you have to ask "is it right" separately, and that question does not answer itself. Binding the output to verifiable ground — a source, a computation, a measurement — has to be part of the architecture.
Twenty years of habit fits exactly here: trust the basis of the output, not the output.
What carried over
The common ground of four periods is four habits:
| Habit | Where it came from |
|---|---|
| Design recovery before setup | The backup years |
| You cannot fix what you cannot measure | The network years |
| An exception is a debt | The identity and scale years |
| Write the reason for a decision, or it cannot be undone | Firewall rule lists |
All four still do the same job today. This site's verification suite — the test set that refuses to look at screenshots and reads luma off the canvas instead — is a direct product of the second. The decision records in the repository are the fourth.
The shared thread: an error budget
There is one concept repeating across all four periods, even if its name changes each time.
In infrastructure it was called the "uptime target". There is no such thing as one hundred percent availability; what exists is stating in advance how much downtime you accept. A team that does not state it re-runs the same argument at every outage.
In networking it was "acceptable latency". In security, "accepted risk". In identity management, "which exceptions are approved". On the product side, "performance budget".
They are all the same thing: writing down a limit in advance. When no limit is written, every decision turns into a negotiation, and negotiations are usually won by whoever is loudest at that moment.
The writing section of this site has a written budget too: largest contentful paint under 2.5 seconds, page script under 60 KB, no opacity gate in front of the text. All three are measured by the verification suite on every run. Exceed the number and the test turns red — no discussion opens.
That may be the most practical lesson of twenty years: good intentions are not a control mechanism. A limit is either measured or it does not exist.
What was left behind
There are things that did not carry over, and dropping them was harder than carrying.
The expectation of flawless operation. In infrastructure the target is zero downtime. On the product side a zero-defect target results in never shipping anything. The new criterion became not "does it never break" but "what happens when it breaks".
Resistance to change. In the server room the safest move is not to move; touching a working system is risk. On the product side the opposite holds: what is not touched goes stale. The same caution must be applied in a different direction — not to prevent the move, but to make it reversible.
Treating invisibility as a virtue. For twenty years good work was work that went unnoticed. That criterion was correct in its own domain but does not generalise. Where there is a field in which the work is supposed to be visible, silence there is not virtue but absence.
This site is the record of that difference. For twenty years I built systems nobody sees; now I am building the surface — and learning that the surface has to be measurable too.
Why the transition looks easy and is not
Most people moving from infrastructure to product fall into the same trap: assuming technical competence is transferable. It is — but on its own it is not enough.
What is missing is not technical. In infrastructure "correct" is usually singular: a configuration either works or it does not, a backup either restores or it does not. On the product side correct is plural and depends on context. Whether an interface decision is "right" changes according to who it is for and what it is meant to achieve.
For an engineering habit that is an uncomfortable state. The certainty you are used to is gone. What replaces it is measurement: where the truth is not singular, measuring what each option produces is the only honest path left.
The second gap: invisible work has no audience, visible work does. For twenty years the counterpart of the work was a system. Now the counterpart is a person, and that person's patience, attention and context vary. This is not a problem to solve but a reality to account for.
A note
Each of the periods above contains concrete events that could be told one by one: a particular migration, a particular night of failure, a particular architectural decision. This piece does not contain them.
The reason is simple: this text is about disciplines, not cases. Cases deserve to be their own pieces, and each should arrive with its own measurement — like the other writing in this section.
There is a risk in generalising and I am aware of it: reducing twenty years to four items flattens the real decisions inside those years. Explaining where a habit came from is not the same as explaining how you earned it. The second takes longer and demands more concrete examples.
Still, this list has a function: it sets the ground on which you read the next piece. Why a writing section this bound to measurement was built this way can be explained by these four habits. The rest is in the cases.