@qijenchen/design-system 0.1.0-beta.85 → 0.1.0-beta.86

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 (477) hide show
  1. package/AGENTS.md +210 -0
  2. package/CLAUDE.md +17 -191
  3. package/cli-init.mjs +30 -2
  4. package/dist/components/Accordion/accordion.d.ts +2 -2
  5. package/dist/components/Accordion/accordion.d.ts.map +1 -1
  6. package/dist/components/Accordion/accordion.js.map +1 -1
  7. package/dist/components/Avatar/avatar.js +1 -1
  8. package/dist/components/Avatar/avatar.js.map +1 -1
  9. package/dist/components/BulkActionBar/bulk-action-bar.d.ts +1 -1
  10. package/dist/components/BulkActionBar/bulk-action-bar.d.ts.map +1 -1
  11. package/dist/components/BulkActionBar/bulk-action-bar.js +3 -3
  12. package/dist/components/BulkActionBar/bulk-action-bar.js.map +1 -1
  13. package/dist/components/Button/button-group.d.ts +2 -2
  14. package/dist/components/Button/button-group.d.ts.map +1 -1
  15. package/dist/components/Button/button-group.js +2 -2
  16. package/dist/components/Button/button-group.js.map +1 -1
  17. package/dist/components/Button/button.d.ts +2 -1
  18. package/dist/components/Button/button.d.ts.map +1 -1
  19. package/dist/components/Button/button.js +1 -1
  20. package/dist/components/Button/button.js.map +1 -1
  21. package/dist/components/Carousel/carousel.d.ts +14 -8
  22. package/dist/components/Carousel/carousel.d.ts.map +1 -1
  23. package/dist/components/Carousel/carousel.js +64 -37
  24. package/dist/components/Carousel/carousel.js.map +1 -1
  25. package/dist/components/Checkbox/checkbox-group.d.ts.map +1 -1
  26. package/dist/components/Checkbox/checkbox-group.js +21 -14
  27. package/dist/components/Checkbox/checkbox-group.js.map +1 -1
  28. package/dist/components/Checkbox/checkbox.d.ts +2 -2
  29. package/dist/components/Checkbox/checkbox.d.ts.map +1 -1
  30. package/dist/components/Checkbox/checkbox.js +49 -10
  31. package/dist/components/Checkbox/checkbox.js.map +1 -1
  32. package/dist/components/Combobox/combobox.d.ts +15 -6
  33. package/dist/components/Combobox/combobox.d.ts.map +1 -1
  34. package/dist/components/Combobox/combobox.js +13 -7
  35. package/dist/components/Combobox/combobox.js.map +1 -1
  36. package/dist/components/Command/command.d.ts.map +1 -1
  37. package/dist/components/Command/command.js +11 -2
  38. package/dist/components/Command/command.js.map +1 -1
  39. package/dist/components/DataTable/cell-registry.d.ts +5 -5
  40. package/dist/components/DataTable/cell-registry.d.ts.map +1 -1
  41. package/dist/components/DataTable/cell-registry.js +41 -38
  42. package/dist/components/DataTable/cell-registry.js.map +1 -1
  43. package/dist/components/DataTable/column-types.d.ts +1 -17
  44. package/dist/components/DataTable/column-types.d.ts.map +1 -1
  45. package/dist/components/DataTable/column-types.js.map +1 -1
  46. package/dist/components/DataTable/data-table-column-visibility-panel.d.ts.map +1 -1
  47. package/dist/components/DataTable/data-table-column-visibility-panel.js +71 -64
  48. package/dist/components/DataTable/data-table-column-visibility-panel.js.map +1 -1
  49. package/dist/components/DataTable/data-table-filter-panel.d.ts +0 -2
  50. package/dist/components/DataTable/data-table-filter-panel.d.ts.map +1 -1
  51. package/dist/components/DataTable/data-table-filter-panel.js +3 -4
  52. package/dist/components/DataTable/data-table-filter-panel.js.map +1 -1
  53. package/dist/components/DataTable/data-table-interaction-layer.d.ts +2 -2
  54. package/dist/components/DataTable/data-table-interaction-layer.js.map +1 -1
  55. package/dist/components/DataTable/data-table-sort-manager.js +2 -2
  56. package/dist/components/DataTable/data-table-sort-manager.js.map +1 -1
  57. package/dist/components/DataTable/data-table.d.ts +1 -1
  58. package/dist/components/DataTable/data-table.d.ts.map +1 -1
  59. package/dist/components/DataTable/data-table.js +44 -32
  60. package/dist/components/DataTable/data-table.js.map +1 -1
  61. package/dist/components/DatePicker/date-picker.d.ts +3 -3
  62. package/dist/components/DatePicker/date-picker.js +4 -4
  63. package/dist/components/DatePicker/date-picker.js.map +1 -1
  64. package/dist/components/DescriptionList/description-list.d.ts +3 -3
  65. package/dist/components/DescriptionList/description-list.d.ts.map +1 -1
  66. package/dist/components/DescriptionList/description-list.js +6 -6
  67. package/dist/components/DescriptionList/description-list.js.map +1 -1
  68. package/dist/components/Dialog/dialog.d.ts +2 -2
  69. package/dist/components/Dialog/dialog.d.ts.map +1 -1
  70. package/dist/components/Dialog/dialog.js.map +1 -1
  71. package/dist/components/DropdownMenu/dropdown-menu.d.ts +8 -3
  72. package/dist/components/DropdownMenu/dropdown-menu.d.ts.map +1 -1
  73. package/dist/components/DropdownMenu/dropdown-menu.js +7 -7
  74. package/dist/components/DropdownMenu/dropdown-menu.js.map +1 -1
  75. package/dist/components/Field/field-context.d.ts +16 -10
  76. package/dist/components/Field/field-context.d.ts.map +1 -1
  77. package/dist/components/Field/field-context.js.map +1 -1
  78. package/dist/components/Field/field-types.d.ts +2 -2
  79. package/dist/components/Field/field-types.d.ts.map +1 -1
  80. package/dist/components/Field/field-types.js.map +1 -1
  81. package/dist/components/Field/field-wrapper.d.ts +20 -4
  82. package/dist/components/Field/field-wrapper.d.ts.map +1 -1
  83. package/dist/components/Field/field-wrapper.js +30 -31
  84. package/dist/components/Field/field-wrapper.js.map +1 -1
  85. package/dist/components/Field/field.d.ts +1 -1
  86. package/dist/components/Field/field.d.ts.map +1 -1
  87. package/dist/components/Field/field.js +25 -3
  88. package/dist/components/Field/field.js.map +1 -1
  89. package/dist/components/Field/use-form-validation.d.ts +1 -1
  90. package/dist/components/Field/use-form-validation.js.map +1 -1
  91. package/dist/components/FileItem/file-item.d.ts.map +1 -1
  92. package/dist/components/FileItem/file-item.js +2 -5
  93. package/dist/components/FileItem/file-item.js.map +1 -1
  94. package/dist/components/FileUpload/file-upload.d.ts.map +1 -1
  95. package/dist/components/FileUpload/file-upload.js +5 -1
  96. package/dist/components/FileUpload/file-upload.js.map +1 -1
  97. package/dist/components/FileViewer/file-viewer.d.ts.map +1 -1
  98. package/dist/components/FileViewer/file-viewer.js +2 -1
  99. package/dist/components/FileViewer/file-viewer.js.map +1 -1
  100. package/dist/components/HoverCard/hover-card.d.ts +2 -2
  101. package/dist/components/HoverCard/hover-card.d.ts.map +1 -1
  102. package/dist/components/HoverCard/hover-card.js +4 -2
  103. package/dist/components/HoverCard/hover-card.js.map +1 -1
  104. package/dist/components/InlineEdit/inline-edit.d.ts +23 -16
  105. package/dist/components/InlineEdit/inline-edit.d.ts.map +1 -1
  106. package/dist/components/InlineEdit/inline-edit.js +104 -62
  107. package/dist/components/InlineEdit/inline-edit.js.map +1 -1
  108. package/dist/components/Input/input.d.ts +1 -1
  109. package/dist/components/Input/input.d.ts.map +1 -1
  110. package/dist/components/Input/input.js +6 -6
  111. package/dist/components/Input/input.js.map +1 -1
  112. package/dist/components/LinkInput/link-input.d.ts +5 -5
  113. package/dist/components/LinkInput/link-input.d.ts.map +1 -1
  114. package/dist/components/LinkInput/link-input.js +3 -3
  115. package/dist/components/LinkInput/link-input.js.map +1 -1
  116. package/dist/components/Notice/notice.d.ts +17 -1
  117. package/dist/components/Notice/notice.d.ts.map +1 -1
  118. package/dist/components/Notice/notice.js +7 -1
  119. package/dist/components/Notice/notice.js.map +1 -1
  120. package/dist/components/NumberInput/number-input.d.ts +1 -1
  121. package/dist/components/NumberInput/number-input.d.ts.map +1 -1
  122. package/dist/components/NumberInput/number-input.js +12 -1
  123. package/dist/components/NumberInput/number-input.js.map +1 -1
  124. package/dist/components/PeoplePicker/avatar-stack-overflow.d.ts +1 -1
  125. package/dist/components/PeoplePicker/avatar-stack-overflow.js.map +1 -1
  126. package/dist/components/PeoplePicker/people-picker.d.ts +5 -5
  127. package/dist/components/PeoplePicker/people-picker.d.ts.map +1 -1
  128. package/dist/components/PeoplePicker/people-picker.js +7 -5
  129. package/dist/components/PeoplePicker/people-picker.js.map +1 -1
  130. package/dist/components/PeoplePicker/person-display.d.ts +1 -1
  131. package/dist/components/PeoplePicker/person-display.js.map +1 -1
  132. package/dist/components/ProfileCard/profile-card.d.ts +1 -1
  133. package/dist/components/ProfileCard/profile-card.js.map +1 -1
  134. package/dist/components/RadioGroup/radio-group.d.ts +3 -3
  135. package/dist/components/RadioGroup/radio-group.d.ts.map +1 -1
  136. package/dist/components/RadioGroup/radio-group.js +1 -1
  137. package/dist/components/RadioGroup/radio-group.js.map +1 -1
  138. package/dist/components/Rating/rating.d.ts.map +1 -1
  139. package/dist/components/Rating/rating.js +4 -0
  140. package/dist/components/Rating/rating.js.map +1 -1
  141. package/dist/components/ScrollArea/scroll-area.d.ts +3 -2
  142. package/dist/components/ScrollArea/scroll-area.d.ts.map +1 -1
  143. package/dist/components/ScrollArea/scroll-area.js.map +1 -1
  144. package/dist/components/SegmentedControl/segmented-control.d.ts +4 -3
  145. package/dist/components/SegmentedControl/segmented-control.d.ts.map +1 -1
  146. package/dist/components/SegmentedControl/segmented-control.js.map +1 -1
  147. package/dist/components/Select/select.d.ts +16 -6
  148. package/dist/components/Select/select.d.ts.map +1 -1
  149. package/dist/components/Select/select.js +17 -5
  150. package/dist/components/Select/select.js.map +1 -1
  151. package/dist/components/SelectMenu/select-menu.d.ts +17 -1
  152. package/dist/components/SelectMenu/select-menu.d.ts.map +1 -1
  153. package/dist/components/SelectMenu/select-menu.js +17 -3
  154. package/dist/components/SelectMenu/select-menu.js.map +1 -1
  155. package/dist/components/SelectionControl/boolean-value.d.ts +1 -1
  156. package/dist/components/SelectionControl/boolean-value.js.map +1 -1
  157. package/dist/components/Sheet/sheet.d.ts +2 -2
  158. package/dist/components/Sheet/sheet.d.ts.map +1 -1
  159. package/dist/components/Sheet/sheet.js.map +1 -1
  160. package/dist/components/Sidebar/sidebar.d.ts +1 -1
  161. package/dist/components/Sidebar/sidebar.js +2 -2
  162. package/dist/components/Sidebar/sidebar.js.map +1 -1
  163. package/dist/components/Slider/slider.d.ts.map +1 -1
  164. package/dist/components/Slider/slider.js +6 -3
  165. package/dist/components/Slider/slider.js.map +1 -1
  166. package/dist/components/Steps/steps.d.ts +6 -4
  167. package/dist/components/Steps/steps.d.ts.map +1 -1
  168. package/dist/components/Steps/steps.js +19 -5
  169. package/dist/components/Steps/steps.js.map +1 -1
  170. package/dist/components/Switch/switch.d.ts +4 -4
  171. package/dist/components/Switch/switch.d.ts.map +1 -1
  172. package/dist/components/Switch/switch.js +3 -1
  173. package/dist/components/Switch/switch.js.map +1 -1
  174. package/dist/components/Tabs/tabs.d.ts +1 -1
  175. package/dist/components/Tabs/tabs.d.ts.map +1 -1
  176. package/dist/components/Tabs/tabs.js +73 -23
  177. package/dist/components/Tabs/tabs.js.map +1 -1
  178. package/dist/components/Tag/tag.d.ts +3 -1
  179. package/dist/components/Tag/tag.d.ts.map +1 -1
  180. package/dist/components/Tag/tag.js +2 -2
  181. package/dist/components/Tag/tag.js.map +1 -1
  182. package/dist/components/Textarea/textarea.d.ts +4 -4
  183. package/dist/components/Textarea/textarea.d.ts.map +1 -1
  184. package/dist/components/Textarea/textarea.js +15 -15
  185. package/dist/components/Textarea/textarea.js.map +1 -1
  186. package/dist/components/TimePicker/time-picker.d.ts +4 -4
  187. package/dist/components/TimePicker/time-picker.d.ts.map +1 -1
  188. package/dist/components/TimePicker/time-picker.js +8 -5
  189. package/dist/components/TimePicker/time-picker.js.map +1 -1
  190. package/dist/components/Tooltip/tooltip.d.ts.map +1 -1
  191. package/dist/components/Tooltip/tooltip.js +27 -23
  192. package/dist/components/Tooltip/tooltip.js.map +1 -1
  193. package/dist/components/TreeView/tree-view.d.ts.map +1 -1
  194. package/dist/components/TreeView/tree-view.js +16 -0
  195. package/dist/components/TreeView/tree-view.js.map +1 -1
  196. package/dist/index.d.ts +7 -7
  197. package/dist/index.d.ts.map +1 -1
  198. package/dist/index.js +6 -13
  199. package/dist/index.js.map +1 -1
  200. package/dist/lib/drag-visual.d.ts +2 -2
  201. package/dist/lib/drag-visual.js.map +1 -1
  202. package/dist/lib/utils.d.ts +1 -0
  203. package/dist/lib/utils.d.ts.map +1 -1
  204. package/dist/lib/utils.js +21 -1
  205. package/dist/lib/utils.js.map +1 -1
  206. package/dist/patterns/element-anatomy/item-anatomy.d.ts +2 -0
  207. package/dist/patterns/element-anatomy/item-anatomy.d.ts.map +1 -1
  208. package/dist/patterns/element-anatomy/item-anatomy.js +2 -2
  209. package/dist/patterns/element-anatomy/item-anatomy.js.map +1 -1
  210. package/dist/tokens/categorical-color.d.ts +3 -3
  211. package/dist/tokens/categorical-color.d.ts.map +1 -1
  212. package/dist/tokens/categorical-color.js +2 -2
  213. package/dist/tokens/categorical-color.js.map +1 -1
  214. package/ds-canonical/fork/AGENTS.md +213 -0
  215. package/ds-canonical/fork/codex/agents/skills/independent-review/SKILL.md +33 -0
  216. package/ds-canonical/fork/codex/hooks.json +16 -0
  217. package/ds-canonical/fork/governance.lock +22 -7
  218. package/ds-canonical/fork/hooks/check_ds_anchor_preflight.sh +22 -1
  219. package/ds-canonical/fork/hooks/inject_deploy_url_after_push.sh +14 -2
  220. package/ds-canonical/fork/manifest.json +10 -1
  221. package/ds-canonical/fork/preamble.md +3 -2
  222. package/ds-canonical/fork/skills/product-ui-audit/SKILL.md +7 -7
  223. package/ds-canonical/fork/skills/ux-audit/SKILL.md +1 -1
  224. package/ds-canonical/fork/skills/visual-audit/SKILL.md +0 -1
  225. package/ds-canonical/hooks/check_codex_brief_invariants.sh +9 -3
  226. package/ds-canonical/hooks/check_ds_anchor_preflight.sh +22 -1
  227. package/ds-canonical/hooks/check_overlay_open_focus_escape_probe.sh +11 -2
  228. package/ds-canonical/hooks/check_plugin_fork_health.sh +17 -1
  229. package/ds-canonical/hooks/check_post_main_ssot_propagate.sh +21 -4
  230. package/ds-canonical/hooks/inject_deploy_url_after_push.sh +14 -2
  231. package/ds-canonical/hooks/session_start_governance_check.sh +10 -2
  232. package/ds-canonical/references/certified-surfaces.md +20 -0
  233. package/ds-canonical/references/preflight-gate-baseline.json +5 -0
  234. package/ds-canonical/references/principle-dim-map.json +20 -2
  235. package/ds-canonical/references/props-naming.md +2 -1
  236. package/ds-canonical/references/ssot-index.md +2 -2
  237. package/ds-canonical/references/story-baseline-registry.json +2 -2
  238. package/ds-canonical/rules/story-rules.md +1 -1
  239. package/ds-canonical/rules/ui-development.md +2 -1
  240. package/ds-canonical/skills/codex-collab/SKILL.md +7 -7
  241. package/ds-canonical/skills/codex-collab/references/brief-template.md +5 -1
  242. package/ds-canonical/skills/component-quality-gate/SKILL.md +1 -1
  243. package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +5 -5
  244. package/ds-canonical/skills/design-system-audit/SKILL.md +5 -5
  245. package/ds-canonical/skills/product-ui-audit/SKILL.md +7 -7
  246. package/ds-canonical/skills/ux-audit/SKILL.md +1 -1
  247. package/ds-canonical/skills/visual-audit/SKILL.md +0 -1
  248. package/ds-story-manifest.json +21 -21
  249. package/llms-full.txt +3 -3
  250. package/llms.txt +1 -1
  251. package/package.json +2 -1
  252. package/src/components/Accordion/accordion.anatomy.stories.tsx +11 -11
  253. package/src/components/Accordion/accordion.principles.stories.tsx +21 -6
  254. package/src/components/Accordion/accordion.spec.md +10 -1
  255. package/src/components/Accordion/accordion.stories.tsx +10 -5
  256. package/src/components/Accordion/accordion.tsx +7 -2
  257. package/src/components/Alert/alert.principles.stories.tsx +2 -8
  258. package/src/components/AppShell/app-shell.anatomy.stories.tsx +19 -13
  259. package/src/components/AppShell/app-shell.principles.stories.tsx +21 -21
  260. package/src/components/AppShell/app-shell.spec.md +4 -0
  261. package/src/components/AppShell/app-shell.stories.tsx +4 -5
  262. package/src/components/Avatar/avatar.tsx +1 -1
  263. package/src/components/Badge/badge.spec.md +2 -2
  264. package/src/components/Breadcrumb/breadcrumb.anatomy.stories.tsx +7 -3
  265. package/src/components/Breadcrumb/breadcrumb.principles.stories.tsx +4 -1
  266. package/src/components/Breadcrumb/breadcrumb.stories.tsx +1 -1
  267. package/src/components/BulkActionBar/bulk-action-bar.anatomy.stories.tsx +6 -6
  268. package/src/components/BulkActionBar/bulk-action-bar.principles.stories.tsx +18 -6
  269. package/src/components/BulkActionBar/bulk-action-bar.spec.md +15 -5
  270. package/src/components/BulkActionBar/bulk-action-bar.stories.tsx +8 -24
  271. package/src/components/BulkActionBar/bulk-action-bar.tsx +4 -4
  272. package/src/components/Button/button-group.tsx +4 -4
  273. package/src/components/Button/button.anatomy.stories.tsx +26 -7
  274. package/src/components/Button/button.principles.stories.tsx +1 -1
  275. package/src/components/Button/button.spec.md +2 -2
  276. package/src/components/Button/button.stories.tsx +22 -28
  277. package/src/components/Button/button.tsx +2 -1
  278. package/src/components/Calendar/calendar.anatomy.stories.tsx +1 -1
  279. package/src/components/Calendar/calendar.spec.md +1 -1
  280. package/src/components/Carousel/carousel.spec.md +17 -1
  281. package/src/components/Carousel/carousel.tsx +93 -42
  282. package/src/components/Checkbox/checkbox-group.tsx +26 -15
  283. package/src/components/Checkbox/checkbox.anatomy.stories.tsx +3 -3
  284. package/src/components/Checkbox/checkbox.spec.md +12 -3
  285. package/src/components/Checkbox/checkbox.stories.tsx +4 -4
  286. package/src/components/Checkbox/checkbox.tsx +79 -19
  287. package/src/components/Coachmark/coachmark.anatomy.stories.tsx +5 -5
  288. package/src/components/Coachmark/coachmark.principles.stories.tsx +1 -1
  289. package/src/components/Combobox/combobox.anatomy.stories.tsx +11 -4
  290. package/src/components/Combobox/combobox.principles.stories.tsx +10 -11
  291. package/src/components/Combobox/combobox.spec.md +6 -2
  292. package/src/components/Combobox/combobox.stories.tsx +9 -36
  293. package/src/components/Combobox/combobox.tsx +42 -27
  294. package/src/components/Command/command.spec.md +3 -3
  295. package/src/components/Command/command.tsx +9 -2
  296. package/src/components/DataTable/cell-registry.tsx +75 -76
  297. package/src/components/DataTable/column-types.ts +4 -17
  298. package/src/components/DataTable/data-table-column-visibility-panel.tsx +20 -7
  299. package/src/components/DataTable/data-table-filter-panel.tsx +6 -6
  300. package/src/components/DataTable/data-table-interaction-layer.tsx +3 -3
  301. package/src/components/DataTable/data-table-sort-manager.tsx +2 -2
  302. package/src/components/DataTable/data-table.anatomy.stories.tsx +25 -24
  303. package/src/components/DataTable/data-table.css +2 -3
  304. package/src/components/DataTable/data-table.principles.stories.tsx +17 -11
  305. package/src/components/DataTable/data-table.spec.md +7 -7
  306. package/src/components/DataTable/data-table.stories.tsx +39 -29
  307. package/src/components/DataTable/data-table.tsx +90 -67
  308. package/src/components/DataTable/filter-operators.spec.md +2 -0
  309. package/src/components/DateGrid/date-grid.spec.md +1 -1
  310. package/src/components/DatePicker/date-picker.anatomy.stories.tsx +9 -9
  311. package/src/components/DatePicker/date-picker.principles.stories.tsx +4 -4
  312. package/src/components/DatePicker/date-picker.spec.md +9 -9
  313. package/src/components/DatePicker/date-picker.stories.tsx +9 -9
  314. package/src/components/DatePicker/date-picker.tsx +13 -13
  315. package/src/components/DescriptionList/description-list.anatomy.stories.tsx +5 -5
  316. package/src/components/DescriptionList/description-list.principles.stories.tsx +2 -2
  317. package/src/components/DescriptionList/description-list.spec.md +12 -12
  318. package/src/components/DescriptionList/description-list.stories.tsx +3 -3
  319. package/src/components/DescriptionList/description-list.tsx +10 -10
  320. package/src/components/Dialog/dialog.tsx +4 -1
  321. package/src/components/DropdownMenu/dropdown-menu.tsx +27 -14
  322. package/src/components/Field/field-context.ts +17 -11
  323. package/src/components/Field/field-controls.spec.md +44 -37
  324. package/src/components/Field/field-types.ts +14 -12
  325. package/src/components/Field/field-wrapper.tsx +59 -43
  326. package/src/components/Field/field.anatomy.stories.tsx +6 -6
  327. package/src/components/Field/field.principles.stories.tsx +5 -28
  328. package/src/components/Field/field.spec.md +4 -4
  329. package/src/components/Field/field.stories.tsx +103 -72
  330. package/src/components/Field/field.tsx +36 -4
  331. package/src/components/Field/form-validation.spec.md +2 -0
  332. package/src/components/Field/use-form-validation.ts +1 -1
  333. package/src/components/FieldControlGroup/field-control-group.principles.stories.tsx +3 -3
  334. package/src/components/FieldControlGroup/field-control-group.spec.md +3 -3
  335. package/src/components/FileItem/file-item.tsx +10 -8
  336. package/src/components/FileUpload/file-upload.principles.stories.tsx +7 -7
  337. package/src/components/FileUpload/file-upload.spec.md +3 -2
  338. package/src/components/FileUpload/file-upload.tsx +5 -1
  339. package/src/components/FileViewer/file-viewer.anatomy.stories.tsx +1 -1
  340. package/src/components/FileViewer/file-viewer.principles.stories.tsx +1 -1
  341. package/src/components/FileViewer/file-viewer.spec.md +1 -1
  342. package/src/components/FileViewer/file-viewer.stories.tsx +1 -1
  343. package/src/components/FileViewer/file-viewer.tsx +3 -2
  344. package/src/components/HoverCard/hover-card.anatomy.stories.tsx +6 -4
  345. package/src/components/HoverCard/hover-card.principles.stories.tsx +6 -1
  346. package/src/components/HoverCard/hover-card.spec.md +2 -2
  347. package/src/components/HoverCard/hover-card.tsx +4 -2
  348. package/src/components/InlineEdit/inline-edit.anatomy.stories.tsx +184 -0
  349. package/src/components/InlineEdit/inline-edit.principles.stories.tsx +142 -0
  350. package/src/components/InlineEdit/inline-edit.spec.md +71 -46
  351. package/src/components/InlineEdit/inline-edit.stories.tsx +20 -19
  352. package/src/components/InlineEdit/inline-edit.tsx +211 -125
  353. package/src/components/Input/input.anatomy.stories.tsx +15 -15
  354. package/src/components/Input/input.principles.stories.tsx +3 -3
  355. package/src/components/Input/input.spec.md +4 -4
  356. package/src/components/Input/input.stories.tsx +3 -3
  357. package/src/components/Input/input.tsx +13 -13
  358. package/src/components/LinkInput/link-input.anatomy.stories.tsx +2 -2
  359. package/src/components/LinkInput/link-input.principles.stories.tsx +1 -1
  360. package/src/components/LinkInput/link-input.spec.md +6 -2
  361. package/src/components/LinkInput/link-input.stories.tsx +8 -8
  362. package/src/components/LinkInput/link-input.tsx +21 -19
  363. package/src/components/Notice/notice.principles.stories.tsx +1 -1
  364. package/src/components/Notice/notice.tsx +8 -2
  365. package/src/components/NumberInput/number-input.anatomy.stories.tsx +6 -6
  366. package/src/components/NumberInput/number-input.principles.stories.tsx +4 -4
  367. package/src/components/NumberInput/number-input.spec.md +6 -6
  368. package/src/components/NumberInput/number-input.stories.tsx +4 -4
  369. package/src/components/NumberInput/number-input.tsx +17 -5
  370. package/src/components/OverflowIndicator/overflow-indicator.anatomy.stories.tsx +8 -4
  371. package/src/components/OverflowIndicator/overflow-indicator.principles.stories.tsx +6 -7
  372. package/src/components/OverflowIndicator/overflow-indicator.spec.md +1 -1
  373. package/src/components/OverflowIndicator/overflow-indicator.stories.tsx +6 -30
  374. package/src/components/PeoplePicker/avatar-stack-overflow.ts +1 -1
  375. package/src/components/PeoplePicker/people-picker.anatomy.stories.tsx +13 -10
  376. package/src/components/PeoplePicker/people-picker.principles.stories.tsx +5 -1
  377. package/src/components/PeoplePicker/people-picker.stories.tsx +5 -5
  378. package/src/components/PeoplePicker/people-picker.tsx +39 -20
  379. package/src/components/PeoplePicker/person-display.tsx +3 -3
  380. package/src/components/Popover/popover.anatomy.stories.tsx +10 -7
  381. package/src/components/Popover/popover.principles.stories.tsx +49 -28
  382. package/src/components/Popover/popover.spec.md +4 -2
  383. package/src/components/ProfileCard/profile-card.anatomy.stories.tsx +1 -1
  384. package/src/components/ProfileCard/profile-card.tsx +1 -1
  385. package/src/components/ProgressBar/progress-bar.anatomy.stories.tsx +14 -13
  386. package/src/components/ProgressBar/progress-bar.principles.stories.tsx +8 -23
  387. package/src/components/ProgressBar/progress-bar.stories.tsx +8 -2
  388. package/src/components/README.md +1 -0
  389. package/src/components/RadioGroup/radio-group.anatomy.stories.tsx +8 -3
  390. package/src/components/RadioGroup/radio-group.stories.tsx +3 -3
  391. package/src/components/RadioGroup/radio-group.tsx +19 -14
  392. package/src/components/Rating/rating.anatomy.stories.tsx +1 -1
  393. package/src/components/Rating/rating.principles.stories.tsx +3 -3
  394. package/src/components/Rating/rating.spec.md +2 -2
  395. package/src/components/Rating/rating.stories.tsx +4 -18
  396. package/src/components/Rating/rating.tsx +5 -1
  397. package/src/components/ScrollArea/scroll-area.principles.stories.tsx +1 -1
  398. package/src/components/ScrollArea/scroll-area.spec.md +1 -1
  399. package/src/components/ScrollArea/scroll-area.tsx +5 -2
  400. package/src/components/SegmentedControl/segmented-control.principles.stories.tsx +4 -1
  401. package/src/components/SegmentedControl/segmented-control.spec.md +5 -10
  402. package/src/components/SegmentedControl/segmented-control.tsx +6 -3
  403. package/src/components/Select/select.anatomy.stories.tsx +13 -7
  404. package/src/components/Select/select.principles.stories.tsx +3 -3
  405. package/src/components/Select/select.spec.md +9 -1
  406. package/src/components/Select/select.stories.tsx +41 -27
  407. package/src/components/Select/select.tsx +44 -26
  408. package/src/components/SelectMenu/select-menu.anatomy.stories.tsx +44 -26
  409. package/src/components/SelectMenu/select-menu.principles.stories.tsx +0 -1
  410. package/src/components/SelectMenu/select-menu.stories.tsx +7 -19
  411. package/src/components/SelectMenu/select-menu.tsx +38 -5
  412. package/src/components/SelectionControl/boolean-value.tsx +2 -2
  413. package/src/components/SelectionControl/selection-item.anatomy.stories.tsx +1 -1
  414. package/src/components/SelectionControl/selection-item.principles.stories.tsx +4 -4
  415. package/src/components/Separator/separator.principles.stories.tsx +1 -1
  416. package/src/components/Sheet/sheet.principles.stories.tsx +5 -3
  417. package/src/components/Sheet/sheet.tsx +4 -1
  418. package/src/components/Sidebar/sidebar.tsx +1 -1
  419. package/src/components/Slider/slider.anatomy.stories.tsx +5 -4
  420. package/src/components/Slider/slider.principles.stories.tsx +6 -6
  421. package/src/components/Slider/slider.spec.md +13 -1
  422. package/src/components/Slider/slider.stories.tsx +44 -32
  423. package/src/components/Slider/slider.tsx +13 -4
  424. package/src/components/Steps/steps.anatomy.stories.tsx +7 -7
  425. package/src/components/Steps/steps.principles.stories.tsx +1 -1
  426. package/src/components/Steps/steps.spec.md +4 -2
  427. package/src/components/Steps/steps.stories.tsx +4 -56
  428. package/src/components/Steps/steps.tsx +31 -7
  429. package/src/components/Switch/switch.anatomy.stories.tsx +3 -3
  430. package/src/components/Switch/switch.principles.stories.tsx +1 -1
  431. package/src/components/Switch/switch.spec.md +4 -4
  432. package/src/components/Switch/switch.stories.tsx +3 -3
  433. package/src/components/Switch/switch.tsx +16 -10
  434. package/src/components/Tabs/tabs.anatomy.stories.tsx +6 -0
  435. package/src/components/Tabs/tabs.principles.stories.tsx +10 -2
  436. package/src/components/Tabs/tabs.spec.md +5 -2
  437. package/src/components/Tabs/tabs.stories.tsx +36 -44
  438. package/src/components/Tabs/tabs.tsx +101 -36
  439. package/src/components/Tag/tag.anatomy.stories.tsx +2 -2
  440. package/src/components/Tag/tag.principles.stories.tsx +4 -4
  441. package/src/components/Tag/tag.spec.md +3 -1
  442. package/src/components/Tag/tag.tsx +5 -3
  443. package/src/components/Textarea/textarea.anatomy.stories.tsx +6 -6
  444. package/src/components/Textarea/textarea.spec.md +5 -5
  445. package/src/components/Textarea/textarea.tsx +24 -24
  446. package/src/components/TimePicker/time-picker.anatomy.stories.tsx +12 -11
  447. package/src/components/TimePicker/time-picker.principles.stories.tsx +37 -44
  448. package/src/components/TimePicker/time-picker.spec.md +6 -5
  449. package/src/components/TimePicker/time-picker.stories.tsx +3 -3
  450. package/src/components/TimePicker/time-picker.tsx +24 -14
  451. package/src/components/Toast/toast.principles.stories.tsx +1 -1
  452. package/src/components/Toast/toast.stories.tsx +1 -1
  453. package/src/components/Tooltip/tooltip.anatomy.stories.tsx +15 -6
  454. package/src/components/Tooltip/tooltip.principles.stories.tsx +4 -4
  455. package/src/components/Tooltip/tooltip.spec.md +9 -3
  456. package/src/components/Tooltip/tooltip.stories.tsx +1 -1
  457. package/src/components/Tooltip/tooltip.tsx +12 -2
  458. package/src/components/TreeView/tree-view.anatomy.stories.tsx +16 -14
  459. package/src/components/TreeView/tree-view.principles.stories.tsx +44 -11
  460. package/src/components/TreeView/tree-view.spec.md +8 -6
  461. package/src/components/TreeView/tree-view.stories.tsx +9 -43
  462. package/src/components/TreeView/tree-view.tsx +36 -0
  463. package/src/index.ts +13 -10
  464. package/src/lib/drag-visual.ts +2 -2
  465. package/src/lib/utils.ts +19 -0
  466. package/src/patterns/element-anatomy/inline-action.spec.md +1 -1
  467. package/src/patterns/element-anatomy/item-anatomy.tsx +4 -2
  468. package/src/patterns/header-canonical/header-canonical.spec.md +9 -0
  469. package/src/patterns/header-canonical/header-canonical.stories.tsx +31 -5
  470. package/src/tokens/categorical-color.ts +5 -5
  471. package/src/tokens/color/color.spec.md +4 -4
  472. package/src/tokens/color/primitives.css +9 -2
  473. package/src/tokens/opacity/opacity.spec.md +1 -1
  474. package/src/tokens/orphan-tokens.spec.md +1 -1
  475. package/src/tokens/typography/typography.spec.md +2 -0
  476. package/src/tokens/uiSize/uiSize.css +5 -0
  477. package/src/tokens/uiSize/uiSize.spec.md +1 -1
