{
 "id": "6.3",
 "title": "Guards",
 "department": "AI and models",
 "department_slug": "ai-and-models",
 "direction": null,
 "branded": false,
 "status": "draft",
 "owner": "Param",
 "last_verified": "Mon Oct 26",
 "holds": "Claims, copy, image guard, look judge, writer slips and mend",
 "urls": {
  "html": "https://handbook.joinsquareup.com/ai-and-models/guards",
  "markdown": "https://handbook.joinsquareup.com/ai-and-models/guards.md",
  "json": "https://handbook.joinsquareup.com/ai-and-models/guards.json"
 },
 "other_directions": [],
 "tldr": {
  "headline": "Nothing a model invents reaches a shopper without a guard looking first",
  "points": [
   {
    "icon": "lock",
    "text": "Five kinds of claim are flagged: codes, guarantees, timed results, absolutes and efficacy."
   },
   {
    "icon": "eye",
    "text": "Every picture gets a product check and a look judge; a second failure is held back."
   },
   {
    "icon": "check",
    "text": "Fact gate, Play check and proof sheet keep every number tied to a source."
   },
   {
    "icon": "gear",
    "text": "Guard tests run on every deploy, and a failing suite stops it."
   },
   {
    "icon": "warn",
    "text": "Nobody counts how often each guard fires yet."
   }
  ],
  "stat": {
   "value": "47",
   "label": "of 54 pictures were fine"
  },
  "decide": "Log one daily line per brand with flags, mends, redos and holds?",
  "mood": "solid"
 },
 "sources": [
  "brew origin/main b91e364: claims.js:1-232, image-guard.js:1-142, draft-quality.js:1-109, text-check.js:1-55, fact-gate.js:1-12, research.js:57, proof-logic.js:128",
  "brew origin/main: server.js:212-236, remix.js:622-650, moves-engine.js:540-575, jam2/creative.js:95-135, jam2/studio.js:88 and 133-142, brand-book-read.js:205, ai.js:9-11",
  "brew origin/main test/: claims, claim-kinds, claim-rules, round2-claims, writer-slips, image-guard, draft-quality, text-check, fact-truth, honest-copy, proof-logic, make-claim, brand-book-guards, qv3-guards",
  "memory brew-draft-quality, brew-brand-book-guards, brew-proof-plain-make, brew-sloosh-finals, brew-viral-remakes, brew-jam-v2, brew-setup-v2, brew-qa-audit-2026-10-20"
 ],
 "open_questions": [
  "**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."
 ],
 "parts": {
  "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\n\n`claimFlags(text, source)` flags five kinds of claim the brand's own words do not carry [src: brew/claims.js:64-82].\n\n| Kind | Example it catches | Passes when | Source |\n|---|---|---|---|\n| code | \"Use code PURE25\" | The code is on the store | [src: brew/claims.js:24-25] |\n| guarantee | \"money back\", \"risk free\" | The store says it | [src: brew/claims.js:26] |\n| timed | \"visible results in 14 days\", \"overnight results\" | The store says the same time | [src: brew/claims.js:28] |\n| 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 | [src: brew/claims.js:32] [src: brew/claims.js:74-78] |\n| 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 | [src: brew/claims.js:36-37] |\n\n- \"Dermat-approved\" passed once on Arata and is now caught in every spelling [src: brew/claims.js:30-31].\n- An approved claim counts only inside the Brand Book's approved list, never anywhere in the brand's words [src: brew/claims.js:50-52].\n- Every writer prompt carries `CLAIMS_RULE` [src: brew/claims.js:88].\n\nWhat happens when a claim fires depends on the surface:\n\n| Surface | Action | Source |\n|---|---|---|\n| A Play | Sentence kept, marked \"Proposed, team decides\"; a claim in a title or cover number goes to To confirm | [src: brew/claims.js:102-137] |\n| A draft made with nobody watching | Every flagged sentence dropped; a flagged headline never set on the picture | [src: brew/claims.js:143-153] |\n| A feed card that no person rewrites | Sentences with codes or guarantees dropped | [src: brew/claims.js:93-97] |\n| Anything a shopper, team or partner may copy | `checkCopy` drops flagged sentences, never throws | [src: brew/claims.js:215-232] |\n| A film's spoken line | Claim taken out before the model hears it | [src: brew/jam2/studio.js:133] |\n| A still's words | A claim, or a price that is not this product's own, is taken out | [src: brew/jam2/studio.js:134-142] |\n\n### Words: banned words, copy and slips\n\n- `bannedHits` finds category words ads cannot use, but never inside quotes, a denial, an avoid list, or a word the brand itself uses [src: brew/claims.js:110-118]. The banned list is config plus the Brand Book never-say list [src: memory brew-brand-book].\n- `copyFlags` flags shouting caps, forced slang, nonsense time phrases, repeated words and literal \"\\n\" [src: brew/claims.js:166-195]. Every writer carries `COPY_RULE` [src: brew/claims.js:196].\n- `writerSlips` adds 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 [src: brew/claims.js:203-213].\n- **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 [src: brew/remix.js:642-650]. Added 26 Oct after an Arata WhatsApp broadcast [src: brew/claims.js:199-202].\n- Every structured reply gets real line breaks, and ₹ written as ‹ is fixed [src: brew/ai.js:9-11].\n\n### Numbers and proof\n\n- **Fact gate:** every money amount and percentage on a card must be on the fact sheet; strict mode also gates multipliers and large counts [src: brew/fact-gate.js:1-12].\n- **Honest:** a story quotes only numbers in its data, small counts up to 10 aside [src: brew/research.js:57].\n- **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 [src: brew/moves-engine.js:553] [src: brew/moves-engine.js:568].\n- **Proof:** the proof sheet must prove the claim it sits under; prices, plan rows and Plays are never proof [src: brew/proof-logic.js:128] [src: memory brew-proof-plain-make].\n- **Brand Book verify:** a line without a citation or a verbatim quote is dropped [src: brew/brand-book-read.js:205]. The Brand Book has its own audit and guard test before every deploy [src: memory brew-brand-book-guards].\n\n### Pictures: the image guard\n\nOne wrapper around the image model gives every caller the same checks [src: brew/image-guard.js:1-24].\n\n| Step | What it does | Source |\n|---|---|---|\n| Reference | The product the words name, matched to the catalog; its plainest photo; never a logo | [src: brew/image-guard.js:74-90] |\n| Keep | The prompt says to keep the product exactly as photographed | [src: brew/image-guard.js:29] |\n| 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 | [src: brew/image-guard.js:110-140] [src: brew/server.js:212-230] |\n| Look judge | A free pixel check, then a vision judge: GOOD, COLLAGE, CROPPED, OFFTOPIC, EXPERT | [src: brew/image-guard.js:57-59] [src: brew/draft-quality.js:91-98] |\n| Redo or hold back | A failure is made once more with the reason; a second failure is held back and never shown | [src: brew/image-guard.js:60-72] |\n| Retry | Up to 3 tries with backoff; a blocked or refused prompt is not retried | [src: brew/image-guard.js:43-50] |\n\n- 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 [src: brew/draft-quality.js:37] [src: brew/draft-quality.js:56-68] [src: memory brew-draft-quality].\n- EXPERT fails any person shown as a doctor or scientist, a fake endorsement; saved drafts were judged again at `LOOKS_V` 2 [src: brew/draft-quality.js:15] [src: brew/draft-quality.js:97].\n- When in doubt the judge says GOOD; split screens pass and page mocks are never judged [src: brew/draft-quality.js:93] [src: memory brew-draft-quality].\n- See-through packshots are flattened on white before the model sees them [src: memory brew-draft-quality].\n- A cut-out with no real matte or a jagged edge is never placed [src: brew/draft-quality.js:73-88].\n- Of 54 pictures the old check threw away on 16 Oct, 47 showed the right product, so blurred small print now counts as SAME [src: brew/server.js:218].\n\n### Studio and finals\n\n- **Critic:** each Studio shot is judged against the product photo; a check that did not run never buys a second picture [src: brew/jam2/creative.js:99-109].\n- **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 [src: brew/jam2/creative.js:111-131].\n- A take that fails its checks is retried once, never more [src: brew/jam2/studio.js:1-5].\n- A testimonial style is blocked when the Brand Book says no testimonials [src: brew/jam2/studio.js:88].\n- **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 [src: brew/text-check.js:1-5] [src: brew/text-check.js:50-55]. Added after Arata's reel read \"concrate\" [src: memory brew-viral-remakes].\n\n### Tests that hold the guards\n\nGuard tests run on every deploy with `AI_MOCK=1`, and a failing suite stops the deploy [src: 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 [src: brew/test/].",
  "Tomorrow": "| Item | Version | Tag |\n|---|---|---|\n| Every guard brand-agnostic, healing saved work on read | v1 | Stays |\n| A labelled claim corpus that measures precision and recall of `claimFlags` | v1 | New, see Evals |\n| Guard verdicts logged per brand and per day, so a rising hold-back rate shows | v1 | New |\n| Video spelling check that offers one remake with the price shown | v2 | Changes |\n| A send gate: nothing posts or schedules without guards passing and a person's yes | v2 | New |\n| Ad policy checks per platform before an ad runs | v4 | New |\n| Category rule packs, such as ASCI, FSSAI, FTC, ASA, kept as Brand Book suggestions until the team keeps them | v1 | Stays [src: memory brew-brand-book] |",
  "How we do it": "1. A new surface that a shopper, team or partner can copy calls `checkCopy` or `checkCopyIn` with `packSource(pack, card)` [src: brew/claims.js:57] [src: brew/claims.js:215-232].\n2. A new picture caller goes through the image guard, never the raw model.\n3. A new incident class gets a guard in code, a test, and a heal for saved data, the same day.\n4. Run the guards locally:\n   ```bash\n   cd /Users/param/Documents/ChatGPT/brew\n   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\n   ```\n5. Turn the look judge off only to diagnose: `LOOKS_CHECK=0`. `IMAGE_CHECK=0` turns off both picture checks [src: brew/server.js:232].\n6. Before a Brand Book deploy: `node tools/audit-brand-book.mjs DIR` and the guards test [src: memory brew-brand-book-guards].",
  "Numbers": "| Metric | Definition | Where measured | Status |\n|---|---|---|---|\n| Hold-back rate | Pictures held back after two look failures, over pictures made | `guard.held` on each picture [src: brew/image-guard.js:70-71] | Proposed, not counted today |\n| Wrong product shipped | Pictures shown whose product is not the catalog product | spot check | Proposed, target 0 |\n| Mend rate | Jam packages rewritten on slips, over packages made | remix.js mend | Proposed |\n| Claim flags per 100 drafts | Flags removed by Clean | `cleanDraftClaims` return | Proposed |\n| Video spelling pass | Finals whose on-screen words match | text-check result | Proposed |",
  "Open": "1. **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.\n2. **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.\n3. **Video spelling remake.** Proposal: keep it manual in v1, and in v2 offer one priced remake."
 }
}