I do not decide to visit the sites that waste my day. I arrive at them. A gap opens between two pieces of work, my hands type four letters and hit enter, and the page is loading before any of it reaches the part of me that had a plan. By the time I notice, I am reading, and the thing I was doing is now a thing I have to come back to.
Every blocker I tried lost to that the same way. They block, right up until the moment you would rather they did not, and then the off switch is one click in a toolbar menu. The switch is closest to hand exactly when you are least inclined to argue with yourself about using it.
So IHateBeingDistracted is built on one idea: getting past a block should cost deliberate effort, and getting out of blocking altogether should cost more than getting into it.
What a block costs
A domain on the Block List is a Blocked Site, and it covers that domain, every subdomain, and every path under it. Navigating to a Blocked Site gets you a Block Screen in place of the page, reading YOU’RE BLOCKED and naming the site you were going to. Nothing loads behind it, so there is nothing to glance at while you decide.
The way through is a button marked Unlock, and then a Challenge: eight digits, generated at the moment you ask for them, which you retype by hand into a box that refuses paste and refuses drag. Get one digit wrong and those digits are discarded and you are handed eight fresh ones. There is no lockout, no cooldown, no escalating penalty. Clumsy fingers are not punished beyond having to type again.
Eight digits is about ten seconds. That is the entire product. Ten seconds is nothing if you meant to go to the site, and it is fatal to the version of the visit that was pure muscle memory, because that version has no reason to spend ten seconds on anything. The Challenge does not decide whether you should be there. It just makes you be the one who decides.
None of this is security. Anyone who wants to beat a Challenge can beat it by reading the digits off the screen and typing them, which is also the intended path. The opponent here is not me at my most determined. It is me at my least attentive, and that opponent gives up almost immediately.
What a Challenge buys
Not much, on purpose. Completing a Challenge on the Block Screen earns an Unlock, which is permission to visit one site in one tab. It ends the moment that tab navigates away from the site, and it ends when the tab closes. A tab opened from an unlocked tab is a stranger and gets the Block Screen like anything else.
That keeps one moment of genuine intent from turning into an open afternoon. I wanted to read one thread, so I get to read one thread. Coming back an hour later is a fresh decision, and it costs another eight digits.
It has an accepted cost. A login flow that bounces through another domain and back burns the Unlock, and I retype. I would rather pay that occasionally than widen the grant.
The Pause, and what it protects
Some work is genuinely all over the web, and a Challenge every few minutes would be intolerable. So the toolbar popup offers a Pause: complete a Challenge there and nothing is intercepted anywhere. A Pause expires on its own after fifteen minutes, which means forgetting to re-arm is not possible. If fifteen minutes is not enough, Stay Off removes the expiry with a free click, and the Pause holds until I end it or quit the browser.
Notice which directions are free. Adding a site to the Block List is free and always available. Ending a Pause early is free. Stay Off is free. Every move that makes blocking stricter costs nothing, and every move that loosens it costs a Challenge.
The Block List rule is where that asymmetry does the real work. A site can go on the list at any time. A site can only come off during a Pause. The moment I most want a site off the list, staring at the Block Screen with the thing I want on the other side of it, is precisely the moment I cannot do it. Removal needs a Pause, a Pause needs a Challenge, and by the time I have retyped eight digits, the feeling that wanted the list edited has usually lost interest.
That is the constraint the whole extension is built around. Every route from blocked to browsing runs through a Challenge. There is no side door where you quietly dismantle the thing instead of asking it for an exception, because dismantling it requires an exception first.
The way out I left in
One Challenge plus one free Stay Off click turns blocking off until I quit Firefox. That is a total bypass and I put it there.
The alternative was making a legitimately unblocked afternoon cost a Challenge every fifteen minutes, and I know how that ends: I would come to resent the extension, and a tool you fight is a tool you uninstall. It only has to beat the impulse, not me.
The other direction is closed, though. Nothing but the Block List survives the browser session. Unlocks are gone, the Pause is gone, Stay Off is gone. Every launch starts fully armed, so restarting Firefox is never a way out. It is only a way back in.
What it does not do
No schedules, no quotas, no time-of-day rules. No streaks, no stats, no weekly report on how distracted I was. Those turn a blocker into a second thing to maintain, and a scoreboard is just another site to check.
There is no account, no sync, and nothing collected. Blocking applies to page navigations rather than to every request, so an unrelated site embedding something from a blocked domain does not trip the Block Screen. It is Firefox only.
One place where the rules live
Underneath, every rule above lives in a single module: a function taking the current state and one event, returning the new state and a list of decisions. The browser side only translates, turning navigations and clicks into events, and turning decisions into tab updates, alarms, and storage writes. The tests feed that module events and assert on what it decides.
That was worth the trouble for one reason. The question worth asking about a blocker is whether there is a way past it, and here that question gets answered by reading one file, rather than by clicking around the browser hoping to find the hole.
Ten seconds of typing, and a list you cannot shorten in the moment you want it shorter. That is all of it.