Notes from a team that kept rebuilding its own code

We spent three weeks working out what our own code already did.

Not designing it. Not writing it. Reading. Then we went looking for a team this doesn’t happen to, and we could not find one.

Where a nine-week feature actually goes
as described by an engineer on Blind, “this entire industry sucks at estimates”
W1
Scoping
W2
Design doc
W3
Doc comments
W4
Coding starts
W5
Still coding
W6
Unexpected work
W7
New requirements
W8
Rollout
W9
“It’s done”
3 weeks

gone before a line of code is written, almost all of it spent working out what the system already does.

2–3×

the original estimate, reported consistently across teams. “Every single engineer I worked with including me was terrible at estimates.”

+40%

scope discovered mid-project on one large effort: a 120-item list finished at roughly 170.

Sources: engineer estimate threads on Blind and r/ExperiencedDevs; “Tackling the Big, Impossible Project”, Michele Titolo, Capital One.
Six times we lost the week

Every one of these was one of us not having read the code.

Six places the work stops. On the right, what we wish we had been looking at.

We built it twice. The first one was behind a flag nobody turned on.

A request came in. Half of it had shipped two years earlier behind a flag that was never turned on, and the one person who knew that had left. So we re-specced it, re-estimated it and built it again. The first version is still sitting in our repository, unused.

“They may not be aware that the documentation exists in some cases.”
on wikis going stale, CodeX
So we made Grounded Chat answer “does this exist?” from code, PRs and docs at once, and tell us the flag state.
BYTEBELL
ByteBell
SPEC
GROUNDED CHAT
PR REVIEW
BLAST RADIUS
CODE GEN
Do we already support bulk export of saved filters?
3 MATCHES IN THIS WORKSPACE
exports/csvWorker.ts SHIPPED
Full worker, queue and retry path. Gated by bulk_export_v2, off in every environment since March.
PR #2841 CLOSED
UI for the same feature, abandoned after review. Two reviewers flagged pagination limits.
docs/exports.mdx STALE
Describes a CSV-only limit the code stopped enforcing 11 commits ago.
Verdict. Roughly 70% built. The remaining work is the UI and the pagination question that killed #2841, not the export engine.

We spent three weeks in meetings about a file none of us had opened.

Scoping is the three weeks before any of us writes code, and we do it in meetings because the answer is in files none of us has open. The number we walk out with is a guess wearing a decimal point.

“People don’t suck at estimates. They suck at scoping the work.”
TPM, Blind estimates thread
So Blast Radius gives us the touched surface before anyone sizes it: files, owners, and the parts it will not guess at.
BYTEBELL
ByteBell
SPEC
GROUNDED CHAT
PR REVIEW
BLAST RADIUS
CODE GEN
14
FILES
3
TEAMS
2
UNRESOLVED
api/filters/schema.ts Platform SHARED
exports/csvWorker.ts Data EXISTS
web/SavedFilterBar.tsx Growth NEW
billing/usageMeter.go Billing ASK FIRST
Two things ByteBell will not guess
Whether exports count against the metered plan, and whether row limits are enforced per workspace. Both need a decision before this can be sized.

Half our design review is us correcting the doc.

Weeks two and three go to writing the doc and arguing about it. Most of the argument is us correcting assumptions the doc never checked against the code, which makes the review a very slow read of our own repository, out loud, in a room.

“Lacking documentation can inflate a feature’s scope.”
CodeX, on wikis vs. repositories
So every claim in the Spec tab carries the file and line it came from. We check the citation now, not each other.
BYTEBELL
ByteBell
SPEC
GROUNDED CHAT
PR REVIEW
BLAST RADIUS
CODE GEN
Bulk export — current behaviour

Exports are queued through a single worker with a concurrency of four csvWorker.ts:41. Failed jobs retry three times, then drop silently, so there is no user-facing failure state queue/retry.ts:88.

Saved filters serialise to a schema shared with the reporting API, so a new field here changes both surfaces filters/schema.ts:120.

OPEN QUESTIONS
Should a dropped job notify the user? Nothing does today.
Reporting API owns the schema. Who approves the field?
Metered plans: does an export bill?
Answer these three and the doc is finished. The rest is already verified.

Our agents opened forty PRs last week. We read three.

Our agents now write more code in a week than we can read line by line. Writing got cheap for us and reading did not, so whoever has time to read the path is the constraint on everyone else, and the rest of it merges unread.

Outsiders estimating a system they haven’t read “assume that the system they are dealing with has zero technical debt.”
Remote Manager, on the surprise factor
So the Spec tab writes the path out in English and draws it, with the file and the line on every step.
BYTEBELL
ByteBell
SPEC
GROUNDED CHAT
PR REVIEW
BLAST RADIUS
CODE GEN
PATH · BULK EXPORT OF SAVED FILTERS
5 FILES
ENTRY
POST /exports
api/exports/route.ts:18
The filter is validated against a schema the reporting API also reads.
THEN
validateFilters()
filters/schema.ts:120
Queued, then picked up four at a time. One worker, and no priority between jobs.
THEN
csvWorker, concurrency 4
exports/csvWorker.ts:41
Here the path splits, and only one side of it is finished.
IF IT SUCCEEDS
File written, job closed
exports/store.ts:57
IF IT FAILS
Retried three times
queue/retry.ts:88
Then it stops. After the third retry the job is dropped. Nothing is written and nothing is shown, so the person who asked for the file is still waiting on one that is never coming.
Twenty seconds of looking, instead of the two days it takes to read five files and work out the same thing.

