All writing

Ten build checks, and the faults they caught that I did not

A rebuild where every commit runs ten checks that can fail it. These are the real defects they found: text at 1.05:1, a font size resolving to 0.38 pixels, a gallery missing from seven pages. None of them were visible.

I rebuilt my own site off Webflow, with a model doing a large share of the typing. The interesting part is not the speed. It is that every commit runs ten checks which can fail the build, and that those checks caught a list of faults I would otherwise have shipped.

Here is the list, honestly reported, including the ones that were my fault rather than the model’s.

The checks

Check What it fails on
headings more than one h1, a skipped heading level
canonical missing, relative, or pointing somewhere else
jsonld a graph that does not parse, a dangling @id, a relative url
alt a missing alt, an unjustified empty one, placeholder text
content a page under a 300-word floor
chrome a footer destination that the port no longer reaches
body a case-sensitive text diff of the page against the previous version
structure elements added, dropped or reclassed, which the text diff cannot see
copy an em dash anywhere a reader can see one
claims a page that stopped making a claim it is supposed to make

The faults

A form field at 1.05:1. The contact page’s message box rendered dark text on a dark fill. The ratio was 1.05 to 1, where readable text needs 4.5. It was invisible, it had been invisible since the section was built, and nobody reviewing the page in a browser noticed, because the eye fills in a box it expects to be there. It was caused by a two-class CSS rule outranking a one-class rule, which is the sort of thing that is obvious once stated and never once spotted.

A font size that resolved to 0.38 pixels. A rule set a size relative to the parent font size rather than to the width, so as the layout scaled it became a fraction of a pixel. The text was there in the markup, present to a crawler, and absent to a person.

A whole gallery missing from seven project pages. The port dropped a section on seven of eleven pages and a second gallery slot on three more. A text diff cannot catch this, because the gallery contains no words. It took a second check comparing the DOM shape, element by element, to find it.

A 0 printed on ten pages. A conditional read a.length || b.length && (...), which evaluates to the number zero when both lists are empty, and a stray zero duly shipped to every project page without a case study.

142 pixels of horizontal scroll on every listing page. Two elements had been hoisted out of a wrapper whose overflow: clip was the only thing containing a background image deliberately set to 120% width.

An image width of minus 36. In a figure I generated for this very site, a hash was shifted with a signed right shift rather than an unsigned one. Above two billion it goes negative, a modulo of a negative is negative, and three of five bars rendered at width="-36" and drew nothing. The figure looked sparse rather than broken, which is precisely how this kind of fault ships.

A check that passed everything. My favourite one. A test was loading built pages over file://, where absolute stylesheet paths silently 404. It was asserting against an unstyled page and would have passed any CSS at all. Re-run over HTTP it immediately found a diagram 717 pixels wide that should not have been.

What the list has in common

Not one of these was visible. Every one of them survived a human looking at the page in a browser and deciding it was fine.

That is the actual argument about building with AI, and it is not the one usually had. The question is not whether a model can write the code. It plainly can. The question is what tells you where it is wrong, and the answer is not a careful reading, because a careful reading is exactly what failed here ten times. A person reviewing a page checks whether it looks right. A model generating it optimises for the same thing. They share a blind spot, and the blind spot is everything that has no appearance: a ratio, a heading level, a canonical, a dangling reference, an element that is absent.

An automated check does not share that blind spot, because it does not look at all.

The check that passed everything, again

I want to dwell on this one, because it is the moral of the piece.

A check that has only ever passed is not yet a check. It might be working. It might be reading the wrong file, matching a pattern that cannot match, or asserting against an empty string. You do not know, and the longer it stays green the more you trust it.

So every check here was tested by deliberately breaking something and watching it fail. The copy check was tested by planting an em dash in a built page. The first attempt planted one inside a class attribute and the check stayed green, which was correct, because attributes are not copy. The second attempt, in visible text, failed it. Only then was it a check.

The claims check earned itself within a minute of being written, by catching the old positioning line still sitting in a heading I was certain I had already rewritten.

If you take one thing

Pick the three faults on your own site that would be most expensive and least visible, and write something that fails the build on each. For most marketing sites that is: text that cannot be read, a page that is empty without JavaScript, and structured data that claims something the page does not contain.

Then break each one on purpose, once, and confirm it goes red.

Questions

Can you trust AI-generated code?
You can trust it about as far as you can check it, which is the same standard as any other code. The difference is the failure mode: generated code fails quietly and confidently. It looks finished. Every fault listed in this article passed a visual review and was caught by an automated check instead.
What should a build check for?
The things a person cannot see and will not notice: contrast ratios, heading order, canonical URLs, structured data that parses and resolves, alt text that is not a placeholder, and a diff of the rendered page against the previous version. Ten checks on this project, all of which can fail the build outright.
Does this slow development down?
The checks run in a few seconds. What slows development down is finding out six months later that a form field has been invisible since launch, which is one of the things on this list.
Is this overkill for a marketing site?
Two of the faults here would have been seen by every visitor and by every crawler: an unreadable form field and a missing image gallery on seven pages. Neither was noticed by a human reviewing the pages. Decide from that.

Read next

All writing, or see how I build websites.