
A model rated a visibly wrong red 0.97 on-brand. That number changed what I built.
I remember the exact number, because it embarrassed me. 0.968. A generic similarity model looked at a holiday asset whose hero red was visibly, obviously wrong, and rated it 0.97 on-brand. On a scale where 1.0 means perfect, it told me this creative was as good as shipped.
I had spent the first stretch of this project assuming the hard problem was the opposite one. I thought the interesting work in trustworthy AI content was making the generation better, teaching a model to hit the brand's exact red, tightening prompts until the output looked right. I was building the Brand Fidelity Firewall, a demo of a pre-ship gate that every AI-generated campaign asset has to clear before it ships. And I kept reaching for the model to be the judge. The model was the last thing I should have trusted with that job.
This is the story of how one wrong number rearranged the whole thing. If you want to see the finished version deciding on a live batch, it runs at veriprajna.com/demos/brand-ai-content. But the demo is the easy part to look at. The part worth writing down is what it took to stop asking the model to do a job it cannot do.
I built the wrong thing first
I started where most people start, which is with a similarity score. The instinct is reasonable. You have a brand book and you have a generated asset, and you want a single number that says how close they are. Every AI aesthetic tool on the market gives you that number, and it feels like governance. It is not governance. It is a vibe with a decimal point.
To make the demo honest I invented a fake brand to test against, because I was not going to put a real company's creative through a proof of concept. The brand is "Lumiere," a synthetic premium house with the tagline "Quiet luxury, since 1984." Its primary color is Lumiere Crimson, Pantone PMS 484, hex #9E2B25, with a per-color tolerance of 3.0. Everything downstream measures against that brand book. It is a made-up brand, but the pixels and the specs are real, which is the only way to test whether a check actually works.
Then I composed a batch of twelve holiday assets, again synthetic, flat layouts built so that every check measures real pixels instead of photographic noise. The firewall itself generates nothing. It ingests pre-generated assets and decides what is safe to ship, so the twelve are test fixtures I authored to exercise the checks. Eleven of them were fine. One, the asset I labeled a08, had a hero red that any art director would flag from across the room. It matched #9D2E0B across roughly 46 percent of its area. That is a different red. Not subtly different. Wrong.
And the similarity score loved it.
A number that cannot tell your red from a competitor's red is not measuring your brand. It is measuring luminance and shrugging.
The reason it loved it is worth understanding, because it is the whole argument. The generic baseline I used is a real perceptual hash, a DCT-based pHash, the same family of technique that content platforms use to spot near-duplicate images. It is deliberately built to be robust to color. It cares about structure and luminance, so it can recognize the same photo after a recolor or a compression pass. That robustness is exactly the property you want for deduplication and exactly the property that makes it useless as a brand judge. It looked at a correctly composed layout with a wrong red poured into it and saw a correctly composed layout. 0.968. It would have shipped.
What does a similarity score actually see?
I keep that screenshot open when I explain this to people, because the panel says it more plainly than I can. On the left, the off-brand asset. On the right, the firewall's read of it.

