@qijenchen/design-system 0.1.0-beta.82 → 0.1.0-beta.84

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 (612) hide show
  1. package/CLAUDE.md +8 -8
  2. package/README.md +3 -2
  3. package/dist/components/Alert/alert.js.map +1 -1
  4. package/dist/components/AppShell/_demo-helpers.d.ts.map +1 -1
  5. package/dist/components/AppShell/app-shell.d.ts +1 -1
  6. package/dist/components/AppShell/app-shell.d.ts.map +1 -1
  7. package/dist/components/AppShell/app-shell.js +22 -2
  8. package/dist/components/AppShell/app-shell.js.map +1 -1
  9. package/dist/components/Avatar/avatar.d.ts.map +1 -1
  10. package/dist/components/Avatar/avatar.js +4 -4
  11. package/dist/components/Avatar/avatar.js.map +1 -1
  12. package/dist/components/Breadcrumb/breadcrumb.d.ts.map +1 -1
  13. package/dist/components/Breadcrumb/breadcrumb.js +1 -1
  14. package/dist/components/Breadcrumb/breadcrumb.js.map +1 -1
  15. package/dist/components/Button/button.d.ts +2 -2
  16. package/dist/components/Button/button.d.ts.map +1 -1
  17. package/dist/components/Button/button.js +12 -3
  18. package/dist/components/Button/button.js.map +1 -1
  19. package/dist/components/Calendar/calendar.d.ts +13 -5
  20. package/dist/components/Calendar/calendar.d.ts.map +1 -1
  21. package/dist/components/Calendar/calendar.js +7 -1
  22. package/dist/components/Calendar/calendar.js.map +1 -1
  23. package/dist/components/Carousel/carousel.d.ts.map +1 -1
  24. package/dist/components/Carousel/carousel.js +8 -3
  25. package/dist/components/Carousel/carousel.js.map +1 -1
  26. package/dist/components/Chart/chart.d.ts.map +1 -1
  27. package/dist/components/Chart/chart.js +1 -0
  28. package/dist/components/Chart/chart.js.map +1 -1
  29. package/dist/components/Checkbox/checkbox.d.ts +1 -1
  30. package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
  31. package/dist/components/Checkbox/checkbox.js +8 -4
  32. package/dist/components/Checkbox/checkbox.js.map +1 -1
  33. package/dist/components/Chip/chip.d.ts +1 -1
  34. package/dist/components/Chip/chip.d.ts.map +1 -1
  35. package/dist/components/Chip/chip.js.map +1 -1
  36. package/dist/components/Coachmark/coachmark.d.ts +10 -3
  37. package/dist/components/Coachmark/coachmark.d.ts.map +1 -1
  38. package/dist/components/Coachmark/coachmark.js.map +1 -1
  39. package/dist/components/Combobox/combobox.d.ts +5 -1
  40. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  41. package/dist/components/Combobox/combobox.js +30 -13
  42. package/dist/components/Combobox/combobox.js.map +1 -1
  43. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  44. package/dist/components/DataTable/cell-registry.js +53 -62
  45. package/dist/components/DataTable/cell-registry.js.map +1 -1
  46. package/dist/components/DataTable/column-types.d.ts +10 -4
  47. package/dist/components/DataTable/column-types.d.ts.map +1 -1
  48. package/dist/components/DataTable/column-types.js.map +1 -1
  49. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts +1 -1
  50. package/dist/components/DataTable/data-table-column-visibility-panel.js +183 -0
  51. package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -0
  52. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
  53. package/dist/components/DataTable/data-table-filter-panel.js +607 -0
  54. package/dist/components/DataTable/data-table-filter-panel.js.map +1 -0
  55. package/dist/components/DataTable/data-table-interaction-layer.d.ts +11 -15
  56. package/dist/components/DataTable/data-table-interaction-layer.d.ts.map +1 -1
  57. package/dist/components/DataTable/data-table-interaction-layer.js +1 -3
  58. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
  59. package/dist/components/DataTable/data-table-sort-manager.js +140 -0
  60. package/dist/components/DataTable/data-table-sort-manager.js.map +1 -0
  61. package/dist/components/DataTable/data-table.d.ts +5 -6
  62. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  63. package/dist/components/DataTable/data-table.js +36 -15
  64. package/dist/components/DataTable/data-table.js.map +1 -1
  65. package/dist/components/DataTable/filter-operators.js +140 -0
  66. package/dist/components/DataTable/filter-operators.js.map +1 -0
  67. package/dist/components/DataTable/filter-tree.js +312 -0
  68. package/dist/components/DataTable/filter-tree.js.map +1 -0
  69. package/dist/components/DataTable/index.d.ts +3 -0
  70. package/dist/components/DataTable/index.d.ts.map +1 -1
  71. package/dist/components/DataTable/index.js +12 -1
  72. package/dist/components/DataTable/index.js.map +1 -1
  73. package/dist/components/DataTable/lib/column-meta.js +25 -0
  74. package/dist/components/DataTable/lib/column-meta.js.map +1 -0
  75. package/dist/components/DateGrid/date-grid.d.ts.map +1 -1
  76. package/dist/components/DateGrid/date-grid.js +3 -1
  77. package/dist/components/DateGrid/date-grid.js.map +1 -1
  78. package/dist/components/DatePicker/date-picker.d.ts +7 -1
  79. package/dist/components/DatePicker/date-picker.d.ts.map +1 -1
  80. package/dist/components/DatePicker/date-picker.js +105 -74
  81. package/dist/components/DatePicker/date-picker.js.map +1 -1
  82. package/dist/components/Dialog/dialog.d.ts +20 -3
  83. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  84. package/dist/components/Dialog/dialog.js +38 -20
  85. package/dist/components/Dialog/dialog.js.map +1 -1
  86. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  87. package/dist/components/DropdownMenu/dropdown-menu.js +3 -1
  88. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  89. package/dist/components/Field/field-context.d.ts +45 -5
  90. package/dist/components/Field/field-context.d.ts.map +1 -1
  91. package/dist/components/Field/field-context.js +19 -0
  92. package/dist/components/Field/field-context.js.map +1 -1
  93. package/dist/components/Field/field-edit-keys.d.ts +21 -0
  94. package/dist/components/Field/field-edit-keys.d.ts.map +1 -0
  95. package/dist/components/Field/field-edit-keys.js +19 -0
  96. package/dist/components/Field/field-edit-keys.js.map +1 -0
  97. package/dist/components/Field/field-types.d.ts +20 -1
  98. package/dist/components/Field/field-types.d.ts.map +1 -1
  99. package/dist/components/Field/field-types.js.map +1 -1
  100. package/dist/components/Field/field-wrapper.d.ts +3 -2
  101. package/dist/components/Field/field-wrapper.d.ts.map +1 -1
  102. package/dist/components/Field/field-wrapper.js +38 -39
  103. package/dist/components/Field/field-wrapper.js.map +1 -1
  104. package/dist/components/Field/field.d.ts +2 -1
  105. package/dist/components/Field/field.d.ts.map +1 -1
  106. package/dist/components/Field/field.js.map +1 -1
  107. package/dist/components/FieldControlGroup/field-control-group.d.ts +1 -1
  108. package/dist/components/FieldControlGroup/field-control-group.js.map +1 -1
  109. package/dist/components/FileItem/file-item.d.ts.map +1 -1
  110. package/dist/components/FileItem/file-item.js +1 -1
  111. package/dist/components/FileItem/file-item.js.map +1 -1
  112. package/dist/components/FileUpload/file-upload.d.ts +1 -1
  113. package/dist/components/FileUpload/file-upload.js.map +1 -1
  114. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  115. package/dist/components/FileViewer/file-viewer.js +7 -2
  116. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  117. package/dist/components/FileViewer/image-renderer.d.ts.map +1 -1
  118. package/dist/components/FileViewer/image-renderer.js +22 -1
  119. package/dist/components/FileViewer/image-renderer.js.map +1 -1
  120. package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
  121. package/dist/components/HoverCard/hover-card.js +5 -3
  122. package/dist/components/HoverCard/hover-card.js.map +1 -1
  123. package/dist/components/InlineEdit/index.d.ts +2 -0
  124. package/dist/components/InlineEdit/index.d.ts.map +1 -0
  125. package/dist/components/InlineEdit/index.js +5 -0
  126. package/dist/components/InlineEdit/index.js.map +1 -0
  127. package/dist/components/InlineEdit/inline-edit.d.ts +59 -0
  128. package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -0
  129. package/dist/components/InlineEdit/inline-edit.js +164 -0
  130. package/dist/components/InlineEdit/inline-edit.js.map +1 -0
  131. package/dist/components/Input/input.d.ts +6 -11
  132. package/dist/components/Input/input.d.ts.map +1 -1
  133. package/dist/components/Input/input.js +43 -13
  134. package/dist/components/Input/input.js.map +1 -1
  135. package/dist/components/LinkInput/link-input.d.ts +2 -2
  136. package/dist/components/LinkInput/link-input.d.ts.map +1 -1
  137. package/dist/components/LinkInput/link-input.js +6 -5
  138. package/dist/components/LinkInput/link-input.js.map +1 -1
  139. package/dist/components/Menu/menu-item.d.ts +14 -2
  140. package/dist/components/Menu/menu-item.d.ts.map +1 -1
  141. package/dist/components/Menu/menu-item.js +25 -3
  142. package/dist/components/Menu/menu-item.js.map +1 -1
  143. package/dist/components/NumberInput/number-input.d.ts +3 -3
  144. package/dist/components/NumberInput/number-input.d.ts.map +1 -1
  145. package/dist/components/NumberInput/number-input.js +6 -5
  146. package/dist/components/NumberInput/number-input.js.map +1 -1
  147. package/dist/components/OverflowIndicator/overflow-indicator.d.ts.map +1 -1
  148. package/dist/components/OverflowIndicator/overflow-indicator.js +2 -6
  149. package/dist/components/OverflowIndicator/overflow-indicator.js.map +1 -1
  150. package/dist/components/Pagination/pagination.js +1 -1
  151. package/dist/components/Pagination/pagination.js.map +1 -1
  152. package/dist/components/PeoplePicker/index.js +7 -1
  153. package/dist/components/PeoplePicker/index.js.map +1 -1
  154. package/dist/components/PeoplePicker/people-picker.d.ts +9 -2
  155. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  156. package/dist/components/PeoplePicker/people-picker.js +23 -10
  157. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  158. package/dist/components/PeoplePicker/person-display.d.ts +6 -3
  159. package/dist/components/PeoplePicker/person-display.d.ts.map +1 -1
  160. package/dist/components/PeoplePicker/person-display.js +19 -14
  161. package/dist/components/PeoplePicker/person-display.js.map +1 -1
  162. package/dist/components/Popover/popover.d.ts.map +1 -1
  163. package/dist/components/Popover/popover.js +3 -1
  164. package/dist/components/Popover/popover.js.map +1 -1
  165. package/dist/components/ProfileCard/profile-card.d.ts +2 -2
  166. package/dist/components/ProfileCard/profile-card.js +3 -3
  167. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  168. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
  169. package/dist/components/RadioGroup/radio-group.js +15 -9
  170. package/dist/components/RadioGroup/radio-group.js.map +1 -1
  171. package/dist/components/ScrollArea/scroll-area.d.ts +11 -1
  172. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
  173. package/dist/components/ScrollArea/scroll-area.js +6 -3
  174. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  175. package/dist/components/Select/select.d.ts +46 -5
  176. package/dist/components/Select/select.d.ts.map +1 -1
  177. package/dist/components/Select/select.js +109 -28
  178. package/dist/components/Select/select.js.map +1 -1
  179. package/dist/components/SelectMenu/select-menu.d.ts +3 -1
  180. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  181. package/dist/components/SelectMenu/select-menu.js +8 -1
  182. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  183. package/dist/components/SelectionControl/boolean-value.d.ts +11 -0
  184. package/dist/components/SelectionControl/boolean-value.d.ts.map +1 -0
  185. package/dist/components/SelectionControl/boolean-value.js +23 -0
  186. package/dist/components/SelectionControl/boolean-value.js.map +1 -0
  187. package/dist/components/SelectionControl/index.d.ts +1 -0
  188. package/dist/components/SelectionControl/index.d.ts.map +1 -1
  189. package/dist/components/SelectionControl/index.js +2 -0
  190. package/dist/components/SelectionControl/index.js.map +1 -1
  191. package/dist/components/Sheet/index.js +2 -1
  192. package/dist/components/Sheet/sheet.d.ts +7 -1
  193. package/dist/components/Sheet/sheet.d.ts.map +1 -1
  194. package/dist/components/Sheet/sheet.js +5 -2
  195. package/dist/components/Sheet/sheet.js.map +1 -1
  196. package/dist/components/Sidebar/sidebar.d.ts +9 -4
  197. package/dist/components/Sidebar/sidebar.d.ts.map +1 -1
  198. package/dist/components/Sidebar/sidebar.js +8 -10
  199. package/dist/components/Sidebar/sidebar.js.map +1 -1
  200. package/dist/components/Slider/slider.d.ts.map +1 -1
  201. package/dist/components/Slider/slider.js.map +1 -1
  202. package/dist/components/Switch/switch.d.ts +6 -6
  203. package/dist/components/Switch/switch.d.ts.map +1 -1
  204. package/dist/components/Switch/switch.js +3 -2
  205. package/dist/components/Switch/switch.js.map +1 -1
  206. package/dist/components/Tabs/tabs.d.ts.map +1 -1
  207. package/dist/components/Tabs/tabs.js +15 -1
  208. package/dist/components/Tabs/tabs.js.map +1 -1
  209. package/dist/components/Textarea/textarea.d.ts +2 -2
  210. package/dist/components/Textarea/textarea.d.ts.map +1 -1
  211. package/dist/components/Textarea/textarea.js +50 -42
  212. package/dist/components/Textarea/textarea.js.map +1 -1
  213. package/dist/components/TimePicker/time-columns.d.ts.map +1 -1
  214. package/dist/components/TimePicker/time-columns.js +42 -38
  215. package/dist/components/TimePicker/time-columns.js.map +1 -1
  216. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  217. package/dist/components/TimePicker/time-picker.js +8 -6
  218. package/dist/components/TimePicker/time-picker.js.map +1 -1
  219. package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
  220. package/dist/components/Tooltip/tooltip.js +7 -5
  221. package/dist/components/Tooltip/tooltip.js.map +1 -1
  222. package/dist/components/TreeView/tree-view.d.ts +56 -1
  223. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  224. package/dist/components/TreeView/tree-view.js +211 -12
  225. package/dist/components/TreeView/tree-view.js.map +1 -1
  226. package/dist/index.d.ts +115 -58
  227. package/dist/index.d.ts.map +1 -1
  228. package/dist/index.js +93 -108
  229. package/dist/index.js.map +1 -1
  230. package/dist/patterns/element-anatomy/item-anatomy.d.ts +7 -6
  231. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
  232. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  233. package/dist/tokens/categorical-color.js +15 -0
  234. package/dist/tokens/categorical-color.js.map +1 -1
  235. package/dist/tokens/motion/motion.d.ts +7 -6
  236. package/dist/tokens/motion/motion.d.ts.map +1 -1
  237. package/dist/tokens/motion/motion.js +6 -6
  238. package/dist/tokens/motion/motion.js.map +1 -1
  239. package/dist/tokens/motion/overlay-motion.d.ts +19 -0
  240. package/dist/tokens/motion/overlay-motion.d.ts.map +1 -0
  241. package/dist/tokens/motion/overlay-motion.js +9 -0
  242. package/dist/tokens/motion/overlay-motion.js.map +1 -0
  243. package/dist/tokens/uiSize/icon-size.js +5 -0
  244. package/dist/tokens/uiSize/icon-size.js.map +1 -0
  245. package/ds-canonical/fork/governance.lock +37 -19
  246. package/ds-canonical/fork/hooks/_log-fire.sh +46 -0
  247. package/ds-canonical/fork/hooks/block_prototype_imports.py +15 -4
  248. package/ds-canonical/fork/hooks/check_consumer_app_invariants.sh +145 -13
  249. package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +17 -5
  250. package/ds-canonical/fork/hooks/check_dynamic_tailwind_class.sh +47 -0
  251. package/ds-canonical/fork/hooks/check_escape_marker_abuse.sh +27 -0
  252. package/ds-canonical/fork/hooks/check_field_family_invariants.sh +61 -1
  253. package/ds-canonical/fork/hooks/check_layout_space_magic_numbers.sh +28 -4
  254. package/ds-canonical/fork/hooks/check_opacity_token_usage.sh +36 -0
  255. package/ds-canonical/fork/hooks/check_story_determinism.sh +39 -0
  256. package/ds-canonical/fork/hooks/check_story_invariants.sh +119 -0
  257. package/ds-canonical/fork/hooks/check_tabs_content_chrome_body_double_gap.sh +29 -0
  258. package/ds-canonical/fork/manifest.json +20 -0
  259. package/ds-canonical/fork/preamble.md +22 -18
  260. package/ds-canonical/fork/skills/bug-fix-rhythm/SKILL.md +9 -3
  261. package/ds-canonical/fork/skills/code-quality-audit/SKILL.md +3 -3
  262. package/ds-canonical/fork/skills/delivery-handoff/SKILL.md +7 -0
  263. package/ds-canonical/fork/skills/performance-audit/SKILL.md +4 -2
  264. package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +3 -3
  265. package/ds-canonical/fork/skills/propose-options/SKILL.md +3 -3
  266. package/ds-canonical/fork/skills/prototype/SKILL.md +1 -1
  267. package/ds-canonical/fork/skills/scan-similar-bugs/SKILL.md +2 -2
  268. package/ds-canonical/fork/skills/visual-audit/SKILL.md +10 -2
  269. package/ds-canonical/hooks/README.md +1 -1
  270. package/ds-canonical/hooks/block_prototype_imports.py +15 -4
  271. package/ds-canonical/hooks/check_audit_post_report_validator.sh +65 -7
  272. package/ds-canonical/hooks/check_benchmark_citation.sh +5 -3
  273. package/ds-canonical/hooks/check_codex_brief_invariants.sh +28 -1
  274. package/ds-canonical/hooks/check_consumer_app_invariants.sh +145 -13
  275. package/ds-canonical/hooks/check_ds_anchor_preflight.sh +17 -5
  276. package/ds-canonical/hooks/check_dynamic_tailwind_class.sh +47 -0
  277. package/ds-canonical/hooks/check_escape_marker_abuse.sh +27 -0
  278. package/ds-canonical/hooks/check_field_family_invariants.sh +61 -1
  279. package/ds-canonical/hooks/check_layout_space_magic_numbers.sh +28 -4
  280. package/ds-canonical/hooks/check_naming_and_abstraction.sh +1 -1
  281. package/ds-canonical/hooks/check_opacity_token_usage.sh +36 -0
  282. package/ds-canonical/hooks/check_pixel_quantified_audit.sh +3 -2
  283. package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +6 -1
  284. package/ds-canonical/hooks/check_propose_without_benchmark.sh +6 -2
  285. package/ds-canonical/hooks/check_ssot_header_declaration.sh +55 -0
  286. package/ds-canonical/hooks/check_story_determinism.sh +39 -0
  287. package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +8 -7
  288. package/ds-canonical/hooks/check_tabs_content_chrome_body_double_gap.sh +29 -0
  289. package/ds-canonical/hooks/lib/_story_compile_drift.sh +1 -1
  290. package/ds-canonical/hooks/lib/_token_hygiene.sh +10 -1
  291. package/ds-canonical/hooks/stop_self_audit.sh +31 -0
  292. package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +24 -0
  293. package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +44 -0
  294. package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +3 -3
  295. package/ds-canonical/hooks/tests/test_check_codex_brief_invariants.sh +43 -2
  296. package/ds-canonical/hooks/tests/test_check_consumer_ds_primitive_misuse.sh +112 -0
  297. package/ds-canonical/hooks/tests/test_check_consumer_story_baseline.sh +9 -2
  298. package/ds-canonical/hooks/tests/test_check_dynamic_tailwind_class.sh +76 -0
  299. package/ds-canonical/hooks/tests/test_check_escape_marker_abuse.sh +24 -0
  300. package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +27 -2
  301. package/ds-canonical/hooks/tests/test_check_fork_user_plugin_install.sh +3 -1
  302. package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +41 -2
  303. package/ds-canonical/hooks/tests/test_check_ssot_header_declaration.sh +72 -0
  304. package/ds-canonical/hooks/tests/test_check_tabs_content_chrome_body_double_gap.sh +76 -0
  305. package/ds-canonical/references/audit-coverage-vs-24-checklist.md +1 -1
  306. package/ds-canonical/references/build-ui-canonicals.md +2 -1
  307. package/ds-canonical/references/failure-class-registry.json +145 -0
  308. package/ds-canonical/references/governance-audit-coverage.md +33 -0
  309. package/ds-canonical/references/item-anatomy-recipe.md +2 -2
  310. package/ds-canonical/references/scenario-definition.md +6 -9
  311. package/ds-canonical/references/ssot-consultation.md +2 -2
  312. package/ds-canonical/references/ssot-index.md +5 -4
  313. package/ds-canonical/references/story-baseline-registry.json +8 -2
  314. package/ds-canonical/references/structural-token-retention.md +6 -9
  315. package/ds-canonical/rules/meta-patterns.md +8 -8
  316. package/ds-canonical/rules/self-verify.md +4 -3
  317. package/ds-canonical/rules/spec-rules.md +1 -1
  318. package/ds-canonical/rules/story-rules.md +2 -2
  319. package/ds-canonical/rules/ui-development.md +4 -2
  320. package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +9 -3
  321. package/ds-canonical/skills/code-quality-audit/SKILL.md +3 -3
  322. package/ds-canonical/skills/codex-collab/SKILL.md +9 -7
  323. package/ds-canonical/skills/codex-collab/references/brief-template.md +1 -1
  324. package/ds-canonical/skills/codify-principle/SKILL.md +2 -2
  325. package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
  326. package/ds-canonical/skills/component-quality-gate/references/checklist.md +2 -2
  327. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +57 -68
  328. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +29 -0
  329. package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +29 -10
  330. package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +21 -0
  331. package/ds-canonical/skills/delivery-handoff/SKILL.md +5 -0
  332. package/ds-canonical/skills/design-system-audit/SKILL.md +27 -26
  333. package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +13 -1
  334. package/ds-canonical/skills/design-system-audit/references/rule-placement.md +1 -1
  335. package/ds-canonical/skills/governance-health/SKILL.md +2 -1
  336. package/ds-canonical/skills/knowledge-prune/SKILL.md +3 -0
  337. package/ds-canonical/skills/knowledge-prune/references/prune-dimensions-d5-d10.md +1 -0
  338. package/ds-canonical/skills/new-component/SKILL.md +7 -5
  339. package/ds-canonical/skills/new-component/references/new-component-checklist.md +1 -1
  340. package/ds-canonical/skills/performance-audit/SKILL.md +2 -2
  341. package/ds-canonical/skills/product-ui-audit/SKILL.md +3 -3
  342. package/ds-canonical/skills/propose-options/SKILL.md +3 -3
  343. package/ds-canonical/skills/prototype/SKILL.md +1 -1
  344. package/ds-canonical/skills/scan-similar-bugs/SKILL.md +2 -2
  345. package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +3 -3
  346. package/ds-canonical/skills/story-writing/SKILL.md +3 -3
  347. package/ds-canonical/skills/visual-audit/SKILL.md +10 -2
  348. package/ds-story-manifest.json +29 -20
  349. package/llms-full.txt +22 -1
  350. package/llms.txt +5 -4
  351. package/package.json +7 -3
  352. package/src/components/Accordion/accordion.principles.stories.tsx +1 -1
  353. package/src/components/Accordion/accordion.stories.tsx +16 -1
  354. package/src/components/Alert/alert.principles.stories.tsx +1 -1
  355. package/src/components/Alert/alert.spec.md +8 -10
  356. package/src/components/Alert/alert.stories.tsx +28 -28
  357. package/src/components/Alert/alert.tsx +1 -1
  358. package/src/components/AppShell/_demo-helpers.tsx +6 -3
  359. package/src/components/AppShell/app-shell.spec.md +4 -4
  360. package/src/components/AppShell/app-shell.tsx +28 -2
  361. package/src/components/AspectRatio/aspect-ratio.spec.md +1 -1
  362. package/src/components/AspectRatio/aspect-ratio.stories.tsx +7 -89
  363. package/src/components/Avatar/avatar.anatomy.stories.tsx +7 -3
  364. package/src/components/Avatar/avatar.principles.stories.tsx +19 -15
  365. package/src/components/Avatar/avatar.spec.md +2 -2
  366. package/src/components/Avatar/avatar.stories.tsx +8 -6
  367. package/src/components/Avatar/avatar.tsx +13 -5
  368. package/src/components/Badge/badge.principles.stories.tsx +1 -1
  369. package/src/components/Badge/badge.spec.md +2 -0
  370. package/src/components/Badge/badge.stories.tsx +4 -2
  371. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +6 -4
  372. package/src/components/Breadcrumb/breadcrumb.stories.tsx +6 -5
  373. package/src/components/Breadcrumb/breadcrumb.tsx +3 -2
  374. package/src/components/BulkActionBar/bulk-action-bar.spec.md +4 -2
  375. package/src/components/Button/button.principles.stories.tsx +1 -1
  376. package/src/components/Button/button.spec.md +2 -2
  377. package/src/components/Button/button.tsx +18 -3
  378. package/src/components/Calendar/calendar.anatomy.stories.tsx +12 -10
  379. package/src/components/Calendar/calendar.principles.stories.tsx +14 -6
  380. package/src/components/Calendar/calendar.spec.md +5 -4
  381. package/src/components/Calendar/calendar.stories.tsx +7 -4
  382. package/src/components/Calendar/calendar.tsx +26 -7
  383. package/src/components/Carousel/carousel.anatomy.stories.tsx +5 -4
  384. package/src/components/Carousel/carousel.spec.md +2 -2
  385. package/src/components/Carousel/carousel.tsx +11 -3
  386. package/src/components/Chart/chart.anatomy.stories.tsx +7 -4
  387. package/src/components/Chart/chart.principles.stories.tsx +1 -1
  388. package/src/components/Chart/chart.stories.tsx +2 -8
  389. package/src/components/Chart/chart.tsx +3 -0
  390. package/src/components/Checkbox/checkbox.anatomy.stories.tsx +28 -49
  391. package/src/components/Checkbox/checkbox.principles.stories.tsx +1 -1
  392. package/src/components/Checkbox/checkbox.spec.md +11 -26
  393. package/src/components/Checkbox/checkbox.stories.tsx +11 -8
  394. package/src/components/Checkbox/checkbox.tsx +18 -13
  395. package/src/components/Chip/chip.anatomy.stories.tsx +44 -24
  396. package/src/components/Chip/chip.principles.stories.tsx +1 -1
  397. package/src/components/Chip/chip.spec.md +5 -4
  398. package/src/components/Chip/chip.tsx +5 -1
  399. package/src/components/CircularProgress/circular-progress.principles.stories.tsx +7 -4
  400. package/src/components/CircularProgress/circular-progress.spec.md +3 -3
  401. package/src/components/CircularProgress/circular-progress.stories.tsx +2 -2
  402. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +2 -2
  403. package/src/components/Coachmark/coachmark.principles.stories.tsx +2 -1
  404. package/src/components/Coachmark/coachmark.spec.md +5 -5
  405. package/src/components/Coachmark/coachmark.stories.tsx +3 -1
  406. package/src/components/Coachmark/coachmark.tsx +10 -3
  407. package/src/components/Combobox/combobox.anatomy.stories.tsx +2 -2
  408. package/src/components/Combobox/combobox.tsx +53 -19
  409. package/src/components/Command/command.anatomy.stories.tsx +2 -2
  410. package/src/components/Command/command.principles.stories.tsx +1 -1
  411. package/src/components/Command/command.stories.tsx +42 -10
  412. package/src/components/DataTable/cell-registry.tsx +86 -63
  413. package/src/components/DataTable/column-types.ts +10 -1
  414. package/src/components/DataTable/data-table-column-visibility-panel.tsx +1 -1
  415. package/src/components/DataTable/data-table-filter-panel.tsx +4 -1
  416. package/src/components/DataTable/data-table-interaction-layer.tsx +15 -19
  417. package/src/components/DataTable/data-table.anatomy.stories.tsx +15 -13
  418. package/src/components/DataTable/data-table.principles.stories.tsx +9 -9
  419. package/src/components/DataTable/data-table.spec.md +32 -12
  420. package/src/components/DataTable/data-table.stories.tsx +16 -17
  421. package/src/components/DataTable/data-table.tsx +103 -60
  422. package/src/components/DataTable/index.ts +3 -0
  423. package/src/components/DateGrid/date-grid.anatomy.stories.tsx +4 -4
  424. package/src/components/DateGrid/date-grid.principles.stories.tsx +1 -1
  425. package/src/components/DateGrid/date-grid.spec.md +1 -1
  426. package/src/components/DateGrid/date-grid.tsx +3 -1
  427. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +8 -8
  428. package/src/components/DatePicker/date-picker.principles.stories.tsx +3 -3
  429. package/src/components/DatePicker/date-picker.spec.md +3 -3
  430. package/src/components/DatePicker/date-picker.stories.tsx +4 -5
  431. package/src/components/DatePicker/date-picker.tsx +99 -45
  432. package/src/components/DescriptionList/description-list.anatomy.stories.tsx +12 -10
  433. package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
  434. package/src/components/DescriptionList/description-list.spec.md +3 -3
  435. package/src/components/DescriptionList/description-list.stories.tsx +7 -6
  436. package/src/components/Dialog/dialog.anatomy.stories.tsx +1 -0
  437. package/src/components/Dialog/dialog.spec.md +9 -0
  438. package/src/components/Dialog/dialog.stories.tsx +66 -5
  439. package/src/components/Dialog/dialog.tsx +60 -25
  440. package/src/components/DropdownMenu/dropdown-menu.anatomy.stories.tsx +1 -1
  441. package/src/components/DropdownMenu/dropdown-menu.principles.stories.tsx +8 -6
  442. package/src/components/DropdownMenu/dropdown-menu.spec.md +5 -5
  443. package/src/components/DropdownMenu/dropdown-menu.tsx +18 -9
  444. package/src/components/Empty/empty.anatomy.stories.tsx +1 -1
  445. package/src/components/Empty/empty.spec.md +2 -2
  446. package/src/components/Field/field-context.ts +69 -5
  447. package/src/components/Field/field-controls.spec.md +62 -8
  448. package/src/components/Field/field-edit-keys.ts +66 -0
  449. package/src/components/Field/field-types.ts +58 -9
  450. package/src/components/Field/field-wrapper.tsx +50 -42
  451. package/src/components/Field/field.anatomy.stories.tsx +9 -6
  452. package/src/components/Field/field.spec.md +1 -1
  453. package/src/components/Field/field.stories.tsx +1 -1
  454. package/src/components/Field/field.tsx +2 -1
  455. package/src/components/Field/form-validation.spec.md +3 -3
  456. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +6 -6
  457. package/src/components/FieldControlGroup/field-control-group.spec.md +9 -4
  458. package/src/components/FieldControlGroup/field-control-group.tsx +1 -1
  459. package/src/components/FileItem/file-item.anatomy.stories.tsx +1 -1
  460. package/src/components/FileItem/file-item.spec.md +14 -8
  461. package/src/components/FileItem/file-item.stories.tsx +36 -25
  462. package/src/components/FileItem/file-item.tsx +8 -6
  463. package/src/components/FileUpload/file-upload.anatomy.stories.tsx +6 -6
  464. package/src/components/FileUpload/file-upload.principles.stories.tsx +5 -5
  465. package/src/components/FileUpload/file-upload.spec.md +1 -1
  466. package/src/components/FileUpload/file-upload.tsx +1 -1
  467. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +4 -3
  468. package/src/components/FileViewer/file-viewer.principles.stories.tsx +3 -3
  469. package/src/components/FileViewer/file-viewer.spec.md +30 -12
  470. package/src/components/FileViewer/file-viewer.stories.tsx +1 -2
  471. package/src/components/FileViewer/file-viewer.tsx +12 -4
  472. package/src/components/FileViewer/image-renderer.tsx +35 -7
  473. package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -2
  474. package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -3
  475. package/src/components/HoverCard/hover-card.spec.md +5 -5
  476. package/src/components/HoverCard/hover-card.stories.tsx +16 -16
  477. package/src/components/HoverCard/hover-card.tsx +5 -3
  478. package/src/components/InlineEdit/index.ts +5 -0
  479. package/src/components/InlineEdit/inline-edit.spec.md +149 -0
  480. package/src/components/InlineEdit/inline-edit.stories.tsx +246 -0
  481. package/src/components/InlineEdit/inline-edit.tsx +287 -0
  482. package/src/components/Input/input.anatomy.stories.tsx +8 -7
  483. package/src/components/Input/input.principles.stories.tsx +2 -12
  484. package/src/components/Input/input.spec.md +13 -18
  485. package/src/components/Input/input.tsx +69 -22
  486. package/src/components/LinkInput/link-input.anatomy.stories.tsx +1 -1
  487. package/src/components/LinkInput/link-input.principles.stories.tsx +2 -2
  488. package/src/components/LinkInput/link-input.tsx +11 -10
  489. package/src/components/Menu/menu-item.anatomy.stories.tsx +3 -3
  490. package/src/components/Menu/menu-item.principles.stories.tsx +1 -1
  491. package/src/components/Menu/menu-item.spec.md +22 -15
  492. package/src/components/Menu/menu-item.stories.tsx +39 -11
  493. package/src/components/Menu/menu-item.tsx +38 -4
  494. package/src/components/Notice/notice.principles.stories.tsx +1 -1
  495. package/src/components/Notice/notice.spec.md +16 -3
  496. package/src/components/NumberInput/number-input.anatomy.stories.tsx +3 -3
  497. package/src/components/NumberInput/number-input.principles.stories.tsx +1 -1
  498. package/src/components/NumberInput/number-input.spec.md +4 -4
  499. package/src/components/NumberInput/number-input.tsx +19 -12
  500. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +10 -8
  501. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +3 -3
  502. package/src/components/OverflowIndicator/overflow-indicator.spec.md +4 -2
  503. package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +71 -63
  504. package/src/components/OverflowIndicator/overflow-indicator.tsx +9 -8
  505. package/src/components/Pagination/pagination.spec.md +1 -1
  506. package/src/components/Pagination/pagination.stories.tsx +2 -6
  507. package/src/components/Pagination/pagination.tsx +1 -1
  508. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +4 -4
  509. package/src/components/PeoplePicker/people-picker.principles.stories.tsx +2 -2
  510. package/src/components/PeoplePicker/people-picker.spec.md +6 -6
  511. package/src/components/PeoplePicker/people-picker.tsx +56 -16
  512. package/src/components/PeoplePicker/person-display.tsx +32 -16
  513. package/src/components/Popover/popover.anatomy.stories.tsx +2 -2
  514. package/src/components/Popover/popover.tsx +3 -1
  515. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +12 -23
  516. package/src/components/ProfileCard/profile-card.spec.md +3 -3
  517. package/src/components/ProfileCard/profile-card.tsx +6 -6
  518. package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +3 -1
  519. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +1 -1
  520. package/src/components/ProgressBar/progress-bar.stories.tsx +50 -42
  521. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +10 -28
  522. package/src/components/RadioGroup/radio-group.stories.tsx +29 -32
  523. package/src/components/RadioGroup/radio-group.tsx +41 -15
  524. package/src/components/Rating/rating.spec.md +11 -3
  525. package/src/components/ScrollArea/scroll-area.anatomy.stories.tsx +1 -1
  526. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
  527. package/src/components/ScrollArea/scroll-area.spec.md +7 -3
  528. package/src/components/ScrollArea/scroll-area.stories.tsx +1 -1
  529. package/src/components/ScrollArea/scroll-area.tsx +17 -4
  530. package/src/components/Select/select.anatomy.stories.tsx +3 -3
  531. package/src/components/Select/select.spec.md +27 -17
  532. package/src/components/Select/select.stories.tsx +33 -0
  533. package/src/components/Select/select.tsx +190 -36
  534. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +4 -4
  535. package/src/components/SelectMenu/select-menu.spec.md +15 -7
  536. package/src/components/SelectMenu/select-menu.tsx +16 -3
  537. package/src/components/SelectionControl/boolean-value.tsx +39 -0
  538. package/src/components/SelectionControl/index.ts +1 -0
  539. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +2 -2
  540. package/src/components/SelectionControl/selection-item.principles.stories.tsx +2 -2
  541. package/src/components/SelectionControl/selection-item.spec.md +3 -3
  542. package/src/components/SelectionControl/selection-item.stories.tsx +3 -3
  543. package/src/components/Separator/separator.spec.md +2 -2
  544. package/src/components/Separator/separator.stories.tsx +6 -27
  545. package/src/components/Sheet/sheet.anatomy.stories.tsx +1 -1
  546. package/src/components/Sheet/sheet.principles.stories.tsx +1 -1
  547. package/src/components/Sheet/sheet.spec.md +2 -2
  548. package/src/components/Sheet/sheet.tsx +9 -5
  549. package/src/components/Sidebar/sidebar.anatomy.stories.tsx +16 -12
  550. package/src/components/Sidebar/sidebar.principles.stories.tsx +10 -8
  551. package/src/components/Sidebar/sidebar.spec.md +13 -15
  552. package/src/components/Sidebar/sidebar.stories.tsx +8 -7
  553. package/src/components/Sidebar/sidebar.tsx +37 -25
  554. package/src/components/Skeleton/skeleton.stories.tsx +4 -11
  555. package/src/components/Slider/slider.anatomy.stories.tsx +3 -3
  556. package/src/components/Slider/slider.principles.stories.tsx +2 -2
  557. package/src/components/Slider/slider.spec.md +5 -5
  558. package/src/components/Slider/slider.tsx +3 -1
  559. package/src/components/Steps/steps.anatomy.stories.tsx +4 -4
  560. package/src/components/Steps/steps.principles.stories.tsx +1 -1
  561. package/src/components/Steps/steps.spec.md +1 -1
  562. package/src/components/Switch/switch.anatomy.stories.tsx +7 -7
  563. package/src/components/Switch/switch.principles.stories.tsx +4 -4
  564. package/src/components/Switch/switch.spec.md +8 -8
  565. package/src/components/Switch/switch.stories.tsx +9 -24
  566. package/src/components/Switch/switch.tsx +17 -13
  567. package/src/components/Tabs/tabs.anatomy.stories.tsx +10 -7
  568. package/src/components/Tabs/tabs.spec.md +1 -1
  569. package/src/components/Tabs/tabs.tsx +21 -1
  570. package/src/components/Textarea/textarea.anatomy.stories.tsx +1 -1
  571. package/src/components/Textarea/textarea.principles.stories.tsx +1 -1
  572. package/src/components/Textarea/textarea.spec.md +4 -4
  573. package/src/components/Textarea/textarea.tsx +72 -46
  574. package/src/components/TimePicker/time-columns.tsx +6 -2
  575. package/src/components/TimePicker/time-picker.principles.stories.tsx +1 -1
  576. package/src/components/TimePicker/time-picker.spec.md +3 -3
  577. package/src/components/TimePicker/time-picker.tsx +16 -10
  578. package/src/components/Toast/toast.stories.tsx +7 -4
  579. package/src/components/Tooltip/tooltip.anatomy.stories.tsx +4 -4
  580. package/src/components/Tooltip/tooltip.principles.stories.tsx +3 -3
  581. package/src/components/Tooltip/tooltip.spec.md +1 -1
  582. package/src/components/Tooltip/tooltip.stories.tsx +4 -39
  583. package/src/components/Tooltip/tooltip.tsx +8 -6
  584. package/src/components/TreeView/tree-view.anatomy.stories.tsx +6 -3
  585. package/src/components/TreeView/tree-view.spec.md +42 -11
  586. package/src/components/TreeView/tree-view.stories.tsx +1 -0
  587. package/src/components/TreeView/tree-view.tsx +322 -17
  588. package/src/index.ts +584 -60
  589. package/src/patterns/action-bar/action-bar.spec.md +9 -0
  590. package/src/patterns/action-bar/action-bar.stories.tsx +6 -3
  591. package/src/patterns/element-anatomy/inline-action.spec.md +2 -0
  592. package/src/patterns/element-anatomy/item-anatomy.spec.md +14 -5
  593. package/src/patterns/element-anatomy/item-anatomy.stories.tsx +6 -4
  594. package/src/patterns/element-anatomy/item-anatomy.tsx +7 -6
  595. package/src/patterns/header-canonical/header-canonical.spec.md +5 -4
  596. package/src/patterns/overlay-surface/overlay-surface.spec.md +22 -1
  597. package/src/styles/tokens.css +3 -0
  598. package/src/tokens/README.md +1 -1
  599. package/src/tokens/color/color.spec.md +3 -3
  600. package/src/tokens/color/color.stories.tsx +3 -3
  601. package/src/tokens/density/density.stories.tsx +16 -3
  602. package/src/tokens/layoutSpace/layoutSpace.spec.md +3 -1
  603. package/src/tokens/motion/motion.css +33 -21
  604. package/src/tokens/motion/motion.spec.md +32 -15
  605. package/src/tokens/motion/motion.stories.tsx +58 -5
  606. package/src/tokens/motion/motion.ts +7 -6
  607. package/src/tokens/motion/overlay-motion.ts +26 -0
  608. package/src/tokens/orphan-tokens.spec.md +4 -4
  609. package/src/tokens/token-system.spec.md +1 -0
  610. package/src/tokens/uiSize/uiSize.spec.md +1 -1
  611. package/src/tokens/uiSize/uiSize.stories.tsx +4 -2
  612. package/src/tokens/utility-registry.json +160 -23