@@ -54,7 +54,28 @@ esac
54
54
  NEW_CONTENT=$(echo "$INPUT" | jq -r '.tool_input.content // .tool_input.new_string // ""' 2>/dev/null)
55
55
 
56
56
  # DS primitive 名單(wrap 這些就觸發 anchor preflight)
57
- DS_PRIMITIVES_RE='<(Sidebar|AppShell|DataTable|Dialog|Sheet|Popover|DropdownMenu|Field|FieldControlGroup|MenuItem|ItemAvatar|ItemLabel|ItemIcon|SegmentedControl|Tabs|TabsList|TabsTrigger|Combobox|Select|DatePicker|TimePicker|TreeView|Tooltip|Coachmark|FileViewer|ScrollArea|Avatar|Badge|Button|ChromeHeader|SurfaceHeader|SurfaceBody|SurfaceFooter|OverlaySurface|NameCard|Toast|FileUpload|DescriptionList|Chart|BulkActionBar|ActionBar|Carousel|Breadcrumb)\b'
57
+ # 2026-07-16 dim 57 修 stale hardcode(含已改名 NameCard→ProfileCard、缺 InlineEdit 等 34 現役元件):
58
+ # 元件名改「機械生成」— 由 components/ dir 動態 ls 派生(hook 每 fire 跑一次 find,成本 <10ms 可接受),
59
+ # 新增/改名元件自動同步,不再靠人手維護清單。
60
+ # 非-dir primitive(patterns/ export + sub-component:MenuItem/Item* slots/TabsList/ChromeHeader/
61
+ # Surface*/OverlaySurface/ActionBar)無 dir 可派生 → 維護小清單於 _PATTERN_PRIMITIVES。
62
+ _COMPONENTS_DIR=""
63
+ for _root in "${CLAUDE_PROJECT_DIR:-}" "$(pwd)"; do
64
+ if [ -n "$_root" ] && [ -d "$_root/packages/design-system/src/components" ]; then
65
+ _COMPONENTS_DIR="$_root/packages/design-system/src/components"
66
+ break
67
+ fi
68
+ done
69
+ if [ -n "$_COMPONENTS_DIR" ]; then
70
+ _COMP_NAMES=$(find "$_COMPONENTS_DIR" -mindepth 1 -maxdepth 1 -type d -exec basename {} \; 2>/dev/null | sort | paste -sd'|' -)
71
+ fi
72
+ # 靜態 fallback(consumer fork repo 無 packages/design-system/src/ → 用 snapshot;
73
+ # 與 DS repo components/ dir 同步,新增元件必補 — snapshot 2026-07-16,63 元件)
74
+ if [ -z "${_COMP_NAMES:-}" ]; then
75
+ _COMP_NAMES='Accordion|Alert|AppShell|AspectRatio|Avatar|Badge|Breadcrumb|BulkActionBar|Button|Calendar|Carousel|Chart|Checkbox|Chip|CircularProgress|Coachmark|Combobox|Command|DataTable|DateGrid|DatePicker|DescriptionList|Dialog|DropdownMenu|Empty|Field|FieldControlGroup|FileItem|FileUpload|FileViewer|HoverCard|InlineEdit|Input|LinkInput|Menu|Notice|NumberInput|OverflowIndicator|Pagination|PeoplePicker|Popover|ProfileCard|ProgressBar|RadioGroup|Rating|ScrollArea|SegmentedControl|Select|SelectionControl|SelectMenu|Separator|Sheet|Sidebar|Skeleton|Slider|Steps|Switch|Tabs|Tag|Textarea|TimePicker|Toast|Tooltip|TreeView'
76
+ fi
77
+ _PATTERN_PRIMITIVES='MenuItem|ItemAvatar|ItemLabel|ItemIcon|TabsList|TabsTrigger|ChromeHeader|SurfaceHeader|SurfaceBody|SurfaceFooter|OverlaySurface|ActionBar'
78
+ DS_PRIMITIVES_RE="<(${_COMP_NAMES}|${_PATTERN_PRIMITIVES})\b"
58
79
 
