The number we deleted
Our homepage said 1,284 builds shipped and 2,140 builders online. Nobody had counted either. Here is what removing them cost, what it caught that we had not seen, and the one rule that came out of it.
- honesty
- engineering
- process
For a long time the front page of this site carried a line of numbers. Twelve
agents. 1,284 builds shipped. 2,140 builders online. A 28-minute average build
time. They looked like telemetry. They were constants in a .tsx file, and
nobody had ever counted a single one of them.
We deleted all of them in a single evening. This post is about that evening, because the interesting part was never the deletion — it was how many other lies were hiding behind them.
Why the page was built to look finished
The honest answer is the boring one. The page was assembled to have the shape of a finished product: a hero with metrics, a wall of shipped work scrolling past, a course catalogue with prices and cohort seats. Every one of those elements is what a landing page is supposed to have, so each one got built — and when a number was needed, a number was written.
COURSES in the course component held four invented courses, CRS-100 through
CRS-400, each with a price and a count of remaining cohort seats. The
wall-of-shipped component rendered a scrolling stream of git commits that
never happened. None of it was a bug. All of it compiled, all of it rendered,
and all of it would have survived every test we had.
A number with no query behind it is not a design decision. It is a debt that accrues interest every time somebody reads it and believes it.
The second sweep, and why the first one missed
We deleted the hero numbers, the invented courses and three fabricated event hosts. That felt like the job being done. It was about a third of it.
The second sweep found the rest, and the reason it missed them is the part worth writing down:
| Where | What it said |
|---|---|
| /meetups stats | 1,200+ members, 100+ sessions streamed, 80k replay views, a 40 workshop cap |
| /meetups channels | member counts on eight Discord channels: 1.2k, 412, 388, 301, 229, 354, 118, 890 |
| /meetups archive | nine past sessions, week numbers W18 through W26, with view counts |
| /meetups leaderboard | five invented builders, ranked, with ship counts |
| the home terminal | AGENT SWARM — 12 agents active, with +412 LOC per tick |
A programme that has never run had a nine-week archive. A room with no measured size had a cap. We had built a history.
The first sweep missed them because it grepped for the values it already knew
about. grep -r "1,284" finds 1,284. It does not find 1.2k, and it never
will. We were searching for the string we had in mind instead of asking the
question that surfaces all of them.
So the second sweep asked one question of every number on the site, and kept asking until the answer was a query:
What query produces this?
1,284 builds shipped — nothing produces it. Gone.
going on an event card — count(*) of RSVP rows. Kept, and now it is real.
Discord channel size — the platform will not tell us, so the card says
not measured yet rather than approximating a privacy-respecting platform's
silence with a number we made up.
What it caught that we were not looking for
The sweep was supposed to be about the page. It found two operational faults instead, and both of them had been costing us for days.
The secrets file and the database were tracked in git. .env and
db/custom.db were committed. A modified secrets file and a rewritten database
file both block a pull, so the server sat seven commits behind and every deploy
refused for reasons that had nothing to do with the deploy. A database in git is
a database you can never delete. An .env in git is a secret waiting to be
published. Both are untracked now, and .env.example ships in their place.
The backend had been built and never deployed. Signup returned 404 in production while working perfectly on a laptop. "It does not work" and "it was never built" are the same sentence, and the second one is much cheaper to fix once you have read it.
The rule
The whole errand reduced to one sentence, and we are keeping it:
A number on this site may only be a count of rows we can query. If we cannot run the query, the number does not go on the page. There is no "roughly", no "community size", no constant.
It sounds severe until you notice what it actually buys. A new contributor can add a feature without a lawyer. Nothing has to be re-litigated when a real number replaces an invented one, because there was never an invented number to defend. And a visitor who finds one bad number has no reason to trust any of the others — so the cost of a single mock is not one mock, it is the whole page.
The guard is now structural rather than a matter of remembering. The deploy
refuses to ship if 1,284, 2,140, 28m avg or CRS-100 appears anywhere in
the built output, and a smoke test sweeps the rendered pages after a deploy for
the same reason. A mock that survives the build does not ship.
What replaced them
Not apologies. Counts.
- Stats are
count(*)on real tables — people with an account, sessions on the schedule, RSVPs across them. - The workshop cap is absent, and says not measured yet, because a room size is measured in a room.
- The archive is empty, on purpose, and says so. A fiction in an archive is worse than a fiction in a hero, because the archive is the part people trust.
- The leaderboard is a query, so it is empty until a real member publishes real work.
- The terminal's agent swarm is now the real course catalogue and one honest
line:
swarm — none here. the courses teach yours.
The part we are still learning
Two things.
The obvious grep is not a strategy. It finds what you already know. The only question that found the nine-week archive and the eight channel counts was "what query produces this?" — asked of every number, without exception, every time.
And a page that is unfinished is honest. A page that is finished-looking and empty is the hardest kind of lie to take back, because by then people have planned around it. So this blog starts with one post, about the night we took all of that back. The cadence is one a week, and it is almost always a thing that was built — what broke, what it cost, what the fix was.
If the posts ever stop, that is the signal. It is better to have a one-post archive than a launch announcement and a silence after it.