The gap between those two numbers is the entire product. 7.12 against a tolerance of 3.0. That is the color difference measured in CIEDE2000, the ISO and CIE standard perceptual color-difference metric, written ΔE00. It is not a similarity guess and it is not something I invented. It is the number the color-science world already agreed on for the question "how different do these two colors look to a human eye." A ΔE00 of 7.12 against a tolerance of 3 is a hard fail. The similarity score's 0.97 and the ΔE00's 7.12 are looking at the same pixels and disagreeing completely, and only one of them is measuring the thing a brand actually cares about.
The first time I put those two readings side by side, I stopped thinking about generation entirely. It did not matter how good the generator was. A perfect generator still produces assets that have to be measured against an exact spec, and a similarity model is structurally incapable of doing that measurement. The problem was never making better creative. The problem was knowing what is safe to ship.
I want to be precise about one thing, because it is a place people oversell. I did not run CLIP here. CLIP is the metric a lot of "AI brand scoring" pitches name, and running it for real is a documented drop-in, but it drags a roughly two-gigabyte dependency along and it demonstrates the identical miss that a pHash demonstrates for free. So the baseline in the demo is an honest perceptual-hash stand-in for the generic-similarity approach, not CLIP wearing a costume. The point survives either way. Similarity, however you compute it, cannot tell your Pantone red from a wrong one. Color science can.
I tried to make the model the judge. It answered fluently and it was wrong.
I did not arrive at that conclusion gracefully. For a stretch I was convinced the right architecture was to let a capable vision-language model be the arbiter. Show it the asset, show it the brand book, ask it to decide. Models are good at describing images. Surely one could tell me whether an asset was on-brand.
It could not, and the way it failed is the part that unsettled me. It did not fail loudly. It failed politely and confidently. I would hand it the off-brand red and it would produce a fluent, plausible paragraph about how the composition honored the brand's restrained aesthetic, and it would land on approve. Then I would hand it a correct asset and get an equally fluent paragraph that sometimes flagged an imaginary problem. The verdicts were prose, and prose is exactly what you do not want between a wrong red and a shipped campaign.
There is a real cost sitting under this, which is why I could not just wave it away as a demo curiosity. Consumers have started pricing in the difference. Half of them say they prefer brands that avoid GenAI content, per Gartner in March 2026. A third stop interacting with a brand once content is revealed as AI, per Adobe's 2026 Digital Trends report. Smartly.io found in 2025 that measured trust in an ad drops from 48 percent to 13 percent when it goes from co-created to fully AI. The Coca-Cola AI holiday spot, seventy thousand generated clips, got called soulless in public. At Cannes in 2025 the DM9 scandal saw twelve awards revoked over AI-fabricated footage. When the downside is that concrete, a governance layer that produces confident paragraphs instead of provable measurements is not a safeguard. It is a liability with good manners.
If the thing standing between a wrong asset and a live campaign can be talked into anything, it is not a gate. It is a suggestion.
So I stopped trying to make the model the judge. That was the turn. Everything I built after that assumes the model is the least trustworthy component in the system, not the smartest.
Why color science, and not a better prompt?
I chose to make the color check the hard, unarguable core, and I want to explain why I trust it in a way I never trusted the model. CIEDE2000 is not a heuristic I tuned until the demo looked good. It is a published formula with reference test data, and I validated my implementation against the Sharma et al. reference color pairs. There is a unit test, test_ciede2000_matches_sharma, and it passes as one of five passing tests in the suite. That matters more than it sounds. It means the 7.12 is not my opinion of how wrong the red is. It is a reproducible measurement that a colorimetrist could check against a textbook.
That is the difference between a number I can defend to a skeptical brand director and a number I have to apologize for. When a similarity model says 0.97, and someone asks why, the honest answer is "the model felt that way." When ΔE00 says 7.12 against a tolerance of 3, the answer is "here are the two colors in CIELAB, here is the standard formula, here is the reference validation, and here is where 7.12 exceeds 3." One of those answers survives a legal review. The other survives until the first hard question.
A verdict I can trace to a published formula survives a legal review. A verdict I can only explain as a model's intuition survives until the first hard question.
I also learned to be careful about where the color is measured. Judging the whole image would let a tiny correct logo drag the average back into tolerance while the giant wrong hero region ships. So the check judges the dominant saturated hero region specifically, which is how the off-brand red gets caught even when a true-crimson logo is sitting in the corner being perfectly correct. The gate is looking where a human eye looks first.
The gate has to be boring
I made a rule for myself partway through: the thing that decides has to be boring. Boring meaning deterministic, plain code, outside any model, testable, and reproducible. The moment a decision depends on a model's mood, it stops being auditable, and an auditable verdict is the entire value.
So the gate is exactly that. It BLOCKS on any hard failure, it FLAGS the cases a human genuinely has to own, and otherwise it PASSes. There is a unit-tested invariant that I care about more than any single feature, test_gate_invariant_no_hard_fail_passes: no asset with a hard failure is ever returned as PASS or FLAG. It cannot slip through. That is a property you can prove, not a behavior you hope for.
Color is not the only hard block, and I deliberately built a second one that has nothing to do with color, to prove the gate is not a one-trick color meter. Asset a09 has a perfect crimson, ΔE00 of 0.00, dead on Lumiere Crimson. And the gate blocks it anyway.

