aw-ecc 1.4.32 → 1.4.48

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 (259) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.cursor/INSTALL.md +7 -5
  3. package/.cursor/hooks/adapter.js +41 -4
  4. package/.cursor/hooks/after-agent-response.js +62 -0
  5. package/.cursor/hooks/before-submit-prompt.js +7 -1
  6. package/.cursor/hooks/post-tool-use-failure.js +21 -0
  7. package/.cursor/hooks/post-tool-use.js +39 -0
  8. package/.cursor/hooks/shared/aw-phase-definitions.js +53 -0
  9. package/.cursor/hooks/shared/aw-phase-runner.js +3 -1
  10. package/.cursor/hooks/subagent-start.js +22 -4
  11. package/.cursor/hooks/subagent-stop.js +18 -1
  12. package/.cursor/hooks.json +23 -2
  13. package/.opencode/package.json +1 -1
  14. package/AGENTS.md +3 -3
  15. package/README.md +5 -5
  16. package/commands/adk.md +52 -0
  17. package/commands/build.md +22 -9
  18. package/commands/deploy.md +12 -0
  19. package/commands/execute.md +9 -0
  20. package/commands/feature.md +333 -0
  21. package/commands/investigate.md +18 -5
  22. package/commands/plan.md +23 -9
  23. package/commands/publish.md +65 -0
  24. package/commands/review.md +12 -0
  25. package/commands/ship.md +12 -0
  26. package/commands/test.md +12 -0
  27. package/commands/verify.md +9 -0
  28. package/hooks/hooks.json +36 -0
  29. package/manifests/install-components.json +8 -0
  30. package/manifests/install-modules.json +83 -0
  31. package/manifests/install-profiles.json +7 -0
  32. package/package.json +2 -2
  33. package/scripts/ci/validate-rules.js +51 -0
  34. package/scripts/cursor-aw-home/hooks.json +23 -2
  35. package/scripts/cursor-aw-hooks/adapter.js +41 -4
  36. package/scripts/cursor-aw-hooks/before-submit-prompt.js +7 -1
  37. package/scripts/hooks/aw-usage-commit-created.js +32 -0
  38. package/scripts/hooks/aw-usage-post-tool-use-failure.js +56 -0
  39. package/scripts/hooks/aw-usage-post-tool-use.js +242 -0
  40. package/scripts/hooks/aw-usage-prompt-submit.js +112 -0
  41. package/scripts/hooks/aw-usage-session-start.js +48 -0
  42. package/scripts/hooks/aw-usage-stop.js +182 -0
  43. package/scripts/hooks/aw-usage-telemetry-send.js +84 -0
  44. package/scripts/hooks/cost-tracker.js +3 -23
  45. package/scripts/hooks/shared/aw-phase-definitions.js +53 -0
  46. package/scripts/hooks/shared/aw-phase-runner.js +3 -1
  47. package/scripts/lib/aw-hook-contract.js +2 -2
  48. package/scripts/lib/aw-pricing.js +306 -0
  49. package/scripts/lib/aw-usage-telemetry.js +472 -0
  50. package/scripts/lib/codex-hook-config.js +8 -8
  51. package/scripts/lib/cursor-hook-config.js +25 -10
  52. package/scripts/lib/install-targets/cursor-project.js +3 -0
  53. package/scripts/lib/install-targets/helpers.js +20 -3
  54. package/skills/aw-adk/SKILL.md +317 -0
  55. package/skills/aw-adk/agents/analyzer.md +113 -0
  56. package/skills/aw-adk/agents/comparator.md +113 -0
  57. package/skills/aw-adk/agents/grader.md +115 -0
  58. package/skills/aw-adk/assets/eval_review.html +76 -0
  59. package/skills/aw-adk/eval-viewer/generate_review.py +164 -0
  60. package/skills/aw-adk/eval-viewer/viewer.html +181 -0
  61. package/skills/aw-adk/evals/eval-colocated-placement.md +84 -0
  62. package/skills/aw-adk/evals/eval-create-agent.md +90 -0
  63. package/skills/aw-adk/evals/eval-create-command.md +98 -0
  64. package/skills/aw-adk/evals/eval-create-eval.md +89 -0
  65. package/skills/aw-adk/evals/eval-create-rule.md +99 -0
  66. package/skills/aw-adk/evals/eval-create-skill.md +97 -0
  67. package/skills/aw-adk/evals/eval-delete-agent.md +79 -0
  68. package/skills/aw-adk/evals/eval-delete-command.md +89 -0
  69. package/skills/aw-adk/evals/eval-delete-rule.md +86 -0
  70. package/skills/aw-adk/evals/eval-delete-skill.md +90 -0
  71. package/skills/aw-adk/evals/eval-meta-eval-coverage.md +78 -0
  72. package/skills/aw-adk/evals/eval-meta-eval-determinism.md +81 -0
  73. package/skills/aw-adk/evals/eval-meta-eval-false-pass.md +81 -0
  74. package/skills/aw-adk/evals/eval-score-accuracy.md +95 -0
  75. package/skills/aw-adk/evals/eval-type-redirect.md +68 -0
  76. package/skills/aw-adk/evals/evals.json +96 -0
  77. package/skills/aw-adk/references/artifact-wiring.md +162 -0
  78. package/skills/aw-adk/references/cross-ide-mapping.md +71 -0
  79. package/skills/aw-adk/references/eval-placement-guide.md +183 -0
  80. package/skills/aw-adk/references/external-resources.md +75 -0
  81. package/skills/aw-adk/references/getting-started.md +66 -0
  82. package/skills/aw-adk/references/registry-structure.md +152 -0
  83. package/skills/aw-adk/references/rubric-agent.md +36 -0
  84. package/skills/aw-adk/references/rubric-command.md +36 -0
  85. package/skills/aw-adk/references/rubric-eval.md +36 -0
  86. package/skills/aw-adk/references/rubric-meta-eval.md +132 -0
  87. package/skills/aw-adk/references/rubric-rule.md +36 -0
  88. package/skills/aw-adk/references/rubric-skill.md +36 -0
  89. package/skills/aw-adk/references/schemas.md +222 -0
  90. package/skills/aw-adk/references/template-agent.md +251 -0
  91. package/skills/aw-adk/references/template-command.md +279 -0
  92. package/skills/aw-adk/references/template-eval.md +176 -0
  93. package/skills/aw-adk/references/template-rule.md +119 -0
  94. package/skills/aw-adk/references/template-skill.md +123 -0
  95. package/skills/aw-adk/references/type-classifier.md +98 -0
  96. package/skills/aw-adk/references/writing-good-agents.md +227 -0
  97. package/skills/aw-adk/references/writing-good-commands.md +258 -0
  98. package/skills/aw-adk/references/writing-good-evals.md +271 -0
  99. package/skills/aw-adk/references/writing-good-rules.md +214 -0
  100. package/skills/aw-adk/references/writing-good-skills.md +159 -0
  101. package/skills/aw-adk/scripts/aggregate-benchmark.py +190 -0
  102. package/skills/aw-adk/scripts/lint-artifact.sh +211 -0
  103. package/skills/aw-adk/scripts/score-artifact.sh +179 -0
  104. package/skills/aw-adk/scripts/trigger-eval.py +192 -0
  105. package/skills/aw-build/SKILL.md +19 -2
  106. package/skills/aw-deploy/SKILL.md +65 -3
  107. package/skills/aw-design/SKILL.md +156 -0
  108. package/skills/aw-design/references/highrise-tokens.md +394 -0
  109. package/skills/aw-design/references/micro-interactions.md +76 -0
  110. package/skills/aw-design/references/prompt-template.md +160 -0
  111. package/skills/aw-design/references/quality-checklist.md +70 -0
  112. package/skills/aw-design/references/self-review.md +497 -0
  113. package/skills/aw-design/references/stitch-workflow.md +127 -0
  114. package/skills/aw-feature/SKILL.md +293 -0
  115. package/skills/aw-investigate/SKILL.md +17 -0
  116. package/skills/aw-plan/SKILL.md +34 -3
  117. package/skills/aw-publish/SKILL.md +300 -0
  118. package/skills/aw-publish/evals/eval-confirmation-gate.md +60 -0
  119. package/skills/aw-publish/evals/eval-intent-detection.md +111 -0
  120. package/skills/aw-publish/evals/eval-push-modes.md +67 -0
  121. package/skills/aw-publish/evals/eval-rules-push.md +60 -0
  122. package/skills/aw-publish/evals/evals.json +29 -0
  123. package/skills/aw-publish/references/push-modes.md +38 -0
  124. package/skills/aw-review/SKILL.md +88 -9
  125. package/skills/aw-rules-review/SKILL.md +124 -0
  126. package/skills/aw-rules-review/agents/openai.yaml +3 -0
  127. package/skills/aw-rules-review/scripts/generate-review-template.mjs +323 -0
  128. package/skills/aw-ship/SKILL.md +16 -0
  129. package/skills/aw-spec/SKILL.md +15 -0
  130. package/skills/aw-tasks/SKILL.md +15 -0
  131. package/skills/aw-test/SKILL.md +16 -0
  132. package/skills/aw-yolo/SKILL.md +4 -0
  133. package/skills/diagnose/SKILL.md +121 -0
  134. package/skills/diagnose/scripts/hitl-loop.template.sh +41 -0
  135. package/skills/finish-only-when-green/SKILL.md +265 -0
  136. package/skills/grill-me/SKILL.md +24 -0
  137. package/skills/grill-with-docs/SKILL.md +92 -0
  138. package/skills/grill-with-docs/adr-format.md +47 -0
  139. package/skills/grill-with-docs/context-format.md +67 -0
  140. package/skills/improve-codebase-architecture/SKILL.md +75 -0
  141. package/skills/improve-codebase-architecture/deepening.md +37 -0
  142. package/skills/improve-codebase-architecture/interface-design.md +44 -0
  143. package/skills/improve-codebase-architecture/language.md +53 -0
  144. package/skills/local-ghl-setup-from-screenshot/SKILL.md +538 -0
  145. package/skills/tdd/SKILL.md +115 -0
  146. package/skills/tdd/deep-modules.md +33 -0
  147. package/skills/tdd/interface-design.md +31 -0
  148. package/skills/tdd/mocking.md +59 -0
  149. package/skills/tdd/refactoring.md +10 -0
  150. package/skills/tdd/tests.md +61 -0
  151. package/skills/to-issues/SKILL.md +62 -0
  152. package/skills/to-prd/SKILL.md +75 -0
  153. package/skills/using-aw-skills/SKILL.md +170 -237
  154. package/skills/using-aw-skills/hooks/session-start.sh +11 -41
  155. package/skills/zoom-out/SKILL.md +24 -0
  156. package/.codex/hooks/aw-post-tool-use.sh +0 -6
  157. package/.codex/hooks/aw-pre-tool-use.sh +0 -6
  158. package/.codex/hooks/aw-session-start.sh +0 -25
  159. package/.codex/hooks/aw-stop.sh +0 -6
  160. package/.codex/hooks/aw-user-prompt-submit.sh +0 -10
  161. package/.codex/hooks.json +0 -62
  162. package/.cursor/rules/common-agents.md +0 -53
  163. package/.cursor/rules/common-aw-routing.md +0 -43
  164. package/.cursor/rules/common-coding-style.md +0 -52
  165. package/.cursor/rules/common-development-workflow.md +0 -33
  166. package/.cursor/rules/common-git-workflow.md +0 -28
  167. package/.cursor/rules/common-hooks.md +0 -34
  168. package/.cursor/rules/common-patterns.md +0 -35
  169. package/.cursor/rules/common-performance.md +0 -59
  170. package/.cursor/rules/common-security.md +0 -33
  171. package/.cursor/rules/common-testing.md +0 -33
  172. package/.cursor/skills/api-and-interface-design/SKILL.md +0 -75
  173. package/.cursor/skills/article-writing/SKILL.md +0 -85
  174. package/.cursor/skills/aw-brainstorm/SKILL.md +0 -115
  175. package/.cursor/skills/aw-build/SKILL.md +0 -152
  176. package/.cursor/skills/aw-build/evals/build-stage-cases.json +0 -28
  177. package/.cursor/skills/aw-debug/SKILL.md +0 -49
  178. package/.cursor/skills/aw-deploy/SKILL.md +0 -101
  179. package/.cursor/skills/aw-deploy/evals/deploy-stage-cases.json +0 -32
  180. package/.cursor/skills/aw-execute/SKILL.md +0 -47
  181. package/.cursor/skills/aw-execute/references/mode-code.md +0 -47
  182. package/.cursor/skills/aw-execute/references/mode-docs.md +0 -28
  183. package/.cursor/skills/aw-execute/references/mode-infra.md +0 -44
  184. package/.cursor/skills/aw-execute/references/mode-migration.md +0 -58
  185. package/.cursor/skills/aw-execute/references/worker-implementer.md +0 -26
  186. package/.cursor/skills/aw-execute/references/worker-parallel-worker.md +0 -23
  187. package/.cursor/skills/aw-execute/references/worker-quality-reviewer.md +0 -23
  188. package/.cursor/skills/aw-execute/references/worker-spec-reviewer.md +0 -23
  189. package/.cursor/skills/aw-execute/scripts/build-worker-bundle.js +0 -229
  190. package/.cursor/skills/aw-finish/SKILL.md +0 -111
  191. package/.cursor/skills/aw-investigate/SKILL.md +0 -109
  192. package/.cursor/skills/aw-plan/SKILL.md +0 -368
  193. package/.cursor/skills/aw-prepare/SKILL.md +0 -118
  194. package/.cursor/skills/aw-review/SKILL.md +0 -118
  195. package/.cursor/skills/aw-ship/SKILL.md +0 -115
  196. package/.cursor/skills/aw-spec/SKILL.md +0 -104
  197. package/.cursor/skills/aw-tasks/SKILL.md +0 -138
  198. package/.cursor/skills/aw-test/SKILL.md +0 -118
  199. package/.cursor/skills/aw-verify/SKILL.md +0 -51
  200. package/.cursor/skills/aw-yolo/SKILL.md +0 -111
  201. package/.cursor/skills/browser-testing-with-devtools/SKILL.md +0 -81
  202. package/.cursor/skills/bun-runtime/SKILL.md +0 -84
  203. package/.cursor/skills/ci-cd-and-automation/SKILL.md +0 -71
  204. package/.cursor/skills/code-simplification/SKILL.md +0 -74
  205. package/.cursor/skills/content-engine/SKILL.md +0 -88
  206. package/.cursor/skills/context-engineering/SKILL.md +0 -74
  207. package/.cursor/skills/deprecation-and-migration/SKILL.md +0 -75
  208. package/.cursor/skills/documentation-and-adrs/SKILL.md +0 -75
  209. package/.cursor/skills/documentation-lookup/SKILL.md +0 -90
  210. package/.cursor/skills/frontend-slides/SKILL.md +0 -184
  211. package/.cursor/skills/frontend-slides/STYLE_PRESETS.md +0 -330
  212. package/.cursor/skills/frontend-ui-engineering/SKILL.md +0 -68
  213. package/.cursor/skills/git-workflow-and-versioning/SKILL.md +0 -75
  214. package/.cursor/skills/idea-refine/SKILL.md +0 -84
  215. package/.cursor/skills/incremental-implementation/SKILL.md +0 -75
  216. package/.cursor/skills/investor-materials/SKILL.md +0 -96
  217. package/.cursor/skills/investor-outreach/SKILL.md +0 -76
  218. package/.cursor/skills/market-research/SKILL.md +0 -75
  219. package/.cursor/skills/mcp-server-patterns/SKILL.md +0 -67
  220. package/.cursor/skills/nextjs-turbopack/SKILL.md +0 -44
  221. package/.cursor/skills/performance-optimization/SKILL.md +0 -77
  222. package/.cursor/skills/security-and-hardening/SKILL.md +0 -70
  223. package/.cursor/skills/using-aw-skills/SKILL.md +0 -290
  224. package/.cursor/skills/using-aw-skills/evals/skill-trigger-cases.tsv +0 -25
  225. package/.cursor/skills/using-aw-skills/evals/test-skill-triggers.sh +0 -171
  226. package/.cursor/skills/using-aw-skills/hooks/hooks.json +0 -9
  227. package/.cursor/skills/using-aw-skills/hooks/session-start.sh +0 -67
  228. package/.cursor/skills/using-platform-skills/SKILL.md +0 -163
  229. package/.cursor/skills/using-platform-skills/evals/platform-selection-cases.json +0 -52
  230. /package/.cursor/rules/{golang-coding-style.md → golang-coding-style.mdc} +0 -0
  231. /package/.cursor/rules/{golang-hooks.md → golang-hooks.mdc} +0 -0
  232. /package/.cursor/rules/{golang-patterns.md → golang-patterns.mdc} +0 -0
  233. /package/.cursor/rules/{golang-security.md → golang-security.mdc} +0 -0
  234. /package/.cursor/rules/{golang-testing.md → golang-testing.mdc} +0 -0
  235. /package/.cursor/rules/{kotlin-coding-style.md → kotlin-coding-style.mdc} +0 -0
  236. /package/.cursor/rules/{kotlin-hooks.md → kotlin-hooks.mdc} +0 -0
  237. /package/.cursor/rules/{kotlin-patterns.md → kotlin-patterns.mdc} +0 -0
  238. /package/.cursor/rules/{kotlin-security.md → kotlin-security.mdc} +0 -0
  239. /package/.cursor/rules/{kotlin-testing.md → kotlin-testing.mdc} +0 -0
  240. /package/.cursor/rules/{php-coding-style.md → php-coding-style.mdc} +0 -0
  241. /package/.cursor/rules/{php-hooks.md → php-hooks.mdc} +0 -0
  242. /package/.cursor/rules/{php-patterns.md → php-patterns.mdc} +0 -0
  243. /package/.cursor/rules/{php-security.md → php-security.mdc} +0 -0
  244. /package/.cursor/rules/{php-testing.md → php-testing.mdc} +0 -0
  245. /package/.cursor/rules/{python-coding-style.md → python-coding-style.mdc} +0 -0
  246. /package/.cursor/rules/{python-hooks.md → python-hooks.mdc} +0 -0
  247. /package/.cursor/rules/{python-patterns.md → python-patterns.mdc} +0 -0
  248. /package/.cursor/rules/{python-security.md → python-security.mdc} +0 -0
  249. /package/.cursor/rules/{python-testing.md → python-testing.mdc} +0 -0
  250. /package/.cursor/rules/{swift-coding-style.md → swift-coding-style.mdc} +0 -0
  251. /package/.cursor/rules/{swift-hooks.md → swift-hooks.mdc} +0 -0
  252. /package/.cursor/rules/{swift-patterns.md → swift-patterns.mdc} +0 -0
  253. /package/.cursor/rules/{swift-security.md → swift-security.mdc} +0 -0
  254. /package/.cursor/rules/{swift-testing.md → swift-testing.mdc} +0 -0
  255. /package/.cursor/rules/{typescript-coding-style.md → typescript-coding-style.mdc} +0 -0
  256. /package/.cursor/rules/{typescript-hooks.md → typescript-hooks.mdc} +0 -0
  257. /package/.cursor/rules/{typescript-patterns.md → typescript-patterns.mdc} +0 -0
  258. /package/.cursor/rules/{typescript-security.md → typescript-security.mdc} +0 -0
  259. /package/.cursor/rules/{typescript-testing.md → typescript-testing.mdc} +0 -0