59
80
  # 沒 wrap DS primitive → 檢「純手刻」洞(2026-07-07 治理進化方向 3 洞 b:原本此分支直接放行,
60
81
  # 「該用 primitive 卻整個手刻」反而抓不到 — 內部盤點 file:line 證據見 planning/2026-07-07-governance-evolution-roadmap.md)
@@ -8,7 +8,7 @@
8
8
  # Triggers on consumer apps/**/*.stories.tsx edit. For each story using overlay
9
9
  # primitive, verify story contains:
10
10
  # - `defaultOpen` prop OR
11
- # - `open={true|isOpen}` controlled state OR
11
+ # - controlled `open={...}` / bare `open` boolean attr(2026-07-16 dim 74 加廣)OR
12
12
  # - `play()` interaction function clicking trigger OR
13
13
  # - `// @overlay-open-skip: <rationale>` per-story escape
14
14
  # Otherwise story is「trigger-only」= visual snapshot 看不到 overlay content (per
@@ -46,8 +46,17 @@ USED=$(echo "$CONTENT" | grep -oE "<(DS\.)?($OVERLAY_PRIMITIVES)Trigger\b" | sor
46
46
  if [ -z "$USED" ]; then exit 0; fi
47
47
 
48
48
  # Detect open-state mechanism
49
+ # 2026-07-16 dim 74 regex 加廣:原只認 open={true|isOpen|isVisible} 3 個字面名 —
50
+ # 漏 controlled `open={<任意變數/expression>}`(如 open={open} / open={!collapsed})與
51
+ # bare `open` boolean attr(JSX `<Popover open>` = true)→ 合法 controlled story 被誤殺。
52
+ # - `open=\{[!a-zA-Z_]` 涵蓋任意 identifier / negation expression(含 true/isOpen/isVisible)
53
+ # - bare attr 兩形態:tag 內 `<Sheet open>` / `<Popover open onX>`(`<Tag[^<>]* open` 限同 tag,
54
+ # `[^<>]*` 不可跨 `>` → JSX 內文 / 註解 prose 的「open / close」不誤中)+ 多行 prop 排版
55
+ # 「整行只有 open」(`^\s*open\s*$`)。存量驗證:Coachmark principles(行只有 open)pass、
56
+ # dropdown-menu.anatomy prose「浮層 open / close」不誤 pass。
57
+ # - defaultOpen 原本就有,保留
49
58
  HAS_OPEN=""
50
- if echo "$CONTENT" | grep -qE 'defaultOpen|open=\{(true|isOpen|isVisible)|play:\s*async|play\(.*click'; then
59
+ if echo "$CONTENT" | grep -qE 'defaultOpen|open=\{[!a-zA-Z_]|<[A-Za-z][^<>]*[[:space:]]open([[:space:]>]|$)|^[[:space:]]*open[[:space:]]*$|play:\s*async|play\(.*click'; then
51
60
  HAS_OPEN="found"
52
61
  fi
53
62
 
@@ -96,6 +96,13 @@ case "${EVENT:-}" in
96
96
  *) exit 0 ;;
97
97
  esac
98
98
 
99
+ # 2026-07-16 dim 75 修:DS repo 本身 early-exit(對齊 r1 guard (a))。原本無此 guard →
100
+ # candidate 3(.claude-plugin/plugin.json 在 DS repo 存在)讓 r2 在 DS repo fire,
101
+ # 印 `npm run sync-all` 但 DS root package.json 無此 script(sync-all 是 fork/template 的
102
+ # consumer script,見 template/ds-product-template/package.json)= 指引斷鏈;
103
+ # 且 DS repo 是 SSOT 源頭,local 版本領先 published 是開發常態,不該 nag。
104
+ [ -d "$(pwd)/packages/design-system/src" ] && exit 0
105
+
99
106
  # Find local plugin.json (DS plugin install path)
100
107
  PLUGIN_JSON=""
101
108
  for candidate in \
