Sutra

Deterministic QA: turning taste into checks a machine can run

Taste cannot be automated. Most of what gets called taste is not taste. Here is how we sort the two, what the mechanical half looks like enforced in code at creation time, and the two metrics of ours that failed confidently in the wrong direction.

What is in here
  1. What can a machine actually decide about creative?
  2. Enforce the mechanical half at creation, not in review
  3. What does that change about who does what?
  4. Most of what gets called taste is not taste
  5. The honest half: most of our rules were only documentation
  6. Which of your automated checks have you had to withdraw?
The short answer

Sort the work by what kind of decision it is. Contrast under a glyph, how long a line stays on screen, letterboxing, how much of an element is covered, loudness at the end: all mechanical, all measurable on the delivered file, and all currently found by eye far too late. Enforce that half in code at creation time so a breach is refused before it renders. Leave the other half, whether the thing is any good, to a person at a cheap moment. Automate the floors and never the ceiling.

What you get out of this
  1. A working sort: which creative checks a machine can decide and which it cannot
  2. The layout contract in full, including occlusion budgets measured after compositing
  3. The standard it was built to meet: change this image is a note, your text escapes its box is a failure
  4. The honest half: most of our own rules lived only as documentation when we counted them
  5. Two of our metrics that failed confidently, including a hook gate that ranked results backwards

Your last ten review notes. Sort them

Move the sliders
Something broke mechanically: text outside its box, a label too small, a letterboxed frame
Something was unreadable or invisible at phone size
A label or a line pointed at the wrong thing
Change this image. This does not stop me. This is not the brand
Notes accounted for

Only the bottom row is a note a person should ever have to give. Every note above it is a defect that a machine could have refused before the file existed, and every one of them spent a verdict somebody only has so many of in a day.

01What can a machine actually decide about creative?

Anything measurable on the delivered file with a number attached to it. Contrast under each run of glyphs. How long a string holds at full opacity. Whether any frame is letterboxed. How much of an element another element covers. Whether the last two seconds are loud. None of those need an opinion, and none of them should ever reach a person.

Which half of QA is which

The sort
Which half of QA is which
DimensionThe checkA machine can decide itOnly a person can
Contrast under the lettersWorst local ground per glyph run, at two widthsYes. Yes. It is arithmetic on pixelsNothing left to judge once the floor is set
How long a line stays upAt least 1.2s, or 0.35s per wordYes. Yes. Computed from the string itselfNothing
Text inside its plateThe box fits or the plate growsYes. Yes, and before render rather than afterNothing
OcclusionDeclared budget, measured post-compositeYes. Yes, against the number the designer declaredSetting the budget in the first place
Does a label point at the thing it namesComprehensionNo. No. Geometry passes and meaning failsYes. Fresh eyes on the bundle, before I see it
Does the hook stop a strangerThe only question that decides the moneyNo. No. Every metric we built for it failedYes. A person, cold, at feed size, once
Are five pieces in a set really differentSameness at set levelPartly. Partly. It can compare declared axesYes. A person names the difference a viewer would notice
The middle column is the useful one to argue with. Almost every dispute about automating creative work is really a dispute about a single row: whether the thing being checked has a number behind it or a judgment behind it.

The same sort, on three frames we made

Three of ours
Two of these three are settled by arithmetic and one is not. That ratio is roughly what we find across a delivered set, which is why moving the arithmetic into the engine buys back so much of a review.

02Enforce the mechanical half at creation, not in review

The audit line we run on now is short. A rule is either in the path, or it is a suggestion. After two weeks of watching which of our own rules held, the pattern was blunt: the ones that never broke had a refusing gate in the only path to the effect. The ones that broke repeatedly were the ones living as prose in a document.

Prose compliance does not accumulate across people. Code does.

the finding that reorganized our whole pipeline

So layout correctness moved into the build engine. Text never exits the plate it belongs to, because the box fits or the plate grows, and that decision is made in code before the render rather than caught in review afterward. This is mistake-proofing at the point of creation, which manufacturing settled decades ago and creative tooling mostly has not.

A composition spec, with the occlusion budgets written in

Copy this shape
plate  hero_card
  bounds          1080 x 1350
  text_runs
    headline      max_width 62%   plate: headline_scrim   grow_plate_if_needed
    subhead       max_width 62%   plate: headline_scrim   grow_plate_if_needed

