DEV Community

RAXXO Studios
RAXXO Studios

Posted on Originally published at raxxo.shop

The Kill Switch Every RAXXO Tool Ships With

  • Every RAXXO tool ships with a kill switch that can turn off one feature or the whole tool in under a minute, no redeploy required

  • I built the first one the night Git Dojo's parser choked on a git log format I had never tested against

  • The switch lives in three places at once, a flag, a status note, and a fallback UI state, so a user never lands on a blank screen

  • It costs a few lines of code per feature and it has saved a live tool exactly twice, both times inside minutes instead of hours

The Night Git Dojo Broke And I Couldn't Turn It Off

Git Dojo teaches git from the terminal, and one of its exercises parses real output from git log so a learner can practice reading history the way it actually looks, not a sanitized textbook version. I tested it against every git log format I could think of. I had not tested it against a repo with a commit message containing a stray unicode character that broke my parser mid-line.

The bug did not crash the tool. It did something worse. It rendered a half-parsed mess on screen and left the learner stuck on an exercise that looked broken, with no error message telling them why. I found out because someone tried the exercise, hit the mess, and quietly closed the tab. I only know that because the analytics showed a session ending on that exact screen, over and over, for two days before I noticed the pattern.

Two days. That is the number that stuck with me. Not because the bug was catastrophic, it affected one exercise in one tool, but because the only way I had to stop it was to write a fix, test the fix, and push a new build. Every minute between "I found the bug" and "the fix is live" was a minute where the broken state was the only state a learner could reach.

I did not need a fix that night. I needed an off switch. Something that could turn the broken exercise into "this one is temporarily unavailable, try the next one" in the time it takes to edit one line and refresh a page, not the time it takes to write, test, and ship code under pressure.

That is the whole origin of the habit. It was not a lesson from a framework or a talk I watched. It was a two-day gap between symptom and fix that I decided was never going to happen again, in any tool, for any feature.

What The Switch Actually Looks Like

The pattern is deliberately boring. Every feature that touches an external input, parses something unpredictable, or calls out to another system gets a named flag that controls whether it runs at all. Flip the flag, the feature stops running. No code change, no build step, no waiting on anything downstream.

The flag alone is not enough, though. A flag that just makes a feature disappear creates a different bad experience, a button that used to work now does nothing and nobody knows why. So every switch ships with two companions.

The first is a fallback UI state, written and tested before the feature ever ships, not improvised during an incident. If the git log parser exercise in Git Dojo goes dark, the learner sees a plain message pointing them to a different exercise, not a blank panel or a spinner that never resolves. Writing that fallback state costs maybe ten minutes per feature. Writing it during an actual incident, half-focused and rushed, would take longer and probably look worse.

The second is a short, visible status note, one sentence, plain language, placed somewhere a user checking on a tool would actually see it. Not a support ticket queue. Not an email I have to send. A note that says what is off and, when I know it, when it is coming back.

Three pieces, one flag, one fallback, one note, and all three exist before the feature launches, not after something goes wrong. That ordering is the entire point. A kill switch designed during a crisis is a worse kill switch than one designed on a calm afternoon with no pressure on it.

The Rule: Every New Feature Gets A Switch Before It Ships

After Git Dojo, I made this a rule for every RAXXO tool, not just the one that broke. Before a feature that touches unpredictable input goes live, in Git Dojo, OhNine, Statusline Builder, or anywhere else, it needs its switch, its fallback state, and its status note. If those three things are not ready, the feature is not ready, regardless of how well the happy path works.

This is a small tax on every release. Writing a fallback state and a status note takes real minutes on a feature that might never need either. Most weeks, most switches sit there unused, flags nobody flips, notes nobody reads. That is fine. The cost of an unused switch is a few minutes once. The cost of no switch, on the one feature that does break, was two days of a broken exercise nobody could turn off.