@@ -0,0 +1,119 @@
1
+ #!/bin/bash
2
+ # check_story_invariants.sh — SHIP_REWRITTEN fork override(consumer 版,2026-07-08 WM 戰役 R4)
3
+ #
4
+ # WHY REWRITE(非 SHIP_AS_IS / 非 DROP):
5
+ # DS-author 原版 10 條 rule 多數 scope 在 DS src stories(anatomy 6-canonical / trait category /
6
+ # title canonical 等 DS-author 撰寫紀律),fork 消費端不適用;但 preamble M23(d) 明文承諾
7
+ # 「Registry SSOT story-baseline-registry.json + hook check_story_invariants.sh R8 + R9 機械強制」
8
+ # — 原版整支 DROP = doc-vs-corpus drift(對 fork 承諾了防線、corpus 卻沒 ship,紙老虎)。
9
+ # 本 override 只 ship fork 真需要的兩條(WM 2026-07-08 實證 drift class):
10
+ # R8 story_archetype_registry — 讀 corpus 內 registry antiPatterns,攔 simplified-mock
11
+ # (wrap Sidebar/DataTable/ChromeHeader 卻手刻 span/div 取代 primitive 結構)
12
+ # R9 hand_craft_overlay_header — 手刻浮層 / chrome header 簽名(px-loose + border-b
13
+ # border-divider 同 className;零誤判簽名,DS-wide 量測 anchor 2026-06-04 upload-manager)
14
+ # Scope 擴到 apps/**/*.tsx:fork 手刻 drift 主戰場在產品 code,非只 stories(WM detail modal 實證)。
15
+ # Escape 與 DS-author 版同源:@story-baseline-allow: <reason>(檔頭 10 行內或本次片段)。
16
+ #
17
+ # Registry 路徑:corpus 相對路徑優先($0 = ds-canonical/fork/hooks/ → ../../references/),
18
+ # 再 fallback $CLAUDE_PROJECT_DIR/node_modules(anchor 2026-06-03:cwd-相對路徑曾靜默失效)。
19
+
20
+ source "$(dirname "$0")/_log-fire.sh" 2>/dev/null && log_hook_fire
21
+
22
+ set -uo pipefail
23
+
24
+ INPUT=$(cat 2>/dev/null || echo "{}")
25
+ TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)
26
+ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""' 2>/dev/null)
27
+ EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // ""' 2>/dev/null)
28
+
29
+ case "$TOOL" in Edit|Write|MultiEdit) ;; *) exit 0 ;; esac
30
+ [ "$EVENT" = "PostToolUse" ] && exit 0
31
+
32
+ # Scope:fork 產品 code(apps/**/*.tsx)+ 任何 stories.tsx;DS 內部 / node_modules 不管
33
+ case "$FILE_PATH" in
34
+ *node_modules/*|*packages/design-system/*) exit 0 ;;
35
+ *.stories.tsx) ;;
36
+ */apps/*.tsx) ;;
37
+ *) exit 0 ;;
38
+ esac
39
+
40
+ NEW_CONTENT=$(echo "$INPUT" | jq -r '
41
+ (.tool_input.content // "") + "\n" +
42
+ (.tool_input.new_string // "") + "\n" +
43
+ ([.tool_input.edits[]? | .new_string] | join("\n"))
44
+ ' 2>/dev/null || echo "")
45
+ [ -z "${NEW_CONTENT//[[:space:]]/}" ] && exit 0
46
+
47
+ # Escape(檔頭 10 行 — 本次片段 or 磁碟上既有檔頭)
48
+ if echo "$NEW_CONTENT" | head -10 | grep -qE '@story-baseline-allow:'; then exit 0; fi
49
+ if [ -f "$FILE_PATH" ] && head -10 "$FILE_PATH" 2>/dev/null | grep -qE '@story-baseline-allow:'; then exit 0; fi
50
+
51
+ WORST=0
52
+
53
+ # ── Registry 定位(corpus 相對優先) ──
54
+ REGISTRY="$(dirname "$0")/../../references/story-baseline-registry.json"
55
+ if [ ! -f "$REGISTRY" ]; then
56
+ REGISTRY="${CLAUDE_PROJECT_DIR:-.}/node_modules/@qijenchen/design-system/ds-canonical/references/story-baseline-registry.json"
57
+ fi
58
+
59
+ # 多行 JSX flatten(registry regex 用 [[:space:]]* / .* 跨原換行;grep 是 line-oriented)
60
+ CONTENT_FLAT=$(echo "$NEW_CONTENT" | tr '\n' ' ')
61
+
62
+ # ─────────────────────────────────────────────────────────────────────────────
63
+ # R8 — story_archetype_registry(registry antiPatterns 攔 simplified-mock)
64
+ # ─────────────────────────────────────────────────────────────────────────────
65
+ if [ -f "$REGISTRY" ]; then
66
+ for COMP in Sidebar DataTable ChromeHeader; do
67
+ echo "$NEW_CONTENT" | grep -qE "<${COMP}\\b" || continue
68
+ # 每條三行一組:severity / regex / unlessRegex(jq -r 原始輸出零跳脫;禁 @tsv/插值 —
69
+ # @tsv 反斜線雙跳脫、插值踩 jq lexer,DS-author 版 2026-07-04 smoke 連抓兩雷)
70
+ PATTERNS=$(jq -r --arg c "$COMP" '.components[$c].antiPatterns[]? | .severity, .regex, (.unlessRegex // "")' "$REGISTRY" 2>/dev/null)
71
+ [ -z "$PATTERNS" ] && continue
72
+ while read -r SEV && read -r PATTERN && { read -r UNLESS || true; }; do
73
+ [ -z "$PATTERN" ] && continue
74
+ # regex self-test(invalid ERE → grep exit 2 靜默永不 fire;fail-loud)
75
+ echo x | grep -qE "$PATTERN" 2>/dev/null
76
+ if [ $? -eq 2 ]; then
77
+ echo "⚠️ R8 registry regex 不可執行(ERE invalid,此條防線失效):$PATTERN" >&2
78
+ continue
79
+ fi
80
+ if echo "$CONTENT_FLAT" | grep -qE "$PATTERN"; then
81
+ if [ -n "$UNLESS" ] && echo "$CONTENT_FLAT" | grep -qE "$UNLESS" 2>/dev/null; then continue; fi
82
+ {
83
+ echo "⚠️ R8 story_archetype_registry violation(severity: $SEV):"
84
+ echo " $FILE_PATH wrap <$COMP> matches anti-pattern:"
85
+ echo " regex: $PATTERN"
86
+ echo ""
87
+ echo " 修法:Read DS baseline story + helpers,抄 production archetype 結構,"
88
+ echo " 不憑印象手刻 simplified mock(<SidebarHeader><span> / 手刻 filter Button 等)。"
89
+ echo " Baseline registry:node_modules/@qijenchen/design-system/ds-canonical/references/story-baseline-registry.json"
90
+ echo " Canonical:preamble M23(d) nearest same-purpose canonical wins。"
91
+ echo " 豁免:檔頭加 // @story-baseline-allow: <reason>(audit-logged)。"
92
+ } >&2
93
+ [ "$SEV" = "block" ] && [ "$WORST" -lt 2 ] && WORST=2
94
+ fi
95
+ done <<< "$PATTERNS"
96
+ done
97
+ fi
98
+
99
+ # ─────────────────────────────────────────────────────────────────────────────
100
+ # R9 — hand_craft_overlay_header(零誤判簽名:px-loose + border-b border-divider 同 className)
101
+ # ─────────────────────────────────────────────────────────────────────────────
102
+ # drop 純註解行再 flatten(避免 commented-out JSX 誤判;不 strip 行內 // 保 https:// URL)
103
+ FLAT9=$(echo "$NEW_CONTENT" | grep -vE '^[[:space:]]*(//|\*|/\*|\{/\*)' | tr '\n' ' ')
104
+ if echo "$FLAT9" | grep -qE '<div[^>]*px-\[var\(--layout-space-loose\)\][^">]*border-b[[:space:]]+border-divider|<div[^>]*border-b[[:space:]]+border-divider[^">]*px-\[var\(--layout-space-loose\)\]'; then
105
+ {
106
+ echo "❌ R9 hand-craft overlay / chrome header:${FILE_PATH}"
107
+ echo " 偵測到 <div ... px-[var(--layout-space-loose)] ... border-b border-divider> = 手刻浮層 / chrome header。"
108
+ echo " 必消費 DS primitive:<SurfaceHeader>(patterns/overlay-surface)/ <PopoverHeader> / <DialogHeader>;"
109
+ echo " 面板殼用 Popover 同款 chrome token(rounded-lg border-border bg-surface-raised elevation-200)。"
110
+ echo " 理由:px-loose + divider border 的 header chrome 是 overlay-surface SSOT;手刻 = drift"
111
+ echo " (anchor 2026-06-04 upload-manager 手刻面板 py-2≠py-tight / 殼 token 全偏,user 抓)。"
112
+ echo " Spec:node_modules/@qijenchen/design-system/src/patterns/overlay-surface/overlay-surface.spec.md"
113
+ echo " 豁免:檔頭加 // @story-baseline-allow: <reason>。"
114
+ } >&2
115
+ WORST=2
116
+ fi
117
+
118
+ [ "$WORST" -ge 2 ] && exit 2
119
+ exit 0
@@ -52,6 +52,34 @@ if ! echo "$FILE" | grep -qE '(packages/design-system/src/|/apps/|(^|/)apps/)';
52
52
  CONTENT=$(cat "$FILE" 2>/dev/null)
53
53
  [ -z "$CONTENT" ] && exit 0
54
54
 
55
+ # ── Check 3(2026-07-08 WM 戰役 R4:root 偵測,不只 symptom)──
56
+ # WM 實證:app 把 TabsList 塞 DialogBody + `!pt-0` hack 對抗 primitive,TabsContent 加了 mt-0
57
+ # 就繞過 Check 2 —— 但 root 錯誤是「沒用 DialogHeader tabsSlot canonical」(雙線 + 底線內縮 +
58
+ # spacing owner 自組)。偵測兩個 root 簽名(任一 → BLOCK 指路 tabsSlot):
59
+ # (a) DialogBody/SheetBody/SurfaceBody className 含 `!pt-0`(important 對抗 primitive 的 pt owner)
60
+ # (b) <TabsList 出現在含 DialogBody 的同段 new content 且無 tabsSlot 字樣
61
+ ROOT_SIG_A=$(printf '%s\n' "$CONTENT" | grep -nE '(DialogBody|SheetBody|SurfaceBody)[^>]*className=[^>]*!pt-0' | grep -v '@tabs-content-gap-ok:' || true)
62
+ ROOT_SIG_B=""
63
+ if printf '%s\n' "$CONTENT" | grep -q '<TabsList' && printf '%s\n' "$CONTENT" | grep -qE '<(DialogBody|SheetBody|SurfaceBody)\b' && ! printf '%s\n' "$CONTENT" | grep -q 'tabsSlot' && ! printf '%s\n' "$CONTENT" | grep -q '@tabs-content-gap-ok:'; then
64
+ ROOT_SIG_B=$(printf '%s\n' "$CONTENT" | grep -n '<TabsList' | head -3)
65
+ fi
66
+ if [ -n "$ROOT_SIG_A" ] || [ -n "$ROOT_SIG_B" ]; then
67
+ cat >&2 << 'EOF_C3'
68
+ 🚨 TABS-IN-BODY ROOT BLOCKER(P0,2026-07-08 WM 戰役 — 攔 root 非 symptom)
69
+
70
+ 偵測到「TabsList 手塞 chrome body / body 用 !pt-0 hack」簽名 —— 這是「沒用 header tabsSlot
71
+ canonical」的 root 錯誤(後果:header 與 TabsList 雙底線、tabs 底線被 body padding 內縮不滿寬、
72
+ spacing owner 鏈自組)。WM ProjectSettings/TypeSettings 錨例。
73
+
74
+ ── 正解 ──
75
+ <Tabs> wrap → <DialogHeader tabsSlot={<TabsList/>}> → <DialogBody><TabsContent className="mt-0">
76
+ 照 dialog.stories.tsx#WithTabsInHeader 逐字結構(header-canonical.spec.md Rule W2)。
77
+ Escape:`// @tabs-content-gap-ok: <rationale>`(例:tabs 本來就不屬 header 的內容分頁場景)
78
+ EOF_C3
79
+ exit 2
80
+ fi
81
+
82
+
55
83
  # ══ Check 2:overlay body 自身用固定 macro gap-N → 該用 layout-space token(2026-07-01 Sheet gap-4 錨例)══
56
84
  # Root(layoutSpace.spec.md 規則 2/3):浮層 body 直接堆疊內容的垂直 gap 屬 macro layout-space,該用
57
85
  # density-scaling token(並列 = loose / functional 交互 = tight),非固定 gap-N(lg 不縮放 → 跟 DS
@@ -157,6 +185,7 @@ while IFS= read -r ln; do
157
185
  UNJUSTIFIED="${UNJUSTIFIED}${ln}: $(echo "$cur" | sed 's/^[[:space:]]*//')\n"
