@hegemonart/get-design-done 1.41.5 → 1.43.0

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 (434) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +1120 -1029
  4. package/README.md +158 -154
  5. package/SKILL.md +42 -42
  6. package/agents/README.md +53 -53
  7. package/agents/a11y-mapper.md +3 -3
  8. package/agents/component-benchmark-harvester.md +8 -8
  9. package/agents/component-benchmark-synthesizer.md +11 -11
  10. package/agents/component-taxonomy-mapper.md +5 -5
  11. package/agents/compose-executor.md +25 -25
  12. package/agents/conflict-resolver.md +8 -8
  13. package/agents/cost-forecaster.md +12 -12
  14. package/agents/decision-journal-exporter.md +5 -5
  15. package/agents/design-advisor.md +19 -19
  16. package/agents/design-assumptions-analyzer.md +16 -16
  17. package/agents/design-auditor.md +39 -39
  18. package/agents/design-authority-watcher.md +28 -28
  19. package/agents/design-component-generator.md +27 -27
  20. package/agents/design-context-builder.md +66 -66
  21. package/agents/design-context-checker-gate.md +5 -5
  22. package/agents/design-context-checker.md +20 -20
  23. package/agents/design-discussant.md +23 -23
  24. package/agents/design-doc-writer.md +12 -12
  25. package/agents/design-executor.md +38 -38
  26. package/agents/design-figma-writer.md +31 -31
  27. package/agents/design-fixer.md +27 -27
  28. package/agents/design-integration-checker-gate.md +5 -5
  29. package/agents/design-integration-checker.md +29 -29
  30. package/agents/design-paper-writer.md +14 -14
  31. package/agents/design-pattern-mapper.md +9 -9
  32. package/agents/design-pencil-writer.md +12 -12
  33. package/agents/design-phase-researcher.md +14 -14
  34. package/agents/design-plan-checker.md +13 -13
  35. package/agents/design-planner.md +24 -24
  36. package/agents/design-reflector.md +48 -48
  37. package/agents/design-research-synthesizer.md +21 -21
  38. package/agents/design-start-writer.md +7 -7
  39. package/agents/design-update-checker.md +8 -8
  40. package/agents/design-verifier-gate.md +5 -5
  41. package/agents/design-verifier.md +80 -80
  42. package/agents/ds-generator.md +14 -14
  43. package/agents/ds-migration-planner.md +12 -12
  44. package/agents/email-executor.md +26 -26
  45. package/agents/experiment-result-ingester.md +10 -10
  46. package/agents/flutter-executor.md +28 -28
  47. package/agents/gdd-graph-refresh.md +10 -10
  48. package/agents/gdd-intel-updater.md +11 -11
  49. package/agents/gdd-learnings-extractor.md +2 -2
  50. package/agents/motion-mapper.md +8 -8
  51. package/agents/motion-verifier.md +16 -16
  52. package/agents/pdf-executor.md +27 -27
  53. package/agents/perf-analyzer.md +20 -20
  54. package/agents/pr-commenter.md +24 -24
  55. package/agents/prototype-gate.md +29 -29
  56. package/agents/quality-gate-runner.md +21 -21
  57. package/agents/rollout-coordinator.md +8 -8
  58. package/agents/swift-executor.md +41 -41
  59. package/agents/ticket-sync-agent.md +19 -19
  60. package/agents/token-mapper.md +6 -6
  61. package/agents/user-research-synthesizer.md +13 -13
  62. package/agents/visual-hierarchy-mapper.md +2 -2
  63. package/dist/claude-code/.claude/skills/add-backlog/SKILL.md +48 -0
  64. package/dist/claude-code/.claude/skills/analyze-dependencies/SKILL.md +95 -0
  65. package/dist/claude-code/.claude/skills/apply-reflections/SKILL.md +92 -0
  66. package/dist/claude-code/.claude/skills/apply-reflections/apply-reflections-procedure.md +170 -0
  67. package/dist/claude-code/.claude/skills/audit/SKILL.md +79 -0
  68. package/dist/claude-code/.claude/skills/bandit-status/SKILL.md +94 -0
  69. package/dist/claude-code/.claude/skills/benchmark/SKILL.md +65 -0
  70. package/dist/claude-code/.claude/skills/bootstrap-ds/SKILL.md +43 -0
  71. package/dist/claude-code/.claude/skills/brief/SKILL.md +128 -0
  72. package/dist/claude-code/.claude/skills/budget/SKILL.md +45 -0
  73. package/dist/claude-code/.claude/skills/cache-manager/SKILL.md +66 -0
  74. package/dist/claude-code/.claude/skills/cache-manager/cache-policy.md +126 -0
  75. package/dist/claude-code/.claude/skills/check-update/SKILL.md +98 -0
  76. package/dist/claude-code/.claude/skills/compare/SKILL.md +82 -0
  77. package/dist/claude-code/.claude/skills/compare/compare-rubric.md +171 -0
  78. package/dist/claude-code/.claude/skills/complete-cycle/SKILL.md +81 -0
  79. package/dist/claude-code/.claude/skills/connections/SKILL.md +71 -0
  80. package/dist/claude-code/.claude/skills/connections/connections-onboarding.md +608 -0
  81. package/dist/claude-code/.claude/skills/continue/SKILL.md +24 -0
  82. package/dist/claude-code/.claude/skills/darkmode/SKILL.md +76 -0
  83. package/dist/claude-code/.claude/skills/darkmode/darkmode-audit-procedure.md +258 -0
  84. package/dist/claude-code/.claude/skills/debug/SKILL.md +41 -0
  85. package/dist/claude-code/.claude/skills/debug/debug-feedback-loops.md +119 -0
  86. package/dist/claude-code/.claude/skills/design/SKILL.md +99 -0
  87. package/dist/claude-code/.claude/skills/design/design-procedure.md +304 -0
  88. package/dist/claude-code/.claude/skills/discover/SKILL.md +72 -0
  89. package/dist/claude-code/.claude/skills/discover/discover-procedure.md +222 -0
  90. package/dist/claude-code/.claude/skills/discuss/SKILL.md +96 -0
  91. package/dist/claude-code/.claude/skills/do/SKILL.md +45 -0
  92. package/dist/claude-code/.claude/skills/explore/SKILL.md +105 -0
  93. package/dist/claude-code/.claude/skills/explore/explore-procedure.md +267 -0
  94. package/dist/claude-code/.claude/skills/export/SKILL.md +30 -0
  95. package/dist/claude-code/.claude/skills/extract-learnings/SKILL.md +98 -0
  96. package/dist/claude-code/.claude/skills/fast/SKILL.md +91 -0
  97. package/dist/claude-code/.claude/skills/figma-extract/SKILL.md +64 -0
  98. package/dist/claude-code/.claude/skills/figma-write/SKILL.md +39 -0
  99. package/dist/claude-code/.claude/skills/graphify/SKILL.md +49 -0
  100. package/dist/claude-code/.claude/skills/health/SKILL.md +99 -0
  101. package/dist/claude-code/.claude/skills/health/health-mcp-detection.md +44 -0
  102. package/dist/claude-code/.claude/skills/health/health-skill-length-report.md +69 -0
  103. package/dist/claude-code/.claude/skills/help/SKILL.md +87 -0
  104. package/dist/claude-code/.claude/skills/list-assumptions/SKILL.md +61 -0
  105. package/dist/claude-code/.claude/skills/locale/SKILL.md +51 -0
  106. package/dist/claude-code/.claude/skills/map/SKILL.md +89 -0
  107. package/dist/claude-code/.claude/skills/migrate/SKILL.md +70 -0
  108. package/dist/claude-code/.claude/skills/new-cycle/SKILL.md +37 -0
  109. package/dist/claude-code/.claude/skills/new-cycle/milestone-completeness-rubric.md +87 -0
  110. package/dist/claude-code/.claude/skills/new-project/SKILL.md +53 -0
  111. package/dist/claude-code/.claude/skills/next/SKILL.md +68 -0
  112. package/dist/claude-code/.claude/skills/note/SKILL.md +48 -0
  113. package/dist/claude-code/.claude/skills/openrouter-status/SKILL.md +86 -0
  114. package/dist/claude-code/.claude/skills/optimize/SKILL.md +97 -0
  115. package/dist/claude-code/.claude/skills/pause/SKILL.md +77 -0
  116. package/dist/claude-code/.claude/skills/peer-cli-add/SKILL.md +88 -0
  117. package/dist/claude-code/.claude/skills/peer-cli-add/peer-cli-protocol.md +161 -0
  118. package/dist/claude-code/.claude/skills/peer-cli-customize/SKILL.md +90 -0
  119. package/dist/claude-code/.claude/skills/peers/SKILL.md +96 -0
  120. package/dist/claude-code/.claude/skills/plan/SKILL.md +105 -0
  121. package/dist/claude-code/.claude/skills/plan/plan-procedure.md +278 -0
  122. package/dist/claude-code/.claude/skills/plant-seed/SKILL.md +48 -0
  123. package/dist/claude-code/.claude/skills/pr-branch/SKILL.md +32 -0
  124. package/dist/claude-code/.claude/skills/progress/SKILL.md +95 -0
  125. package/dist/claude-code/.claude/skills/quality-gate/SKILL.md +90 -0
  126. package/dist/claude-code/.claude/skills/quality-gate/threat-modeling.md +101 -0
  127. package/dist/claude-code/.claude/skills/quick/SKILL.md +44 -0
  128. package/dist/claude-code/.claude/skills/reapply-patches/SKILL.md +32 -0
  129. package/dist/claude-code/.claude/skills/recall/SKILL.md +75 -0
  130. package/dist/claude-code/.claude/skills/reflect/SKILL.md +85 -0
  131. package/dist/claude-code/.claude/skills/reflect/procedures/capability-gap-scan.md +120 -0
  132. package/dist/claude-code/.claude/skills/report-issue/SKILL.md +53 -0
  133. package/dist/claude-code/.claude/skills/report-issue/report-issue-procedure.md +120 -0
  134. package/dist/claude-code/.claude/skills/resume/SKILL.md +93 -0
  135. package/dist/claude-code/.claude/skills/review-backlog/SKILL.md +46 -0
  136. package/dist/claude-code/.claude/skills/review-decisions/SKILL.md +42 -0
  137. package/dist/claude-code/.claude/skills/roi/SKILL.md +54 -0
  138. package/dist/claude-code/.claude/skills/rollout-status/SKILL.md +35 -0
  139. package/dist/claude-code/.claude/skills/router/SKILL.md +89 -0
  140. package/dist/claude-code/.claude/skills/router/capability-gap-emitter.md +65 -0
  141. package/dist/claude-code/.claude/skills/router/router-pick-emitter.md +78 -0
  142. package/dist/claude-code/.claude/skills/router/router-rules.md +84 -0
  143. package/dist/claude-code/.claude/skills/scan/SKILL.md +92 -0
  144. package/dist/claude-code/.claude/skills/scan/scan-procedure.md +732 -0
  145. package/dist/claude-code/.claude/skills/settings/SKILL.md +87 -0
  146. package/dist/claude-code/.claude/skills/ship/SKILL.md +48 -0
  147. package/dist/claude-code/.claude/skills/sketch/SKILL.md +78 -0
  148. package/dist/claude-code/.claude/skills/sketch-wrap-up/SKILL.md +92 -0
  149. package/dist/claude-code/.claude/skills/skill-manifest/SKILL.md +79 -0
  150. package/dist/claude-code/.claude/skills/spike/SKILL.md +67 -0
  151. package/dist/claude-code/.claude/skills/spike-wrap-up/SKILL.md +86 -0
  152. package/dist/claude-code/.claude/skills/start/SKILL.md +67 -0
  153. package/dist/claude-code/.claude/skills/start/start-procedure.md +115 -0
  154. package/dist/claude-code/.claude/skills/stats/SKILL.md +51 -0
  155. package/dist/claude-code/.claude/skills/style/SKILL.md +71 -0
  156. package/dist/claude-code/.claude/skills/style/style-doc-procedure.md +150 -0
  157. package/dist/claude-code/.claude/skills/synthesize/SKILL.md +94 -0
  158. package/dist/claude-code/.claude/skills/timeline/SKILL.md +66 -0
  159. package/dist/claude-code/.claude/skills/todo/SKILL.md +64 -0
  160. package/dist/claude-code/.claude/skills/turn-closeout/SKILL.md +95 -0
  161. package/dist/claude-code/.claude/skills/undo/SKILL.md +31 -0
  162. package/dist/claude-code/.claude/skills/unlock-decision/SKILL.md +54 -0
  163. package/dist/claude-code/.claude/skills/update/SKILL.md +56 -0
  164. package/dist/claude-code/.claude/skills/using-gdd/SKILL.md +78 -0
  165. package/dist/claude-code/.claude/skills/verify/SKILL.md +113 -0
  166. package/dist/claude-code/.claude/skills/verify/verify-procedure.md +512 -0
  167. package/dist/claude-code/.claude/skills/warm-cache/SKILL.md +81 -0
  168. package/dist/claude-code/.claude/skills/watch-authorities/SKILL.md +82 -0
  169. package/dist/claude-code/.claude/skills/zoom-out/SKILL.md +26 -0
  170. package/package.json +8 -2
  171. package/reference/DEPRECATIONS.md +21 -7
  172. package/reference/STATE-TEMPLATE.md +26 -26
  173. package/reference/accessibility.md +13 -13
  174. package/reference/adr-format.md +13 -13
  175. package/reference/ai-native-tool-interface.md +5 -5
  176. package/reference/anti-patterns.md +9 -9
  177. package/reference/architecture-vocabulary.md +31 -31
  178. package/reference/audit-scoring.md +13 -13
  179. package/reference/authority-feeds.md +36 -36
  180. package/reference/bandit-integration.md +25 -25
  181. package/reference/brand-voice.md +36 -36
  182. package/reference/capability-gap-stage-gate.md +20 -20
  183. package/reference/checklists.md +26 -26
  184. package/reference/cli-localization.md +13 -13
  185. package/reference/codex-tools.md +2 -2
  186. package/reference/color-theory.md +28 -28
  187. package/reference/component-authoring.md +4 -4
  188. package/reference/components/README.md +13 -13
  189. package/reference/components/TEMPLATE.md +13 -13
  190. package/reference/components/accordion.md +15 -15
  191. package/reference/components/alert.md +25 -25
  192. package/reference/components/badge.md +18 -18
  193. package/reference/components/breadcrumbs.md +24 -24
  194. package/reference/components/button.md +21 -21
  195. package/reference/components/card.md +13 -13
  196. package/reference/components/checkbox.md +20 -20
  197. package/reference/components/chip.md +20 -20
  198. package/reference/components/command-palette.md +15 -15
  199. package/reference/components/date-picker.md +22 -22
  200. package/reference/components/drawer.md +13 -13
  201. package/reference/components/file-upload.md +22 -22
  202. package/reference/components/input.md +18 -18
  203. package/reference/components/label.md +25 -25
  204. package/reference/components/link.md +19 -19
  205. package/reference/components/list.md +17 -17
  206. package/reference/components/menu.md +19 -19
  207. package/reference/components/modal-dialog.md +16 -16
  208. package/reference/components/navbar.md +19 -19
  209. package/reference/components/pagination.md +18 -18
  210. package/reference/components/popover.md +12 -12
  211. package/reference/components/progress.md +18 -18
  212. package/reference/components/radio.md +17 -17
  213. package/reference/components/rich-text-editor.md +24 -24
  214. package/reference/components/select-combobox.md +16 -16
  215. package/reference/components/sidebar.md +15 -15
  216. package/reference/components/skeleton.md +20 -20
  217. package/reference/components/slider.md +20 -20
  218. package/reference/components/stepper.md +24 -24
  219. package/reference/components/switch.md +19 -19
  220. package/reference/components/table.md +21 -21
  221. package/reference/components/tabs.md +11 -11
  222. package/reference/components/toast.md +19 -19
  223. package/reference/components/tooltip.md +19 -19
  224. package/reference/components/tree.md +17 -17
  225. package/reference/composition.md +38 -38
  226. package/reference/config-schema.md +37 -37
  227. package/reference/context-md-format.md +9 -9
  228. package/reference/contrast-advanced.md +29 -29
  229. package/reference/conversational-ui.md +17 -17
  230. package/reference/cost-governance.md +14 -14
  231. package/reference/css-grid-layout.md +8 -8
  232. package/reference/cycle-handoff-preamble.md +3 -3
  233. package/reference/data-visualization.md +67 -67
  234. package/reference/debugger-philosophy.md +5 -5
  235. package/reference/design-system-guidance.md +21 -21
  236. package/reference/design-systems-catalog.md +20 -20
  237. package/reference/design-variants.md +11 -11
  238. package/reference/domains/civic-patterns.md +10 -10
  239. package/reference/domains/finance-patterns.md +9 -9
  240. package/reference/domains/gaming-patterns.md +9 -9
  241. package/reference/domains/healthcare-patterns.md +11 -11
  242. package/reference/ds-bootstrap-rubric.md +13 -13
  243. package/reference/email-design.md +22 -22
  244. package/reference/emotional-design.md +10 -10
  245. package/reference/error-recovery.md +11 -11
  246. package/reference/export-formats.md +7 -7
  247. package/reference/figma-sandbox.md +6 -6
  248. package/reference/first-principles.md +10 -10
  249. package/reference/form-patterns.md +26 -26
  250. package/reference/framer-motion-patterns.md +49 -49
  251. package/reference/gdd-runtime-audit.md +17 -17
  252. package/reference/gdd-threat-model.md +44 -44
  253. package/reference/gemini-tools.md +3 -3
  254. package/reference/gestalt.md +24 -24
  255. package/reference/heuristics.md +32 -32
  256. package/reference/i18n.md +44 -44
  257. package/reference/iconography.md +24 -24
  258. package/reference/image-optimization.md +14 -14
  259. package/reference/information-architecture.md +47 -47
  260. package/reference/intel-schema.md +1 -1
  261. package/reference/known-failure-modes.md +37 -37
  262. package/reference/meta-rules.md +5 -5
  263. package/reference/migrations/material-3-to-4.md +17 -17
  264. package/reference/migrations/mui-v6.md +16 -16
  265. package/reference/migrations/shadcn-v2.md +25 -25
  266. package/reference/migrations/tailwind-v4.md +21 -21
  267. package/reference/model-prices.md +3 -3
  268. package/reference/model-tiers.md +40 -40
  269. package/reference/motion-advanced.md +21 -21
  270. package/reference/motion-easings.md +29 -29
  271. package/reference/motion-interpolate.md +1 -1
  272. package/reference/motion-spring.md +13 -13
  273. package/reference/motion-transition-taxonomy.md +34 -34
  274. package/reference/motion.md +31 -31
  275. package/reference/multi-author-model.md +13 -13
  276. package/reference/native-platforms.md +28 -28
  277. package/reference/notification-routing.md +6 -6
  278. package/reference/onboarding-progressive-disclosure.md +32 -32
  279. package/reference/openrouter-tier-mapping.md +8 -8
  280. package/reference/palette-catalog.md +37 -37
  281. package/reference/parallelism-rules.md +20 -20
  282. package/reference/peer-cli-capabilities.md +14 -14
  283. package/reference/peer-protocols.md +21 -21
  284. package/reference/perf-budget.md +21 -21
  285. package/reference/performance.md +22 -22
  286. package/reference/platforms.md +51 -51
  287. package/reference/pr-review-integration.md +7 -7
  288. package/reference/prices/antigravity.md +3 -3
  289. package/reference/prices/augment.md +3 -3
  290. package/reference/prices/claude.md +2 -2
  291. package/reference/prices/cline.md +4 -4
  292. package/reference/prices/codebuddy.md +3 -3
  293. package/reference/prices/codex.md +2 -2
  294. package/reference/prices/copilot.md +3 -3
  295. package/reference/prices/cursor.md +3 -3
  296. package/reference/prices/gemini.md +2 -2
  297. package/reference/prices/kilo.md +3 -3
  298. package/reference/prices/opencode.md +4 -4
  299. package/reference/prices/qwen.md +2 -2
  300. package/reference/prices/trae.md +3 -3
  301. package/reference/prices/windsurf.md +3 -3
  302. package/reference/prices.openrouter.md +5 -5
  303. package/reference/print-design.md +36 -36
  304. package/reference/priority-matrix.md +2 -2
  305. package/reference/project-skills-guide.md +3 -3
  306. package/reference/proportion-systems.md +23 -23
  307. package/reference/pseudonymization-rules.md +30 -30
  308. package/reference/registry.json +7 -0
  309. package/reference/retrieval-contract.md +14 -14
  310. package/reference/review-format.md +7 -7
  311. package/reference/rollout-coordination.md +10 -10
  312. package/reference/rtl-cjk-cultural.md +39 -39
  313. package/reference/runtime-models.md +28 -28
  314. package/reference/shared-preamble.md +26 -26
  315. package/reference/skill-authoring-contract.md +16 -16
  316. package/reference/skill-placeholders.md +71 -0
  317. package/reference/start-interview.md +10 -10
  318. package/reference/style-vocabulary.md +25 -25
  319. package/reference/surfaces.md +4 -4
  320. package/reference/ticket-sync.md +9 -9
  321. package/reference/typography.md +64 -64
  322. package/reference/user-research.md +54 -54
  323. package/reference/variable-fonts-loading.md +15 -15
  324. package/reference/visual-hierarchy-layout.md +41 -41
  325. package/scripts/lib/build/factory.cjs +62 -0
  326. package/scripts/lib/build/harness-configs.cjs +64 -0
  327. package/scripts/lib/manifest/prose-denylist.json +1 -1
  328. package/sdk/cli/commands/build.ts +106 -0
  329. package/sdk/cli/index.js +84 -2
  330. package/sdk/cli/index.ts +7 -0
  331. package/skills/add-backlog/SKILL.md +3 -3
  332. package/skills/analyze-dependencies/SKILL.md +10 -10
  333. package/skills/apply-reflections/SKILL.md +13 -13
  334. package/skills/apply-reflections/apply-reflections-procedure.md +20 -20
  335. package/skills/audit/SKILL.md +7 -7
  336. package/skills/bandit-status/SKILL.md +7 -7
  337. package/skills/benchmark/SKILL.md +7 -7
  338. package/skills/bootstrap-ds/SKILL.md +10 -10
  339. package/skills/brief/SKILL.md +20 -20
  340. package/skills/budget/SKILL.md +4 -4
  341. package/skills/cache-manager/SKILL.md +6 -6
  342. package/skills/cache-manager/cache-policy.md +5 -5
  343. package/skills/check-update/SKILL.md +5 -5
  344. package/skills/compare/SKILL.md +15 -15
  345. package/skills/compare/compare-rubric.md +17 -17
  346. package/skills/complete-cycle/SKILL.md +5 -5
  347. package/skills/connections/SKILL.md +11 -11
  348. package/skills/connections/connections-onboarding.md +76 -76
  349. package/skills/continue/SKILL.md +2 -2
  350. package/skills/darkmode/SKILL.md +17 -17
  351. package/skills/darkmode/darkmode-audit-procedure.md +7 -7
  352. package/skills/debug/SKILL.md +3 -3
  353. package/skills/debug/debug-feedback-loops.md +12 -12
  354. package/skills/design/SKILL.md +12 -12
  355. package/skills/design/design-procedure.md +23 -23
  356. package/skills/discover/SKILL.md +7 -7
  357. package/skills/discover/discover-procedure.md +18 -18
  358. package/skills/discuss/SKILL.md +12 -12
  359. package/skills/do/SKILL.md +1 -1
  360. package/skills/explore/SKILL.md +21 -21
  361. package/skills/explore/explore-procedure.md +48 -48
  362. package/skills/export/SKILL.md +9 -9
  363. package/skills/extract-learnings/SKILL.md +5 -5
  364. package/skills/fast/SKILL.md +7 -7
  365. package/skills/figma-extract/SKILL.md +11 -11
  366. package/skills/figma-write/SKILL.md +6 -6
  367. package/skills/graphify/SKILL.md +4 -4
  368. package/skills/health/SKILL.md +16 -16
  369. package/skills/health/health-mcp-detection.md +3 -3
  370. package/skills/health/health-skill-length-report.md +6 -6
  371. package/skills/help/SKILL.md +1 -1
  372. package/skills/list-assumptions/SKILL.md +4 -4
  373. package/skills/map/SKILL.md +12 -12
  374. package/skills/migrate/SKILL.md +5 -5
  375. package/skills/new-cycle/SKILL.md +2 -2
  376. package/skills/new-cycle/milestone-completeness-rubric.md +16 -16
  377. package/skills/new-project/SKILL.md +1 -1
  378. package/skills/next/SKILL.md +5 -5
  379. package/skills/note/SKILL.md +1 -1
  380. package/skills/openrouter-status/SKILL.md +4 -4
  381. package/skills/optimize/SKILL.md +15 -15
  382. package/skills/pause/SKILL.md +5 -5
  383. package/skills/peer-cli-add/SKILL.md +11 -11
  384. package/skills/peer-cli-add/peer-cli-protocol.md +39 -39
  385. package/skills/peer-cli-customize/SKILL.md +14 -14
  386. package/skills/peers/SKILL.md +4 -4
  387. package/skills/plan/SKILL.md +13 -13
  388. package/skills/plan/plan-procedure.md +24 -24
  389. package/skills/plant-seed/SKILL.md +4 -4
  390. package/skills/pr-branch/SKILL.md +2 -2
  391. package/skills/progress/SKILL.md +15 -15
  392. package/skills/quality-gate/SKILL.md +22 -22
  393. package/skills/quality-gate/threat-modeling.md +19 -19
  394. package/skills/quick/SKILL.md +5 -5
  395. package/skills/reapply-patches/SKILL.md +7 -7
  396. package/skills/reflect/SKILL.md +3 -3
  397. package/skills/reflect/procedures/capability-gap-scan.md +11 -11
  398. package/skills/report-issue/SKILL.md +5 -5
  399. package/skills/report-issue/report-issue-procedure.md +27 -27
  400. package/skills/resume/SKILL.md +9 -9
  401. package/skills/review-backlog/SKILL.md +3 -3
  402. package/skills/review-decisions/SKILL.md +3 -3
  403. package/skills/roi/SKILL.md +5 -5
  404. package/skills/rollout-status/SKILL.md +4 -4
  405. package/skills/router/SKILL.md +11 -11
  406. package/skills/router/capability-gap-emitter.md +6 -6
  407. package/skills/router/router-pick-emitter.md +9 -9
  408. package/skills/router/router-rules.md +7 -7
  409. package/skills/scan/SKILL.md +16 -16
  410. package/skills/scan/scan-procedure.md +42 -42
  411. package/skills/settings/SKILL.md +2 -2
  412. package/skills/ship/SKILL.md +7 -7
  413. package/skills/sketch/SKILL.md +10 -10
  414. package/skills/sketch-wrap-up/SKILL.md +12 -12
  415. package/skills/skill-manifest/SKILL.md +5 -5
  416. package/skills/spike/SKILL.md +7 -7
  417. package/skills/spike-wrap-up/SKILL.md +13 -13
  418. package/skills/start/SKILL.md +8 -8
  419. package/skills/start/start-procedure.md +9 -9
  420. package/skills/stats/SKILL.md +5 -5
  421. package/skills/style/SKILL.md +12 -12
  422. package/skills/style/style-doc-procedure.md +12 -12
  423. package/skills/synthesize/SKILL.md +10 -10
  424. package/skills/timeline/SKILL.md +4 -4
  425. package/skills/todo/SKILL.md +3 -3
  426. package/skills/turn-closeout/SKILL.md +10 -10
  427. package/skills/unlock-decision/SKILL.md +3 -3
  428. package/skills/update/SKILL.md +9 -9
  429. package/skills/using-gdd/SKILL.md +17 -17
  430. package/skills/verify/SKILL.md +13 -13
  431. package/skills/verify/verify-procedure.md +34 -34
  432. package/skills/warm-cache/SKILL.md +8 -8
  433. package/skills/watch-authorities/SKILL.md +9 -9
  434. package/skills/zoom-out/SKILL.md +4 -4