@@ -119,6 +126,15 @@ REMOTE_VERSION=$(curl -sS --max-time 5 \
119
126
  if [ -z "$REMOTE_VERSION" ] || [ "$REMOTE_VERSION" = "null" ]; then exit 0; fi
120
127
 
121
128
  if [ "$LOCAL_VERSION" != "$REMOTE_VERSION" ]; then
129
+ # 2026-07-16 dim 75:指令按「指引在哪個 repo 語境印」推導,不 hardcode `npm run sync-all`
130
+ # (template-based fork 有此 script;老 fork / 部分裝態可能只有 scripts/sync-all.mjs 或都沒有)。
131
+ if jq -e '.scripts["sync-all"]' package.json >/dev/null 2>&1; then
132
+ SYNC_CMD="npm run sync-all"
133
+ elif [ -f scripts/sync-all.mjs ]; then
134
+ SYNC_CMD="node scripts/sync-all.mjs"
135
+ else
136
+ SYNC_CMD="npm install @qijenchen/design-system@beta @qijenchen/storybook-config@beta --legacy-peer-deps"
137
+ fi
122
138
  cat << EOF
123
139
 
124
140
  📦 DS governance update available:
@@ -126,7 +142,7 @@ if [ "$LOCAL_VERSION" != "$REMOTE_VERSION" ]; then
126
142
  Latest published: $REMOTE_VERSION
127
143
 
128
144
  Run in terminal (1 command):
129
- npm run sync-all # npm install @beta(治理本體)+ 刷新接線骨架(committed launchers + settings + skills);npm-only,免 plugin
145
+ $SYNC_CMD # npm install @beta(治理本體)+ 刷新接線骨架(committed launchers + settings + skills);npm-only,免 plugin
130
146
 
131
147
 
132
148
  (Per user 2026-05-27 directive「DS 增刪改自動同步」— this hook detects staleness on session start.)
@@ -41,7 +41,17 @@ CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""' 2>/dev/null)
41
41
  [ "$TOOL" != "Bash" ] && exit 0
42
42
 
43
43
  # Match: git push origin main(NOT push to working branch, NOT push --delete)
44
- if ! echo "$CMD" | grep -qE '\bgit\s+push\s+(-u\s+)?origin\s+main\b'; then
44
+ # 2026-07-16 dim 73/hooks 硬化(照 sibling inject_deploy_url_after_push.sh:43-46 已硬化 pattern 抄):
45
+ # 原 `\bgit\s+push\s+(-u\s+)?origin\s+main\b` 漏 —
46
+ # - `git -C <dir> push origin main`(-C 變體)
47
+ # - `git push --force-with-lease origin main`(任意 flag 在 origin 前)
48
+ # - `git push origin HEAD:main` / `HEAD:refs/heads/main`(refspec 變體)
49
+ # - `ENV=x git push origin main`(env-prefix)
50
+ # → 漏 fire = SSOT propagation gate 靜默失守。
51
+ _ENVP='([A-Za-z_][A-Za-z0-9_]*=[^[:space:]]+[[:space:]]+)*'
52
+ _GITPRE='git[[:space:]]+(-C[[:space:]]+[^[:space:]]+[[:space:]]+|-[A-Za-z][^[:space:]]*[[:space:]]+)*push'
53
+ _PUSHFLAGS='([[:space:]]+-{1,2}[A-Za-z][^[:space:]]*)*'
54
+ if ! echo "$CMD" | grep -qE "(^|[;&|(])[[:space:]]*${_ENVP}${_GITPRE}${_PUSHFLAGS}[[:space:]]+origin[[:space:]]+((HEAD|[^[:space:]:]+):)?(refs/heads/)?main([[:space:]]|$|[;&|)])"; then
45
55
  exit 0
46
56
  fi
47
57
  if echo "$CMD" | grep -qE 'push\s+origin\s+--delete'; then
@@ -52,8 +62,15 @@ fi
52
62
  CWD=$(pwd)
53
63
  [ ! -d "$CWD/packages/design-system/src" ] && exit 0
54
64
 
55
- # Detect SSOT-affecting diff between HEAD~1 and HEAD
56
- SSOT_DIFF=$(git diff --name-only HEAD~1 HEAD 2>/dev/null | grep -E '^(packages/design-system/src/|packages/storybook-config/(addons/|addons-preset\.ts|preview\.tsx|package\.json)|\.claude/(rules|hooks|skills|commands|references)/|\.claude-plugin/(plugin|marketplace)\.json|hooks/hooks\.json|CLAUDE\.md)' || true)
65
+ # Detect SSOT-affecting diff in the pushed commit range
66
+ # 2026-07-16 硬化:原 HEAD~1..HEAD 只看最後 1 commit push 多 commit(fast-forward 累積 /
67
+ # bump+fix 連發)時漏偵測前面 commits 的 SSOT paths。理想是 @{u}..HEAD,但 PostToolUse 跑在
68
+ # push 成功「之後」,remote-tracking ref 已更新到 HEAD → @{u}..HEAD 恆空,不可用。
69
+ # 保守改 HEAD~5..HEAD(單次 push >5 commits 在 squash-merge solo workflow 極罕見;
70
+ # 淺 history(<5 commits)fallback root commit,不炸)。
71
+ RANGE_BASE=$(git rev-parse --verify --quiet HEAD~5 2>/dev/null || git rev-list --max-parents=0 HEAD 2>/dev/null | head -1)
72
+ [ -z "$RANGE_BASE" ] && RANGE_BASE="HEAD~1"
73
+ SSOT_DIFF=$(git diff --name-only "$RANGE_BASE" HEAD 2>/dev/null | grep -E '^(packages/design-system/src/|packages/storybook-config/(addons/|addons-preset\.ts|preview\.tsx|package\.json)|\.claude/(rules|hooks|skills|commands|references)/|\.claude-plugin/(plugin|marketplace)\.json|hooks/hooks\.json|CLAUDE\.md)' || true)
57
74
 
58
75
  [ -z "$SSOT_DIFF" ] && exit 0
59
76
 
@@ -69,7 +86,7 @@ PKG_VERSION=$(jq -r '.version' "$CWD/packages/design-system/package.json" 2>/dev
69
86
  MSG=$(cat <<EOF
70
87
  🔄 SSOT propagation gate(post push origin main):
71
88
 
72
- 📊 偵測:HEAD~1..HEAD 含 $SSOT_COUNT 個 SSOT-affecting file changes
89
+ 📊 偵測:${RANGE_BASE:0:12}..HEAD(push range,保守 ≤5 commits)含 $SSOT_COUNT 個 SSOT-affecting file changes
73
90
  📦 目前 npm version:$PKG_VERSION
74
91
  🎯 AI 必「全自動執行」(不需 user 再問 / 再確認 — per Step 5.5 2026-06-02 user directive Option A):
75
92
  bump → release:preflight → tag → push tag → Release workflow → npm publish → npm view 驗證
@@ -194,11 +194,23 @@ if [ -z "$URLS_FOUND" ] && [ -f "$CWD/netlify.toml" ]; then
194
194
  # Branch preview:always use `<branch>--<sitename>` pattern,but sitename unknown unless USER_OVERRIDE
195
195
  if [ -n "$USER_OVERRIDE" ]; then
196
196
  SITENAME=$(echo "$USER_OVERRIDE" | sed -E 's|https?://([^.]+)\.netlify\.app.*|\1|')
197
- CANDIDATE="https://${BRANCH}--${SITENAME}.netlify.app"
197
+ # 2026-07-17 bug 修:DNS 單標籤硬上限 63 字元。`<branch>--<site>` 超過 → 該子網域**無法存在**
198
+ # (curl 連 header 都收不到,非 404)。舊版直接拼不截斷 → 長 branch 名吐「物理上不可能」的網址,
199
+ # verify 失敗後還印該 URL 誤導 user。修:超長時截 branch + 誠實標示「branch 名太長,預覽不可靠」。
200
+ BRANCH_SLUG=$(echo "$BRANCH" | tr '[:upper:]' '[:lower:]' | sed -E 's/[^a-z0-9-]/-/g; s/-+/-/g')
201
+ BUDGET=$(( 63 - ${#SITENAME} - 2 ))
202
+ TRUNCATED=0
203
+ if [ ${#BRANCH_SLUG} -gt $BUDGET ]; then
204
+ BRANCH_SLUG=$(echo "${BRANCH_SLUG:0:$BUDGET}" | sed -E 's/-+$//')
205
+ TRUNCATED=1
206
+ fi
207
+ CANDIDATE="https://${BRANCH_SLUG}--${SITENAME}.netlify.app"
198
208
  if [ "$(verify_url "$CANDIDATE")" = "OK" ]; then
199
209
  URLS_FOUND="${URLS_FOUND}🔍 Netlify PREVIEW(${BRANCH}): ${CANDIDATE} ✅ verified 200\n"
210
+ elif [ $TRUNCATED -eq 1 ]; then
211
+ URLS_FOUND="${URLS_FOUND}⚠️ branch 名太長(『${BRANCH}』+ --${SITENAME} 超過 DNS 63 字元)→ Netlify 建不出預覽子網域;截斷版 ${CANDIDATE} 也未命中。可靠做法:縮短 branch 名(≤${BUDGET} 字元)重推,或合 main 後看正式站 https://${SITENAME}.netlify.app\n"
200
212
  else
201
- URLS_FOUND="${URLS_FOUND}🔍 Netlify PREVIEW 推導: ${CANDIDATE} ⚠️ 404(preview 未啟 OR build pending — Netlify build 2-3 min)\n"
213
+ URLS_FOUND="${URLS_FOUND}🔍 Netlify PREVIEW 推導: ${CANDIDATE} ⚠️ 未命中(preview 未啟 / build pending / 此 branch 未啟 branch-deploy Netlify Dashboard Deploys)\n"
202
214
  fi
203
215
  else
204
216
  URLS_FOUND="${URLS_FOUND}🔍 Netlify PREVIEW(${BRANCH}) — sitename 未知;設 \$HOME/.claude/local/deploy-targets.json 後 hook 可推 preview URL\n"
@@ -48,9 +48,9 @@ fi
48
48
  REMINDERS="${MEMSYNC_NOTE:-}"
49
49
  BLOCKERS=""
50
50
 
51
- # Check 1: CLAUDE.md size(soft 800 / hard 1000)
51
+ # Check 1: bootstrap size(AGENTS.md + CLAUDE.md 合計;PNG 2026-07-16 治理核心遷 AGENTS.md)
52
52
  if [ -f CLAUDE.md ]; then
53
- LINES=$(wc -l < CLAUDE.md | tr -d ' ')
53
+ LINES=$(( $(wc -l < CLAUDE.md | tr -d ' ') + $( [ -f AGENTS.md ] && wc -l < AGENTS.md | tr -d ' ' || echo 0 ) ))
54
54
  # 2026-04-26 tightened thresholds(對應 M19 + user 質問「auto self-improve」要更主動):
55
55
  # SSOT alignment per CLAUDE.md L35: target ≤ 200 / transition ≤ 400 / hard cap 800
56
56
  # Stratified soft warnings: 500 approaching / 600 strong / 800 hard-cap blocker
@@ -279,6 +279,14 @@ fi
279
279
  if [ -f package.json ] && grep -q '"@qijenchen/design-system"' package.json 2>/dev/null && [ ! -d node_modules/@qijenchen/design-system ]; then
280
280
  ENV_SMOKE="${ENV_SMOKE}\n - Consumer repo 引用 @qijenchen/design-system 但 node_modules 沒裝(跑 npm install)。"
281
281
  fi
282
+ # (e) 長駐 bypass env 偵測(2026-07-16 加):CLAUDE_BYPASS_* 設計為單次 audit-logged escape,
283
+ # session 進程繼承殘留(export 後沒 unset / shell profile 誤設)= 對應 approval / anchor / solo-workflow
284
+ # 閘每次 edit 都靜默放行 = 治理失效。泛掃 CLAUDE_BYPASS_ prefix(機械生成精神,新 bypass var 自動涵蓋;
285
+ # 已知住戶:DESIGN_APPROVAL / SOLO_WORKFLOW / DS_ANCHOR / MAIN_WORKBENCH / ESCAPE_MARKER_AUDIT 等)。
286
+ LINGERING_BYPASS=$(env 2>/dev/null | grep -E '^CLAUDE_BYPASS_[A-Z_]+=' | grep -vE '=0?$' | cut -d= -f1 | sort | paste -sd, -)
287
+ if [ -n "${LINGERING_BYPASS:-}" ]; then
288
+ ENV_SMOKE="${ENV_SMOKE}\n - ⚠ bypass env 長駐,approval 閘失效中:${LINGERING_BYPASS}(bypass 應單次使用即 unset;跑 \`unset ${LINGERING_BYPASS%%,*}\` 或檢查 shell profile / 啟動環境是否誤 export)。"
289
+ fi
282
290
  if [ -n "$ENV_SMOKE" ]; then
283
291
  PRUNE_TRIGGERS="${PRUNE_TRIGGERS}\n- 🩺 env-smoke(non-blocking,環境健檢):${ENV_SMOKE}"
284
292
  fi
@@ -0,0 +1,20 @@
1
+ # Certified Surface Registry(PNG ADR-5;SSOT)
2
+
3
+ **規則**:每個 AI provider × surface 的治理支援度**只能由實測證據升級**;未測 = Uncertified,禁推定。三態:
4
+ - **Certified** — 原生機制完整實測(instructions/rules/hooks discovery + gates)
5
+ - **Certified-equivalent** — 原生機制不足,但 provider-neutral verifier(release:preflight + CI)達成相同 rule coverage 與 blocking outcome,無 Critical 弱化
6
+ - **Uncertified** — 缺實測證據;可產草稿,**不得**宣稱合規/取得 attestation/發佈
7
+
8
+ **最終 authority(所有 surface 共通)**:`npm run release:preflight`(~30 deterministic gates)+ CI(release.yml/ci.yml)— 任何 surface 的不合規產出無法發佈。此層與 surface 無關,故「Uncertified surface 產的草稿」仍會在 merge/release 被同一套擋下(fail-closed)。
9
+
10
+ | Provider | Surface | 狀態 | 原生機制實測 | 等效控制 | 證據 | 日期 |
11
+ |---|---|---|---|---|---|---|
12
+ | Claude Code | local CLI/desktop | **Certified** | CLAUDE.md(@AGENTS.md import)+ .claude/rules path-scoped + hooks 4 events + skills/commands 全量日常運行 | preflight+CI | 本 repo 全程開發史;hook fire logs;**@AGENTS.md import live canary PASS(2026-07-17,headless 全新 session 禁工具答出 canonical 內容 + cite AGENTS.md:4)** | 2026-07-17 |
13
+ | Claude Code | cloud/web(sandbox) | **Certified-equivalent** | committed `.claude` 4 hook events fire 實測 ✓;plugin **不可靠**(官方 issue #63028/#62174)→ 治理不依賴 plugin | preflight+CI | memory `reference_cloud_governance_loading.md`(2026-06-16 + 2026-07-14 端到端蓋章) | 2026-07-14 |
14
+ | OpenAI Codex | CLI local(exec) | **Certified-equivalent** | AGENTS.md 原生 discovery ✓(canary 不讀檔答出「release:preflight與CI」);repo skills `.agents/skills/` ✓(P2.2 probe:`design-system:independent-review` 原生列出);repo hooks `.codex/hooks.json` ✓ 可 block(P2.1 probe C exit-2)+ P2.2 生成版 live fire ✓(codex 檔案寫入 → 投影 hook fire-log +1;另實測 schema strict:top-level 只准 `description`/`hooks`,unknown field → 整檔靜默不載)**但有 per-hook hash trust 閘:未 trust 非互動 exec 靜默跳過(fail-open)→ hooks 僅加速器,生效需 user TUI `/hooks` 一次 trust 或 `--dangerously-bypass-hook-trust`(hook 檔一改 hash 變 → 需重 trust)** | preflight+CI + codex-run-guarded 失敗守衛 + freshness 閘 | commit d88ceac2 canary;P2.1 probe A/B/C(`.claude/planning/2026-07-16-png-p2-codex-research.md`);P2.2 skills probe `/tmp/png-p22-skills-probe-out.txt`(2026-07-16) | 2026-07-16 |
15
+ | OpenAI Codex | cloud / IDE / app | **Uncertified** | 未實測(載入哪些 repo config 未知) | —(preflight/CI 仍擋 merge/release) | 無 | — |
16
+ | 其他 AGENTS.md 相容 agent(Cursor/Copilot/Jules…) | 各自 | **Uncertified** | AGENTS.md 標準宣稱支援,本 repo 未逐一實測 | preflight+CI | agents.md 標準頁(宣稱層) | — |
17
+
18
+ **升級程序**:(1) 官方文件 cite;(2) 本 repo live 實測(canary probe / clean-room);(3) 記錄 provider+版本+日期+證據;(4) 更新本表同 commit。**降級**:發現 regression(如 provider 改版 discovery 變更)→ 立即降 Uncertified + 記錄。
19
+
20
+ **Fork/template consumer surfaces**:consumer repo 的 Claude 治理 = C-prime corpus(實測蓋章 2026-07-14);consumer 的 Codex 治理 = **P2.4 已投影 + P2.4b 已接線**(fork corpus `AGENTS.md` + `codex/hooks.json` + `codex/agents/skills/independent-review` + template checked-in `AGENTS.md`;既有 fork 經 `npm run sync-all` 送達 `.codex`/`.agents`/`AGENTS.md` 到 fork root — marker 政策 generated→刷新 / consumer-owned→不碰,harness 4h 斷言 2026-07-17),**consumer 端 live 實測前仍 Uncertified**(P4.4 clean-room 排程)。
@@ -0,0 +1,5 @@
1
+ {
2
+ "gateCount": 51,
3
+ "updated": "2026-07-18",
4
+ "note": "合法 retire gate 需同 commit 更新本檔 + preflight 檔內記 retire 理由"
5
+ }
@@ -2,7 +2,7 @@
2
2
  "_meta": {
3
3
  "purpose": "Explicit semantic mapping: principle (M-rule / trait / hook) → audit dim cover",
4
4
  "ssot": ".claude/memory/feedback_audit_preflight_全盤查.md + design-system-audit/SKILL.md",
5
- "updated": "2026-05-18",
5
+ "updated": "2026-07-16",
6
6
  "version": "1.0",
7
7
  "_principle": "禁 heuristic match;每原則必 explicit dim list。新原則加入必同 commit 加 entry,違 = hook BLOCK"
8
8
  },
@@ -536,6 +536,24 @@
536
536
  71
537
537
  ],
538
538
  "note": "2026-07-03 entry add per audit-preflight gap:write-time 攔隱式 wrap;audit-time dim 71 primitive misuse + A.1b composition cover"
539
+ },
540
+ "dynamic_tailwind_class": {
541
+ "dims": [
542
+ 18
543
+ ],
544
+ "note": "動態拼 Tailwind class 不被掃描 silent 失效(2026-07-09 hook;dim 18 token hygiene 家族 cover;2026-07-16 PNG 補 entry)"
545
+ },
546
+ "ssot_header_declaration": {
547
+ "dims": [
548
+ 5
549
+ ],
550
+ "note": "新 production tsx 必帶「── 消費的 SSOT ──」段(2026-07-07 hook;dim 5 SSOT 消費 cover;2026-07-16 補 entry)"
551
+ },
552
+ "story_determinism": {
553
+ "dims": [
554
+ 46
555
+ ],
556
+ "note": "story 禁 Date.now/Math.random 非決定性(2026-07-09 hook;dim 46 cover;2026-07-16 補 entry)"
539
557
  }
540
558
  },
541
559
  "newDims_2026_05_17": {
@@ -610,4 +628,4 @@
610
628
  }
611
629
  ]
612
630
  }
613
- }
631
+ }
@@ -12,8 +12,9 @@
12
12
  | `onDismiss` | **通知被忽略** — 暫時訊息被關,不影響流程 | Alert / Notice / Toast / Coachmark | Polaris `Toast.onDismiss` / iOS `dismiss()` |
13
13
  | `onRemove` | **從集合移除 item** — parent collection 狀態變化 | PeoplePicker / Combobox multi-select tag / Tag(in list) | Material `Chip.onDelete` / React Aria `onRemove` |
14
14
  | `onClear` | **欄位內容清空** — value 設 empty,元件不關 | Input / Select / Combobox / DatePicker clear | Ant `allowClear` + `onClear` / Polaris `clearButton` |
15
+ | `onClearSelection` | **清空多選集合** — 取消所有勾選項(非清欄位內容)| BulkActionBar | Polaris `ResourceList` bulk clear / Material DataGrid `onRowSelectionModelChange([])` |
15
16
 
16
- **禁止**:用同一名 cover 多語意(`onClose` 同時表達 Tag 的 `onRemove`)。spec 寫 callback 時必明示哪一類。
17
+ **禁止**:用同一名 cover 多語意(`onClose` 同時表達 Tag 的 `onRemove`;`onClear` 同時表達「清欄位」與「清勾選」→ 後者必用 `onClearSelection`,2026-07-18 決策12)。spec 寫 callback 時必明示哪一類。
17
18
 
18
19
  ## Badge 類 prop 名 canonical(按放置,不按「是 badge」籠統命名)
19
20
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  | Interface | Owner spec | Canonical sentence | Drift status | Last divergence event |
14
14
  |---|---|---|---|---|
15
- | **DataTable body cell internal indicator**(display endAction / clear / edit indicator)| `data-table.spec.md`「Body cell internal」row + `inline-action.spec.md`「DataTable body cell internal」row | 「Body cell internal = Field family endAction(自動繼承)」「Field display 元件已對齊」 | ✅ aligned:2026-05-09 D-path retired — `getEditIndicator(colType)` parallel system 移除,indicator authority 移交 Field naked-display `showDisplayEndIcon` opt-in,cellEl 不再 render parallel indicator(見 data-table.tsx「D-path retired」註解);2026-07-08 A 案:cell-registry 預設不再傳(display 態零恆顯 icon,prop 留 opt-in 逃生門,見 field.spec L6 v16)| 2026-05-08 round 5 → 2026-05-09 resolved |
15
+ | **DataTable body cell internal indicator**(view endAction / clear / edit indicator)| `data-table.spec.md`「Body cell internal」row + `inline-action.spec.md`「DataTable body cell internal」row | 「Body cell internal = Field family endAction(自動繼承)」「Field view 元件已對齊」 | ✅ aligned:2026-05-09 D-path retired — `getEditIndicator(colType)` parallel system 移除,indicator authority 移交 Field naked view `showDisplayEndIcon` opt-in(prop 名保留),cellEl 不再 render parallel indicator(見 data-table.tsx「D-path retired」註解);2026-07-08 A 案:cell-registry 預設不再傳(view 態零恆顯 icon,prop 留 opt-in 逃生門,見 field.spec L6 v16)| 2026-05-08 round 5 → 2026-05-09 resolved |
16
16
  | **Field naked variant state ring**(hover / focus / open / error)| `field-wrapper.tsx` cva compoundVariants(v13.3)+ `field.spec.md`「focus dominates」段 | 「SSOT 在 field-wrapper.tsx 三 compoundVariant — 改一處全 control + cell + variant 跟動」 | ✅ aligned(2026-05-08 D path canary 違反後 revert)| 2026-05-08 round 4(D path canary 違反 SSOT,已 revert `f0faab9`)|
17
17
  | **Row prefix/suffix slot**(`<ItemPrefix>` / `<ItemSuffix>`)| `patterns/element-anatomy/item-anatomy.spec.md:175+190` | 「row prefix/suffix slot 必走 patterns/element-anatomy L1 primitive」「`h-[1lh] shrink-0 flex items-center` 普世正確」 | ✅ aligned(hook `check_pattern_invariants.sh` C.4 enforce)| — |
18
18
  | **Inline action gap**(ItemInlineAction sibling spacing)| `patterns/element-anatomy/inline-action.spec.md`「多個 inline action 間距」段 | 「inline-action 跟 sibling gap 必 = `gap-2`(8px)」 | ✅ aligned(hook C.2 enforce)| — |
@@ -20,7 +20,7 @@
20
20
  | **Color tokens**(primitive vs semantic)| `tokens/color/color.spec.md`(架構流派定位)+ `tokens/color/semantic.css` | 「禁 primitive 色名作 utility,用 semantic alias」 | ✅ aligned(hook `check_naming_and_abstraction.sh` D.3 enforce)| — |
21
21
  | **Layout space**(region/element + 親疏三級)| `tokens/layoutSpace/layoutSpace.spec.md` v6(原 memory `feedback_layout_v6_canonical.md` 已 retire)| 「region/element + bounded/unbounded + 親疏三級」 | ✅ aligned(2026-05-01 flush variant retire)| 2026-05-01 |
22
22
  | **DataTable scroll**(3-region synced + cross-OS scrollbar)| `data-table.spec.md:245-251` | 「center body 用 native overflow-x-auto(非 ScrollArea),pinned column 三 region 同步」 | ✅ aligned(v15.13 interim CSS parity for Windows Bug H,deferred ScrollArea full migration)| 2026-04-30 / 2026-05-07 |
23
- | **Cell display vs edit content position**(picker offset)| `field.spec.md`「Layout Family 4」段 + `data-table.spec.md`「Body cell internal」row | 「Field control display + edit 共用同 wrapper geometry」 | partial:DataTable cell 場景已對齊(D-path `showDisplayEndIcon` opt-in 走 Field naked-display);standalone `mode="display"` bare-span(documented deferral,見 select.tsx 檔頭 `@renderer-symmetry-allow`)| 2026-05-07~08 round 1-5 → 2026-05-09 D-path 部分解決 |
23
+ | **Cell view vs edit content position**(picker offset)| `field.spec.md`「Layout Family 4」段 + `data-table.spec.md`「Body cell internal」row | 「Field control view + edit 共用同 wrapper geometry(Model A:view×default = edit 幾何減 chrome,保留 px/py)」 | aligned:DataTable cell 場景走 Field naked(`showDisplayEndIcon` opt-in);standalone `mode="view"` view×default = edit 幾何減 chrome(2026-07-16 Model A,原 bare-span deferral 已兌現;值內容層 4-mode 共享 renderer,見 select.tsx 檔頭 `@renderer-symmetry-allow`)| 2026-05-07~08 round 1-5 → 2026-07-16 Model A resolved |
24
24
  | **Field state machine focus dominates**(v13.3)| `field-wrapper.tsx` cva compoundVariants + `field.spec.md`「focus dominates」段 + `check_field_family_invariants.sh` A.3 | 「focus dominates everything;naked 不寫平行 outline ring」 | ✅ aligned;hook A.3 enforce | 2026-05-06 v9-v13.3 5 round refinement |
25
25
  | **Solo dev workflow**(1 chat = 1 branch / Netlify gate / squash merge)| `feedback_solo_dev_workflow.md` + CLAUDE.md「Git solo-work canonical」 | 「1 chat = 1 working branch;Netlify preview = user gate;『push / OK』trigger 才 merge main」 | ✅ aligned(M28 + hook `check_solo_workflow.sh`)| 2026-05-08 M28 codify |
26
26
  | **Wrapper-vs-primitive schema unify**(SelectOption / MenuItemProps 等)| `SelectMenu/select-menu.tsx` SelectMenuOption + `Combobox/combobox.tsx` extends + `PeoplePicker/people-picker.tsx` extends | 「wrapper API schema 必 `extends primitive`,wrapper 內部 mapping 必 forward 全 primitive surface field(M30)」 | ✅ aligned(2026-05-10 Round 1 commit `561945b` Combobox extends + forward 全 field;PeoplePicker 對齊 + hook `check_wrapper_primitive_schema_drift.sh` BLOCKER)| 2026-05-10 M30 codify |
@@ -86,9 +86,9 @@
86
86
  {
87
87
  "id": "datatable-always-edit-cell",
88
88
  "regex": "cell:[^;]{0,160}<(DS\\.)?(Select|Combobox|PeoplePicker|DatePicker|TimePicker)\\b",
89
- "unlessRegex": "onCellCommit|editable|mode=[\"']display",
89
+ "unlessRegex": "onCellCommit|editable|mode=[\"']view",
90
90
  "severity": "block",
91
- "rationale": "cell: 直接渲染恆-edit 控件 = display 態渲染 edit chrome,違 data-table.spec.md:373 indicator A 案(display 零恆顯 + hover outline + meta.editable/onCellCommit)。custom cell 元件包裹的同違規 regex 看不進去 → 由 product-ui-audit judgment 兜底(failure-class registry always-edit-cell)"
91
+ "rationale": "cell: 直接渲染恆-edit 控件 = view 態渲染 edit chrome,違 data-table.spec.md:373 indicator A 案(view 零恆顯 + hover outline + meta.editable/onCellCommit)。custom cell 元件包裹的同違規 regex 看不進去 → 由 product-ui-audit judgment 兜底(failure-class registry always-edit-cell)。2026-07-16 dim 54:mode display→view 更名後 unlessRegex stale(0 hit)→ 對齊 view"
92
92
  }
93
93
  ]
94
94
  },