I also treat the naming of each flag as part of the discipline, not an afterthought. A flag called something vague tells me nothing six months later when I am staring at a list of switches trying to remember what each one guards. Every flag name says exactly which feature it controls and, where it matters, which tool it belongs to. It sounds like a small thing until the list of switches across five tools gets long enough that vague names turn into a guessing game at the worst possible moment, mid-incident, trying to remember which flag actually stops the thing that is currently broken.

I do not apply this to everything. A static page with no external input, no parsing, no network call, does not need a kill switch, because there is nothing about it that can fail in an unpredictable way at 11pm when I am not looking at it. The rule is scoped to the parts of a tool that touch the outside world, real user input, real external data, real formats I do not fully control. Those are exactly the places where something I did not test against will eventually show up.

The other reason this rule stuck is that it changed how I think about scope during a build. Knowing a feature will get a switch makes me more honest about which parts of it are actually risky. Writing the switch forces me to name, explicitly, what could go wrong with this specific feature, which is a question I used to skip until something went wrong and answered it for me.

What A Kill Switch Doesn't Fix

A kill switch is not a fix. It buys time, it does not replace the actual repair. Flipping a flag off turns "the tool is broken and nobody can stop it" into "one exercise is paused while I fix it," and that second sentence is a much better place to debug from, calm instead of urgent, with real users no longer hitting the broken state while I work. But the underlying bug still has to get found and fixed properly, and a switch that stays flipped off for good is really just a deleted feature wearing a disguise.

It also does not fix bugs I have not thought to guard. My switches cover features I already judged risky before launch, the parser that reads unpredictable input, the exercise built on a format I do not control. A bug in a part of the tool I judged safe does not have a switch waiting for it, because I did not think it needed one. That gap is real, and the honest fix is not more switches everywhere, which would just make every release slower without proportional benefit. The fix is paying attention when something in what looked like the safe part of a tool actually breaks, and updating my sense of what counts as risky the next time I build something similar.

There is also a version of this that can become an excuse. It would be easy to ship a feature I am not confident about, tell myself the switch covers it, and skip testing I should have done anyway. A kill switch is for the failure I did not anticipate, not a substitute for testing the failure I could have anticipated. I try to hold that line, test first, switch second, not the other way around.

Since I added the rule, the switch has actually fired twice. Once on a Statusline Builder integration that started receiving a response shape I had not seen before, and once on an OhNine notification path that a platform change quietly broke. Both times, the fix was live inside minutes of noticing, not days. That is the entire return on a habit that mostly sits idle. It is worth building even though most weeks it does nothing at all, because the one week it matters, it is the only thing standing between a broken feature and a broken feature nobody can turn off.

Neither incident needed a dramatic response. In both cases I noticed the same way I noticed the Git Dojo bug, a pattern in how people were using the tool that did not look right, checked it, confirmed the feature was misbehaving, and flipped the flag before writing a single line of the actual fix. Only after the fallback state was live and the status note was up did I sit down and work out what had actually gone wrong upstream. Separating "stop the bleeding" from "understand the cause" into two distinct steps, done in that order, is probably the real habit underneath the kill switch itself. The switch is just the tool that makes the separation possible.

Bottom Line

I did not learn this from a book. I learned it from a two-day gap between "I found the bug" and "the fix shipped," during which a learner hit a broken exercise and quietly gave up on it. Every RAXXO tool now ships its risky features with a switch, a fallback state, and a status note, written before launch, not improvised during an incident.

It is a small tax most weeks. A few extra minutes per feature, mostly unused, flags that sit flipped on for months at a time. But the two times it has actually mattered, in Statusline Builder and OhNine, the difference was minutes instead of days, and a paused feature instead of a broken one nobody could stop. That trade holds up every time I check it, and it is one habit from the four-pass check I run before calling anything shipped that earns its place on every single release, not just the risky ones. It fits the same instinct behind the changelog line I write before code merges, plain, small, boring, and there so nobody, including me, has to guess what state a tool is actually in.

Top comments (0)