elements
  product         occlusion_budget  0%    # nothing may cover the pack, ever
  brand_mark      occlusion_budget  0%    # and it holds 1.0s at full opacity
  ingredient_chip occlusion_budget 10%    # a tenth is a design decision
  texture_card    occlusion_budget 40%    # it is background. say so out loud

on_breach
  1  measure ACTUAL occlusion after compositing, never from the layout intent
  2  reposition, or grow the plate, then re-measure on the new pixels
  3  still over budget -> REFUSE the render. never ship and hope
  4  log the value that failed, never only the fact that something did
An example in the format ours use, with the names changed. The line people leave out is the third one under on_breach. A system that measures, warns and ships anyway has not moved the decision at all, it has only added a log file nobody reads.

That file is the whole idea in twenty lines. A budget is a design decision made out loud, in advance, by the person composing the frame, and the engine's job is to hold them to their own number rather than to have taste about it. We got here because a client once received a static where an image chip was almost entirely hidden behind other elements, and nothing in the code knew that was wrong.

03What does that change about who does what?

It changes the content of a review, not its length. My own standard for this system is that my quality control should be taste-only. Change this image is a legitimate note for me to have to give. Your text escapes its box is not a note at all, it is evidence that something upstream failed, and no amount of care from whoever built that file would have prevented it.

Every note I give that is not a taste note is a bug report the system should have filed instead.

the standard the layout contract was written to meet

What happens between a check failing and a file existing

How a breach is handled
00Measureafter compositing, onthe pixels that wouldactually ship01Fix at creationthe box fits or theplate grows, decidedin codeIN THE PATH02Re-measureagainst the samenumber, on the newbytes03Refuseif it still breaches,the render does nothappenNO FORCE FLAG04Log the numberthe value thatfailed, not the factthat something did
00Measureafter compositing, on the pixels that would actually ship
01Fix at creationthe box fits or the plate grows, decided in codein the path
02Re-measureagainst the same number, on the new bytes
03Refuseif it still breaches, the render does not happenno force flag
04Log the numberthe value that failed, not the fact that something did
Five steps, and the interesting one is the last. A refusal that records the number it failed on makes the next composition start closer, which is the difference between a gate and a lesson.

The same logic runs on delivery. Every measurable floor is re-measured on the bytes that will ship, a re-render voids every verdict, and there is no override. The generation side of the same architecture is in deterministic pipelines plus AI generation, and the human-facing version of the list is the pre-launch QA checklist.

04Most of what gets called taste is not taste

This is the claim worth arguing with, so here is the test. Take a note you would describe as a taste note and ask whether two strangers looking at the same file would agree on it. If they would, it is a fact with a number missing. If they would not, it is taste and it belongs to a person.

How much of your quality control is actually taste?

Score yourself
Four questions, about ninety seconds. The score is a conversation rather than a verdict. What matters is which question you answered worst, because that is the one thing worth changing this month.

One warning goes with that sort. A set of our statics once came back with zero geometric breaches and was killed entirely on meaning: a leader line ending somewhere other than the thing it named, a label pointing at the wrong doorway, a room called by another room's name. Geometry passed and comprehension failed, so a check for meaning had to be added, and it is a human one.

05The honest half: most of our rules were only documentation

We audited our own rulebook once, classifying every rule by how it was actually enforced rather than by how important it sounded. The result is the reason this post exists, and it is not flattering. Over half of the rules were prose with nothing behind them, in a book where roughly a third carried kill severity.

The enforcement audit, on the day we ran it

Counted in this studio
293rules in our own rulebook when we counted themSutra Haus enforcement audit
149of those existed only as documentation, with no gate, checklist or agent behind themSutra Haus enforcement audit
96carried kill severity, meaning breaking one should end the pieceSutra Haus enforcement audit
58were enforced by an automated gate that could actually refuse somethingSutra Haus enforcement audit
Ours, counted once. Treat the exact figures as a snapshot of one day rather than a constant. The shape is the finding, and the shape was that the rules living only in a document were precisely the ones that kept getting broken.