@@ -0,0 +1,70 @@
1
+ # Quality Checklist
2
+
3
+ This is the **pass/fail contract** that the self-review loop (step 6) enforces against every screen, every state, and the index page. Items are grouped by review track:
4
+
5
+ - **Track A** items are deterministic — checked by regex/grep during `references/self-review.md` Track A.
6
+ - **Track B** items are visual — checked by `cursor-ide-browser` during Track B.
7
+
8
+ The agent must reach ✅ on every item, or explicitly flag the remaining failures in `designs/REVIEW.md` before presenting.
9
+
10
+ ## Token compliance
11
+
12
+ - [ ] Colors match `references/highrise-tokens.md` exactly — no rogue hex values
13
+ - [ ] Only ONE accent color used (#155EEF — HighRise brand blue)
14
+ - [ ] Status indicators are tiny 6px dots + gray text, not colored pills
15
+ - [ ] Cards are white with thin border, no colored backgrounds
16
+ - [ ] No heavy shadows at rest
17
+ - [ ] Section gaps are 48px+
18
+ - [ ] Metric numbers 30–36px (Display sm/md) with small gray labels
19
+ - [ ] Tables have no zebra stripes
20
+ - [ ] Data looks realistic (real names, plausible numbers, recent dates)
21
+
22
+ ## Micro-interactions
23
+
24
+ - [ ] All interactive elements have `:hover`, `:focus-visible`, and `:active` states
25
+ - [ ] Transitions are 0.15s ease (or 0.2s for larger movement)
26
+ - [ ] `@media (prefers-reduced-motion: reduce)` media query present
27
+ - [ ] Modal has entrance/exit animation
28
+ - [ ] Toast slides in from top-right
29
+ - [ ] Skeleton shimmer uses `@keyframes pulse`
30
+ - [ ] Input focus ring renders correctly in both light and dark mode
31
+
32
+ ## Variants completeness
33
+
34
+ - [ ] Every screen has default + loading + empty + error (+ modal if applicable)
35
+ - [ ] Dark mode toggle works on every screen
36
+
37
+ ## Responsive (verify by actually resizing the viewport — don't just trust the code)
38
+
39
+ Open each HTML file and resize through 320px, 768px, 1024px, and 1440px. Confirm at each width:
40
+
41
+ - [ ] No horizontal scroll on `<body>` at any viewport width
42
+ - [ ] **Mobile (≤767px):** sidebar hidden, hamburger drawer works, cards stack vertically, modals go full-screen, touch targets ≥44×44px, body font ≥14px
43
+ - [ ] **Tablet (768–1023px):** sidebar collapsed to 64px icon rail, 2-column grid
44
+ - [ ] **Desktop (1024–1279px):** full 240px sidebar with labels, grid uses 3+ columns
45
+ - [ ] **Wide (≥1280px):** content capped at 1200px max-width, centered
46
+ - [ ] Tables either scroll horizontally OR collapse to card layout on mobile — never overflow the viewport
47
+ - [ ] Media queries use mobile-first `min-width` and are pure CSS (no JS layout switching)
48
+
49
+ ## Linked prototype
50
+
51
+ - [ ] `index.html` exists and links to every screen + state variant
52
+ - [ ] Sidebar nav items have working `<a href>` relative links
53
+ - [ ] Current page highlighted in sidebar
54
+ - [ ] Theme toggle persists via localStorage and applies to all previews
55
+ - [ ] Navigation flow diagram present in index
56
+
57
+ ## Index page requirements
58
+
59
+ The `.aw_docs/features/<slug>/designs/index.html` is mandatory and must include:
60
+
61
+ - Feature name and 1-line description
62
+ - Every screen as a card with:
63
+ - Screen name
64
+ - Thumbnail (Stitch screenshot URL, or iframe preview for HTML)
65
+ - Links to each state variant: default, empty, loading, error, modal-*
66
+ - Navigation flow diagram (simple arrows showing screen → screen relationships)
67
+ - Links to `design.md` (at feature root), `SCREEN_PLAN.md` (same folder), and `REVIEW.md` (same folder)
68
+ - Theme toggle (light/dark) that persists to localStorage and applies to all previews
69
+
70
+ The index follows the same Highrise tokens and micro-interactions — it must look as polished as the screens it links to.
@@ -0,0 +1,497 @@
1
+ # Self-Review & Iterate
2
+
3
+ Step 6 of the workflow. You don't "present" a design — you **prove it's production-ready** first. This file defines how.
4
+
5
+ Run two tracks in order: **deterministic** (fast, regex) then **visual** (browser MCP). Fix findings, re-validate. Loop up to **3 iterations**. Stop early when all pass. If you can't reach a pass state in 3 iterations, write unresolved items to `REVIEW.md` and surface them to the user — don't hide them.
6
+
7
+ ---
8
+
9
+ ## Track A — Deterministic sweep
10
+
11
+ Run these as shell checks from the feature root (`.aw_docs/features/<slug>/`). Every check produces zero or more findings. Zero findings across all checks = Track A passes.
12
+
13
+ ### A1. No rogue hex values
14
+
15
+ Every hex color in every HTML must exist in `references/highrise-tokens.md`. Anything else is a rogue value.
16
+
17
+ ```bash
18
+ # Harvest the allowed hex set once
19
+ grep -hoE '#[0-9A-Fa-f]{6}' aw-ecc/skills/aw-design/references/highrise-tokens.md | sort -u > /tmp/allowed_hex.txt
20
+
21
+ # Find all hex in generated designs, compare
22
+ grep -rhoE '#[0-9A-Fa-f]{6}' designs/ | sort -u > /tmp/used_hex.txt
23
+ comm -23 /tmp/used_hex.txt /tmp/allowed_hex.txt
24
+ ```
25
+
26
+ Any output line is a finding: "rogue hex `<value>`". Locate each with `rg -n '<value>' designs/` and fix.
27
+
28
+ **Allowed exceptions** (do not flag):
29
+ - `#000000` in `rgba(0,0,0,…)` for shadows and scrim — present as `0 4px 6px -2px rgba(16, 24, 40, 0.03)` style already
30
+ - Values inside HTML comments `<!-- … -->`
31
+
32
+ ### A2. Exactly one brand accent
33
+
34
+ Only the blue family is a brand color. Any use of violet/purple/indigo/pink/etc. as a primary action color is a finding.
35
+
36
+ ```bash
37
+ # If any of these 600-values appear, it's an accent misuse
38
+ grep -rhnE '#(6938EF|7839EE|9E77ED|BA24D5|D444F1|E31B54|EF6820|F63D68|DD2590|2E90FA|0BA5EC|0086C9|06AED4|0E9384|15B79E|3CCB7F|66C61C|16B364|669F2A|EAAA08|EF6820)\b' designs/
39
+ ```
40
+
41
+ Any match = finding. The only permitted non-blue accents are status colors (success `#12B76A`, warning `#F79009`, error `#F04438`) and only as status indicators — never as button fills or nav highlights.
42
+
43
+ ### A3. All state variants present
44
+
45
+ For every screen folder, the set `{default, empty, loading, error}` must all exist. Modal is optional.
46
+
47
+ ```bash
48
+ for dir in designs/*/; do
49
+ [ "$dir" = "designs/screenshots/" ] && continue
50
+ for state in default empty loading error; do
51
+ [ -f "$dir$state.html" ] || echo "MISSING: $dir$state.html"
52
+ done
53
+ done
54
+ ```
55
+
56
+ ### A4. Responsive media queries
57
+
58
+ Every screen HTML must contain all three breakpoints.
59
+
60
+ ```bash
61
+ for f in designs/**/*.html; do
62
+ grep -q '@media (min-width: 768px)' "$f" || echo "$f — missing tablet breakpoint"
63
+ grep -q '@media (min-width: 1024px)' "$f" || echo "$f — missing desktop breakpoint"
64
+ grep -q '@media (min-width: 1280px)' "$f" || echo "$f — missing wide breakpoint"
65
+ done
66
+ ```
67
+
68
+ ### A5. Focus rings + reduced motion
69
+
70
+ Every screen HTML must include `:focus-visible`, at least one `@keyframes`, and the `prefers-reduced-motion` fallback.
71
+
72
+ ```bash
73
+ for f in designs/**/*.html; do
74
+ grep -q ':focus-visible' "$f" || echo "$f — no :focus-visible"
75
+ grep -q '@keyframes' "$f" || echo "$f — no @keyframes"
76
+ grep -q 'prefers-reduced-motion' "$f" || echo "$f — no prefers-reduced-motion"
77
+ done
78
+ ```
79
+
80
+ ### A6. Typography is on the scale
81
+
82
+ Every font size — whether written as `font-size:` or inside `font:` shorthand — must be one of: `8 9 10 11 12 13 14 15 16 18 20 24 30 36 48 60 72` px (or `rem`/`em` equivalents, or a `var(--font-size-*)` reference).
83
+
84
+ **A6a — `font-size:` declarations:**
85
+
86
+ ```bash
87
+ grep -rhoE 'font-size:\s*[0-9.]+(px|rem|em)' designs/ \
88
+ | grep -vE 'font-size:\s*(8|9|10|11|12|13|14|15|16|18|20|24|30|36|48|60|72)(px|rem|em)' \
89
+ | sort -u
90
+ ```
91
+
92
+ **A6b — `font:` shorthand (e.g. `font: 600 30px/38px Inter`):**
93
+
94
+ ```bash
95
+ # Pull size tokens out of any "font:" shorthand, then filter to off-scale
96
+ grep -rhoE 'font:\s*[^;}"]+' designs/ \
97
+ | grep -oE '[0-9.]+(px|rem|em)\b' \
98
+ | grep -vE '^(8|9|10|11|12|13|14|15|16|18|20|24|30|36|48|60|72)(px|rem|em)$' \
99
+ | sort -u
100
+ ```
101
+
102
+ Any output from **either** check = off-scale size finding. Run both — `font:` shorthand is the sneaky one Stitch loves to emit.
103
+
104
+ ### A7. Sidebar restraint
105
+
106
+ Sidebars are light, not colored.
107
+
108
+ ```bash
109
+ # Expect sidebar bg to be #F9FAFB (gray-50) or white — never a brand color
110
+ rg -n --multiline-dotall 'class="[^"]*sidebar[^"]*"[^>]*>.*?background[^;]*?(#155EEF|#EFF4FF|#D1E0FF)' designs/
111
+ ```
112
+
113
+ Any match = finding. Brand blue belongs on the active nav item only (bg `#EFF4FF`, text `#155EEF`, 2px left border `#155EEF`).
114
+
115
+ ### A8. Index page completeness
116
+
117
+ `designs/index.html` must exist and must link to every screen + state variant.
118
+
119
+ ```bash
120
+ [ -f designs/index.html ] || echo "MISSING: designs/index.html"
121
+
122
+ # Every state HTML must be referenced somewhere in index.html
123
+ for f in designs/*/*.html; do
124
+ rel="${f#designs/}"
125
+ grep -q "$rel" designs/index.html || echo "index.html does not link $rel"
126
+ done
127
+ ```
128
+
129
+ ### A9. Realistic data
130
+
131
+ Spot-check for placeholder strings that leak past Stitch.
132
+
133
+ ```bash
134
+ rg -n --ignore-case 'lorem ipsum|placeholder|foo bar|test data|john doe|jane doe|example\.com|dummy' designs/
135
+ ```
136
+
137
+ Any match = finding. Replace with plausible domain-appropriate data.
138
+
139
+ ---
140
+
141
+ ## Track B — Visual sweep (browser MCP)
142
+
143
+ Run once Track A is clean.
144
+
145
+ ### B0. Browser MCP selection (agent-portable)
146
+
147
+ Track B requires a browser MCP that exposes the standard `browser_*` tool surface. The tool names below (`browser_navigate`, `browser_resize`, `browser_snapshot`, `browser_take_screenshot`, `browser_console_messages`, optional `browser_evaluate`) are identical across both supported servers — only the server you route to changes.
148
+
149
+ | Environment | Recommended MCP | Notes |
150
+ |---|---|---|
151
+ | Codex | `playwright` (preconfigured in `~/.codex/config.toml` as `@playwright/mcp@latest`) | Portable default. Runs headless Chromium locally. |
152
+ | Claude Desktop / Claude Code | `playwright` (install `@playwright/mcp`) | Same as Codex. |
153
+ | Cursor | `cursor-ide-browser` **or** `playwright` | `cursor-ide-browser` opens a real Cursor tab (nice for the human to watch); Playwright is faster and headless. Either works. |
154
+
155
+ Detect capability before starting Track B:
156
+
157
+ ```
158
+ 1. Check whether any of browser_navigate / browser_snapshot are registered.
159
+ 2. If yes → proceed.
160
+ 3. If no → mark Track B as SKIPPED in REVIEW.md with reason
161
+ "no browser MCP available in this environment" and downgrade the final
162
+ status to ⚠️ Shipped with partial verification. Track A is still enforceable.
163
+ ```
164
+
165
+ **`file://` fallback (mandatory probe before the main sweep).** Some Playwright MCP configs and hardened Cursor setups refuse `file://` URLs for security. Probe once with the index page:
166
+
167
+ ```
168
+ browser_navigate → file:///<abs>/designs/index.html
169
+ ```
170
+
171
+ If the call errors with a security/permission/unsupported-scheme message, start a local HTTP server and use it for the rest of Track B:
172
+
173
+ ```bash
174
+ # Run in a background shell (block_until_ms: 0). Note the PID.
175
+ python3 -m http.server 8765 --directory <abs path to designs>
176
+ ```
177
+
178
+ Then substitute `http://127.0.0.1:8765/...` for every `file://` URL in B1–B5. Kill the server in B6 teardown with the PID. Record in REVIEW.md which scheme was used (`file://` or `http://127.0.0.1:8765`).
179
+
180
+ **Cursor-only step:** if you selected `cursor-ide-browser`, call `browser_lock { action: "lock" }` after the first navigation and `browser_lock { action: "unlock" }` at the end of Track B. Playwright MCP has no equivalent — skip it.
181
+
182
+ ### B1. Per-screen breakpoint pass
183
+
184
+ Open `designs/index.html` once as a warm-up, then for each screen + state (loop across `designs/*/*.html`):
185
+
186
+ ```
187
+ browser_navigate → <scheme>://…/<screen>/<state>.html
188
+ for width in [320, 768, 1024, 1440]:
189
+ browser_resize { width, height: 900 }
190
+ browser_snapshot
191
+ browser_take_screenshot → designs/screenshots/<screen>-<state>-<width>.png
192
+ ```
193
+
194
+ **What to look for in each snapshot + screenshot:**
195
+
196
+ | Width | Must be true |
197
+ |---|---|
198
+ | 320 | No sidebar visible, no horizontal scroll, touch targets ≥44×44, body font ≥14px, modals full-screen if present, hero/brand panels must not push primary content below the fold |
199
+ | 768 | Sidebar collapsed to 64px icon rail, 2-column grid where applicable |
200
+ | 1024 | Full 240px sidebar with labels, ≥3-column grid on dashboards |
201
+ | 1440 | Content capped at ~1200px max-width and centered — not edge-to-edge |
202
+
203
+ For each violation, write a finding: `<screen>/<state> @ <width>px: <what is wrong>`.
204
+
205
+ **Capture matrix (enforced head count).** Before marking B1 as ✅, compute:
206
+
207
+ ```bash
208
+ # Count generated HTML files (exclude index.html and screenshots/)
209
+ files=$(find designs/ -name '*.html' ! -name 'index.html' | wc -l | tr -d ' ')
210
+
211
+ # Per-file expected captures at B1 (4 widths) + B2 (1 dark capture)
212
+ expected=$(( files * 4 + files )) # = files × 5
213
+
214
+ # Actual captures on disk
215
+ actual=$(find designs/screenshots/ -name '*.png' 2>/dev/null | wc -l | tr -d ' ')
216
+
217
+ echo "Captures: $actual / $expected"
218
+ ```
219
+
220
+ B1 + B2 combined PASS requires `actual >= expected`. If `actual < 0.9 × expected`, Track B is ❌ not partial — you skipped work. Record the ratio in REVIEW.md verbatim (e.g. `Captures: 18/20 (90%) PASS` or `Captures: 3/20 (15%) FAIL — most breakpoints never rendered`).
221
+
222
+ ### B2. Dark mode pass
223
+
224
+ At 1440px width, toggle dark class and re-screenshot one screen per folder:
225
+
226
+ ```
227
+ browser_navigate → file:///…/<screen>/default.html
228
+ browser_resize → 1440 × 900
229
+ # Inject .dark on <html>
230
+ browser_snapshot (confirm dark class present)
231
+ browser_take_screenshot → designs/screenshots/<screen>-default-1440-dark.png
232
+ ```
233
+
234
+ Inspect: background near-black (not pure `#000`), text gray-100/200 (not pure white), borders visible at low contrast, accent blue still legible on dark surface.
235
+
236
+ ### B3. Cross-screen consistency
237
+
238
+ Pick two screens in the feature (e.g., list view + detail view). At 1440 light mode:
239
+
240
+ - Primary button: same height, padding, bg, hover shade
241
+ - Input: same height, border, focus ring
242
+ - Card: same border, radius, shadow (or lack thereof)
243
+ - Sidebar: same width, item spacing, active-state styling
244
+
245
+ Any visible inconsistency = finding.
246
+
247
+ ### B4. Console check
248
+
249
+ After every navigation:
250
+
251
+ ```
252
+ browser_console_messages
253
+ ```
254
+
255
+ Any JS error or CSS parse error = finding.
256
+
257
+ ### B5. Computed-style spot-check (optional, Playwright only)
258
+
259
+ If `browser_evaluate` is available (Playwright MCP exposes it; cursor-ide-browser does not), run computed-style assertions that regex can't catch. Pick one primary button and one focused input per screen and verify rendered values:
260
+
261
+ ```js
262
+ // Inside browser_evaluate
263
+ const btn = document.querySelector('.btn-primary, [data-role="primary"]');
264
+ const s = getComputedStyle(btn);
265
+ return {
266
+ bg: s.backgroundColor, // must resolve to rgb(21, 94, 239) == #155EEF
267
+ radius: s.borderRadius, // must be 8px
268
+ fontWeight: s.fontWeight, // must be 500 or 600
269
+ minHeight: s.height // must be ≥ 36px
270
+ };
271
+ ```
272
+
273
+ This catches cascade bugs (e.g. a `:root` override that silently broke the token) that Track A's hex grep can't see. Skip this section on cursor-ide-browser — not a finding, just `N/A` in REVIEW.md.
274
+
275
+ ### B6. Teardown
276
+
277
+ ```
278
+ (if cursor-ide-browser) browser_lock { action: "unlock" }
279
+ (if http fallback) kill <pid of python3 http.server>
280
+ ```
281
+
282
+ Playwright MCP auto-cleans on session end — no explicit unlock needed.
283
+
284
+ ---
285
+
286
+ ## Categorizing findings → fix method
287
+
288
+ Every finding must be tagged with a fix method before applying. This keeps us off the Stitch quota.
289
+
290
+ | Finding class | Fix method | Stitch cost |
291
+ |---|---|---|
292
+ | Rogue hex (A1, A2) | `sed -i` on the HTML — swap to the correct token hex | 0 |
293
+ | Missing `@media` block (A4) | Direct edit — append the block to `<style>` | 0 |
294
+ | Missing `:focus-visible` / `@keyframes` / `prefers-reduced-motion` (A5) | Direct edit — copy from `references/micro-interactions.md` | 0 |
295
+ | Off-scale font-size (A6) | Direct edit — snap to nearest scale value | 0 |
296
+ | Wrong sidebar bg (A7) | Direct edit — change background token | 0 |
297
+ | Index page missing links (A8) | Direct edit — append `<a>` entries | 0 |
298
+ | Placeholder data (A9) | Direct edit — substitute realistic values | 0 |
299
+ | Missing state variant file (A3) | `stitch_generate-screen` (Flash) with state-variant prompt | 1 |
300
+ | Cross-screen inconsistency (B3) | `stitch_apply-design-system` multi-select on affected screens | 1 total |
301
+ | Layout broken at a breakpoint (B1) | `stitch_edit-screens` with specific instruction | 1 per screen |
302
+ | Dark mode unreadable (B2) | Direct edit — adjust `.dark` overrides in CSS | 0 |
303
+ | Architectural wrongness (wrong hierarchy, wrong primary CTA) | **Do not auto-fix.** Surface to user as a BLOCKER in REVIEW.md | 0 |
304
+
305
+ **Hard rule:** never regenerate a whole screen to fix a rogue hex. If a finding has a 0-cost fix path, that is the only acceptable fix method.
306
+
307
+ ---
308
+
309
+ ## The iteration loop — what "done" actually means
310
+
311
+ This is the skill's teeth. The loop is **not optional** and **not a single pass**. Treat each of these as a hard contract:
312
+
313
+ 1. **Every iteration runs both tracks, in full.** No skipping Track B because Track A still has findings — Track B catches things Track A can't see, and you need both signals every round.
314
+ 2. **Every iteration must apply fixes to the findings it produced.** An iteration where you ran the checks but didn't edit anything is not a real iteration.
315
+ 3. **Every iteration must produce evidence in REVIEW.md.** See "Per-iteration evidence" below.
316
+ 4. **The loop stops for exactly three reasons** — and only the first is a success:
317
+
318
+ | Stop condition | REVIEW.md status |
319
+ |---|---|
320
+ | Zero findings across both tracks | ✅ Production-ready |
321
+ | 3 iterations completed, some findings remain but count is decreasing | ⚠️ Shipped with known issues (only valid with **≥2 iterations of fixes on disk**) |
322
+ | Findings count stopped decreasing (fix regressed something) or a BLOCKER finding surfaced | ❌ Blocked — surface to user |
323
+
324
+ A status of ⚠️ is **invalid** if fewer than 2 iterations applied fixes. If you ran 1 iteration and have findings, the status is ❌ BLOCKED, not ⚠️. No shortcuts.
325
+
326
+ ### Pseudocode
327
+
328
+ ```
329
+ iter = 1
330
+ prev_count = infinity
331
+
332
+ while iter <= 3:
333
+ findings_A = run_track_A()
334
+ findings_B = run_track_B() # always runs, no skipping
335
+ findings = findings_A + findings_B
336
+
337
+ write_iteration_evidence(iter, findings) # to REVIEW.md § Iteration <iter>
338
+
339
+ if len(findings) == 0:
340
+ final_status = "✅"
341
+ break
342
+
343
+ if iter > 1 and len(findings) >= prev_count:
344
+ final_status = "❌" # not converging
345
+ break
346
+
347
+ prev_count = len(findings)
348
+ apply_fixes(findings) # <-- mandatory; iteration without this is void
349
+ record_fixes_applied(iter) # to REVIEW.md § Iteration <iter> § Fixes
350
+ iter += 1
351
+
352
+ if final_status is unset:
353
+ # Ran all 3, still have findings, but count decreased each time
354
+ final_status = "⚠️"
355
+ assert iterations_with_fixes_on_disk >= 2, "⚠️ requires ≥2 fix iterations"
356
+
357
+ finalize_REVIEW_md(final_status, remaining=findings)
358
+ ```
359
+
360
+ **Convergence check:** iteration N+1 must have strictly fewer findings than iteration N. If not, a fix regressed something — stop and write ❌ BLOCKED with the regression listed.
361
+
362
+ **No ask-first shortcuts.** Do not stop after iteration 1 to ask the user "should I continue?" The contract says 3 iterations (or zero findings). Asking is a protocol violation.
363
+
364
+ ---
365
+
366
+ ## REVIEW.md — the evidence-required output contract
367
+
368
+ `designs/REVIEW.md` is not a summary document. It is an **audit trail** that proves each iteration actually ran. An agent reading their own REVIEW.md should not be able to fake compliance — the file format demands pasted commands, numeric outputs, capture counts, and fix diffs. Anything less is non-compliant.
369
+
370
+ ### Per-check evidence requirement (Track A)
371
+
372
+ Every A-check row in every iteration's section must include:
373
+
374
+ 1. The **exact command** that was run (copy-pasted, not paraphrased).
375
+ 2. The **raw output** or a match-count (e.g. `→ 3 matches` or `→ empty output, 0 findings`).
376
+ 3. A ✅/❌ verdict.
377
+
378
+ A row without command + output is treated as **not run** and forces the status to ❌ BLOCKED, regardless of what the verdict column says.
379
+
380
+ ### Per-iteration capture count (Track B)
381
+
382
+ B1 must record the capture matrix ratio before its ✅. If `actual < 0.9 × expected` the row is ❌ and forces a ❌ BLOCKED overall status.
383
+
384
+ ### Template
385
+
386
+ ```markdown
387
+ # Design Review — <feature>
388
+
389
+ **Status:** ✅ Production-ready | ⚠️ Shipped with known issues (requires ≥2 fix iterations) | ❌ Blocked
390
+ **Iterations run:** N / 3
391
+ **Iterations with fixes applied:** M (M ≥ 2 required for ⚠️)
392
+ **Browser MCP:** playwright | cursor-ide-browser | none (Track B skipped)
393
+ **URL scheme used:** file:// | http://127.0.0.1:8765 (local server fallback)
394
+ **Last reviewed:** <YYYY-MM-DD HH:MM TZ>
395
+
396
+ ## Summary
397
+
398
+ <1–3 sentence plain-English state of the designs. If ⚠️ or ❌, lead with what is broken.>
399
+
400
+ ---
401
+
402
+ ## Iteration 1
403
+
404
+ ### Track A — deterministic
405
+
406
+ | # | Check | Command run | Output | Verdict |
407
+ |---|---|---|---|---|
408
+ | A1 | rogue hex | `comm -23 /tmp/used_hex.txt /tmp/allowed_hex.txt` | `(empty)` | ✅ |
409
+ | A2 | one brand accent | `grep -rhnE '#(6938EF\|7839EE\|...)' designs/` | `0 matches` | ✅ |
410
+ | A3 | state variants | <loop script output> | `no MISSING lines` | ✅ |
411
+ | A4 | responsive breakpoints | <loop output> | `0 warnings` | ✅ |
412
+ | A5 | focus + motion | <loop output> | `0 warnings` | ✅ |
413
+ | A6a | font-size: scale | `grep -rhoE 'font-size:...' \| grep -vE ...` | `(empty)` | ✅ |
414
+ | A6b | font: shorthand | `grep -rhoE 'font:...' \| grep -oE ... \| grep -vE ...` | `14px` | ❌ 1 off-scale (in error.html) |
415
+ | A7 | sidebar restraint | `rg -n --multiline-dotall 'class="[^"]*sidebar[^"]*"...' designs/` | `0 matches` | ✅ |
416
+ | A8 | index completeness | `grep -q` loop over `designs/*/*.html` | `no unlinked lines` | ✅ |
417
+ | A9 | realistic data | `rg -n --ignore-case 'lorem ipsum\|...' designs/` | `0 matches` | ✅ |
418
+
419
+ ### Track B — visual
420
+
421
+ | # | Check | Evidence | Verdict |
422
+ |---|---|---|---|
423
+ | B1 | breakpoint + capture matrix | Captures: **20 / 20 (100%)**. files=4, widths=4, dark=4 | ✅ |
424
+ | B2 | dark mode | 4 dark screenshots at 1440 captured | ✅ |
425
+ | B3 | cross-screen consistency | Button heights 40/40/40 px; input borders identical; card radius 8/8/8 | ✅ |
426
+ | B4 | console clean | No errors across 16 navigations | ✅ |
427
+ | B5 | computed-style spot-check | `.btn-primary` bg `rgb(21, 94, 239)`, radius `8px`, weight `500`, height `40px` | ✅ |
428
+
429
+ ### Findings in this iteration
430
+
431
+ 1. **A6b / error.html** — `font: 600 14px/20px Inter` (14px not in scale; closest is 15px)
432
+ 2. **B1 / login/loading.html @ 320px** — brand hero panel occupies full viewport height, pushes form skeleton below fold
433
+
434
+ ### Fixes applied
435
+
436
+ 1. A6b → changed `font: 600 14px/20px Inter` to `font: 600 15px/22px Inter` in `error.html` line 147
437
+ 2. B1 → added `@media (max-width: 767px) { .brand-panel { display: none; } }` in `loading.html` line 62
438
+
439
+ ---
440
+
441
+ ## Iteration 2
442
+
443
+ <same format — must show fewer findings than Iteration 1>
444
+
445
+ ---
446
+
447
+ ## Iteration 3
448
+
449
+ <only present if Iteration 2 still had findings>
450
+
451
+ ---
452
+
453
+ ## Final status
454
+
455
+ - **Status:** ✅ / ⚠️ / ❌
456
+ - **Remaining findings:** <0 or list>
457
+
458
+ ## Known issues (only if status is ⚠️ or ❌)
459
+
460
+ For each remaining finding after iteration 3:
461
+
462
+ - **Severity:** blocker / minor
463
+ - **Where:** `<screen>/<state>.html` (+ breakpoint if visual)
464
+ - **What:** <description>
465
+ - **Why it wasn't auto-fixed:** <reason — needs judgment, needs Stitch regen the user didn't authorize, architectural>
466
+ - **Suggested next step:** <concrete action for the user>
467
+
468
+ ## Artifacts
469
+
470
+ - Screenshots: `designs/screenshots/<screen>-<state>-<width>[-dark].png` (N files)
471
+ - Source files reviewed: <count>
472
+ ```
473
+
474
+ ### Anti-fake rules (self-review enforcement)
475
+
476
+ Before finalizing REVIEW.md, run these sanity checks on the file you just wrote:
477
+
478
+ | Rule | How to verify |
479
+ |---|---|
480
+ | Every A-check row has a non-empty `Command run` column | `grep -cE '^\| A[0-9]' REVIEW.md` equals 10 (A1–A6b–A9) per iteration |
481
+ | B1 row includes a `Captures: X / Y` fragment | `grep -c 'Captures: [0-9]' REVIEW.md` ≥ iteration count |
482
+ | If status is ⚠️, at least 2 iterations contain a `## Fixes applied` subsection with non-empty body | count `## Fixes applied` sections ≥ 2 |
483
+ | If status is ✅, the final iteration's findings list is literally empty | last `### Findings in this iteration` has no numbered items |
484
+
485
+ If any rule fails, **the status is ❌ BLOCKED** — rewrite the missing evidence or downgrade honestly. Do not present ⚠️ without the fixes-on-disk proof.
486
+
487
+ If status is ⚠️ or ❌, **explicitly flag this when presenting to the user** — don't bury it. The whole point of this review is that the agent is honest about what it couldn't verify or fix.
488
+
489
+ ---
490
+
491
+ ## Related skills (reference, not duplicate)
492
+
493
+ These exist in the broader registry and cover adjacent but distinct concerns. Don't re-read them whole — point to specific sections when the need arises.
494
+
495
+ - **`platform-design:pixel-fidelity-review`** — computed-style audit comparing a *Vue implementation* against an HTML design prototype. Opposite direction from us: they treat the HTML as ground truth; we audit the HTML itself. Borrow their `browser_evaluate` computed-style patterns for B5 if you need depth beyond the spot-check.
496
+ - **`platform-design:auditor`** (subagent) — end-to-end design fidelity auditor with pass/fail verdicts. If you need a full parallel review run (not just self-check), delegate via Task tool.
497
+ - **`platform-webapp-testing`** — Playwright helper scripts (`with_server.py`) for live dev servers. Not needed here (we use `file://` URLs) but relevant if a future step spins up a dev server to audit a built implementation.