@@ -1,27 +1,27 @@
1
1
  # Form Patterns
2
2
 
3
- Forms are one of the highest-friction surfaces in any product. Every unnecessary click, ambiguous label, or poorly-timed error message is a conversion lost or a user abandoned mid-task. The patterns below are grounded in empirical research primarily Luke Wroblewski's eye-tracking studies, WCAG 2.1 requirements, and NCSC/NIST guidance on authentication UX.
3
+ Forms are one of the highest-friction surfaces in any product. Every unnecessary click, ambiguous label, or poorly-timed error message is a conversion lost or a user abandoned mid-task. The patterns below are grounded in empirical research - primarily Luke Wroblewski's eye-tracking studies, WCAG 2.1 requirements, and NCSC/NIST guidance on authentication UX.
4
4
 
5
5
  ---
6
6
 
7
7
  ## 1. Label Position
8
8
 
9
- Wroblewski's eye-tracking research measured the number of eye fixations required to move from label to field across the three common label placements. The findings are decisive: top-aligned labels are fastest because the eye travels in one direction down without a horizontal context switch.
9
+ Wroblewski's eye-tracking research measured the number of eye fixations required to move from label to field across the three common label placements. The findings are decisive: top-aligned labels are fastest because the eye travels in one direction - down - without a horizontal context switch.
10
10
 