158
186
  done <<< "$CANDIDATES"
159
187
 
188
+
160
189
  if [ -z "$UNJUSTIFIED" ]; then exit 0; fi
161
190
 
162
191
  cat >&2 << EOF
@@ -36,6 +36,11 @@
36
36
  "file": "hooks/inject_deploy_url_after_push.sh",
37
37
  "sourceHook": "inject_deploy_url_after_push.sh",
38
38
  "bucket": "SHIP_REWRITTEN"
39
+ },
40
+ {
41
+ "file": "hooks/check_story_invariants.sh",
42
+ "sourceHook": "check_story_invariants.sh",
43
+ "bucket": "SHIP_REWRITTEN"
39
44
  }
40
45
  ],
41
46
  "PreToolUse": [
@@ -64,6 +69,16 @@
64
69
  "sourceHook": "check_chrome_header_avatar_canonical.sh",
65
70
  "bucket": "SHIP_AS_IS"
66
71
  },
72
+ {
73
+ "file": "hooks/check_story_determinism.sh",
74
+ "sourceHook": "check_story_determinism.sh",
75
+ "bucket": "SHIP_AS_IS"
76
+ },
77
+ {
78
+ "file": "hooks/check_dynamic_tailwind_class.sh",
79
+ "sourceHook": "check_dynamic_tailwind_class.sh",
80
+ "bucket": "SHIP_AS_IS"
81
+ },
67
82
  {
68
83
  "file": "hooks/check_opacity_token_usage.sh",
69
84
  "sourceHook": "check_opacity_token_usage.sh",
@@ -74,6 +89,11 @@
74
89
  "sourceHook": "check_ds_anchor_preflight.sh",
75
90
  "bucket": "SHIP_REWRITTEN"
76
91
  },
