{
 "id": "5.18",
 "title": "Engineering rules",
 "department": "Engineering",
 "department_slug": "engineering",
 "direction": null,
 "branded": false,
 "status": "draft",
 "owner": "Param",
 "last_verified": "Mon Oct 26",
 "holds": "Every brand, heal saved data, errors never shown as zero, dummies marked",
 "urls": {
  "html": "https://handbook.joinsquareup.com/engineering/engineering-rules",
  "markdown": "https://handbook.joinsquareup.com/engineering/engineering-rules.md",
  "json": "https://handbook.joinsquareup.com/engineering/engineering-rules.json"
 },
 "other_directions": [],
 "tldr": {
  "headline": "The rules every change follows, each one earned by a past hurt",
  "points": [
   {
    "icon": "flag",
    "text": "Truth: no invented numbers, and a check that did not run is never shown as none."
   },
   {
    "icon": "check",
    "text": "Every brand: a fix works for any brand, with a test and healed saved data."
   },
   {
    "icon": "lock",
    "text": "Dummies carry a tag in three places, and none reaches production."
   },
   {
    "icon": "book",
    "text": "Never re-add a cut feature without a product decision."
   },
   {
    "icon": "gear",
    "text": "Enforce in CI where possible, starting with the Dummy marker check."
   }
  ],
  "stat": {
   "value": "15",
   "label": "files carry DUMMY markers today"
  },
  "decide": "Should CI enforce these rules? Proposal: yes, start with the Dummy marker check.",
  "mood": "solid"
 },
 "sources": [
  "brew origin/main: CLAUDE.md (all sections), SPEC.md 'Hard rules', SCOPE.md, DUMMY.md (three markers, rules that keep a dummy from passing as real)",
  "brew origin/main: connectors/protected.js; db/prod-clean.mjs:1-6; roles.js:39; jobs.js:4-5",
  "memory feed-for-all-brands, fix-as-product, prod-clean-only, never-disconnect-arata-meta, brew-qv-process, always-deploy-to-test, no-spend-while-building, keep-all-moves, brew-one-version, brew-external-data-skill, brew-parallel-sessions-deploy, brew-live-stores, brew-name-and-scope, treg-usage-rules"
 ],
 "open_questions": [
  "**Should these rules be enforced in CI where possible?** Proposal: yes; start with the Dummy-marker check and a ban on brand slugs in code outside tests and data."
 ],
 "parts": {
  "Answer": "These are the rules every change to Brew follows, from any person or session, and each one exists because breaking it hurt a brand or cost money before.",
  "Today": "### Truth\n\n1. No invented numbers, quotes, founders, reviews or backstory. Every number traces to a ledger entry or a cited source; otherwise it says \"to confirm\". [src: brew/SPEC.md]\n2. Observed, inferred and implication stay separate; \"not observed\" never means \"absent\"; never state a rival's motive; benchmarks are labelled. [src: brew/SPEC.md]\n3. An error or a check that did not run is never shown as \"none\", \"not found\" or \"0\". Keep `error` on the item and say the check did not go through. [src: brew/CLAUDE.md]\n4. A Play is never evidence; proof is real data, real voice, real numbers. [src: memory brew-proof-plain-make]\n5. No disclaimers or AI labels on ad creative. [src: brew/SPEC.md]\n\n### Every brand\n\n6. A fix is done only when it works for any brand Brew could onboard, every card type, every widget and every view: platform, how it sells, market, name, how the site reads, background runs across deploys. Never a per-brand patch, hard-coded id or brand name. [src: brew/CLAUDE.md] [src: memory feed-for-all-brands]\n7. Fix as product: shared cause in code, a test or audit that would have caught it, healed saved data, then deploy. A hand patch to a pack is only a stopgap and is said so. [src: memory fix-as-product]\n8. Saved data heals itself: `heal()`, a stage or pack version bump, a load-time repair, wherever text is read. [src: brew/CLAUDE.md] [src: memory brew-one-version]\n9. Add a case to `test/non-shopify.test.js` for every new kind of brand that breaks; add a check to `tools/audit-brand-book.mjs` and a guard test for every new Brand Book problem class. [src: brew/CLAUDE.md]\n\n### Dummies and production\n\n10. Anything simulated is marked in three places: a Dummy tag in the UI, a `DUMMY:` comment in the code, a row in `DUMMY.md`. Simulated rows are never evidence. [src: brew/DUMMY.md]\n11. Nothing dummy, simulated or from testing ever reaches production; the clean gate refuses a promote on any finding. [src: memory prod-clean-only] [src: brew/db/prod-clean.mjs:1-6]\n12. Never re-add a cut feature without a product decision. [src: brew/SCOPE.md]\n\n### Partners and money\n\n13. Never disconnect, reconnect or re-select Arata's Meta or Shopify connection; `PROTECTED_CONNECTIONS` guards it in code. Test disconnects on Cozy. [src: memory never-disconnect-arata-meta] [src: brew/connectors/protected.js]\n14. Never wipe or reset the five design partners; risky tests run on Cozy or Zenant. [src: memory brew-live-stores]\n15. No paid generation while only building; ask before a paid probe; never full reads just to test. [src: memory no-spend-while-building] [src: memory feed-for-all-brands]\n16. Every treg call goes through `treg.js`; paid sources fall back to free ones; never repeat a call for data we hold. Load the `brew-external-data` skill before touching outside data. [src: brew/CLAUDE.md] [src: memory treg-usage-rules]\n17. Cost cuts never drop Plays; make each Play cheaper. [src: memory keep-all-moves]\n18. Every paid action shows its price and waits for a yes; nothing is paid twice (idempotency keys, make claims, saved job ids). [src: brew/jam2/studio.js:1-5] [src: brew/jobs.js:4-5]\n19. Paid background work runs only on the lease holder. [src: brew/roles.js:39]\n\n### Product shape\n\n20. Read only in v1: Brew never writes to a brand's accounts or sends to its customers. [src: brew/SCOPE.md]\n21. One version, then Redo it; never several options to pick from. [src: memory brew-one-version]\n22. Say Plays to people; ids, routes and files may keep \"move\". [src: memory brew-qa-round2-2026-10-24]\n\n### Shipping\n\n23. Run `AI_MOCK=1 node --test test/*.test.js`, boot locally, then deploy with `./deploy.sh` from a clean tree; deploy right after a change is tested so Param can test on staging. [src: brew/CLAUDE.md] [src: memory always-deploy-to-test]\n24. Commit only your own lines, push before deploying, deploy from a clean worktree of origin/main. [src: memory brew-parallel-sessions-deploy]\n25. Production only through `tools/promote.sh`. [src: brew/.wt-prod/docs/production.md]\n26. Phased work: a full QV round after each phase, three more before closing. [src: memory brew-qv-process]",
  "Tomorrow": "| Item | Version | Tag |\n|---|---|---|\n| All rules above | v1 | Stays |\n| Rule 20 (read only) | v3 | Changes: writes and sends arrive one at a time, each behind a person's yes |\n| A CI check for rules that code can test (no undeclared constants, Dummy markers in step) | v1 | New |",
  "How we do it": "1. Before a change, read `brew/CLAUDE.md`, `SCOPE.md` and `DUMMY.md` on origin/main.\n2. Before shipping, walk this list and say in the commit which rules the change touched.\n3. When a rule is broken, add the incident to the rule's source note and a guard test.",
  "Numbers": "| Metric | Definition | Where measured |\n|---|---|---|\n| Clean gate findings | Findings per promote | `brew-prod-clean` job logs |\n| Dummy markers in step | `DUMMY:` comments, UI tags and `DUMMY.md` rows that match | Proposed: a test that compares them (15 files carry `DUMMY:` today) [src: git grep \"DUMMY:\" origin/main] |\n| Per-brand patches | Commits naming one brand slug in code | Proposed: a grep in CI |",
  "Open": "1. **Should these rules be enforced in CI where possible?** Proposal: yes; start with the Dummy-marker check and a ban on brand slugs in code outside tests and data."
 }
}