@qijenchen/design-system 0.1.0-beta.10 → 0.1.0-beta.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +201 -0
- package/README.md +7 -15
- package/cli-init.mjs +90 -0
- package/ds-canonical/commands/README.md +26 -0
- package/ds-canonical/commands/gov-status.md +79 -0
- package/ds-canonical/hooks/README.md +145 -0
- package/ds-canonical/hooks/_log-fire.sh +44 -0
- package/ds-canonical/hooks/block_prototype_imports.py +111 -0
- package/ds-canonical/hooks/check_app_shell_primary_header_consistency.sh +68 -0
- package/ds-canonical/hooks/check_audit_post_report_validator.sh +88 -0
- package/ds-canonical/hooks/check_audit_sample_escape.sh +73 -0
- package/ds-canonical/hooks/check_benchmark_citation.sh +106 -0
- package/ds-canonical/hooks/check_canonical_propagation.sh +189 -0
- package/ds-canonical/hooks/check_chrome_header_handcraft.sh +70 -0
- package/ds-canonical/hooks/check_codex_brief_invariants.sh +83 -0
- package/ds-canonical/hooks/check_codex_collab_5step.sh +108 -0
- package/ds-canonical/hooks/check_datatable_invariants.sh +117 -0
- package/ds-canonical/hooks/check_dim_count_drift.sh +72 -0
- package/ds-canonical/hooks/check_field_controls_contracts.sh +110 -0
- package/ds-canonical/hooks/check_field_family_invariants.sh +205 -0
- package/ds-canonical/hooks/check_file_size_budget.sh +60 -0
- package/ds-canonical/hooks/check_header_with_tabs_border.sh +87 -0
- package/ds-canonical/hooks/check_main_branch_workbench.sh +93 -0
- package/ds-canonical/hooks/check_naming_and_abstraction.sh +165 -0
- package/ds-canonical/hooks/check_opacity_token_usage.sh +149 -0
- package/ds-canonical/hooks/check_pattern_invariants.sh +194 -0
- package/ds-canonical/hooks/check_peoplepicker_ssot_drift.sh +56 -0
- package/ds-canonical/hooks/check_pixel_quantified_audit.sh +53 -0
- package/ds-canonical/hooks/check_propose_plain_chinese.sh +74 -0
- package/ds-canonical/hooks/check_propose_pre_grep_verify.sh +70 -0
- package/ds-canonical/hooks/check_select_all_canonical.sh +58 -0
- package/ds-canonical/hooks/check_solo_workflow.sh +258 -0
- package/ds-canonical/hooks/check_spec_class_drift.sh +88 -0
- package/ds-canonical/hooks/check_story_invariants.sh +612 -0
- package/ds-canonical/hooks/check_substantive_edit_approval_preflight.sh +105 -0
- package/ds-canonical/hooks/check_tab_lg_chrome_header_equal.sh +66 -0
- package/ds-canonical/hooks/check_wrapper_primitive_schema_drift.sh +104 -0
- package/ds-canonical/hooks/enforce_home_charter.sh +44 -0
- package/ds-canonical/hooks/inject_pending_self_audit.sh +204 -0
- package/ds-canonical/hooks/lib/_approval_re.sh +33 -0
- package/ds-canonical/hooks/lib/_code_quality.sh +73 -0
- package/ds-canonical/hooks/lib/_cva_default_sync.sh +69 -0
- package/ds-canonical/hooks/lib/_governance_coverage_check.sh +49 -0
- package/ds-canonical/hooks/lib/_hardcoded_strings.sh +163 -0
- package/ds-canonical/hooks/lib/_layout_space_canonical.sh +56 -0
- package/ds-canonical/hooks/lib/_overlay_handcraft.sh +141 -0
- package/ds-canonical/hooks/lib/_person_data_richness.sh +42 -0
- package/ds-canonical/hooks/lib/_story_compile_drift.sh +48 -0
- package/ds-canonical/hooks/lib/_token_hygiene.sh +95 -0
- package/ds-canonical/hooks/log_governance_fires.sh +50 -0
- package/ds-canonical/hooks/log_skill_invokes.sh +41 -0
- package/ds-canonical/hooks/post_edit_dispatcher.sh +62 -0
- package/ds-canonical/hooks/retired/check_anatomy_section_numbering.sh +106 -0
- package/ds-canonical/hooks/retired/check_avatar_hovercard.sh +90 -0
- package/ds-canonical/hooks/retired/check_button_icon_literal.sh.retired-2026-04-28 +38 -0
- package/ds-canonical/hooks/retired/check_container_breathing.sh +142 -0
- package/ds-canonical/hooks/retired/check_governance_compliance.sh +61 -0
- package/ds-canonical/hooks/retired/check_icon_only_padding_formula.sh +104 -0
- package/ds-canonical/hooks/retired/check_item_content_primitive.sh +150 -0
- package/ds-canonical/hooks/retired/check_item_list_gap.sh +153 -0
- package/ds-canonical/hooks/retired/check_sideoffset_canonical.sh +65 -0
- package/ds-canonical/hooks/retired/check_spec_iteration_tag.sh +87 -0
- package/ds-canonical/hooks/retired/check_ssot_consultation.sh +88 -0
- package/ds-canonical/hooks/retired/check_sync_update.sh +20 -0
- package/ds-canonical/hooks/retired/check_third_party_dom_verified.sh +95 -0
- package/ds-canonical/hooks/retired/enforce_home_charter.sh +125 -0
- package/ds-canonical/hooks/retired/post_edit_canonical_interrogate.sh +109 -0
- package/ds-canonical/hooks/retired/pre_edit_spec_check.sh +68 -0
- package/ds-canonical/hooks/retired/pre_new_component_spec.sh +39 -0
- package/ds-canonical/hooks/retired/pre_write_subsumption_check.sh +112 -0
- package/ds-canonical/hooks/retired/stop_meta_self_audit.sh.retired-2026-05-13 +76 -0
- package/ds-canonical/hooks/retired/tests/test_check_anatomy_section_numbering.sh +14 -0
- package/ds-canonical/hooks/retired/tests/test_check_avatar_hovercard.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_container_breathing.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_governance_compliance.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_icon_only_padding_formula.sh +79 -0
- package/ds-canonical/hooks/retired/tests/test_check_item_content_primitive.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_item_list_gap.sh +163 -0
- package/ds-canonical/hooks/retired/tests/test_check_sideoffset_canonical.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_spec_iteration_tag.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_ssot_consultation.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_check_sync_update.sh +14 -0
- package/ds-canonical/hooks/retired/tests/test_check_third_party_dom_verified.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_enforce_home_charter.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_edit_spec_check.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_new_component_spec.sh +15 -0
- package/ds-canonical/hooks/retired/tests/test_pre_write_subsumption_check.sh +63 -0
- package/ds-canonical/hooks/session_start_governance_check.sh +263 -0
- package/ds-canonical/hooks/stop_passive_logging.sh +322 -0
- package/ds-canonical/hooks/stop_self_audit.sh +450 -0
- package/ds-canonical/hooks/tests/KNOWN-BROKEN.md +15 -0
- package/ds-canonical/hooks/tests/run-all.sh +76 -0
- package/ds-canonical/hooks/tests/test_block_prototype_imports.sh +143 -0
- package/ds-canonical/hooks/tests/test_check_app_shell_primary_header_consistency.sh +140 -0
- package/ds-canonical/hooks/tests/test_check_audit_post_report_validator.sh +115 -0
- package/ds-canonical/hooks/tests/test_check_audit_sample_escape.sh +93 -0
- package/ds-canonical/hooks/tests/test_check_benchmark_citation.sh +115 -0
- package/ds-canonical/hooks/tests/test_check_canonical_propagation.sh +133 -0
- package/ds-canonical/hooks/tests/test_check_chrome_header_handcraft.sh +123 -0
- package/ds-canonical/hooks/tests/test_check_code_quality.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_codex_collab_5step.sh +96 -0
- package/ds-canonical/hooks/tests/test_check_cva_default_sync.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_datatable_invariants.sh +122 -0
- package/ds-canonical/hooks/tests/test_check_dim_count_drift.sh +98 -0
- package/ds-canonical/hooks/tests/test_check_field_controls_contracts.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_field_family_invariants.sh +194 -0
- package/ds-canonical/hooks/tests/test_check_file_size_budget.sh +32 -0
- package/ds-canonical/hooks/tests/test_check_hardcoded_strings.sh +14 -0
- package/ds-canonical/hooks/tests/test_check_header_with_tabs_border.sh +110 -0
- package/ds-canonical/hooks/tests/test_check_layout_space_canonical.sh +73 -0
- package/ds-canonical/hooks/tests/test_check_main_branch_workbench.sh +147 -0
- package/ds-canonical/hooks/tests/test_check_naming_and_abstraction.sh +136 -0
- package/ds-canonical/hooks/tests/test_check_opacity_token_usage.sh +110 -0
- package/ds-canonical/hooks/tests/test_check_overlay_handcraft.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_pattern_invariants.sh +148 -0
- package/ds-canonical/hooks/tests/test_check_peoplepicker_ssot_drift.sh +108 -0
- package/ds-canonical/hooks/tests/test_check_person_data_richness.sh +58 -0
- package/ds-canonical/hooks/tests/test_check_pixel_quantified_audit.sh +142 -0
- package/ds-canonical/hooks/tests/test_check_propose_plain_chinese.sh +126 -0
- package/ds-canonical/hooks/tests/test_check_propose_pre_grep_verify.sh +117 -0
- package/ds-canonical/hooks/tests/test_check_select_all_canonical.sh +125 -0
- package/ds-canonical/hooks/tests/test_check_solo_workflow.sh +201 -0
- package/ds-canonical/hooks/tests/test_check_spec_class_drift.sh +135 -0
- package/ds-canonical/hooks/tests/test_check_story_anatomy.sh.broken +197 -0
- package/ds-canonical/hooks/tests/test_check_story_category.sh.broken +187 -0
- package/ds-canonical/hooks/tests/test_check_story_compile_drift.sh +15 -0
- package/ds-canonical/hooks/tests/test_check_story_invariants.sh +209 -0
- package/ds-canonical/hooks/tests/test_check_story_name_jargon.sh.broken +53 -0
- package/ds-canonical/hooks/tests/test_check_story_slot_split.sh +156 -0
- package/ds-canonical/hooks/tests/test_check_substantive_edit_approval_preflight.sh +176 -0
- package/ds-canonical/hooks/tests/test_check_tab_lg_chrome_header_equal.sh +138 -0
- package/ds-canonical/hooks/tests/test_check_token_hygiene.sh +21 -0
- package/ds-canonical/hooks/tests/test_check_wrapper_primitive_schema_drift.sh +169 -0
- package/ds-canonical/hooks/tests/test_enforce_home_charter.sh +77 -0
- package/ds-canonical/hooks/tests/test_inject_pending_self_audit.sh +125 -0
- package/ds-canonical/hooks/tests/test_log_governance_fires.sh +10 -0
- package/ds-canonical/hooks/tests/test_log_skill_invokes.sh +7 -0
- package/ds-canonical/hooks/tests/test_post_edit_dispatcher.sh +108 -0
- package/ds-canonical/hooks/tests/test_session_start_governance_check.sh +143 -0
- package/ds-canonical/hooks/tests/test_stop_capture_metrics.sh +95 -0
- package/ds-canonical/hooks/tests/test_stop_governance_drift_check.sh.broken +125 -0
- package/ds-canonical/hooks/tests/test_stop_harvest_corrections.sh +10 -0
- package/ds-canonical/hooks/tests/test_stop_passive_logging.sh +100 -0
- package/ds-canonical/hooks/tests/test_stop_self_audit.sh +76 -0
- package/ds-canonical/hooks/tests/test_stop_tsc_sanity.sh +10 -0
- package/ds-canonical/references/README.md +43 -0
- package/ds-canonical/references/audit-coverage-vs-24-checklist.md +74 -0
- package/ds-canonical/references/build-ui-canonicals.md +69 -0
- package/ds-canonical/references/cva-patterns.md +41 -0
- package/ds-canonical/references/drag-canonical.md +331 -0
- package/ds-canonical/references/item-anatomy-recipe.md +225 -0
- package/ds-canonical/references/naming-conventions.md +56 -0
- package/ds-canonical/references/principle-dim-map.json +515 -0
- package/ds-canonical/references/props-naming.md +45 -0
- package/ds-canonical/references/spec-rules.md +58 -0
- package/ds-canonical/references/ssot-consultation.md +63 -0
- package/ds-canonical/references/ssot-index.md +40 -0
- package/ds-canonical/references/story-baseline-registry.json +79 -0
- package/ds-canonical/references/structural-token-retention.md +42 -0
- package/ds-canonical/references/tailwind-gotchas.md +87 -0
- package/ds-canonical/references/ui-dev-rules.md +60 -0
- package/ds-canonical/rules/README.md +34 -0
- package/ds-canonical/rules/meta-patterns.md +87 -0
- package/ds-canonical/rules/self-verify.md +53 -0
- package/ds-canonical/rules/spec-rules.md +25 -0
- package/ds-canonical/rules/story-rules.md +56 -0
- package/ds-canonical/rules/ui-development.md +87 -0
- package/ds-canonical/skills/README.md +88 -0
- package/ds-canonical/skills/bug-fix-rhythm/SKILL.md +181 -0
- package/ds-canonical/skills/code-quality-audit/SKILL.md +63 -0
- package/ds-canonical/skills/codex-collab/SKILL.md +249 -0
- package/ds-canonical/skills/codex-collab/references/brief-template.md +48 -0
- package/ds-canonical/skills/codex-collab/references/transport.md +58 -0
- package/ds-canonical/skills/codify-corrections/SKILL.md +184 -0
- package/ds-canonical/skills/codify-principle/SKILL.md +151 -0
- package/ds-canonical/skills/component-quality-gate/SKILL.md +102 -0
- package/ds-canonical/skills/component-quality-gate/references/checklist.md +79 -0
- package/ds-canonical/skills/deep-audit-cross-codex/SKILL.md +247 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-a-workflow.md +123 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/phase-b-codex-brief.md +165 -0
- package/ds-canonical/skills/deep-audit-cross-codex/references/triage-rubric.md +91 -0
- package/ds-canonical/skills/delivery-handoff/SKILL.md +229 -0
- package/ds-canonical/skills/delivery-handoff/references/flow-diagram.md +180 -0
- package/ds-canonical/skills/delivery-handoff/references/handoff-template.md +177 -0
- package/ds-canonical/skills/delivery-handoff/references/inventory-checklist.md +196 -0
- package/ds-canonical/skills/design-system-audit/SKILL.md +343 -0
- package/ds-canonical/skills/design-system-audit/references/audit-prompts.md +1260 -0
- package/ds-canonical/skills/design-system-audit/references/checkpoints.md +240 -0
- package/ds-canonical/skills/design-system-audit/references/historical-bugs.md +240 -0
- package/ds-canonical/skills/design-system-audit/references/principle-audit-protocol.md +364 -0
- package/ds-canonical/skills/design-system-audit/references/rule-placement.md +175 -0
- package/ds-canonical/skills/design-system-audit/references/spec-template.md +66 -0
- package/ds-canonical/skills/ensure-canonical/SKILL.md +196 -0
- package/ds-canonical/skills/governance-health/SKILL.md +146 -0
- package/ds-canonical/skills/knowledge-prune/SKILL.md +303 -0
- package/ds-canonical/skills/new-component/SKILL.md +170 -0
- package/ds-canonical/skills/new-component/references/new-component-checklist.md +85 -0
- package/ds-canonical/skills/performance-audit/SKILL.md +107 -0
- package/ds-canonical/skills/product-ui-audit/SKILL.md +230 -0
- package/ds-canonical/skills/product-ui-audit/references/audit-checks.md +246 -0
- package/ds-canonical/skills/product-ui-audit/references/common-misuses.md +329 -0
- package/ds-canonical/skills/product-ui-audit/references/report-template.md +159 -0
- package/ds-canonical/skills/propose-options/SKILL.md +177 -0
- package/ds-canonical/skills/prototype/SKILL.md +244 -0
- package/ds-canonical/skills/prototype/references/audit-checks.md +37 -0
- package/ds-canonical/skills/prototype/references/benchmark-sources.md +94 -0
- package/ds-canonical/skills/prototype/references/checkpoints.md +191 -0
- package/ds-canonical/skills/prototype/references/evaluation-matrix.md +141 -0
- package/ds-canonical/skills/prototype/references/ooux-template.md +198 -0
- package/ds-canonical/skills/prototype/references/proposal-template.md +229 -0
- package/ds-canonical/skills/scan-similar-bugs/SKILL.md +198 -0
- package/ds-canonical/skills/story-auto-compile-migrate/SKILL.md +159 -0
- package/ds-canonical/skills/story-writing/SKILL.md +122 -0
- package/ds-canonical/skills/story-writing/references/anatomy-standard.md +217 -0
- package/ds-canonical/skills/story-writing/references/category-templates.md +174 -0
- package/ds-canonical/skills/story-writing/references/example-selection.md +70 -0
- package/ds-canonical/skills/story-writing/references/self-check.md +20 -0
- package/ds-canonical/skills/ux-audit/SKILL.md +130 -0
- package/ds-canonical/skills/visual-audit/SKILL.md +245 -0
- package/ds-canonical/skills/visual-audit/output/.gitkeep +0 -0
- package/ds-canonical/skills/visual-audit/references/audit-architecture.md +100 -0
- package/ds-canonical/skills/visual-audit/references/visual-checklist.md +297 -0
- package/ds-canonical/skills/visual-audit/references/world-class-benchmarks.md +198 -0
- package/package.json +9 -5
- package/src/components/Accordion/accordion.spec.md +114 -0
- package/src/components/Alert/alert.spec.md +197 -0
- package/src/components/AppShell/app-shell.spec.md +331 -0
- package/src/components/AspectRatio/aspect-ratio.spec.md +134 -0
- package/src/components/Avatar/avatar.spec.md +329 -0
- package/src/components/Badge/badge.spec.md +380 -0
- package/src/components/Breadcrumb/breadcrumb.spec.md +257 -0
- package/src/components/BulkActionBar/bulk-action-bar.spec.md +210 -0
- package/src/components/Button/button.spec.md +460 -0
- package/src/components/Calendar/calendar.spec.md +242 -0
- package/src/components/Carousel/carousel.spec.md +253 -0
- package/src/components/Chart/chart.spec.md +155 -0
- package/src/components/Checkbox/checkbox.spec.md +344 -0
- package/src/components/Chip/chip.spec.md +237 -0
- package/src/components/CircularProgress/circular-progress.spec.md +268 -0
- package/src/components/Coachmark/coachmark.spec.md +230 -0
- package/src/components/Combobox/combobox.spec.md +180 -0
- package/src/components/Command/command.spec.md +171 -0
- package/src/components/DataTable/data-table.spec.md +525 -0
- package/src/components/DateGrid/date-grid.spec.md +215 -0
- package/src/components/DatePicker/date-picker.spec.md +334 -0
- package/src/components/DescriptionList/description-list.spec.md +214 -0
- package/src/components/Dialog/dialog.spec.md +202 -0
- package/src/components/DropdownMenu/dropdown-menu.spec.md +250 -0
- package/src/components/Empty/empty.spec.md +214 -0
- package/src/components/Field/field-controls.spec.md +338 -0
- package/src/components/Field/field.spec.md +438 -0
- package/src/components/Field/form-validation.spec.md +152 -0
- package/src/components/FieldControlGroup/field-control-group.spec.md +176 -0
- package/src/components/FileItem/file-item.spec.md +467 -0
- package/src/components/FileUpload/file-upload.spec.md +123 -0
- package/src/components/FileViewer/file-viewer.spec.md +373 -0
- package/src/components/HoverCard/hover-card.spec.md +157 -0
- package/src/components/Input/input.spec.md +193 -0
- package/src/components/LinkInput/link-input.spec.md +130 -0
- package/src/components/Menu/menu-item.spec.md +290 -0
- package/src/components/NameCard/name-card.spec.md +171 -0
- package/src/components/Notice/notice.spec.md +149 -0
- package/src/components/NumberInput/number-input.spec.md +126 -0
- package/src/components/OverflowIndicator/overflow-indicator.spec.md +120 -0
- package/src/components/PeoplePicker/people-picker.spec.md +263 -0
- package/src/components/Popover/popover.spec.md +198 -0
- package/src/components/ProgressBar/progress-bar.spec.md +232 -0
- package/src/components/RadioGroup/radio-group.spec.md +141 -0
- package/src/components/Rating/rating.spec.md +208 -0
- package/src/components/ScrollArea/scroll-area.spec.md +145 -0
- package/src/components/SegmentedControl/segmented-control.spec.md +295 -0
- package/src/components/Select/select.spec.md +299 -0
- package/src/components/SelectMenu/select-menu.spec.md +220 -0
- package/src/components/SelectionControl/selection-item.spec.md +128 -0
- package/src/components/Separator/separator.spec.md +109 -0
- package/src/components/Sheet/sheet.spec.md +148 -0
- package/src/components/Sidebar/sidebar.spec.md +713 -0
- package/src/components/Skeleton/skeleton.spec.md +104 -0
- package/src/components/Slider/slider.spec.md +353 -0
- package/src/components/Steps/steps.spec.md +465 -0
- package/src/components/Switch/switch.spec.md +215 -0
- package/src/components/Tabs/tabs.spec.md +314 -0
- package/src/components/Tag/tag.spec.md +282 -0
- package/src/components/Textarea/textarea.spec.md +151 -0
- package/src/components/TimePicker/time-picker.spec.md +279 -0
- package/src/components/Toast/toast.spec.md +177 -0
- package/src/components/Tooltip/tooltip.spec.md +139 -0
- package/src/components/TreeView/tree-view.spec.md +374 -0
- package/src/patterns/action-bar/action-bar.spec.md +458 -0
- package/src/patterns/element-anatomy/element-anatomy.spec.md +215 -0
- package/src/patterns/element-anatomy/inline-action.spec.md +315 -0
- package/src/patterns/element-anatomy/item-anatomy.spec.md +1042 -0
- package/src/patterns/header-canonical/header-canonical.spec.md +285 -0
- package/src/patterns/horizontal-overflow/horizontal-overflow.spec.md +191 -0
- package/src/patterns/overlay-surface/overlay-surface.spec.md +428 -0
- package/src/patterns/resize-handle/resize-handle.spec.md +109 -0
- package/src/tokens/color/color.spec.md +804 -0
- package/src/tokens/density/density.spec.md +127 -0
- package/src/tokens/elevation/elevation.spec.md +81 -0
- package/src/tokens/layoutSpace/layoutSpace.spec.md +314 -0
- package/src/tokens/motion/motion.spec.md +97 -0
- package/src/tokens/opacity/opacity.spec.md +78 -0
- package/src/tokens/orphan-tokens.spec.md +117 -0
- package/src/tokens/radius/radius.spec.md +123 -0
- package/src/tokens/typography/typography.spec.md +202 -0
- package/src/tokens/uiSize/uiSize.spec.md +438 -0
- package/src/styles/preset.css +0 -31
|
@@ -0,0 +1,1260 @@
|
|
|
1
|
+
# Audit Subagent Prompts(全 dim per `SKILL.md SSOT`)
|
|
2
|
+
|
|
3
|
+
> **Count canonical**:本檔 dim 數對齊 `.claude/skills/design-system-audit/SKILL.md` `## The N audit dimensions` 表。歷史標題曾寫「22 audits」,已 deprecated — 真實 dim 數以 SKILL.md 為準,本檔每加 dim 必同步補 prompt section。`scripts/sync-governance-counters.mjs` 自動 cross-verify。
|
|
4
|
+
|
|
5
|
+
Each prompt is self-contained — designed to paste into an `Agent` call with `run_in_background: true` and `subagent_type: ds-dim-auditor`(registered agent since 2026-04-24;scoped Read/Grep/Glob only;fallback to `general-purpose` if agent not available)。
|
|
6
|
+
|
|
7
|
+
All prompts start with:
|
|
8
|
+
```
|
|
9
|
+
Working directory: /Users/chenqiren/Library/CloudStorage/GoogleDrive-qijenchen@gmail.com/我的雲端硬碟/my-project
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## ⚠️ 必先讀的 canonical(所有 sub-agent 跑前強制)
|
|
13
|
+
|
|
14
|
+
**sub-agent 最常見失誤:不讀 scope defaults + rationale 就判 violation,造成 ~60% false positive**。每個 prompt 執行前**強制**先讀:
|
|
15
|
+
|
|
16
|
+
1. `CLAUDE.md` 的 `# Meta-Pattern 預警`(**M1-M9** meta-principles,含 M8 Benchmark-First / M9 Predicate Self-Test 2026-04-22)
|
|
17
|
+
2. `CLAUDE.md` 的 `# SSOT 消費 canonical`(做 X 前必查 Y 對照表)
|
|
18
|
+
3. `CLAUDE.md` 的 `# 稽核 canonical`「Audit-vs-execute 分權」(flag 是提議,不是 auto-fix)
|
|
19
|
+
4. `.claude/rules/spec-rules.md` 的「Scope 預設」節(Field 家族 / pure wrapper / semantic token 自動 scope 豁免)
|
|
20
|
+
5. 每個 Consistency 類 dim:flag violation 前**必先 grep 元件 spec.md 整個檔案**找 rationale;有任何一段明文(`##`/`###`/「為什麼」/「rationale」/「對照」)觸及 deviation 原因 → 不是 violation 是 `deviation ✓`
|
|
21
|
+
6. **Consistency 類 dim(含 D6b/D6c/D6e)必走 Phase 0 全掃再判**(CLAUDE.md `# 稽核 6 維` 規則 + `principle-audit-protocol.md` D6 scan)— 單元件看無法檢出系統性 drift / 跨 item 矛盾 / predicate membership drift
|
|
22
|
+
|
|
23
|
+
### 常見 false positive(記憶)
|
|
24
|
+
|
|
25
|
+
- **「缺 dark mode 覆蓋」** → 若 spec 寫「semantic token 自動處理(見 color.spec.md)」或元件用 `--primary` / `--fg` 等 semantic token = **自動豁免**
|
|
26
|
+
- **「缺 empty state」** → 若 spec 寫「empty 由 consumer 用 `<Empty>`」= **豁免**
|
|
27
|
+
- **「SSOT reciprocal 缺」** → SSOT pointer 可是 inline prose 不一定是 `##` heading(例:RadioGroup line 24 prose pointer 就足夠)。flag 前 grep 對方 spec 完整,**找不到 target 的 anchor 才是 violation**
|
|
28
|
+
- **「7-dim 7 維度不足」** → scope defaults 豁免「Internal 類 / wrapper 類 / 互動極少類」;flag 前驗證 scope default 是否適用
|
|
29
|
+
- **「anatomy 缺 Inspector / SizeMatrix」** → applicable-where-meaningful policy(見 `.claude/skills/story-writing/references/anatomy-standard.md`);AspectRatio 沒 Inspector / Badge 沒 SizeMatrix 都可能是 N/A + 有 rationale。**先 grep spec 是否有「無 X story,因為...」段**
|
|
30
|
+
- **「ARIA / tabIndex 不對」** → Radix primitives 內建 roving-tabindex / focus management。flag 前驗證該元件是否 wrap Radix;wrap 就豁免
|
|
31
|
+
- **「decorative indicator 被誤列入 action predicate」(D6e,2026-04-22)** → `pointer-events-none` + `aria-hidden` 的 icon 不該出現在 action example 表。Calendar / status dot / CircularProgress 等被誤收 = P0 flag。對照 CLAUDE.md M9 predicate 自測
|
|
32
|
+
- **「Row action 尺寸 > 24」(D6e cap 違反,2026-04-22)** → row primitive 內 inline action 絕對值 cap = 24,row tier 放大不該讓 action 同步放大。違反 = P0 flag。對照 `patterns/element-anatomy/item-anatomy.spec.md`「Inline Action 設計規格」Row ≤ 24 cap
|
|
33
|
+
|
|
34
|
+
## Dimension Type Taxonomy (CLAUDE.md「Consistency Audit 原則」)
|
|
35
|
+
|
|
36
|
+
Every dimension below is tagged **Absolute** or **Consistency** so sub-agents apply the right formula:
|
|
37
|
+
|
|
38
|
+
| Type | Meaning | Audit formula |
|
|
39
|
+
|------|---------|---------------|
|
|
40
|
+
| **Absolute** | Violation = bug regardless of context. No rationale exempts. Fix required. | `actual == canonical` else VIOLATION |
|
|
41
|
+
| **Consistency** | Canonical behavior defined; deviation allowed IF documented rationale in designated home. | `actual == canonical OR (actual != canonical AND rationale present)` else VIOLATION |
|
|
42
|
+
|
|
43
|
+
**Sub-agent protocol(強化,2026-04-21)**: Consistency 類 finding 必走 3 步 before 回報 VIOLATION:
|
|
44
|
+
1. Grep 元件 spec.md 全文(不只 anchor 區)— 找 deviation 對應的 rationale prose
|
|
45
|
+
2. 檢查 scope defaults 是否適用(Field 家族 / semantic token / wrapper 類 / Radix 包)
|
|
46
|
+
3. 兩者皆不豁免 → VIOLATION;任一豁免 → `deviation ✓`(仍列出但不 block)
|
|
47
|
+
|
|
48
|
+
Every dimension header below has three lines:
|
|
49
|
+
- **Type**: Absolute / Consistency
|
|
50
|
+
- **Canonical source**: the document segment that defines correct behavior
|
|
51
|
+
- **Rationale home**: where to look for deviation justification (`N/A` for Absolute)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
# Group A — Correctness (P0 priority)
|
|
56
|
+
|
|
57
|
+
## 1. cva defaultVariants 三方漂移
|
|
58
|
+
|
|
59
|
+
**Type**: Absolute
|
|
60
|
+
**Canonical source**: component .tsx `cva(...)` is the source of truth; spec.md prop table + anatomy SIZE_SPECS must mirror exactly
|
|
61
|
+
**Rationale home**: N/A — three-way drift is always a bug (SegmentedControl precedent)
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
Your job: audit cva `defaultVariants` three-way consistency (code vs spec.md vs anatomy story) across ALL variant keys.
|
|
65
|
+
|
|
66
|
+
For each component in packages/design-system/src/components/ with a `defaultVariants` block:
|
|
67
|
+
1. Grep its `cva(...)` — identify every `defaultVariants` key + value
|
|
68
|
+
2. Check `.spec.md` prop table / docblock — `★` / `預設` / `default` markers
|
|
69
|
+
3. Check `.tsx` top-of-file docblock (JSDoc)
|
|
70
|
+
4. Check `.anatomy.stories.tsx` SIZE_SPECS / prop table / default markers
|
|
71
|
+
|
|
72
|
+
Report ONLY mismatches. Format:
|
|
73
|
+
- `ComponentName: cva says X='A', spec.md:N says ★B, anatomy:M says C`
|
|
74
|
+
|
|
75
|
+
End: `N components checked, M mismatches.` Under 400 words. Don't fix.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 2. SSOT dead link
|
|
79
|
+
|
|
80
|
+
**Type**: Absolute
|
|
81
|
+
**Canonical source**: `.claude/rules/spec-rules.md` SSOT anchors list; every pointer must resolve to an actual `##`/`###` heading OR actual filesystem path
|
|
82
|
+
**Rationale home**: N/A — dead link is never acceptable
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
Your job: verify all SSOT pointers in .spec.md / .tsx files resolve (1) to real headings AND (2) to real filesystem paths.
|
|
86
|
+
|
|
87
|
+
## Part A — Heading anchor checks
|
|
88
|
+
Grep patterns to collect:
|
|
89
|
+
- `\.spec\.md「[^」]+」`
|
|
90
|
+
- `\.spec\.md\s*的「[^」]+」`
|
|
91
|
+
|
|
92
|
+
For each `xxx.spec.md「HEADING」`:
|
|
93
|
+
1. Open xxx.spec.md
|
|
94
|
+
2. Verify a `##` or `###` heading matching HEADING exactly exists
|
|
95
|
+
3. Report mismatches with `file:line — pointer — actual closest heading`
|
|
96
|
+
|
|
97
|
+
## Part B — File path existence checks(2026-04-22 補盲點)
|
|
98
|
+
|
|
99
|
+
先前盲點:只檢 heading anchor「」,未檢 bare file-path reference。例如 item-anatomy.spec.md 曾寫
|
|
100
|
+
`→ packages/design-system/src/ELEMENT-ANATOMY.md`(此 file 從未存在),agent 視為 legitimate 因為
|
|
101
|
+
無「」anchor 落在檢測外。
|
|
102
|
+
|
|
103
|
+
Grep patterns:
|
|
104
|
+
- `src/[a-zA-Z0-9/_.-]+\.(md|tsx|ts)` 作為 pointer 出現在 .md / .tsx 文件內(非 import)
|
|
105
|
+
- 尤其 ALL-CAPS filename convention(`ELEMENT-ANATOMY.md` / `CLAUDE.md` / `README.md` 等)
|
|
106
|
+
- 注意排除 code comments 講路徑但實為 illustration 的(e.g. `// 見 src/...`)
|
|
107
|
+
|
|
108
|
+
For each file-path reference:
|
|
109
|
+
1. `test -f <path>` 檢查 file 實際存在
|
|
110
|
+
2. 若 pointer 指向不存在的 file → P0 dead pointer
|
|
111
|
+
3. 若 pointer 指向 file 但 file 已 rename / moved → suggest correct path
|
|
112
|
+
|
|
113
|
+
## Part C — Spec self-placement consistency(2026-04-22 新增)
|
|
114
|
+
|
|
115
|
+
檢查 spec 是否自稱在某個位置但實際 location 不符(doc drift):
|
|
116
|
+
|
|
117
|
+
- Grep spec.md 開頭段落中「放/住/位於」等 location claim
|
|
118
|
+
- 例:「本檔放頂層 `packages/design-system/src/`」但檔案實際在 `patterns/element-anatomy/`
|
|
119
|
+
- Cross-check with `packages/design-system/src/README.md` 的 home governance 決策
|
|
120
|
+
- 若 claim 不符實際 → Flag「self-placement drift」
|
|
121
|
+
|
|
122
|
+
End: `N pointers checked, M heading-dead, K path-dead, L self-placement drift.` Under 400 words. Don't fix.
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## 3. SSOT reciprocal
|
|
126
|
+
|
|
127
|
+
**Type**: Absolute
|
|
128
|
+
**Canonical source**: `.claude/rules/spec-rules.md` → "reciprocal 必須存在,不可單向"
|
|
129
|
+
**Rationale home**: N/A — single-direction SSOT is a bug
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
Your job: verify every cross-spec SSOT pointer has a reciprocal pointer back.
|
|
133
|
+
|
|
134
|
+
CLAUDE.md rule: "Own 方寫深度 section;被指方寫一行 pointer (reciprocal 必須存在,不可單向)".
|
|
135
|
+
|
|
136
|
+
For each pointer A → B「section」 found:
|
|
137
|
+
1. Open B.spec.md
|
|
138
|
+
2. Search for a pointer back to A.spec.md (anywhere, any format)
|
|
139
|
+
3. If missing, flag as non-reciprocal
|
|
140
|
+
|
|
141
|
+
Common patterns of reverse pointer:
|
|
142
|
+
- `../A/A.spec.md` in 「相關」section
|
|
143
|
+
- Inline `詳見 ../A/A.spec.md` reference
|
|
144
|
+
|
|
145
|
+
Report: `A.spec.md → B.spec.md:N — B 未指回 A`
|
|
146
|
+
|
|
147
|
+
Focus on current SSOT anchors (`.claude/rules/spec-rules.md` lists them):
|
|
148
|
+
- tabs ↔ segmented-control
|
|
149
|
+
- select ↔ radio-group
|
|
150
|
+
- checkbox ↔ switch
|
|
151
|
+
- hover-card ↔ tooltip
|
|
152
|
+
- item-layout ↔ row primitive consumers (MenuItem / TreeItem / SidebarMenuButton / Steps)
|
|
153
|
+
- field-controls ↔ Field family consumers
|
|
154
|
+
|
|
155
|
+
End: `N pointers checked, M non-reciprocal.` Under 400 words. Don't fix.
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## 4. Tailwind v4 / tailwind-merge grep
|
|
159
|
+
|
|
160
|
+
**Type**: Absolute
|
|
161
|
+
**Canonical source**: `.claude/rules/ui-development.md`「Tailwind 5 條核心」 → "Tailwind v4 任意值" + "tailwind-merge 自訂 utility 註冊" bug patterns
|
|
162
|
+
**Rationale home**: N/A — these are technical bugs (Sidebar `[--foo]` / `text-body` misclassification)
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
Your job: grep for known Tailwind-related bug patterns.
|
|
166
|
+
|
|
167
|
+
Check 1 — Tailwind v4 任意值缺 `var()` 包覆:
|
|
168
|
+
- Grep `className=.*\[--[a-z]` (e.g., `w-[--sidebar-width]`)
|
|
169
|
+
- Must be `var(--sidebar-width)` form
|
|
170
|
+
- False positive exclusions: `[&[data-...]]` / `[&:hover]` etc (arbitrary variants, not arbitrary values)
|
|
171
|
+
|
|
172
|
+
Check 2 — tailwind-merge 自訂 utility 未註冊:
|
|
173
|
+
- Find custom font-size / text-color utilities used in `className={cn(...)}`
|
|
174
|
+
- Cross-reference with `src/lib/utils.ts` tailwind-merge config
|
|
175
|
+
- Flag any custom `text-*` / `bg-*` / `border-*` utility not explicitly registered
|
|
176
|
+
|
|
177
|
+
Check 3 — Unused Swatch / TokenCell helper after past edits:
|
|
178
|
+
- If a file has `const Swatch = ...` but no `<Swatch` usage, flag
|
|
179
|
+
|
|
180
|
+
Report: `file:line — violation type — suggested fix`
|
|
181
|
+
|
|
182
|
+
End: `N .tsx files checked, M violations.` Under 400 words. Don't fix.
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## 5. Token 消費紀律
|
|
186
|
+
|
|
187
|
+
**Type**: Absolute
|
|
188
|
+
**Canonical source**: `.claude/rules/ui-development.md`「Tailwind 5 條核心」 → 禁止清單 (hex / rgb / shadow-md/sm / raw px 等)
|
|
189
|
+
**Rationale home**: N/A — tokens bypass breaks dark mode / density / brand-swap
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
Your job: grep packages/design-system/src/components/*.tsx for hardcoded color values, pixel values, or magic numbers that should use tokens.
|
|
193
|
+
|
|
194
|
+
Flag:
|
|
195
|
+
- Hex colors: `#[0-9a-fA-F]{3,8}` (except within SVG / storybook-only files)
|
|
196
|
+
- rgb/rgba literals: `rgb\(|rgba\(`
|
|
197
|
+
- Pixel values in className like `w-[48px]`, `h-[32px]` when a token exists (e.g., `--field-height-md` is 32px)
|
|
198
|
+
- Inline style with raw color: `style={{ color: '#...', backgroundColor: 'rgba(...)' }}`
|
|
199
|
+
|
|
200
|
+
Don't flag:
|
|
201
|
+
- Opacity values (0.45, 0.6 etc)
|
|
202
|
+
- Generic `w-full` / `h-auto` / Tailwind-native sizes
|
|
203
|
+
- Story/anatomy files (those are visualization)
|
|
204
|
+
- SVG stroke/fill (these may need raw values for currentColor tricks)
|
|
205
|
+
|
|
206
|
+
Report: `file:line — hardcoded value — likely token replacement`
|
|
207
|
+
|
|
208
|
+
End: `N component .tsx files checked, M violations.` Under 500 words. Don't fix.
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
# Group B — Spec hygiene (P1 priority)
|
|
214
|
+
|
|
215
|
+
## 6. Spec Rule A 文字品質
|
|
216
|
+
|
|
217
|
+
**Type**: Absolute
|
|
218
|
+
**Canonical source**: `.claude/rules/spec-rules.md` → Spec 文字品質 (不描述視覺形狀 / 實作細節 / 術語一致)
|
|
219
|
+
**Rationale home**: N/A — visual metaphors / raw px / Tailwind class dumps in spec are always defects
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
Your job: audit all .spec.md under packages/design-system/src/ against Rule A in `.claude/rules/spec-rules.md`.
|
|
223
|
+
|
|
224
|
+
Rule A — no visual-form / implementation pollution. Flag:
|
|
225
|
+
- Visual: 「窄長形」/ 「圓圓的」/ 「凸起」/ 「扁平」/ 「跳動」/ 「崩潰」/ 「看不出 X 邊界」/「看起來像 Y」
|
|
226
|
+
- Implementation leak: raw pixel values in running text (`5.5px`, `21px`), Tailwind class lists (`bg-muted rounded-md px-3`), CSS literal (`display: flex; gap: 8px;`), pseudo-element selectors (`::after`, `bottom: -1px`)
|
|
227
|
+
- Physical metaphors: 「空心洞」「浮在上面的異物」(ok in stories, NOT spec)
|
|
228
|
+
|
|
229
|
+
Don't flag:
|
|
230
|
+
- Token names (`--field-height-md`, `var(--primary)`)
|
|
231
|
+
- cva variant string literals
|
|
232
|
+
- SSOT pointers referencing class names
|
|
233
|
+
|
|
234
|
+
Report: `file:line — 違規句 — 替換方向`
|
|
235
|
+
End: `N specs checked, V violations, top offenders: [list]` Under 500 words. Don't fix.
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## 7. Spec Rule B 邊界案例
|
|
239
|
+
|
|
240
|
+
**Type**: Consistency
|
|
241
|
+
**Canonical source**: `.claude/rules/spec-rules.md` → 邊界案例覆蓋 + Scope 預設 (Field family delegates to field-controls, Separator/Skeleton/CircularProgress/ProgressBar claim 無互動狀態, etc.)
|
|
242
|
+
**Rationale home**: element .spec.md —「本元件無 X 狀態」/「由 {family} spec 繼承」 one-liner acceptable
|
|
243
|
+
|
|
244
|
+
```
|
|
245
|
+
Your job: audit all .spec.md against Rule B in `.claude/rules/spec-rules.md` → 邊界案例覆蓋 (apply Scope 預設).
|
|
246
|
+
|
|
247
|
+
For each spec check:
|
|
248
|
+
- disabled / loading / empty
|
|
249
|
+
- dark mode (flag only if custom palette beyond semantic tokens)
|
|
250
|
+
- density (flag only if not using field-height/layout-space tokens)
|
|
251
|
+
- icon-only (flag only if component supports icon-only)
|
|
252
|
+
|
|
253
|
+
Scope defaults (do NOT flag if):
|
|
254
|
+
- Field-family component delegating to field-controls.spec.md
|
|
255
|
+
- Pure wrappers (Separator/Skeleton/CircularProgress/ProgressBar) claiming "無互動狀態"
|
|
256
|
+
- Dark mode handled by semantic token
|
|
257
|
+
|
|
258
|
+
Report GENUINE gaps only: `ComponentName — missing: X / Y` + why not N/A
|
|
259
|
+
|
|
260
|
+
End: `N specs checked, M genuine gaps, L scope-N/A accepted.` Under 500 words. Don't fix.
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
## 8. 7-維度 對標覆蓋
|
|
264
|
+
|
|
265
|
+
**Type**: Consistency
|
|
266
|
+
**Canonical source**: `.claude/rules/spec-rules.md` → 對標世界級 DS 七維度 (何時用 / 不用 / 近親分界 / 誤解 / 相關 / 空值 / 驗證時機 / Loading / a11y)
|
|
267
|
+
**Rationale home**: element .spec.md — 某維度 N/A 時須一行說明 (「本元件為純版面 primitive,無驗證時機」)
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
Your job: for each .spec.md, verify coverage of the 7 world-class DS dimensions (`.claude/rules/spec-rules.md` → 對標世界級 DS).
|
|
271
|
+
|
|
272
|
+
The 7 dimensions:
|
|
273
|
+
1. 何時用 / 何時不用 (when to use / not use)
|
|
274
|
+
2. 與近親元件的分界 (vs neighboring components — SSOT)
|
|
275
|
+
3. 常見誤解 / 禁止事項 (common misuses)
|
|
276
|
+
4. 相關元件 links (related)
|
|
277
|
+
5. 空值呈現 (empty state)
|
|
278
|
+
6. 驗證時機 (validation timing — for form-related)
|
|
279
|
+
7. Loading / 無障礙預設 (loading / a11y defaults)
|
|
280
|
+
|
|
281
|
+
For each spec, list which dimensions are missing that should be present (apply judgment — pure layout primitives may skip 6/7, behavior primitives may skip 5).
|
|
282
|
+
|
|
283
|
+
Report: `ComponentName — covered: [list] | missing: [list]`
|
|
284
|
+
|
|
285
|
+
Include: analysis of 3 specs as exemplars (Button / SegmentedControl / Badge should hit all 7 if applicable).
|
|
286
|
+
|
|
287
|
+
End: `N specs checked, average dimensions covered: X/7. Specs needing most attention: [top 5]`. Under 600 words. Don't fix.
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
# Group C — Code conformance (P1 priority)
|
|
293
|
+
|
|
294
|
+
## 9. shadcn passthrough 完整度
|
|
295
|
+
|
|
296
|
+
**Type**: Consistency
|
|
297
|
+
**Canonical source**: `.claude/rules/ui-development.md`「shadcn 元件規範」 — forwardRef / displayName / ...props / cva / Radix data-attrs / asChild
|
|
298
|
+
**Rationale home**: element .spec.md — internal helper / non-Slot primitives may skip asChild with documented reason
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
Your job: check every component .tsx in packages/design-system/src/components/ for shadcn structural completeness.
|
|
302
|
+
|
|
303
|
+
Each component's main exported component must have:
|
|
304
|
+
1. `React.forwardRef<...>` (ref forwarded to DOM)
|
|
305
|
+
2. `displayName` set
|
|
306
|
+
3. `...props` spread to DOM
|
|
307
|
+
4. cva() managing variants (if has variants)
|
|
308
|
+
5. Radix data-state / data-disabled / data-orientation preserved (if wraps Radix)
|
|
309
|
+
6. `asChild` support OR documented reason not to (if wraps Radix Slot-compatible primitive)
|
|
310
|
+
|
|
311
|
+
Flag components missing any of these. Report per component:
|
|
312
|
+
- `ComponentName — missing: forwardRef / displayName / ...props / asChild / radix data-attribute`
|
|
313
|
+
|
|
314
|
+
Exclude:
|
|
315
|
+
- Internal-only helpers (SelectionItem, anatomy-utils)
|
|
316
|
+
- Simple function components that aren't the main export
|
|
317
|
+
|
|
318
|
+
Report: `N components checked, M with holes.` Under 500 words. Don't fix.
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## 10. a11y 基本覆蓋
|
|
322
|
+
|
|
323
|
+
**Type**: Consistency (mostly Absolute)
|
|
324
|
+
**Canonical source**: WCAG + `.claude/rules/ui-development.md` (keyboard handlers / aria-label on icon-only / form labels)
|
|
325
|
+
**Rationale home**: element .spec.md — decorative/internal primitives may document aria-hidden or omitted role with reason
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
Your job: audit packages/design-system/src/components/ for a11y basics.
|
|
329
|
+
|
|
330
|
+
Check each .tsx and its .stories/.anatomy/.principles:
|
|
331
|
+
1. icon-only interactive elements (Button iconOnly / IconButton) — must have `aria-label`
|
|
332
|
+
2. Interactive elements (onClick / onKeyDown) — must have keyboard handler or role
|
|
333
|
+
3. Form controls — must be properly labeled (Field / FieldLabel or aria-labelledby)
|
|
334
|
+
4. Role semantics — does button use <button>? Does listbox use role="listbox"?
|
|
335
|
+
|
|
336
|
+
DON'T flag:
|
|
337
|
+
- Radix primitives (they manage ARIA internally — Checkbox / Radio / Dialog etc.)
|
|
338
|
+
- Skeleton / CircularProgress (aria-hidden is common pattern)
|
|
339
|
+
- Decorative icons without interactive parent
|
|
340
|
+
|
|
341
|
+
Report: `file:line — missing: aria-label / role / keyboard`
|
|
342
|
+
|
|
343
|
+
End: `N files checked, M a11y gaps, top offenders: [list]`. Under 500 words. Don't fix.
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
# Group D — Story layer (P1 priority)
|
|
349
|
+
|
|
350
|
+
## 11. Story 三層齊全
|
|
351
|
+
|
|
352
|
+
**Type**: Consistency
|
|
353
|
+
**Canonical source**: `.claude/rules/story-rules.md` 三層定位 (Components: 展示 + anatomy + principles;Internal: 展示 + anatomy)
|
|
354
|
+
**Rationale home**: Storybook title classification (`Internal/` → principles optional by design). Components missing a layer without Internal classification = violation
|
|
355
|
+
|
|
356
|
+
```
|
|
357
|
+
Your job: verify every public Components/ folder has all 3 stories:
|
|
358
|
+
- {name}.stories.tsx (showcase)
|
|
359
|
+
- {name}.anatomy.stories.tsx (spec)
|
|
360
|
+
- {name}.principles.stories.tsx (usage principles)
|
|
361
|
+
|
|
362
|
+
For Internal/ folder, only .stories.tsx + .anatomy.stories.tsx required (principles optional).
|
|
363
|
+
|
|
364
|
+
Scan packages/design-system/src/components/ — for each component folder:
|
|
365
|
+
1. List files
|
|
366
|
+
2. Classify: public (Components/) or internal based on Storybook title in .stories.tsx
|
|
367
|
+
3. Report missing layer per classification
|
|
368
|
+
|
|
369
|
+
Report: `ComponentName (classification) — missing: [stories type]`
|
|
370
|
+
|
|
371
|
+
End: `N component folders checked, M missing layers.` Under 400 words. Don't fix.
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
## 12. Story 人話範例
|
|
375
|
+
|
|
376
|
+
**Type**: Absolute
|
|
377
|
+
**Canonical source**: `.claude/rules/story-rules.md` → 範例最高準則 + 禁止清單 (「人」test + 舉一反三 test)
|
|
378
|
+
**Rationale home**: N/A — Lorem ipsum / Option A/B / Variant X / ASCII art have no legitimate use
|
|
379
|
+
|
|
380
|
+
```
|
|
381
|
+
Your job: audit all .stories.tsx + .principles.stories.tsx for placeholder / abstract text per `.claude/rules/story-rules.md` → 範例選擇原則 → 明確禁止.
|
|
382
|
+
|
|
383
|
+
Flag:
|
|
384
|
+
- Placeholder: `Option A/B/C`, `Lorem ipsum`, `foo/bar`, `Item 1/2/3`
|
|
385
|
+
- Abstract 代號: `按鈕一 / 按鈕二`, `Variant X`, `Rule A/B`
|
|
386
|
+
- Extreme unrealistic: single Button with destructive 3-line text, 50-item filter, 5-level dialog
|
|
387
|
+
- Visual symbols: `│─ 業務 ─│`, ASCII art
|
|
388
|
+
- spec 代號: `符合 Rule 3.2`
|
|
389
|
+
- Variant names as visible labels (e.g., literal `<Button>Primary</Button>`)
|
|
390
|
+
|
|
391
|
+
DON'T flag:
|
|
392
|
+
- aria-label / placeholder= / cva value literals
|
|
393
|
+
- Badge/status where the label IS real content
|
|
394
|
+
|
|
395
|
+
Report: `file:line — violating text — real scenario suggestion`
|
|
396
|
+
End: `N files checked, V violations.` Under 600 words. Don't fix.
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## 13. Anatomy Figma-inspect 完整度 + Canonical `export const` 命名 + 中文 `name:` 覆寫
|
|
400
|
+
|
|
401
|
+
**Type**: Consistency
|
|
402
|
+
**Canonical source**: `/story-writing` anatomy-standard.md → 6 件套 (`Overview / Inspector / ColorMatrix / SizeMatrix / StateBehavior / Accessibility`) + 強制中文 `name:` 覆寫(含編號前綴)
|
|
403
|
+
**Rationale home**: element .spec.md — replacing/omitting a 6-canonical section requires a rationale paragraph explaining why (e.g., "Badge 無互動狀態,不需 StateBehavior"). Renaming identifier is never allowed. **`*.anatomy.stories.tsx` 檔頭 `// @anatomy-rationale:` 註解列出 N/A sections + 一行原因 → legitimately N/A,不報為 violation**(對齊 hook `check_story_anatomy.sh` 同源處理)。
|
|
404
|
+
|
|
405
|
+
```
|
|
406
|
+
Your job: audit .anatomy.stories.tsx against `/story-writing` anatomy-standard.md on THREE layers, enforcing CLAUDE.md 「Consistency Audit 原則」.
|
|
407
|
+
|
|
408
|
+
**Layer 1 — Canonical `export const` names** (一字不差, in order):
|
|
409
|
+
1. `Overview` / 2. `Inspector` / 3. `ColorMatrix` / 4. `SizeMatrix` / 5. `StateBehavior` / 6. `Accessibility`(互動元件強制,純視覺 indicator N/A)
|
|
410
|
+
Additional `export const` 7+ allowed (component-specific, no rationale required).
|
|
411
|
+
Replacing 6-canonical with different identifier → VIOLATION regardless of rationale.
|
|
412
|
+
Missing 6-canonical → requires rationale paragraph in .spec.md OR `// @anatomy-rationale:` 檔頭註解列出 N/A sections + 一行原因(legitimate 偏離)。
|
|
413
|
+
|
|
414
|
+
**Layer 2 — Mandatory `name:` 中文覆寫(素顏型,**一律不加序號**)**:
|
|
415
|
+
1. `Overview` → `name: '元件總覽'`
|
|
416
|
+
2. `Inspector` → `name: '元件檢閱器'`
|
|
417
|
+
3. `ColorMatrix` → `name: '色彩對照表'`
|
|
418
|
+
4. `SizeMatrix` → `name: '尺寸對照表'`
|
|
419
|
+
5. `StateBehavior`→ `name: '狀態行為'`
|
|
420
|
+
6. `Accessibility`→ `name: '無障礙與鍵盤'`
|
|
421
|
+
7+ (extras) → `name: '{中文描述}'`(中文命名,**禁止編號前綴**)
|
|
422
|
+
|
|
423
|
+
依賴 `export const` identifier 讓 Storybook sidebar 顯示英文 = VIOLATION(sidebar 中英混雜)。
|
|
424
|
+
帶編號前綴 `name: '1. 元件總覽'` = VIOLATION(2026-05-01 canonical flip:sidebar 順序由 `export const` 順序決定,序號重複 = 視覺噪音)。
|
|
425
|
+
帶括號英文 context `name: 'Orientation(horizontal / vertical)'` = VIOLATION(canonical 命名不應混英文 context)。
|
|
426
|
+
|
|
427
|
+
**Layer 3 — Content hygiene** (only if Layer 1+2 pass):
|
|
428
|
+
- Density dual values (`md density / lg density` columns) — CLAUDE.md forbids
|
|
429
|
+
- `rest` instead of `default` — dev language violation
|
|
430
|
+
- Token name shown without live swatch (`var()` inline style)
|
|
431
|
+
- Raw pixels when token exists
|
|
432
|
+
|
|
433
|
+
**For each `packages/design-system/src/components/*/*.anatomy.stories.tsx`**:
|
|
434
|
+
1. Grep `^export const ([A-Za-z]+)` — Layer 1 identifier list
|
|
435
|
+
2. For each export, grep its `name:` field value — Layer 2 中文覆寫
|
|
436
|
+
3. Check 6-canonical presence + rationale in .spec.md OR `// @anatomy-rationale:` 檔頭註解 for any missing(若 .anatomy.stories.tsx 檔頭有 `// @anatomy-rationale:` 註解,列出 N/A sections 和理由 — 視為 legitimate 偏離,不報為 violation。Hook `check_story_anatomy.sh` 同源處理。)
|
|
437
|
+
|
|
438
|
+
Report format:
|
|
439
|
+
- `ComponentName L1: missing [Inspector, ColorMatrix] — no rationale in spec.md`
|
|
440
|
+
- `ComponentName L1: renamed VisualTokens (not ColorMatrix) — rename forbidden`
|
|
441
|
+
- `ComponentName L2: Overview 無 name 覆寫 (sidebar 顯示英文)` ← 39 件常見
|
|
442
|
+
- `ComponentName L2: ColorMatrix name='3. 色彩對照' 漏「表」字`
|
|
443
|
+
- `ComponentName L2: 素顏型無編號 '元件總覽'`
|
|
444
|
+
- `ComponentName L2: extra story 6 name='6. Orientation(horizontal)' 含英文 context`
|
|
445
|
+
- `ComponentName L3: density dual values in SizeMatrix column`
|
|
446
|
+
- `ComponentName: 6-canonical + name 覆寫完整 + extras [StandardRatios='7. 標準比例'] — OK`
|
|
447
|
+
- `ComponentName: missing StateBehavior — rationale found at badge.spec.md:L45 ✓`
|
|
448
|
+
|
|
449
|
+
End: `N checked, L1 V1 violations, L2 V2 violations, L3 V3 content issues. Top 5 worst: [list]`. Under 900 words. Don't fix.
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
# Group E — System-level (P1 priority)
|
|
455
|
+
|
|
456
|
+
## 14. 命名一致性
|
|
457
|
+
|
|
458
|
+
**Type**: Absolute
|
|
459
|
+
**Canonical source**: CLAUDE.md `# 命名與語言一致性` 各表格 (PascalCase/kebab-case/camelCase 規則 + suffix 鐵律)
|
|
460
|
+
**Rationale home**: N/A — naming rules are meta-rules with no legit exemption
|
|
461
|
+
|
|
462
|
+
```
|
|
463
|
+
Your job: audit the codebase against CLAUDE.md `# 命名與語言一致性` (Meta 規則).
|
|
464
|
+
|
|
465
|
+
Checks:
|
|
466
|
+
1. Component folder = PascalCase (e.g., `DatePicker/`)
|
|
467
|
+
2. Component file = kebab-case (e.g., `date-picker.tsx`)
|
|
468
|
+
3. Pattern folder + file = kebab-case (e.g., `item-layout/item-anatomy.spec.md`)
|
|
469
|
+
4. Hook file = kebab-case (e.g., `use-is-mobile.ts`)
|
|
470
|
+
5. Token folder: single word lowercase / multi camelCase (`color/` / `uiSize/`)
|
|
471
|
+
6. Spec H1 = `# {元件名} 設計原則` pattern
|
|
472
|
+
7. Storybook title = `Design System/{Components|Internal|Patterns|Tokens}/{Name}/{子頁中文}`
|
|
473
|
+
8. Suffix 統一: `.spec.md` / `.stories.tsx` / `.anatomy.stories.tsx` / `.principles.stories.tsx` — no custom suffixes
|
|
474
|
+
9. Single-file comment language consistency (中 file → 中 comments, 英 file → 英 comments)
|
|
475
|
+
|
|
476
|
+
Report: `path — violation — suggested correction`
|
|
477
|
+
|
|
478
|
+
End: `N files checked, M violations across C categories.` Under 600 words. Don't fix.
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
## 15. Cross-doc 一致性(CLAUDE.md + spec.md + tsx docblock 全域 drift)
|
|
482
|
+
|
|
483
|
+
**Type**: Absolute
|
|
484
|
+
**Canonical source**: 各 SSOT home(per `# 資訊治理 canonical` 8-home)
|
|
485
|
+
**Rationale home**: N/A — duplicated / contradictory / drift 永遠是 bug
|
|
486
|
+
|
|
487
|
+
**2026-04-30 擴 scope**:從原「CLAUDE.md 自身」擴到 cross-doc(CLAUDE.md + spec.md +
|
|
488
|
+
tsx docblock + inline comments)— 補本 thread 暴露的 3 個漏洞:
|
|
489
|
+
1. spec.md 兩家描寫同 canonical 不同值(popover 重複 overlay)
|
|
490
|
+
2. tsx docblock claims X 但 spec.md 說 Y(overlay-surface docblock stale 提 xs canonical
|
|
491
|
+
實際 sm+v5 trick)
|
|
492
|
+
3. 元件升級後 docblock 沒同步(stale upgrade marker)
|
|
493
|
+
|
|
494
|
+
```
|
|
495
|
+
Your job: audit cross-doc consistency for CLAUDE.md + all spec.md + tsx docblocks.
|
|
496
|
+
|
|
497
|
+
Checks(原 CLAUDE.md 7 條 + 新 cross-doc 3 條):
|
|
498
|
+
|
|
499
|
+
# CLAUDE.md 自身
|
|
500
|
+
1. No duplicated rules (same rule stated in 2 sections)
|
|
501
|
+
2. No contradictions (section X says "always do A" + Y says "never do A")
|
|
502
|
+
3. Internal section references resolve (`# Story`, `# Spec 規則`等真實存在)
|
|
503
|
+
4. Rule coverage: every item in 「失敗記憶索引」 has an anchor section
|
|
504
|
+
5. Pointer format: `# Section` or `# A → ## B` not mixed
|
|
505
|
+
6. Task navigation table entries all resolve to real sections
|
|
506
|
+
7. Mindset rules referenced in other sections exist
|
|
507
|
+
|
|
508
|
+
# Cross-doc(2026-04-30 擴 scope)
|
|
509
|
+
8. **Cross-spec full duplication**:同 canonical 在 ≥ 2 spec.md 完整描寫(非 pointer)
|
|
510
|
+
= 違 Rule-of-3。grep 同 keyword 的 H2/H3 段落,若內容超過 5 行雷同 → flag。
|
|
511
|
+
Example: "Chrome dismiss size canonical" 完整段在 popover.spec.md + overlay-surface.spec.md
|
|
512
|
+
都有 → 一個必降為 SSOT pointer。
|
|
513
|
+
9. **Docblock-spec drift**:tsx 檔頭 / inline 註解 claim 某 canonical(「v5 unbounded trick
|
|
514
|
+
2026-04-22」「xs canonical」「sm+trick」等),grep 對應 spec.md 是否一致。
|
|
515
|
+
Example: overlay-surface.tsx docblock 寫「unbounded 從 xs canonical」但 inline-action.spec.md
|
|
516
|
+
寫「sm + v5 trick canonical」→ docblock 為 stale,P0 修。
|
|
517
|
+
10. **Stale upgrade markers**:docblock / spec 含日期(`2026-XX-XX`)+ canonical change keyword
|
|
518
|
+
(`canonical`/`upgrade`/`v\d`),檢查實際 tsx code 是否真用該 canonical。
|
|
519
|
+
Example: spec 說「2026-04 升 v5 trick」但 tsx 仍 hardcode xs → drift。
|
|
520
|
+
|
|
521
|
+
Report: `file:line — issue — affected files — suggestion`
|
|
522
|
+
|
|
523
|
+
End: `Total issues found: M. Categories: [breakdown 1-10]`. Under 600 words. Don't fix.
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## Running all 22 in parallel
|
|
529
|
+
|
|
530
|
+
Single message with 20 `Agent` tool calls, each with `run_in_background: true`. Expected wall time: 3-5 minutes for all to complete (they process in parallel server-side).
|
|
531
|
+
|
|
532
|
+
After all return:
|
|
533
|
+
- Consolidate findings per file with line numbers
|
|
534
|
+
- Build priority matrix (P0 / P1 / P2)
|
|
535
|
+
- Present Checkpoint 1 triage to user
|
|
536
|
+
- DO NOT auto-fix P2 without approval
|
|
537
|
+
|
|
538
|
+
---
|
|
539
|
+
|
|
540
|
+
# Group F — Architecture compliance (session-learned)
|
|
541
|
+
|
|
542
|
+
## 16. Layout Family 宣告
|
|
543
|
+
|
|
544
|
+
**Type**: Consistency
|
|
545
|
+
**Canonical source**: CLAUDE.md `# 4-Family Layout Model`
|
|
546
|
+
**Rationale home**: element .spec.md — 聲明「本元件不屬於 4-Family Model」+ reason (self-contained / composite) is an acceptable rationale
|
|
547
|
+
|
|
548
|
+
```
|
|
549
|
+
Your job: verify every component spec.md under packages/design-system/src/components/ has a「Layout Family」declaration in its first section (after 定位/實作基礎, before 何時用).
|
|
550
|
+
|
|
551
|
+
The 4-Family Model (CLAUDE.md `# 4-Family Layout Model`):
|
|
552
|
+
- Family 1: Menu item layout
|
|
553
|
+
- Family 2: List item layout
|
|
554
|
+
- Family 3: Pill layout
|
|
555
|
+
- Family 4: Field control layout
|
|
556
|
+
|
|
557
|
+
Acceptable declarations:
|
|
558
|
+
- "Layout Family: CLAUDE.md 4-Family Model **Family N(...)**消費者"
|
|
559
|
+
- 「本元件不屬於 4-Family Model」+ reason (self-contained primitive / composite)
|
|
560
|
+
|
|
561
|
+
Report components missing the declaration:
|
|
562
|
+
- `ComponentName: no Layout Family declaration` (should be added)
|
|
563
|
+
|
|
564
|
+
Don't flag:
|
|
565
|
+
- Pattern specs (item-layout is the SSOT itself, not a consumer)
|
|
566
|
+
- Internal primitives with documented reason for no Family
|
|
567
|
+
|
|
568
|
+
End: `N component specs checked, M missing Family declaration, top 5: [list]`. Under 300 words. Don't fix.
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
## 17. Prop value 跨元件認知衝突
|
|
572
|
+
|
|
573
|
+
**Type**: Absolute
|
|
574
|
+
**Canonical source**: CLAUDE.md `## 命名必過三重 test` → test #3 (跨元件認知衝突)
|
|
575
|
+
**Rationale home**: N/A — same string with materially different semantic = cognitive dissonance bug (text/rich/picture precedent)
|
|
576
|
+
|
|
577
|
+
```
|
|
578
|
+
Your job: find cross-component prop value collisions that create cognitive dissonance (CLAUDE.md `## 命名必過三重 test` test #3).
|
|
579
|
+
|
|
580
|
+
Grep approach:
|
|
581
|
+
1. Extract all cva variant values + type prop values from every component .tsx
|
|
582
|
+
2. Group by literal string (e.g., all components using value `'text'`)
|
|
583
|
+
3. For each duplicate, compare semantic meaning
|
|
584
|
+
|
|
585
|
+
Flag collisions where same string has materially different semantics:
|
|
586
|
+
- Example: `Button variant="text"` (text-style button, no chrome) vs hypothetical `FileItem mode="text"` (text-based presentation) — same `'text'`, different concept
|
|
587
|
+
- Non-collisions: `size="sm" / "md" / "lg"` across elements is NOT collision (same semantic scale)
|
|
588
|
+
- Non-collisions: same `'error'` for Alert variant and Badge variant IS OK (same semantic)
|
|
589
|
+
|
|
590
|
+
Report: `ComponentA.prop="value" = 語義A | ComponentB.prop="value" = 語義B — 建議改其中一個`
|
|
591
|
+
|
|
592
|
+
End: `N cva/prop definitions scanned, M genuine collisions found. Historical: text/rich/picture naming iteration (fixed)`. Under 500 words. Don't fix.
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
## 18. shadcn compat alias 回流檢查
|
|
596
|
+
|
|
597
|
+
**Type**: Absolute
|
|
598
|
+
**Canonical source**: `.claude/rules/ui-development.md`「Tailwind 5 條核心」 → 「shadcn compat aliases — 不給我們元件用」
|
|
599
|
+
**Rationale home**: N/A — aliases are migration safety net only; human-edited / new code must use direct tokens
|
|
600
|
+
|
|
601
|
+
```
|
|
602
|
+
Your job: grep component .tsx files for shadcn compat aliases that should have been migrated to our direct tokens. This is a **recurring check** — future `npx shadcn add X` may introduce these and we must catch them early.
|
|
603
|
+
|
|
604
|
+
Per CLAUDE.md「shadcn compat aliases — 不給我們元件用」:
|
|
605
|
+
|
|
606
|
+
Forbidden in our code (these SHOULD be migrated to direct tokens):
|
|
607
|
+
- `bg-popover` → `bg-surface-raised`
|
|
608
|
+
- `text-popover-foreground` → `text-foreground`
|
|
609
|
+
- `text-muted-foreground` → `text-fg-muted`
|
|
610
|
+
- `bg-accent` → `bg-neutral-hover`
|
|
611
|
+
- `text-accent-foreground` → `text-foreground`
|
|
612
|
+
- `bg-destructive` → `bg-error`
|
|
613
|
+
- `bg-background` → `bg-canvas`
|
|
614
|
+
- `bg-card` / `text-card-foreground` → `bg-surface` / `text-foreground`
|
|
615
|
+
- `text-primary-foreground` → `text-white`
|
|
616
|
+
- `border-input` → `border-border`
|
|
617
|
+
- `shadow-md / shadow-sm / shadow-lg / shadow-xl / shadow-2xl` → `shadow-[var(--elevation-*)]`
|
|
618
|
+
|
|
619
|
+
OK (these are OUR approved tokens, not shadcn aliases):
|
|
620
|
+
- `bg-muted` (semantic.css keeps --muted as real token)
|
|
621
|
+
- `bg-secondary` (promoted to real token)
|
|
622
|
+
- `ring-ring` (our focus color)
|
|
623
|
+
|
|
624
|
+
Grep `packages/design-system/src/components/**/*.tsx` (exclude .stories/.anatomy/.principles which may legit show token references in demos).
|
|
625
|
+
|
|
626
|
+
Report: `file:line — shadcn alias found — migrate to: [direct token]`
|
|
627
|
+
|
|
628
|
+
End: `N tsx files checked, M alias leakage, typically 0 in clean state`. Under 400 words. Don't fix.
|
|
629
|
+
```
|
|
630
|
+
|
|
631
|
+
# Group G — Home governance (session-learned 2026-04-20)
|
|
632
|
+
|
|
633
|
+
## 19. Home-name-vs-scope 一致性
|
|
634
|
+
|
|
635
|
+
**Type**: Consistency
|
|
636
|
+
**Canonical source**: each folder's charter README (`patterns/*/README.md`, `components/README.md`, `tokens/README.md`, `.claude/skills/*/SKILL.md` description)
|
|
637
|
+
**Rationale home**: charter README —「這裡收 X / 不收 Y」明文即可,不符合就 rename folder 或修 charter
|
|
638
|
+
|
|
639
|
+
```
|
|
640
|
+
Your job: verify each classification home folder's NAME still accurately reflects the scope of content it contains. Session 2026-04-20 learned this the hard way — `item-layout/` absorbed 4-family taxonomy (including Family 3 Pill + Family 4 Field pointers), becoming misleadingly named. Renamed to `item-anatomy/` to match scope.
|
|
641
|
+
|
|
642
|
+
Targets (folders governed by charter READMEs):
|
|
643
|
+
- `packages/design-system/src/patterns/*/`
|
|
644
|
+
- `packages/design-system/src/components/*/`(PascalCase folders)
|
|
645
|
+
- `packages/design-system/src/tokens/*/`
|
|
646
|
+
- `.claude/skills/*/`
|
|
647
|
+
|
|
648
|
+
For each folder `F`:
|
|
649
|
+
1. Read `F/*.spec.md` or `F/SKILL.md` or the primary doc first paragraph (「定位」or frontmatter description)
|
|
650
|
+
2. Extract the declared scope in one sentence
|
|
651
|
+
3. Compare declared scope with folder name:
|
|
652
|
+
- Is folder name a substring of or semantically aligned with the scope?
|
|
653
|
+
- Does folder name UNDER-represent the scope (e.g., `item-layout/` containing 4-family taxonomy)?
|
|
654
|
+
- Does folder name OVER-represent the scope (e.g., `item-anatomy/` containing only Menu item stuff)?
|
|
655
|
+
|
|
656
|
+
Flag mismatches: `folder/ declared scope = X, name implies Y, suggest rename to Z`.
|
|
657
|
+
|
|
658
|
+
Also flag "layout" word collisions:
|
|
659
|
+
- `patterns/*layout*/` at element-level scope MUST use「anatomy」not「layout」(CLAUDE.md 命名鐵律;「layout」保留 page-level)
|
|
660
|
+
- Exception: primitive file name matching folder name (e.g., `item-anatomy/item-anatomy.tsx` exporting slot components `<ItemIcon>` / `<ItemAvatar>` / etc. following Material/Polaris/Radix compound-component idiom) — allowed and encouraged
|
|
661
|
+
|
|
662
|
+
Report: `F: scope "..." vs name "..." — rename candidate: Z`
|
|
663
|
+
|
|
664
|
+
End: `N folders audited, M rename candidates, top 3: [list]`. Under 400 words. Don't rename.
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
## 20. Spec 硬寫機械化值檢查
|
|
668
|
+
|
|
669
|
+
**Type**: Consistency
|
|
670
|
+
**Canonical source**: `.claude/rules/spec-rules.md` →「spec 只記錄設計原則,可程式化規則寫 .tsx」
|
|
671
|
+
**Rationale home**: element/pattern .spec.md — token spec 本身 / pattern rationale 節 / historical bug anchor 可合法保留具體數值,需有一行說明為何在此
|
|
672
|
+
|
|
673
|
+
```
|
|
674
|
+
Your job: grep spec.md files for mechanical values that should live in .tsx, not spec. Per CLAUDE.md 「spec 只記錄設計原則,可程式化規則寫 .tsx」.
|
|
675
|
+
|
|
676
|
+
Forbidden in spec.md(should migrate to tsx/cva):
|
|
677
|
+
- Hardcoded px values: `\d+px` outside of「藍圖」/「尺寸對照表」/ pattern explanation contexts
|
|
678
|
+
- Literal Tailwind utility classes: `className="..."` / `w-\d` / `h-\d` / `p-\d` / `gap-\d` blocks outside code fences showing WHY the value exists
|
|
679
|
+
- CVA variant object literals(those belong in tsx)
|
|
680
|
+
|
|
681
|
+
OK in spec(these are 判斷性 explanations):
|
|
682
|
+
- Token names: `--field-height-md`, `h-field-sm` (referring to the token, not instructing concrete code)
|
|
683
|
+
- Approximate size ranges in design reasoning: "roughly 16-20px"
|
|
684
|
+
- Code examples within ``` fences showing intended usage
|
|
685
|
+
|
|
686
|
+
Report per hit: `spec.md:line — hardcoded [value] — should live in [component-name].tsx`.
|
|
687
|
+
|
|
688
|
+
Don't flag:
|
|
689
|
+
- `tokens/*.spec.md` (token specs legitimately declare values)
|
|
690
|
+
- `patterns/element-anatomy/item-anatomy.spec.md`「Inline Action 設計規格」(documents why 16/20/24 size tiers — pattern rationale, belongs here)
|
|
691
|
+
- Historical bug anchors(「曾發生 padding 8px 錯位」is narrative, not instruction)
|
|
692
|
+
|
|
693
|
+
End: `N specs checked, M hardcoded violations, top 5: [list]`. Under 400 words. Don't fix.
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
## 21. Stories / consumer code 手刻繞 DS canonical(視覺對齊盲點的可機械化前哨)
|
|
699
|
+
|
|
700
|
+
**Type**: Absolute
|
|
701
|
+
**Canonical source**: `.claude/rules/ui-development.md`「Story / consumer code 禁止手刻既有 DS 元件已支援的 pattern」+ 元件 spec.md(提供的 API)
|
|
702
|
+
**Rationale home**: N/A — hand-craft 繞 DS canonical 是 absolute bug,不容 rationale 例外
|
|
703
|
+
|
|
704
|
+
**背景**:pixel-level 視覺對齊無法 grep(需 visual regression 工具,長期基建 tech debt)。但「stories 自刻 `absolute + translate-y-1/2` 繞過 DS 元件的 loading / overlay / search 等 pattern」是**強信號**——這類 hand-craft 在不同 size / density 下視覺對齊跑掉,是視覺 bug 的上游。本 dim 抓 hand-craft 反 canonical 路徑,預防視覺 bug 進 production。
|
|
705
|
+
|
|
706
|
+
```
|
|
707
|
+
Your job: grep stories (.stories.tsx / .anatomy.stories.tsx / .principles.stories.tsx) and non-DS consumer code for hand-crafted patterns that bypass existing DS component APIs. Per CLAUDE.md 「Story / consumer code 禁止手刻既有 DS 元件已支援的 pattern」.
|
|
708
|
+
|
|
709
|
+
Hand-craft 反 canonical 的強信號 pattern(每個違反 → VIOLATION):
|
|
710
|
+
|
|
711
|
+
**A. 自刻 Input loading(繞過 `<Input loading/>` prop)**:
|
|
712
|
+
- grep: `<div className="[^"]*relative[^"]*">[\s\S]*?<input[\s\S]*?absolute[\s\S]*?translate-y-1/2[\s\S]*?</div>` (multiline)
|
|
713
|
+
- 或: 同檔案近距離出現 `<input` + `absolute.*(translate-y-1/2|top-1/2)` + (`CircularProgress` / `Loader2`)
|
|
714
|
+
- 正確做法: `<Input startIcon={Search} loading />`
|
|
715
|
+
|
|
716
|
+
**B. 自刻 Field endAction loading(繞過元件 `loading` prop)**:
|
|
717
|
+
- grep: NumberInput / Combobox / Select / DatePicker 鄰近 `CircularProgress` / `Loader2` 非 consumer 導出
|
|
718
|
+
- 正確做法: 元件 `loading` prop(若元件沒支援 → 回元件 spec 討論擴 API,不自刻)
|
|
719
|
+
|
|
720
|
+
**C. 自刻全頁 loading overlay(繞過 `<Empty icon={<CircularProgress/>}/>` compose)**:
|
|
721
|
+
- grep: `absolute\s+inset-0[\s\S]*?flex[\s\S]*?items-center[\s\S]*?justify-center[\s\S]*?(CircularProgress|Loader2)`
|
|
722
|
+
- 正確做法: `<Empty icon={<CircularProgress size={48}/>} title="..." description="..."/>`
|
|
723
|
+
|
|
724
|
+
**D. 自刻 search field(繞過 `<Input startIcon={Search}/>`)**:
|
|
725
|
+
- grep: `<input[\s\S]*?type=["']?(text\|search)` + `Search.*size=\{16\}` + 在同一個 JSX tree 非 DS 元件消費 context
|
|
726
|
+
- 正確做法: `<Input startIcon={Search} placeholder="..."/>`
|
|
727
|
+
|
|
728
|
+
**E. 自刻 table loading row/cell(繞過 DataTable loading 能力)**:
|
|
729
|
+
- grep: `<table` 手刻 + CircularProgress / Loader2 在內
|
|
730
|
+
- 正確做法: `<DataTable loading/>` 或 DataTable empty state slot `<Empty icon={<CircularProgress/>}/>`
|
|
731
|
+
|
|
732
|
+
**Exemption(唯一合法自刻場景)**:
|
|
733
|
+
- `.principles.stories.tsx` 的 ❌ Don't 範例(示範錯誤 pattern 給 reader 看的反例)— 必須明確標 ❌ 或 `Don't` label
|
|
734
|
+
- 探索性 `/explorations/` prototype 暫時 code(但要標註「pattern 缺口,pending DS 擴 API」)
|
|
735
|
+
|
|
736
|
+
For each violation:
|
|
737
|
+
1. File:line + hand-craft 片段
|
|
738
|
+
2. 違反哪個 signal(A/B/C/D/E)
|
|
739
|
+
3. 建議 canonical 路徑(要用哪個元件的什麼 prop)
|
|
740
|
+
|
|
741
|
+
Report format:
|
|
742
|
+
- `path/to/story.stories.tsx:L42 [signal A] — 手刻 Input + absolute CircularProgress,改用 <Input loading/>`
|
|
743
|
+
- `path/to/explorations/x.tsx:L88 [signal C] — 手刻全頁 overlay,改用 <Empty icon={<CircularProgress/>}/>`
|
|
744
|
+
|
|
745
|
+
End: `N files checked, V violations by signal: A=?, B=?, C=?, D=?, E=?. Top 5 worst: [list]`. Under 700 words. Don't fix.
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
---
|
|
749
|
+
|
|
750
|
+
**後續待辦(已記 memory tech debt)**:pixel-level 視覺 regression 基建(Chromatic / Playwright screenshots)— 本 dim 只是**上游攔截**,不涵蓋「已用對 API 但視覺仍跑掉」的 pixel bug。真正視覺對齊 audit 需要視覺工具,不是 grep 能 cover 的維度。
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
# Group H — Principle self-audit (D6 子維,session-learned 2026-04-22)
|
|
755
|
+
|
|
756
|
+
## 22. D6e Predicate coherence(對齊 CLAUDE.md Meta-Pattern M9)
|
|
757
|
+
|
|
758
|
+
**Type**: Consistency
|
|
759
|
+
**Canonical source**: `.claude/skills/design-system-audit/references/principle-audit-protocol.md` → D6e Predicate coherence scan;CLAUDE.md `# Meta-Pattern 預警` M9(Predicate Self-Test)
|
|
760
|
+
**Rationale home**: spec.md — 若某 example 故意違反 predicate(教學反例),必在旁邊明示「反例」/「故意違反 X cap」;cap 值本身更動需在 spec 留 rationale + benchmark
|
|
761
|
+
|
|
762
|
+
```
|
|
763
|
+
Your job: audit spec.md 內「含 decision tree + example 表 + cap / predicate 定義」的 spec(典型:item-anatomy「Inline Action 設計規格」/ button「Dismiss canonical」/ action-bar predicate 等),走 D6e 4 題 coherence check 防 predicate drift。
|
|
764
|
+
|
|
765
|
+
**Phase 0(必跑)**:grep 專案所有 `patterns/**/*.spec.md` + `components/**/*.spec.md` 找 predicate / decision tree / example 表位置,列清單。
|
|
766
|
+
|
|
767
|
+
**Per predicate spec 4 題 scan**:
|
|
768
|
+
|
|
769
|
+
Q1. **Membership drift** — example 表每一筆 literally 符合 predicate?
|
|
770
|
+
- `pointer-events-none` / `aria-hidden` icon 不該列入 action predicate(decorative indicator)
|
|
771
|
+
- Trash / Delete / Clear / Remove 不該列入 Dismiss predicate(Dismiss 嚴格 = X close only)
|
|
772
|
+
- 邊界 case(status dot / loading indicator / badge overlay)歸屬是否明示
|
|
773
|
+
|
|
774
|
+
Q2. **Cap / size 違反** — example 的幾何值符合 predicate 定義的 cap?
|
|
775
|
+
- Row action 絕對值 cap = 24 — example 是否 row tier 放大就讓 action 同步放大(違反 cap)
|
|
776
|
+
- Dismiss 尺寸統一 — example 是否有 tier 自己另訂尺寸
|
|
777
|
+
|
|
778
|
+
Q3. **World-class 對照覆蓋** — 每個 predicate 決策都有至少 3 家 world-class DS 對照?
|
|
779
|
+
- Polaris / Material / Atlassian / Apple HIG / Ant / Carbon / Figma / Linear 至少 3 家
|
|
780
|
+
- 對照缺 = predicate 根據薄 → P1 flag(請補 benchmark 或 downgrade 為 heuristic 不上升 canonical)
|
|
781
|
+
|
|
782
|
+
Q4. **Empty category** — predicate 有 category 但 example 表沒 real case?
|
|
783
|
+
- 空 category = 概念未收斂 / predicate 未完成 → P1 flag
|
|
784
|
+
|
|
785
|
+
**報告格式**:
|
|
786
|
+
- `spec.md:L42 [Q1 membership drift] — DatePicker Calendar icon 列入 Inline Action 但 pointer-events-none / aria-hidden → 改歸 decorative indicator`
|
|
787
|
+
- `spec.md:L88 [Q2 cap 違反] — FileItem rich row 56 → Button size md (32) 違反 row ≤ 24 cap`
|
|
788
|
+
- `spec.md:L120 [Q3 benchmark 缺] — overlay close X 無 world-class 對照 → 補 Material / Polaris / Apple HIG`
|
|
789
|
+
- `spec.md:L200 [Q4 empty] — Cat 3 standalone action 無 real example → 待補或刪 category`
|
|
790
|
+
|
|
791
|
+
End: `N predicate specs scanned, V1/V2/V3/V4 violations by Q. Top offenders: [list]`. Under 600 words. Don't fix.
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
## 23. Benchmark-First discipline(對齊 CLAUDE.md Meta-Pattern M8)
|
|
795
|
+
|
|
796
|
+
**Type**: Consistency
|
|
797
|
+
**Canonical source**: CLAUDE.md `# Meta-Pattern 預警` M8(訂 canonical 前必 benchmark 至少 3 家 world-class);principle-audit-protocol.md D6e Q3
|
|
798
|
+
**Rationale home**: spec.md / memory — 若 canonical 刻意偏離 benchmark 或 benchmark 不適用,需明文 rationale
|
|
799
|
+
|
|
800
|
+
```
|
|
801
|
+
Your job: audit「spec 訂 canonical 決策」是否前置 benchmark(M8)。防「憑直覺訂 → 疊代 4 次 → user 拉回」bug class(2026-04-22 Icon Action Primitive 案例)。
|
|
802
|
+
|
|
803
|
+
For each canonical declaration in spec.md(任何「Row action cap = X」「Dismiss 嚴格 = X only」「predicate A vs B 分類」等 canonical 聲明):
|
|
804
|
+
1. 該段落 / 近區有無至少 3 家 world-class DS 對照(Polaris / Material / Atlassian / Apple HIG / Ant / Carbon / Figma / Linear / Notion)
|
|
805
|
+
2. 有對照 → `benchmark ✓`
|
|
806
|
+
3. 無對照但在 memory / CLAUDE.md `# Meta-Pattern` 有 rationale → `rationale ✓`
|
|
807
|
+
4. 兩者皆無 → P1 flag「canonical 無 benchmark 根據,疑似憑直覺訂」
|
|
808
|
+
|
|
809
|
+
Report: `spec.md:L{line} — canonical「{宣告}」無 benchmark 對照 → 補 world-class 至少 3 家 or 降級為 heuristic`
|
|
810
|
+
|
|
811
|
+
End: `N canonical declarations scanned, M without benchmark, top 3: [list]`. Under 400 words. Don't fix.
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
---
|
|
815
|
+
|
|
816
|
+
## 21. 連續 item list wrapper gap(consumer 層)
|
|
817
|
+
|
|
818
|
+
**Type**: Consistency
|
|
819
|
+
**Canonical source**: `patterns/element-anatomy/item-anatomy.spec.md`「連續 item 貼邊合法性」公式 3 條 + 元件 spec「List wrapper canonical」(e.g. `components/FileItem/file-item.spec.md`)
|
|
820
|
+
**Rationale home**: consumer code 的 inline comment / 元件 spec「List wrapper canonical」
|
|
821
|
+
|
|
822
|
+
Scan consumer 層(`.tsx` / `.stories.tsx` / `src/explorations/`)對 item 元件的 list wrapper gap 是否正確:
|
|
823
|
+
|
|
824
|
+
1. 公式 1(同類 standalone card/pill list):每個 card/pill 永久視覺層(bg + radius + inset)相鄰必 gap。violation:`<div className="flex flex-col">`(無 gap)下多個 FileItem rich / Card / Chip standalone
|
|
825
|
+
2. 公式 2(同類 flush / transparent list):0 gap 合法,分隔靠 border-b / progress bar / connector。無需 gap → flag 是 FP
|
|
826
|
+
3. 公式 3(混合視覺語言 list):必取最保守 gap。violation:compact FileItem Type A + Type B 混用但無 gap
|
|
827
|
+
|
|
828
|
+
Hook `check_item_list_gap.sh` 已 P2 block 外框 / P1 warn 缺 gap,本 dim 為 audit 層 redundant check 捕遺漏。
|
|
829
|
+
|
|
830
|
+
對每個 list wrapper violation:
|
|
831
|
+
- file:line
|
|
832
|
+
- 元件類型 + 判斷屬哪條公式 violation
|
|
833
|
+
- 建議 gap 值(該元件 spec「List wrapper canonical」指定值)
|
|
834
|
+
|
|
835
|
+
Report format:
|
|
836
|
+
```
|
|
837
|
+
[P0 consumer list wrapper 違反 gap canonical] {file}:{line}
|
|
838
|
+
wrapper: {className}
|
|
839
|
+
children: {item type}
|
|
840
|
+
公式: {1/2/3} → 必 gap {value}
|
|
841
|
+
SSOT: {元件 spec「List wrapper canonical」}
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
End: `N wrappers scanned, M violations, top 3: [list]`. Under 300 words. Don't fix.
|
|
845
|
+
|
|
846
|
+
---
|
|
847
|
+
|
|
848
|
+
## 22. 視覺容器 inner breathing(consumer 層)
|
|
849
|
+
|
|
850
|
+
**Type**: Absolute
|
|
851
|
+
**Canonical source**: `patterns/element-anatomy/element-anatomy.spec.md`「視覺容器 breathing invariant」
|
|
852
|
+
**Rationale home**: N/A(absolute rule · breathing 必存在)
|
|
853
|
+
|
|
854
|
+
Scan consumer 自建的視覺邊界容器(非 chrome primitive 消費)是否有 inner padding:
|
|
855
|
+
|
|
856
|
+
`.tsx` 內 grep pattern `<(div|section|aside|header|footer|main|nav)` 帶以下任一:
|
|
857
|
+
- `bg-(surface|neutral|primary|error|warning|success|info|inverse|overlay)-*` 或 `bg-\[var(--...)\]`
|
|
858
|
+
- `border` 類(非 `border-0` / `border-transparent`)
|
|
859
|
+
- `shadow-\[var(--elevation-...\]` / `shadow-\[...\]`(非 `shadow-none`)
|
|
860
|
+
|
|
861
|
+
若同 className 無 `p-N` / `px-N` / `py-N` / `p-\[var(...)\]` / `pt-N` / `pb-N` → violation。
|
|
862
|
+
|
|
863
|
+
Hook `check_container_breathing.sh` 已 P1 warn,本 dim 為 audit 層捕 hook 遺漏 / 多行 className split 的 case。
|
|
864
|
+
|
|
865
|
+
**排除**(hook 同邏輯):
|
|
866
|
+
- Chrome primitive(SurfaceHeader / SurfaceBody / SurfaceFooter / Field wrapper / Button / Input)= 自帶 canonical padding
|
|
867
|
+
- `@breathing-exempt:` / `@breathing-exempt-next` 標記
|
|
868
|
+
- Specific justification in spec (e.g. SheetBody variant="list" 刻意 `py-2 no px`)
|
|
869
|
+
|
|
870
|
+
對每個 violation 報:
|
|
871
|
+
- file:line
|
|
872
|
+
- container 類型(div/section/etc)
|
|
873
|
+
- 視覺邊界類(bg / border / shadow)
|
|
874
|
+
- 建議 padding token(chrome → `--layout-space-loose/tight`;其他 → `px-3` 等)
|
|
875
|
+
|
|
876
|
+
Report format:
|
|
877
|
+
```
|
|
878
|
+
[P0 視覺容器缺 inner breathing] {file}:{line}
|
|
879
|
+
container: {tag className}
|
|
880
|
+
視覺邊界: {bg / border / shadow}
|
|
881
|
+
SSOT: `patterns/element-anatomy/element-anatomy.spec.md`「視覺容器 breathing invariant」
|
|
882
|
+
```
|
|
883
|
+
|
|
884
|
+
End: `N containers scanned, M violations, top 3: [list]`. Under 300 words. Don't fix.
|
|
885
|
+
```
|
|
886
|
+
|
|
887
|
+
---
|
|
888
|
+
|
|
889
|
+
# Group I — Form & State integrity(2026-04-24 新增,補 24-checklist #3+#12 gap)
|
|
890
|
+
|
|
891
|
+
## 23. Controlled / Uncontrolled dual-mode coherence
|
|
892
|
+
|
|
893
|
+
**Type**: Absolute
|
|
894
|
+
**Canonical source**: React docs + `components/Field/field-controls.spec.md` + 每元件自己 spec 的「controlled / uncontrolled」節(若適用)
|
|
895
|
+
**Rationale home**: 該元件 spec.md(若刻意只支援單一模式須註明)
|
|
896
|
+
|
|
897
|
+
掃所有 form-like + overlay-like 元件的 dual-mode prop 配對,確認不會混用造成 undefined behaviour。
|
|
898
|
+
|
|
899
|
+
**Scan 對象**(`packages/design-system/src/components/**/*.tsx`):
|
|
900
|
+
1. Form controls:`Input / Textarea / Select / Combobox / Checkbox / Radio / Switch / DatePicker / Slider / RadioGroup / CheckboxGroup`
|
|
901
|
+
2. Overlay:`Dialog / Sheet / Popover / DropdownMenu / Tooltip / HoverCard / FileViewer`
|
|
902
|
+
3. Tab-like:`Tabs / Accordion / Collapsible`
|
|
903
|
+
|
|
904
|
+
**Pair 對照表**(每 pair 必同時支援 controlled + uncontrolled,且互斥):
|
|
905
|
+
|
|
906
|
+
| 元件類 | controlled prop | uncontrolled prop | onChange prop |
|
|
907
|
+
|---|---|---|---|
|
|
908
|
+
| text input | `value` | `defaultValue` | `onChange` / `onValueChange` |
|
|
909
|
+
| select / combobox | `value` | `defaultValue` | `onValueChange` |
|
|
910
|
+
| checkbox / switch | `checked` | `defaultChecked` | `onCheckedChange` |
|
|
911
|
+
| radio group | `value` | `defaultValue` | `onValueChange` |
|
|
912
|
+
| overlay open | `open` | `defaultOpen` | `onOpenChange` |
|
|
913
|
+
| tabs / accordion | `value` | `defaultValue` | `onValueChange` |
|
|
914
|
+
|
|
915
|
+
**Violation 定義**:
|
|
916
|
+
- **V1 — missing uncontrolled fallback**:只吃 `value` 不吃 `defaultValue`(forces consumer 必 controlled)
|
|
917
|
+
- **V2 — missing controlled**:只吃 `defaultValue` 不吃 `value`(forces uncontrolled)
|
|
918
|
+
- **V3 — no callback**:有 `value` 但無 `onChange` / `onValueChange`(controlled 模式下狀態無法同步)
|
|
919
|
+
- **V4 — internal state shadows prop**:元件內 `useState(value ?? defaultValue)` 然後忽略後續 `value` 更新(silent bug)
|
|
920
|
+
|
|
921
|
+
**排除 / 例外**(需 spec 明文 rationale):
|
|
922
|
+
- 刻意只支援單一模式:spec.md 該元件節有「Controlled-only rationale」 或「Uncontrolled-only rationale」段
|
|
923
|
+
- Readonly display component(非互動,僅讀 value prop):spec 第一段聲明「display only」
|
|
924
|
+
|
|
925
|
+
**Radix primitive 元件(DropdownMenu / Popover / Dialog 等)**:Radix 內建支援 dual-mode,我們 wrap 時必 forward `open / defaultOpen / onOpenChange` 3 個 prop — 漏任何一個 = V1/V2/V3。
|
|
926
|
+
|
|
927
|
+
**檢查法**(per file):
|
|
928
|
+
1. Grep tsx interface / type for `value / defaultValue / open / defaultOpen / checked / defaultChecked`
|
|
929
|
+
2. Cross-check 對應 pair 是否都在
|
|
930
|
+
3. 檢查 internal `useState` 有無正確 mirror controlled prop(`useControllableState` pattern or manual sync)
|
|
931
|
+
4. 若缺 pair → check spec.md 有無 rationale → 無 = violation
|
|
932
|
+
|
|
933
|
+
Report format:
|
|
934
|
+
```
|
|
935
|
+
[P0 Controlled/Uncontrolled V{n}] {component}({file:line})
|
|
936
|
+
missing: {prop pair}
|
|
937
|
+
spec rationale: {有 / 無}
|
|
938
|
+
fix: 加 {prop} + pair + `onXChange` 並 forward 到 Radix primitive / internal state
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
End: `N components scanned, M violations, by type: V1=X V2=Y V3=Z V4=W`. Under 400 words. Don't fix.
|
|
942
|
+
|
|
943
|
+
## 29. Trait-based展示 stories compliance(2026-04-26 — M19 ensure-canonical pipeline)
|
|
944
|
+
|
|
945
|
+
**Type**: Absolute
|
|
946
|
+
**Canonical source**: `.claude/skills/story-writing/references/category-templates.md` v2(trait-based typology)
|
|
947
|
+
**Rationale home**: 元件 spec.md frontmatter + 邊界案例 scope-N/A 段
|
|
948
|
+
|
|
949
|
+
Working directory: /Users/chenqiren/Library/CloudStorage/GoogleDrive-qijenchen@gmail.com/我的雲端硬碟/my-project
|
|
950
|
+
|
|
951
|
+
對 `packages/design-system/src/components/*/` 每元件:
|
|
952
|
+
|
|
953
|
+
1. 讀 `{name}.spec.md` frontmatter `traits:` array(若無則記為「P2 migration pending」)
|
|
954
|
+
2. 讀 `{name}.stories.tsx`(展示 only,排除 anatomy/principles)的 `export const X` 列表
|
|
955
|
+
3. 對照 v2 trait→required stories 表(讀 category-templates.md):
|
|
956
|
+
- `hasVariants` → AllVariants 或 ≥ 2 per-variant exports
|
|
957
|
+
- `hasSizes` → AllSizes(merged grid)
|
|
958
|
+
- `hasInteractiveStates` → Disabled / States
|
|
959
|
+
- `isOverlay` → OpenSnapshot 或 defaultOpen scenario + ≥ 3 業務 scenarios
|
|
960
|
+
- `isInputLike` → WithError / ErrorState
|
|
961
|
+
- `isSelectionMulti` → States + VerticalGroup + Disabled
|
|
962
|
+
- `isSelectionSingle` → States only
|
|
963
|
+
- `isMatrixHeavy` → ≥ 4 matrix stories
|
|
964
|
+
- `isStructural` → 結構變體 stories(無固定數,過 earn-existence)
|
|
965
|
+
- `isInternal` → 1 Default + ≤ 1 composition scenario
|
|
966
|
+
4. 缺哪個 → 過 spec.md「邊界案例 scope」找 N/A rationale。**有 rationale = `deviation ✓`,無 rationale = P0**
|
|
967
|
+
5. universal `Default` 缺 → P1 warn
|
|
968
|
+
6. 多餘 stories → 過 earn-existence 2-test → 失敗 retire 候選 P1
|
|
969
|
+
|
|
970
|
+
Report format:
|
|
971
|
+
```
|
|
972
|
+
[P0] {component}({file}):trait `{trait}` declared but missing `{required-story}`,no scope-N/A rationale in spec
|
|
973
|
+
[P2] {component}:no `traits:` frontmatter — pending migration via /story-auto-compile-migrate
|
|
974
|
+
deviation ✓: {component} `{trait}` 在 spec.md L{n} 標 N/A,因 {rationale}
|
|
975
|
+
```
|
|
976
|
+
|
|
977
|
+
End: `N components scanned, M with traits, K P0 violations, J P2 pending migration, I retire candidates`. Under 400 words. Don't fix.
|
|
978
|
+
|
|
979
|
+
## 30. Principles canonical compliance(2026-04-26 — Polaris/Material/Ant aligned;**v3 update 2026-05-01**)
|
|
980
|
+
|
|
981
|
+
**Type**: Absolute
|
|
982
|
+
**Canonical source**: `.claude/skills/story-writing/references/category-templates.md`「Principles canonical」節 v3(2026-04-26 整合)
|
|
983
|
+
**Rationale home**: 元件 spec.md(若需 scope-N/A 例外)
|
|
984
|
+
**Hook**: `check_principles_canonical.sh`(已 v3-aware)
|
|
985
|
+
|
|
986
|
+
Working directory: /Users/chenqiren/Library/CloudStorage/GoogleDrive-qijenchen@gmail.com/我的雲端硬碟/my-project
|
|
987
|
+
|
|
988
|
+
**v3 schema(2026-04-26)**:`UsageGuidance` 為預設 canonical(整合 WhenTo + WhenNotTo + Vs 為單一 story,對齊 Polaris/Material/Ant 共識)。`WhenToUse` / `WhenNotToUse` / `Vs*Rule` 仍接受(split style),但新元件預設用 `UsageGuidance`。
|
|
989
|
+
|
|
990
|
+
對 `packages/design-system/src/components/*/` 每元件:
|
|
991
|
+
|
|
992
|
+
1. 讀 `*.principles.stories.tsx` 列 `export const X` 名稱
|
|
993
|
+
2. **核心規則**:每元件 principle stories `export const` 數 ≥ 2(對齊 audit-content-quality.mjs 寬鬆 ≥ 2)
|
|
994
|
+
3. 計算 universal core 命中數(v3 schema):
|
|
995
|
+
- **`UsageGuidance`** 命中 → 視為「has core」(整合 schema,等同 ≥ 2 core)
|
|
996
|
+
- 或 split style:`WhenToUse`(legacy `UsageScenarioRule` / `WhatItIs` 算)+ `WhenNotToUse`(legacy `Forbidden*` / `Donts` / `Pitfalls` / `Prohibitions` / `NonGoals` / `VisualDonts` 算)+ `Vs*Rule` + `ContentGuidelines` ≥ 2 → 「has core」
|
|
997
|
+
4. 違反:
|
|
998
|
+
- **P0**:exports < 2(不夠教學量)
|
|
999
|
+
- **P0**:無任一 universal core(`UsageGuidance` / split / legacy 都無)
|
|
1000
|
+
- **P1**:用 deprecated naming(`Forbidden*` / `Donts` etc.)→ rename target(整合到 `UsageGuidance` 或改 `WhenNotToUse`)
|
|
1001
|
+
5. 多餘 stories → 過 earn-existence 2-test(對齊 Dim 24/25)→ retire 候選
|
|
1002
|
+
|
|
1003
|
+
Report format:
|
|
1004
|
+
```
|
|
1005
|
+
[P0] {component}({file}):exports < 2(only N)— 補 component-specific *Rule 或 ContentGuidelines
|
|
1006
|
+
[P0] {component}:無 universal core(無 UsageGuidance 也無 split style)
|
|
1007
|
+
[P1] {component}:deprecated naming `{OldName}` → 整合到 `UsageGuidance` 或 rename `WhenNotToUse`
|
|
1008
|
+
deviation ✓: {component} 在 spec.md 邊界案例 scope 標 N/A,因 {rationale}
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
End: `N components scanned, K P0 (exports<2 OR no core), J P1 (deprecated naming), I retire candidates`. Under 400 words. Don't fix.
|
|
1012
|
+
|
|
1013
|
+
---
|
|
1014
|
+
|
|
1015
|
+
# Compact prompts(Dim 24-28 + 31-51,2026-05-17 補完)
|
|
1016
|
+
|
|
1017
|
+
## 24. Story 範例重複性(Manual stories cross-3-file 不該 scenario 重疊)
|
|
1018
|
+
|
|
1019
|
+
**Type**: Consistency / **Canonical**: SKILL.md Group I + Dim 24 rationale / **Home**: spec.md「邊界案例」rationale
|
|
1020
|
+
|
|
1021
|
+
For each DS component, grep 3 stories files。列每 manual story 的 scenario(variant × size × state × 業務情境)。**Rule**:同 scenario 同元件不該在 ≥ 2 file 重複 = noise。Earn-existence test 第 1 條「教別 story 沒教的事」應命中。Report retire candidate per duplicate cluster。Under 300 words. 不修。
|
|
1022
|
+
|
|
1023
|
+
## 25. Story 必要性 grounding(manual story 補足模糊原則的具象化)
|
|
1024
|
+
|
|
1025
|
+
**Type**: AI-judgement / **Canonical**: SKILL.md Dim 25 / **Home**: spec.md 對應抽象原則段
|
|
1026
|
+
|
|
1027
|
+
每 manual story 過 2 test:(a) tied 到 spec 某條抽象原則 + 讓「人」透過範例看懂?(b) 移除後 spec 理解 degrade?兩題皆 NO → retire candidate。**核心 philosophy**:「manual 範例補充模糊原則讓其具象化」非「秀肌肉湊數」。Report per-story:`✅ earn / ❌ retire(reason)/ ⚠️ borderline`。
|
|
1028
|
+
|
|
1029
|
+
## 26. Controlled / Uncontrolled dual-mode coherence
|
|
1030
|
+
|
|
1031
|
+
**Type**: Absolute / **Canonical**: SKILL.md Group J Dim 26 / **Home**: spec.md「Dual-mode rationale」段
|
|
1032
|
+
|
|
1033
|
+
對 form-like + overlay-like 元件 grep dual-mode prop pair:`value/defaultValue + onChange` / `open/defaultOpen + onOpenChange`。**4 違反 case**:V1 missing uncontrolled / V2 missing controlled / V3 no callback / V4 internal state shadows prop。Radix wrapper 必 forward 3 個 prop。**例外**:刻意 single mode 必 spec.md rationale。Report per-component pair status。
|
|
1034
|
+
|
|
1035
|
+
## 27. Clean code 量化(auto-chain `/code-quality-audit`)
|
|
1036
|
+
|
|
1037
|
+
**Type**: Absolute / **Canonical**: scripts/code-quality-audit.mjs / **Home**: 無
|
|
1038
|
+
|
|
1039
|
+
Chain `node scripts/code-quality-audit.mjs --scope=all`(`--deep`)or `--scope=changed`(default)。檢 `any` 使用 / dead export / tsx > 500 行(cap 800)/ function > 80 行 / circular dep / magic number。Report top offenders per rule。
|
|
1040
|
+
|
|
1041
|
+
## 28. Manual story 拆分原則 alignment(對齊 Polaris/Carbon/Storybook)
|
|
1042
|
+
|
|
1043
|
+
**Type**: Absolute / **Canonical**: `.claude/rules/story-rules.md`「拆分原則」 / **Home**: 檔首 `// @story-split-rationale: <reason>`
|
|
1044
|
+
|
|
1045
|
+
Per-component grep `*.stories.tsx`(非 anatomy/principles)反 pattern:
|
|
1046
|
+
- `WithStartIcon` + `WithEndIcon` 拆兩 story → 該 `WithIcon` 對照 grid
|
|
1047
|
+
- `Default` + `AllVariants` 同檔 → 冗餘
|
|
1048
|
+
- ≥ 2 個 variant 拆細 → 該合 `AllVariants`
|
|
1049
|
+
|
|
1050
|
+
對齊 Hook `check_story_invariants.sh` R2(write-time)+ 本 dim batch verify 既有元件。
|
|
1051
|
+
|
|
1052
|
+
## 31. Overlay body 無 stripped-padding boolean variant
|
|
1053
|
+
|
|
1054
|
+
**Type**: Absolute / **Canonical**: `overlay-surface.spec.md`「List-as-region in overlay body」+ memory `feedback_layout_v6_canonical.md` / **Home**: 檔頭 `// overlay-body-stripped-variant-allow:`(必含 ≥ 3 家世界級對照 + multi-row hold)
|
|
1055
|
+
|
|
1056
|
+
Per-overlay grep `components/(Dialog|Sheet|Popover)/*.tsx`(非 stories)反 pattern:`(flush|naked|bare|stripped|unpadded|noPadding|paddingless)\?:\s*boolean` 在 body component。對齊 Material/Atlassian/Mantine/shadcn 主流。違反 = list-as-region 該 consumer override(`!px-0 !pt-0`)+ 自管 list outer wrapper。Hook `check_overlay_handcraft.sh` Check 6 同源。
|
|
1057
|
+
|
|
1058
|
+
## 32. Filter operator registry SSOT consumption
|
|
1059
|
+
|
|
1060
|
+
**Type**: Absolute / **Canonical**: `DataTable/filter-operators.ts` SSOT / **Home**: 檔頭 `// filter-op-inline-allow:`
|
|
1061
|
+
|
|
1062
|
+
Per-consumer grep:反 pattern(a)hardcode op 字串 array 不 import `OPERATOR_REGISTRY`;(b)inline switch on op derive ValueShape(該走 `getValueShape`)。對齊 ClickUp/Airtable/Notion filter API + M17 SSOT。
|
|
1063
|
+
|
|
1064
|
+
## 33. Component classification + abstraction discipline(5 子維)
|
|
1065
|
+
|
|
1066
|
+
**Type**: Consistency / **Canonical**: M21 + M22 + M23 / **Home**: spec.md「abstraction rationale」/「benchmark cite」
|
|
1067
|
+
|
|
1068
|
+
Per-component verify:
|
|
1069
|
+
- (a) Internal vs Components 一致性(對齊 Dim 44)
|
|
1070
|
+
- (b) Premature abstraction:`<Existing>+suffix` 需 3-test 過(prop variant 不行嗎 / ≥ 3 家 world-class 分離 / value 結構真不同),否則退 prop(M21)
|
|
1071
|
+
- (c) Sub-component 5-file 結構過度
|
|
1072
|
+
- (d) Benchmark claim 缺 source(M22 inline cite)
|
|
1073
|
+
- (e) DS internal canonical 優先(M23):visual decision 未先 grep DS token / variant / pattern 命中 → flag
|
|
1074
|
+
|
|
1075
|
+
Sub-agent 對每 benchmark cite 反查 DS 內既有 codified canonical;有 → cite 應為輔證非主導。違反 = M23 自開新 tier。
|
|
1076
|
+
|
|
1077
|
+
## 34. Disabled state 顯著性 precedence(M24)
|
|
1078
|
+
|
|
1079
|
+
**Type**: Absolute / **Canonical**: M24 + `field-controls.spec.md` disabled state machine / **Home**: spec.md「state precedence」
|
|
1080
|
+
|
|
1081
|
+
Per-element grep disabled mode → 內 placeholder / value / icon 全切 `text-fg-disabled`(neutral-6)非 `text-fg-muted`(neutral-7)。state > emphasis。Hook `check_disabled_placeholder_color.sh` 同源,本 dim DS-wide batch。
|
|
1082
|
+
|
|
1083
|
+
## 35. Layered chain invariant — overlay scroll(M25)
|
|
1084
|
+
|
|
1085
|
+
**Type**: Absolute / **Canonical**: M25 + `overlay-surface.spec.md` / **Home**: spec.md SSOT
|
|
1086
|
+
|
|
1087
|
+
Overlay primitive → SurfaceBody 中間 wrapper 必 `flex flex-col h-full`,斷一層 = body 不 scroll。Hook `check_overlay_panel_scroll_chain.sh` 同源,本 dim DS-wide batch verify integrity。
|
|
1088
|
+
|
|
1089
|
+
## 36. Naked variant cell-as-input row-mode propagation(M19)
|
|
1090
|
+
|
|
1091
|
+
**Type**: Absolute / **Canonical**: `nakedCellRowModeAlign` SSOT / **Home**: spec.md
|
|
1092
|
+
|
|
1093
|
+
`variant="naked"` consumer 內 wrapper 必 import + apply `nakedCellRowModeAlign` SSOT。Hook `check_naked_row_mode_propagation.sh` 同源。
|
|
1094
|
+
|
|
1095
|
+
## 37. Field state machine「focus dominates everything」(M19 v13.3)
|
|
1096
|
+
|
|
1097
|
+
**Type**: Absolute / **Canonical**: `field-wrapper.tsx` 三 compoundVariant SSOT / **Home**: spec.md state machine 段
|
|
1098
|
+
|
|
1099
|
+
禁 per-control `(open|isOpen) && 'border-primary'`(Field default 處理)+ naked variant 禁平行 outline ring。對齊 Material 3 / Polaris / Ant 共識。Hook `check_field_state_token_consume.sh` 同源,本 dim batch verify Field family + outliers。
|
|
1100
|
+
|
|
1101
|
+
## 38. Inline-action gap canonical
|
|
1102
|
+
|
|
1103
|
+
**Type**: Absolute / **Canonical**: `inline-action.spec.md:80` / **Home**: spec.md
|
|
1104
|
+
|
|
1105
|
+
`<ItemInlineAction>` sibling gap = `gap-2`(8px)。Hook `check_inline_action_canonical_gap.sh` 同源,本 dim batch verify consumer。
|
|
1106
|
+
|
|
1107
|
+
## 39. Row-layout slot primitive consumption(M1+M17)
|
|
1108
|
+
|
|
1109
|
+
**Type**: Absolute / **Canonical**: `ItemPrefix` / `ItemSuffix` primitive / **Home**: `item-anatomy.spec.md`
|
|
1110
|
+
|
|
1111
|
+
禁自刻 `<span h-[1lh] shrink-0 flex items-center>` slot wrapper(item-anatomy / field-wrapper 外),必消費 `<ItemPrefix>` / `<ItemSuffix>`。Hook `check_row_slot_handcraft.sh` 同源。
|
|
1112
|
+
|
|
1113
|
+
## 40. Title 命名 quality(story-rules.md L18-22)
|
|
1114
|
+
|
|
1115
|
+
**Type**: Absolute / **Canonical**: `.claude/rules/story-rules.md`「Title 命名」 / **Home**: 無 escape
|
|
1116
|
+
|
|
1117
|
+
Per-story regex check:`Design System/{Tokens|Patterns|Components|Internal}/{PascalCase Name}/{中文 subpage}` 結構;第一層英 / 子頁中文 / 子頁前**不**加元件名(❌ `MenuItem 展示` → ✓ `展示`)。Tokens/Patterns single-file 3-part exempt(per story-rules canonical)。
|
|
1118
|
+
|
|
1119
|
+
## 41. Story name jargon(spec 內部代號)
|
|
1120
|
+
|
|
1121
|
+
**Type**: Absolute / **Canonical**: story-rules.md「禁 spec 內部代號」 / **Home**: 無 escape
|
|
1122
|
+
|
|
1123
|
+
Grep story `name:` field 含 `L1-L7 | canonical | spec X | phase Y | stream [A-Z]` 等。Hook `check_story_invariants.sh` R5(post-write)同源。本 dim DS-wide batch verify。
|
|
1124
|
+
|
|
1125
|
+
## 42. 範例佔位符 / 抽象代號
|
|
1126
|
+
|
|
1127
|
+
**Type**: Absolute / **Canonical**: story-rules.md「禁佔位符」 / **Home**: 無 escape(用真實業務情境替代)
|
|
1128
|
+
|
|
1129
|
+
Grep `.stories.tsx` body 含 `Option A/B/C` / `按鈕一` / `Foo/Bar/Baz` / `Lorem ipsum` / `Hello World` / `Test 1/2` 等。對齊 Polaris/Carbon 共識用 Jira/Stripe/Notion 真情境。
|
|
1130
|
+
|
|
1131
|
+
## 43. Rule note 品質(原則 > 結論 / 無中英夾雜)
|
|
1132
|
+
|
|
1133
|
+
**Type**: AI-judgement(NO-SAMPLE per audit-full-sweep canonical:DS-wide ALL principles stories,不 sample)/ **Canonical**: `references/example-selection.md` / **Home**: spec.md rationale
|
|
1134
|
+
|
|
1135
|
+
Per-element 讀 `.principles.stories.tsx` Rule notes,判 (a) 是否「告訴讀者原則為何」而非「只說結論」;(b) 是否無中英夾雜(技術術語例外)。
|
|
1136
|
+
|
|
1137
|
+
## 44. Internal vs Components 分類三 test
|
|
1138
|
+
|
|
1139
|
+
**Type**: Consistency / **Canonical**: story-rules.md L25 / **Home**: spec.md「compound-component API」段(豁免 source)
|
|
1140
|
+
|
|
1141
|
+
Per-element folder verify 三 test:(a) 有預設視覺?(b) 直接 `<X>` 有視覺?(c) 所有 consumer 包 wrapper?三題傾向 Internal → 該住 `packages/design-system/src/components/Internal/`。**例外:compound-component public API**(`Dialog.Root/Trigger/Content` / `Field + FieldLabel + FieldError` 等)豁免。Sub-agent 必先檢 component 是否 export ≥ 2 sub-component + spec.md 有「composition pattern / compound API」 cite → 豁免。
|
|
1142
|
+
|
|
1143
|
+
## 45. Mechanical output structural validation
|
|
1144
|
+
|
|
1145
|
+
**Type**: Absolute / **Canonical**: `scripts/compile-stories.mjs` + `references/anatomy-standard.md` / **Home**: 無
|
|
1146
|
+
|
|
1147
|
+
對每元件跑 `compile-stories.mjs <Name>` 取 generated rows;grep 確認:
|
|
1148
|
+
- `AllSizes` 含所有 cva sizes
|
|
1149
|
+
- `AllVariants` / `ColorMatrix` 含所有 cva variants
|
|
1150
|
+
- `Accessibility` story 含 ARIA hint / keyboard map
|
|
1151
|
+
- `See also` cross-link 反指 spec.md 既有 link section
|
|
1152
|
+
|
|
1153
|
+
## 46. Manual vs Mechanical boundary
|
|
1154
|
+
|
|
1155
|
+
**Type**: Absolute / **Canonical**: `category-templates.md` v2 trait-based / **Home**: 檔頭 `// @manual-trait-allow: <reason>`
|
|
1156
|
+
|
|
1157
|
+
Per-元件 grep `.stories.tsx`(非 anatomy/principles),若含 trait-derived `AllSizes` / `AllVariants` / `WithIcon` hand-written export 而非 import auto-compile = anti-pattern(該 migrate 進 auto-compile)。
|
|
1158
|
+
|
|
1159
|
+
## 47. Tailwind utility registry compliance(2026-05-17 新增,codex Q2 verdict)
|
|
1160
|
+
|
|
1161
|
+
**Type**: Absolute / **Canonical**: `packages/design-system/src/tokens/utility-registry.json` SSOT / **Home**: spec.md「禁止事項」(對應 registry block 列)
|
|
1162
|
+
|
|
1163
|
+
Per-file grep `packages/design-system/src/**/*.{tsx,css}` + consumer code,對 `utility-registry.json` 每個 block list 跑反 pattern:
|
|
1164
|
+
- typography:`text-(xs|sm|base|lg|xl|...)` / `font-(thin|light|semibold|black)` / `leading-N` / `tracking-*`
|
|
1165
|
+
- radius:`rounded-(xl|2xl|3xl)` / `rounded`(無 size)/ `rounded-[Npx]`
|
|
1166
|
+
- opacity:`opacity-(5|10|...|95)`(numeric tier;只 0/100/disabled allowed)
|
|
1167
|
+
- elevation:`shadow-(sm|md|lg|xl|2xl|inner)`
|
|
1168
|
+
- shadcn alias:`bg-popover` / `text-muted-foreground` 等
|
|
1169
|
+
- primitive class:`bg-neutral-1` / `text-blue-6` 等
|
|
1170
|
+
|
|
1171
|
+
對齊 Atlassian `@atlaskit/tokens` + Carbon `@carbon/themes` + Ant ConfigProvider + Polaris `polaris-tokens` registry + lint enforcement。Hook `check_tailwind_token_registry.sh`(由 `check_opacity_token_usage.sh` 升級)同源,本 dim DS-wide batch。
|
|
1172
|
+
|
|
1173
|
+
## 48. Unused / orphan token detector(2026-05-17 新增,codex Q5 verdict)
|
|
1174
|
+
|
|
1175
|
+
**Type**: Absolute / **Canonical**: `tokens/**/*.spec.md`「消費者」段 cross-verify / **Home**: spec.md「消費者」段
|
|
1176
|
+
|
|
1177
|
+
對每個 token 定義(`--<token-name>` in `tokens/*.css`)grep `packages/design-system/src/**/*.{tsx,css}` consumer。0 consumer = retire 候選。同時驗 spec.md「消費者」段宣稱真有用。對齊 Polaris quarterly token audit + Material `theme-cleanup`。
|
|
1178
|
+
|
|
1179
|
+
## 49. a11y axe-core 自動跑 + WCAG contrast ratio(2026-05-17 新增,codex Q5 verdict)
|
|
1180
|
+
|
|
1181
|
+
**Type**: Absolute / **Canonical**: WCAG AA(4.5:1 text / 3:1 UI)/ **Home**: spec.md「a11y 預設」段(escape rationale)
|
|
1182
|
+
|
|
1183
|
+
Per `*.stories.tsx` 跑 axe-core via Storybook a11y addon;contrast ≥ 4.5:1(text)/ 3:1(large text / UI element)。對齊 Carbon AVT 每 PR + Storybook a11y addon + Atlassian linter integration。需 install `@storybook/addon-a11y` + CI integration。
|
|
1184
|
+
|
|
1185
|
+
## 50. Bundle size budget per component(2026-05-17 新增,codex Q5 verdict)
|
|
1186
|
+
|
|
1187
|
+
**Type**: Absolute / **Canonical**: `package.json` `size-limit` 段 + per-component manifest / **Home**: spec.md「bundle impact」段
|
|
1188
|
+
|
|
1189
|
+
Per component gzip size 上限(eg. Button ≤ 5KB / DataTable ≤ 50KB);CI fail if regress > 10%。對齊 Material UI `size-limit` + Material Web 公開 tracking + Ant tree-shake article + Polaris bundle audit。需 `size-limit` pkg integration。
|
|
1190
|
+
|
|
1191
|
+
## 51. Theme / density visual matrix(2026-05-17 新增,codex Q5 verdict)
|
|
1192
|
+
|
|
1193
|
+
**Type**: Absolute(deep mode only)/ **Canonical**: visual-audit Layer B + baseline snapshot / **Home**: spec.md「邊界案例」段
|
|
1194
|
+
|
|
1195
|
+
Deep mode 每 core story 跑 light/dark/high-contrast/density-md/density-lg/RTL 6-cell matrix screenshot diff;baseline drift > 5% pixel-diff → flag。對齊 Polaris visual regression + Carbon dark token matrix + Material 3 dynamic color + Apple HIG Dynamic Type。Chain `/visual-audit --scope=all --matrix=theme-density-rtl`。
|
|
1196
|
+
|
|
1197
|
+
## 52. Header canonical cross-family invariants(2026-05-17 新增,W1-W6 per M31 codex 共識)
|
|
1198
|
+
|
|
1199
|
+
**Type**: Absolute / **Canonical**: `patterns/chrome-header/*.spec.md` + `patterns/overlay-surface/*.spec.md` + tokens `--tab-height-lg` / `--chrome-header-height` / `--layout-space-loose` / **Home**: spec.md「header tabs invariant」段
|
|
1200
|
+
|
|
1201
|
+
對齊 GitHub Primer header + Ant Design Layout.Header + Material v1 AppBar 共識。Per chrome / overlay header tsx 跑 6 invariants:
|
|
1202
|
+
|
|
1203
|
+
- **W1**:含 `<Tabs>` child 必有 `withTabs` prop(border 自動 suppress;手寫 `border-b-0` = 違反)
|
|
1204
|
+
- **W2**:tabs padding 必 = header padding(`px-[var(--layout-space-loose)]`),不可獨立 padding 值
|
|
1205
|
+
- **W3**:`--tab-height-lg` 必 == `--chrome-header-height`(md/lg 對等,token 公式 cross-check)
|
|
1206
|
+
- **W4**:header + tabs flush stack 必無 negative margin(`-mt-px` / `-mb-px` = 違反)
|
|
1207
|
+
- **W5**:tabs default size 必 = `sm`(已 land);出現 `size="md"` chrome header 場景 = drift
|
|
1208
|
+
- **W6**:tabs cva `defaultVariants.size` 必 = `sm`(已從 md 改 sm,grep `defaultVariants: { size: 'md' }` in tabs.tsx = bug)
|
|
1209
|
+
|
|
1210
|
+
```
|
|
1211
|
+
Your job: audit Header W1-W6 canonical invariants DS-wide.
|
|
1212
|
+
|
|
1213
|
+
Coverage requirement(NO-SAMPLE STRICT):全 `packages/design-system/src/components/*/<X>.tsx` + `packages/design-system/src/patterns/chrome-header/**` + overlay surface header usage。
|
|
1214
|
+
|
|
1215
|
+
For each header tsx:
|
|
1216
|
+
1. **W1** — grep `<Tabs` / `<TabsList` inside header — 若有 → require `withTabs` prop on header element。手寫 `border-b-0` / `border-b-transparent` 同步 flag
|
|
1217
|
+
2. **W2** — Tabs padding 必 reference `var(--layout-space-loose)`,不可硬寫 `px-N` 或別的 token
|
|
1218
|
+
3. **W3** — open tokens/uiSize / tokens/layoutSpace spec.md verify `--tab-height-lg === --chrome-header-height`(計算公式對等;不等 = token drift)
|
|
1219
|
+
4. **W4** — grep `-mt-px` / `-mb-px` / `-mt-N` 在 header + tabs flush stack region = violation
|
|
1220
|
+
5. **W5** — grep `<Tabs ... size="md"` in chrome header usage = violation(default sm)
|
|
1221
|
+
6. **W6** — grep `defaultVariants:\s*\{\s*size:\s*['"]md['"]` in `tabs.tsx` cva = violation
|
|
1222
|
+
|
|
1223
|
+
Cross-reference companion hooks:
|
|
1224
|
+
- `check_tab_lg_chrome_header_equal.sh`(W3 mechanical)
|
|
1225
|
+
- `check_header_with_tabs_border.sh`(W1 mechanical)
|
|
1226
|
+
- `check_chrome_header_handcraft.sh`(Layer 3 ChromeHeader consumption)
|
|
1227
|
+
|
|
1228
|
+
Report ONLY violations。Format:
|
|
1229
|
+
- `<Component>: W<N> violation — file:line — actual vs canonical`
|
|
1230
|
+
|
|
1231
|
+
End: `N header surfaces checked, M violations.` Under 400 words. Don't fix.
|
|
1232
|
+
```
|
|
1233
|
+
|
|
1234
|
+
## 53. Code-to-spec reverse drift check(2026-05-17 新增,FileViewer h-14 case 啟發)
|
|
1235
|
+
|
|
1236
|
+
**Type**: Absolute / **Canonical**: per-component `spec.md`「禁止事項」段 + `<X>.tsx` 真實 className 對比 / **Home**: 該 component spec.md(rationale 段)
|
|
1237
|
+
|
|
1238
|
+
對每 component grep `packages/design-system/src/components/<X>/<X>.tsx` 的硬寫 utility(`h-14` / `w-80` / `px-loose` 類 — code 已 migrate to token / DS canonical),反向掃對應 `<X>.spec.md` 是否仍寫「固定 h-NN」「寫死 N px」「H 不消費 token」等 known-drift keyword。**互補既有 forward Dim 15/20(spec → code drift)— 本 dim 抓 spec → code 反向 drift**(code 已對齊 spec 還寫 drift caveat = 漏改)。
|
|
1239
|
+
|
|
1240
|
+
```
|
|
1241
|
+
Your job: detect spec → code reverse drift(spec writes「known drift / hardcoded / 未消費 token」keyword 但 code has migrated to token / DS canonical).
|
|
1242
|
+
|
|
1243
|
+
Coverage requirement(NO-SAMPLE STRICT):全 `packages/design-system/src/components/*/`(60+ 元件)。
|
|
1244
|
+
|
|
1245
|
+
For each component:
|
|
1246
|
+
1. Grep `<X>.spec.md` 找 keyword:`known drift` / `hardcoded` / `寫死` / `不消費 token` / `h-NN 硬寫` / `w-NN 硬寫` / `未對齊 token` / `TODO migrate` / `interim hardcode`
|
|
1247
|
+
2. 若命中 → 開 `<X>.tsx` grep 對應 className(`h-14` / `w-80` / `px-N` 等具體值)
|
|
1248
|
+
3. **若 code 已 token-ified(`h-[var(--chrome-header-height)]` / `w-[var(--field-width-md)]` / `px-loose` 等)** → spec.md 仍寫 drift caveat = **reverse drift**(漏改)。Flag
|
|
1249
|
+
4. Cross-reference write-time hook `check_spec_class_drift.sh`(本 dim batch verify hook 未覆蓋的既存 drift)
|
|
1250
|
+
|
|
1251
|
+
錨例(2026-05-17 Phase 1 漏抓):
|
|
1252
|
+
- `file-viewer.spec.md` L103 寫「Known drift:h-14 硬寫不消費 token」
|
|
1253
|
+
- 但 `file-viewer.tsx:333` 已 `h-[var(--chrome-header-height)]` migrate 完成
|
|
1254
|
+
- → spec.md 那段該刪 / 該改寫 rationale,3+ 次 `--deep` 都沒抓到
|
|
1255
|
+
|
|
1256
|
+
Report ONLY violations。Format:
|
|
1257
|
+
- `<Component>: spec.md L<N> 寫「<drift keyword>」 vs <X>.tsx L<M> 已 token-ified `<actual className>`(spec 漏改)`
|
|
1258
|
+
|
|
1259
|
+
End: `N components checked, M reverse drift gaps.` Under 400 words. Don't fix.
|
|
1260
|
+
```
|