92
+ {
93
+ "file": "hooks/check_story_invariants.sh",
94
+ "sourceHook": "check_story_invariants.sh",
95
+ "bucket": "SHIP_REWRITTEN"
96
+ },
77
97
  {
78
98
  "file": "hooks/check_fork_product_quality.sh",
79
99
  "sourceHook": "check_substantive_edit_approval_preflight.sh",
@@ -48,7 +48,7 @@
48
48
 
49
49
  **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 才動。
50
50
 
51
- **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(6fire 或 rare-event 豁免)。
51
+ **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(3invoke 或 rare-event 豁免;hooks 才是 6 月 fire,SSOT → knowledge-prune/SKILL.md)。
52
52
 
53
53
 
54
54
  | # | Meta-Principle | 能吸收的 bug 類型(舉例,非窮舉) |
@@ -62,7 +62,7 @@
62
62
  | **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 漏 |
63
63
  | **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 次才有世界級對照 |
64
64
  | **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 |
65
- | **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 一次炸 |
65
+ | **M10** | **Proactive exhaustive scan**:canonical migration 完成前禁止只改「直覺相關」元件;final report 前禁止省略「我知道但沒講」的 tech debt。**Mechanical 落地**:batch-end(session ≥2 fix commits)跑一次 `/scan-similar-bugs` grep DS-wide(2026-05-12 per-fix → batch-end 重構);`session_start_governance_check.sh` Check 6 偵測 24h 內 fix commit 漏跑 → soft 提醒。 | dismiss migration 漏 FileViewer / 7 題 silent tech debt user 一次炸 |
66
66
  | **M11** | **User-perspective interactive state walk**:改完 UI 後 present 前必親自走 7 題 self-test(static / hover / focus-visible / active / keyboard / 範例真實性 / CSS 對稱)。每 UI 改動未跑 7 題就 commit = 違反。 | ListBody 修完 user 連抓 5 波 |
67
67
  | **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 |
68
68
  | **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 次催才全改 |
@@ -70,11 +70,11 @@
70
70
  | **M15** | **Product UI flow 必須 visual-audit coverable**。任何 stakeholder-facing flow 必含 OpenSnapshot 類 stories(`defaultOpen` / `useState(true)` / `play()`)。禁留「需真人點擊才能看到的 state」未截圖。 | Sheet / FileViewer 只截 trigger 缺 OpenSnapshot |
71
71
  | **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 連續相連 |
72
72
  | **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 |
73
- | **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 → `node_modules/@qijenchen/design-system/ds-canonical/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 包括所有實作代碼,自主自動驗證這些問題是否真的是問題」 |
73
+ | **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 → `node_modules/@qijenchen/design-system/ds-canonical/skills/propose-options/SKILL.md`。Hook `check_propose_pre_grep_verify.sh` 機械化警告 Q0(P1 soft,scope 僅 planning/reports/handoff md 的 cite-presence;chat reply propose 靠 discipline)。 | 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 包括所有實作代碼,自主自動驗證這些問題是否真的是問題」 |
74
74
  | **M19** | **Trigger phrase auto-pipeline**。「確保 / 一定 / 永不漂移 / ensure / always」trigger → 自動 5-layer ≥ 3 層落地 + M8 + M17 + M10。Substantive 走 STOP。SSOT → `node_modules/@qijenchen/design-system/ds-canonical/skills/ensure-canonical/SKILL.md`。 | story splitting 2026-04-26 user 第 N 次強調才落地 |
75
- | **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`(檔頭「Checks + thresholds」註解 + Check 7)+ 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 多次糾正「沒理由不做」 |
76
- | **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 |
77
- | **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 鬼話事件)|
75
+ | **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`(檔頭「Checks + thresholds」註解 + Check 7)+ 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 已拍板「全部做完」/「繼續」/「沒理由不做」→ WARN + next-turn inject(stop_self_audit.sh Mechanism 4)。對齊 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 多次糾正「沒理由不做」 |
76
+ | **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:folded 入 `check_naming_and_abstraction.sh` D.1(P0 BLOCK,2026-05-08 cluster D consolidation;escape @separate-component-rationale)。 | DateTimePicker 從 DatePicker 拆 → 撤回合併 `<DatePicker showTime>`(2026-05-02);DataTableFilterPanel 5-file → 撤回 sub-file pattern |
77
+ | **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` 機械強制(P0 BLOCKER exit 2,2026-07-07 升級;escape @benchmark-unverified 逐句 / @benchmark-citation-allow / @benchmark-unverified-blanket 檔級)。每次 implement 前跑 WebFetch 取真 source,不憑印象解碼。 | claim「Ant showTime range = 2 calendars」憑印象,實證 source code `multiplePanel = false` = 1 calendar(2026-05-02 鬼話事件)|
78
78
  | **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。**手刻浮層 / chrome header 子規則(2026-06-04 加)**:做「像 popover / dialog 的浮層面板」前必先 grep + Read `patterns/overlay-surface`(SurfaceHeader/Body/Footer)+ `Popover`(chrome token + PopoverHeader/PopoverTitle)SSOT;**手刻 `<div px-loose border-b border-divider>` header 或 `<div rounded bg-surface shadow-elevation>` 殼 = drift**,必消費 primitive。Registry SSOT `node_modules/@qijenchen/design-system/ds-canonical/references/story-baseline-registry.json` + hook `check_story_invariants.sh R8 story_archetype_registry` **+ R9 hand_craft_overlay_header(零誤判 px-loose+border-divider 簽名,BLOCKER)**。**forcing-function 教訓**:M1/M23(d) 是 mindset,但 mindset 沒有完整 hook 兜底 = 紙老虎(會憑印象手刻);新場景若既有 hook 無 antiPattern 覆蓋 → 補 hook rule 才算落地。 | 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。**2026-06-04 upload-manager 面板手刻 header + 殼**(`py-2`≠`py-tight` / `rounded-md`≠`lg` / `border-divider`≠`border` / `bg-surface`≠`raised`),既有 3 道網全漏(R1-C 要 absolute+dismiss / `_chrome_header_handcraft` skip stories / R7-R8 只比已註冊 primitive 名)→ adversarial workflow 抓 + 加 R9 補洞。Hook `check_datatable_invariants.sh(r2 folded,2026-06-11)` + `check_story_invariants.sh R8/R9` |