@@ -22,7 +22,7 @@ paths:
22
22
 
23
23
  | Repo / Path | Title pattern | 用途 |
24
24
  |---|---|---|
25
- | **DS repo** `packages/design-system/**/*.stories.tsx` | `Design System/{Tokens|Patterns|Components|Internal}/{Name}/{展示|設計規格|設計原則}` | DS 元件 / token / pattern building block |
25
+ | **DS repo** `packages/design-system/**/*.stories.tsx` | `Design System/{Tokens|Patterns|Components|Internal|Internal Patterns}/{Name}/{展示|設計規格|設計原則}` | DS 元件 / token / pattern building block |
26
26
  | **Consumer apps**(template / fork repos)`apps/**/*.stories.tsx` | `Apps/{app-kebab-name}/{Page Purpose}` | 產品 UI composition demo(eg. `Apps/order-dashboard/AppShell Dashboard`)|
27
27
 
28
28
  **Why 不統一**:DS 是 building block library(可重用元件),consumer apps 是 product UI 真實 composition demo(整頁、整 flow)。Namespace 不同 = Storybook sidebar 兩塊清楚分區。
@@ -28,9 +28,10 @@ paths:
28
28
 
29
29
  **Folder + storybook canonical**:
30
30
  - public:`components/<Name>/` OR `patterns/<name>/`(frontmatter 無 `internal: true`),storybook title `Design System/Components/<Name>/...` OR `Design System/Patterns/<Name>`