11
11
  **Top-aligned labels** are the default for most forms. Completion time is fastest because the label and input form a single vertical unit. They also accommodate longer translated strings without breaking layout, making them the correct default for internationalised products. Use top-aligned labels whenever form complexity is moderate to high or field types are mixed.
12
12
 
13
- **See:** [`./i18n.md`](./i18n.md) §Locale Formatting for the full `Intl.*` family (`NumberFormat`, `DateTimeFormat`, `PluralRules`, `RelativeTimeFormat`, `ListFormat`) over hand-rolled string concatenation never assemble locale-aware strings via template literals. §Text Expansion explains the +30–40% LTR budget that top-aligned labels accommodate.
13
+ **See:** [`./i18n.md`](./i18n.md) §Locale Formatting for the full `Intl.*` family (`NumberFormat`, `DateTimeFormat`, `PluralRules`, `RelativeTimeFormat`, `ListFormat`) over hand-rolled string concatenation - never assemble locale-aware strings via template literals. §Text Expansion explains the +30–40% LTR budget that top-aligned labels accommodate.
14
14
 
15
- **Left-aligned labels** create the slowest completion time because the eye must saccade horizontally from label to field on every row. They earn their place only when scannability of values matters more than speed settings pages, data-entry tables, or read-heavy forms where users compare label and value together. In these contexts the horizontal alignment aids review, not input.
15
+ **Left-aligned labels** create the slowest completion time because the eye must saccade horizontally from label to field on every row. They earn their place only when scannability of values matters more than speed - settings pages, data-entry tables, or read-heavy forms where users compare label and value together. In these contexts the horizontal alignment aids review, not input.
16
16
 
