# I Put My Own Product Through a Colonoscopy and Found 260 Things

> Source: <https://dev.to/choksi_3003/i-put-my-own-product-through-a-colonoscopy-and-found-260-things-3895>
> Published: 2026-10-18 15:05:43+00:00

*Or: how one human, ~80 AI sub-agents across ten fleets, and a graph database that occasionally changed its personality taught me what "production-grade" actually means. Mostly by violating it first.*

Every identity breach you've read about — Storm-0558, MGM, Snowflake — was not a *hack*. It was a **walk**. Somebody got one credential, opened their favorite graph tool, followed the pretty attack-path arrows to Domain Admin, and the arrows did not fight back. The tools that exist will happily draw you a beautiful map of your own destruction and then leave for lunch.

BloodHound shows you the path. Nobody swings the sword. And when a real SOC analyst finally hand-edits a group membership at 3 AM to break an attack chain, nobody re-measures anything, nobody writes a receipt, and the next auditor asks "how do you know that worked?" and everyone stares at the carpet.

So I built **SEVER** — an attack-path interdiction agent on FalkorDB. It ingests BloodHound-style Active Directory + Entra identity graphs, watches a findings stream, and computes the one edge whose removal kills the most attack paths to the crown jewels. Then — because I am not a monster — it refuses to do anything about it until a human clicks **APPROVE** and then **CONFIRM**. Two clicks. Deliberately annoying. Like a nuclear launch, but for Active Directory.

Then it deletes the edge *on the live graph*, re-queries reachability, and writes an append-only receipt: reachability 1 → 0, re-query measured, `verdict: COLLAPSED`, and the operator who approved it. The receipt is the product. Everything else is ceremony.

