GA has to be earned
Written August 2026
From building a multi-tenant business platform single-handed — one of four notes on what the work actually taught.
Every feature list I have ever written was a claim about the future. The module existed, the tests were green, the screens rendered — and none of that answered the only question a person actually has, which is whether the thing works when a real person does the real task in the environment it is deployed to.
So I built a registry that labels every surface of the platform, and I inverted the default. alpha means known not to work end to end. beta means complete and plausible but not proven against reality — and it is what an unregistered surface resolves to, so forgetting to label something does not quietly grant it a promotion. ga means proven, and it requires an evidence string naming what proves it.
The consequence took four months to arrive: the first surface reached ga four months after the label existed. Not because the code was bad — because nothing had yet been run anywhere but on a laptop.
What earned the first one was a place, not a test
The process test for that surface had been driving the whole flow on every pull request for days. The sentence standing between it and ga was that no run had ever happened anywhere but a local stack. When it finally ran against the deployed environment — one run, no retry, nothing skipped, every row read back through a privileged client — that was the whole difference.
A test that exists is not a run that happened.
The promotion is written by a tool rather than by hand, and the tool refuses. No process test: refused. A run whose claims came from reading the test file rather than from the run itself: refused. An uncommitted working tree, a local target, zero tests, anything skipped or retried: refused. It has produced more refusals than promotions, and that ratio is the instrument working, not failing.
The refusal I keep
One surface was run three times and went pass, fail, pass. The entire reason the tool retries nothing is that the second attempt does not get to erase the first. The cause turned out to be a click landing in the gap between a page reload resolving and the framework attaching its handlers: the click reached the DOM and not the component, so the screen never changed and the assertion below waited twenty seconds for a number that was never going to move.
I fixed it by asserting the button's own pressed state first, which turns "did the click take" into a question with an answer instead of something inferred from the figure that depends on it. Seven clean runs followed, and it was still refused — a run that needed repeating to come out clean is not evidence, and promoting it anyway would make the label mean nothing the next time I looked at it.
That surface is ga now, and how it got there is the more useful half. It was not promoted by relaxing anything. It was promoted once I noticed the tool had been asking it the wrong question: the bar was a template written for a module that writes records, and this one computes from records it did not create. A dashboard was being refused for failing a test about writes it does not perform, and the tool never once named the bar it was applying.
So there are now two kinds of proof, and the second is not the easier one. A process that writes a row and reads it back cannot easily agree with itself by accident; a figure compared against a database can, because both sides may be computed from the same mistake and the comparison then passes for ever. That kind therefore has to include a negative control — an assertion run against a value known to be wrong, which must fail — and the other does not.
A refusal can mean two different things, and it is worth being able to tell them apart. One is the instrument holding its line against a result I wanted. The other is the instrument being wrong. The first costs a day. The second is invisible until somebody asks why a whole class of surface never passes, which is why it went unfixed for months.
Most of the platform still sits at beta. I could move those numbers in an afternoon by relabelling. The reason not to is that the registry is the only thing standing between me and my own optimism, and its value is exactly its willingness to say no.