17
- **Floating labels (Material 3 style)** are an acceptable middle ground when screen real estate is severely constrained. The label begins as visible hint text above the field and remains visible (shrunk, repositioned) after the user starts typing. This pattern is distinct from and incompatible with placeholder-as-label. Never use placeholder text as the sole label: when the field receives focus the placeholder disappears, leaving the user to recall what was asked. This is a WCAG 2.1 failure under criterion 1.3.5 (Identify Input Purpose) and a general usability failure on any form longer than three fields.
17
+ **Floating labels (Material 3 style)** are an acceptable middle ground when screen real estate is severely constrained. The label begins as visible hint text above the field and remains visible (shrunk, repositioned) after the user starts typing. This pattern is distinct from - and incompatible with - placeholder-as-label. Never use placeholder text as the sole label: when the field receives focus the placeholder disappears, leaving the user to recall what was asked. This is a WCAG 2.1 failure under criterion 1.3.5 (Identify Input Purpose) and a general usability failure on any form longer than three fields.
18
18
 
19
19
  | Label position | Completion speed | Best use case |
20
20
  |---|---|---|
21
21
  | Top-aligned | Fastest | Most forms; mixed field types; long forms |
22
22
  | Left-aligned | Slowest | Settings pages; data comparison; values matter |
23
23
  | Floating (Material 3) | Medium | Space-constrained mobile forms |
24
- | Placeholder-only | | **Never** WCAG 1.3.5 failure |
24
+ | Placeholder-only | - | **Never** - WCAG 1.3.5 failure |
25
25
 
26
26
  ---
27
27
 
@@ -31,23 +31,23 @@ The timing of inline validation determines whether it helps or hinders. Validate
31
31
 
32
32
  **On-submit only** carries the lowest cognitive load during form completion and is appropriate for short forms (three fields or fewer). The cost is UX debt on long forms: when multiple fields fail at once, the user must scroll up to find errors, fix one, scroll back, and repeat. Provide an error summary at the top if using submit-only validation on long forms (see Section 3).
33
33
 
34
- **On-blur (field exit)** is the recommended default for most forms. Validation fires after the user leaves the field, not while they are in it. This prevents the jarring experience of an error appearing mid-keystroke. The critical rule: never validate on first focus only after the field has been blurred at least once. A pristine, untouched field should never show an error state.
34
+ **On-blur (field exit)** is the recommended default for most forms. Validation fires after the user leaves the field, not while they are in it. This prevents the jarring experience of an error appearing mid-keystroke. The critical rule: never validate on first focus - only after the field has been blurred at least once. A pristine, untouched field should never show an error state.
35
35
 
36
- **On-change (real-time)** is appropriate for two specific cases: password strength meters and character counters. It is not appropriate for format validation such as email addresses. Validating email format on every keystroke flags `hello@` as invalid before the user has finished typing the domain a false negative that erodes trust in the form.
36
+ **On-change (real-time)** is appropriate for two specific cases: password strength meters and character counters. It is not appropriate for format validation such as email addresses. Validating email format on every keystroke flags `hello@` as invalid before the user has finished typing the domain - a false negative that erodes trust in the form.
37
37
 
38
38
  Never show a red error state before the user has had a realistic opportunity to complete the field. The error state is a signal that something is wrong; triggering it prematurely teaches users to ignore it.
39
39
 
40
40
  | Timing | When to use | When to avoid |
41
41
  |---|---|---|
42
42
  | On-submit | Short forms (≤ 3 fields) | Long multi-section forms |
43
- | On-blur | Default for most fields | |
43
+ | On-blur | Default for most fields | - |
44
44
  | On-change | Password strength, character count | Format validation (email, phone) |
45
45
 
46
46
  ---
47
47
 
48
48
  ## 3. Error Placement and Recovery Copy
49
49
 
50
- Errors placed far from their source in a top banner, a modal, or a footer force the user to map the error message back to the problematic field. Errors belong immediately below the field they describe, appearing between the field and the next element in the flow.
50
+ Errors placed far from their source - in a top banner, a modal, or a footer - force the user to map the error message back to the problematic field. Errors belong immediately below the field they describe, appearing between the field and the next element in the flow.
51
51
 
52
52
  **Visual treatment**: error messages must never rely on color alone. A red border communicates nothing to users with red-green color deficiency. Use an error icon alongside the message text. The field border color change is acceptable as a supplemental indicator, not the primary one.
53
53
 
@@ -83,7 +83,7 @@ Marking required fields unambiguously prevents submission errors and sets accura
83
83
 
84
84
  The **asterisk (*) convention** is the web default. Mark every required field with `*` and place the legend "* Required" near the top of the form, before the first field. Users arriving mid-page may not see a legend placed at the bottom.
85
85
 
86
- The **"(optional)" alternative** is better when most fields are required and only a few are not. Marking three optional fields "(optional)" is less visual noise than marking fifteen fields with `*`. Choose one convention per form never mix both. A form that marks some fields `*` and labels others "(optional)" implies that unlabelled fields are neither required nor optional, which is simply confusing.
86
+ The **"(optional)" alternative** is better when most fields are required and only a few are not. Marking three optional fields "(optional)" is less visual noise than marking fifteen fields with `*`. Choose one convention per form - never mix both. A form that marks some fields `*` and labels others "(optional)" implies that unlabelled fields are neither required nor optional, which is simply confusing.
87
87
 
88
88
  Regardless of which visual convention is used, every required field must carry `aria-required="true"` or the native `required` attribute. Screen readers announce the required state from these attributes, not from the visible asterisk.
89
89
 
@@ -103,17 +103,17 @@ Multi-step forms break long processes into manageable stages, but they introduce
103
103
 
104
104
  **Show total step count upfront** and maintain it throughout. "Step 2 of 4" gives the user a completion model. Never add steps mid-flow; if a conditional step becomes necessary, it must have been accounted for in the total from the beginning. Surprise steps feel like bait-and-switch.
105
105
 
106
- **Preserve state between steps** unconditionally. Browser back must restore the previous step with all previously-entered values intact. Losing data on back-navigation is one of the most damaging patterns in multi-step forms it destroys user trust and forces re-entry of work already done. Use session storage, URL state, or in-memory state managed at the form's root level.
106
+ **Preserve state between steps** unconditionally. Browser back must restore the previous step with all previously-entered values intact. Losing data on back-navigation is one of the most damaging patterns in multi-step forms - it destroys user trust and forces re-entry of work already done. Use session storage, URL state, or in-memory state managed at the form's root level.
107
107
 
108
108
  **Allow non-linear completion where the domain permits.** If a user wants to skip to step 3 and complete step 2 later, let them. Stepped progress indicators (like a horizontal stepper component) should be interactive links, not decorative labels, unless there is a hard dependency that makes out-of-order completion genuinely impossible.
109
109
 
110
- **Summary step before final submission.** Any multi-step form that results in a consequential action purchase, account creation, booking should include a review step that shows all entered values before the commit action. The CTA on the summary step should name the action ("Place order", "Create account") not just "Submit".
110
+ **Summary step before final submission.** Any multi-step form that results in a consequential action - purchase, account creation, booking - should include a review step that shows all entered values before the commit action. The CTA on the summary step should name the action ("Place order", "Create account") not just "Submit".
111
111
 
112
112
  ---
113
113
 
114
- ## 6. Autofill Hints `autocomplete` Taxonomy
114
+ ## 6. Autofill Hints - `autocomplete` Taxonomy
115
115
 
116
- The `autocomplete` attribute tells the browser and password managers, autofill services, and mobile OS keyboards exactly what category of data a field expects. Proper use of `autocomplete` tokens reduces form completion time by 15–30% in controlled studies, primarily because browsers and password managers can populate multiple fields in a single tap. Always pair each token with the correct `input type`.
116
+ The `autocomplete` attribute tells the browser - and password managers, autofill services, and mobile OS keyboards - exactly what category of data a field expects. Proper use of `autocomplete` tokens reduces form completion time by 15–30% in controlled studies, primarily because browsers and password managers can populate multiple fields in a single tap. Always pair each token with the correct `input type`.
117
117
 
118
118
  | Token | Meaning | Recommended `input type` |
119
119
  |---|---|---|