The third hard block is regulatory, and it is the one with real dates attached. If AI content ships into a market that requires a machine-readable AI-content disclosure and the disclosure is missing, that is a hard block regardless of how good the pixels are. Asset a10 is a clean, on-brand layout headed into the EU with no Article 50 label. The EU AI Act's Article 50 disclosure obligation is enforceable on August 2, 2026, with penalties up to 15 million euros or 3 percent of turnover. New York's SB-8420A lands June 9, 2026. California's CAITA arrives in August 2026. The FTC's Section 5 sits over all of it. A missing required label is not a style note. It is a fine waiting to happen, and the gate treats it that way.
On the full twelve-asset demo batch, the split comes out to seven PASS, three BLOCK, two FLAG. That is a 58.3 percent auto-clear rate on this specific fixed batch, and I say "this specific batch" on purpose, because it is a computed result on twelve synthetic assets, not a promise about your production pipeline.

The two FLAG cases are the ones I am proudest of, because they are the cases where an honest system says "I do not know, a human has to decide." Asset a11 contains an AI-generated human face, so it routes to a person for authenticity sign-off rather than getting bluffed into a PASS or a BLOCK. That is the NielsenIQ negative-halo risk, the finding that AI-generated faces can drag down brand perception, and it is not a call code should make alone. Asset a12 targets Japan, a market outside the brand book's coverage, so the disclosure rules are unknown and it goes to legal instead of being falsely cleared. A gate that never admits uncertainty is not rigorous. It is reckless.
What the model is still good for
I did not throw the model out, and I want to be honest about where it landed, because "we removed the AI" would be a lie and also a waste. The vision-language model is still in the pipeline. It just has no vote. It writes an advisory note, one provider-swappable call, and it is informational only. It abstains cleanly if there is no key or it errors, and it never changes a PASS, a FLAG, or a BLOCK.

The model can be as fluent and confident as it likes. It still cannot ship a wrong red.
Read that advisory note next to the verdict and you can see the healthy division of labor I was after. The gate already said BLOCK, on the strength of 7.12 against 3.0. The model adds the human color, the why-it-matters, the sentence a brand director actually wants to read. That is genuinely useful. It is context, not judgment. The deterministic gate decides. The model only advises. Once I put the model in that seat, I stopped being nervous about it. Its fluency turned from a risk into a feature, because that fluency now sits underneath a verdict it has no power to move.
Every cleared asset exports a Brand Fidelity Certificate, JSON plus printable HTML, carrying the per-check measurements, the provenance of which elements were AI versus human, the per-market disclosure status, the gate result, the model and version, and a timestamp. I should be careful about what that document is. It is a filable evidence artifact, a reproducible receipt of what was measured and decided. It is not a legal certification and it is not legal advice. Calling it "EU AI Act certified" would be exactly the kind of confident overstatement this whole project exists to reject.
Generation was never the bottleneck
I keep coming back to the moment with 0.968, because it inverted my sense of where the hard problem lives. I had assumed that as generators improved, the trust problem would shrink. Building this convinced me of the opposite. A better generator produces a wrong red faster and at higher volume. It does not tell you the red is wrong. Nothing about model quality touches the question of whether an asset matches PMS 484 and carries an Article 50 label, and those are the questions that decide what is safe to ship.
The uncomfortable version of this, the one I have started saying out loud, is that the most important part of a trustworthy-AI-content stack contains almost no AI. The color check is a formula from a standards body. The clear-space check is geometry. The disclosure check is a rules engine mapped to dated statutes. The one model in the system is not allowed to decide anything. That felt like a strange thing to build until I remembered that the whole point was to be able to prove the verdict, and you cannot prove a paragraph.
You can run the finished gate yourself and watch it catch the red at veriprajna.com/demos/brand-ai-content. What I would rather you take away is the question it left me with. If your governance layer can be talked into approving a wrong red with a confident sentence, was it ever governing anything? Or were you just generating faster and calling the speed a strategy?
And if you would rather watch it than read me describe it, here is the whole gate running end to end.
I do not think that question gets easier as the models get better. I think it gets sharper.