Nothing about that gap was laziness. Writing a rule down feels like solving it, and the feeling is convincing enough that a team can add rules for months while the same defect keeps shipping. The fix was not more rules. It was a policy that a new rule ships the same day as its enforcement, or it does not count as shipped.

How to move one recurring note from a document into the path

One screen at a time
Step 1
Write the note as a sentence with a number in it

Make it big enough to read is not a rule. Cap height is at least five percent of frame height, measured off the plate's own ink, is a rule.

If you cannot get a number into the sentence, stop here. What you have is a taste note and it belongs to a person, permanently.

Step 2
Decide what it is measured on

The delivered file, not the project file, not the layout intent, not the design tool's preview. Occlusion is measured after compositing because that is the only place it is real.

Then decide the second width. Ours is about 360 pixels, because that is roughly what a feed tile gives you.

Step 3
Put it in the only path to the effect

Not in a linter somebody runs when they remember. Inside the function that draws the thing, so a breach is corrected or refused before a file exists.

If there are two paths to the effect, you do not have a rule yet. You have a rule and a bypass.

Step 4
Delete the line from the document

This is the step people skip, and it is the one that keeps the rulebook honest. A rule that is in the path does not need to be in a document, and a rule in both places will drift.

Then check whether the note has stopped appearing in reviews. If it has not, it is not really in the path.

1 / 4

Do this for the single note you repeat most often in feedback. One rule a fortnight retires one recurring argument permanently, which compounds faster than writing twenty more rules that nobody enforces.

06Which of your automated checks have you had to withdraw?

Two, and both failed the same way: confidently, silently, and in a direction that looked reassuring. The first was a hook gate. Change in the first two seconds is the obvious thing to measure, so we measured it across five films I had already judged, expecting the accepted ones to be the changeful ones.

The hook gate that ranked our own films backwards

Ours, and it failed
Accepted film A7Accepted film B6.7Rejected film C9.1Rejected film D9.2Rejected film E11.9
See the numbers as a table
Mean frame delta in the first two seconds, in thousandthsFrame delta
Accepted film A7
Accepted film B6.7
Rejected film C9.1
Rejected film D9.2
Rejected film E11.9
Ours, measured on five judged films. The raw values are 0.0070 and 0.0067 for the two accepted films, and 0.0091, 0.0092 and 0.0119 for the three rejected ones. The two accepted films were the least changeful of the five, so the metric was formally withdrawn rather than tuned.

What actually separated those films sat in the last row of the same table, and it was not motion. The accepted films state one legible proposition before frame twelve. The rejected ones said their first word at frame 238, or never. Information, not change. A gate built on the wrong variable would have blocked the two films worth running.

Five things people say about checking creative with software

Flip them
Four of the five were positions we held ourselves and abandoned after they cost us something. The first one is the only one we have never held, and it is the most common.
The second failure, and the rule it producedA lint is a floor, not a target. When a check fails, fix the thing rather than the number. Tuning a threshold until the answer looks right is fitting to noise, which is Goodhart's law arriving in a mix session. The bed an agent tuned green and shipped anyway is in sound is 40% of the ad.
A still ad on a dark blue-gray bed: a single white feather lying in a shaft of light across creased linen, with a large cream serif headline reading Sleep like you're on feathers above it and the brand lockup along the bottom
Pale display type over a photograph is the pattern that fails our contrast check most often. This one clears because the ground under every letter is genuinely dark. Move the same lockup onto the lit part of the sheet and it does not.

There is a machine-measured perceptual quality metric worth knowing about, and knowing its limits. Netflix's VMAF predicts how much a compression pass degraded a video against its own source. It is genuinely good at that and it has no opinion about whether the video was worth watching, which is the boundary this whole post is about.

The vocabulary this sort needs