79
79
  | **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_field_family_invariants.sh` A.4(原 check_disabled_placeholder_color folded,live P1 stderr)。 | 2026-05-04 5+ violation:`bareInputStyles` 永遠 muted / `select.tsx` 3 處 plain&tag empty 不分 mode / `textarea.tsx` 同;Input.tsx 唯一做對。User 5+ 次糾正才 codify |
80
80
  | **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_pattern_invariants.sh` C.1(原 check_overlay_panel_scroll_chain folded,live P1 WARN)。 | 2026-05-04:Filter / Sort panel root `<div w-[640px]>` 無 flex-col → user 縮 viewport 時 body 不 scroll。NameCard 因自設 max-h flex-col 才繞過(無中間 wrapper) |
@@ -82,11 +82,11 @@
82
82
  <!-- 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_datatable_invariants.sh(r2 folded,2026-06-11)` retained 在 M23 children。 -->
83
83
 
84
84
  | **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 違反 |
85
- | **M29** | **DS Anchor Preflight invariant — 視覺 / 結構 propose 前必 grep `*.spec.md` 找 owner SSOT**。動 component / pattern / token 視覺結構前,**必先**:(a) `rg <touched component> + <behavior keyword>` in `node_modules/@qijenchen/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 `node_modules/@qijenchen/design-system/ds-canonical/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 抓「為何沒研讀設計原則」 |
85
+ | **M29** | **DS Anchor Preflight invariant — 視覺 / 結構 propose 前必 grep `*.spec.md` 找 owner SSOT**。動 component / pattern / token 視覺結構前,**必先**:(a) `rg <touched component> + <behavior keyword>` in `node_modules/@qijenchen/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 `node_modules/@qijenchen/design-system/ds-canonical/references/ssot-index.md`(high-risk interface owner mapping)Step 0.1 先查再 grep verify。Hook `check_ds_anchor_preflight.sh` P0 BLOCKER(exit 2,2026-07-07 升級;bypass CLAUDE_BYPASS_DS_ANCHOR=1 audit-logged)。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 抓「為何沒研讀設計原則」 |
86
86
  | **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。 |
