@qijenchen/design-system 0.1.0-beta.10 → 0.1.0-beta.13

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 (307) hide show
  1. package/CLAUDE.md +201 -0
  2. package/README.md +7 -15
  3. package/cli-init.mjs +90 -0
  4. package/ds-canonical/commands/README.md +26 -0
  5. package/ds-canonical/commands/gov-status.md +79 -0
  6. package/ds-canonical/hooks/README.md +145 -0
  7. package/ds-canonical/hooks/_log-fire.sh +44 -0
  8. package/ds-canonical/hooks/block_prototype_imports.py +111 -0
  9. package/ds-canonical/hooks/check_app_shell_primary_header_consistency.sh +68 -0
  10. package/ds-canonical/hooks/check_audit_post_report_validator.sh +88 -0
  11. package/ds-canonical/hooks/check_audit_sample_escape.sh +73 -0
  12. package/ds-canonical/hooks/check_benchmark_citation.sh +106 -0
  13. package/ds-canonical/hooks/check_canonical_propagation.sh +189 -0
  14. package/ds-canonical/hooks/check_chrome_header_handcraft.sh +70 -0
  15. package/ds-canonical/hooks/check_codex_brief_invariants.sh +83 -0
  16. package/ds-canonical/hooks/check_codex_collab_5step.sh +108 -0
  17. package/ds-canonical/hooks/check_datatable_invariants.sh +117 -0
  18. package/ds-canonical/hooks/check_dim_count_drift.sh +72 -0
  19. package/ds-canonical/hooks/check_field_controls_contracts.sh +110 -0
  20. package/ds-canonical/hooks/check_field_family_invariants.sh +205 -0
  21. package/ds-canonical/hooks/check_file_size_budget.sh +60 -0
  22. package/ds-canonical/hooks/check_header_with_tabs_border.sh +87 -0
  23. package/ds-canonical/hooks/check_main_branch_workbench.sh +93 -0
  24. package/ds-canonical/hooks/check_naming_and_abstraction.sh +165 -0
  25. package/ds-canonical/hooks/check_opacity_token_usage.sh +149 -0
  26. package/ds-canonical/hooks/check_pattern_invariants.sh +194 -0
  27. package/ds-canonical/hooks/check_peoplepicker_ssot_drift.sh +56 -0
  28. package/ds-canonical/hooks/check_pixel_quantified_audit.sh +53 -0
  29. package/ds-canonical/hooks/check_propose_plain_chinese.sh +74 -0
  30. package/ds-canonical/hooks/check_propose_pre_grep_verify.sh +70 -0
  31. package/ds-canonical/hooks/check_select_all_canonical.sh +58 -0
  32. package/ds-canonical/hooks/check_solo_workflow.sh +258 -0
  33. package/ds-canonical/hooks/check_spec_class_drift.sh +88 -0
  34. package/ds-canonical/hooks/check_story_invariants.sh +612 -0
  35. package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +105 -0
  36. package/ds-canonical/hooks/check_tab_lg_chrome_header_equal.sh +66 -0
  37. package/ds-canonical/hooks/check_wrapper_primitive_schema_drift.sh +104 -0
  38. package/ds-canonical/hooks/enforce_home_charter.sh +44 -0
  39. package/ds-canonical/hooks/inject_pending_self_audit.sh +204 -0
  40. package/ds-canonical/hooks/lib/_approval_re.sh +33 -0
  41. package/ds-canonical/hooks/lib/_code_quality.sh +73 -0
  42. package/ds-canonical/hooks/lib/_cva_default_sync.sh +69 -0
  43. package/ds-canonical/hooks/lib/_governance_coverage_check.sh +49 -0
  44. package/ds-canonical/hooks/lib/_hardcoded_strings.sh +163 -0
  45. package/ds-canonical/hooks/lib/_layout_space_canonical.sh +56 -0
  46. package/ds-canonical/hooks/lib/_overlay_handcraft.sh +141 -0
  47. package/ds-canonical/hooks/lib/_person_data_richness.sh +42 -0
  48. package/ds-canonical/hooks/lib/_story_compile_drift.sh +48 -0
  49. package/ds-canonical/hooks/lib/_token_hygiene.sh +95 -0
  50. package/ds-canonical/hooks/log_governance_fires.sh +50 -0
  51. package/ds-canonical/hooks/log_skill_invokes.sh +41 -0
  52. package/ds-canonical/hooks/post_edit_dispatcher.sh +62 -0
  53. package/ds-canonical/hooks/retired/check_anatomy_section_numbering.sh +106 -0
  54. package/ds-canonical/hooks/retired/check_avatar_hovercard.sh +90 -0
  55. package/ds-canonical/hooks/retired/check_button_icon_literal.sh.retired-2026-04-28 +38 -0
  56. package/ds-canonical/hooks/retired/check_container_breathing.sh +142 -0
  57. package/ds-canonical/hooks/retired/check_governance_compliance.sh +61 -0
  58. package/ds-canonical/hooks/retired/check_icon_only_padding_formula.sh +104 -0
  59. package/ds-canonical/hooks/retired/check_item_content_primitive.sh +150 -0
  60. package/ds-canonical/hooks/retired/check_item_list_gap.sh +153 -0
  61. package/ds-canonical/hooks/retired/check_sideoffset_canonical.sh +65 -0
  62. package/ds-canonical/hooks/retired/check_spec_iteration_tag.sh +87 -0
  63. package/ds-canonical/hooks/retired/check_ssot_consultation.sh +88 -0
  64. package/ds-canonical/hooks/retired/check_sync_update.sh +20 -0
  65. package/ds-canonical/hooks/retired/check_third_party_dom_verified.sh +95 -0
  66. package/ds-canonical/hooks/retired/enforce_home_charter.sh +125 -0
  67. package/ds-canonical/hooks/retired/post_edit_canonical_interrogate.sh +109 -0
  68. package/ds-canonical/hooks/retired/pre_edit_spec_check.sh +68 -0
  69. package/ds-canonical/hooks/retired/pre_new_component_spec.sh +39 -0
  70. package/ds-canonical/hooks/retired/pre_write_subsumption_check.sh +112 -0
  71. package/ds-canonical/hooks/retired/stop_meta_self_audit.sh.retired-2026-05-13 +76 -0
  72. package/ds-canonical/hooks/retired/tests/test_check_anatomy_section_numbering.sh +14 -0
  73. package/ds-canonical/hooks/retired/tests/test_check_avatar_hovercard.sh +15 -0
  74. package/ds-canonical/hooks/retired/tests/test_check_container_breathing.sh +15 -0
  75. package/ds-canonical/hooks/retired/tests/test_check_governance_compliance.sh +15 -0
  76. package/ds-canonical/hooks/retired/tests/test_check_icon_only_padding_formula.sh +79 -0
  77. package/ds-canonical/hooks/retired/tests/test_check_item_content_primitive.sh +15 -0
  78. package/ds-canonical/hooks/retired/tests/test_check_item_list_gap.sh +163 -0
  79. package/ds-canonical/hooks/retired/tests/test_check_sideoffset_canonical.sh +15 -0
  80. package/ds-canonical/hooks/retired/tests/test_check_spec_iteration_tag.sh +15 -0
  81. package/ds-canonical/hooks/retired/tests/test_check_ssot_consultation.sh +15 -0
  82. package/ds-canonical/hooks/retired/tests/test_check_sync_update.sh +14 -0
  83. package/ds-canonical/hooks/retired/tests/test_check_third_party_dom_verified.sh +15 -0
  84. package/ds-canonical/hooks/retired/tests/test_enforce_home_charter.sh +15 -0
  85. package/ds-canonical/hooks/retired/tests/test_pre_edit_spec_check.sh +15 -0
  86. package/ds-canonical/hooks/retired/tests/test_pre_new_component_spec.sh +15 -0
  87. package/ds-canonical/hooks/retired/tests/test_pre_write_subsumption_check.sh +63 -0
  88. package/ds-canonical/hooks/session_start_governance_check.sh +263 -0
  89. package/ds-canonical/hooks/stop_passive_logging.sh +322 -0
  90. package/ds-canonical/hooks/stop_self_audit.sh +450 -0
  91. package/ds-canonical/hooks/tests/KNOWN-BROKEN.md +15 -0
  92. package/ds-canonical/hooks/tests/run-all.sh +76 -0
  93. package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +143 -0
  94. package/ds-canonical/hooks/tests/test_check_app_shell_primary_header_consistency.sh +140 -0
  95. package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +115 -0
  96. package/ds-canonical/hooks/tests/test_check_audit_sample_escape.sh +93 -0
  97. package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +115 -0
  98. package/ds-canonical/hooks/tests/test_check_canonical_propagation.sh +133 -0
  99. package/ds-canonical/hooks/tests/test_check_chrome_header_handcraft.sh +123 -0
  100. package/ds-canonical/hooks/tests/test_check_code_quality.sh +15 -0
  101. package/ds-canonical/hooks/tests/test_check_codex_collab_5step.sh +96 -0
  102. package/ds-canonical/hooks/tests/test_check_cva_default_sync.sh +15 -0
  103. package/ds-canonical/hooks/tests/test_check_datatable_invariants.sh +122 -0
  104. package/ds-canonical/hooks/tests/test_check_dim_count_drift.sh +98 -0
  105. package/ds-canonical/hooks/tests/test_check_field_controls_contracts.sh +126 -0
  106. package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +194 -0
  107. package/ds-canonical/hooks/tests/test_check_file_size_budget.sh +32 -0
  108. package/ds-canonical/hooks/tests/test_check_hardcoded_strings.sh +14 -0
  109. package/ds-canonical/hooks/tests/test_check_header_with_tabs_border.sh +110 -0
  110. package/ds-canonical/hooks/tests/test_check_layout_space_canonical.sh +73 -0
  111. package/ds-canonical/hooks/tests/test_check_main_branch_workbench.sh +147 -0
  112. package/ds-canonical/hooks/tests/test_check_naming_and_abstraction.sh +136 -0
  113. package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +110 -0
  114. package/ds-canonical/hooks/tests/test_check_overlay_handcraft.sh +126 -0
  115. package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +148 -0
  116. package/ds-canonical/hooks/tests/test_check_peoplepicker_ssot_drift.sh +108 -0
  117. package/ds-canonical/hooks/tests/test_check_person_data_richness.sh +58 -0
  118. package/ds-canonical/hooks/tests/test_check_pixel_quantified_audit.sh +142 -0
  119. package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +126 -0
  120. package/ds-canonical/hooks/tests/test_check_propose_pre_grep_verify.sh +117 -0
  121. package/ds-canonical/hooks/tests/test_check_select_all_canonical.sh +125 -0
  122. package/ds-canonical/hooks/tests/test_check_solo_workflow.sh +201 -0
  123. package/ds-canonical/hooks/tests/test_check_spec_class_drift.sh +135 -0
  124. package/ds-canonical/hooks/tests/test_check_story_anatomy.sh.broken +197 -0
  125. package/ds-canonical/hooks/tests/test_check_story_category.sh.broken +187 -0
  126. package/ds-canonical/hooks/tests/test_check_story_compile_drift.sh +15 -0
  127. package/ds-canonical/hooks/tests/test_check_story_invariants.sh +209 -0
  128. package/ds-canonical/hooks/tests/test_check_story_name_jargon.sh.broken +53 -0
  129. package/ds-canonical/hooks/tests/test_check_story_slot_split.sh +156 -0
  130. package/ds-canonical/hooks/tests/test_check_substantive_edit_approval_preflight.sh +176 -0
  131. package/ds-canonical/hooks/tests/test_check_tab_lg_chrome_header_equal.sh +138 -0
  132. package/ds-canonical/hooks/tests/test_check_token_hygiene.sh +21 -0
  133. package/ds-canonical/hooks/tests/test_check_wrapper_primitive_schema_drift.sh +169 -0
  134. package/ds-canonical/hooks/tests/test_enforce_home_charter.sh +77 -0
  135. package/ds-canonical/hooks/tests/test_inject_pending_self_audit.sh +125 -0
  136. package/ds-canonical/hooks/tests/test_log_governance_fires.sh +10 -0
  137. package/ds-canonical/hooks/tests/test_log_skill_invokes.sh +7 -0
  138. package/ds-canonical/hooks/tests/test_post_edit_dispatcher.sh +108 -0
  139. package/ds-canonical/hooks/tests/test_session_start_governance_check.sh +143 -0
  140. package/ds-canonical/hooks/tests/test_stop_capture_metrics.sh +95 -0
  141. package/ds-canonical/hooks/tests/test_stop_governance_drift_check.sh.broken +125 -0
  142. package/ds-canonical/hooks/tests/test_stop_harvest_corrections.sh +10 -0
  143. package/ds-canonical/hooks/tests/test_stop_passive_logging.sh +100 -0
  144. package/ds-canonical/hooks/tests/test_stop_self_audit.sh +76 -0
  145. package/ds-canonical/hooks/tests/test_stop_tsc_sanity.sh +10 -0
  146. package/ds-canonical/references/README.md +43 -0
  147. package/ds-canonical/references/audit-coverage-vs-24-checklist.md +74 -0
  148. package/ds-canonical/references/build-ui-canonicals.md +69 -0
  149. package/ds-canonical/references/cva-patterns.md +41 -0
  150. package/ds-canonical/references/drag-canonical.md +331 -0
  151. package/ds-canonical/references/item-anatomy-recipe.md +225 -0
  152. package/ds-canonical/references/naming-conventions.md +56 -0
  153. package/ds-canonical/references/principle-dim-map.json +515 -0
  154. package/ds-canonical/references/props-naming.md +45 -0
  155. package/ds-canonical/references/spec-rules.md +58 -0
  156. package/ds-canonical/references/ssot-consultation.md +63 -0
  157. package/ds-canonical/references/ssot-index.md +40 -0
  158. package/ds-canonical/references/story-baseline-registry.json +79 -0
  159. package/ds-canonical/references/structural-token-retention.md +42 -0
  160. package/ds-canonical/references/tailwind-gotchas.md +87 -0
  161. package/ds-canonical/references/ui-dev-rules.md +60 -0
  162. package/ds-canonical/rules/README.md +34 -0
  163. package/ds-canonical/rules/meta-patterns.md +87 -0
  164. package/ds-canonical/rules/self-verify.md +53 -0
  165. package/ds-canonical/rules/spec-rules.md +25 -0
  166. package/ds-canonical/rules/story-rules.md +56 -0
  167. package/ds-canonical/rules/ui-development.md +87 -0
  168. package/ds-canonical/skills/README.md +88 -0
  169. package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +181 -0
  170. package/ds-canonical/skills/code-quality-audit/SKILL.md +63 -0
  171. package/ds-canonical/skills/codex-collab/SKILL.md +249 -0
  172. package/ds-canonical/skills/codex-collab/references/brief-template.md +48 -0
  173. package/ds-canonical/skills/codex-collab/references/transport.md +58 -0
  174. package/ds-canonical/skills/codify-corrections/SKILL.md +184 -0
  175. package/ds-canonical/skills/codify-principle/SKILL.md +151 -0
  176. package/ds-canonical/skills/component-quality-gate/SKILL.md +102 -0
  177. package/ds-canonical/skills/component-quality-gate/references/checklist.md +79 -0
  178. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +247 -0
  179. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +123 -0
  180. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +165 -0
  181. package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +91 -0
  182. package/ds-canonical/skills/delivery-handoff/SKILL.md +229 -0
  183. package/ds-canonical/skills/delivery-handoff/references/flow-diagram.md +180 -0
  184. package/ds-canonical/skills/delivery-handoff/references/handoff-template.md +177 -0
  185. package/ds-canonical/skills/delivery-handoff/references/inventory-checklist.md +196 -0
  186. package/ds-canonical/skills/design-system-audit/SKILL.md +343 -0
  187. package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1260 -0
  188. package/ds-canonical/skills/design-system-audit/references/checkpoints.md +240 -0
  189. package/ds-canonical/skills/design-system-audit/references/historical-bugs.md +240 -0
  190. package/ds-canonical/skills/design-system-audit/references/principle-audit-protocol.md +364 -0
  191. package/ds-canonical/skills/design-system-audit/references/rule-placement.md +175 -0
  192. package/ds-canonical/skills/design-system-audit/references/spec-template.md +66 -0
  193. package/ds-canonical/skills/ensure-canonical/SKILL.md +196 -0
  194. package/ds-canonical/skills/governance-health/SKILL.md +146 -0
  195. package/ds-canonical/skills/knowledge-prune/SKILL.md +303 -0
  196. package/ds-canonical/skills/new-component/SKILL.md +170 -0
  197. package/ds-canonical/skills/new-component/references/new-component-checklist.md +85 -0
  198. package/ds-canonical/skills/performance-audit/SKILL.md +107 -0
  199. package/ds-canonical/skills/product-ui-audit/SKILL.md +230 -0
  200. package/ds-canonical/skills/product-ui-audit/references/audit-checks.md +246 -0
  201. package/ds-canonical/skills/product-ui-audit/references/common-misuses.md +329 -0
  202. package/ds-canonical/skills/product-ui-audit/references/report-template.md +159 -0
  203. package/ds-canonical/skills/propose-options/SKILL.md +177 -0
  204. package/ds-canonical/skills/prototype/SKILL.md +244 -0
  205. package/ds-canonical/skills/prototype/references/audit-checks.md +37 -0
  206. package/ds-canonical/skills/prototype/references/benchmark-sources.md +94 -0
  207. package/ds-canonical/skills/prototype/references/checkpoints.md +191 -0
  208. package/ds-canonical/skills/prototype/references/evaluation-matrix.md +141 -0
  209. package/ds-canonical/skills/prototype/references/ooux-template.md +198 -0
  210. package/ds-canonical/skills/prototype/references/proposal-template.md +229 -0
  211. package/ds-canonical/skills/scan-similar-bugs/SKILL.md +198 -0
  212. package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +159 -0
  213. package/ds-canonical/skills/story-writing/SKILL.md +122 -0
  214. package/ds-canonical/skills/story-writing/references/anatomy-standard.md +217 -0
  215. package/ds-canonical/skills/story-writing/references/category-templates.md +174 -0
  216. package/ds-canonical/skills/story-writing/references/example-selection.md +70 -0
  217. package/ds-canonical/skills/story-writing/references/self-check.md +20 -0
  218. package/ds-canonical/skills/ux-audit/SKILL.md +130 -0
  219. package/ds-canonical/skills/visual-audit/SKILL.md +245 -0
  220. package/ds-canonical/skills/visual-audit/output/.gitkeep +0 -0
  221. package/ds-canonical/skills/visual-audit/references/audit-architecture.md +100 -0
  222. package/ds-canonical/skills/visual-audit/references/visual-checklist.md +297 -0
  223. package/ds-canonical/skills/visual-audit/references/world-class-benchmarks.md +198 -0
  224. package/package.json +9 -5
  225. package/src/components/Accordion/accordion.spec.md +114 -0
  226. package/src/components/Alert/alert.spec.md +197 -0
  227. package/src/components/AppShell/app-shell.spec.md +331 -0
  228. package/src/components/AspectRatio/aspect-ratio.spec.md +134 -0
  229. package/src/components/Avatar/avatar.spec.md +329 -0
  230. package/src/components/Badge/badge.spec.md +380 -0
  231. package/src/components/Breadcrumb/breadcrumb.spec.md +257 -0
  232. package/src/components/BulkActionBar/bulk-action-bar.spec.md +210 -0
  233. package/src/components/Button/button.spec.md +460 -0
  234. package/src/components/Calendar/calendar.spec.md +242 -0
  235. package/src/components/Carousel/carousel.spec.md +253 -0
  236. package/src/components/Chart/chart.spec.md +155 -0
  237. package/src/components/Checkbox/checkbox.spec.md +344 -0
  238. package/src/components/Chip/chip.spec.md +237 -0
  239. package/src/components/CircularProgress/circular-progress.spec.md +268 -0
  240. package/src/components/Coachmark/coachmark.spec.md +230 -0
  241. package/src/components/Combobox/combobox.spec.md +180 -0
  242. package/src/components/Command/command.spec.md +171 -0
  243. package/src/components/DataTable/data-table.spec.md +525 -0
  244. package/src/components/DateGrid/date-grid.spec.md +215 -0
  245. package/src/components/DatePicker/date-picker.spec.md +334 -0
  246. package/src/components/DescriptionList/description-list.spec.md +214 -0
  247. package/src/components/Dialog/dialog.spec.md +202 -0
  248. package/src/components/DropdownMenu/dropdown-menu.spec.md +250 -0
  249. package/src/components/Empty/empty.spec.md +214 -0
  250. package/src/components/Field/field-controls.spec.md +338 -0
  251. package/src/components/Field/field.spec.md +438 -0
  252. package/src/components/Field/form-validation.spec.md +152 -0
  253. package/src/components/FieldControlGroup/field-control-group.spec.md +176 -0
  254. package/src/components/FileItem/file-item.spec.md +467 -0
  255. package/src/components/FileUpload/file-upload.spec.md +123 -0
  256. package/src/components/FileViewer/file-viewer.spec.md +373 -0
  257. package/src/components/HoverCard/hover-card.spec.md +157 -0
  258. package/src/components/Input/input.spec.md +193 -0
  259. package/src/components/LinkInput/link-input.spec.md +130 -0
  260. package/src/components/Menu/menu-item.spec.md +290 -0
  261. package/src/components/NameCard/name-card.spec.md +171 -0
  262. package/src/components/Notice/notice.spec.md +149 -0
  263. package/src/components/NumberInput/number-input.spec.md +126 -0
  264. package/src/components/OverflowIndicator/overflow-indicator.spec.md +120 -0
  265. package/src/components/PeoplePicker/people-picker.spec.md +263 -0
  266. package/src/components/Popover/popover.spec.md +198 -0
  267. package/src/components/ProgressBar/progress-bar.spec.md +232 -0
  268. package/src/components/RadioGroup/radio-group.spec.md +141 -0
  269. package/src/components/Rating/rating.spec.md +208 -0
  270. package/src/components/ScrollArea/scroll-area.spec.md +145 -0
  271. package/src/components/SegmentedControl/segmented-control.spec.md +295 -0
  272. package/src/components/Select/select.spec.md +299 -0
  273. package/src/components/SelectMenu/select-menu.spec.md +220 -0
  274. package/src/components/SelectionControl/selection-item.spec.md +128 -0
  275. package/src/components/Separator/separator.spec.md +109 -0
  276. package/src/components/Sheet/sheet.spec.md +148 -0
  277. package/src/components/Sidebar/sidebar.spec.md +713 -0
  278. package/src/components/Skeleton/skeleton.spec.md +104 -0
  279. package/src/components/Slider/slider.spec.md +353 -0
  280. package/src/components/Steps/steps.spec.md +465 -0
  281. package/src/components/Switch/switch.spec.md +215 -0
  282. package/src/components/Tabs/tabs.spec.md +314 -0
  283. package/src/components/Tag/tag.spec.md +282 -0
  284. package/src/components/Textarea/textarea.spec.md +151 -0
  285. package/src/components/TimePicker/time-picker.spec.md +279 -0
  286. package/src/components/Toast/toast.spec.md +177 -0
  287. package/src/components/Tooltip/tooltip.spec.md +139 -0
  288. package/src/components/TreeView/tree-view.spec.md +374 -0
  289. package/src/patterns/action-bar/action-bar.spec.md +458 -0
  290. package/src/patterns/element-anatomy/element-anatomy.spec.md +215 -0
  291. package/src/patterns/element-anatomy/inline-action.spec.md +315 -0
  292. package/src/patterns/element-anatomy/item-anatomy.spec.md +1042 -0
  293. package/src/patterns/header-canonical/header-canonical.spec.md +285 -0
  294. package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +191 -0
  295. package/src/patterns/overlay-surface/overlay-surface.spec.md +428 -0
  296. package/src/patterns/resize-handle/resize-handle.spec.md +109 -0
  297. package/src/tokens/color/color.spec.md +804 -0
  298. package/src/tokens/density/density.spec.md +127 -0
  299. package/src/tokens/elevation/elevation.spec.md +81 -0
  300. package/src/tokens/layoutSpace/layoutSpace.spec.md +314 -0
  301. package/src/tokens/motion/motion.spec.md +97 -0
  302. package/src/tokens/opacity/opacity.spec.md +78 -0
  303. package/src/tokens/orphan-tokens.spec.md +117 -0
  304. package/src/tokens/radius/radius.spec.md +123 -0
  305. package/src/tokens/typography/typography.spec.md +202 -0
  306. package/src/tokens/uiSize/uiSize.spec.md +438 -0
  307. package/src/styles/preset.css +0 -31