@@ -140,7 +140,7 @@ For address fields that are split across multiple inputs, use the sub-tokens (`a
140
140
 
141
141
  ## 7. Input Mode and Enter Key Hints
142
142
 
143
- On mobile devices, `inputmode` controls which virtual keyboard the OS presents, independently of the input's semantic type. `enterkeyhint` controls the label shown on the Enter/Go key. Both attributes are pure UX signals they carry no validation meaning and they cost nothing to add.
143
+ On mobile devices, `inputmode` controls which virtual keyboard the OS presents, independently of the input's semantic type. `enterkeyhint` controls the label shown on the Enter/Go key. Both attributes are pure UX signals - they carry no validation meaning - and they cost nothing to add.
144
144
 
145
145
  ### `inputmode` values
146
146
 
@@ -185,7 +185,7 @@ Password fields carry more UX debt than almost any other input type, largely due
185
185
 
186
186
  **Show/hide toggle** is mandatory on any password field. The eye icon is the standard affordance. Both states must have accessible labels: `aria-label="Show password"` and `aria-label="Hide password"`. The toggle should be positioned as a button inside the trailing edge of the input, using `type="button"` to prevent accidental form submission.
187
187
 
188
- **Never block paste** on password fields. The UK National Cyber Security Centre (NCSC) explicitly recommends against paste-blocking. The rationale is simple: blocking paste discourages the use of password managers, which in turn pushes users toward shorter, simpler, more memorable and therefore weaker passwords. Paste-blocking does not prevent any known attack vector on the server side. Remove any `onpaste="return false"` or equivalent.
188
+ **Never block paste** on password fields. The UK National Cyber Security Centre (NCSC) explicitly recommends against paste-blocking. The rationale is simple: blocking paste discourages the use of password managers, which in turn pushes users toward shorter, simpler, more memorable - and therefore weaker - passwords. Paste-blocking does not prevent any known attack vector on the server side. Remove any `onpaste="return false"` or equivalent.
189
189
 
190
190
  **Password strength meters** belong on new-password creation flows only. Displaying a strength meter on a login form reveals information about the stored password and adds noise to a flow where speed matters. Use `zxcvbn` or an equivalent entropy-based library rather than simple length/character-class rules, which users learn to game (e.g., "Password1!" satisfies most naive rules but is trivially guessable).
191
191
 
@@ -211,18 +211,18 @@ Password fields carry more UX debt than almost any other input type, largely due
211
211
 
212
212
  These three patterns all involve the user acknowledging an outcome, but they operate at different risk levels and require different interaction costs to match.
213
213
 
214
- **Consent checkboxes** govern communication preferences and data use. For marketing communications, the checkbox must be unchecked by default opt-in is required under GDPR and comparable legislation in most jurisdictions. Pre-checked opt-out is only permissible for certain transactional communications or in jurisdictions that explicitly permit it; assume opt-in required unless legal has confirmed otherwise. The checkbox label must be specific about what the user is consenting to "I agree to receive marketing emails from Acme Ltd." rather than "I accept the terms."
214
+ **Consent checkboxes** govern communication preferences and data use. For marketing communications, the checkbox must be unchecked by default - opt-in is required under GDPR and comparable legislation in most jurisdictions. Pre-checked opt-out is only permissible for certain transactional communications or in jurisdictions that explicitly permit it; assume opt-in required unless legal has confirmed otherwise. The checkbox label must be specific about what the user is consenting to - "I agree to receive marketing emails from Acme Ltd." rather than "I accept the terms."
215
215
 
216
- **Confirmation dialogs** are appropriate for irreversible actions that affect data the user owns deleting a file, cancelling a subscription, archiving a project. The confirmation dialog must state exactly what will happen. "Are you sure?" is not a confirmation. "Delete the project 'Website Redesign'? This cannot be undone." is a confirmation. The destructive action button should be visually distinct (typically red or a warning tone) and should not be the default focused element.
216
+ **Confirmation dialogs** are appropriate for irreversible actions that affect data the user owns - deleting a file, cancelling a subscription, archiving a project. The confirmation dialog must state exactly what will happen. "Are you sure?" is not a confirmation. "Delete the project 'Website Redesign'? This cannot be undone." is a confirmation. The destructive action button should be visually distinct (typically red or a warning tone) and should not be the default focused element.
217
217
 
218
- **Destructive-confirmation with typed phrase** applies to catastrophic, irreversible operations: deleting an account, purging all data, permanently revoking access. Require the user to type a specific phrase the account name, the word "DELETE", the number of items being erased before the action becomes available. This pattern exists not to prevent accidents but to ensure the user is making a conscious, deliberate decision. GitHub, Heroku, and most infrastructure tools use this pattern for account deletion. The required phrase should be shown plainly; do not require the user to guess it.
218
+ **Destructive-confirmation with typed phrase** applies to catastrophic, irreversible operations: deleting an account, purging all data, permanently revoking access. Require the user to type a specific phrase - the account name, the word "DELETE", the number of items being erased - before the action becomes available. This pattern exists not to prevent accidents but to ensure the user is making a conscious, deliberate decision. GitHub, Heroku, and most infrastructure tools use this pattern for account deletion. The required phrase should be shown plainly; do not require the user to guess it.
219
219
 
220
220
  | Risk level | Pattern | Example |
221
221
  |---|---|---|
222
- | Low reversible | None needed | Moving a file to trash |
223
- | Medium data loss possible | Confirmation dialog with specific text | Deleting a saved draft |
224
- | High irreversible | Dialog + destructive button style | Cancelling a paid subscription |
225
- | Critical catastrophic | Dialog + type-to-confirm phrase | Deleting an account and all its data |
222
+ | Low - reversible | None needed | Moving a file to trash |
223
+ | Medium - data loss possible | Confirmation dialog with specific text | Deleting a saved draft |
224
+ | High - irreversible | Dialog + destructive button style | Cancelling a paid subscription |
225
+ | Critical - catastrophic | Dialog + type-to-confirm phrase | Deleting an account and all its data |
226
226
 
227
227
  ---
228
228
 
@@ -232,9 +232,9 @@ CAPTCHA presents a genuine tension: friction added to stop bots is friction expe
232
232
 
233
233
  **Invisible CAPTCHA v3** (Google reCAPTCHA v3, Cloudflare Turnstile, hCaptcha Invisible) is the preferred approach. These services score user behaviour in the background and surface a challenge only when the risk score exceeds a threshold. Typical deployments have challenge rates under 1% for real users. There is no visible puzzle, no audio fallback needed for the happy path.
234
234
 
235
- **When a visible challenge is unavoidable**, WCAG 1.1.1 requires a non-visual alternative. Every visual CAPTCHA must have an audio alternative that is solvable with a screen reader and no visual ability. Text-based CAPTCHAs distorted beyond normal variance effectively exclude users with dyslexia and cognitive disabilities treat this as a legal and ethical risk, not just a UX inconvenience.
235
+ **When a visible challenge is unavoidable**, WCAG 1.1.1 requires a non-visual alternative. Every visual CAPTCHA must have an audio alternative that is solvable with a screen reader and no visual ability. Text-based CAPTCHAs distorted beyond normal variance effectively exclude users with dyslexia and cognitive disabilities - treat this as a legal and ethical risk, not just a UX inconvenience.
236
236
 
237
- **Time-limited CAPTCHAs** those that expire while a slow or motor-impaired user is completing them are inaccessible by design and should never be used. If a CAPTCHA session can time out, the user must be able to request a refresh without losing their form data.
237
+ **Time-limited CAPTCHAs** - those that expire while a slow or motor-impaired user is completing them - are inaccessible by design and should never be used. If a CAPTCHA session can time out, the user must be able to request a refresh without losing their form data.
238
238
 
239
239
  **Progressive trust** is the most human approach for authenticated flows. A logged-in user with a verified email and account history presents a negligible bot risk. Do not require CAPTCHA from authenticated users unless there is a specific elevated-risk action (e.g., a bulk API call or mass send). Reserve CAPTCHA friction for unauthenticated, rate-limited, or anomalous-behaviour scenarios.
240
240
 
@@ -2,20 +2,20 @@
2
2
 
3
3
  # Framer Motion Patterns
4
4
 
5
- Framer Motion is the standard animation library for React. It abstracts the browser's animation primitives into a declarative API that stays out of your way for common cases while exposing full physics-based control when you need it. This reference covers implementation patterns not just the API, but _why_ each pattern exists and when to apply it.
5
+ Framer Motion is the standard animation library for React. It abstracts the browser's animation primitives into a declarative API that stays out of your way for common cases while exposing full physics-based control when you need it. This reference covers implementation patterns - not just the API, but _why_ each pattern exists and when to apply it.
6
6
 
7
7
  ---
8
8
 
9
- ## 1. Basics motion components
9
+ ## 1. Basics - motion components
10
10
 
11
11
  Any HTML (or SVG) element can become a motion component by prefixing it with `motion.`. The most common variants are `motion.div`, `motion.span`, `motion.button`, and `motion.li`, but `motion.section`, `motion.a`, `motion.img`, and any other HTML element follow the same pattern.
12
12
 
13
13
  The four primary animation props are:
14
14
 
15
- - **`initial`** the state the element starts in before it mounts (or before a transition begins). Without `initial`, the element won't animate _from_ anything it'll just be in the `animate` state on mount. Always provide `initial` when you want an entrance animation.
16
- - **`animate`** the state the element should animate _to_. Framer drives the element toward this state whenever it changes.
17
- - **`exit`** the state the element animates _to_ when it unmounts. Requires `<AnimatePresence>` as a parent see Section 3.
18
- - **`transition`** controls how the animation happens (spring, tween, duration, ease). If omitted, Framer applies a spring by default for layout/positional changes and a tween for opacity.
15
+ - **`initial`** - the state the element starts in before it mounts (or before a transition begins). Without `initial`, the element won't animate _from_ anything - it'll just be in the `animate` state on mount. Always provide `initial` when you want an entrance animation.
16
+ - **`animate`** - the state the element should animate _to_. Framer drives the element toward this state whenever it changes.
17
+ - **`exit`** - the state the element animates _to_ when it unmounts. Requires `<AnimatePresence>` as a parent - see Section 3.
18
+ - **`transition`** - controls how the animation happens (spring, tween, duration, ease). If omitted, Framer applies a spring by default for layout/positional changes and a tween for opacity.
19
19
 
20
20
  A basic fade-in example:
21
21
 
@@ -35,17 +35,17 @@ function FadeIn({ children }: { children: React.ReactNode }) {
35
35
  }
36
36
  ```
37
37
 
38
- The slight `y: 8` offset on entry gives the element a sense of emerging from below a common, subtle entrance pattern. The `easeOut` ease starts fast and slows at the end, which feels responsive.
38
+ The slight `y: 8` offset on entry gives the element a sense of emerging from below - a common, subtle entrance pattern. The `easeOut` ease starts fast and slows at the end, which feels responsive.
39
39
 
40
40
  ---
41
41
 
42
42
  ## 2. Spring vs. Tween Configuration
43
43
 
44
- Framer Motion supports two fundamentally different animation models. Choosing between them is not arbitrary each has a domain where it clearly wins.
44
+ Framer Motion supports two fundamentally different animation models. Choosing between them is not arbitrary - each has a domain where it clearly wins.
45
45
 
46
46
  ### Spring physics (preferred for UI motion)
47
47
 
48
- Springs model the physics of a real spring: the element overshoots slightly and settles. This is why spring motion _feels natural_ real objects in the world have inertia and settle under physical forces. For UI, spring motion communicates responsiveness and quality.
48
+ Springs model the physics of a real spring: the element overshoots slightly and settles. This is why spring motion _feels natural_ - real objects in the world have inertia and settle under physical forces. For UI, spring motion communicates responsiveness and quality.
49
49
 
50
50
  `type: "spring"` is Framer's default for layout animations and positional changes. Key parameters:
51
51
 
@@ -54,10 +54,10 @@ Springs model the physics of a real spring: the element overshoots slightly and
54
54
  - **`mass`** (0.5–2): adds inertia. Higher mass makes the element feel heavier and slower to respond.
55
55
 
56
56
  The relationship that matters in practice:
57
- - **High stiffness + high damping = snappy** fast arrival, no bounce. This is the production UI default.
58
- - **Low stiffness + low damping = bouncy** never use in production UI. Bounce feels playful and toy-like, which is wrong for most product contexts.
57
+ - **High stiffness + high damping = snappy** - fast arrival, no bounce. This is the production UI default.
58
+ - **Low stiffness + low damping = bouncy** - never use in production UI. Bounce feels playful and toy-like, which is wrong for most product contexts.
59
59
 
60
- **Hard constraint: `bounce: 0` always for icon cross-fades and micro-interactions.** The `bounce` shorthand parameter is a convenience alias setting it to 0 ensures no oscillation. "Bounce must be zero" is a non-negotiable rule for any interaction that fires frequently or in information-dense UI.
60
+ **Hard constraint: `bounce: 0` always for icon cross-fades and micro-interactions.** The `bounce` shorthand parameter is a convenience alias - setting it to 0 ensures no oscillation. "Bounce must be zero" is a non-negotiable rule for any interaction that fires frequently or in information-dense UI.
61
61
 
62
62
  Recommended production preset:
63
63
 
@@ -69,16 +69,16 @@ This is snappy and clean. It arrives fast and settles without any visible oscill
69
69
 
70
70
  ### Tween (for duration-controlled, eased animations)
71
71
 
72
- Tween animations run over a fixed duration with a specified easing curve. Use them when exact timing matters opacity fades, color transitions, anything where you need predictable, duration-controlled behavior rather than physics.
72
+ Tween animations run over a fixed duration with a specified easing curve. Use them when exact timing matters - opacity fades, color transitions, anything where you need predictable, duration-controlled behavior rather than physics.
73
73
 
74
74
  ```tsx
75
75
  transition={{ type: 'tween', duration: 0.2, ease: 'easeOut' }}
76
76
  ```
77
77
 
78
78
  Ease guidance:
79
- - **`"easeOut"`** for entrances starts fast (feels responsive), decelerates to rest.
80
- - **`"easeIn"`** for exits accelerates away, gets out of the way quickly.
81
- - **`"easeInOut"`** for emphasis transitions smooth acceleration and deceleration, used when the same element transitions between states (not entering/exiting).
79
+ - **`"easeOut"`** for entrances - starts fast (feels responsive), decelerates to rest.
80
+ - **`"easeIn"`** for exits - accelerates away, gets out of the way quickly.
81
+ - **`"easeInOut"`** for emphasis transitions - smooth acceleration and deceleration, used when the same element transitions between states (not entering/exiting).
82
82
 
83
83
  The rule of thumb: use springs for movement and scale; use tweens for opacity, color, and blur.
84
84
 
@@ -86,7 +86,7 @@ The rule of thumb: use springs for movement and scale; use tweens for opacity, c
86
86
 
87
87
  ## 3. AnimatePresence
88
88
 
89
- `AnimatePresence` is the component that enables exit animations. Without it, React unmounts components immediately, and `exit` props are never executed the element simply vanishes.
89
+ `AnimatePresence` is the component that enables exit animations. Without it, React unmounts components immediately, and `exit` props are never executed - the element simply vanishes.
90
90
 
91
91
  ```tsx
92
92
  import { AnimatePresence, motion } from 'framer-motion'
@@ -116,13 +116,13 @@ Every child of `AnimatePresence` that will be conditionally rendered **must have
116
116
 
117
117
  The `mode` prop controls how entering and exiting elements interact during a transition:
118
118
 
119
- - **`mode: "wait"`** the exiting element completes its exit animation fully before the entering element begins its entrance. Use this for route transitions and tab panel swaps, where showing two elements simultaneously would be confusing.
120
- - **`mode: "sync"`** enter and exit animations run simultaneously. Use this when you're swapping UI elements (like icon cross-fades) and want both transitions to happen at once.
121
- - **`mode: "popLayout"`** the exiting element immediately pops out of the document flow so surrounding elements can animate into their new positions right away, while the exiting element still plays its exit animation. Ideal for list item removal.
119
+ - **`mode: "wait"`** - the exiting element completes its exit animation fully before the entering element begins its entrance. Use this for route transitions and tab panel swaps, where showing two elements simultaneously would be confusing.
120
+ - **`mode: "sync"`** - enter and exit animations run simultaneously. Use this when you're swapping UI elements (like icon cross-fades) and want both transitions to happen at once.
121
+ - **`mode: "popLayout"`** - the exiting element immediately pops out of the document flow so surrounding elements can animate into their new positions right away, while the exiting element still plays its exit animation. Ideal for list item removal.
122
122
 
123
123
  ### Critical rule: `<AnimatePresence initial={false}>`
124
124
 
125
- When `AnimatePresence` wraps persistent UI that already exists on first render like a tab panel that's visible on page load, or a sidebar that's open by default you must pass `initial={false}`:
125
+ When `AnimatePresence` wraps persistent UI that already exists on first render - like a tab panel that's visible on page load, or a sidebar that's open by default - you must pass `initial={false}`:
126
126
 
127
127
  ```tsx
128
128
  <AnimatePresence initial={false}>
@@ -134,13 +134,13 @@ When `AnimatePresence` wraps persistent UI that already exists on first render
134
134
  </AnimatePresence>
135
135
  ```
136
136
 
137
- Without `initial={false}`, every component inside `AnimatePresence` will play its entrance animation on first mount, even when the user didn't trigger it. This is jarring and wrong **never animate on initial load for existing UI**.
137
+ Without `initial={false}`, every component inside `AnimatePresence` will play its entrance animation on first mount, even when the user didn't trigger it. This is jarring and wrong - **never animate on initial load for existing UI**.
138
138
 
139
139
  ---
140
140
 
141
141
  ## 4. Layout Animations
142
142
 
143
- The `layout` prop is one of Framer Motion's most powerful features. Add `layout` to a `motion` component, and Framer automatically detects when the component's position or size changes in the DOM and animates it from the old layout to the new one even if the change was caused by other elements shifting around it.
143
+ The `layout` prop is one of Framer Motion's most powerful features. Add `layout` to a `motion` component, and Framer automatically detects when the component's position or size changes in the DOM and animates it from the old layout to the new one - even if the change was caused by other elements shifting around it.
144
144
 
145
145
  ```tsx
146
146
  <motion.div layout className="card">
@@ -150,7 +150,7 @@ The `layout` prop is one of Framer Motion's most powerful features. Add `layout`
150
150
 
151
151
  When `isExpanded` changes, Framer measures the old and new layouts and smoothly animates the transition. This works for position changes caused by sibling elements reordering, parent resizing, or content toggling.
152
152
 
153
- **`layoutId` shared element transitions:** Assign the same `layoutId` to two different components, and Framer will morph between them when one unmounts and the other mounts. This is the canonical implementation for expanding card → detail transitions and hero → full-view animations.
153
+ **`layoutId` - shared element transitions:** Assign the same `layoutId` to two different components, and Framer will morph between them when one unmounts and the other mounts. This is the canonical implementation for expanding card → detail transitions and hero → full-view animations.
154
154
 
155
155
  ```tsx
156
156
  // Card in list view
@@ -160,7 +160,7 @@ When `isExpanded` changes, Framer measures the old and new layouts and smoothly
160
160
  <motion.img layoutId={`product-image-${id}`} src={fullImage} />
161
161
  ```
162
162
 
163
- When the list-view card unmounts and the modal mounts, Framer animates the image from its list-view position to its modal position. The two components don't need to coexist the transition bridges the gap.
163
+ When the list-view card unmounts and the modal mounts, Framer animates the image from its list-view position to its modal position. The two components don't need to coexist - the transition bridges the gap.
164
164
 
165
165
  **Important:** ensure only one component with a given `layoutId` is mounted at a time. Two simultaneously mounted components with the same `layoutId` will fight each other and produce broken animations.
166
166
 
@@ -206,9 +206,9 @@ function AnimatedList({ items }) {
206
206
  }
207
207
  ```
208
208
 
209
- **Propagation:** When a parent has `variants` and `animate="visible"`, child `motion` components that also have `variants` will automatically receive the same `animate` value they don't need their own `animate` prop. Framer propagates the state name down the tree.
209
+ **Propagation:** When a parent has `variants` and `animate="visible"`, child `motion` components that also have `variants` will automatically receive the same `animate` value - they don't need their own `animate` prop. Framer propagates the state name down the tree.
210
210
 
211
- **`staggerChildren`** delays each child's animation start by the specified seconds after the previous child. A value of `0.05` means each item enters 50ms after the previous the standard for list entrance animations. More than `0.08` seconds starts to feel slow; more than 6–8 items should stagger in parallel (`staggerChildren` + `staggerDirection` with a cap).
211
+ **`staggerChildren`** delays each child's animation start by the specified seconds after the previous child. A value of `0.05` means each item enters 50ms after the previous - the standard for list entrance animations. More than `0.08` seconds starts to feel slow; more than 6–8 items should stagger in parallel (`staggerChildren` + `staggerDirection` with a cap).
212
212
 
213
213
  **`delayChildren`** adds an initial delay before the first child begins, which gives the parent time to render visibly before its children start entering.
214
214
 
@@ -218,7 +218,7 @@ function AnimatedList({ items }) {
218
218
 
219
219
  Framer Motion provides props that animate elements in response to user gestures without requiring event handlers or state.
220
220
 
221
- **`whileHover`:** The animation state while the pointer is hovering. Prefer subtle transforms `scale: 1.02` for a gentle grow or `y: -2` for a subtle lift. Avoid large scale values (> 1.05) on UI elements; they feel unstable.
221
+ **`whileHover`:** The animation state while the pointer is hovering. Prefer subtle transforms - `scale: 1.02` for a gentle grow or `y: -2` for a subtle lift. Avoid large scale values (> 1.05) on UI elements; they feel unstable.
222
222
 
223
223
  ```tsx
224
224
  <motion.button whileHover={{ scale: 1.02 }} transition={{ type: 'spring', stiffness: 400, damping: 30 }}>
@@ -238,7 +238,7 @@ Framer Motion provides props that animate elements in response to user gestures
238
238
  </motion.button>
239
239
  ```
240
240
 
241
- **`drag` + `dragConstraints`:** Enable drag with `drag` (either `true`, `"x"`, or `"y"`), and bound the drag region with `dragConstraints`. Use `dragElastic: 0.1` for a subtle resistance when dragging beyond the constraint boundaries this gives physical feedback that the user has reached an edge.
241
+ **`drag` + `dragConstraints`:** Enable drag with `drag` (either `true`, `"x"`, or `"y"`), and bound the drag region with `dragConstraints`. Use `dragElastic: 0.1` for a subtle resistance when dragging beyond the constraint boundaries - this gives physical feedback that the user has reached an edge.
242
242
 
243
243
  ```tsx
244
244
  <motion.div
@@ -289,13 +289,13 @@ Use `style={{ y }}` (not `animate`) for scroll-linked values because `animate` c
289
289
  </motion.section>
290
290
  ```
291
291
 
292
- **`viewport={{ once: true }}`** is the preferred option for entrance animations the element animates in once and stays visible. Without `once: true`, the element will animate every time it enters the viewport, which is usually wrong for entrance effects (and can feel janky during fast scrolling).
292
+ **`viewport={{ once: true }}`** is the preferred option for entrance animations - the element animates in once and stays visible. Without `once: true`, the element will animate every time it enters the viewport, which is usually wrong for entrance effects (and can feel janky during fast scrolling).
293
293
 
294
294
  ---
295
295
 
296
296
  ## 8. prefers-reduced-motion Compliance
297
297
 
298
- Respecting `prefers-reduced-motion` is **mandatory** for accessibility compliance. Some users have vestibular disorders or motion sensitivity for them, unnecessary motion causes real physical discomfort. This is not optional polish; it is a WCAG 2.1 requirement.
298
+ Respecting `prefers-reduced-motion` is **mandatory** for accessibility compliance. Some users have vestibular disorders or motion sensitivity - for them, unnecessary motion causes real physical discomfort. This is not optional polish; it is a WCAG 2.1 requirement.
299
299
 
300
300
  ### Per-component approach with `useReducedMotion`
301
301
 
@@ -321,11 +321,11 @@ function AnimatedCard() {
321
321
  }
322
322
  ```
323
323
 
324
- When `prefersReducedMotion` is true, set `duration: 0` and remove any positional animation values the element should appear instantly without motion.
324
+ When `prefersReducedMotion` is true, set `duration: 0` and remove any positional animation values - the element should appear instantly without motion.
325
325
 
326
326
  ### App-wide approach with `MotionConfig` (preferred)
327
327
 
328
- The cleanest solution for most applications is to wrap the app root with `MotionConfig` using `reducedMotion: "user"`. This instructs Framer to automatically apply reduced-motion behavior for all motion components in the subtree when the OS preference is set no per-component logic needed.
328
+ The cleanest solution for most applications is to wrap the app root with `MotionConfig` using `reducedMotion: "user"`. This instructs Framer to automatically apply reduced-motion behavior for all motion components in the subtree when the OS preference is set - no per-component logic needed.
329
329
 
330
330
  ```tsx
331
331
  import { MotionConfig } from 'framer-motion'
@@ -339,18 +339,18 @@ function App() {
339
339
  }
340
340
  ```
341
341
 
342
- `reducedMotion: "user"` reads the OS setting via `prefers-reduced-motion` media query and disables animations globally when it's set. This is the preferred approach because it's zero-maintenance adding new animated components automatically inherits the behavior.
342
+ `reducedMotion: "user"` reads the OS setting via `prefers-reduced-motion` media query and disables animations globally when it's set. This is the preferred approach because it's zero-maintenance - adding new animated components automatically inherits the behavior.
343
343
 
344
344
  ---
345
345
 
346
346
  ## 9. 60fps Performance Rules
347
347
 
348
- Animation performance on the web comes down to a single principle: **only animate properties that the browser can handle on the GPU compositor thread**. Everything else requires the browser to recalculate layout or repaint pixels work that happens on the main thread and causes dropped frames.
348
+ Animation performance on the web comes down to a single principle: **only animate properties that the browser can handle on the GPU compositor thread**. Everything else requires the browser to recalculate layout or repaint pixels - work that happens on the main thread and causes dropped frames.
349
349
 
350
350
  ### Properties that are GPU-safe (always use these)
351
351
 
352
- - `x`, `y` map to `translateX()` and `translateY()` in `transform`
353
- - `scale`, `scaleX`, `scaleY` map to `scale()` in `transform`
352
+ - `x`, `y` - map to `translateX()` and `translateY()` in `transform`
353
+ - `scale`, `scaleX`, `scaleY` - map to `scale()` in `transform`
354
354
  - `rotate`, `rotateX`, `rotateY`, `rotateZ`
355
355
  - `skewX`, `skewY`
356
356
  - `opacity`
@@ -359,17 +359,17 @@ These properties run on the compositor thread and never block the main thread, r
359
359
 
360
360
  ### Properties that cause jank (never animate these)
361
361
 
362
- - `width`, `height` triggers layout recalculation on every frame
363
- - `margin`, `padding` shifts surrounding elements, triggers full reflow
362
+ - `width`, `height` - triggers layout recalculation on every frame
363
+ - `margin`, `padding` - shifts surrounding elements, triggers full reflow
364
364
  - `border-width`
365
- - `left`, `top`, `right`, `bottom` (on positioned elements) triggers layout
366
- - `font-size` triggers layout and repaint
365
+ - `left`, `top`, `right`, `bottom` (on positioned elements) - triggers layout
366
+ - `font-size` - triggers layout and repaint
367
367
 
368
- If you need to animate a size change, use `scale` on a wrapper. If you need to animate position, use `x`/`y` rather than `left`/`top`. This distinction is why Framer's layout animation system (Section 4) works it uses `transform` internally even when responding to layout-driven position changes.
368
+ If you need to animate a size change, use `scale` on a wrapper. If you need to animate position, use `x`/`y` rather than `left`/`top`. This distinction is why Framer's layout animation system (Section 4) works - it uses `transform` internally even when responding to layout-driven position changes.
369
369
 
370
370
  ### `will-change: transform`
371
371
 
372
- Only add `will-change: transform` when you observe a first-frame stutter on a specific element. Do not add it preemptively it forces the browser to allocate a separate GPU layer for the element immediately, consuming GPU memory whether or not the animation is actually playing. Reserve it for elements with known performance issues after profiling.
372
+ Only add `will-change: transform` when you observe a first-frame stutter on a specific element. Do not add it preemptively - it forces the browser to allocate a separate GPU layer for the element immediately, consuming GPU memory whether or not the animation is actually playing. Reserve it for elements with known performance issues after profiling.
373
373
 
374
374
  ---
375
375
 
@@ -377,9 +377,9 @@ Only add `will-change: transform` when you observe a first-frame stutter on a sp
377
377
 
378
378
  `MotionConfig` is a context provider that configures all `motion` components within its subtree. Use it for:
379
379
 
380
- - **Reduced motion compliance** as shown in Section 8, `reducedMotion: "user"` is the cleanest global solution.
381
- - **Global transition defaults** set a default transition for all motion components so individual components don't need to repeat the same `transition` prop.
382
- - **Custom ease functions** define a custom cubic-bezier ease once and reference it by name throughout the tree.
380
+ - **Reduced motion compliance** - as shown in Section 8, `reducedMotion: "user"` is the cleanest global solution.
381
+ - **Global transition defaults** - set a default transition for all motion components so individual components don't need to repeat the same `transition` prop.
382
+ - **Custom ease functions** - define a custom cubic-bezier ease once and reference it by name throughout the tree.
383
383
 
384
384
  ```tsx
385
385
  <MotionConfig
@@ -398,14 +398,14 @@ With this configuration, every `motion` component that doesn't specify its own `
398
398
 
399
399
  These are the mistakes that appear most frequently in codebases using Framer Motion:
400
400
 
401
- **Missing `initial` with `animate`:** If you add `animate={{ opacity: 1 }}` without `initial={{ opacity: 0 }}`, the element is already at opacity 1 on mount there's nothing to animate from. Always pair `animate` with `initial` when you want an entrance effect.
401
+ **Missing `initial` with `animate`:** If you add `animate={{ opacity: 1 }}` without `initial={{ opacity: 0 }}`, the element is already at opacity 1 on mount - there's nothing to animate from. Always pair `animate` with `initial` when you want an entrance effect.
402
402
 
403
403
  **Missing `key` props in `AnimatePresence`:** Exit animations will silently not fire if children of `AnimatePresence` don't have `key` props. Framer can't identify which element is leaving without a stable key.
404
404
 
405
405
  **Variant propagation only reaches `motion` children:** Parent variants propagate to child `motion` components, but not to plain HTML children or non-motion React components. If a list item is a plain `<li>` instead of `<motion.li>`, it won't receive the parent's variant orchestration.
406
406
 
407
- **`layoutId` conflicts:** If two components with the same `layoutId` are both mounted simultaneously even briefly during a transition Framer doesn't know which is the source and which is the target. The result is erratic, broken animation. Ensure mutual exclusivity: when one mounts, the other must have already unmounted.
407
+ **`layoutId` conflicts:** If two components with the same `layoutId` are both mounted simultaneously - even briefly during a transition - Framer doesn't know which is the source and which is the target. The result is erratic, broken animation. Ensure mutual exclusivity: when one mounts, the other must have already unmounted.
408
408
 
409
- **Unnecessary `AnimatePresence` nesting:** Nesting `AnimatePresence` inside another `AnimatePresence` complicates exit orchestration inner exits may not complete before outer exits begin. Keep the tree flat; use a single `AnimatePresence` at the appropriate level.
409
+ **Unnecessary `AnimatePresence` nesting:** Nesting `AnimatePresence` inside another `AnimatePresence` complicates exit orchestration - inner exits may not complete before outer exits begin. Keep the tree flat; use a single `AnimatePresence` at the appropriate level.
410
410
 
411
411
  **Wrapping everything in `motion.div`:** `motion.div` carries a slightly larger bundle footprint than a plain `div` because it registers the element with Framer's animation engine. Don't wrap static, unanimated elements. Only wrap elements that actually need animation. Reserve `motion.*` for elements where animation provides genuine value.
@@ -1,15 +1,15 @@
1
1
  # GDD Runtime Static Security Audit
2
2
 
3
- **Phase:** 33.5 GDD Runtime Security Hardening · **Plan:** 33.5-02 (Wave A) · **Date:** 2026-05-31
3
+ **Phase:** 33.5 - GDD Runtime Security Hardening · **Plan:** 33.5-02 (Wave A) · **Date:** 2026-05-31
4
4
  **Reference:** branch `phase/33-5-runtime-security`
5
- **Scope:** the SHIPPED runtime surface `hooks/`, `scripts/`, `sdk/`, `bin/`.
5
+ **Scope:** the SHIPPED runtime surface - `hooks/`, `scripts/`, `sdk/`, `bin/`.
6
6
  **Method:** static enumeration (read-only source inspection, no execution, no network).
7
7
  **Companions:**
8
8
 
9
- - `scripts/security/outbound-allowlist.json` the machine-readable, CANONICAL active-egress
9
+ - `scripts/security/outbound-allowlist.json` - the machine-readable, CANONICAL active-egress
10
10
  allowlist that Phase 33.5-04's `scripts/scan-outbound-network.cjs` gate `JSON.parse`s (this
11
11
  report is its human-readable rationale).
