Answer
The checks that sit between a model's output and a person: what each one catches, what it does when it fires, and the rule that every guard works for every brand and heals saved work, so nothing a model invents reaches a shopper unchecked.
Today
Words: claims
claimFlags(text, source) flags five kinds of claim the brand's own words do not carry brew/claims.js:64-82.
| Kind | Example it catches | Passes when | Source |
|---|---|---|---|
| code | "Use code PURE25" | The code is on the store | brew/claims.js:24-25 |
| guarantee | "money back", "risk free" | The store says it | brew/claims.js:26 |
| timed | "visible results in 14 days", "overnight results" | The store says the same time | brew/claims.js:28 |
| absolute | "clinically proven", "dermat-approved", "100% natural", "cures" | Health words need the study, test or certificate beside them in the store's words, or a Brand Book approved claim; other absolutes need the store's own words | brew/claims.js:32 brew/claims.js:74-78 |
| efficacy | "up to 60% less hair fall", "reduce hair fall by 7.4X" | The store names where the number was measured, or the claim is approved | brew/claims.js:36-37 |
- "Dermat-approved" passed once on Arata and is now caught in every spelling brew/claims.js:30-31.
- An approved claim counts only inside the Brand Book's approved list, never anywhere in the brand's words brew/claims.js:50-52.
- Every writer prompt carries
CLAIMS_RULEbrew/claims.js:88.
What happens when a claim fires depends on the surface:
| Surface | Action | Source |
|---|---|---|
| A Play | Sentence kept, marked "Proposed, team decides"; a claim in a title or cover number goes to To confirm | brew/claims.js:102-137 |
| A draft made with nobody watching | Every flagged sentence dropped; a flagged headline never set on the picture | brew/claims.js:143-153 |
| A feed card that no person rewrites | Sentences with codes or guarantees dropped | brew/claims.js:93-97 |
| Anything a shopper, team or partner may copy | checkCopy drops flagged sentences, never throws |
brew/claims.js:215-232 |
| A film's spoken line | Claim taken out before the model hears it | brew/jam2/studio.js:133 |
| A still's words | A claim, or a price that is not this product's own, is taken out | brew/jam2/studio.js:134-142 |
Words: banned words, copy and slips
bannedHitsfinds category words ads cannot use, but never inside quotes, a denial, an avoid list, or a word the brand itself uses brew/claims.js:110-118. The banned list is config plus the Brand Book never-say list memory brew-brand-book.copyFlagsflags shouting caps, forced slang, nonsense time phrases, repeated words and literal "\n" brew/claims.js:166-195. Every writer carriesCOPY_RULEbrew/claims.js:196.writerSlipsadds the "isn't A; it's B" turn, paise on a price the store shows whole, and for WhatsApp or SMS: dash lists, label lines, over 700 characters brew/claims.js:203-213.- Mend: a jam package with slips is rewritten once on exactly those slips before anyone sees it, so "Needs a fix" never lands on a fresh draft brew/remix.js:642-650. Added 26 Oct after an Arata WhatsApp broadcast brew/claims.js:199-202.
- Every structured reply gets real line breaks, and ₹ written as ‹ is fixed brew/ai.js:9-11.
Numbers and proof
- Fact gate: every money amount and percentage on a card must be on the fact sheet; strict mode also gates multipliers and large counts brew/fact-gate.js:1-12.
- Honest: a story quotes only numbers in its data, small counts up to 10 aside brew/research.js:57.
- Play check: each Play is read by a second model against the lines it cites, and only flagged sentences are fixed; an unbacked number becomes a labelled target brew/moves-engine.js:553 brew/moves-engine.js:568.
- Proof: the proof sheet must prove the claim it sits under; prices, plan rows and Plays are never proof brew/proof-logic.js:128 memory brew-proof-plain-make.
- Brand Book verify: a line without a citation or a verbatim quote is dropped brew/brand-book-read.js:205. The Brand Book has its own audit and guard test before every deploy memory brew-brand-book-guards.
Pictures: the image guard
One wrapper around the image model gives every caller the same checks brew/image-guard.js:1-24.
| Step | What it does | Source |
|---|---|---|
| Reference | The product the words name, matched to the catalog; its plainest photo; never a logo | brew/image-guard.js:74-90 |
| Keep | The prompt says to keep the product exactly as photographed | brew/image-guard.js:29 |
| Product check | SAME keeps it; TEXT remakes once on the other model, turned and smaller; DIFFERENT remakes stricter, then the real photo stands in; NOREF tries the next catalog photo | brew/image-guard.js:110-140 brew/server.js:212-230 |
| Look judge | A free pixel check, then a vision judge: GOOD, COLLAGE, CROPPED, OFFTOPIC, EXPERT | brew/image-guard.js:57-59 brew/draft-quality.js:91-98 |
| Redo or hold back | A failure is made once more with the reason; a second failure is held back and never shown | brew/image-guard.js:60-72 |
| Retry | Up to 3 tries with backoff; a blocked or refused prompt is not retried | brew/image-guard.js:43-50 |
- The pixel check flags two flat grounds of different colours at the frame, or a blank band; it is strict on purpose, FLAT 2.5 and 10% of the frame brew/draft-quality.js:37 brew/draft-quality.js:56-68 memory brew-draft-quality.
- EXPERT fails any person shown as a doctor or scientist, a fake endorsement; saved drafts were judged again at
LOOKS_V2 brew/draft-quality.js:15 brew/draft-quality.js:97. - When in doubt the judge says GOOD; split screens pass and page mocks are never judged brew/draft-quality.js:93 memory brew-draft-quality.
- See-through packshots are flattened on white before the model sees them memory brew-draft-quality.
- A cut-out with no real matte or a jagged edge is never placed brew/draft-quality.js:73-88.
- Of 54 pictures the old check threw away on 16 Oct, 47 showed the right product, so blurred small print now counts as SAME brew/server.js:218.
Studio and finals
- Critic: each Studio shot is judged against the product photo; a check that did not run never buys a second picture brew/jam2/creative.js:99-109.
- Made check: every word a designed piece drew is read back; an invented size, number, claim or fake review fails it. Higgsfield once printed "10ml" on a 30 ml bottle and set a tagline as a 5-star review brew/jam2/creative.js:111-131.
- A take that fails its checks is retried once, never more brew/jam2/studio.js:1-5.
- A testimonial style is blocked when the Brand Book says no testimonials brew/jam2/studio.js:88.
- Video spelling: after a video final lands, two frames per worded beat are read and compared with the words asked for; nothing is remade by itself because a remake costs credits brew/text-check.js:1-5 brew/text-check.js:50-55. Added after Arata's reel read "concrate" memory brew-viral-remakes.
Tests that hold the guards
Guard tests run on every deploy with AI_MOCK=1, and a failing suite stops the deploy brew/deploy.sh:12-16. Files: claims, claim-kinds, claim-rules, round2-claims, writer-slips, make-claim, fact-truth, honest-copy, proof-logic, image-guard, draft-quality, text-check, brand-book-guards, qv3-guards brew/test/.
Tomorrow
| Item | Version | Tag |
|---|---|---|
| Every guard brand-agnostic, healing saved work on read | v1 | Stays |
A labelled claim corpus that measures precision and recall of claimFlags |
v1 | New, see Evals |
| Guard verdicts logged per brand and per day, so a rising hold-back rate shows | v1 | New |
| Video spelling check that offers one remake with the price shown | v2 | Changes |
| A send gate: nothing posts or schedules without guards passing and a person's yes | v2 | New |
| Ad policy checks per platform before an ad runs | v4 | New |
| Category rule packs, such as ASCI, FSSAI, FTC, ASA, kept as Brand Book suggestions until the team keeps them | v1 | Stays memory brew-brand-book |
How we do it
- A new surface that a shopper, team or partner can copy calls
checkCopyorcheckCopyInwithpackSource(pack, card)brew/claims.js:57 brew/claims.js:215-232. - A new picture caller goes through the image guard, never the raw model.
- A new incident class gets a guard in code, a test, and a heal for saved data, the same day.
- Run the guards locally:
cd /Users/param/Documents/ChatGPT/brew AI_MOCK=1 node --test test/claims.test.js test/writer-slips.test.js test/image-guard.test.js test/draft-quality.test.js test/text-check.test.js - Turn the look judge off only to diagnose:
LOOKS_CHECK=0.IMAGE_CHECK=0turns off both picture checks brew/server.js:232. - Before a Brand Book deploy:
node tools/audit-brand-book.mjs DIRand the guards test memory brew-brand-book-guards.
Numbers
| Metric | Definition | Where measured | Status |
|---|---|---|---|
| Hold-back rate | Pictures held back after two look failures, over pictures made | guard.held on each picture brew/image-guard.js:70-71 |
Proposed, not counted today |
| Wrong product shipped | Pictures shown whose product is not the catalog product | spot check | Proposed, target 0 |
| Mend rate | Jam packages rewritten on slips, over packages made | remix.js mend | Proposed |
| Claim flags per 100 drafts | Flags removed by Clean | cleanDraftClaims return |
Proposed |
| Video spelling pass | Finals whose on-screen words match | text-check result | Proposed |
Open
- Count the guards. Nothing records how often each guard fires. Proposal: one daily line per brand in the ops page with flags, mends, redos and holds.
- Judge model. The picture checks ask for Haiku and run on Flash today. Proposal: keep Flash until the eval set shows judge agreement with a person below 90%, then move the judge to Claude.
- Video spelling remake. Proposal: keep it manual in v1, and in v2 offer one priced remake.