buildanything 2.0.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +9 -1
  3. package/README.md +57 -61
  4. package/agents/a11y-architect.md +2 -0
  5. package/agents/briefing-officer.md +172 -0
  6. package/agents/business-model.md +14 -12
  7. package/agents/code-architect.md +6 -1
  8. package/agents/code-reviewer.md +3 -2
  9. package/agents/code-simplifier.md +12 -4
  10. package/agents/design-brand-guardian.md +19 -0
  11. package/agents/design-critic.md +16 -11
  12. package/agents/design-inclusive-visuals-specialist.md +2 -0
  13. package/agents/design-ui-designer.md +17 -0
  14. package/agents/design-ux-architect.md +15 -0
  15. package/agents/design-ux-researcher.md +102 -7
  16. package/agents/engineering-ai-engineer.md +2 -0
  17. package/agents/engineering-backend-architect.md +2 -0
  18. package/agents/engineering-data-engineer.md +2 -0
  19. package/agents/engineering-devops-automator.md +2 -0
  20. package/agents/engineering-frontend-developer.md +13 -0
  21. package/agents/engineering-mobile-app-builder.md +2 -0
  22. package/agents/engineering-rapid-prototyper.md +15 -2
  23. package/agents/engineering-security-engineer.md +2 -0
  24. package/agents/engineering-senior-developer.md +13 -0
  25. package/agents/engineering-sre.md +2 -0
  26. package/agents/engineering-technical-writer.md +2 -0
  27. package/agents/feature-intel.md +8 -7
  28. package/agents/ios-app-review-guardian.md +2 -0
  29. package/agents/ios-foundation-models-specialist.md +2 -0
  30. package/agents/ios-product-reality-auditor.md +292 -0
  31. package/agents/ios-storekit-specialist.md +2 -0
  32. package/agents/ios-swift-architect.md +1 -0
  33. package/agents/ios-swift-search.md +1 -0
  34. package/agents/ios-swift-ui-design.md +7 -4
  35. package/agents/marketing-app-store-optimizer.md +2 -0
  36. package/agents/planner.md +6 -1
  37. package/agents/pr-test-analyzer.md +3 -2
  38. package/agents/product-feedback-synthesizer.md +62 -0
  39. package/agents/product-owner.md +163 -0
  40. package/agents/product-reality-auditor.md +216 -0
  41. package/agents/product-spec-writer.md +176 -0
  42. package/agents/refactor-cleaner.md +9 -1
  43. package/agents/security-reviewer.md +2 -1
  44. package/agents/silent-failure-hunter.md +2 -1
  45. package/agents/swift-build-resolver.md +2 -0
  46. package/agents/swift-reviewer.md +2 -1
  47. package/agents/tech-feasibility.md +5 -3
  48. package/agents/testing-api-tester.md +2 -0
  49. package/agents/testing-evidence-collector.md +24 -0
  50. package/agents/testing-performance-benchmarker.md +2 -0
  51. package/agents/testing-reality-checker.md +2 -1
  52. package/agents/visual-research.md +7 -5
  53. package/bin/adapters/scribe-tool.ts +4 -2
  54. package/bin/adapters/write-lease-tool.ts +1 -1
  55. package/bin/buildanything-runtime.ts +20 -107
  56. package/bin/graph-index.js +24 -0
  57. package/bin/graph-index.ts +340 -0
  58. package/bin/mcp-servers/graph-mcp.js +26 -0
  59. package/bin/mcp-servers/graph-mcp.ts +481 -0
  60. package/bin/mcp-servers/orchestrator-mcp.js +26 -0
  61. package/bin/mcp-servers/orchestrator-mcp.ts +361 -0
  62. package/bin/setup.js +272 -111
  63. package/commands/build.md +424 -177
  64. package/commands/idea-sweep.md +2 -2
  65. package/commands/setup.md +15 -4
  66. package/commands/ux-review.md +3 -3
  67. package/commands/verify.md +3 -0
  68. package/docs/migration/phase-graph.yaml +573 -157
  69. package/hooks/design-md-lint +4 -0
  70. package/hooks/design-md-lint.ts +295 -0
  71. package/hooks/pre-tool-use.ts +37 -6
  72. package/hooks/record-mode-transitions.ts +63 -6
  73. package/hooks/subagent-start.ts +3 -2
  74. package/package.json +3 -1
  75. package/protocols/agent-prompt-authoring.md +165 -0
  76. package/protocols/architecture-schema.md +10 -3
  77. package/protocols/cleanup.md +4 -0
  78. package/protocols/decision-log.md +8 -4
  79. package/protocols/design-md-authoring.md +520 -0
  80. package/protocols/design-md-spec.md +362 -0
  81. package/protocols/fake-data-detector.md +1 -1
  82. package/protocols/ios-fake-data-detector.md +65 -0
  83. package/protocols/ios-phase-branches.md +128 -43
  84. package/protocols/launch-readiness.md +9 -5
  85. package/protocols/metric-loop.md +1 -1
  86. package/protocols/page-spec-schema.md +234 -0
  87. package/protocols/product-spec-schema.md +354 -0
  88. package/protocols/sprint-tasks-schema.md +53 -0
  89. package/protocols/state-schema.json +38 -3
  90. package/protocols/state-schema.md +32 -2
  91. package/protocols/verify.md +29 -1
  92. package/protocols/web-phase-branches.md +246 -76
  93. package/skills/ios/ios-bootstrap/SKILL.md +1 -1
  94. package/src/graph/ids.ts +86 -0
  95. package/src/graph/index.ts +32 -0
  96. package/src/graph/parser/architecture.ts +603 -0
  97. package/src/graph/parser/component-manifest.ts +268 -0
  98. package/src/graph/parser/decisions-jsonl.ts +407 -0
  99. package/src/graph/parser/design-md-pass2.ts +253 -0
  100. package/src/graph/parser/design-md.ts +477 -0
  101. package/src/graph/parser/page-spec.ts +496 -0
  102. package/src/graph/parser/product-spec.ts +930 -0
  103. package/src/graph/parser/screenshot.ts +342 -0
  104. package/src/graph/parser/sprint-tasks.ts +317 -0
  105. package/src/graph/storage/index.ts +1154 -0
  106. package/src/graph/types.ts +432 -0
  107. package/src/graph/util/dhash.ts +84 -0
  108. package/src/lrr/aggregator.ts +105 -10
  109. package/src/orchestrator/hooks/context-header.ts +34 -10
  110. package/src/orchestrator/hooks/token-accounting.ts +25 -14
  111. package/src/orchestrator/mcp/cycle-counter.ts +2 -1
  112. package/src/orchestrator/mcp/scribe.ts +27 -16
  113. package/src/orchestrator/mcp/write-lease.ts +30 -13
  114. package/src/orchestrator/phase4-shared-context.ts +20 -4
  115. package/protocols/visual-dna.md +0 -185
