An automated check can pass while the result is wrong. I ran into this on a small project on my website, twice, and for two different reasons.

I think this will matter more as AI agents take on more work. We will rely on checks that run automatically too, and a passing check will stand in for a person looking at the result. That only works if the check tests the right thing and can actually recognise it.

The project is the portrait at the top of my home page. It follows the mouse pointer with its head and eyes. I built it with two AI agents, from a single photo and twelve generated poses. Along the way, three defects appeared that I spotted by eye within seconds. An automated check had passed two of them.

The idea came from Claire Vo

The idea comes from Claire Vo, the founder of ChatPRD. In mid-September she published a portrait that follows the cursor in four directions and winks when you click it. She wrote up how she built it. Her six images were generated by Codex, OpenAI's coding agent. Her portrait is black and white. I wanted to know whether the same would work with my own picture, in colour and exactly as it already appeared on the site.

I worked with Claude Code, Anthropic's coding agent. It handed the image generation to Codex and did everything else locally on my Mac. My portrait was the only image sent to OpenAI, with my explicit approval. My role was sign-off. I said no several times: to the first black-and-white version, to the wrong background, to the squinting eye, to the specks and to the overlapping images. Nothing went live that I had not looked at myself.

Twelve poses from one photo

The result is twelve images: the unchanged front pose, eight looking directions, a blink, a wink and a thoughtful look. The portrait shows the thoughtful look when a visitor asks it a question. Answers come only from what I have published.

Every pose came from the same photo with the same instructions. Only the head and eyes were allowed to move. Colours, crop and shoulders had to stay the same. The image model followed this only roughly. So every image went through local post-processing: cut out, shifted, scaled and colour-matched until it lined up with the original. In one run Codex had moved the entire body ten pixels. A measurement caught that one, not me. Afterwards the shoulder outlines of all poses matched by at least 99.8 percent.

The model changes what nobody mentioned

When looking left, the far eye looked slightly squinted, almost like a wink. I did not want a portrait that winks at every visitor who moves the mouse to the left. It took three attempts. Two changes to the prompt fixed it: a smaller head turn, and an explicit rule that both eyelids sit at the same height. Part of the effect is probably perspective. But with that rule, all four diagonal poses came out right on the first try.

No automated check covered this defect. I still find it instructive. The model did what it was asked, turn the head to the left, and changed something nobody had mentioned.

The vision model reports "clean"

When the head turned, I saw single white and black pixels in the lenses of my glasses. The agent looked for them and found nothing. It had a local vision model describe enlarged crops of the eye area. The model reported "clean" for all six crops, even though the defect was already confirmed.

The cause was the post-processing, not Codex. To match colours, the agent had built a lookup table from my front photo. It mapped each colour to a colour in the original, but only for colours that appear in the front photo. For highlights in the lenses or the edges of the frames, it filled in wrong values. The agent replaced the table with a formula that also gives sensible values for colours the front photo does not contain. After that, the specks were gone.

The vision model had asked the right question. It had just never shown that it could spot this kind of defect.

The test passes, the picture shows two heads

To make the switch between poses smoother, the first version briefly faded one image into the next. The agent had written automated browser tests for this. They moved the mouse like a visitor in all eight directions and checked each time that the right pose was showing. Every test passed. The first time I tried it, I still saw two heads on top of each other.

During a fade, two images are half visible at once. Because the poses are cut-outs, the straight head showed through wherever the turned one did not cover it. That produced a double outline at the ear, the hair and the glasses. The test had correctly measured which image was showing. Whether the result looked right was not its question.

Today the portrait switches hard, as Claire's does. Exactly one image is visible at any time. The test run also saves a screenshot of every pose, which gets looked at before anything is published.

Wrong checker or wrong question

The two checks failed in different ways. The vision model was an unproven checker: it asked the right question but could not reliably recognise the answer. The browser test was reliable but asked the wrong question. It checked the state of the page, not the picture.

That leaves me with two questions for any check. Does it cover the defect at all? And can it recognise it? You answer the second with defects planted on purpose. If the check misses them, it is not good enough for that kind of defect. You answer the first by writing down what the check actually measures and comparing it with what the user sees. I still do not have an automated check for specks. If I build one, it will run against the old, broken images first.

Bottom line

I ask the same two questions of every AI system that gives people answers. When I had the chat on my website graded by an AI, the grader first had to reproduce my own verdicts, including on answers with planted errors. Only then was it allowed to grade new answers.

The second question is harder, because nothing answers it automatically. Does the evaluation measure what reaches users, or only whether the system did its job? Whoever signs off on an AI system should know both answers. I would give the second question to someone who sees the result through the users' eyes. The team that wrote the tests is often too close.

I would still not do without automated checks. Without them I would never have run twelve poses in eight directions so often. But I only trust a passing check once I know its question and know that it can find defects.

Which of your checks has ever caught a defect you planted on purpose? And does it check what your users see, or only that your system ran?

Rebuild it

This is the prompt that got the third attempt at the left-looking pose right. The portrait was attached as an image, and the eyelid rule is in the last paragraph.

Prompt
Use your image generation tool. The attached image (reference.png) is my current website portrait, in color. Generate ONE edited frame from it and save it as ./gen/left.png. Do not touch any other file.

Edit this exact image. Preserve this exact man: identity, facial proportions, skin tone, expression, hairstyle, clothing, colors, color grading, lighting, background, shoulders, torso and crop. Keep the full color look of the reference exactly. Keep the same square 1:1 canvas, same subject scale, head center at the same position, body in the same position. Do not shift, mirror, zoom, recolor, or change camera position. No text, no props.

The ONLY change: head turned only slightly, about 8 degrees, toward the LEFT edge of the image, and eyes looking toward the left edge. IMPORTANT: both eyes exactly as wide open as in the reference image, identical eyelid height on both sides, the eye nearer the left edge must NOT look smaller, narrower or squinted. No wink, no squint, no half-closed eyelid, no smile-squint. Move mainly the irises toward the left edge. Same friendly expression as the reference.

At the end, report the saved file and its pixel size.

And this is the core of the component. The angle between the face and the pointer picks one of eight directions. Near the border between two directions, the current one is kept, or the head would flicker back and forth. When the pointer is close to the face, the portrait looks straight ahead, which is decided before this call. Below it is the line that remained after the double outline.

Code
const DIRECTIONS = ["right", "down-right", "down",
  "down-left", "left", "up-left", "up", "up-right"] as const;
// Near a sector edge the previous direction is kept,
// otherwise the head flickers.
const HYSTERESIS_DEG = 8;

function directionFor(dx: number, dy: number, current: Pose) {
  const angle =
    ((Math.atan2(dy, dx) * 180) / Math.PI + 360) % 360;
  const sector = Math.round(angle / 45) % 8;
  if (current !== "front") {
    // Angular distance to the centre of the current sector.
    const index = DIRECTIONS.indexOf(current);
    const offset =
      Math.abs(((angle - index * 45 + 540) % 360) - 180);
    if (offset < 22.5 + HYSTERESIS_DEG) return current;
  }
  return DIRECTIONS[sector];
}

// In the render loop: all twelve frames are stacked and
// exactly one is visible. No cross-fade, because two
// cut-outs at once show a double outline.
style={{ opacity: shown === name ? 1 : 0 }}