← All work

com.abiola.anchor · v1.1.2 · SIGNED RELEASE

Anchor

Your phone stays still, or the session dies.

A focus timer that cannot be ignored, because the phone itself is the commitment. Start a session and put it down. Pick it up, or leave the app, and your anchor breaks.

Built to a signed release bundle. Not currently listed.
Deep workREC
25:00
Hold still
Streak 12Anchored ⚓

Try it

Move your mouse and you'll lose it.

That ring is filling right now because you're holding still. Move the cursor quickly and you'll get the same five-second warning the app gives you. Come back to stillness and you keep the session. Let it run out and the streak resets to zero.

It is a slightly unfair thing to do to a visitor, which is the point. Reading that a focus app is strict tells you nothing. Losing a session to a twitch tells you everything.

Package

com.abiola.anchor

Version

1.1.2 · build 14

Platform

Android · minSdk 24

Source

~3,900 lines · 31 files

Anchor's timer screen: streak, best and minutes tiles above a Novice rank, a daily goal bar, and a 25:00 timer reading Ready to focus.
The real thing. Streak, rank, daily goal, and the timer before a session starts.

Your hand is the loophole. So the phone had to become the commitment instead of the thing measuring it.

01

The loophole

Every focus app can be ignored. You pick the phone up anyway — the timer keeps running, your focus doesn't. The app has no idea. Your hand is the loophole, so the phone had to become the commitment instead of the thing measuring it.

02

How it knows

Anchor reads the device motion sensors and smooths them exponentially so a passing truck doesn't end your session. Deviate more than the threshold from the established baseline and you've moved. It re-baselines only after a full run of consecutive still readings, so setting the phone down somewhere new is allowed — while lifting it is not. Switching apps is caught separately through visibility, because leaving is the same as moving.

The four numbers the detector runs on
Smoothing factor α0.18

rejects jitter, keeps real movement

Violation threshold0.55

deviation from the established baseline

Re-baseline after60

consecutive still readings

Grace period5s

RETURN TO ANCHOR — none in Strict Mode

Every one of these is a number I had to guess wrong first. 0.18 was 0.5, and a bus going past ended a session.

03

The five seconds

Breaking focus doesn't end the session instantly. The screen goes red — RETURN TO ANCHOR — and a countdown starts. Put it back and you keep your streak with a warning against your score. Let the countdown run out and the session is gone. Strict Mode removes the mercy entirely: any movement, instant failure. That toggle exists for the days you don't trust yourself.

04

Making discipline compound

Six ranks climb from Novice to Iron Anchor at a sixty-day streak. Sessions pay credits, credits can be wagered on the next session double-or-nothing, and a broken streak gives you ten seconds to spend credits saving it. Squads take it further: a four-character join code, live member status, and a flag that tells everyone when one of you breaks. Focus stops being private.

05

Two bugs worth keeping

The Android build shipped as a black screen for a while. The Capacitor WebView silently refuses module script tags carrying a crossorigin attribute, so I wrote a Vite plugin that strips it at build time. The second was Firebase Analytics throwing at module load and blanking the whole app before React mounted — fixed by deferring initialization past first paint. Neither is in any tutorial. Both are written down in the config next to the reason.

Both bugs had the same symptom
<script type=module crossorigin>black

Capacitor WebView refuses it, silently → stripCrossorigin() Vite plugin

getAnalytics() at module loadblack

throws before React mounts → deferred past first paint

A black screen tells you nothing about which of the two you are looking at. That is why they are both written down in the config, next to the reason.

Built with

  • React 19
  • TypeScript
  • Vite 6
  • Capacitor 8
  • Firebase
  • Tailwind 4
  • Play Billing

Next

Ghost

ghostinterview.dev · LIVE