31
- - internal:in-place `components/<Name>/` 或 `patterns/<name>/` + frontmatter `internal: true` / `- isInternal`(主路徑;現行 11 個 internal 單元全走 frontmatter,`components/Internal/<Name>/` folder 路線同樣支援但目前無住戶),storybook title `Design System/Internal/<Name>/...` OR `Design System/Internal Patterns/<Name>`(end-user 設計師 default 過濾掉,DS contributor 看 reference 用)
31
+ - internal:in-place `components/<Name>/` 或 `patterns/<name>/` + frontmatter `internal: true` / `- isInternal`(主路徑;現行 10 個 internal 單元全走 frontmatter,`components/Internal/<Name>/` folder 路線同樣支援但目前無住戶),storybook title `Design System/Internal/<Name>/...` OR `Design System/Internal Patterns/<Name>`(end-user 設計師 default 過濾掉,DS contributor 看 reference 用)
32
32
  - export jsDoc 加 `@internal` marker(IDE intellisense 警示 end-user)
33
33
  - **Root barrel front-door 排除(2026-06-05 dim-72 SSOT,user Q2 拍板)**:internal 元件/pattern **不進** `packages/design-system/src/index.ts`(root barrel = 直接 front-door),**只**經 per-component subpath `@qijenchen/design-system/{components,patterns}/<Dir>` 取用 —— 對應 user 原則「internal 要**另外包裝過 + 自行確認**才可用,不得直接 front-door 使用;public 才可直接用」。SSOT = spec frontmatter isInternal;機械 = `gen-design-system-barrel.mjs`(生成時自動排除)+ `--check`(release:preflight drift gate)。改 public/internal → 改 frontmatter 後重跑 generator。
34
+ - **符號級 `@internal` 排除(2026-07-18 決策3)**:public 元件內個別 export 若帶 `/** @internal */` JSDoc tag(如 `ButtonGroupContext` / `floatingLayerClass` / `RowSizeProvider` / `ItemInlineAction(Button)` 等私有 context/helper/primitive),generator 亦排除出 root front-door(subpath `export *` 仍有,DS 內部 relative import 不受影響)。對齊 TS `stripInternal` / MUI `@ignore` / API-Extractor `@internal` release tag。**偵測鐵律**:`@internal` 必為 JSDoc(`/** */`)tag(行首),`//` line-comment prose 提及不算(否則自身 doc 提及兄弟 `@internal` 的 public 型別如 `FieldVariant` 會被誤殺)。加/移私有符號的 front-door 排除 → 改該 export 的 `@internal` marker 後重跑 generator。
34
35
 
35
36
  **對齊世界級**:Polaris 「Building blocks」(public) vs「layout primitives」(internal)/ Material UI `@mui/material`(public)vs `@mui/utils` `@mui/system`(internal hooks/primitives)/ Atlassian `@atlaskit/<component>`(public)vs internal `<unstyled>` primitives / Carbon turnkey components + internal utilities / Apple HIG「Presented controls」vs「implementation primitives」 共識。
36
37
 
@@ -43,7 +43,7 @@ ls -la ~/.codex/auth.json # 3 Auth(
43
43
 
44
44
  **Decision**:1 ✅ → local CLI(canonical per `references/transport.md:36-40`)/ 1 ❌ + 2 ✅ → global / 1+2 ❌ + 3 ✅ → `npm install`(`@openai/codex` 已 npm dep)/ 全 ❌ → 報 user。**禁 fallback Explore agent 當 codex**(M31 違反:Explore 同模型,不滿足 dual-track 第 2 bias)。
45
45
 
46
- **Anti-pattern**:`which codex` 失敗就斷言 unreachable → 嘗試 sudo install / 繞 M28 開 PR / Explore 替身。詳 `.claude/memory/feedback_codex_local_transport_node_modules.md`。
46
+ **Anti-pattern**:`which codex` 失敗就斷言 unreachable → 嘗試 sudo install / 繞 M28 開 PR / Explore 替身。詳 `.claude/memory/feedback_codex_exec_transport_canonical.md`。
47
47
 
48
48
  **Hook 機械強制**:`stop_self_audit.sh` 偵測「codex/dual-track/比稿 keyword + 無 `node_modules/.bin/codex` cmd trace」→ BLOCKER。
49
49
 
@@ -64,7 +64,7 @@ ls -la ~/.codex/auth.json # 3 Auth(
64
64
  | Step | Claude | Codex | 共通 invariant |
65
65
  |---|---|---|---|
66
66
  | **1 各自熟讀** | grep / read spec.md / canonical / source 真讀 | `exec -s read-only` grep / git show / read source | 憑印象 propose = M31 違反 |
67
- | **2 各自驗證** | `npx tsc -b` + invariant + audit script | **audit-verify**:`exec --dangerously-bypass-approvals-and-sandbox -C $PWD`(user-authorize)跑**同樣** tsc / invariant / .mjs / Playwright + 貼 stdout(per `references/phase-b-codex-brief.md` B.0.1);**純讀**:`exec -s read-only` grep / git show | 任一方未跑真 verify 撤回;**禁** codex 只目測機械維度(verify 不對稱違 M31 Step 2)|
67
+ | **2 各自驗證** | `npx tsc -b` + invariant + audit script | **audit-verify**:`exec --dangerously-bypass-approvals-and-sandbox -C $PWD`(user-authorize)跑**同樣** tsc / invariant / .mjs / Playwright + 貼 stdout(per `../deep-audit-cross-codex/references/phase-b-codex-brief.md` B.0.1);**純讀**:`exec -s read-only` grep / git show | 任一方未跑真 verify 撤回;**禁** codex 只目測機械維度(verify 不對稱違 M31 Step 2)|
68
68
  | **3 各自視覺稽核** | playwright screenshot + DOM + pixel audit | code-read + diff + grep visual path | 只 code 跳 visual 違反 user directive |
69
69
  | **4 各自 cite-based propose** | 3-column:`spec.md path:line / 引文 / reasoning` | 同上獨立出 | hand-wave 無 cite 撤回 |
70
70
  | **5 整合完美版本**(NOT pass-through)| Agree → synthesize 補對方缺漏;Disagree → cite battle verify 對方 cite + counter-cite | 同上雙向 | **絕禁** Claude pass-through codex / 只一方驗證跳整合 |
@@ -108,7 +108,7 @@ User 說「跟 codex 討論 X」或本 skill 自動 trigger condition 滿足。
108
108
 
109
109
  ### Step 0.1:**DS Anchor Preflight**(M29 mandatory,2026-05-08)
110
110
 
111
- Brief 前必查 `.claude/references/ssot-index.md` + grep `*.spec.md` 找 anchor canonical,brief 內含 **3-column owner table**(`Candidate owner spec` / `Canonical sentence` / `Conflicting code/comment`)。**若 spec ≠ code → STOP 寫 RFC**(`.claude/planning/<topic>-rfc.md`),等 user 拍板才進 Step 0.5。詳 `.claude/memory/feedback_ds_anchor_preflight.md`。
111
+ Brief 前必查 `.claude/references/ssot-index.md` + grep `*.spec.md` 找 anchor canonical,brief 內含 **3-column owner table**(`Candidate owner spec` / `Canonical sentence` / `Conflicting code/comment`)。**若 spec ≠ code → STOP 寫 RFC**(`.claude/planning/<topic>-rfc.md`),等 user 拍板才進 Step 0.5。詳 `.claude/rules/meta-patterns.md` M29。
112
112
 
113
113
  ### Step 0.5:**Claude own-version v1 + dimension matrix**(合併原 Step 0.5+0.6,anti-pass-through)
114
114
 