Search the terms
6 terms
Occlusion budgetLayout
A declared limit on how much of an element another element may cover, written when the composition is designed and measured on the composited pixels rather than on the layout intent. Over budget, the engine repositions or refuses.
Worst local groundMeasurement
The darkest and lightest background actually sitting under a run of letters, rather than an average across the whole string. A mean of a doorway edge and a lit sleeve describes no pixel anybody is looking at.
Floor, not a targetPolicy
The rule that a passing threshold is a minimum to clear rather than a number to optimize toward. When a check fails you change the thing, never the threshold, because tuning until the answer looks right is fitting to noise.
Force flagPolicy
The override that lets somebody ship past a failing gate. The useful property of our delivery checks is that no such flag exists, so a failure is a decision to fix rather than a decision to make at five in the evening.
Comprehension checkHuman
A human pass that answers what this ad is saying and whether every label points at the thing it names. Added after a set of ours passed geometry with zero breaches and was killed entirely on meaning.
Enforcement classAudit
How a rule is actually held: an automated gate, a checkpoint with a named artifact, a checker agent, a checklist line, or documentation only. Classifying every rule this way is what showed us how many of ours were prose.
Six words that do most of the work. The names matter less than having exactly one name per idea, so that a rule can be argued about without anybody having to describe it first.

Questions people actually ask

Open what you need
Can creative QA be automated?

The floors can and the ceiling cannot. Contrast, dwell time, layout geometry, occlusion, letterboxing, loudness and tempo are all measurable on the delivered file and belong in code. Whether an ad is any good is not measurable, and every metric we built to stand in for that judgment failed toward a confident wrong answer.

What is deterministic QA?

Quality control where the same file always produces the same verdict, because every check is a computation on the delivered bytes rather than an impression. The practical marker is that there is no force flag: a failing check refuses the render or blocks the package, and a re-render voids every verdict that was attached to the old file.

Which video ad checks can a machine run reliably?

Text staying inside its plate, cap height as a fraction of frame height, perceptual contrast against the worst local background under each glyph run, dwell time per string, occlusion against a declared budget, full-bleed frames, first-sound timing, and end loudness.

All of those are measured on the file that will actually ship, at delivery width and again at about 360 pixels, because the losses at feed size are the ones that catch people out.

What should never be automated in creative QA?

The hook, the story, the combined claim words and picture make, and whether one piece in a set is different from the others in a way a viewer would notice. Also anything where a wrong answer would look reassuring, which is most attempts at scoring quality. We had a tempo detector report 165 BPM on a track built on a 90 BPM grid.

How do you stop a team optimizing to the checker?

Say out loud that every check is a floor rather than a target, and refuse threshold changes as a way of passing. The rule we use is that when a check fails you fix the thing, not the number. It sounds obvious and it is the exact failure that produced the worst audio we have ever shipped.

Which checks did you have to withdraw?

Two, and both failed the same way. A hook gate built on change in the first two seconds ranked our accepted films below our rejected ones, so it was withdrawn rather than tuned. A midrange check on sound was passed by an agent moving the number instead of fixing the bed, and the ad got worse. Any check that can be satisfied without improving the work is a check you have to withdraw.

Here is the sharp version. If somebody on your team can name the defect they keep pointing out, that defect already has a number behind it, and saying it again is the most expensive way in the world to fix it. Write the number down, put it in the only path to the effect, delete the sentence from your rulebook, and do that a dozen more times. What is left is the one question worth a human opinion, which is whether anybody stops. Getting to that question earlier is the whole argument in approving the story on paper before anything renders, and the defects worth naming first are cataloged in why AI ads look fake.

Where the numbers came from

  1. Wikipedia. Goodhart's law - a measure that becomes a target stops being a good measure, which is the entire risk here
  2. W3C. Understanding Success Criterion 1.4.3: Contrast (Minimum) - the 4.5:1 ratio our contrast gate measures against at delivery width
  3. Netflix Technology Blog. Toward a practical perceptual video quality metric (VMAF) - the state of the art in machine-measured perceptual quality, and what it is and is not for
  4. Wikipedia. Poka-yoke - mistake-proofing at the point of creation, which is what a layout contract is

Every figure above links to the place it was published. Numbers marked as ours are measured inside this studio and we say so where they appear. We do not print a statistic we cannot point at.

Badal Kariwal

Runs Sutra Haus, a one-person ad studio that has shipped over a thousand finished creatives - film and stills - for DTC brands and hotels. Writes here about what the work actually taught him, including the parts that failed. The person who reads your brief is the person who builds the work. Send him something to make.

The checks, run on your product instead of ours

Send a link. Get one finished ad back.

One finished cut built from your own product inside three days, free and yours to run whether or not we ever work together. It clears the same floors described on this page, and if any of them failed on the way you will hear the number from us before you hear anything else.

Replies within a day. Ad within three.
Read next