Someone refactored main and our feature broke.

A refactor landed on main, broke the features that depended on the old mechanism, and a week of bug fixing appeared in a sprint that was already full. Nobody told us. We found out from a failing build.

“latest push of his to our main branch breaks some other features that were dependent on that messaging”
engineer, Blind
So Blast Radius watches the files a feature depends on and tells us the day they move.
BYTEBELL
ByteBell
SPEC
GROUNDED CHAT
PR REVIEW
BLAST RADIUS
CODE GEN
PR #3012 changed filters/schema.ts 40 minutes ago.
Merged by Platform. It is one of the 14 files your bulk-export scope depends on.
DOWNSTREAM OF THAT CHANGE
exports/csvWorker.ts WILL BREAK
reporting/queryBuilder.ts NEEDS REVIEW
mobile/SavedViews.kt OTHER TEAM
web/SavedFilterBar.tsx SAFE
Scope moved. 14 files to 16, and one of the new two belongs to Mobile.
NOTIFY STAKEHOLDERS

Our wiki stopped being true eleven commits ago.

We write release notes from tickets rather than from what actually merged, and the wiki drifts one user story at a time. The next thing we scope then starts from a document that is wrong, and the nine weeks begin again.

“Developers work in code repositories, not Confluence. Unless they update documentation on every change, a single user story could make it stale.”
CodeX
So PR Review writes our notes from what merged, and flags the pages the release just made wrong.
BYTEBELL
ByteBell
SPEC
GROUNDED CHAT
PR REVIEW
BLAST RADIUS
CODE GEN
RELEASE 2026.8.1 · WRITTEN FROM 9 MERGED PRS
Saved filters can now be exported in bulk, up to 50,000 rows per job.
Failed exports surface a retry state instead of disappearing.
Filter schema gained an exportFormat field. Reporting API consumers should redeploy.
3 pages now contradict the code
docs/exports.mdx CSV-only limit
Confluence / Reporting API Old schema
support/macros/export-fail Says silent failure
OPEN SUGGESTED EDITS
From the newest person on the team

Nobody taught me how to read a codebase. I was expected to already know.

The hard part of my first year has not been writing code. It is reading two hundred thousand lines of somebody else’s.

01 / Day one
My first ticket was inside a 2,000-line file.

I read it for two days and still could not say whether changing line 400 breaks checkout. Nobody sat me down and taught me how to do this. It was assumed I arrived knowing.

02 / The fifth question
I stopped asking, because asking started to feel like admitting.

The first four questions of the day are fine. The fifth one I swallow and guess instead, and the guess is what ends up in my PR. Nobody is keeping count. It feels like somebody is.

03 / git blame
The commit message said “fix”. The author left two years ago.

The actual reason is in a PR thread, a review comment and a ticket nobody linked. The diff tells me what changed. It has never once told me why.

04 / The wiki
The doc said one thing. The code did another.

I usually find out which one is true in review, in front of everybody. The page stopped being true eleven commits ago and nothing about it says so.

05 / Pattern matching
I copied the file next to mine. It was the deprecated one.

Three implementations exist. One is live, one sits behind a flag that never turned on, one is waiting to be deleted. Nothing in the repository marks which is which.

06 / The AI answer
It sounds confident. I can’t tell whether it’s right.

Checking the answer needs exactly the knowledge I was asking for. So I either trust it, or I go and read the code, which is the thing I was trying to avoid.

Nine weeks of work, three of them spent finding out what we had already built.

So we built it

We got tired of it and built one index over our own code.

Every answer carries the file and the line it came from, so checking it takes ten seconds instead of trust. We point it at our own repositories first.

ByteBell demo — Blast Radius explained Play the demo: Why AI coding agents keep breaking production
Why AI coding agents keep breaking production · Blast Radius explained

“Scoping used to be three weeks of meetings. Now the first meeting starts from a file list, and we argue about the two decisions that actually matter.”

SA
Sofia Almeida
Director of Engineering, marketplace
What we would want to know before booking anything
so the call can be about your repository instead of ours
Freshness

The index updates on every commit. An answer reflects the branch as it stands right now, not last night's snapshot, which is the whole reason we trust it over our wiki.

Languages

Every language in common use. The gaps are the genuinely new and genuinely rare ones. Mojo, for example, is not supported yet.

Models

Bring your own key. Anthropic, OpenAI Codex, Gemini, DeepSeek, Qwen, Z.ai, or anything reachable through OpenRouter. Your keys, your spend, your choice of model per workspace.

Deployment

Hosted, on dedicated hardware, or fully on-premise inside your own network. On the second two, your source never leaves your infrastructure. Access is read-only in all three.

Pricing

Index a thousand files before you decide anything.

Same index, same citations, same MCP connection on every plan. What changes is how many files it holds and whose hardware it runs on.

Free
1,000files indexed

Enough for a service or a mid-sized repository. No card, and no feature held back.

  • Every answer cited to a file and a line
  • MCP connection to Cursor, Claude Code and Windsurf
  • Your own model keys
On-premise
Dedicatedhardware or your own

Runs inside your network. The index, the models you point it at, and your source all stay on infrastructure you control.

  • Dedicated hardware or fully on-premise
  • Anthropic, Gemini, Codex, DeepSeek, Qwen, Z.ai, OpenRouter
  • Scoped to your repository count, not per seat