Working live demo: **[https://sever-console.onrender.com](https://sever-console.onrender.com)** — go click things, it's real, the estate is a public BloodHound CE sample (PHANTOM.CORP, the most-breached fictional company in security research).

Early on, I wanted a 10-agent audit fleet. The delegation API has a hard cap of 10 tasks per call. My first payload had 11. It got rejected. Fine. I fixed it. And by "fixed it," I mean my fix was also 11 tasks, five times in a row, and the runtime — which had been quietly counting — hit a guard: *this turn has already spawned 55 subagents (limit 50).*

I had spawned 55 agents while trying to spawn 10. This is the closest I have ever come to a fork bomb with a spending limit. Somewhere in a data center, 50 AI agents were all simultaneously deciding to inspect the same repository, like a flash mob for people who love `pytest`.

The lesson: when a machine tells you "max 10," it is not a suggestion, and it *is* counting. Unlike your gym membership.

At one point, five separate agents had each redesigned the same HTML file. Each one was *individually* brilliant and *collectively* a war crime. Merging their branches produced **31 conflicts** — in one file. Not 31 lines. 31 conflict regions. The file was roughly 60% conflict markers by volume, which is a sentence that should never be true of anything.

I resolved them by hand, one by one, deciding which agent's design language won where — like a divorce lawyer for CSS. Then a vision-check of the merged result caught that the animation constants were broken: a missing variable, a dead element ID, and a UX rule that the banner could overwrite your cut receipt with a "partial data" notice. All three shipped bugs were mine, from the merge, not the agents'. The agents' code worked. My glue didn't. Humbling — like building a car from five perfect engines and discovering you've connected them with shoelaces.

We fixed it, wrote regression tests pinning the exact failure modes, and moved on to never doing that again: every subsequent fleet got **isolated git worktrees and single-file ownership**, so merges became ceremonial. Boring is a feature. Boring is *the* feature.

The brief: "a great logo, very deep and very unique."

The journey:

Twelve versions, one vision model, zero human designers. The final mark literally tells the product story: the attack path (a ring) is severed by one precise blade, and the crown jewel rides the surviving arc. The AI critic earned its keep — every rating was an actionable diagnosis, not a vibe. I have worked with human designers who gave less usable feedback, and I have *been* the designer giving less usable feedback.

The night before final polish, production "broke." Click "Simulate breach finding" and the console said the attacker could reach... zero crown jewels. Empty paths panel. Panic. Three separate fix attempts by three separate agents, each addressing a plausible engine-dialect theory. A forensic deep-dive that exonerated the engine, the queries, the client library, and the network — each verified live, with receipts.

Then the actual answer arrived: **my own demo-video script had clicked APPROVE → CONFIRM on the top-ranked edge** — the exact max-coverage bottleneck edge — and the engine had *correctly collapsed the estate.* Reachability zero. Paths gone. The product was not broken; the product had *won*, on camera, and left me a forensic trail of receipts explaining exactly how it had won, which I was too busy debugging to read.

The bug was filed as "production reachability broken." It should have been filed as **"product defends itself against owner; owner surprised."** I spent hours debugging my own product's success. Somewhere, a skeptic of AI-written software is reading this and feeling very validated, and I want them to know: the receipts said COLLAPSED the entire time. The receipts are the product. *Read the receipts.*

(Lesson industrialized: never diagnose against an estate your own scripts mutated. Fresh reload, re-verify, then panic.)

FalkorDB Cloud ran engine v4.22.0. Our dev box ran 6.0.0. Same product, same version family — and, we discovered, **not the same Cypher dialect.** A `WITH shortestPath(...)` query form that runs clean on 6.0.0 returned a single row containing `null` on 4.22.0 — not an error, not an empty set, just a serene little `null`, the database equivalent of answering a question with a shrug.

Meanwhile the cloud engine rejected a batched query form with a syntax error at column 741, inside a 43-relationship alternation list, and the error mentioned relationship names that the *dev* engine accepted happily. Two engines, two personalities, one codebase.

The fix: probe the engine version at first contact, fail safe to the older dialect, and verify the fallback on the live cloud — because the local test suite *physically cannot* catch a dialect that only exists in production. The test that guards this runs the real engine, or it doesn't run. Everything else is theater.

Every database has a dark side. Ours was polite, well-documented, and null-shaped.

A security product should survive its own users, so one audit agent threw the whole keyboard at the API: unicode RTL overrides, lone surrogates, emoji, 2^70 as an integer, JSON with byte-order marks. Almost everything failed closed and politely, per spec — 422, 400, readable errors.

Then one agent sent a **single NUL byte** inside a principal name. It sailed through the schema, hit the engine as a query parameter, and the engine responded with an error our outage handler didn't classify. Bare 500. The kind of thing that ends up in a CTF write-up, except we were the target.

We fixed it the right way: control characters now die at the schema, 422, before any mutation, with a regression test file dedicated to this exact shame. There is now a test in the repo whose entire purpose is to assert that a NUL byte gets told no. A single test, standing in the darkness, so that no byte may pass unnamed. I have written worse monuments.

Our free-tier host health-checks every few seconds and requires a 200 within five. Our `/api/state` endpoint runs several engine queries, and under cloud load it took 6-24 seconds. So the health check failed, the host restarted the container, and the restart wiped the ephemeral receipts ledger. Four times in 47 minutes. We watched our own append-only audit trail get append-*deleted* on a schedule you could set a clock by.

The fix had layers, like an onion, or a parrot: a `/api/health` endpoint that runs *one* cheap query and writes no receipt; the receipts route bounded to the newest entries so it can't 502 the worker by shipping megabytes of history; and the ephemeral-filesystem reality documented in the README — honestly — because lying about persistence in a *security receipts* product would be a fun headline for somebody else.

The lesson: free-tier infrastructure will find your product's assumptions and eat them. Design for the tier you're on.

A user clicked "Plan k-cut sequence" and the UI said "planning..." and then *nothing*, for thirteen seconds, which on the internet is a geological era. The button wasn't broken. The problem was arithmetic: **197 round-trips** from the console to the cloud engine, at ~65ms of WAN latency each. The algorithm was fast; the *distance* was slow.

We re-derived the whole path: fold redundant queries (197 → 11), batch the per-pair enumerations into one server-side statement, pipeline the independent reads, and overlap the copy with the first measurement. Result: the same plan, in about two seconds — with an equivalence test suite proving old and new return identical results, because the only thing worse than slow is *different*.

Now the UI also shows elapsed time and a real progress bar while it works. Turns out "the engine is thinking" is a message users find reassuring, whereas silence makes them assume you've stopped paying your hosting bill. Correct on both counts.

Before going public, I ran a full rules-compliance audit — six auditor agents against the eighteen official rules, with fixer agents patching every finding live. The receipts:

If you take one thing from this post: **receipts or it didn't happen.** Not in the marketing sense. In the "here is the JSON file with the median latency, generated by the script in the repo, re-runnable by you" sense.

Days from the deadline, I did the thing you're supposed to do and nobody actually does: **a full-repo audit where ten review agents read every single line of all 142 tracked files — 27,895 lines, zero skipped, zero duplicated, verified programmatically.**

The result was a document I have come to think of as my product's medical chart: **260 findings. One CRITICAL. Twenty HIGH. Eighty-four MEDIUM. A hundred and seven LOW. Forty-eight nits** — the last category being things like a test whose name promises to verify a real attack-path target and whose body asserts the literal string `"B"` it just passed in, which is the testing equivalent of a guard dog that barks at a recording of itself.

The CRITICAL was exactly what you want a CRITICAL to be: **on engines we don't vouch for, our reachability function shipped a query form that our own receipt had measured returning zero reachable principals where the honest form returned one.** The receipt was sitting in our repo the entire time, patiently testifying against the code sitting next to it. Nobody had connected them, because nobody had read every line. That's what the colonoscopy was for.

Then came the fix fleet: **ten agents, single-file shards, two reinforcement helpers** — one running the engine gate on every branch as it landed, one auditing cross-shard consistency so nothing fell through the seams between the shards. Every finding fixed, annotated, or explicitly ratified. The two test files whose pins had to change *in coordination* — one agent's code change, another agent's test update — converged green exactly as the contract specified. I have seen Fortune 500 teams fail to do that with a meeting and a Jira board.

My favorite HIGH of the audit, for its pure bureaucratic violence: a CSS custom property — `--motion: 150ms` — was declared **outside any rule block**, followed by a **stray closing brace**. One character. `}`.

The CSS parser, doing its best, absorbed the next rule into the invalid selector and discarded it — and that next rule was the **universal reset**. So the shipped console — the judge-facing product — had `content-box` sizing, surviving browser-default margins, and every single polish animation we'd written (`animation: none` via a token that resolved to nothing). All of it killed by one orphaned `}`. The browser didn't crash. It didn't warn. It just quietly made everything worse, like a coworker.

The fix was two lines. The regression test asserts the token resolves and the reset applies, so no future merge can ever do this again — because the bug itself was born in a merge, which is the most humiliating part.

The audit's most philosophically disturbing finding: **the agent-layer approval gate — the thing the README describes as the fourth fail-closed layer between a schema lie and a severed edge — was structurally inert on the HTTP path.** The console never forwarded the operator's decision into it; the gate's own `require_explicit_approval` parameter defaulted to `True` and satisfied itself. A security control that checks your paperwork by looking at its own default settings and saying "looks approved to me."

The fix is one line per endpoint — forward the actual decision — but it's the kind of finding that keeps security people up at night, because everything *looked* right: the tests passed, the README described four layers, the gate code was correct. It was just never in the loop on the path that mattered. Defense in depth is only depth if every layer is wired to the electricity.

And while we were at it: our headline metric — `requery_ms`, the number in every demo receipt — **was timing the DELETE, not the re-query it was named after.** The timer wrapped the wrong half of the operation. The number was real, the label was a lie by four characters of placement. The fix moved the timer; the field kept its name; every receipt since is what it always claimed to be. That's the honest way to fix an honest mistake: change the truth, not the truth's name.

Every sufficiently large test suite has a ghost. Ours was a wall-clock pin — a test that asserts a plan completes in under a hard-coded milliseconds threshold — that failed *identically at the pristine tip*, under load, solo, and on every branch. I ran it at the base commit in a detached worktree to prove it: same failure, untouched code. An environmental phantom that three fleets of agents each independently caught, diagnosed, and documented as Not Our Problem.

And then there was the time I wrote a PowerShell sweep script to run the suite file-by-file and it produced **38 identical failures** — because my script's argument-passing wrote NUL bytes into the log and pytest never ran once. The script reported total defeat with total confidence. It was the most honest thing in the repo: broken tooling admitting it has no idea what happened. I threw it away and used the working command, which is also a metaphor for most debugging.

The rules require disclosure, so here it is with receipts. This project was built during the hackathon window (first commit at 00:02:53 IST, window opened at 00:01 — we are nothing if not prompt) by me directing AI agents under explicit gates. The evidence that a human was home: **merge commits authored by me, each with a stated reason** — "merging the atomic-cut fix because the count-then-delete pair double-claimed under a race, reproduced 6/6 rounds." The agents wrote code; I decided what was true, what merged, and what the product believes. That's not a disclaimer, that's the job description — and the product's own two-step human gate is the philosophy wearing a UI.

The failures in this post were my glue, my flags, my 11-vs-10 counting, my own demo script collapsing my own estate, my one-character `}`. The successes belong to the loop: human sets the bar, agents clear it, receipts keep everyone honest.

AI did not build this product. A human with 80 power tools and a receipt printer built this product. The power tools just don't sleep.

Everything below is a file in the repo you can re-run:

`docs/receipts/`)
*SEVER: sever the path, prove the collapse, read the receipts. Preferably before assuming the product is broken.*

*Built solo with AI assistance, disclosed per Rule 11 and lived per Chapter 4.*