12
- - `reference/gdd-threat-model.md` the STRIDE threat model (Phase 33.5-01).
12
+ - `reference/gdd-threat-model.md` - the STRIDE threat model (Phase 33.5-01).
13
13
 
14
14
  This audit freezes the egress / secret / external-input picture so any *future* surface that is
15
15
  not pre-approved trips the 33.5-04 gate at CI time. It is grounded in the CONTEXT real-tree sweep
@@ -21,10 +21,10 @@ not pre-approved trips the 33.5-04 gate at CI time. It is grounded in the CONTEX
21
21
 
22
22
  GDD's runtime makes outbound calls (or local IPC/server binds) from exactly the sites below. Each
23
23
  maps to an `outbound-allowlist.json` directory glob (see the **Allowlisted** column). The 33.5-04
24
- gate is **ACTIVE-egress-only** it matches `require`/`import` of `node:http(s)`/`http(s)`/`ws`/
24
+ gate is **ACTIVE-egress-only** - it matches `require`/`import` of `node:http(s)`/`http(s)`/`ws`/
25
25
  `node-fetch`/`axios`/`undici`, `fetch(`, `http(s).get/.request(`, `new WebSocket`/`new
26
26
  WebSocketServer`/`WebSocketServer(`, and child-process `spawn`/`spawnSync`/`exec*` of