@@ -154,19 +154,19 @@ target PR:當前 working branch 的 PR(`mcp__github__list_pull_requests` 找到
154
154
 
155
155
  `mcp__github__subscribe_pr_activity` → 等 webhook event,**不 poll**(Anthropic best-practice,等推送)。
156
156
 
157
- ### Step 4:Codex 回覆 → Claude 自檢(M22/M23/M27/M8)
157
+ ### Step 4:Codex 回覆 → Claude 自檢(M22/M23/M23(c)/M8)
158
158
 
159
159
  收到 codex reply 必跑 4 題自檢(避免 codex 也犯 M1/M22 錯):
160
160
  1. **M22 cite check**:codex 引的 benchmark 有 inline source?無 → reply 要求補
161
161
  2. **M23 DS-first**:codex 建議是否覆蓋 DS 既有 canonical?有 → 我手動驗 DS spec/token
162
- 3. **M27 namespace**:codex 建議 prop name 是否撞 DS 既有?
162
+ 3. **M23(c) namespace**(former M27):codex 建議 prop name 是否撞 DS 既有?
163
163
  4. **M8 ≥3 source**:codex 只引 1 家 → reply 要求補到 3 家
164
164
 
165
165
  任一題失敗 → Step 4.5 仍要跑(自檢結果記下),Step 5 一併 report。
166
166
 
167
167
  ### Step 4.5:**獨立 verify codex 具體 claim**(不可省 — anti-pass-through)
168
168
 
169
- **Why**:Step 4 只 check 表面 cite,不 verify codex 結論。錨 2026-05-07 `775d879` pass-through + 2026-05-19 6+ 條讀前 N 行就斷 truncated(SSOT `memory/codex_collab_backfill_2026-05-19.md`)
169
+ **Why**:Step 4 只 check 表面 cite,不 verify codex 結論。錨 2026-05-07 `775d879` pass-through + 2026-05-19 6+ 條讀前 N 行就斷 truncated。
170
170
  **強制動作**(逐條 claim):
171
171
  0. **Last-verdict gate**(MUST 先跑):`tail -n 240 reply.md` grep `Verdict|tokens used|採納` 必命中;Read `--offset=$((total-240)) --limit=240`。禁讀前 N 行就斷 truncated。
172
172
  1. **Grep DS-internal**:codex 指的 file/token/pattern 真存在?`grep -rn` 確認
@@ -205,7 +205,7 @@ target PR:當前 working branch 的 PR(`mcp__github__list_pull_requests` 找到
205
205
  - **重啟**(兩邊都不對 → 重新做)
206
206
  3. 列 final 方案,不再列 A/B/C 給 user 拍 unless 真歧義
207
207
 
208
- **強制 reply format**:Step 4 self-check(M22/M23/M27/M8)+ 4.5 verify 表 + 4.6 regression scan 表 + 5 接受/拒絕/修正 + final action(僅真歧義列 options)。錨例 `029b647` `f24998f` `775d879`。
208
+ **強制 reply format**:Step 4 self-check(M22/M23/M23(c)/M8)+ 4.5 verify 表 + 4.6 regression scan 表 + 5 接受/拒絕/修正 + final action(僅真歧義列 options)。錨例 `029b647` `f24998f` `775d879`。
209
209
 
210
210
  ### Step 6:User approve → Claude 實作
211
211
 
@@ -37,10 +37,14 @@ N. <SSOT 是否該抽到更上層 primitive?>
37
37
  - Counter-proposal request:挑戰我的 hypothesis,提第 4 條路
38
38
  - 必產 3-column cite table(claim / path:line / reasoning)
39
39
 
40
- ## 🚨 invariant — 2026-05-23 user 永久 directive(缺一 = brief 不合格)
40
+ ## 🚨 invariant — 2026-05-23 user 永久 directive + 2026-07-10「任務/資訊/判準對等」directive(缺一 = brief 不合格,hook check_codex_brief_invariants.sh BLOCK)
41
41
  1. **全盤閱讀全部 source**(CLAUDE.md / 31 active M-rules / 5 rules/*.md / 91 audit dims SKILL.md / 全部 spec.md / 全部 stories / 全部 components / tokens / patterns / hooks / 全部 memory files / planning),**禁憑記憶**(spec/story/component/memory 數量隨時變動,故不硬編數字 — 一律「全部」;M-rule / audit-dim 數由 sync-governance-counters 機械守住)
42
42
  2. **Triple-verify per finding**:(a) grep DS-wide 確認 pattern 存在 (b) Read 對應 spec.md / tsx 確認 problem 真存在 (c) 對照既有 canonical 確認非 documented exception。任一 NO → 自動撤回,**禁無病呻吟**
43
43
  3. **禁抽樣** — DS-wide ALL files 全掃,context 不夠拆 stage 全跑完;sub-agent admission「I sampled / spot-check / representative」= audit incomplete reject
44
+ 4. **禁列檔** — 禁 `rg --files` / 禁 find 全 repo 列檔燒 reasoning(2026-05-27 codex 2× token-burn anchor);只讀 brief 列的 file(targeted rg / Read),不需報告探索過程,直接出 verdict
45
+ 5. **輸入對等**(2026-07-10「codex 擁有的資訊要跟 Claude 一模一樣」)— 閱讀清單逐字鏡射 Claude Phase A.0 六項,**必具名含** `.claude/rules/meta-patterns.md`(31 active M-rules)+ `.claude/memory/MEMORY.md` index(泛 glob ≠ 對等)
46
+ 6. **判準對等**(2026-07-10「兩邊用同樣完美標準稽核」)— brief 必附 `design-system-audit/references/audit-prompts.md` 每-dim rubric 並要求逐 dim 套用同一判準;只給 dim 編號 = codex 憑己意判 = 標準不對稱
47
+ 7. **A.1b 對等** — brief 必要求 codex 做 A.1b per-component claim-vs-code 對抗驗證(讀每元件 .tsx + wrap lib source 逐句驗宣稱);漏 = codex 少做 Claude 最高產出 pass(2026-05-30 抓 403 findings)= 任務不對等
44
48
  ```
45
49
 
46
50
  ## 歷史錨點
@@ -44,7 +44,7 @@ cva `defaultVariants` 異動 → 強制 grep 該元件所有檔案確認三方
44
44
 
45
45
  ### Phase 4 — Ship 審查(最後驗證)
46
46
 
47
- 走 **Ship section**(6 項):
47
+ 走 **Ship section**(checklist 4 = 35 項總數的 Ship 份額;下列 5-7 為 checklist 外加掛的 mechanical gate,不計入 35):
48
48
  1. `npm run storybook` 本地渲染正常
49
49
  2. `npx tsc -b` 無錯(**禁用 `--noEmit`**,root tsconfig `files: []` silent pass)
50
50
  3. import 路徑 `@/design-system/...`
@@ -59,7 +59,7 @@ detect_mode snippet / 為何 2-mode 不是 3-mode(3-mode = dead code)/ mode×sco
59
59
 
60
60
  **禁** hardcode dim range numbers(eg.「Dims 1-15」/「Dims 34-56」)在 sub-agent prompt — 用 dispatch-audit-dims.mjs output 的 `dispatchPlan.suggestedBatches[].dimNumbers` 動態填。
61
61
 
62
- 完整跑,**no sample / no escape**(對齊 `feedback_audit_full_sweep_not_sample.md` + `check_audit_sample_escape.sh` BLOCKER)。
62
+ 完整跑,**no sample / no escape**(對齊 `feedback_audit_discipline_full_sweep_deterministic_preflight.md` + `check_audit_sample_escape.sh` BLOCKER)。
63
63
  每 dim sub-agent prompt 必含「DS-wide 全盤,禁 sample top N」。
64
64
 
65
65
  **DETERMINISTIC dim 必驗「mode 真的有跑」(2026-06-11 加)**:script exit 0 ≠ 該 dim 宣稱的模式真的執行了 — 必看輸出證據(per-mode 計數 / cell label / scenario 數)確認 flag 真生效。Anchor:dim 51 `--matrix` flag 接受後 `MATRIX_CELLS` 定義但 main loop 從未消費(dead code),跑出來是無 matrix 的普通 scan + exit 0 = 連續假綠;另 cell 清單含 Storybook 不認識的 globals(hc/rtl)= 注入後靜默 fallback = 假覆蓋。兩層都要驗:flag→行為、行為→真值。
@@ -152,7 +152,7 @@ Brief 必含 4 段(完整 template SSOT → `references/phase-b-codex-brief.md`,
152
152
  保證鏈三段:brief 端(check_codex_brief_invariants.sh 攔缺 invariant 的 brief)→ 回程端(本對帳步)→ 報告端(對帳表進 report 供 report-validator 掃)。
153
153
 
154
154
  **禁 pass-through**(per M31 + `feedback_codex_dual_track_synthesizer.md`):
155
- - Step 4:M22/M23/M27/M8 4 題自檢
155
+ - Step 4:M22/M23/M23(c)/M8 4 題自檢
156
156
  - **Step 4.5 verify each claim**:grep / WebFetch / run invariant script / counter-example scan
157
157
  - 每 codex claim 標 `✅ verified` / `❌ FALSE` / `⚠️ partial`
158
158
 
@@ -187,7 +187,7 @@ Deep-audit 收尾**必自動跑** `/knowledge-prune` deep — **前提鐵律:確
187
187
 
188
188
  Deep-audit 收尾(C.0a 旁)**必跑**:讀 `node scripts/audit-coverage-matrix.mjs` 的 PURE-JUDGMENT gap list,**選 top 1-3 個本輪已充分理解的 judgment 維度,當場寫成 deterministic script**(invariant .mjs / hook rule);寫不成的必記一行「為何不能謂詞化」(品味 / 需 LLM 讀 source / 外部演進類)。**雙柱模型**:完整稽核 = 永久機構(存量 / 外來 / 漂移 / 防線腐化 / 品味五類永遠需要);謂詞化 = 稽核的機械化引擎——每類問題轉謂詞後,同一謂詞對存量與外來元件全量零抽樣免費掃,稽核不縮編、機械部分逐季變厚。KPI(PURE-JUDGMENT 佔比 trend)由 `/governance-health` 月度追蹤。SSOT → `.claude/planning/2026-07-07-governance-evolution-roadmap.md`。錨例:2026-07-07 selected/active meta 謂詞、VR shifted-clock(當場謂詞化,存量 63 元件一次掃平)。
189
189
 
190
- ### C.0b — 治理全軸覆蓋對照(2026-07-10 user「deep audit 會稽核所有治理軸嗎?要確保」)
190
+ ### C.0c — 治理全軸覆蓋對照(2026-07-10 user「deep audit 會稽核所有治理軸嗎?要確保」)
191
191
 
192
192
  收尾必讀 `.claude/references/governance-audit-coverage.md`(治理 home × 稽核者覆蓋表)逐 row 對照:
193
193
  (1) 本輪新增/改動的治理物(新 hook / script / reference / registry / home)在表上**有 row 嗎**?沒有 → 當場補 row(誰稽核它、多常跑);(2) 表上 4 個弱軸(gate script meta-test / SKILL claim-vs-behavior / eslint 發佈 / planning 靜置)狀態有變 → 更新。**沒對照 = C 階段不完整**。
@@ -202,7 +202,7 @@ Deep-audit 收尾(C.0a 旁)**必跑**:讀 `node scripts/audit-coverage-matrix.mj
202
202
 
203
203
  **每題必附「SSOT 理由:」一句**(= 為何這是「會影響 SSOT 的 UI/UX 增刪改」:新 API contract / 改 canonical 語意 / 新視覺 design language,三類之一,具體指出)。**寫不出 SSOT 理由 = 該題不是拍板題,移回 AUTO 自己做**(2026-06-11 user 第 3 次糾正 codify:bug fix / a11y 對齊 W3C / 對齊 spec 既有意圖 / story 內容 / 治理 / 補 rationale 文件 / dead code 清除,全部 AUTO 不問)。Hook `check_audit_post_report_validator.sh` Validator H 機械強制。
204
204
 
205
- **🔒 決策品質四要件(2026-07-13 user verbatim「需我拍板的議題,不是應該確保你和 codex 來回討論辯論出來的共識與解法有研究過世界級的設計且符合我們需求與一致設計語言和設計原則並確保 SSOT?現在跟未來都應該要確保這件事永遠成立」)—— 每個送 user 拍板的 decision 必全備,缺一即不成熟、退回研究/辯論、禁送 user**:
205
+ **🔒 決策品質四要件(scope = 本 skill C.1 決策清單;user 直接下的設計任務照 user 指示走,codex 辯論僅在 M31 Step 0 條件〔自試卡關 OR user 點名〕才啟 — 2026-07-15 user 糾正「我有叫你跟 codex 辯論嗎」,勿過度延伸)(2026-07-13 user verbatim「需我拍板的議題,不是應該確保你和 codex 來回討論辯論出來的共識與解法有研究過世界級的設計且符合我們需求與一致設計語言和設計原則並確保 SSOT?現在跟未來都應該要確保這件事永遠成立」)—— 每個送 user 拍板的 decision 必全備,缺一即不成熟、退回研究/辯論、禁送 user**:
206
206
  1. **SSOT-check 先行**:先 grep 我方 spec + memory + user 歷史拍板,查**是否已有 canonical / 你已拍板過**。已有 → 對齊即可、移回 AUTO,**不重問**(錨例:2026-07-13 誤把 MenuItem-internal〔你 2026-06-05 Q2 已拍板「可 subpath 消費」〕+ menu selected×hover 色〔你 2026-07-04 Q2 已拍板 neutral-selected 且已 cite Ant/VS Code〕當「新決策」問你 → 應是 autonomous 對齊,不是拍板題)。
207
207
  2. **World-class ≥3 cite(M26)**:每個真決策的 recommendation 必附 **≥3 家世界級 DS 在該情況的真實做法**(WebFetch 真 source + URL,禁憑印象)。
208
208
  3. **Claude↔codex 雙軌辯論(M31)**:兩 model **各自獨立研究 + propose + cite battle → 共識**;禁單方憑感覺直接給 user。
@@ -229,7 +229,7 @@ Deep-audit 收尾(C.0a 旁)**必跑**:讀 `node scripts/audit-coverage-matrix.mj
229
229
  | **CP-P0** | Phase 0 結束 | Print detected mode(ds-repo / fork-user-repo),mode = non-ds 直接 exit;確認 user 跑對 repo |
230
230
  | **CP-A0** | A.0 結束 | 全盤閱讀清單給 user 看(列 N file read,per detected mode 切 scope),禁未讀就進 A.1 |
231
231
  | **CP-A1b** | A.1b 結束 | **每個** component/pattern 都有 story-vs-code adversarial verdict(讀 .tsx + wrap lib 逐句比對宣稱);**禁** 用「無 code 改動」跳過任一單元。缺任一 component verdict = 不可進 A.2(2026-05-30 403-finding 偷懶 anchor)|
232
- | **CP-A2** | A.2 SSOT-UI/UX propose | 中文人話 + 4-Q gate;**STOP** 等 user A/B 才動 code(fork-user-repo mode:propose scope 限 `apps/**`,禁 DS source)|
232
+ | **CP-A2** | A.2 SSOT-UI/UX propose | 中文人話 + 7-Q gate;**STOP** 等 user A/B 才動 code(fork-user-repo mode:propose scope 限 `apps/**`,禁 DS source)|
233
233
  | **CP-B0** | B.0 codex transport | **solo mode(user opt-out)→ 整個 Phase B 跳過不進此 CP**;3-test 全 ❌ + cwd=fork → **auto-fallback Phase A only 印中文**,不 interactive ASK;cwd=ds-repo → 報 user;禁 Explore 替身 |
234
234
  | **CP-B4** | B.4 cite battle | evidence 對等 → STOP 等 user 拍板,**禁** AI 自決誰勝 |
235
235
  | **CP-C2** | C.2 push gate | 等 user「Push 到 main」trigger;禁 AI 自決 merge |
@@ -131,7 +131,7 @@ Grouped by theme. Each runs as an independent subagent; many can parallelize.
131
131
 
132
132
  | # | Audit | What it catches |
133
133
  |---|-------|-----------------|
134
- | 31 | **Overlay body 無 stripped-padding boolean variant**(對齊 Material/Atlassian/Mantine/shadcn 主流;Polaris flush API 例外但 scope 極窄)| Per-overlay grep `components/(Dialog\|Sheet\|Popover)/*.tsx`(非 stories)反 pattern:`(flush\|naked\|bare\|stripped\|unpadded\|noPadding\|paddingless)\?:\s*boolean` 在 body component。違反 = list-as-region 場景該由 consumer 用 className override(`!px-0 !pt-0 !pb-0`)+ 自管 list outer wrapper 處理,不該加 body variant。Rationale:variant 不解決底層脆弱(加 1 row search/banner 就破功)+ 把 1 surface decision 拆兩 API。對應 hook `lib/_overlay_handcraft.sh` Check 6(`post_edit_dispatcher.sh` 消費;原 check_overlay_handcraft.sh 2026-05-13 fold)+ `overlay-surface.spec.md`「List-as-region in overlay body」+ memory `feedback_layout_v6_canonical.md`。Hook 是 PostToolUse WARN(additionalContext,非 block),本 dim 對既有 overlay 元件 + 未來新增 overlay primitive(Drawer / FileViewer body 等)batch verify。`// overlay-body-stripped-variant-allow:` 檔頭 allowlist 例外(必含 ≥3 家世界級對照 + multi-row hold 保證)|
134
+ | 31 | **Overlay body 無 stripped-padding boolean variant**(對齊 Material/Atlassian/Mantine/shadcn 主流;Polaris flush API 例外但 scope 極窄)| Per-overlay grep `components/(Dialog\|Sheet\|Popover)/*.tsx`(非 stories)反 pattern:`(flush\|naked\|bare\|stripped\|unpadded\|noPadding\|paddingless)\?:\s*boolean` 在 body component。違反 = list-as-region 場景該由 consumer 用 className override(`!px-0 !pt-0 !pb-0`)+ 自管 list outer wrapper 處理,不該加 body variant。Rationale:variant 不解決底層脆弱(加 1 row search/banner 就破功)+ 把 1 surface decision 拆兩 API。對應 hook `lib/_overlay_handcraft.sh` Check 6(`post_edit_dispatcher.sh` 消費;原 check_overlay_handcraft.sh 2026-05-13 fold)+ `overlay-surface.spec.md`「List-as-region in overlay body」。Hook 是 PostToolUse WARN(additionalContext,非 block),本 dim 對既有 overlay 元件 + 未來新增 overlay primitive(Drawer / FileViewer body 等)batch verify。`// overlay-body-stripped-variant-allow:` 檔頭 allowlist 例外(必含 ≥3 家世界級對照 + multi-row hold 保證)|
135
135
  | 32 | **Filter operator registry SSOT consumption**(對齊 ClickUp/Airtable/Notion API + M17)| Per-consumer grep:反 pattern(a)hardcode op 字串 array 不 import `OPERATOR_REGISTRY`;(b)inline switch on op derive ValueShape(該走 `getValueShape`)。SSOT:`DataTable/filter-operators.ts`。`// filter-op-inline-allow:` 檔頭 escape |
136
136
  | 33 | **Component classification + abstraction discipline**(對齊 M21 + M22 + M23)| Per-component verify 5 子維:(a) **Internal vs Components 一致性**;(b) **Premature abstraction** rationale + cite;(c) **Sub-component 5-file 結構過度**;(d) **Benchmark claim 缺 source**(M22);(e) **DS internal canonical 優先**(M23)— spec / tsx 含 world-class DS keyword 但 visual decision(color / size / spacing / typography / state)未先 grep DS 既有 token / variant / pattern 命中 → flag。Sub-agent 對每 benchmark cite 反查:該屬性在 `tokens/` / 近親 spec 已有 codified canonical 嗎?有 → 該 cite 應為**輔證**(內部 canonical 主)而非**主導**(外部覆蓋內部)。違反 = M23 自開新 tier(2026-05-03 chevron 事件:Ant 5 家 muted 覆蓋 DS icon-only Button neutral-9 預設)|
137
137
 
@@ -179,7 +179,7 @@ User 2026-05-15 verbatim 抓「DS 深度稽核漏 storybook content quality」+
179
179
  | 59 | **Approval preflight scope coverage**(2026-05-26 extend per user「未來其他人 fork 用其他元件也偏移」)| `check_substantive_edit_approval_preflight.sh` scope 從 `packages/design-system/src/**` 擴大到 `apps/**.{tsx,ts,css}` + `node_modules/@qijenchen/design-system/**`。Audit verify hook regex 涵蓋三 scope + allowlist `*.stories.tsx`/`*.test.*`/`scripts/*`。對應 memory/feedback_ship_then_revert_anti_pattern.md SSOT |
180
180
  | 60 | **M26 propose-without-benchmark enforcement**(2026-05-26 backfill)| UserPromptSubmit hook `check_propose_without_benchmark.sh` 偵測 user prompt 含 trigger keyword(propose me / give me options / 列 option / 建議…方案·做法 / 哪個比較 / 對齊哪家 / 比稿 / 要怎麼設計 / 該用哪個 / design tradeoff / recommend / world-class 對照;2026-05-26 收緊,拿掉 看法/design/behavior 等籠統詞防 false-positive)+ 過去 20 turns transcript 中 `WebFetch`/`WebSearch` tool_use count < 2 → P0 措辭 directive context inject(exit 0 by design — UserPromptSubmit 不可 exit 2)「propose 前必跑 ≥3 source benchmark」。對應 meta-patterns.md M26 + propose-options/SKILL.md。錨例:2026-05-05 user 反覆糾「為什麼每次都沒 webfetch 只憑印象」 |
181
181
  | 61 | **M16 item-list gap + M23(c) DataTable framework prop conflict enforcement**(2026-05-26 backfill)| PreToolUse hooks 兩 invariant:(a) `check_item_list_gap.sh` — 2+ `<FileItem>` / `<MenuItem variant="rich">` 在同 NEW content 且無 `gap-N` / `space-y-N` parent → warn(M16);(b) `check_datatable_invariants.sh(r2 folded,2026-06-11)` — `ColumnDef` 上下文出現 `size: <number>` 但無 `meta: { width: ... }` → warn TanStack `size:px` vs DS `size:density` 框架 prop 衝突(M23(c))。對應 meta-patterns.md M16 + M23(c) + item-anatomy.spec.md + data-table.spec.md |
182
- | 62 | **Fork-user Netlify onboarding canonical**(2026-05-26 codify;2026-06-05 二修 → 免費密碼 = Edge Function Basic Auth,SSOT `memory/feedback_netlify_basic_password_canonical_2026_05_29.md` Rule 1)| Audit product-workspace + fork repos:(a) `netlify.toml` 含 access control:X-Robots-Tag noindex header **+ `[[edge_functions]]` path="/*" function="basic-auth" wire** + comment 指向 edge function 免費機制(**不**寫「Basic Password 免費 / `_headers` 免費」= drift); (b) `netlify/edge-functions/basic-auth.ts` 存在且讀 `STORYBOOK_BASIC_AUTH` env var 做 HTTP Basic Auth(讀 Authorization → 比對 → 缺/錯回 401 + WWW-Authenticate);`.storybook/manager-head.html` **不** 含 Netlify Identity widget script(我們用 edge-function Basic Auth,client-side Identity widget 不需要;若仍含 widget = 殘留 drift); (c) `scripts/setup-netlify-access.mjs` 含「沒 Netlify 帳號」前置 explainer + gh auth pre-check + 最後印 dashboard URL 教 user 在 Environment variables 設 `STORYBOOK_BASIC_AUTH` = `user:password`(**不**教「點 Basic Password radio」= 舊 flow drift); (d) `package.json` 有 `setup:netlify` npm script; (e) **CLAUDE.md `Access control` 段含「Claude 引導使用者 Netlify onboarding」≥6 條話術**(解釋 Netlify / GitHub 1-click OAuth / **免費 = edge-function Basic Auth 設 env var 30 秒** / SEO header 已 ship / deploy 驗證 / GitHub CLI 未 login / Codespaces cloud-dev path)+ 真實斷點清單(plugin install + OAuth + env var 設 + password 分享 4 斷點)+ **禁寫「`_headers`/Dashboard Basic Password 免費」「Identity 已 deprecated」(皆 2026-06-05 官方 docs 證實為錯)段**。錨例:2026-05-26 user「Claude 會知道引導 user 完成環境建置嗎?」+ 2026-06-05 user「仔細查查研究」抓出免費密碼 = Edge Function(Dashboard + `_headers` 都 Pro $20/mo;Identity 2026-02 撤回 deprecate 但是 full-login 不適合 simple gate)|
182
+ | 62 | **Fork-user Netlify onboarding canonical**(2026-05-26 codify;2026-06-05 二修 → 免費密碼 = Edge Function Basic Auth,SSOT `memory/reference_deploy_targets.md`)| Audit product-workspace + fork repos:(a) `netlify.toml` 含 access control:X-Robots-Tag noindex header **+ `[[edge_functions]]` path="/*" function="basic-auth" wire** + comment 指向 edge function 免費機制(**不**寫「Basic Password 免費 / `_headers` 免費」= drift); (b) `netlify/edge-functions/basic-auth.ts` 存在且讀 `STORYBOOK_BASIC_AUTH` env var 做 HTTP Basic Auth(讀 Authorization → 比對 → 缺/錯回 401 + WWW-Authenticate);`.storybook/manager-head.html` **不** 含 Netlify Identity widget script(我們用 edge-function Basic Auth,client-side Identity widget 不需要;若仍含 widget = 殘留 drift); (c) `scripts/setup-netlify-access.mjs` 含「沒 Netlify 帳號」前置 explainer + gh auth pre-check + 最後印 dashboard URL 教 user 在 Environment variables 設 `STORYBOOK_BASIC_AUTH` = `user:password`(**不**教「點 Basic Password radio」= 舊 flow drift); (d) `package.json` 有 `setup:netlify` npm script; (e) **CLAUDE.md `Access control` 段含「Claude 引導使用者 Netlify onboarding」≥6 條話術**(解釋 Netlify / GitHub 1-click OAuth / **免費 = edge-function Basic Auth 設 env var 30 秒** / SEO header 已 ship / deploy 驗證 / GitHub CLI 未 login / Codespaces cloud-dev path)+ 真實斷點清單(plugin install + OAuth + env var 設 + password 分享 4 斷點)+ **禁寫「`_headers`/Dashboard Basic Password 免費」「Identity 已 deprecated」(皆 2026-06-05 官方 docs 證實為錯)段**。錨例:2026-05-26 user「Claude 會知道引導 user 完成環境建置嗎?」+ 2026-06-05 user「仔細查查研究」抓出免費密碼 = Edge Function(Dashboard + `_headers` 都 Pro $20/mo;Identity 2026-02 撤回 deprecate 但是 full-login 不適合 simple gate)|
183
183
  | 63 | **Deploy URL auto-reply infra**(2026-05-26 codify per user verbatim「完成部署之後都應該自動回吐部署的連結,每次必定自動回,不論是現在這個 session 還是其他的」)| Audit product-workspace + fork repos:(a) `scripts/deploy-url.mjs` 存在 + executable + 輸出 production 或 preview URL JSON;(b) `package.json` 有 `deploy-url` script wired;(c) DS-side hook `.claude/hooks/inject_deploy_url_after_push.sh` 偵測 `git push origin <branch>` PostToolUse Bash → auto inject deploy URL into AI context;(d) hook scope skip `push --delete`(branch cleanup 非 deploy);(e) hook silent skip if no `.netlify/state.json` 或 `scripts/deploy-url.mjs`(DS repo 自身 + 非 Netlify-wired repos 不誤觸發)。Cross-session benefit:hook ship via plugin → 任何 fork user `/plugin install` 後自動受惠 |
184
184
  | 64 | **Post-main-push SSOT propagation canonical**(2026-05-26 user correction「不是只要一 knowledge audit deep 之後就要,是等我 push main 後才要」)| Audit:(a) CLAUDE.md `# Git solo-work canonical` 有 Step 5.5 SSOT propagation 段;(b) Hook `check_post_main_ssot_propagate.sh` 存在 + 註冊在 PostToolUse Bash matcher;(c) hook 偵測 `git push origin main` + diff HEAD~..HEAD 含 SSOT-affecting paths(`packages/design-system/src` + `packages/storybook-config/{addons,addons-preset.ts,preview.tsx}`(無 src/)+ `.claude/{rules,hooks,skills,commands,references}` + `.claude-plugin/*.json` + `hooks/hooks.json` + `CLAUDE.md`)→ inject 提議 bump beta.N+1;(d) cross-repo SSOT sync 統一由 CLAUDE.md Step 5.5 + `check_post_main_ssot_propagate.sh` canonical trigger(push-main-based;**不需 skill-specific Phase Z**,/knowledge-prune + /deep-audit-cross-codex 不複製,DRY);(e) 整鏈 cover 任何 SSOT-affecting 來源(/knowledge-prune / /deep-audit-cross-codex / 一般 dev / 新元件 / bug fix)。對應「一次更新所有 DS repo 增刪改,不需手動 1 個 1 個」directive |
185
185
  | 65 | **Chrome header avatar canonical**(2026-05-27 codex Step 4 cite battle + user 抓 UserFooter vertical stack drift)| 對每 production tsx + DS sidebar.stories.tsx / anatomy / principles 跑:`<SidebarHeader>` block 內偵測 `<ItemAvatar>` → 違反 chrome-header canonical(per `header-canonical.spec.md:57-72` / `sidebar.spec.md:241-247` / `item-anatomy.spec.md:513-537`「chrome header 不是 row context」)。正確 pattern = raw `<Avatar size={24}>`。Hook `check_chrome_header_avatar_canonical.sh` PreToolUse Edit/Write 用 python multiline regex 對 `<SidebarHeader>...<ItemAvatar>...</SidebarHeader>` block 偵測;SidebarFooter / SidebarMenuButton row context 不攔(footer IS row context per spec)。錨例 2026-05-27 product-workspace App.tsx + DS 3 sidebar stories 連動 fix |
@@ -241,7 +241,7 @@ User 2026-05-15 verbatim 抓「DS 深度稽核漏 storybook content quality」+
241
241
 
242
242
  User verbatim:「你完整稽核之前應該會先全面盤查全部檔案和所有設計原則對吧?我記得之前我有命令你要在 infra 定義這件事」+「確保現在和未來都會自動涵蓋,當有新的準則就務必更新設計系統進階稽核的內容」。
243
243
 
244
- **強制 chain**:`/design-system-audit --deep` 跑時 Phase 1 前自動跑 `node scripts/audit-preflight.mjs`(對應 SSOT `.claude/memory/feedback_audit_preflight_全盤查.md`)
244
+ **強制 chain**:`/design-system-audit --deep` 跑時 Phase 1 前自動跑 `node scripts/audit-preflight.mjs`(對應 SSOT `.claude/memory/feedback_audit_discipline_full_sweep_deterministic_preflight.md`)
245
245
 
246
246
  **輸出 3 件**:
247
247
  1. **檔案 enumeration**:全 `packages/design-system/src/**/*.{tsx,ts,css,md}` 計數 + per type bucket(component tsx / showcase stories / anatomy stories / principles stories / spec.md / tokens)
@@ -287,7 +287,7 @@ User verbatim 2026-05-15:
287
287
  - Sub-agent prompt **禁含「sample top N / subset / pick top X / top hot / sampled components / sample evidence allowed / heavy agent needed / full sweep deferred」**等任何縮 scope keyword
288
288
  - 每 dim 必 **DS-wide ALL components**(60+ 元件全掃),不 sample subset
289
289
  - Context 不夠 → 拆 N stages(每 stage 10-15 元件 batch),**不 sample**
290
- - 對應 SSOT:`memory/feedback_audit_full_sweep_not_sample.md`
290
+ - 對應 SSOT:`memory/feedback_audit_discipline_full_sweep_deterministic_preflight.md`
291
291
  - **2026-05-17 強化(user verbatim 抓教訓)**:「每次抓出的問題你他媽要給我基於我們所有的檔案包括設計原則去再三確認到底是不是問題」+「沒有取樣這種東西」+「重新深度完整稽核」。Dispatch prompt 任何「sample evidence allowed」/「heavy agent needed for full sweep」/「sample-N」escape clause **禁止寫入** — 違 = BLOCKER 不發 dispatch
292
292
 
293
293
  **Sub-agent dispatch prompt template MUST 含(2026-05-17 升級)**:
@@ -365,7 +365,7 @@ Phase 1-3 覆蓋 D1+D2;D3-D6 chain 專門 skill。**模式**:高效(default)scop
365
365
 
366
366
  ### Phase 4 — Final report + memory + Self-improvement(強制)
367
367
 
368
- Update `memory/project_audit_progress.md`(date / coverage / findings / deferred P2)+ short report(commits / deferred / next trigger)。
368
+ 產出 short report(date / coverage / findings / deferred P2 / commits / next trigger);需跨 session 持久化的 audit 計畫 / backlog 寫 `.claude/planning/` audit doc(memory 只留短 index pointer,per 8-home Level 9)。
369
369
 
370
370
  **Self-improvement capture(強制)**:每 audit 寫 3 行(無發現也寫「無」,不省略):
371
371
  - 新 FP pattern + 回填位置(`principle-audit-protocol.md`「常見 FP 記憶」)OR「無」
@@ -87,13 +87,13 @@ Purpose: design-system-audit audits the **DS itself**(spec / cva / SSOT 三方
87
87
 
88
88
  ### Dim 4 — Mindset adherence
89
89
 
90
- 對齊 CLAUDE.md 5 條 mindset:
90
+ 對齊 CLAUDE.md 6 條 mindset(逐條檢查 #1-#5;#6「大原則吸收瑣碎」屬 governance meta 層,不在 consumer code audit scope。編號用 mindset #N,避免撞 meta-patterns M-rules 編號):
91
91
 
92
- - **M1 對標世界級**:新 pattern 有對標備註? 或找得到對應既有元件?
93
- - **M2 不憑直覺發明**:新數值(gap / padding / font-size)前有 grep 既有?
94
- - **M3 改一處看三處**:若改 DS 的 cva defaultVariants,spec / docblock / anatomy 三方同步?
95
- - **M4 真實業務場景**:stories / examples 用真實場景 (Jira / Stripe / Notion...)?無 `Option A/B/C` / `按鈕一` / `Rule A`?
96
- - **M5 猶豫就問**:code 裡有 TODO-未確認留白?
92
+ - **mindset #1 對標世界級**:新 pattern 有對標備註? 或找得到對應既有元件?
93
+ - **mindset #2 不憑直覺發明**:新數值(gap / padding / font-size)前有 grep 既有?
94
+ - **mindset #3 改一處看三處**:若改 DS 的 cva defaultVariants,spec / docblock / anatomy 三方同步?
95
+ - **mindset #4 真實業務場景**:stories / examples 用真實場景 (Jira / Stripe / Notion...)?無 `Option A/B/C` / `按鈕一` / `Rule A`?
96
+ - **mindset #5 猶豫就問**:code 裡有 TODO-未確認留白?
97
97
 
98
98
  ### Dim 5 — 視覺幾何(Mindset #1 視覺擴充 + .claude/references/ui-dev-rules.md「同 flex 列互動 slot 幾何鐵律」)
99
99
 
@@ -131,7 +131,7 @@ chain `.claude/skills/design-system-audit/references/principle-audit-protocol.md
131
131
 
132
132
  確認 audit target:file / folder / feature area。提問 user 若模糊。禁止掃整個 repo(失焦)。
133
133
 
134
- ### Phase 1 — Parallel 6-dim audit
134
+ ### Phase 1 — Parallel 7-Dimension audit
135
135
 
136
136
  7 個維度各自獨立 grep + code review。可 parallelize。
137
137