Where I stop when I use AI
This site's logo was fake for months and nobody noticed. The rule that came out of it isn't “don't use AI” — it's don't accept an output you can't check. With five measurements that came back wrong in a single night.

This site's logo was fake for months.
There were four files sitting in public/brand/ and the names were all correct: mark.svg, favicon.svg, a dark logo and a light one. Open any of them and what you find is a <text>e</text> set in Arial with a circle placed next to it. The real logo, emirhan.ai-logo.png at 1254×1254, had been in the same folder the whole time.
Nobody looked at it. The imitation sat in the tab icon, the page header and the footer.
This piece is about the rule that came out of that. The rule is not "don't use AI." It is: don't accept an output you can't check.
Derive, don't generate
The brand mark is no longer drawn by AI. It is derived from the source image's own pixels. A script reads the PNG, finds the bounds of the "e", and measures the centre and radius of the dot.
What it measures are not estimates: dot centre at (570.4 · 401.6), radius 74.8, and a separate check that this is genuinely a circle — the difference between the area-based radius and the maximum radius is 0.38 pixels. Because it is provably a circle, it goes into the SVG as a <circle>. Converting a circle into a bezier curve loses information.
The important part comes last: the script rasterises its own SVG output and compares it pixel by pixel against the source mask. It doesn't claim it drew the right thing. It measures that it did.
The same rule covers the portrait. Three crops were derived from a real studio photograph using cropping and Lanczos resampling, with the facial geometry untouched. An AI-generated face does not enter canonical identity data.
The line isn't "AI or not"
The problem with those four files wasn't that AI made them. The problem was that nobody checked. A file in the right folder with the right name gets assumed to be right.
So my line isn't drawn by tool. It's drawn by checkability. If a claim can be measured, I delegate it. If it can't, I don't, because what I'm left with in that case is the output's own confidence, and a machine sounds exactly the same when it's wrong.
Five wrong measurements in one night
This isn't abstract. On the night of 6 September, five separate measurements in this repository came back wrong, and all five were caught by measuring again.
- "Vercel Analytics isn't connected." It was. The check searched network requests for "vercel" and "insights"; the Vercel script loads from an obfuscated path built to dodge ad blockers. The filter never saw it.
- "Analytics writes no cookies, measured in a browser." The measurement was void. Vercel's script checks
navigator.webdriveron its first line and returns without doing anything. So what had been measured was a script that never ran writing no cookies. Rerun with the flag removed, the answer came out the same — but now it has a basis. - "Nine empty pages are in the sitemap." They weren't. The repo had built that gate a day earlier: empty bodies are kept out of the sitemap and marked
noindex. A false premise plus sound reasoning produced an overstated risk report. - "The sitemap refreshed in 15 minutes." It didn't. A push went out inside those 15 minutes and a deployment resets the cache. What got measured was deploy time, not the revalidation window. Repeated with no deployment, the number went past 100 minutes.
- "The hreflang tags are missing." They weren't. The search looked for lowercase
hreflang; Next emitshrefLang.
In all five the code was right and the measuring tool was wrong. None of them were caught by intuition. Every one surfaced on a second measurement.
The more expensive version of this
Two older incidents in this repo belong to the same family, and both cost more.
A migration file was waiting to be applied by hand and got forgotten. Every query reading that column failed, the read layer fell back to seed data, and for 24 hours the site served the seed instead of the 23 real records in the database. The build passed, the type check passed, four separate browser audits passed — because an empty list renders as "no results," not as an error.
On another day a parallel session ran a build while the server was up. The CSS file moved to a new hash, the running server kept asking for the old one, and pages rendered with no stylesheet. The audit tool reported 110 small touch targets, 4 overflows and 132 console errors. None of it was real. Not one line of code was broken.
That second one taught me the most: the tool didn't lie. It reported exactly what it saw. What it was looking at just wasn't the site.
What I hand over and what I don't
Handed over: measurement scripts, repetitive transformations, browser audits, draft text, source hunting.
Not handed over: canonical identity assets (logo, portrait), applying database migrations, and the claim that a number is correct. Migrations still run by hand. Automating them would have been easy, but the cost of one migration going wrong is larger than the cost of running them myself.
There's a written rule alongside this: comments in this repo carry measurement, not intent. Next to a decision sits the reason it was made and the measurement that forced it, with a date. "This is cleaner" is not a reason.
How this article was written
I wrote this with AI, and publishing it without saying so would be strange for a piece about exactly this.
Here is how it worked. Nothing was invented; every incident above is in this repository's documentation and git history, with dates. The numbers were read from source. Each of those five wrong measurements really happened that night, and each was committed with its correction.
There is also something I refused to write: a discovery scene. A nice paragraph about the moment I noticed those four fake files could have been produced, and it would have been entirely fabricated. Instead I wrote what was inside the files, because that can be checked.
Which is the line itself. What can be delegated is what can be measured.
What I don't know
I don't know how far this distinction carries. "Delegate it if it's measurable" works for code and images, because in both cases you can write a test for correctness. Whether a piece of writing is any good is not measured that way. I could check whether the paragraphs above are true. I could not check whether they are interesting.
And this much is open: the rule feels like discipline to me, but it might just be a habit. After being wrong enough times you start measuring everything twice, and I haven't worked out what measuring twice costs.