87
87
  | **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(`)。**+ Sub-invariant(2026-05-30,doc-claim layer)**:story/anatomy/a11y/spec 的**文字宣稱 ≠ code 真實**——audit 必 adversarial **讀元件 .tsx +(其 wrap 的 Radix/cmdk/react-day-picker 等 lib)source**,逐句驗 keyboard map/ARIA role/focus 行為/prop 存在性/native-vs-custom;prose-skim「looks fine」= false-pass(prose-pass ≠ source-verified)。**「無 code 改動」≠ 可跳過**。`/deep-audit-cross-codex` A.1b + CP-A1b + report-validator F 機械強制。Anchor:2026-05-30 獨立 adversarial 抓 403 findings/64 單元/202 FALSE_CLAIM(前期 prose-skim story dim 全漏);prop-existence deterministic detector 因 passthrough over-flag 證實此類本質需 LLM 讀 source → 用 mandatory-dim + report-validator 保證真跑。**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(CLI binary 必跑 4-test discovery:which / npx / package.json / auth.json,禁短路「not installed」假警報)— 原 memory `feedback_tool_binary_preflight_sweep.md` 已 retire,invariant 一行收容於此 / (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)。|
88
88
  | **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。 |
89
- <!-- 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」合併。 -->
89
+ <!-- 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` P1 warn detection(Mechanism 4 + 次 turn auto-inject)retained at M20 entry。Single-bug rule → 與 M20 同類「AI self-correction under feedback signals」合併。 -->
90
90
 
91
91
  <!-- 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 合併。 -->
92
92
 
@@ -122,9 +122,9 @@ paths:
122
122
 
123
123
  **唯一判準 = 「DS 是否想讓 consumer 直接 import 來用它」(public-API intent)** —— **不是**「空 `<X/>` 能不能 render 出有意義 UI」。世界級實證:MUI Base 官方「**requiring composition and styling does NOT make something internal — these are explicitly public primitives**」;Atlassian Primitives(Box/Stack/Inline)/ Bootstrap input-group / Ant Space.Compact 皆 public 卻需 compose。
124
124
 
125
- **Public**(consumer-facing):DS 想讓 consumer 直接用的東西,**包含**:(a) 成品元件 `<Button>` / `<Avatar>` / `<Dialog>` / `<DataTable>` / `<Select>`;(b) **組合 primitive —— consumer 把自己內容塞進去 / 自接 callback 才完整**:`<FieldControlGroup>`(塞 field controls = Bootstrap input-group idiom)/ `<ResizeHandle>`(接 drag math = VS Code/Figma resize idiom)/ `<ChromeHeader>`(自建 chrome header chrome,follow `header-canonical` anatomy = 對標 item-anatomy 的公開 anatomy primitive)。**「需要 children / 接線 / 組合」是正常 public 用法,不是 internal**。判斷訊號:benchmark 對標 consumer-facing primitive / spec「何時用」是 consumer 場景 / 有 standalone 用法 / export 給 consumer。
125
+ **Public**(consumer-facing):DS 想讓 consumer 直接用的東西,**包含**:(a) 成品元件 `<Button>` / `<Avatar>` / `<Dialog>` / `<DataTable>` / `<Select>`;(b) **組合 primitive —— consumer 把自己內容塞進去 / 自接 callback 才完整**:`<FieldControlGroup>`(塞 field controls = Bootstrap input-group idiom)/ `<ResizeHandle>`(接 drag math = VS Code/Figma resize idiom)/ `<ChromeHeader>`(自建 chrome header chrome,follow `header-canonical` anatomy = 對標 item-anatomy 的公開 anatomy primitive)/ `<ItemIcon>` `<ItemAvatar>`(row context 內 consumer 塞 icon/avatar 的公開 named slot —— item-anatomy.spec.md「Helper 程式化封裝」段 mandate consumer 必用 + root barrel 匯出;對齊 Material ListItemIcon/ListItemAvatar、Primer ActionList.LeadingVisual 公開 named-slot 模型;**row-context-scoped**:離開 row primitive 子樹無意義,如 Material ListItemIcon 離開 List 無意義)。**「需要 children / 接線 / 組合」是正常 public 用法,不是 internal**。判斷訊號:benchmark 對標 consumer-facing primitive / spec「何時用」是 consumer 場景 / 有 standalone 用法 / export 給 consumer。
126
126
 
127
- **Internal primitive**:**只有 DS 內部其他元件會用、consumer 永遠不碰**(consumer wrapper 而非它)。Examples:`<SurfaceHeader/Body/Footer>`(只 Dialog 內部)/ `useOverflowItems` hook / `<ItemIcon>` / `<ItemAvatar>`( MenuItem 內部 slot,consumer `<MenuItem>` 不用裸 slot)。判斷訊號:無 consumer 場景 / 只被其他 DS 元件 import / 是別元件的 sub-part/slot/chrome
127
+ **Internal primitive**:**主要給 DS 內部其他元件用;不進 root barrel front-door、consumer 不「直接裸用」——但 internal ≠ 禁用:consumer 可經 per-component subpath(`@qijenchen/design-system/{components,patterns}/<Dir>`)「另外包裝過 + 自行確認」後消費**(見下方「Root barrel front-door 排除」2026-06-05 user Q2 拍板 SSOT = 權威定義,取代舊「永遠不碰」絕對措辭 —— 2026-07-10 修此 spec-internal 矛盾,該矛盾曾誤導判定 `<MenuItem>`「consumer 不可用」)。Examples:`<SurfaceHeader/Body/Footer>`(只 Dialog 內部)/ `useOverflowItems` hook / `<RowSizeProvider>` `<ItemInlineAction(Button)>`(item-anatomy.tsx `@internal` 標記的 L3 row-size / inline-action primitive,經 MenuItem/Row 消費)。⚠️ `<ItemIcon>` / `<ItemAvatar>` **不是** internal —— 是 public 組合 primitive(見上方 (b);2026-07-14 stale drift:spec mandate + root barrel 匯出 + app template 實用四處一致 public,本行舊列法與其全牴觸)。判斷訊號:無 standalone consumer 直用場景 / 主要被其他 DS 元件 import / 是別元件的 sub-part/slot/chrome。**`isInternal` = 需 subpath + 包裝後才用(如 `<MenuItem>` 之於 nav row),非「禁止 consumer 使用」。**
128
128
 
129
129
  **決策(verifiable)**:
130
130
  - 問:DS 想讓 end-user 在自己 app 直接 import 並用它嗎(看 benchmark / 何時用 / 是否 export 給 consumer)?
@@ -198,6 +198,8 @@ paths:
198
198
 
199
199
  **元件不得自包全域 Provider**(Tooltip / Theme / Toast / Portal)— 由應用層統一設定。**判斷**:Context 是行為狀態(open / size)→ 可包;全域外觀配置(delay / theme / portal / variant defaults)→ 禁止。
200
200
 
201
+ **shadcn 目錄後續新增元件 vs DS 既有(2026-07-07 codify,anchor:Attachment vs FileItem)**:「遵循 shadcn 框架」= 結構 idiom(forwardRef / Slot / data-* / cva),**非**「必須消費目錄每個元件」。shadcn 是 copy-in scaffold 非 runtime 依賴——遷移無上游更新流入。目錄新增元件時二分:(a) 帶 primitive / behavior 增益(Radix core、新 interaction model)且 DS 無等價 → 走 `/new-component` 近親評估;(b) **純組合式且 DS 已有 Family-compliant 等價物 → 不換架構、不改名**(M23 禁外部覆蓋既有 canonical),只做 API 對照:值得的 state / pattern 逐項評估為 DS prop 演進(SSOT-affecting → ASK),該元件 spec 補 M22 benchmark 對照行 + known-gap 記錄。同類先例:Empty / Item(≈item-anatomy)/ Field / Spinner(≈CircularProgress)/ InputGroup(≈FieldControlGroup)。
202
+
201
203
 
202
204
  ---
203
205
  ## rules/story-rules.md
@@ -217,7 +219,7 @@ paths:
217
219
  | 層 | 檔案 | Canonical | Hook | Audit Dim |
218
220
  |---|------|-----------|------|-----------|
219
221
  | 1 展示 | `*.stories.tsx` | trait-based v2 | `check_story_invariants.sh` R3 category | 29 |
220
- | 2 設計規格 | `*.anatomy.stories.tsx` | 6-canonical(Overview / Inspector / ColorMatrix / SizeMatrix / StateBehavior / Accessibility)| `check_story_invariants.sh` R1 anatomy | 13 |
222
+ | 2 設計規格 | `*.anatomy.stories.tsx` | 6-canonical(Overview / Inspector / ColorMatrix / SizeMatrix / StateBehavior / Accessibility)| —(6-canonical 由 Dim 13 batch verify + `compile-stories.mjs --check` 兜底;`check_story_invariants.sh` R1 = 展示層 hand-craft 偵測,2026-06-11 起豁免 anatomy 檔)| 13 |
221
223
  | 3 設計原則 | `*.principles.stories.tsx` | Polaris-aligned ≥ 2 of {WhenToUse / WhenNotToUse / Vs*Rule / ContentGuidelines};v3 預設整合 `UsageGuidance` 單一 export(Polaris/Material/Ant 共識) | `check_canonical_propagation.sh` E.1 principles | 30 |
222
224
 
223
225
  ## Title 命名
@@ -243,7 +245,7 @@ paths:
243
245
 
244
246
  **MenuItem-as-listbox-child 鍵盤 delegation 例外**(2026-05-16 codified per Combobox spec.md L130-142):MenuItem `<div role="option">` 不需自帶 Enter/Space handler — 由 parent listbox(Combobox / SelectMenu / DropdownMenu)的 hidden native `<select>` handle 鍵盤導覽(對齊 Material/Atlassian/GitHub mixed-control「單 native tab stop + 多 mouse click surface」 canonical)。MenuItem 為 building block 不該重複 handler。
245
247
 
246
- **Story `name:` field 必中文人話**(no auto-compile 豁免):`compile-stories.mjs` auto-generate 已產生中文 name(如 `'元件總覽'`)Manually-written stories `name:` 用純英文 implementation label(`'Default'` / `'Pressed'` / `'SizeMatrix'`)= drift,**必 humanize 中文**。Export const 維持 PascalCase(英)為 code identifier,**`name:` field 為 reader-facing 必中文**(術語例外:`FAQ` / 元件名 `Avatar/Tooltip` 等專有可保英)。
248
+ **Story `name:` field 必中文人話**(no auto-compile 豁免):anatomy 6-story canonical 的中文 name(如 `'元件總覽'`)為 checked-in convention(`check_story_invariants.sh` R4 title_canonical / R5 name_jargon 看守);`compile-stories.mjs` 僅做 spec/tsx componentMeta key drift `--check`(stdout POC markdown),**不**產生 stories 或 name 欄。Manually-written stories `name:` 用純英文 implementation label(`'Default'` / `'Pressed'` / `'SizeMatrix'`)= drift,**必 humanize 中文**。Export const 維持 PascalCase(英)為 code identifier,**`name:` field 為 reader-facing 必中文**(術語例外:`FAQ` / 元件名 `Avatar/Tooltip` 等專有可保英)。
247
249
 
248
250
  ## 範例最高準則
249
251
 
@@ -307,11 +309,12 @@ paths:
307
309
 
308
310
  ## Mechanical enforcement
309
311
 
310
- - **Pre-edit**:`check_substantive_edit_approval_preflight.sh`(production code)+ `stop_self_audit.sh`(spec/canonical 補位)+ `check_ds_anchor_preflight.sh`(M29 anchor)
312
+ - **Pre-edit**:`check_substantive_edit_approval_preflight.sh`(production code)+ `stop_self_audit.sh`(spec/canonical 補位 — 僅覆蓋 codex-collab turn(Mechanism 4 嵌在 codex-reply 閘內);非 codex turn 的 spec.md edit 靠 discipline)+ `check_ds_anchor_preflight.sh`(M29 anchor)
311
313
  - **Post-edit**:`stop_self_audit.sh` Mechanism 1(claim-verify-gap)BLOCKER
312
314
  - **Pre-final(宣告完成前)**:`stop_self_audit.sh` Mechanism 7(完整性宣告閘)BLOCKER — 宣告「全做完 / 全部完成」+ 本 turn 實質改動但**無全庫 stale-ref 掃描證據** → block。**觸發器 = 「宣告完成」本身,非等 user 問第二次**(2026-06-03 user-authorized,根治重複 failure)
313
- - **Pre-final(重大 / SSOT / 模型 / 跨多檔改動)**:除 M7 自掃外,**宣告完成前必跑「獨立對抗稽核」**(multi-agent Workflow,每路假設「還有 loose end」主動去找 + cite 證據)。**理由**:self-grep 系統性漏(self-assessment unreliable,對齊 `feedback_ai_ground_truth_unreliable_mechanical_primary`)+ 信任機械閘(preflight / R4 / hook BLOCKER)勝於自評。**小改 = M7 自掃即可**,不需對抗稽核(避免過度)。2026-06-03 user-authorized,根治「宣告做完 → user 問第 N 次 → 才補掃出 loose end」
314
- - **Pre-commit**:`scripts/audit-content-quality.mjs --check` + `scripts/extract-canonical-rules.mjs` fail = block
315
+ - **⚠️ 紀律條(非本段機械閘 — #39 2026-07-11 誠實標註,原誤置於機械段暗示有 hook 強制,實為零機械消費點)Pre-final(中型以上 = ≥3 substantive、任何 canonical/SSOT/模型改動、或宣告「殘項/債歸零」類完整性 claim)**:除 M7 自掃外,**宣告完成前應跑「獨立對抗稽核」**(multi-agent Workflow,每路假設「還有 loose end」主動去找 + cite 證據)。**理由**:self-grep 系統性漏(self-assessment unreliable,對齊 `feedback_ai_ground_truth_unreliable_mechanical_primary`)+ 信任機械閘(preflight / R4 / hook BLOCKER)勝於自評。**小改 = M7 自掃即可**,不需對抗稽核(避免過度)。2026-06-03 user-authorized
316
+ **為何不機械化(#39 決策記錄)**:硬做成 BLOCKER 會**自我 brick** —— subagent 額度耗盡時無法 dispatch Workflow,則每個中型以上「宣告完成」都被擋(含修此條的 turn 本身);即使有額度,強制每次 ≥3 檔改動都 dispatch adversarial Workflow 亦過重。故本條**保持紀律**,不進 stop_self_audit BLOCKER。**未來可選**:額度穩定後加「completion claim + ≥3 檔 diff + transcript 無 Workflow/Agent dispatch **soft WARN**(非 block)」溫和提醒,不走 BLOCKER。
317
+ - **Pre-commit / release gate**:`scripts/audit-content-quality.mjs --check` 於 `release:preflight` fail-closed 阻擋(release-preflight.mjs);Stop hook 每 turn 跑兩支僅報告(command 尾 `|| true`,non-blocking);`scripts/extract-canonical-rules.mjs` 目前無 blocking 消費點(.husky/pre-commit 未接兩支)
315
318
 
316
319
  ## Anti-pattern(永久 ban)
317
320
 
@@ -358,6 +361,7 @@ paths:
358
361
  | 資料表格(含 header / sorting / sticky) | `<table><thead>...</thead><tbody>...</tbody></table>` | `<DataTable columns={...} data={...} />` |
359
362
  | 檔案上傳列表 | `<div>filename</div><ProgressBar /><Paperclip />` | `<FileItem mode="compact" />` or `<FileUpload>` |
360
363
  | 表單欄位(label + control + error) | `<label>...</label><input/><span className="text-error">...</span>` | `<Field><FieldLabel>...<Input />...<FieldError/>` |
364
+ | 表單提交驗證(何時顯錯 / 提交可點性) | 手刻 `useState(showErrors)` + `submitAttempt` 旗標自組顯錯時機 | `useFormValidation`(Field 家族 hook,`intent:'create'` = 提交恆可點、點擊時 validate 顯錯;搭 `<FieldError>`)|
361
365
  | 全頁 / 區域 loading | `<div className="absolute inset-0 flex center"><Spinner /></div>` | `<Empty icon={<CircularProgress />} description="..." />` |
362
366
  | 確認對話框 | raw `<div className="fixed inset-0 bg-black/50">...<button>OK</button>` | `<Dialog>` + `<DialogHeader>` etc |
363
367
  | 分隔線 | `<hr className="..." />` or `<div className="h-px bg-..."/>` | `<Separator />`(必要時)or CSS border(見 separator.spec) |
@@ -400,7 +404,7 @@ paths:
400
404
  - 以上都沒命中 → 才可自建,但 **建完要立刻回來加行**(防下一個人又重造輪子)
401
405
  - **本規則同樣適用 story / consumer / exploration code**:不 hand-craft 已有 prop 能做的事(如 Input loading 走 `loading` prop 不自刻 `<div className="relative"><input/><div className="absolute">` / 全頁 loading 走 `<Empty icon={<CircularProgress/>}/>` 不自刻 `absolute inset-0`)。遇缺口**回元件 spec 擴 API**,不自刻繞過 — hand-craft 視覺對齊 bug 上游
402
406
 
403
- 具體 anti-pattern signals → `/design-system-audit` Dim 21;pixel-level 視覺 regression(API 用對但視覺仍跑掉)→ `/visual-audit`(D5)抓(原 memory `project_pending_tasks` 已 retire)。
407
+ 具體 anti-pattern signals → `design-system-audit/references/audit-prompts.md`「L1. 手刻繞 DS canonical」+ Dim 71 consumer 手刻(Pattern 10;現行 Dim 21 已是「連續 item list wrapper gap」,勿誤指);pixel-level 視覺 regression(API 用對但視覺仍跑掉)→ `/visual-audit`(D5)抓(原 memory `project_pending_tasks` 已 retire)。
404
408
 
405
409
  ---
406
410
 
@@ -467,7 +471,7 @@ CLAUDE.md `# SSOT 消費 canonical` 的詳表 + 反例。主章留核心 + point
467
471
  */
468
472
  ```
469
473
 
470
- Hook `check_ssot_consultation.sh`(retired;改靠 mindset #2 + `check_canonical_propagation.sh`)( Write tsx `node_modules/@qijenchen/design-system/src/components/` `src/explorations/` 若檔內無上述註解區 warn 要求補齊)
474
+ Hook `check_ssot_consultation.sh` retired;**2026-07-07 `check_ssot_header_declaration.sh` 精簡復活**(新建 production tsx 必帶「── 消費的 SSOT ──」段,P0 BLOCKER)+ mindset #2 + `check_canonical_propagation.sh`。(2026-07-10 hunt stale 描述)
471
475
 
472
476
  ## 禁止:隱性自創
473
477
 
@@ -477,7 +481,7 @@ Hook `check_ssot_consultation.sh`(retired;改靠 mindset #2 + `check_canonical_p
477
481
  - 自寫 `<button aria-label="Close"><X /></button>` 作 dismiss(應用 `ItemInlineAction`)
478
482
  - 自寫 Row `<div><Icon /><span>label</span><Button /></div>`(應用 `<MenuItem>` + slot)
479
483
  - 自訂 Input `variant="custom-name"` 未先 grep 既有 variant 值
480
- - 在 Toolbar 用 `<input className="bg-transparent border-0 ...">`(應用 `<Input variant="bare">` 若既有;無 Ambiguity Protocol)
484
+ - 在 Toolbar 用 `<input className="bg-transparent border-0 ...">`(應用 `<Input size="sm" autoWidth>` 標準 default variant;`variant="bare"` 已於 2026-07-09 退役,不再使用)
481
485
 
482
486
 
483
487
  - 需要時 Read:node_modules/@qijenchen/design-system/ds-canonical/references/ui-dev-rules.md(flex slot 幾何/Padding 3 層/Icon size 3 類,fork 寫 .tsx 通用)
@@ -57,6 +57,12 @@ description: Batch-end-verify rhythm + parallel tool batch + user-listed N-rule
57
57
  - 漏 N 條中第 K 條當「做完」report
58
58
  - 改寫 user wording 為自己 paraphrase(verbatim 保留)
59
59
 
60
+ **Sweep-first, edit-second(2026-07-07 治理進化軌道 2 codify)**:任一 fix 屬「跨切面決策」
61
+ (改名 / 詞彙統一 / 規則性改動,可寫成 grep 謂詞者)→ **先跑謂詞產出「sweep manifest」**
62
+ (grep 指令 + 全庫命中清單,artifact 化),照清單做完、驗證清單歸零,才算該 fix 完成。
63
+ **禁**「先改直覺想到的檔、稽核抓漏再補」(anchor:2026-07-07 meta 詞彙統一三波 11→16→9 檔,
64
+ 規則在散文裡 → 三輪才收斂;寫成謂詞後一個 grep 掃平)。
65
+
60
66
  ### Phase 1 — Parallel tool batch(原 M32(d))
61
67
 
62
68
  Read / Grep / Glob 多檔需求 → **single message multi-tool-call**:
@@ -97,7 +103,7 @@ Read / Grep / Glob 多檔需求 → **single message multi-tool-call**:
97
103
  ```bash
98
104
  npx tsc -b # type
99
105
  npm run hooks:test # invariant
100
- node scripts/visual-audit-<target>.mjs # pixel-quantified per M32(a)
106
+ node scripts/visual-audit.mjs --scope=changed # pixel-quantified per M32(a)(或 --scope=component:<X>)
101
107
  ```
102
108
 
103
109
  **MUST-ALL re-check**(per Phase 0 checklist):
@@ -141,11 +147,11 @@ node scripts/visual-audit-<target>.mjs # pixel-quantified per M32(a)
141
147
  | `/visual-audit` | 單次視覺對齊 | Phase 3 sub-step,本 skill 包它 |
142
148
  | `/component-quality-gate` | stakeholder gate | 不重疊(stakeholder vs daily bug fix) |
143
149
  | `stop_self_audit.sh`(hook) | claim-verify gap 攔 | 本 skill Phase 3 是 active side;hook 是 passive trip-wire |
144
- | `check_pixel_quantified_audit.sh`(hook) | M32(a) audit script 必 pixel | 本 skill Phase 3 跑該 audit |
150
+ | `check_pixel_quantified_audit.sh`(hook) | M32(a) audit script(`scripts/visual-audit*.mjs`,canonical = `visual-audit.mjs`)必 pixel | 本 skill Phase 3 跑該 audit |
145
151
 
146
152
  **3 層 防線**:
147
153
  - **本 skill**(active workflow):MUST-ALL checklist + batch-end-verify rhythm
148
- - **stop_self_audit.sh / check_codex_collab_5step.sh**(passive hook):claim-verify gap
154
+ - **stop_self_audit.sh**(passive hook,claim-verify gap,BLOCKER)+ **check_codex_collab_5step.sh**(passive hook,codex-collab commit 缺 cite+verify+verdict marker,P1 soft stderr 不 block)
149
155
  - **M20 / M32(a)**(meta-rule):上游 invariant
150
156
 
151
157
  ---
@@ -18,7 +18,7 @@ Scope:**tsx / ts code hygiene**,跟 design canonical 正交。
18
18
  | # | Check | Severity | 如何判定 |
19
19
  |---|-------|---------|---------|
20
20
  | 1 | `any` 使用 | P0 | grep `: any` / `as any` / `<any>` / `any[]` / `Record<X, any>`;支援 `// any-allow: {rationale}` 逃生口(同行或上一行) |
21
- | 2 | File size(.tsx)| P0 > 800 / P1 > 500 | `wc -l`;budget 500 / transition cap 800;spec `check_file_size_budget.sh` policy |
21
+ | 2 | File size(.tsx)| P0 > 800 / P1 > 500 | `wc -l`;budget 500 / transition cap 800(tsx SSOT = `scripts/code-quality-audit.mjs:36-37` + `lib/_code_quality.sh`;`check_file_size_budget.sh` 僅管治理 md,數字精神一致非同一 policy)|
22
22
  | 3 | Long function | P1 > 80 行 | naive:`function`/`const` 宣告到 matching `}` indent 行距 |
23
23
  | 4 | Dead export | P1 | `export` 名稱在其他 src/ 檔無出現;exempt `*Props/Options/Config/Args/Context/Variants/Value` 型別 API 慣例 |
24
24
  | 5 | Circular dep | P0 | DFS import graph,找 cycle |
@@ -56,10 +56,10 @@ Scope:**tsx / ts code hygiene**,跟 design canonical 正交。
56
56
  | `/design-system-audit` Dim 27 | `--deep` 必 chain 本 skill scope=all |
57
57
  | `/component-quality-gate` Ship | chain 本 skill scope=component:{Name} |
58
58
  | `/new-component` Phase 4.5 | 元件建完必跑 scope=component:{Name} |
59
- | Hook `check_code_quality.sh` | PostToolUse Edit/Write on src/ — 只跑 any + file-size(quick) |
59
+ | Hook `post_edit_dispatcher.sh` → `lib/_code_quality.sh` | PostToolUse Edit/Write on src/ — 只跑 any + file-size(quick);原 check_code_quality.sh folded(2026-05-13 dispatcher consolidation)|
60
60
 
61
61
  ## References
62
62
 
63
63
  - `scripts/code-quality-audit.mjs` — 實作
64
- - `.claude/hooks/check_code_quality.sh` — per-edit lite check
64
+ - `.claude/hooks/lib/_code_quality.sh`(經 `post_edit_dispatcher.sh` chain)— per-edit lite check
65
65
  - 相關:token 防線 `lib/_token_hygiene.sh` + `check_opacity_token_usage.sh`(正交 — token 紀律 vs code 紀律)
@@ -3,6 +3,8 @@ name: delivery-handoff
3
3
  description: Generate stakeholder-ready handoff documentation when a product / feature is confirmed final. Produces Storybook handoff page + UI flow diagram + component usage inventory + token consumption report + a11y checklist + per-screen spec — a Figma-like inspectable delivery package. Invoke via /delivery-handoff when user says「要交付」「handoff」「交付文件」「給 X 團隊的文件」「產品確認要上線了」. **只在產品確認 final 後才 invoke**,非 prototype 階段。
4
4
  ---
5
5
 
6
+ > **⚠️ Fork 工具註記(build 自動加)**:本 skill 提到的 `scripts/*.mjs` 或非標準 `npm run <audit>` 是 **DS-author repo 的機械工具,未隨 fork 套件附帶**(Claude Code 不掃 node_modules,fork 也無這些 executor + dep)。你的 product fork 用本 skill 的**方法論**(human / AI judgment)+ 既有 committed governance hook 的機械強制即可;要 mechanical 腳本層(截圖 / CI gate)請自行設置對應工具,或把該檢查 PR 回 DS repo 跑。
7
+
6
8
  # Delivery Handoff Workflow
7
9
 
8
10
  Purpose: 產品 / feature 通過 prototype → audit → stakeholder 決策後確認 final,需要產 **Figma-like inspectable handoff documentation** 給工程 / PM / QA / 其他 stakeholder。
@@ -60,6 +62,11 @@ Purpose: 產品 / feature 通過 prototype → audit → stakeholder 決策後
60
62
 
61
63
  ### Phase 1 — Inventory 生成
62
64
 
65
+ **Deterministic 源優先(2026-07-07 治理進化收尾:本 skill 原「幾乎零機械依賴」列冊補強)**:
66
+ - Component / story 母集 = `node scripts/gen-ds-story-manifest.mjs` 產出的 manifest(禁憑記憶列)
67
+ - Token 使用 = `rg -o -- '--[a-z][a-z0-9-]*' <feature files> | sort | uniq -c`(機械計數,非印象;字元類含 0-9 — DS token 名 46% 含數字如 `--chart-1`/`--black-a02`,缺數字會截斷合併成假 key)
68
+ - 消費統計交叉驗 `scripts/audit-orphan-tokens.mjs` 的消費通道邏輯(同一套 5 通道定義)
69
+
63
70
  scan 目標 feature 的 code,自動 inventory:
64
71
 
65
72
  1. **Component 清單**(哪些 DS 元件被此 feature 消費):
@@ -3,6 +3,8 @@ name: performance-audit
3
3
  description: Performance audit for design-system components and product UI. Checks render count, unnecessary re-renders, memoization gaps, bundle size impact, useEffect chains, context thrashing. Invoke when user says「這元件效能如何」「為什麼很卡」「bundle 變大」「re-render 太多」, auto-invoked by `/component-quality-gate` Phase 4.5 (advanced mode) and `/design-system-audit` Dimension D3.
4
4
  ---
5
5
 
6
+ > **⚠️ Fork 工具註記(build 自動加)**:本 skill 提到的 `scripts/*.mjs` 或非標準 `npm run <audit>` 是 **DS-author repo 的機械工具,未隨 fork 套件附帶**(Claude Code 不掃 node_modules,fork 也無這些 executor + dep)。你的 product fork 用本 skill 的**方法論**(human / AI judgment)+ 既有 committed governance hook 的機械強制即可;要 mechanical 腳本層(截圖 / CI gate)請自行設置對應工具,或把該檢查 PR 回 DS repo 跑。
7
+
6
8
  # Performance Audit — 元件效能稽核
7
9
 
8
10
  ## 存在意義
@@ -47,7 +49,7 @@ description: Performance audit for design-system components and product UI. Chec
47
49
 
48
50
  **工具**:
49
51
  - React DevTools Profiler record → 看 flame graph
50
- - `why-did-you-render` dev dep 觸發警告(未來可加)
52
+ - `why-did-you-render` dev dep 觸發警告(**尚未落地**;trigger = 下一個 render-storm 類 bug 實例時一併引入,roadmap 殘項列冊)
51
53
  - 直接 grep pattern(inline style / arrow onClick)
52
54
 
53
55
  ### Phase 2 — Memoization / dependency
@@ -66,7 +68,7 @@ description: Performance audit for design-system components and product UI. Chec
66
68
 
67
69
  **工具**:
68
70
  - `npx vite build --report`(vite bundle visualizer)
69
- - bundle-size CI check(未來可加)
71
+ - **bundle-size gate(已落地 2026-07-07)**:`npm run check:bundle-size`(budget SSOT = `packages/design-system/bundle-budget.json`,total + top-8 entry 各 +10% headroom;release-preflight 內建必跑;蓄意增大 → `--init` 更新 budget + commit 說明)
70
72
 
71
73
  ### Phase F — Report(必 STOP,對齊分權 canonical)
72
74
 
@@ -57,7 +57,7 @@ Purpose: design-system-audit audits the **DS itself**(spec / cva / SSOT 三方
57
57
  - Tailwind v4 `[--foo]` shorthand 靜默失效
58
58
  - 硬寫 px 值當該用 token(`w-[48px]` 應改 token)
59
59
 
60
- 此維對齊既有 token 防線(`lib/_token_hygiene.sh` 5-check:shadcn alias / v4 shorthand / hardcoded shadow / primitive-color-as-utility / native overflow,由 `post_edit_dispatcher.sh` source;+ `check_opacity_token_usage.sh` utility-registry.json)+ 擴充硬色值 / 硬 px 檢查。
60
+ 此維對齊既有 token 防線(`lib/_token_hygiene.sh` 5-check:shadcn alias / v4 shorthand / hardcoded shadow / primitive-color-as-utility / native overflow,由 `post_edit_dispatcher.sh` source;+ `check_opacity_token_usage.sh` 對齊 utility-registry.json 類別 — pattern hardcode 於 hook,registry 僅存在性 fallback gate)+ 擴充硬色值 / 硬 px 檢查。
61
61
 
62
62
  ### Dim 2 — Layout primitive 消費(per CLAUDE.md 清單)
63
63
 
@@ -172,7 +172,7 @@ P2(需討論):K 項
172
172
 
173
173
  ### Phase 4 — Verify
174
174
 
175
- - `npx tsc --noEmit` 通過
175
+ - `npx tsc -b` 無錯(禁 `--noEmit` — root tsconfig `files: []` silent pass;動型別 surface 加跑 `npm run build:lib`,對齊 component-quality-gate + self-verify.md)
176
176
  - re-run 本 skill(縮窄到原 findings)確認 zero regression
177
177
 
178
178
  ### Phase 5 — Visual audit(stakeholder-gate,mandatory on stakeholder-visible work)
@@ -185,7 +185,7 @@ P2(需討論):K 項
185
185
  1. 確認 user 有提供 **URL 清單**(產品 app routes)或 **Storybook scenario id**(若產品 stories 在 Storybook):
186
186
  - URL mode:`npm run visual-audit -- --urls=<csv>`(例:`--urls=http://localhost:3000/inbox,http://localhost:3000/settings`)
187
187
  - Storybook mode:`npm run visual-audit -- --scope=component:<topic>`
188
- 2. **Layer A mechanical**(auto):WCAG 對比度 + DOM 幾何 assertion + retina screenshot → `snapshots/`
188
+ 2. **Layer A mechanical**(auto):WCAG 對比度 + DOM 幾何 assertion + 1x screenshot(retina 需 `--retina` opt-in)→ `snapshots/`
189
189
  3. **Layer B AI judgement**(chain `/visual-audit` skill):讀 `snapshots/*.png`,判斷設計合理性(視覺對齊 / 覆蓋限制 / 世界級對照 / typography hierarchy)
190
190
  4. Violation 分級:
191
191
  - Contrast AA 不過 → **P0**(a11y 強制)
@@ -59,7 +59,7 @@ description: Auto-invoke when listing options / 建議 / 候選方案. Forces in
59
59
  - ✅ "grep 結果 Input/NumberInput/LinkInput 3 file 都未消費 ItemInlineAction(file:line)+ spec.md L60 表格列為 expected consumer → 真 gap"
60
60
  - ❌ "5 元件應該 migrate"(沒 grep / 沒 cite spec / 不知道 K 元件已 migrate / 是 colored host 合法例外)
61
61
 
62
- **對應 hook**:`check_propose_pre_grep_verify.sh`(2026-05-18 加,Edit/Write `*.md` 內含「propose」/「請拍板」/「決策」keyword 但近 N turn grep/Read tool call → P1 warn)
62
+ **對應 hook**:`check_propose_pre_grep_verify.sh`(2026-05-18 加,PreToolUse Edit/Write 限 `*/planning|reports|handoff/*.md`,內容含「請拍板 / 決策 N / 選項」等 propose keyword contentfile:line cite → P1 stderr warn(exit 0);escape:檔頭 `<!-- @propose-pre-verified -->`。chat reply 通道無 hook 覆蓋,靠本 skill Q0 自律)
63
63
 
64
64
  ### Q1 — M8 World-class benchmark
65
65
  **問**:本 option ≥ 3 家 world-class DS / framework / canonical 有對照嗎?
@@ -169,9 +169,9 @@ User 已就「為什麼會給錯誤建議」糾正 ≥ 3 次:
169
169
 
170
170
  | Skill | scope |
171
171
  |---|---|
172
- | `pre_write_subsumption_check.sh`(hook)| Edit/Write 已發生時 |
172
+ | `pre_write_subsumption_check.sh`(retired 2026-06 → `.claude/hooks/retired/` — write 前層由 `check_file_size_budget.sh` + `enforce_home_charter.sh` 等現役 pre-write hook 部分補位)| Edit/Write 已發生時 |
173
173
  | `post_edit_canonical_interrogate.sh`(retired/未實作 — mindset enforcement)| 寫完 canonical 後 3 題 |
174
174
  | `check_governance_compliance.sh`(retired/未實作 — 靠 `check_propose_pre_grep_verify.sh` + 加 hook 前 3 題)| 寫新 hook 7 題 |
175
175
  | **本 skill** `/propose-options` | **propose-time(寫進 user 回覆前)7 題** |
176
176
 
177
- 4 個正交 — propose 前 / write 前 / write 中 / write 後 cover
177
+ 4 個正交層(propose 前 / write 前 / write 中 / write 後);現役機械覆蓋僅 propose 前(本 skill + P1 hook)+ write 前部分補位,其餘層 retired/未實作,靠 mindset
@@ -141,7 +141,7 @@ Narrative 必含:
141
141
 
142
142
  **Input**: shortlist(2-3 items)+ Phase 3.0 產出的 Object Map
143
143
 
144
- **Phase 3.0a — SSOT 5-step pre-check**:寫任何 candidate code 前必過 CLAUDE.md「SSOT 消費 canonical」+ memory `feedback_proactive_5layer_pipeline.md`「5-step pre-check」(SSOT 在 memory + CLAUDE.md,本 skill 不重複)。`check_story_invariants.sh` R1 anatomy(原 check_story_anatomy.sh folded 折入)PreToolUse 是最後安全網,但 5-step 是事前 discipline。
144
+ **Phase 3.0a — SSOT 5-step pre-check**:寫任何 candidate code 前必過 CLAUDE.md「SSOT 消費 canonical」+ `node_modules/@qijenchen/design-system/ds-canonical/references/ssot-consultation.md`「5-step pre-check」(SSOT 在 memory + CLAUDE.md,本 skill 不重複)。`check_story_invariants.sh` R1 anatomy(原 check_story_anatomy.sh folded 折入)PreToolUse 是最後安全網,但 5-step 是事前 discipline。
145
145
 
146
146
  **Process**: 每個 candidate 建一個 exploration story,**各 candidate 共享 Object Map 但差異在 UI shape + CTAs 順序**。see `references/proposal-template.md` for structure。
147
147
 
@@ -24,7 +24,7 @@ description: Auto-invoke after fix commits — extracts root-cause anti-pattern,
24
24
  **強制(auto-chain)— batch-end only**(2026-05-12 重構,per codex):
25
25
  - multi-issue session 結束後**一次**(不是每 fix 一次)
26
26
  - session 內 ≥ 2 fix commit 觸發批次 root-pattern scan
27
- - session_start_governance_check.sh 偵測 session 2 fix commit batch-end scan 沒跑 → 提醒
27
+ - session_start_governance_check.sh Check 6 偵測 24h 1 fix commit skill-invokes log 24h 無 scan-similar-bugs invokesoft 提醒
28
28
 
29
29
  **手動 invoke**:
30
30
  - user 明言「掃同類 bug / 看其他元件有沒有 / 全 DS scan」
@@ -170,7 +170,7 @@ N 個 candidate 的修法 scope。**禁止 auto-fix 超過 5 檔不 ask user**
170
170
  | `/scan-similar-bugs`(本) | **immediate-after-fix grep + verify** | M10 mechanical 落地 |
171
171
  | `/knowledge-prune` | 季度 governance prune | 不重複 |
172
172
  | `check_canonical_propagation.sh` E.2(hook;原 check_l3_primitive_import.sh folded 折入,P0 BLOCK) | L3 primitive import 違規 | 即時 detect,本 skill 是 batch retro scan |
173
- | `pre_write_subsumption_check.sh`(hook)| 新 file / M-row | 不重複 |
173
+ | `pre_write_subsumption_check.sh`(retired 2026-06 → `.claude/hooks/retired/`;新 file / M-row 治理由 `session_start_governance_check.sh` + `enforce_home_charter.sh` 現役防線接手)| 新 file / M-row | 不重複 |
174
174
 
175
175
  **3 層 防線**:
176
176
  - Hook(pre/post tool):**寫的瞬間** detect