@@ -0,0 +1,40 @@
1
+ # SSOT Index — High-risk interface ownership map
2
+
3
+ **Purpose**:per codex round 5 (e) — 設計提案前必查本 index 找 owner,再 grep spec verify。
4
+ 避免 round 1-4 反覆「沒查就提案 → 提錯 owner → user 糾 → 再來」的 loop。
5
+
6
+ **Usage**:
7
+ 1. 動視覺 / 結構前 → grep 本 file 找該 interface 是否列管
8
+ 2. 命中 → 跳 owner spec 查 canonical sentence + 看 conflicting code 嗎?
9
+ 3. 沒命中 → grep `*.spec.md` 找 anchor,**找到後加進本 index**(防下次再漏)
10
+
11
+ ## High-risk interfaces(active divergence / past trap)
12
+
13
+ | Interface | Owner spec | Canonical sentence | Drift status | Last divergence event |
14
+ |---|---|---|---|---|
15
+ | **DataTable body cell internal indicator**(display endAction / clear / edit indicator)| `data-table.spec.md:204` + `inline-action.spec.md:157` | 「Body cell internal = Field family endAction(自動繼承)」「Field display 元件已對齊」 | ⚠ **DRIFT**:`data-table.tsx:1074-1191` `getEditIndicator(colType)` parallel system,`:1190` comment 反向說 SSOT 在 DataTable cellEl | 2026-05-08 round 5(`.claude/planning/cell-indicator-ssot-rfc.md` pending decision)|
16
+ | **Field naked variant state ring**(hover / focus / open / error)| `field-wrapper.tsx:140-189` cva compoundVariants(v13.3)+ `field.spec.md:371-415`「focus dominates everything」| 「SSOT 在 field-wrapper.tsx 三 compoundVariant — 改一處全 control + cell + variant 跟動」 | ✅ aligned(2026-05-08 D path canary 違反後 revert)| 2026-05-08 round 4(D path canary 違反 SSOT,已 revert `f0faab9`)|
17
+ | **Row prefix/suffix slot**(`<ItemPrefix>` / `<ItemSuffix>`)| `patterns/element-anatomy/item-anatomy.spec.md:175+190` | 「row prefix/suffix slot 必走 patterns/element-anatomy L1 primitive」「`h-[1lh] shrink-0 flex items-center` 普世正確」 | ✅ aligned(hook `check_pattern_invariants.sh` C.4 enforce)| — |
18
+ | **Inline action gap**(ItemInlineAction sibling spacing)| `patterns/element-anatomy/inline-action.spec.md:80` | 「inline-action 跟 sibling gap 必 = `gap-2`(8px)」 | ✅ aligned(hook C.2 enforce)| — |
19
+ | **Drag visual**(drop indicator / drag overlay)| `lib/drag-visual.ts`(2026-05-06 v14.5)+ `tree-view.spec.md:265` | 「TreeView 是 DS 內最早 codified 的 drag canonical,DataTable row drag + column reorder 都 inherit via drag-visual.ts SSOT module」 | ✅ aligned | — |
20
+ | **Color tokens**(primitive vs semantic)| `tokens/color/color.spec.md`(架構流派定位)+ `tokens/color/semantic.css` | 「禁 primitive 色名作 utility,用 semantic alias」 | ✅ aligned(hook D.3 enforce)| — |
21
+ | **Layout space**(region/element + 親疏三級)| `tokens/layoutSpace/layoutSpace.spec.md` v6 + `feedback_layout_v6_canonical.md` | 「region/element + bounded/unbounded + 親疏三級」 | ✅ aligned(2026-05-01 flush variant retire)| 2026-05-01 |
22
+ | **DataTable scroll**(3-region synced + cross-OS scrollbar)| `data-table.spec.md:245-251` | 「center body 用 native overflow-x-auto(非 ScrollArea),pinned column 三 region 同步」 | ✅ aligned(v15.13 interim CSS parity for Windows Bug H,deferred ScrollArea full migration)| 2026-04-30 / 2026-05-07 |
23
+ | **Cell display vs edit content position**(picker offset)| `field.spec.md:407` Layout Family 4 + `data-table.spec.md:204` | 「Field control display + edit 共用同 wrapper geometry」 | ⚠ **MISALIGNED**:6 picker display 走裸 span,跟 edit Field wrapper 不同 DOM | 2026-05-07~08 round 1-5(blocked on indicator SSOT decision)|
24
+ | **Field state machine focus dominates**(v13.3)| `field-wrapper.tsx:140-189` + `field.spec.md:371-415` + `check_field_family_invariants.sh` A.3 | 「focus dominates everything;naked 不寫平行 outline ring」 | ✅ aligned;hook A.3 enforce | 2026-05-06 v9-v13.3 5 round refinement |
25
+ | **Solo dev workflow**(1 chat = 1 branch / Netlify gate / squash merge)| `feedback_solo_dev_workflow.md` + CLAUDE.md「Git solo-work canonical」 | 「1 chat = 1 working branch;Netlify preview = user gate;『push / OK』trigger 才 merge main」 | ✅ aligned(M28 + hook `check_solo_workflow.sh`)| 2026-05-08 M28 codify |
26
+ | **Wrapper-vs-primitive schema unify**(SelectOption / MenuItemProps 等)| `SelectMenu/select-menu.tsx` SelectMenuOption + `Combobox/combobox.tsx` extends + `PeoplePicker/people-picker.tsx` extends | 「wrapper API schema 必 `extends primitive`,wrapper 內部 mapping 必 forward 全 primitive surface field(M30)」 | ✅ aligned(2026-05-10 Round 1 commit `561945b` Combobox extends + forward 全 field;PeoplePicker 對齊 + hook `check_wrapper_primitive_schema_drift.sh` BLOCKER)| 2026-05-10 M30 codify |
27
+
28
+ ## How to maintain
29
+
30
+ - 新 interface 第一次 surface → 加進本 index
31
+ - 新 divergence 發現 → 加 row + 標 ⚠ DRIFT
32
+ - Drift 解決 → 改 ✅ aligned
33
+ - 重大 round 結束 → 跑 audit Dim 38 反 grep verify
34
+
35
+ ## 與 hook 關係
36
+
37
+ - `check_ds_anchor_preflight.sh`(待 ship)— 偵測編 Field / DataTable / patterns code 時 stderr 提醒「先 grep ssot-index.md」
38
+ - `check_field_family_invariants.sh` A.3 — 機械化 enforce v13.3 SSOT
39
+ - `check_pattern_invariants.sh` C.4 — 機械化 enforce row slot SSOT
40
+ - `check_canonical_propagation.sh` E.2 — 機械化 enforce L3 primitive import
@@ -0,0 +1,79 @@
1
+ {
2
+ "$schema": "./story-baseline-registry.schema.json",
3
+ "_meta": {
4
+ "purpose": "Anti-drift registry for stories wrap既有 primitive(Sidebar / ChromeHeader / DataTable / Dialog / Sheet / Popover)— machine-readable canonical archetype。Hook `check_story_invariants.sh R8` reads this(not grep spec.md / not憑 Claude judgment)to enforce nearest same-purpose canonical usage(per codex Layer B D4 2026-05-20)。新增 primitive entry 必先寫 baseline + helper list + antiPatterns regex + variantRules。",
5
+ "owner": ".claude/references/story-baseline-registry.json",
6
+ "consumed_by": [
7
+ ".claude/hooks/check_story_invariants.sh#R8(story_archetype_registry)",
8
+ ".claude/skills/story-writing/SKILL.md#Phase-0.0(load registry + read baseline + produce diff table)"
9
+ ],
10
+ "rollout": "ship as warn mode first;確認 zero existing violation → 升 P0 BLOCKER"
11
+ },
12
+ "components": {
13
+ "Sidebar": {
14
+ "baseline": "packages/design-system/src/components/Sidebar/sidebar.stories.tsx#IconCollapse",
15
+ "requiredHelpers": ["WorkspaceBrand", "MAIN_NAV", "SidebarHeader", "SidebarFooter"],
16
+ "antiPatterns": [
17
+ {
18
+ "id": "sidebar-header-simplified-span",
19
+ "regex": "<SidebarHeader>\\s*<span",
20
+ "severity": "block",
21
+ "rationale": "SidebarHeader 必 wrap WorkspaceBrand-like ItemAvatar block(per sidebar.stories#IconCollapse baseline);simplified <span> mock = drift"
22
+ },
23
+ {
24
+ "id": "sidebar-menu-button-inline-icon",
25
+ "regex": "<SidebarMenuButton>[^<]*<[A-Z][a-zA-Z]+\\s+className=\"size-",
26
+ "severity": "block",
27
+ "rationale": "SidebarMenuButton 必用 startIcon prop + tooltip prop;children inline icon = drift"
28
+ }
29
+ ]
30
+ },
31
+ "DataTable": {
32
+ "baseline": "packages/design-system/src/components/DataTable/data-table.stories.tsx#WithBulkActions",
33
+ "toolbar": {
34
+ "requiredHelpers": ["Popover", "PopoverTrigger", "PopoverContent", "Input"],
35
+ "filterPanel": "DataTableFilterPanel",
36
+ "sortManager": "DataTableSortManager",
37
+ "buttonCanonical": {
38
+ "variant": "text",
39
+ "size": "sm",
40
+ "iconOnly": true,
41
+ "pressed": "required(state expression)",
42
+ "rationale": "per codex D2 verdict 2026-05-20 + action-bar.spec.md narrow scope:dense always-visible toolbar = low visual weight + pressed/chips/badges 顯示 state;tertiary 只用 standalone/labeled context"
43
+ }
44
+ },
45
+ "antiPatterns": [
46
+ {
47
+ "id": "datatable-toolbar-tertiary-filter-sort",
48
+ "regex": "startIcon=\\{(Filter|ArrowUpDown)\\}[^>]*variant=\"tertiary\"|variant=\"tertiary\"[^>]*startIcon=\\{(Filter|ArrowUpDown)\\}",
49
+ "severity": "block",
50
+ "rationale": "DataTable toolbar filter/sort 必 variant=text(per data-table.stories#WithBulkActions L998 canonical)"
51
+ },
52
+ {
53
+ "id": "datatable-toolbar-button-with-label",
54
+ "regex": "startIcon=\\{(Filter|ArrowUpDown)\\}[^>]*>[^<]+(篩選|排序|Filter|Sort)[^<]*</Button>",
55
+ "severity": "block",
56
+ "rationale": "DataTable toolbar 必 iconOnly(per WithBulkActions L998 canonical),不掛 label"
57
+ },
58
+ {
59
+ "id": "datatable-toolbar-no-popover-wrap",
60
+ "regex": "startIcon=\\{(Filter|ArrowUpDown)\\}(?![\\s\\S]*?(DataTableFilterPanel|DataTableSortManager))",
61
+ "severity": "warn",
62
+ "rationale": "DataTable toolbar filter/sort button 必包在 Popover 內,內含真 DataTableFilterPanel / DataTableSortManager primitive"
63
+ }
64
+ ]
65
+ },
66
+ "ChromeHeader": {
67
+ "baseline": "packages/design-system/src/components/Sidebar/sidebar.stories.tsx#IconCollapse (PageContent helper)",
68
+ "requiredStructure": "SidebarTrigger + h1.text-body-lg.font-medium 緊鄰 gap-2",
69
+ "antiPatterns": [
70
+ {
71
+ "id": "chromeheader-span-flex-1",
72
+ "regex": "<ChromeHeader>[\\s\\S]*?<span\\s+className=\"[^\"]*flex-1[^\"]*\">",
73
+ "severity": "block",
74
+ "rationale": "ChromeHeader title 該用 <h1 className=\"text-body-lg font-medium\"> 緊鄰 SidebarTrigger,不該用 <span flex-1> 撐空間造成 toggle + title 巨大間距"
75
+ }
76
+ ]
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,42 @@
1
+ # 結構性保留 token canonical(audit Dim 48 SSOT,2026-05-17 codified)
2
+
3
+ 某些 token 看起來「0 consumer」但屬**結構性保留**,不該 retire。**Sub-agent 跑 audit Dim 48 抓 0-consumer candidate 時必先過此 table,屬下列 6 類則 retract finding(不列為 violation)**。
4
+
5
+ ## 6 類結構性保留(對齊 Radix Color / Atlassian @atlaskit/tokens / Polaris polaris-tokens 三家共識)
6
+
7
+ | 類別 | Examples | 保留 rationale |
8
+ |---|---|---|
9
+ | **1. Radix-style palette completeness** | `--color-{blue,deep-orange,orange,amber,yellow,lime,green,turquoise,indigo,purple,magenta}-{3,4,5,8,9,10}` / `--white-a{12,15,25,45,65,85}` / `--color-red-{1..10}`(red palette 因 semantic 重映射 deep-orange 而不直接消費)| Radix Color idiom 必 12 步階完整,即使目前只消費 step-{1,2,6,7} 給 Tag/Avatar,中間步階保留供未來 hue scale 擴充 / hue calibration 對照。Retire = 破壞 palette 完整契約,新加 hue 時需重新訂全套 |
10
+ | **2. Forward-looking consumer reservation** | `--brand` / `--color-brand` | 預留給 consumer-layer(`src/app` / product UI)消費的品牌色 token。DS 本身不消費,跟 `--primary`(DS UI accent)分層。Retire = 未來產品做品牌頁時要重補 token + spec |
11
+ | **3. Tailwind bridge alias to semantic state SOP** | `--color-warning-foreground` / `--color-status-{online,busy,away,offline}` / `--color-inverse-neutral-{hover,active}` | `@theme inline` bridge 讓 `bg-status-online` 類 utility 可用,即使現有 code 走 `var(--status-online)` direct(NameCard.tsx / Avatar.tsx / Tag.tsx 實際消費 underlying token 非 alias)。Bridge 是 future-proof Tailwind class consumption,retire = 限縮使用方式 |
12
+ | **4. State SOP 5 件套** | `--info-active / --success-active / --warning-active / --primary-text` 等 | semantic state 5 件套(base / hover / active / subtle / text)結構完整性,即使現有 active variant 無 consumer,保留供未來互動 state 擴充 |
13
+ | **5. Type scale completeness** | `--font-h1-size` / `--font-h4-size` 等 typography utility | Type scale 12-tier completeness,即使現有 production 只用 h2/h3/h5,h1/h4/h6 預留供 marketing / hero / drawer title 等場景 |
14
+ | **6. Elevation dark-mode pair** | `--elevation-100-hover / --elevation-200-hover` | `primitives.css:236,238,419,421` light + dark 雙模式各自定義 → 結構性 dual-tier,retire 會破 dark mode visual contract |
15
+
16
+ ## Retire criteria 真實 strict(只有以下才 retire)
17
+
18
+ - 真實 0 consumer + **0 forward-looking reservation** + **0 dark-mode pair** + **0 palette completeness role**
19
+ - 對齊 Radix Color / Atlassian `@atlaskit/tokens` / Polaris polaris-tokens 三家 retire 政策共識
20
+
21
+ ## Sub-agent 強制 triple-verify before propose retire
22
+
23
+ 對每 candidate retire token,sub-agent 必 verify 3 layer:
24
+
25
+ 1. **`grep -rn var(--TOKEN_NAME)` DS-wide**(含 `packages/design-system/src/**` + `src/app/**` + `src/explorations/**`)— 抓 direct `var()` consumption
26
+ 2. **`grep -rn "TOKEN_NAME"` 排除 css/spec.md 定義 + template literal usage**(eg. `\`h-table-row-${size}\``)— 抓動態 utility class generation
27
+ 3. **Cross-check 上 6 類**:屬任一 → retract finding,**不列 retire candidate**
28
+
29
+ **任一 layer 顯示「有 consumer / 屬結構保留」→ 從 retire report 中拿掉**(不要送 user 拍板浪費時間)。
30
+
31
+ ## Audit Dim 48 false-positive 經驗(2026-05-17,user 抓教訓)
32
+
33
+ Sub-agent 用 narrow grep(只看 utility class hit,沒看 `var()` direct + template literal + dark mode override + forward-looking)抓 58 個 retire candidate;Layer A own re-verify 後 100% 為 false positive(全是結構性保留)。
34
+
35
+ User verbatim 2026-05-17:「每次抓出的問題你他媽要給我基於我們所有的檔案包括設計原則去再三確認到底是不是問題,避免明明就不是問題卻一直要我決策浪費我的時間」。
36
+
37
+ 本檔 codify 後類似 audit 跑時自動辨識結構性保留 token,不再誤判。
38
+
39
+ ## 引用
40
+
41
+ - `tokens/color/color.spec.md`「結構性保留 token canonical」(pointer 段)
42
+ - `.claude/skills/design-system-audit/SKILL.md` Dim 48(sub-agent prompt 必 cite 本檔)
@@ -0,0 +1,87 @@
1
+ # Tailwind 使用完整陷阱對照(從 CLAUDE.md 拆出)
2
+
3
+ `.claude/rules/ui-development.md`「Tailwind 5 條核心」段保留最精要 rules 和一行 bug anchor;完整範例、完整禁止清單、每條 bug 的詳細歷史在本檔。
4
+
5
+ ---
6
+
7
+ ## Tailwind v4 任意值:CSS variable 必須用 `var()` 包覆
8
+
9
+ **必須寫 `w-[var(--foo)]`,不能寫 `w-[--foo]`**。Tailwind v4 對任意值裡的 CSS variable 處理改了——舊的 `[--foo]` shorthand **不會自動包 `var()`**,會被當成 custom property declaration,整個 class **靜默失效**(不報錯,但完全沒效果)。
10
+
11
+ **曾經發生的 bug**:Sidebar 從 shadcn 複製的 `w-[--sidebar-width]` 在 8 個位置寬度全失效,sidebar 寬度變成 content fallback 導致主內容被蓋住。
12
+
13
+ ```tsx
14
+ // ❌ 錯(v4 失效)
15
+ <div className="w-[--sidebar-width] min-w-[--sidebar-width-min]" />
16
+
17
+ // ✅ 對
18
+ <div className="w-[var(--sidebar-width)] min-w-[var(--sidebar-width-min)]" />
19
+ ```
20
+
21
+ **自我檢查**:若 CSS var 相關寬高看起來怪怪的,先 `grep '\[--[a-z]'` 在 src 裡找有沒有漏網的 shorthand 語法。
22
+
23
+ ---
24
+
25
+ ## 圓角對應表
26
+
27
+ | Utility class | 值 |
28
+ |----------------|---------------------------|
29
+ | `rounded-md` | 4px(--radius-md) |
30
+ | `rounded-lg` | 8px(--radius-lg) |
31
+ | `rounded-full` | 9999px(--radius-full)|
32
+
33
+ ---
34
+
35
+ ## tailwind-merge 自訂 utility 註冊(技術陷阱)
36
+
37
+ 新增任何 `text-*`、`bg-*`、`border-*`、`ring-*` 自訂 utility 後,**必須到 `lib/utils.ts` 顯式註冊到正確的 group**(font-size / text-color 等)。否則 tailwind-merge 會用 heuristic 猜分組,把不衝突的 class 誤判為衝突並 strip 掉。
38
+
39
+ **曾發生的 bug**:`text-body`(font-size)和 `text-fg-secondary`(color)被誤判同組,description 失去 font-size。
40
+
41
+ **診斷法**:`cn()` 後某個 class 消失 → 99% 是 tailwind-merge 誤判 → 去 `lib/utils.ts` 註冊。
42
+ **逃生艙**:inline style + CSS variable(`style={{ fontSize: 'var(--font-body-size)' }}`)。
43
+
44
+ ---
45
+
46
+ ## 何時可以 / 不可以用 Tailwind utility
47
+
48
+ ### 核可清單(我們的元件 code 可以直接用)
49
+
50
+ | 類別 | 允許 utility | 備註 |
51
+ |------|-------------|------|
52
+ | **Layout / Flex / Grid** | `flex`, `grid`, `items-*`, `justify-*`, `gap-*`, `p-*`, `m-*`, `w-*`, `h-*`, `min-*`, `max-*` 等 Tailwind 預設 | spacing scale `p-4` / `gap-2` 等都 OK |
53
+ | **Display / Position** | `block`, `hidden`, `absolute`, `relative`, `z-*` | |
54
+ | **我們 DS 自訂 token utility** | `bg-surface-raised`, `text-foreground`, `text-fg-secondary`, `text-fg-muted`, `border-border`, `border-divider`, `text-body`, `text-caption`, `h-field-*`, `rounded-md` 等 | 所有 semantic token 對應的 utility |
55
+ | **CSS variable 任意值** | `shadow-[var(--elevation-200)]`, `h-[var(--field-height-md)]` 等 | **必須 `var()` 包覆**,不能 `[--foo]` shorthand |
56
+
57
+ ### 禁止清單
58
+
59
+ | 類別 | 為什麼禁止 | 改用 |
60
+ |------|----------|------|
61
+ | `shadow-sm/md/lg/xl/2xl` | 繞過 elevation token 系統,沒跟 dark mode 調整聯動 | `shadow-[var(--elevation-100/200/300)]` |
62
+ | 硬寫色值 `#xxx`, `rgb(...)`, `bg-red-500` | 繞過 semantic token,dark mode / brand swap 會斷 | 對應 semantic token |
63
+ | Tailwind 預設 typography `text-xs/sm/base/lg` | 我們有自己的 `text-caption/body/body-lg/h1/h2` 系統 | 用我們的 typography token |
64
+ | 硬寫 px 值 `w-[48px]` 當有 token | 失去 token 關聯,改值時零散處要一起改 | 對應 token 或 calc() |
65
+
66
+ ---
67
+
68
+ ## shadcn compat aliases — 不給我們元件用
69
+
70
+ `semantic.css` 的「shadcn Compat Aliases」段(`--popover`, `--popover-foreground`, `--muted-foreground`, `--accent`, `--accent-foreground` 等)**只是 `npx shadcn add X` 複製貼上時的安全網**,讓 shadcn 原生 className 不會因找不到 CSS variable 而 fallback。
71
+
72
+ **我們自己 design-system 的元件 code 禁止直接使用這些 alias**:
73
+
74
+ | 禁止(shadcn alias) | 必用(我們的 token) |
75
+ |--------------------|--------------------|
76
+ | `bg-popover` | `bg-surface-raised` |
77
+ | `text-popover-foreground` | `text-foreground` |
78
+ | `text-muted-foreground` | `text-fg-muted` |
79
+ | `bg-accent` | `bg-neutral-hover` |
80
+ | `text-accent-foreground` | `text-foreground` |
81
+ | `bg-muted` | 這個是我們核可的 token(neutral-2 subtle bg),**不是** shadcn alias,OK 用 |
82
+
83
+ **原則**:shadcn 原生 utility 只在 shadcn 自動生成的檔案**暫時**存在(作遷移緩衝);任何人類編輯或新增的元件 code 都必須用我們的 direct token。**用 shadcn alias = 設計 bug**,優先改為 direct token。
84
+
85
+ **為什麼**:shadcn alias 是「臨時橋」讓 shadcn add 不炸;我們有自己 design opinion 後直接用 own token,保持 DS 單一真實來源。允許 shadcn alias 進我們的 code = 慢慢讓 shadcn 命名污染回流,DS 自主性退化。
86
+
87
+ **曾經發生的 bug**:Popover.tsx / Command.tsx 保留 shadcn template 的 `bg-popover`, `text-popover-foreground`, `text-muted-foreground`, `bg-accent`, `text-accent-foreground` 多處,2026-04-18 session 時 audit 發現統一遷移為 direct token(`bg-surface-raised` / `text-foreground` / `text-fg-muted` / `bg-neutral-hover`)。hook `check_token_hygiene.sh` 現已自動攔截此類回流。
@@ -0,0 +1,60 @@
1
+ # UI 開發規則 — 深度展開
2
+
3
+ `.claude/rules/ui-development.md` 的 detail 版本。主章留 meta 規則(必重用既有 / 用 token / 檢查 pattern / `cn()` / 清 imports 後 runtime 驗證 / 一句話 pointer),本檔放 4 個 sub-rule 的完整規格。
4
+
5
+ ---
6
+
7
+ ## 同 flex 列的互動 slot 幾何鐵律(避免 gap token 被破壞)
8
+
9
+ 任何新 slot(status indicator / inline action / hover-swap button)放進既有 flex row 之前,**必須**執行 3 步 mechanical check:
10
+
11
+ 1. **grep 該行既有 interactive slot 的 box 尺寸**:讀 row host spec(FileItem rich row=56 用 Button xs 24 / compact row=24 用 Inline Action,依 item-anatomy「≤24 cap」canonical);grep stories 看 consumer 傳什麼
12
+ 2. **新 slot box 尺寸 = 既有 slot 尺寸**(嚴格相等):不同 → `gap-*` token 被 overflow 吃掉,實際 gap ≠ 宣告值;例外需明文 spec 註解
13
+ 3. **Hover state 也要驗**:hover-bg / ring / focus outline 若超出 box 會吃進 gap 空間
14
+
15
+ **失敗案例**:2026-04-19 FileItem status-slot hover-swap 用 `ItemInlineActionButton` 16px(不符 rich 用 Button),hover-bg 24px overflow 吃掉 4px `gap-2` → status ↔ delete 實際 gap 變 ~4px 違反 8px。修法:rich row=56 用 Button xs 24 / compact row=24 用 Inline Action。
16
+
17
+ **世界級鐵律**:同 flex 列互動元素統一 box 尺寸,gap token 才能如實呈現 — 跨元件治理層不變量,非元件內部細節。
18
+
19
+ ---
20
+
21
+ ## 新增數值前必先查既有 pattern(舉一反三)
22
+
23
+ 寫 gap / padding / font-size / line-height / icon size / border-radius 數值前,**必 grep 系統現值**。
24
+
25
+ - `gap` → `fieldWrapperStyles`(gap-2)/ MenuItem cva / SelectionItem cva
26
+ - `padding` → `--layout-space-loose/tight` / fieldWrapperStyles `px-3`
27
+ - `font-size` → `typography.css` + item-anatomy reading/scanning 規則
28
+ - `line-height` → scanning = leading-compact 1.3,reading = default 1.5
29
+ - `icon size` → `ICON_SIZE` 常數(sm/md=16, lg=20)
30
+ - `inline action` → item-anatomy「Inline Action 設計規格」(icon 16 / hover-bg=icon+2 / gap-2 / fg-muted → hover foreground)
31
+
32
+ **舉一反三**:Select inline action gap-2 → 所有元件 inline action gap-2。MenuItem description reading 14px → 所有 reading mode desc 14px。確實需要新值 → 先提理由讓 user 確認,不自決。
33
+
34
+ ---
35
+
36
+ ## Padding source 分層規則(三層各自 canonical)
37
+
38
+ | 層級 | 用途 | 來源 | 例 |
39
+ |------|------|------|---|
40
+ | **Chrome / Section / Card**(跨元件、密度切換)| page gutter / card padding / toolbar / dialog body | `p-[var(--layout-space-loose)]` / `p-[var(--layout-space-tight)]` | FileViewer toolbar / Dialog body |
41
+ | **元件內 slot**(結構性、不隨 density)| MenuItem row / Field wrapper / Dropdown item padding | Tailwind `p-N`(`p-3` / `px-2 py-1.5` 等) | item-anatomy row `px-2` / Field `px-3` |
42
+ | **精確幾何**(icon ↔ text 對齊、calc-based)| Button padding = `(field-height - icon-size)/2` | `p-[calc(...)]` / `p-[var(...)]` | Button `px-[calc((h-field-md-icon-md)/2)]` |
43
+
44
+ **判斷法**:padding 會隨 density/theme 變動嗎?是 → layout-space token;元件內部 layout 結構?是 → Tailwind `p-N`;跟 icon/text/token 算出來?是 → calc()/var。
45
+
46
+ **禁止**:Chrome padding 硬寫 `p-4`(density 切換會壞)/ 元件內 slot 用 `p-[var(--layout-space-tight)]`(密度切換讓 row 結構跑掉)。
47
+
48
+ ---
49
+
50
+ ## Icon size 來源分層規則
51
+
52
+ Icon 尺寸按 context 分三類:
53
+
54
+ | Context | 來源 | 例 |
55
+ |---------|------|---|
56
+ | **Row primitive 內**(MenuItem / TreeItem / SelectionItem / FileItem slot)| `ICON_SIZE[size]` 讀 `RowSizeContext`(自動 size-aware) | `<ItemIcon icon={User} />` 內部走 `ICON_SIZE[contextSize]` |
57
+ | **Button startIcon / endIcon** | Button 自己 mapping(固定 16/16/20 by size)| `<Button size="lg" startIcon={Save} />` 自動走 20px |
58
+ | **一次性 / 非 row / 非 Button**(chrome / decorative / toolbar)| inline `size={n}`,**n 必對齊 uiSize token**(16/20/24,不自創)| `<FileIcon size={16} />` |
59
+
60
+ **禁止**:Tailwind `w-4 h-4` / `size-4` 表達 icon size(是 dimension 非 semantic)/ Row 內手刻 `<Icon size={16} />` 繞過 Context(density 切換不聯動)/ 自創非 uiSize 值(`size={18}` / `size={22}`)。
@@ -0,0 +1,34 @@
1
+ # .claude/rules/ Charter
2
+
3
+ ## 這裡只收:path-scoped 規則(編特定 file 才 load,降 every-session context cost)
4
+
5
+ 每條 rule 一個 `.md` file,內含:
6
+ - frontmatter `paths:` glob(`**/*.spec.md` / `**/*.tsx` 等)— Claude Code 自動只在編該 path 時 inject 進 context
7
+ - body — 該 file family 的設計 / 撰寫 / 命名 / 紀律規則
8
+
9
+ **核心特徵**:**只在編對應 file 才載入**(不像 CLAUDE.md 每 session 載入)。對齊 Anthropic 2026 推薦 path-scoped CLAUDE.md fragment pattern。
10
+
11
+ ## 當前居民
12
+
13
+ | Rule | Paths | Scope |
14
+ |------|-------|-------|
15
+ | [meta-patterns.md](meta-patterns.md) | always(fundamental)| 31 active M-rules(M1-M32,M27/M33/M34/M35 retired)|
16
+ | [spec-rules.md](spec-rules.md) | `**/*.spec.md` + `packages/design-system/src/**` | Spec 撰寫紀律 + SSOT / 邊界案例 / 職責分離 |
17
+ | [ui-development.md](ui-development.md) | `**/*.tsx` + `**/*.ts` | 建 UI 前必讀 / Tailwind 5 條 / Token 4 條 / Props 命名 / shadcn |
18
+ | [story-rules.md](story-rules.md) | `**/*.stories.tsx` | 三層 stories canonical + Title / 範例 / 撰寫紀律 |
19
+ | [self-verify.md](self-verify.md) | `src/**` + `.claude/**` + `*.spec.md` + `*.tsx` + `*.css` | 4 階段(Pre/Mid/Post/Pre-commit)自主驗證 routine(2026-05-17 codify M10/M11/M20/M32 散在 meta-patterns 之 SSOT)|
20
+
21
+ ## 跟 CLAUDE.md 分工
22
+
23
+ | | CLAUDE.md | .claude/rules/ |
24
+ |---|---|---|
25
+ | 載入時機 | 每 session start 載入(行數預算 ≤ 200)| 編對應 path file 才載入(降 context cost)|
26
+ | 內容 | 6 mindset + 治理 / 稽核 / SSOT canonical / 任務導航 / fundamental rules | 該 file family 細節規則(spec 撰寫 / UI 開發 / story / self-verify)|
27
+
28
+ ## 新增 rule 流程
29
+
30
+ 1. **過 3 題**(per CLAUDE.md `# 治理 canonical`)— 既有 rule cover?Rule-of-3?7 天後還 fire 嗎?
31
+ 2. **檔名**:`<topic>.md`(kebab-case),內含 frontmatter
32
+ 3. **paths frontmatter**:glob 該 rule 該 load 的 path
33
+ 4. **加進本 README.md 表格**
34
+ 5. **MEMORY.md / CLAUDE.md 補 pointer**(若 cross-reference)
@@ -0,0 +1,87 @@
1
+ # Meta-Pattern 預警(31 active M-rules)
2
+
3
+ **mindset #6 的具體化**。每條吸收數十個具體 bug,是失敗記憶索引上游。任務前先過全部 M-rules(M1-M32,M27 retired 2026-05-15 → M23(c) child / M33-M35 retired 2026-05-22 → folded into M20/M7/M23(d) per `/knowledge-prune` deep audit Lens 1+2)。
4
+
5
+ ## 2026-05-10 cluster cross-link(per codex Q-13 deep prune audit + 2026-05-22 fold update)
6
+
7
+ 31 M-rules(M1-M32,M27/M33/M34/M35 retired)分 6 cluster(舉一反三 grouping):
8
+
9
+ | Cluster | M-rules | 共同主軸 |
10
+ |---|---|---|
11
+ | **A. SSOT-first / DS-anchor preflight** | M1 / M23(含 M27+M35 子規則)/ M29 / M30 | 視覺決策前必消費既有 SSOT;DS canonical 優先;spec.md 先 grep 找 owner;wrapper schema extends primitive;nearest same-purpose canonical wins |
12
+ | **B. Benchmark discipline stages** | M8 / M22 / M26 | 訂 rule ≥3 家對照 / 寫 spec 含 cite / propose 前 WebFetch |
13
+ | **C. Auto-integrate pipeline** | M14 / M19 / M31 | 對話結論 5-layer / trigger phrase auto-pipeline / claude-codex 5-step |
14
+ | **D. Verify / similar-bug / visual coverage** | M10 / M13 / M15 | proactive scan / user 第 2 次截圖 / visual-audit-coverable |
15
+ | **E. Propose-time discipline** | M18 / M21@watch | 4-Q 自檢 / 新元件抽象前 prop variant test |
16
+ | **F. Sharp invariants(各自獨立)** | M2 / M3 / M4 / M5 / M6 / M7(含 M34 子規則)/ M9 / M11 / M12 / M16@watch / M17 / M20(含 M33 子規則)/ M24 / M25@watch / M28 / M30@watch / M32 | sharp invariant |
17
+
18
+ `@watch` 標記(2026-05-15)= 該 M-rule 目前 absorbs 1-2 bugs(charter 要 ≥3)。1 quarter 觀察:無新 bug → demote 為既有 M-rule 子規則;有新 bug → 升 sharp keep。**2026-05-22 fold prune**:M33/M34/M35 各 absorb 1 bug → folded into parent cluster home(M33→M20 / M34→M7 / M35→M23(d)),減 3 條 M-rule 同時保留全部 invariants。Velocity 修正:本季 net add 12 rules(15 new − 3 fold)= 18 → 12 趨近 charter ≤3/quarter target,持續觀察。
19
+
20
+ **Why no merge content**:per codex Q-13「Keep M24/M25 because they are sharp, reusable state/chain invariants」+ Layer A own 認 cluster headers 是檢索輔助,不該強行 merge content(各 M-rule 已 1-line tight)。Cluster headers help 「舉一反三」without 削減 M-rule 數量。**Task #19 M21-M29 meta-merge analysis(2026-05-10 closed)**:re-audit M21-M31 全部,verdict **無 merge candidate**,各 rule sharp invariant 覆蓋 distinct failure mode(M22 implement-time cite vs M26 propose-time cite / M30 wrapper-primitive 跟 M27 framework-vs-DS / M31 collab discipline 跟 M14 / M19 auto-pipeline 各 unique scope)。Cluster table 已 cross-link,不需 merge。
21
+
22
+ ## 2026-05-10 skills consolidation analysis(Task #20 closed)
23
+
24
+ **Per Anthropic「~10 sweet spot」benchmark**:DS 現有 20 skills(`.claude/skills/` minus README),約 2x Anthropic typical recommend。**Verdict:無 aggressive merge candidate**,維持 20 skills justified:
25
+
26
+ | 類別 | Skills | 為何不 merge |
27
+ |---|---|---|
28
+ | Core audit | design-system-audit / visual-audit / component-quality-gate / knowledge-prune | 各 sharp trigger,invoke logs 顯示高頻(design-system-audit 6 / knowledge-prune 7) |
29
+ | Domain audit | ux-audit / performance-audit / code-quality-audit / product-ui-audit | D2/D3/D4/consumer-code dim 已 chain 進 design-system-audit |
30
+ | Workflow | prototype / new-component / delivery-handoff / story-writing / story-auto-compile-migrate | create / prototype / final-handoff / story 各 phase distinct rare-event(per knowledge-prune retire rule 例外) |
31
+ | Discipline | ensure-canonical / propose-options / codify-principle / codify-corrections / scan-similar-bugs / governance-health | trigger phrase / 4-Q gate / 5-layer artifact gen / batch log / post-fix scan / monthly metric 各 unique |
32
+ | Collab | codex-collab | M31 5-step home,unique |
33
+
34
+ **Marginal merge candidate**(留 user 後續 explicit approve):`codify-principle` + `codify-corrections` 都產 5-layer artifact,trigger 不同(live propose vs batch log)— 可合 `codify` 一統 skill。**不執行原因**:codex Q-13 sharp-rule preference + auto-mode 不 destructive 風險 + 兩 skill SKILL.md 各自 250 lines budget 內。User 後續 invoke `/knowledge-prune` 並 explicit approve 才動。
35
+
36
+ **RFC**:Anthropic「~10 sweet spot」是 typical CRUD app benchmark;DS governance complexity(31 active M-rules + 全 dim audit per design-system-audit SSOT + dual-track codex collab + 8-home 治理)justified higher skill count。每 skill 都過 knowledge-prune retire rule(6 月 fire 或 rare-event 豁免)。
37
+
38
+
39
+ | # | Meta-Principle | 能吸收的 bug 類型(舉例,非窮舉) |
40
+ |---|---|---|
41
+ | **M1** | **視覺決策前必消費 SSOT**(元件 / token / pattern / spec)。強制跑 `# SSOT 消費 canonical` 清單,沒列出 = 自創。 | `variant="bare"` 自發明 / chrome-header token 漏用 / Row 沒用 item-anatomy(詳 historical-bugs.md) |
42
+ | **M2** | **消費 3rd-party lib 必驗 rendered DOM**(不信 docs)。任何 `[&\[data-...\]]:` attribute selector 針對第三方元件前,inspect 真實 DOM 有無該 attribute。Library API(fit / zoom / wheel step)先寫 3 行 POC 驗證行為,再寫到元件裡。 | react-day-picker `data-range-*` 不存在 / react-zoom-pan-pinch fit-to-page 算錯(詳 historical-bugs.md) |
43
+ | **M3** | **Portal 逃逸 subtree context**(theme / density / provider)。任何 overlay 元件(DropdownMenu / Popover / Dialog / HoverCard)走 Portal 到 document body **不繼承觸發點的 subtree attribute**;theme 預設從 `<html data-theme>` 經 CSS 繼承(Portal 後 CSS chain 從 app root 起算)— 需要 override 才顯式 set `data-theme` on Portal Content;`data-density` 部分 overlay 刻意 lock `md`(詳 `density.spec.md`)。 | DropdownMenu 在 dark subtree 變亮 / Avatar HoverCard NameCard 文字白色(詳 historical-bugs.md) |
44
+ | **M4** | **`_Group` 元件必隔離單 item 的 fieldCtx**。當 Group 元件(CheckboxGroup / RadioGroup / SwitchGroup)包在 Field 內,其 child items **不可共用 fieldCtx.id / fieldCtx.hasFieldWrapper**;Group 必建自己的 Context 告訴 items「你在 group 裡」。 | CheckboxGroup 共 fieldCtx.id,label 全抑制 / 點擊只 toggle 第一個(詳 historical-bugs.md) |
45
+ | **M5** | **視覺 canonical 必 spec 聲明所有 state 疊加組合**。單一 state(today / selected / hover / disabled)有視覺定義不夠;**所有兩兩疊加、三疊加組合也要在 spec 有明文**。 | DatePicker today+selected 隱形 / hover+disabled ring 仍顯示(詳 historical-bugs.md) |
46
+ | **M6** | **Stakeholder-visible 產出 → 強制進階稽核才出稿**(不是 merge 後補)。任何「有視覺可以給 stakeholder 看」的產出(新元件 / 元件新功能 / 新產品頁 / 比稿)**必過進階完整稽核**(6 維 + 全截圖視覺驗證)。日常 dev 可用高效模式,stakeholder gate 不可。 | FileViewer 初版 8+ 項給人看才發現(詳 historical-bugs.md) |
47
+ | **M7** | **新 protocol / skill / rule 寫完,必反向 cross-check 既有 Meta-Principle 是否該套用**。尤其:consistency-class 的 protocol 必走「一致性類稽核必先全掃再判」(本章節);audit skill 必加「Self-improvement capture」Phase F step;Rule 觸及「canonical」「SSOT」「rationale」keyword → 必明示 substantive vs 表達層分權。**+ Sub-rule M34 (folded 2026-05-22)**:Hook detection regex 必對齊 spec wording 廣度。Triple test before merge new hook — (1) Spec rule wording 是「一般類別」(broad)還是「特定 keyword」(narrow)?(2) Hook regex 匹配「一般類別」還是只「特定 keyword subset」?(3) Spec broad + Hook narrow → **gap**,必擴 hook regex(unicode pattern / negative-list approach / counter-example DS-wide scan)。Propose 新 hook 必先寫 3-column table:`Spec wording` / `Hook regex` / `Gap?(broad-vs-narrow)`。 | principle-audit-protocol v1 漏套既有 Phase 0 全掃;2026-05-17 story name `照妳` `決策N` 等中英人話 detection regex 漏 |
48
+ | **M8** | **訂立 / 修改 cross-component canonical 前必 world-class benchmark**。任何 predicate / decision tree / taxonomy 類 spec,**必先 grep 至少 3 家世界級 DS**(Polaris / Material / Atlassian / Ant Design / Carbon / Apple HIG / VS Code / Figma 等)列對照表,再訂 rule。**絕對禁止**憑直覺開場寫 predicate,user 問才補對照。每個 category / variant / case 必附世界級 reference(實作名或 API 指向),沒有對照的 rule 視同未成熟,走 Checkpoint 3。 | item-anatomy Inline Action 疊代 4 次才有世界級對照 |
49
+ | **M9** | **Predicate / decision tree 寫完,present 前必 4 題自測**,防 membership drift。(a) 每 example 回跑決策樹;(b) cap / constraint cross-check;(c) 每 example 對 ≥3 家 world-class DS;(d) 每 category ≥1 example。任一題失敗 → 重收斂,**禁止 present**。 | Cat 1 IA 塞 endAction / FileItem sm 違 ≤24 cap |
50
+ | **M10** | **Proactive exhaustive scan**:canonical migration 完成前禁止只改「直覺相關」元件;final report 前禁止省略「我知道但沒講」的 tech debt。**Mechanical 落地**:每 fix commit 後 `/scan-similar-bugs` skill 強制 grep DS-wide。 | dismiss migration 漏 FileViewer / 7 題 silent tech debt user 一次炸 |
51
+ | **M11** | **User-perspective interactive state walk**:改完 UI 後 present 前必親自走 7 題 self-test(static / hover / focus-visible / active / keyboard / 範例真實性 / CSS 對稱)。每 UI 改動未跑 7 題就 commit = 違反。 | ListBody 修完 user 連抓 5 波 |
52
+ | **M12** | **Binary strict rule + fix-time root-invariant pre-question(「必 X」/「禁 Y」/ bug fix)前必 benchmark + invariant test**。3 題自測:≥3 家世界級一致 / counter-example scan / root invariant vs surface observation。震盪症狀(A→not A→A)= meta invariant 沒抓到,**停下 present**。**Fix-time 延伸**(2026-05-12 absorbs 原 M32(b)):visual / behavior bug 改前必 inline 答 3 題 — Q1「root invariant 是什麼?」Q2「symptom 在哪 layer?」Q3「fix 是 root-layer 還是 surface-layer?」。surface-only 修(改 symptom 不動 invariant)違反。對齊 5-whys / Toyota TPS / Linux kernel「fix the root not symptom」canonical。 | hover bg 震盪 4 次(bg-edge vs content-padding invariant);2026-05-12 cell-align fix surface-modify Field padding 不動 inline-flex `!h-full` root invariant |
53
+ | **M13** | **User 第 2 次提相關問題 → 自動截圖 verify**。當 user 就同一視覺 / 行為主題第 2 次問 / 糾正,AI 必 invoke 截圖 verify(`visual-audit.mjs --scope=component:XXX`)。第 3 次才 verify = 違反。**Corollary**:user 指定「所有 X 都要 Y」,同 session 全部做完 + 建 hook 防線。 | avatar-NameCard migration 分批拖延 user 第 2 次催才全改 |
54
+ | **M14** | **對話結論 → AUTO integrate pipeline**(不等 user 催)。每次 canonical / 設計決策 / 新 rule 結論時必執行 5-layer pipeline ≥ 3 層落地:M8 benchmark / SSOT home 識別 / spec / code / hook / CLAUDE.md / memory / 驗證。User 問「有沒有整合到 X」= M14 violation。**Governance auto-trigger**:`session_start_governance_check.sh` 檢查 hook / memory / CLAUDE.md / 上次 prune 達標 → 自動 inject「建議 /knowledge-prune」directive(soft 提示;hard cap 升 BLOCKER)。**數值 SSOT**:`session_start_governance_check.sh`(L19-22 + L173)+ CLAUDE.md `# 治理 canonical` 行數預算表;本 M-rule 不重述,避免 drift。 | chrome-header / dismiss / hoverCard 每個都 user 提醒才整合 |
55
+ | **M15** | **Product UI flow 必須 visual-audit coverable**。任何 stakeholder-facing flow 必含 OpenSnapshot 類 stories(`defaultOpen` / `useState(true)` / `play()`)。禁留「需真人點擊才能看到的 state」未截圖。 | Sheet / FileViewer 只截 trigger 缺 OpenSnapshot |
56
+ | **M16** | **訂 standalone card/pill 容器 canonical 必同步訂 multi-instance gap canonical**(`@watch` 2026-05-22)。3 條公式:同類 standalone → 必 gap;同類 permanent flush → 0 gap OK;混合語言 → 必取最保守 gap。Hook `check_item_list_gap.sh` 預警 + audit dim verify。**@watch 2026-05-22**:單 bug source(FileItem rich/compact)— 1 quarter 觀察是否 absorb ≥3 同類 bug,否則 demote 為 item-anatomy.spec.md 子規則。 | FileItem rich card + compact bg 連續相連 |
57
+ | **M17** | **SSOT 必可傳播**(非僅 markdown)。同值 / 同公式 hard-code 在 3+ consumer = 必抽成 token / primitive / utility class。**兩層 SSOT 架構**:底層 token(值可調)+ primitive(結構封裝 + 消費 token);世界級對照 Material/Carbon/Ant/Polaris 共識。 | mt-0.5 canonical 13 consumer hard-code 假 SSOT |
58
+ | **M18** | **Propose-time 6 題自檢 gate**(2026-05-18 升 4→6 加 Q0 + Q5)。列 option / 建議前必 inline 跑 **Q0 Pre-ASK self-verify problem 真存在**(2026-05-18 加,absorbs Sheet/inline-action/SurfaceBody 三題誤判)/ Q1 M8 benchmark / Q1' M23 DS canonical / Q2 M17 SSOT / Q3 Rule-of-3 / Q4 M10 下游吸收 / Q5 Issue 100% mapped。Reject 不列出,通過寫 6-Q 證據表。**Q0 強制動作**:propose 給 user 拍板前必 grep DS-wide + Read 相關 spec.md + Read consumer usage 確認 problem 真存在,沒 grep 就斷言「N 元件缺 X / 該 migrate」= 撤回 propose。SSOT → `.claude/skills/propose-options/SKILL.md`。Hook `check_propose_pre_grep_verify.sh` 機械強制 Q0。 | 2026-05-18:Sheet 補 / 5 元件 inline-action migrate / 5 元件 SurfaceBody migrate 三題全錯誤 propose 給 user 拍板,grep 後 0 個真 gap(Sheet 已完整 / 6 元件全消費 inline action / Dialog 走 ScrollArea canonical 不該用 SurfaceBody / HoverCard 是 behavior primitive / DatePicker TimePicker 是專用 layout / Sidebar 是 chrome 不是浮層)。User verbatim「不是老早就跟你說過要我決策前請先基於我們所有的檔案包括設計原則包括 ssot 包括所有實作代碼,自主自動驗證這些問題是否真的是問題」 |
59
+ | **M19** | **Trigger phrase auto-pipeline**。「確保 / 一定 / 永不漂移 / ensure / always」trigger → 自動 5-layer ≥ 3 層落地 + M8 + M17 + M10。Substantive 走 STOP。SSOT → `.claude/skills/ensure-canonical/SKILL.md`。 | story splitting 2026-04-26 user 第 N 次強調才落地 |
60
+ | **M20** | **AI 自問 best-practice + 自動 self-improve**(不靠 user 提醒)。Stop hook `rule_infra_best_practice_score`(R5 in `stop_passive_logging.sh`,2026-05-13 folded from retired `stop_meta_self_audit.sh`)每 turn 跑 score → < 80 / regression ≥ 5 log to `score-history.jsonl`;next-turn UserPromptSubmit `inject_pending_self_audit.sh` 注入 BLOCKER prompt。**Threshold 數值 SSOT**:`session_start_governance_check.sh`(L19-22 + L173)+ CLAUDE.md `# 治理 canonical` 行數預算表;本 M-rule 不重述具體 cap,避免多 home 漂移(2026-05-22 prune codify per Rule-of-3 violation fix)。**+ Sub-rule M33 (folded 2026-05-22)**:Stop hook overfire → AI conservative-defer 反 pattern。同 stop hook fire ≥ 5 次 within session → AI 自動 hedge / 撤回 claim / 「下個 session」defer **可做工作**。真理由 vs 偽 prereq 區辨 — (a)真 prereq 缺(cross-frame test fixture 等)= 具體 deliverable need;(b)偽 prereq(「context budget」「省工」「下個 session」)= conditioned hedge,user 反覆催 = 真理由不存在。**Rule**:AI reply 含「下個 session」「context budget」「省工」keyword 且前 1 turn user 已拍板「全部做完」/「繼續」/「沒理由不做」→ BLOCKER。對齊 Atlassian「stop using vague defer」+ Linux kernel patch review。 | user 10 次問「best-practice 嗎」直到外部 benchmark 確認真 gap;2026-05-13 claim-verify-gap stop hook fire 12+ 次 → 我每 reply 自動 hedge → user 多次糾正「沒理由不做」 |
61
+ | **M21** | **新元件 / 新 sub-component 抽象前必過 prop variant test**。當新元件名 = `<Existing>+suffix`(Time / Range / Color / Light / Dark / Filled / Outline / Compact / Rich)→ 強烈 signal 應為 prop variant on `<Existing>`。3-test 通過才能分(全失敗 → prop):(1) `<Existing>` 加 prop 無法達成同 DOM/behavior?(2) ≥3 家 world-class DS 用分離元件而非 prop(必 cite source)?(3) value 結構或 contract 真的不同(如 Range = [start, end])?Hook check_premature_abstraction(retired/未實作;mindset enforcement)。 | DateTimePicker 從 DatePicker 拆 → 撤回合併 `<DatePicker showTime>`(2026-05-02);DataTableFilterPanel 5-file → 撤回 sub-file pattern |
62
+ | **M22** | **Benchmark claim 必附 inline source citation**(不可憑印象)。寫 spec / tsx 含「Ant / Material / Polaris / Atlassian / Carbon / shadcn / Radix」等 world-class DS claim,必同段附:(a) inline URL(domain 對應 DS 官網 / GitHub source);(b) GitHub source path + line ref `#L42`;(c) screenshot reference `snapshots/...`;(d) 顯式撤回 `@benchmark-unverified`。Hook `check_benchmark_citation.sh` 機械化警告(P1 soft)。每次 implement 前跑 WebFetch 取真 source,不憑印象解碼。 | claim「Ant showTime range = 2 calendars」憑印象,實證 source code `multiplePanel = false` = 1 calendar(2026-05-02 鬼話事件)|
63
+ | **M23** | **DS 內既有 canonical 優先於外部 benchmark**。寫 visual decision(color / size / spacing / typography / state)/ prop name namespace 前必先 grep DS 既有 codified token / variant / pattern / prop;命中 → 必對齊;沒命中 → 才引 world-class + 同步補 canonical。**禁止**:外部 benchmark(M22 cite OK)直接覆蓋 DS 內已有 canonical。Mindset #2「優先消費既有」的 visual layer。判斷流程:(a) grep 該屬性 / prop 既有 token/variant/usage;(b) 命中 canonical?有 → 用,沒 → 走 M22 cite 然後 codify;(c) **prop name conflict 子規則**(former M27,2026-05-15 collapsed):外部 framework prop name(TanStack `size` / Radix `disabled` / dnd-kit attrs 等)跟 DS 既有 prop 同字不同義 → wrap-and-rename(DS-internal naming + pre-process map);(d) **nearest same-purpose canonical wins 子規則**(former M35,2026-05-22 folded):寫 stories / UI composition wrap 既有 primitive 前必先 grep + Read primitive 的「完整佈局」production canonical story(eg. `sidebar.stories.tsx#IconCollapse`)抄 archetype 結構 / helper / variant — 不准憑記憶寫 simplified mock。**Cite 存在 ≠ consume 落實**(codex 2026-05-20 verdict)。最相近同目的 canonical 用法 > 泛用 component spec / 寬鬆 pattern wording。Registry SSOT `.claude/references/story-baseline-registry.json` + hook `check_story_invariants.sh R8 story_archetype_registry`。 | 2026-05-03 chevron color:DS `text-foreground` (icon-only Button neutral-9 85%) vs 我憑「Ant 5 家 muted」覆蓋 → 自開新 tier 違反一致設計語言。2026-05-06 column width:DS 49+ 處 `size: 'sm'\|'md'\|'lg'` density vs TanStack `size: 280` px = 同 prop 不同義 → `meta.width` wrap。2026-05-20 AppShell-vs-Sidebar drift:simplified mock + jargon + wrong variant + 不消費 primitive props。Hook `check_data_table_size_num_to_meta_width.sh` + `check_story_invariants.sh R8` |
64
+ | **M24** | **State 顯著性 precedence:disabled > muted > emphasis**。元件在 disabled state 時,內部所有文字載體(label / value / placeholder / icon)統一切 disabled token(`text-fg-disabled` neutral-6),**不**繼續 muted token(`text-fg-muted` neutral-7)。muted 是裝飾,disabled 是語意 state — state 勝 emphasis。同理:error / warning state 內 placeholder 應對應 state token。Hook check_disabled_placeholder_color(retired/未實作;mindset enforcement)。 | 2026-05-04 5+ violation:`bareInputStyles` 永遠 muted / `select.tsx` 3 處 plain&tag empty 不分 mode / `textarea.tsx` 同;Input.tsx 唯一做對。User 5+ 次糾正才 codify |
65
+ | **M25** | **Layered chain invariant 必整鏈 forward(viewport-aware overlay scroll 範例)**。Overlay surface(Popover / HoverCard / Dialog / Sheet)的 viewport-aware scroll 機制要求 root → SurfaceBody 之間**所有中間 wrapper 都 forward `flex flex-col h-full`**;任何中間 div 沒 forward → SurfaceBody flex-1 失效 → body 不 scroll。同類 chain pattern:density 透傳 / fieldCtx 鏈 / theme subtree(M3 portal 逃逸對偶)。Hook check_overlay_panel_scroll_chain(retired/未實作;mindset enforcement)。 | 2026-05-04:Filter / Sort panel root `<div w-[640px]>` 無 flex-col → user 縮 viewport 時 body 不 scroll。NameCard 因自設 max-h flex-col 才繞過(無中間 wrapper) |
66
+ | **M26** | **Behavior / visual canonical decision 前必跑 WebFetch + WebSearch 取 ≥ 3 source,不可憑印象 propose**。M22 升級版 — M22 管「寫 spec / tsx 含 claim 必附 cite」(實作後),M26 管「propose / 決策前必先 fetch」(實作前)。Pipeline:(1) WebFetch 3 家世界級 source(Atlassian / Material / Polaris / Ant / Carbon / Apple HIG / shadcn / Radix);(2) 全 403 → WebSearch fallback 用 snippet,**明示「search-only confidence」**;(3) WebFetch + WebSearch 都失敗 → STOP propose,告知 user「無法 verify,要看 screenshot/實機」。Hook `check_propose_without_benchmark.sh`(PreToolUse Edit/Write 攔截 visual decision keywords + 近 N turn 無 fetch tool call → BLOCKER)。 | 2026-05-05:user 反覆糾「為什麼每次都沒 webfetch 只憑印象」— Jira drag handle / cell display 兩題我憑印象 propose 多輪;升級成硬規範 |
67
+ <!-- M27 retired 2026-05-15(per /knowledge-prune D3 audit):self-flagged「M23 子規則」 → collapsed into M23 sub-bullet (c) "framework prop name namespace conflict"。Original case (TanStack size vs DS density) + hook `check_data_table_size_num_to_meta_width.sh` retained 在 M23 children。 -->
68
+
69
+ | **M28** | **Solo-work git ops 必先 grep canonical**(mindset #2 AI-ops 子規則)。AI 自己 git/branch/PR/merge ops(`git checkout -b` / `gh pr create` / `git push origin main` / `mcp__github__create_pull_request` / `mcp__github__merge_pull_request`)前必 grep `.claude/memory/feedback_solo_dev_workflow.md` + CLAUDE.md `# Git solo-work canonical`,**不憑直覺反射開新 branch / 開 PR / 自決 merge**。Solo work 鐵律:1 chat = 1 working branch / no PR / 等 user「push」 trigger 才 merge main。Hook `check_solo_workflow.sh` 機械化攔(R1 第 2 個 branch / R2 PR creation / R3 merge 無 user trigger keyword)+ override `CLAUDE_BYPASS_SOLO_WORKFLOW=1` audit-logged。 | 2026-05-08:同 session AI 開 5 branch + 2 PR (#7 #8),user 第 3 次糾正才升 mechanical;memory file 2026-05-04 codified 但 markdown 級 + AI 沒 grep 直接憑印象 = mindset #2 違反 |
70
+ | **M29** | **DS Anchor Preflight invariant — 視覺 / 結構 propose 前必 grep `*.spec.md` 找 owner SSOT**。動 component / pattern / token 視覺結構前,**必先**:(a) `rg <touched component> + <behavior keyword>` in `packages/design-system/src/**/*.spec.md` (b) 出 **3-column owner table**(`candidate owner spec` / `canonical sentence/table row` / `conflicting code/comment if any`)(c) 若 spec ≠ code → STOP 寫 RFC 不直接 propose implementation。沒 3-column = anti-pattern,提案不被接受。SSOT index `.claude/references/ssot-index.md`(high-risk interface owner mapping)Step 0.1 先查再 grep verify。Hook `check_ds_anchor_preflight.sh` soft warn。codex-collab/SKILL.md Step 0.1 mandatory pre-grep。對齊 Carbon「design spec is source of truth」+ Atlassian「system-wide coordination first」。 | 2026-05-08:Claude+Codex 連 5 round 跳過 spec anchor pre-grep,直覺加 primitive(D path / Path A);user 抓「為何沒研讀設計原則」 |
71
+ | **M30** | **Wrapper-vs-primitive schema unify invariant — wrapper API option / config schema 必 `extends` primitive SSOT,且 wrapper 內部轉換 mapping 必 forward 全 primitive surface field**。Primitive(`SelectMenuOption` / `MenuItemProps` / `ItemAnatomyProps` 等)宣告 SSOT 後,所有 wrapper(`Select.SelectOption` / `Combobox.SelectOption` / `PeoplePicker` 等)若有同類 schema,(a) 用 TypeScript `extends primitive` 機械繼承,**不可平行 declare** weak schema(同名 / 部分欄位)(b) wrapper 內部 `xxxToYyy()` mapping 必 forward 全 primitive surface field(不可只 forward `value` + `label`,silently drop avatar / description / disabled 等)(c) wrapper-only field 加在 `extends body`(不污染 primitive)。Hook `check_wrapper_primitive_schema_drift.sh` 機械強制(P0 BLOCKER):grep `export interface .*Option \{` cross components/,同名 ≥ 2 處且未 `extends` primitive → BLOCK。對齊 Polaris ChoiceList / Material Autocomplete / Carbon Dropdown wrapper-vs-primitive schema-extension idiom。 | 2026-05-10 PeoplePicker multi-mode 漏 avatar:`Combobox.SelectOption = { value, label }` weak schema(跟 `Select.SelectOption` 同名不同 fields)+ `Combobox.menuOptions` mapping 只 forward 2 fields → dropdown rows 永遠純文字。user 抓「為什麼之前會把 people picker 改壞 + 還有沒有其他東西也改壞」。Round 1 commit `561945b` 修(Combobox extends + forward 全 field)+ Round 2 codify。 |
72
+ | **M32** | **Audit script 必 pixel-quantified verify ≠ attribute existence**(2026-05-12)。Audit 必驗 `rect.top / .left / .height` numeric pixel,**不**可只驗 `getAttribute('data-state')` / `class.includes(...)` = false-positive trap(DOM-pass ≠ visual-pass)。對齊 Material X-DataGrid / AG Grid playwright pixel snapshot / Polaris visual diff canonical。Hook `check_pixel_quantified_audit.sh` 機械強制(scans `getAttribute(` without paired `getBoundingClientRect(`)。**Split note**:原 mega 8 sub-invariants 拆 4 home — (b) fix-time root-invariant → M12 extension / (c)(d)(h) batch + parallel + claim-verify → `/bug-fix-rhythm` skill / (e) tool preflight → memory `feedback_tool_binary_preflight_sweep.md` / (f) ship gate → CLAUDE.md `# 稽核 canonical` / (g) Layer marker → M31 + hook。git blame 2026-05-12 commit 留 audit trail。 | 2026-05-12 4 audit-vs-visual gap absorbed:cell-align / divider 2px / breadcrumb tooltip / row-alignment 全 audit「Δ=0 ALL PASS」但 user 抓視覺壞(詳 historical-bugs.md)。|
73
+ | **M31** | **Adversarial dual-track 5-step canonical**(2026-05-10 user directive,verbatim quotes → `memory/feedback_codex_dual_track_synthesizer.md`)。**Step 0 入口 gate**:Claude 自試(grep / read source / cite DS canonical / WebFetch)完;啟 codex collab criteria 兩種:(a)自試卡 root cause / design tradeoff,OR(b)user 明確 keyword「跟 codex 討論 / 比稿 / 辯論 / dual-track」。**禁** auto-fire。**Step 1-5**(啟動後每題必過):(1)各自熟讀 spec/canonical/source(M29 anchor pre-grep + M23 既有 canonical 優先)(2)各自驗證(`tsc -b` + invariant + audit;codex `exec -s read-only`)— **不可只一方 verify**(M20)(3)各自視覺稽核(playwright + DOM inspect + pixel-level)(4)各自 3-column cite propose(`spec.md path:line / 引文 quote / reasoning`)— hand-wave 無 cite 自動撤回(5)整合「完美完整版本」**not pass-through**:agree → synthesize 補對方缺漏;disagree → cite battle,evidence stronger 勝。**禁**:pass-through codex propose(M28「被牽著走」);commit 無 3-column cite verdict。Hook `check_codex_collab_5step.sh` 機械化攔(P1 soft)。對齊 RFC 學術同儕審查 / Linux kernel-mailinglist cite source / Google ML eng-design-review。 | 2026-05-10 Issue 8 cell border:codex propose「Field edit border 透明」Claude pass-through ship → user「被 codex 牽著走」→ cite battle: `field-controls.spec.md` state machine + `item-anatomy.spec.md` cell 4-edge grid not in Field scope → 落地雙 owner;Issue 11 同 pattern cite battle ship retire + RFC backfill。 |
74
+ <!-- M33 retired 2026-05-22(per /knowledge-prune deep audit Lens 1+2):folded into M20 as sub-rule「Stop hook overfire defer anti-pattern」。Original session context(2026-05-13 claim-verify-gap)+ hook `stop_self_audit.sh` P0 detection retained at M20 entry。Single-bug rule → 與 M20 同類「AI self-correction under feedback signals」合併。 -->
75
+
76
+ <!-- M34 retired 2026-05-22(per /knowledge-prune deep audit Lens 1+2):folded into M7 as sub-rule「Hook detection regex 必對齊 spec wording 廣度」。Original Triple test + 錨例(story-rules.md name field detection)retained at M7 entry。Single-bug rule + same-class「rule-authoring hygiene」與 M7 合併。 -->
77
+
78
+ <!-- M35 retired 2026-05-22(per /knowledge-prune deep audit Lens 1+2):folded into M23(d) as sub-rule「Nearest same-purpose canonical wins」。Original verdict(codex 2026-05-20「Cite 存在 ≠ consume 落實」)+ Triple test + registry SSOT + hook R8 retained at M23(d)。Single-bug rule + same-class「優先消費既有」與 M23 合併。 -->
79
+
80
+ ## 判斷 meta-principle 是否漏寫的 test
81
+
82
+ - 同類 bug 一年內被糾正 3 次 → meta-principle 漏寫或沒執行,檢討本清單
83
+ - 某 bug 跟現有 M-rules 任一條對不上 → **先評估 meta-merge 既有 M-rule(velocity ≤ 3/quarter,單 M-rule 必吸收 ≥ 3 prior bugs)**;真無上游覆蓋才考慮新增 M-rule。M-rule 不該無限膨脹
84
+
85
+ ## 與失敗記憶索引的關係
86
+
87
+ Meta-principle 是**上游**(預防);具體 bug 歷史詳解移到 `.claude/skills/design-system-audit/references/historical-bugs.md`。CLAUDE.md 只留 meta-principle one-liner anchor + pointer。
@@ -0,0 +1,53 @@
1
+ # Self-verify canonical(path-scoped)
2
+
3
+ 僅在編輯任何 file(`src/**` / `.claude/**` / `*.spec.md` / `*.tsx` / `*.css`)時 load。
4
+
5
+ **Why**:M10/M11/M20/M32 散在 meta-patterns,缺單一「改檔前中後該驗什麼」canonical。本 rule SSOT。對齊 Linux kernel patch checklist / Toyota TPS 自働化 / Google CL pre-submit。
6
+
7
+ ## 4 階段強制(每階段 fail 任一 → STOP)
8
+
9
+ | 階段 | 動作 | 工具 / cmd |
10
+ |---|---|---|
11
+ | **Pre-edit** | (1) M29 3-column owner table(grep `*.spec.md` 找 anchor)(2) M23 既有 canonical 優先(`# SSOT 消費 canonical` 清單)(3) Touched file inventory + Read 真讀(非憑記憶)(4) 若 SSOT-UI/UX substantive → STOP 用中文 propose 等 user 拍板 | grep / Read / propose-options skill |
12
+ | **Mid-edit** | (1) 每 5-8 個檔案或跨新 domain 跑 scoped invariant grep(2) 發現 spec/code 衝突 STOP,不選邊(3) Hook 自動 intercept(check_substantive_edit_approval_preflight / check_solo_workflow / check_story_invariants 等)| auto-fire hooks |
13
+ | **Post-edit** | (1) `npx tsc -b`(任何 tsx/ts 改)(2) 相關 invariant script(`node scripts/data-table-invariants.mjs` 若動 DataTable / `node scripts/audit-content-quality.mjs --check` 若動 spec)(3) M10 proactive scan(`/scan-similar-bugs` 或 manual grep 同 pattern DS-wide)(4) UI 改動加 visual probe(`/visual-audit --scope=changed` 或 Playwright screenshot)(5) M14 5-layer pipeline(spec / hook / SKILL / CLAUDE.md / memory 該動的同步)| `tsc` / `*.mjs` 腳本 / visual-audit |
14
+ | **Pre-commit / Pre-final** | (1) Claim-verify table:每「已修」「已驗」對應具體 command + artifact + file:line(2) 過 `scripts/audit-content-quality.mjs --check`(3) Stop hook BLOCKER 紅燈通過(claim-verify-gap / codex-verify / codex-transport)(4) Commit message 含 cite + verdict keyword 滿足 `check_codex_collab_5step.sh` | claim-verify table + content-quality + stop hook |
15
+
16
+ ## 強制 trigger condition(滿足任一 → 整 4 階段必跑)
17
+
18
+ - 動 `packages/design-system/src/**`(production code)
19
+ - 動 `*.spec.md`(canonical text)
20
+ - 動 `.claude/{rules,skills,hooks,memory,commands}/**`(governance)
21
+ - 動 `CLAUDE.md`
22
+ - 動 token(`packages/design-system/src/tokens/**`)
23
+ - 動 component primitive consumer 行為
24
+
25
+ ## 例外 escape(明寫,**不**靠記憶)
26
+
27
+ - Typo fix(無語意改變)→ Pre-edit + tsc 即可
28
+ - 純 markdown layout / 標點 → tsc + content-quality 即可
29
+ - Hook script 內部 logic refactor(無 BLOCKER 邏輯變)→ Pre-edit + smoke test(`bash -n` + `echo {} | bash hook.sh`)
30
+ - Audit / explore agent dispatch(不動 file)→ Pre-edit 即可
31
+
32
+ ## Mechanical enforcement
33
+
34
+ - **Pre-edit**:`check_substantive_edit_approval_preflight.sh`(production code)+ `stop_self_audit.sh`(spec/canonical 補位)+ `check_ds_anchor_preflight.sh`(M29 anchor)
35
+ - **Post-edit**:`stop_self_audit.sh` Mechanism 1(claim-verify-gap)BLOCKER
36
+ - **Pre-commit**:`scripts/audit-content-quality.mjs --check` + `scripts/extract-canonical-rules.mjs` 各 fail = block
37
+
38
+ ## Anti-pattern(永久 ban)
39
+
40
+ - ❌「我感覺修好了」沒跑 tsc / invariant 就 claim done
41
+ - ❌ 動 spec / src 沒先 grep owner anchor(M29 違反)
42
+ - ❌ 改 hook 沒跑 syntax check + smoke test
43
+ - ❌「下個 session 補」defer 可做的 verify(M33 違反)
44
+ - ❌ pass-through Explore / codex propose 沒 own-version 比稿
45
+
46
+ ## 對齊歷史
47
+
48
+ - Linux kernel:`scripts/checkpatch.pl` pre-submit + `git log --oneline | head -3` 後 sign-off
49
+ - Toyota TPS:Jidoka(自働化)— 機器發現異常自己停,人別繼續(對應 hook BLOCKER)
50
+ - Google CL:LGTM + 必跑 presubmit(對應 Pre-commit table)
51
+ - Atlassian RFC:cite + counter-example scan 必過 reviewer round
52
+
53
+ 對應 CLAUDE.md `# 自主執行 canonical` + meta-patterns M10/M11/M20/M32。
@@ -0,0 +1,25 @@
1
+ ---
2
+ paths:
3
+ - "**/*.spec.md"
4
+ - "src/design-system/**"
5
+ - "packages/design-system/**"
6
+ ---
7
+
8
+ # Spec 規則(path-scoped)
9
+
10
+ 僅在編 `*.spec.md` 或 `src/design-system/` 內容時 load。
11
+
12
+ ## 核心原則
13
+
14
+ - 回答設計問題前必先讀相關 spec.md,不憑記憶
15
+ - 編輯 spec 或建新元件時必對照 **Polaris / Material / Ant / Atlassian / Carbon / Apple HIG** 的 7 維度:何時用 / 何時不用 / 近親分界 / 常見誤解 / 相關 links / 空值 / 驗證 / Loading / a11y 預設。SegmentedControl spec 是本專案 template
16
+ - 編輯 spec 必交叉比對相關 spec + Storybook,確認無矛盾 / 術語一致 / 無重複
17
+ - 與既有 spec 有邏輯衝突 / 概念混淆 → 主動提出討論,不默默改 / 不迴避
18
+ - 所有元件遵循 shadcn 框架(forwardRef / Slot / data-* / cva),不從零重寫
19
+ - 每個元件 spec「定位」段必明確宣告實作基礎:`基於 Radix X` / `基於 cmdk / sonner` / native / `自建 + 理由`(自建必說明為何不用現有 primitive)
20
+ - Spec 文字品質:不描述視覺形狀 / 實作細節(「窄長形」「會變寬」「zero layout shift」屬 story 不進 spec);術語一致;「禁止事項(❌)」列所有常見誤用
21
+ - **a11y 段強制**:互動元件 spec.md 必含 `## A11y 預設` 段(列 ARIA + Keyboard map);純視覺 indicator(Badge / Tag / Separator / Skeleton)豁免明文寫「本元件無互動」
22
+
23
+ ## SSOT + 邊界案例覆蓋 + 職責分離
24
+
25
+ 詳 `.claude/references/spec-rules.md` — SSOT 深度判斷 / reciprocal 規則 / 目前 6 個 SSOT anchors / 邊界案例 scope 預設(Field 家族 / dark mode / density / 純 wrapper)/ spec 與 tsx 職責分離 / calc() 公式表達。