@@ -0,0 +1,520 @@
1
+ # DESIGN.md Authoring Protocol
2
+
3
+ `DESIGN.md` is the single design-system artifact for every web build. It replaces the prior `visual-dna.md` + `visual-design-spec.md` pair. The format is specified by `protocols/design-md-spec.md` (vendored from `google-labs-code/design.md` at a pinned commit). This protocol layers our pipeline contract on top of the spec — the two-pass authoring model, the DNA preservation rule, the lint gate, and the iOS component vocabulary.
4
+
5
+ Every Phase 3 design step and every Phase 4+ implementer reads `DESIGN.md`. If the file drifts, every downstream surface drifts with it. This protocol exists to make ownership, schema additions, and the gate behavior explicit.
6
+
7
+ ## 1. File location and ownership
8
+
9
+ **Canonical path:** `DESIGN.md` at the **repository root** (NOT under `docs/plans/`). Repo-root placement is required so external tools (Cursor, Claude Code, Antigravity, Gemini CLI) auto-load it as design context. Only this path is read.
10
+
11
+ **Two-pass authoring** — the file is built by two agents in two phases:
12
+
13
+ | Pass | Step | Agent | Writes |
14
+ |---|---|---|---|
15
+ | 1 | 3.0 | `design-brand-guardian` | Markdown body: `## Overview` (including `### Brand DNA` subsection) + `## Do's and Don'ts`. YAML front matter contains only `version: alpha` and `name`. All other sections present as headings with `<!-- Pass 2 — UI Designer -->` placeholders so the file lints (missing-sections is a warning, not an error). |
16
+ | 2 | 3.4 | `design-ui-designer` | Fills YAML front matter (`colors`, `typography`, `rounded`, `spacing`, `components`) AND writes the remaining prose sections: `## Colors`, `## Typography`, `## Layout`, `## Elevation & Depth`, `## Shapes`, `## Components`. |
17
+
18
+ Both agents Edit the same file; ordering is enforced by the phase graph (3.0 must complete before 3.4 dispatches). The writer-owner table in `docs/migration/phase-graph.yaml` registers `DESIGN.md` with both agents as legitimate writers.
19
+
20
+ **No other agent writes `DESIGN.md`.** Brand Guardian's Phase 5 drift check and Phase 6 LRR Brand Guardian chapter are READ-ONLY against this file.
21
+
22
+ ## 2. Schema additions (on top of the vendored spec)
23
+
24
+ The vendored spec (`protocols/design-md-spec.md`) defines the canonical sections, YAML schema, and linter rules. Our pipeline adds three structured constraints inside DESIGN.md that the spec leaves implicit:
25
+
26
+ ### 2.1 Required `### Brand DNA` subsection inside `## Overview`
27
+
28
+ `## Overview` MUST contain a `### Brand DNA` h3 subsection that lists the 7 locked DNA axes as a bullet list. The DESIGN.md linter treats unknown h3 subsections as preserve-not-error (per spec's "Consumer Behavior for Unknown Content" table), so this is schema-safe. Our pipeline depends on these values for: CONTEXT header injection (Phase 3+), Design Critic scoring (Step 3.6), Phase 5 brand drift check, Phase 6 LRR Brand Guardian chapter, and Phase 4 implementer dispatches.
29
+
30
+ ```markdown
31
+ ## Overview
32
+
33
+ <2-4 paragraph holistic brand description — personality, target audience, emotional response>
34
+
35
+ ### Brand DNA
36
+
37
+ - Scope: <Marketing | Product | Dashboard | Internal Tool>
38
+ - Density: <Airy | Balanced | Dense>
39
+ - Character: <Minimal | Editorial | Maximalist | Brutalist | Playful>
40
+ - Material: <Flat | Glassy | Physical | Neumorphic>
41
+ - Motion: <Still | Subtle | Expressive | Cinematic>
42
+ - Type: <Neutral Sans | Humanist Sans | Serif-forward | Display-forward | Mono-accented>
43
+ - Copy: <Functional | Narrative | Punchy | Technical>
44
+
45
+ ### Locked At
46
+
47
+ - locked_at: <ISO-8601 timestamp set exactly once at Step 3.0>
48
+ - locked_by: design-brand-guardian
49
+ - build_session: <session_id>
50
+
51
+ ### References
52
+
53
+ - <url or path> — exemplifies <axes>
54
+ - <url or path> — exemplifies <axes>
55
+ ```
56
+
57
+ The 7 axis values, the incompatibility matrix in §3, the anti-slop gates in §4, and the rationale rules below ALL preserve from the prior `visual-dna.md` protocol — the visual mechanics did not change, only the file format.
58
+
59
+ ### 2.2 YAML `name` and `description` derive from Overview
60
+
61
+ `name:` MUST match the brand identity declared in Overview (e.g. "Daylight Prestige"). `description:` MUST be a single sentence drawn from the Overview's first paragraph. This keeps tools that read the YAML standalone (export, diff, third-party tooling) consistent with the prose.
62
+
63
+ ### 2.3 Component naming follows DNA Material
64
+
65
+ When DNA Material = `Flat`, the `components:` block uses shadcn-aligned variant names (`button-primary`, `card`, `input`). When DNA Material = `Glassy`, names append the material register (`button-primary-glass`, `card-glass`). When DNA Material = `Physical`, names append elevation steps (`button-primary-elev-1`, `card-elev-2`). This is convention only — the linter does not enforce naming, but the Style Guide critic and Phase 4 implementers expect it.
66
+
67
+ ## 3. Incompatibility matrix
68
+
69
+ <HARD-GATE>
70
+ Brand Guardian is forbidden from locking any of the combinations below. If the user's references or design doc push toward an illegal combo, Brand Guardian picks the closest legal alternative and emits a decision-log row explaining the rejection.
71
+ </HARD-GATE>
72
+
73
+ | # | Illegal combination | Why |
74
+ |---|---|---|
75
+ | 1 | Dashboard + Cinematic motion | Dashboards need snappy feedback (100-200ms), not 650ms cinematic eases. Users lose their place. |
76
+ | 2 | Internal Tool + Maximalist character | Internal tools exist for fast parse; decoration-heavy styling buries the data users came for. |
77
+ | 3 | Internal Tool + Expressive or Cinematic motion | Internal tools ship at <200KB budget; framer-motion choreography + GSAP break that budget. |
78
+ | 4 | Marketing + Dense density | Marketing pages need breathing room to sell; dense kills scroll rhythm and conversion. |
79
+ | 5 | Dashboard + Glassy material + Dense density | Glass blur on dense data surfaces renders unreadable — the backdrop-filter eats legibility. |
80
+ | 6 | Dashboard + Serif-forward type | Dashboards need high-readability UI faces at small sizes; serifs lose clarity at 12-14px. |
81
+ | 7 | Product + Neumorphic material (with WCAG AA target) | Neumorphic shadows depend on low-contrast surfaces; AA contrast math fails by construction. |
82
+ | 8 | Brutalist character + Glassy material | Brutalism is raw, unapologetic, unadorned; glass is the opposite ethos. Visual contradiction. |
83
+ | 9 | Playful character + Still motion | Playful without motion reads as stiff and off-brand. Playful implies at least Subtle motion. |
84
+ | 10 | Marketing + Still motion | Marketing pages rely on scroll reveal and choreography to guide attention; Still kills that. |
85
+ | 11 | Internal Tool + Display-forward type | Display faces are for hero moments, not tool chrome. Clashes with fast-parse requirement. |
86
+ | 12 | Dashboard + Physical material | Heavy drop shadows on data grids add visual noise that competes with the chart ink. |
87
+ | 13 | Playful character + Technical copy | Playful implies approachable warmth; technical copy creates cognitive dissonance — the visual feel promises friendliness, the words deliver distance. |
88
+ | 14 | Brutalist character + Narrative copy | Brutalism is raw, direct, unapologetic; narrative copy is storytelling and emotional pull — the aesthetic actively rejects the storytelling register. |
89
+
90
+ Anything not on this list is legal. When two legal combinations both fit the user's references, Brand Guardian reads `quality-targets.json` and the architecture stack to resolve ties (e.g., if the stack is Next.js + shadcn default and quality-targets say "fast build," prefer Flat over Glassy).
91
+
92
+ ## 4. Anti-slop gates (Step 3.0 — Brand Guardian)
93
+
94
+ These gates fire at DNA lock time, before any design decisions are made. If the user's references or design doc push toward any item on these lists, Brand Guardian rejects it, picks the closest acceptable alternative, and emits a decision-log row naming the rejection.
95
+
96
+ ### 4.1 Font hard-ban
97
+
98
+ Never recommend in any role: Papyrus, Comic Sans, Lobster, Impact, Jokerman, Bleeding Cowboys, Permanent Marker, Bradley Hand, Brush Script, Hobo, Trajan, Raleway, Clash Display, Courier New (as body text).
99
+
100
+ ### 4.2 Font overuse-ban (never as primary)
101
+
102
+ Inter, Roboto, Arial, Helvetica, Open Sans, Lato, Montserrat, Poppins. Acceptable as secondary/utility faces when the primary is more distinctive. Not acceptable as the sole or headline typeface if non-generic output is the goal.
103
+
104
+ ### 4.3 AI-slop pattern ban
105
+
106
+ 1. Purple/violet/indigo gradients as default accent.
107
+ 2. 3-column feature grid with icons in colored circles.
108
+ 3. Centered everything with uniform spacing.
109
+ 4. Uniform bubbly border-radius on all elements.
110
+ 5. Gradient buttons as primary CTA.
111
+ 6. Decorative blobs, floating circles, wavy SVG dividers.
112
+ 7. Emoji as design elements.
113
+ 8. Colored left-border cards.
114
+ 9. Generic hero copy ("Welcome to [X]", "Unlock the power of...", "Your all-in-one solution for...").
115
+ 10. Cookie-cutter section rhythm (Hero → Features 3-col → Testimonials → Pricing → CTA).
116
+
117
+ ### 4.4 Copy axis validation
118
+
119
+ After locking the Copy axis value, validate any example headlines or microcopy in the design doc against the locked register. Functional → labels, no marketing language. Narrative → headlines read as story openings. Punchy → ≤5 word headlines, ≤3 word CTAs. Technical → exact vocabulary, no softeners.
120
+
121
+ ## 5. Pass 1 — Step 3.0 Brand Guardian
122
+
123
+ **Reads:** `docs/plans/product-spec.md` (App Overview, Screen Inventory, Permissions & Roles), `docs/plans/design-doc.md` (#persona, #scope, #voice), `docs/plans/phase1-scratch/findings-digest.md`, `docs/plans/architecture.md` (stack constraints), `docs/plans/quality-targets.json` (perf budget gates Motion/Material), `docs/plans/phase1-scratch/user-decisions.md`.
124
+
125
+ **Writes:** `DESIGN.md` (repo root) with this skeleton:
126
+
127
+ ```markdown
128
+ ---
129
+ version: alpha
130
+ name: <Brand Name>
131
+ ---
132
+
133
+ # <Brand Name>
134
+
135
+ ## Overview
136
+
137
+ <2-4 paragraph holistic brand description — personality, target audience, emotional response>
138
+
139
+ ### Brand DNA
140
+
141
+ - Scope: <value>
142
+ - Density: <value>
143
+ - Character: <value>
144
+ - Material: <value>
145
+ - Motion: <value>
146
+ - Type: <value>
147
+ - Copy: <value>
148
+
149
+ ### Rationale
150
+
151
+ <4-8 sentences citing design-doc.md sections + findings-digest signals that pushed each axis to its chosen value. No padding>
152
+
153
+ ### Locked At
154
+
155
+ - locked_at: <ISO-8601>
156
+ - locked_by: design-brand-guardian
157
+ - build_session: <session_id>
158
+
159
+ ### References
160
+
161
+ - <url or path> — exemplifies <axes>
162
+ - <url or path> — exemplifies <axes>
163
+
164
+ ## Colors
165
+
166
+ <!-- Pass 2 — UI Designer at Step 3.4 -->
167
+
168
+ ## Typography
169
+
170
+ <!-- Pass 2 — UI Designer at Step 3.4 -->
171
+
172
+ ## Layout
173
+
174
+ <!-- Pass 2 — UI Designer at Step 3.4 -->
175
+
176
+ ## Elevation & Depth
177
+
178
+ <!-- Pass 2 — UI Designer at Step 3.4 -->
179
+
180
+ ## Shapes
181
+
182
+ <!-- Pass 2 — UI Designer at Step 3.4 -->
183
+
184
+ ## Components
185
+
186
+ <!-- Pass 2 — UI Designer at Step 3.4 -->
187
+
188
+ ## Do's and Don'ts
189
+
190
+ - Do <rule from references + DNA>
191
+ - Don't <rule against AI-slop patterns or DNA contradictions>
192
+ - (4-10 bullets total)
193
+ ```
194
+
195
+ <HARD-GATE>
196
+ PASS 1 SCHEMA CONTRACT:
197
+
198
+ - All seven axis fields MUST be present and MUST be one of the allowed values from §3 enumeration.
199
+ - The combination across all seven axes MUST NOT appear in the §3 incompatibility matrix.
200
+ - `locked_at` is set exactly once and is never rewritten.
201
+ - `### References` MUST contain at least two entries, each tied to specific axis pairs. "Looks good" without axis attribution is not permitted.
202
+ - `## Do's and Don'ts` MUST contain at least 4 bullets — at least 2 Do, at least 2 Don't.
203
+ - All eight required `<h2>` sections MUST appear in the canonical order from the spec, even if Pass 2 sections are placeholders.
204
+ - The file MUST be at repo root. No other path is read.
205
+ </HARD-GATE>
206
+
207
+ ## 6. Pass 2 — Step 3.4 UI Designer
208
+
209
+ **Reads:** `DESIGN.md` (Pass 1 output), `docs/plans/component-manifest.md` (locked component picks), `docs/plans/ux-architecture.md`, `docs/plans/page-specs/*.md` (the wireframes the typography/spacing scale must work for), `docs/plans/design-references.md`, `docs/plans/product-spec.md` (per-feature States and Empty/Loading/Error States — the state matrix must cover every state the product spec defines).
210
+
211
+ **Writes:** Edits `DESIGN.md` to (a) fill YAML front matter and (b) replace Pass 2 placeholder sections with prose.
212
+
213
+ ### 6.1 YAML front matter — token shape
214
+
215
+ ```yaml
216
+ ---
217
+ version: alpha
218
+ name: <Brand Name>
219
+ description: <single sentence from Overview>
220
+ colors:
221
+ primary: "#..." # hex SRGB only
222
+ secondary: "#..."
223
+ tertiary: "#..." # optional
224
+ neutral: "#..." # optional
225
+ surface: "#..." # optional
226
+ on-surface: "#..." # optional
227
+ error: "#..." # optional
228
+ typography:
229
+ headline-display: # 9-15 levels typical; names follow spec's recommended set
230
+ fontFamily: <face>
231
+ fontSize: 48px # px / em / rem only
232
+ fontWeight: 700
233
+ lineHeight: 1.1 # unitless multiplier preferred
234
+ letterSpacing: -0.02em
235
+ body-md:
236
+ fontFamily: <face>
237
+ fontSize: 16px
238
+ fontWeight: 400
239
+ lineHeight: 1.6
240
+ # ... additional levels
241
+ rounded:
242
+ none: 0px
243
+ sm: 4px
244
+ md: 8px
245
+ lg: 12px
246
+ xl: 16px
247
+ full: 9999px
248
+ spacing:
249
+ xs: 4px
250
+ sm: 8px
251
+ md: 16px
252
+ lg: 32px
253
+ xl: 64px
254
+ gutter: 24px
255
+ margin: 32px
256
+ components:
257
+ button-primary:
258
+ backgroundColor: "{colors.primary}"
259
+ textColor: "{colors.on-surface}"
260
+ typography: "{typography.label-md}"
261
+ rounded: "{rounded.md}"
262
+ padding: "{spacing.md}"
263
+ button-primary-hover:
264
+ backgroundColor: "{colors.primary}"
265
+ # variants follow <base>-<state> naming per spec §Components > Variants
266
+ # ... at minimum: button-primary, input, card, nav for every project
267
+ ---
268
+ ```
269
+
270
+ Token references (`{colors.primary}`) MUST resolve. The linter's broken-ref rule is a hard-fail (see §8).
271
+
272
+ ### 6.2 Prose sections — required
273
+
274
+ Each Pass 2 section follows the vendored spec's example shape:
275
+
276
+ - `## Colors` — palette description tied to DNA Character axis. Cite contrast ratios where they motivate choices. Pass 2 fills semantic role for each token.
277
+ - `## Typography` — pairing rationale, role per level (headlines / body / labels / caption). Tracking tuning per size if DNA Type axis demands it (e.g. Editorial → eyebrow 11px uppercase +0.15em).
278
+ - `## Layout` — grid model + spacing scale. Tied to DNA Density axis (Airy = 32px gutters; Dense = 12-16px gutters; Balanced = 24px).
279
+ - `## Elevation & Depth` — material treatment per DNA Material axis. Flat = describe how hierarchy is conveyed without shadows. Glassy = blur radii, border rgba, surface opacity per variant. Physical = drop shadow specs (offset, blur, color). Neumorphic = inset/outset shadow pairs.
280
+ - `## Shapes` — radius scale + decorative shape rules. Cite DNA Character axis (Brutalist = 0px radius across the board; Playful = liberal use of `rounded.lg`+).
281
+ - `## Components` — narrative for the most important component types (buttons, inputs, cards, modals, lists, tooltips). YAML token block in §6.1 carries the machine-readable values.
282
+
283
+ ### 6.3 Motion and state matrix
284
+
285
+ The vendored spec has no `motion:` or component-state-matrix block. Our pipeline preserves both inside the prose and uses convention names in the `components:` YAML:
286
+
287
+ - **Motion** — write inside `## Components` or as an h3 inside `## Elevation & Depth`. Specify easings (cubic-bezier curves), duration clusters (fast / base / slow), scroll patterns, hover patterns, choreography notes — tuned to DNA Motion axis (Still=none, Subtle=200-300ms, Expressive=400-600ms, Cinematic=650-1100ms).
288
+ - **Component state matrix** — every interactive component needs `<base>`, `<base>-hover`, `<base>-focus`, `<base>-active`, `<base>-disabled`, `<base>-loading`, `<base>-error` in the YAML where relevant. Spec convention: `button-primary-hover: { backgroundColor: ... }` overrides only the changed properties from `button-primary`.
289
+
290
+ ## 7. Iteration discipline
291
+
292
+ **No revision after Pass 2 except via metric loop.** Step 3.6 (Style Guide Implementation) runs the design-critic loop and may surface findings that require re-tuning DESIGN.md. Re-tuning is allowed during the metric loop only and re-invokes `design-ui-designer` with a tight, finding-scoped prompt — NOT a full Pass 2 rewrite. The DNA axes (§2.1) are LOCKED by Pass 1 and never edited mid-build; a DNA revision is a new build session.
293
+
294
+ LRR backward routing per `docs/migration/phase-graph.yaml` re-entry rules: if the LRR Brand Guardian chapter routes a BLOCK back to Phase 3, the orchestrator re-opens the specific step named by `decision_row.author` (3.0 for DNA-level findings, 3.4 for token-level findings). Unaffected sections of DESIGN.md are not re-edited.
295
+
296
+ ## 8. Lint gate
297
+
298
+ After Pass 2 completes, the orchestrator runs:
299
+
300
+ ```bash
301
+ npx @google/design.md lint DESIGN.md
302
+ ```
303
+
304
+ Linter rules (per vendored spec):
305
+
306
+ | Rule | Severity | Pipeline behavior |
307
+ |---|---|---|
308
+ | broken-ref | error | HARD FAIL — Step 3.4 must re-dispatch with the broken ref as the focused finding |
309
+ | missing-primary | warn | Logged to `docs/plans/build-log.md` Phase 3 Step 3.4 entry; allowed to pass |
310
+ | contrast-ratio (WCAG AA) | warn | Logged; Phase 3.7 a11y review may escalate to BLOCK |
311
+ | orphaned-tokens | warn | Logged; pruning is a Phase 5 hardening-loop concern |
312
+ | missing-typography | warn | Logged |
313
+ | section-order | warn | Logged; Pass 2 must produce sections in canonical order from the spec |
314
+ | token-summary | info | Logged |
315
+ | missing-sections | info | Logged; Pass 1 placeholders satisfy this rule once Pass 2 fills them |
316
+
317
+ Broken-refs is the only hard-fail. Warnings accumulate in the build log and feed the Phase 3.8 gate summary, but do not block Phase 4. The lint hook is invoked at Phase 3 Step 3.8 (Autonomous Quality Gate) — see `hooks/design-md-lint.ts`.
318
+
319
+ ## 9. iOS DESIGN.md (Phase B)
320
+
321
+ The same DESIGN.md format applies to iOS builds. The 7-axis Brand DNA, two-pass authoring, and lint gate are unchanged. iOS specifics live in this section.
322
+
323
+ ### 9.1 Authoring agents
324
+
325
+ iOS uses a single Pass 2 author rather than the web's `design-ui-designer`. The dispatch table:
326
+
327
+ | Pass | Step | Agent | Writes |
328
+ |---|---|---|---|
329
+ | 1 | 3.0 | `design-brand-guardian` | Markdown body (Overview + Brand DNA + Do's and Don'ts), shared with web. iOS-specific anti-slop guidance inline in §4. |
330
+ | 2 | 3.2-ios | `ios-swift-ui-design` | YAML front matter + Pass 2 prose. Replaces the prior `ios-design-board.md` artifact entirely. |
331
+
332
+ `ios-swift-ui-design` is the only iOS Pass 2 writer. The visual QA loop at Step 3.4-ios uses it as the generator (Preview tweaks) paired with `design-critic` as the critic — same pattern as web Step 3.6, just measuring against SwiftUI Preview captures instead of Playwright screenshots.
333
+
334
+ ### 9.2 iOS-specific YAML conventions
335
+
336
+ The vendored spec is platform-agnostic. iOS authoring layers these conventions on top — they are NOT linter-enforced (the linter doesn't know about iOS), but downstream agents and the SwiftUI translator depend on them.
337
+
338
+ **Colors** — every color token has a paired `-dark` token for dark-mode UITraitCollection. Authoring example:
339
+ ```yaml
340
+ colors:
341
+ primary: "#1A1C1E"
342
+ primary-dark: "#F2F4F6"
343
+ surface: "#FFFFFF"
344
+ surface-dark: "#0B0B0C"
345
+ on-surface: "#1A1C1E"
346
+ on-surface-dark: "#F2F4F6"
347
+ ```
348
+ The translator emits a single `Color("primary")` that resolves through Asset Catalog with both appearances. Authors who skip the `-dark` pair get a contrast warning at Step 3.7.
349
+
350
+ **Typography** — name tokens after iOS Dynamic Type roles, not display sizes. The roles map directly to `Font.TextStyle`:
351
+ ```yaml
352
+ typography:
353
+ largeTitle: { fontFamily: SF Pro Display, fontSize: 34px, fontWeight: 700, lineHeight: 1.2 }
354
+ title: { fontFamily: SF Pro Display, fontSize: 28px, fontWeight: 700, lineHeight: 1.2 }
355
+ title2: { fontFamily: SF Pro Display, fontSize: 22px, fontWeight: 600, lineHeight: 1.2 }
356
+ title3: { fontFamily: SF Pro Text, fontSize: 20px, fontWeight: 600, lineHeight: 1.2 }
357
+ headline: { fontFamily: SF Pro Text, fontSize: 17px, fontWeight: 600, lineHeight: 1.3 }
358
+ body: { fontFamily: SF Pro Text, fontSize: 17px, fontWeight: 400, lineHeight: 1.4 }
359
+ callout: { fontFamily: SF Pro Text, fontSize: 16px, fontWeight: 400, lineHeight: 1.4 }
360
+ subheadline: { fontFamily: SF Pro Text, fontSize: 15px, fontWeight: 400, lineHeight: 1.4 }
361
+ footnote: { fontFamily: SF Pro Text, fontSize: 13px, fontWeight: 400, lineHeight: 1.3 }
362
+ caption: { fontFamily: SF Pro Text, fontSize: 12px, fontWeight: 400, lineHeight: 1.3 }
363
+ caption2: { fontFamily: SF Pro Text, fontSize: 11px, fontWeight: 400, lineHeight: 1.3 }
364
+ ```
365
+ Token names that match a Dynamic Type role get a `Font.TextStyle` (which scales with the user's accessibility setting). Custom names that don't match emit a fixed-size Font, breaking accessibility — Step 3.7 will flag those.
366
+
367
+ **Spacing** — iOS uses HIG's 4 / 8 / 16 / 20 / 24 progression (`xs: 4 / sm: 8 / md: 16 / lg: 20 / xl: 24 / xxl: 32`). The translator emits these as `CGFloat` constants. Use `safeArea`, `gutter`, and `margin` named tokens for layout anchors.
368
+
369
+ **Rounded** — iOS prefers `continuous` corner curves on iOS 13+. The translator emits `RoundedRectangle(cornerRadius: X, style: .continuous)`. Token names follow the web convention (`sm / md / lg / xl / full`).
370
+
371
+ ### 9.3 Required iOS components vocabulary
372
+
373
+ The `components:` block MUST cover at minimum these slots (additional components are encouraged):
374
+
375
+ ```yaml
376
+ components:
377
+ # Navigation
378
+ nav-tab-bar: { backgroundColor: "{colors.surface}", textColor: "{colors.on-surface}" }
379
+ nav-stack-bar: { backgroundColor: "{colors.surface}", textColor: "{colors.on-surface}" }
380
+ nav-large-title: { textColor: "{colors.on-surface}", typography: "{typography.largeTitle}" }
381
+
382
+ # Lists / cards
383
+ list-row: { backgroundColor: "{colors.surface}", textColor: "{colors.on-surface}", padding: "{spacing.md}" }
384
+ list-row-grouped: { backgroundColor: "{colors.surface}", rounded: "{rounded.md}" }
385
+ list-row-inset: { backgroundColor: "{colors.surface}", padding: "{spacing.lg}" }
386
+ card-elevated: { backgroundColor: "{colors.surface}", rounded: "{rounded.lg}", padding: "{spacing.md}" }
387
+ card-bordered: { backgroundColor: "{colors.surface}", rounded: "{rounded.md}", padding: "{spacing.md}" }
388
+ # iOS 26+ Liquid Glass — use only when DNA Material = Glassy AND build targets iOS 26+
389
+ card-glass: { backgroundColor: "{colors.surface}", rounded: "{rounded.lg}" }
390
+
391
+ # Buttons (HIG primary / secondary / tertiary; iOS 26+ tinted)
392
+ button-primary: { backgroundColor: "{colors.primary}", textColor: "{colors.surface}", typography: "{typography.headline}", padding: "{spacing.md}", rounded: "{rounded.md}" }
393
+ button-primary-pressed: { backgroundColor: "{colors.primary}" } # 90% opacity applied by translator
394
+ button-primary-disabled: { backgroundColor: "{colors.primary}" } # 40% opacity applied by translator
395
+ button-secondary: { backgroundColor: "{colors.surface}", textColor: "{colors.primary}", typography: "{typography.headline}", padding: "{spacing.md}", rounded: "{rounded.md}" }
396
+ button-tertiary: { backgroundColor: "{colors.surface}", textColor: "{colors.primary}", typography: "{typography.headline}", padding: "{spacing.sm}" }
397
+ # iOS 26+ only
398
+ button-tinted: { backgroundColor: "{colors.primary}", textColor: "{colors.primary}" }
399
+
400
+ # Inputs
401
+ input-text: { backgroundColor: "{colors.surface}", textColor: "{colors.on-surface}", typography: "{typography.body}", padding: "{spacing.md}", rounded: "{rounded.md}" }
402
+ input-search: { backgroundColor: "{colors.surface}", typography: "{typography.body}", padding: "{spacing.sm}" }
403
+ input-stepper: { backgroundColor: "{colors.surface}", textColor: "{colors.on-surface}", typography: "{typography.body}" }
404
+ input-toggle: { backgroundColor: "{colors.primary}" } # tint color when on
405
+
406
+ # Containers
407
+ sheet-modal: { backgroundColor: "{colors.surface}", rounded: "{rounded.lg}" }
408
+ sheet-presented: { backgroundColor: "{colors.surface}" }
409
+ popover: { backgroundColor: "{colors.surface}", rounded: "{rounded.md}", padding: "{spacing.md}" }
410
+ ```
411
+
412
+ The same `<base>-<state>` variant convention applies. State suffixes for iOS: `-pressed` (corresponds to SwiftUI `pressed` state via `.buttonStyle`), `-disabled`, `-selected`, `-focused`. Hover does NOT exist on touch — do not author `-hover` variants for iOS.
413
+
414
+ ### 9.4 SwiftUI translator (Phase 4 reference)
415
+
416
+ Phase 4's iOS scaffold step (`Step 4.0.b`) reads `DESIGN.md` and emits a Swift file that exposes the tokens as Swift extensions. The translator is part of the implementer's prompt — it is NOT a separate generated artifact, and it is NOT vendored. Implementers reference this template:
417
+
418
+ ```swift
419
+ // DesignTokens.swift — generated from DESIGN.md at <commit-sha>. Do not edit by hand.
420
+ // Re-run the iOS design tokens setup task to regenerate after DESIGN.md changes.
421
+
422
+ import SwiftUI
423
+
424
+ extension Color {
425
+ // Asset Catalog colors with light + dark appearances per DESIGN.md `colors:` block.
426
+ // Each token requires a paired `-dark` entry in DESIGN.md to populate the dark appearance.
427
+ static let primary = Color("primary")
428
+ static let surface = Color("surface")
429
+ static let onSurface = Color("on-surface")
430
+ static let neutral = Color("neutral")
431
+ static let error = Color("error")
432
+ // ... one per `colors:` token
433
+ }
434
+
435
+ extension Font {
436
+ // Dynamic Type roles map to SwiftUI Font.TextStyle.
437
+ // Tokens whose name matches a TextStyle scale with the user's text-size setting.
438
+ static let largeTitle = Font.system(.largeTitle, design: .default).weight(.bold)
439
+ static let title = Font.system(.title, design: .default).weight(.bold)
440
+ static let title2 = Font.system(.title2, design: .default).weight(.semibold)
441
+ static let title3 = Font.system(.title3, design: .default).weight(.semibold)
442
+ static let headline = Font.system(.headline, design: .default).weight(.semibold)
443
+ static let body = Font.system(.body, design: .default)
444
+ static let callout = Font.system(.callout, design: .default)
445
+ static let subheadline = Font.system(.subheadline, design: .default)
446
+ static let footnote = Font.system(.footnote, design: .default)
447
+ static let caption = Font.system(.caption, design: .default)
448
+ static let caption2 = Font.system(.caption2, design: .default)
449
+ // Custom font tokens (those not matching a TextStyle role) emit fixed-size Fonts.
450
+ // These do NOT scale with Dynamic Type — Step 3.7 will flag accessibility risk.
451
+ }
452
+
453
+ enum Spacing {
454
+ // Spacing scale per DESIGN.md `spacing:` block. CGFloat constants.
455
+ static let xs: CGFloat = 4
456
+ static let sm: CGFloat = 8
457
+ static let md: CGFloat = 16
458
+ static let lg: CGFloat = 20
459
+ static let xl: CGFloat = 24
460
+ static let xxl: CGFloat = 32
461
+ static let gutter: CGFloat = 16
462
+ static let margin: CGFloat = 20
463
+ }
464
+
465
+ enum Radius {
466
+ // Use with RoundedRectangle(cornerRadius: Radius.md, style: .continuous).
467
+ static let sm: CGFloat = 4
468
+ static let md: CGFloat = 8
469
+ static let lg: CGFloat = 12
470
+ static let xl: CGFloat = 16
471
+ static let full: CGFloat = 9999
472
+ }
473
+ ```
474
+
475
+ The implementer also creates `Resources/Assets.xcassets` color set entries — one per `colors:` token, with the `-dark` variant populating the Dark appearance slot. Component tokens (`button-primary`, `card-elevated`, etc.) are NOT translated to Swift directly; they are applied via SwiftUI view modifiers (`.background(Color.primary)`, `.font(.headline)`, `.cornerRadius(Radius.md)`) inside per-screen views. The token YAML is the contract; the translator output is the toolkit; the views compose them.
476
+
477
+ ### 9.5 iOS lint behavior
478
+
479
+ The vendored linter runs unchanged on iOS DESIGN.md. Three iOS-specific behaviors layer on top:
480
+
481
+ 1. **Dark-pair rule** (warn, advisory) — the orchestrator post-processes lint results and warns when a `colors:` token lacks a `-dark` pair. Not in the vendored linter; logged to `build-log.md` Step 3.8 alongside the lint output.
482
+ 2. **Dynamic Type role check** (warn, advisory) — same post-process step warns when a `typography:` token name does not match a known `Font.TextStyle` role. Custom names are allowed but accessibility-flagged.
483
+ 3. **iOS 26 gating** (info) — when the DNA Material axis is `Glassy` AND the build's `ios_features` include iOS 26 targets, the orchestrator confirms `card-glass` and `button-tinted` variants exist. When DNA Material is anything else, those variants must be absent.
484
+
485
+ These post-process checks live in `hooks/design-md-lint.ts` (web codepath unaffected; iOS codepath gated on `project_type=ios` in `.build-state.json`).
486
+
487
+ ## 10. Readers (downstream pipeline)
488
+
489
+ Every Phase 3+ agent that needs visual context reads `DESIGN.md` (the relevant subset, not the whole file):
490
+
491
+ | Phase / Step | Agent | Reads |
492
+ |---|---|---|
493
+ | 3.1 | visual-research | `## Overview` (incl. `### Brand DNA`) — to frame reference queries around the chosen axes |
494
+ | 3.2 | design-ui-designer (Component Manifest) | `## Overview` + reference paths from `### References` — picks library variants matching DNA |
495
+ | 3.2b | design-ux-researcher (DNA Persona Check) | `## Overview` (full) — validates DNA against persona/JTBD |
496
+ | 3.3 | design-ux-architect | `## Overview` (Density axis drives spatial decisions; Character/Motion shape interaction patterns) |
497
+ | 3.3b | design-ux-researcher (UX Flow Validation) | `## Overview` (full) |
498
+ | 3.4 | design-ui-designer | Reads its own Pass 1 output; writes Pass 2 |
499
+ | 3.5 | design-inclusive-visuals-specialist | `## Overview` + `## Colors` + `## Typography` (a11y risk surfaces) |
500
+ | 3.6 | engineering-frontend-developer (generator) | YAML front matter + every section (compositional source) |
501
+ | 3.6 | design-critic | `## Overview` (DNA scoring) + YAML tokens + `## Components` (compositional check) + `## Do's and Don'ts` (anti-slop scoring) |
502
+ | 3.7 | a11y-architect | `## Colors` + `## Typography` + YAML `components:` (focus state, contrast) |
503
+ | 4 | every implementer | YAML front matter via `refs.json` primary anchor — NOT the full file. Implementers Read individual sections on demand |
504
+ | 5 | testing-performance-benchmarker | `## Overview` (Scope axis → bundle budget) |
505
+ | 5 | design-brand-guardian (drift check) | `## Overview` (DNA values) + Playwright screenshots — scores drift against locked DNA |
506
+ | 5 | design-ux-researcher (audit) | `## Overview` + YAML `components:` — visual consistency check |
507
+ | 6 | LRR Brand Guardian chapter | `## Overview` + YAML tokens + Playwright evidence — final verdict pass |
508
+
509
+ **CONTEXT header injection (Phase 3+):** the orchestrator extracts the 7 axis values from `### Brand DNA` (NOT the full file) and inlines them into the dispatch CONTEXT header. ~100 tokens, not ~5K. See `protocols/web-phase-branches.md` CONTEXT header section.
510
+
511
+ ## 11. Schema-contract enforcement order
512
+
513
+ When `DESIGN.md` is read by any agent and any of these is true, the agent halts and emits a finding instead of producing output:
514
+
515
+ 1. The file does not exist at repo root.
516
+ 2. `## Overview > ### Brand DNA` block is missing or has fewer than 7 axis bullets.
517
+ 3. The 7-axis combination matches a row in §3 incompatibility matrix.
518
+ 4. The file fails the broken-ref linter rule.
519
+
520
+ Findings 2-4 route back to Step 3.0 (axis-related) or Step 3.4 (token-related) per the decision_row.author convention.