27
- `gh|curl|wget|nc|ssh|scp` so a bare URL string alone never trips it.
27
+ `gh|curl|wget|nc|ssh|scp` - so a bare URL string alone never trips it.
28
28
 
29
29
  | File | What it calls | Transport | Legitimacy | Allowlisted by |
30
30
  | --- | --- | --- | --- | --- |
@@ -40,7 +40,7 @@ WebSocketServer`/`WebSocketServer(`, and child-process `spawn`/`spawnSync`/`exec
40
40
  | `scripts/e2e/run-headless.ts` | live Anthropic API run | REST (key-gated) | Test infrastructure only; gated on `ANTHROPIC_API_KEY` + main-branch; never in default `npm test` | `scripts/e2e/**` |
41
41
  | `scripts/lib/authority-watcher/index.cjs` | authority-feed classification of already-fetched records | (delegated) | The live article fetch is delegated to `agents/design-authority-watcher.md`; `index.cjs` is the pure-CommonJS classifier. Allowlisted so any direct feed fetch added here stays pre-approved | `scripts/lib/authority-watcher/**` |
42
42
 
43
- **Documented but NOT hard-gated** (the scanner scope is `.js`-family + active-egress only
43
+ **Documented but NOT hard-gated** (the scanner scope is `.js`-family + active-egress only -
44
44
  these cannot exfiltrate on their own and are covered by gitleaks + the threat model):
45
45
 
46
46
  | File / surface | What it is | Why not gated |
@@ -50,8 +50,8 @@ these cannot exfiltrate on their own and are covered by gitleaks + the threat mo
50
50
  | `scripts/lib/install/merge.cjs` (line 85) | "Plugin repository: https://github.com/hegemonart/get-design-done" printed string | bare URL string, no call |
51
51
  | `scripts/lib/issue-reporter/destination.cjs` (lines 29–30) | frozen `DESTINATION_URL` / `ISSUE_TEMPLATE_URL` constants | constants consumed only via the `gh` spawn above |
52
52
  | `scripts/lint-agentskills-spec.cjs` (line 76) | spec-example URL in a comment | bare URL string, no call |
53
- | `hooks/update-check.sh` | shell update-check egress | shell script outside the `.{js,cjs,mjs,ts}` scanner scope |
54
- | `scripts/bootstrap.sh` | shell bootstrap egress | shell script outside the `.{js,cjs,mjs,ts}` scanner scope |
53
+ | `hooks/update-check.sh` | shell update-check egress | shell script - outside the `.{js,cjs,mjs,ts}` scanner scope |
54
+ | `scripts/bootstrap.sh` | shell bootstrap egress | shell script - outside the `.{js,cjs,mjs,ts}` scanner scope |
55
55
 
56
56
  ---
57
57
 
@@ -64,7 +64,7 @@ Where a token/key/credential is read, forwarded, or scrubbed across the shipped
64
64
  | `scripts/lib/redact.cjs` | PEM, JWT, Anthropic `sk-ant-`, Stripe `sk_live_`, Slack `xox*`, GitHub `ghp_`, AWS `AKIA`, generic `sk-` (8 patterns) | **scrub** | Deep-walks event-stream payloads at serialize time so everything that hits disk / a bus subscriber is `[REDACTED:<type>]`. **D-07 extends** with Gemini `AIza…`, GitHub fine-grained `github_pat_`, and GitHub `ghs_/gho_/ghu_/ghr_` (currently uncovered). |
65
65
  | `scripts/lib/peer-cli/acp-client.cjs` (line 102) | full `process.env` | **forward** (default) | `const env = opts.env … : process.env` → GDD's `ANTHROPIC_API_KEY`/`GH_TOKEN`/`GDD_*` leak to a spawned peer when `opts.env` is absent. **Fixed by 33.5-04** (allowlist-forward, default-deny, shared `sanitize-env`). |
66
66
  | `scripts/lib/peer-cli/asp-client.cjs` (line 122) | full `process.env` | **forward** (default) | Same default-inherit gap; same 33.5-04 fix. |
67
- | `scripts/lib/figma-extract/pull.cjs` | `FIGMA_TOKEN` / `FIGMA_PERSONAL_ACCESS_TOKEN` | **read** | Lives only inside caller-provided `headers`; NEVER written to disk, NEVER logged (diagnostics read a short body prefix, never the token D-10 of the figma sub-plan). |
67
+ | `scripts/lib/figma-extract/pull.cjs` | `FIGMA_TOKEN` / `FIGMA_PERSONAL_ACCESS_TOKEN` | **read** | Lives only inside caller-provided `headers`; NEVER written to disk, NEVER logged (diagnostics read a short body prefix, never the token - D-10 of the figma sub-plan). |
68
68
  | `scripts/lib/issue-reporter/gh-submit.cjs` / `dedup.cjs` | none held by GDD | **delegate** | Authentication is `gh`'s own logged-in credential store; GDD never reads or forwards a GitHub token for these spawns. |
69
69
 
70
70
  ---
@@ -77,32 +77,32 @@ Where untrusted data crosses a trust boundary into GDD's runtime.
77
77
  | --- | --- | --- | --- |
78
78
  | WebSocket upgrade request | a remote client connecting to the event-stream WS | `scripts/lib/transports/ws.cjs` HTTP `upgrade` handler | Bearer-token gate (≥8 chars) already ships; **33.5-03** adds 127.0.0.1-default bind + timing-safe compare so the default config does not expose `0.0.0.0`. |
79
79
  | gdd-state MCP tool inputs | the MCP client / model | `sdk/mcp/gdd-state/tools/*.ts` (11 tools) + `tools/shared.ts` | Each tool has a JSON schema under `sdk/mcp/gdd-state/schemas/`; **33.5-08** tightens them (`additionalProperties:false` + `maxLength`) and adds a payload-size cap (JSON-bomb guard). |
80
- | `GDD_STATE_PATH` env override | the launching environment | `sdk/mcp/gdd-state/tools/shared.ts:resolveStatePath()` (line 60–61) | `process.env['GDD_STATE_PATH'] ?? .design/STATE.md` with **no path-traversal guard** today `..`/absolute-outside escape is unchecked. **Closed by 33.5-08** (resolve + assert within project root / `.design/`). |
80
+ | `GDD_STATE_PATH` env override | the launching environment | `sdk/mcp/gdd-state/tools/shared.ts:resolveStatePath()` (line 60–61) | `process.env['GDD_STATE_PATH'] ?? .design/STATE.md` with **no path-traversal guard** today - `..`/absolute-outside escape is unchecked. **Closed by 33.5-08** (resolve + assert within project root / `.design/`). |
81
81
  | `.design/config.json` | a repo-local config file (potentially attacker-influenced in a malicious clone) | 14 modules incl. `scripts/lib/peer-cli/registry.cjs` (line 154) | Drives `peer_cli.enabled_peers` / (33.5) `peer_cli.env_allowlist`, the WS `event_stream.bind_host`, and the issue-reporter kill-switch. Parsed defensively; opt-in by design (a peer must be explicitly enabled). |
82
- | peer child `stdout` | a spawned LOCAL peer CLI | `scripts/lib/peer-cli/acp-client.cjs` (JSON-RPC frame parser) | A malicious/buggy peer could flood stdout **already capped at 16 MiB un-newlined** (DoS guard). JSON-RPC frames are parsed, not `eval`'d. |
82
+ | peer child `stdout` | a spawned LOCAL peer CLI | `scripts/lib/peer-cli/acp-client.cjs` (JSON-RPC frame parser) | A malicious/buggy peer could flood stdout - **already capped at 16 MiB un-newlined** (DoS guard). JSON-RPC frames are parsed, not `eval`'d. |
83
83
 
84
84
  ---
85
85
 
86
86
  ## Finding
87
87
 
88
88
  The legitimate active-egress set is fully enumerated above and **no raw unexpected egress was
89
- found** every outbound call, server bind, or child spawn maps to one of six trusted modules,
89
+ found** - every outbound call, server bind, or child spawn maps to one of six trusted modules,
90
90
  each frozen into `scripts/security/outbound-allowlist.json` with a justification. The allowlist
91
91
  uses **directory globs** so a new helper in an already-trusted module (e.g. another
92
92
  `figma-extract` file) does not silently trip the gate, and every glob is asserted by
93
- `test/suite/phase-33-5-audit.test.cjs` to resolve to ≥1 real file so the 33.5-04 gate cannot be
93
+ `test/suite/phase-33-5-audit.test.cjs` to resolve to ≥1 real file - so the 33.5-04 gate cannot be
94
94
  defeated by a stale entry that matches nothing.
95
95
 
96
96
  The residual gaps surfaced here are **closed by the remaining Phase 33.5 plans**:
97
97
 
98
- - **33.5-03** WebSocket bind hardening: 127.0.0.1 default bind (no more `0.0.0.0`), opt-in remote
98
+ - **33.5-03** - WebSocket bind hardening: 127.0.0.1 default bind (no more `0.0.0.0`), opt-in remote
99
99
  via `event_stream.bind_host`, and a timing-safe (`crypto.timingSafeEqual`) token compare. Closes
100
100
  the WS-upgrade external-input row.
101
- - **33.5-04** Outbound-network static CI gate: `scripts/scan-outbound-network.cjs` +
101
+ - **33.5-04** - Outbound-network static CI gate: `scripts/scan-outbound-network.cjs` +
102
102
  `npm run scan:outbound`, consuming THIS plan's `outbound-allowlist.json`. Also lands the
103
103
  peer-CLI env-allowlist sandbox (shared `sanitize-env`) that closes the `acp-client.cjs` /
104
104
  `asp-client.cjs` full-`process.env` forward rows.
105
- - **33.5-05** (and 33.5-07/08) secret-scan extension (Gemini + GitHub fine-grained/server
105
+ - **33.5-05** (and 33.5-07/08) - secret-scan extension (Gemini + GitHub fine-grained/server
106
106
  tokens) with a synthetic-secret fuzz, the gdd-state path-traversal guard + payload cap +
107
107
  tightened schemas, `SECURITY.md`, and the regression baseline.
108
108