# Meta-Pattern 預警(31 active M-rules)

**mindset #6 的具體化**。每條吸收數十個具體 bug,是失敗記憶索引上游。任務前先過全部 M-rules(M1-M32,M27 retired 2026-05-15 → M23(c) child / M33-M35 retired 2026-05-22 → folded into M20/M7/M23(d) per `/knowledge-prune` deep audit Lens 1+2)。

## 2026-05-10 cluster cross-link(per codex Q-13 deep prune audit + 2026-05-22 fold update)

31 M-rules(M1-M32,M27/M33/M34/M35 retired)分 6 cluster(舉一反三 grouping):

| Cluster | M-rules | 共同主軸 |
|---|---|---|
| **A. SSOT-first / DS-anchor preflight** | M1 / M23(含 M27+M35 子規則)/ M29 / M30 | 視覺決策前必消費既有 SSOT;DS canonical 優先;spec.md 先 grep 找 owner;wrapper schema extends primitive;nearest same-purpose canonical wins |
| **B. Benchmark discipline stages** | M8 / M22 / M26 | 訂 rule ≥3 家對照 / 寫 spec 含 cite / propose 前 WebFetch |
| **C. Auto-integrate pipeline** | M14 / M19 / M31 | 對話結論 5-layer / trigger phrase auto-pipeline / claude-codex 5-step |
| **D. Verify / similar-bug / visual coverage** | M10 / M13 / M15 | proactive scan / user 第 2 次截圖 / visual-audit-coverable |
| **E. Propose-time discipline** | M18 / M21@watch | 4-Q 自檢 / 新元件抽象前 prop variant test |
| **F. Sharp invariants(各自獨立)** | M2 / M3 / M4 / M5 / M6 / M7(含 M34 子規則)/ M9 / M11 / M12 / M16@watch / M17 / M20(含 M33 子規則)/ M24 / M25@watch / M28 / M30@watch / M32 | sharp invariant |

`@watch` 標記(2026-05-15)= 該 M-rule 目前 absorbs 1-2 bugs(charter 要 ≥3)。1 quarter 觀察:無新 bug → demote 為既有 M-rule 子規則;有新 bug → 升 sharp keep。**2026-05-22 fold prune**:M33/M34/M35 各 absorb 1 bug → folded into parent cluster home(M33→M20 / M34→M7 / M35→M23(d)),減 3 條 M-rule 同時保留全部 invariants。Velocity 修正:本季 net add 12 rules(15 new − 3 fold)= 18 → 12 趨近 charter ≤3/quarter target,持續觀察。

**Why no merge content**:per codex Q-13「Keep M24/M25 because they are sharp, reusable state/chain invariants」+ Layer A own 認 cluster headers 是檢索輔助,不該強行 merge content(各 M-rule 已 1-line tight)。Cluster headers help 「舉一反三」without 削減 M-rule 數量。**Task #19 M21-M29 meta-merge analysis(2026-05-10 closed)**:re-audit M21-M31 全部,verdict **無 merge candidate**,各 rule sharp invariant 覆蓋 distinct failure mode(M22 implement-time cite vs M26 propose-time cite / M30 wrapper-primitive 跟 M27 framework-vs-DS / M31 collab discipline 跟 M14 / M19 auto-pipeline 各 unique scope)。Cluster table 已 cross-link,不需 merge。

## 2026-05-10 skills consolidation analysis(Task #20 closed)

**Per Anthropic「~10 sweet spot」benchmark**:DS 現有 20 skills(`.claude/skills/` minus README),約 2x Anthropic typical recommend。**Verdict:無 aggressive merge candidate**,維持 20 skills justified:

| 類別 | Skills | 為何不 merge |
|---|---|---|
| Core audit | design-system-audit / visual-audit / component-quality-gate / knowledge-prune | 各 sharp trigger,invoke logs 顯示高頻(design-system-audit 6 / knowledge-prune 7) |
| Domain audit | ux-audit / performance-audit / code-quality-audit / product-ui-audit | D2/D3/D4/consumer-code dim 已 chain 進 design-system-audit |
| Workflow | prototype / new-component / delivery-handoff / story-writing / story-auto-compile-migrate | create / prototype / final-handoff / story 各 phase distinct rare-event(per knowledge-prune retire rule 例外) |
| Discipline | ensure-canonical / propose-options / codify-principle / codify-corrections / scan-similar-bugs / governance-health | trigger phrase / 4-Q gate / 5-layer artifact gen / batch log / post-fix scan / monthly metric 各 unique |
| Collab | codex-collab | M31 5-step home,unique |

**Marginal merge candidate**(留 user 後續 explicit approve):`codify-principle` + `codify-corrections` 都產 5-layer artifact,trigger 不同(live propose vs batch log)— 可合 `codify` 一統 skill。**不執行原因**:codex Q-13 sharp-rule preference + auto-mode 不 destructive 風險 + 兩 skill SKILL.md 各自 250 lines budget 內。User 後續 invoke `/knowledge-prune` 並 explicit approve 才動。

**RFC**:Anthropic「~10 sweet spot」是 typical CRUD app benchmark;DS governance complexity(31 active M-rules + 全 dim audit per design-system-audit SSOT + dual-track codex collab + 8-home 治理)justified higher skill count。每 skill 都過 knowledge-prune retire rule(6 月 fire 或 rare-event 豁免)。


| # | Meta-Principle | 能吸收的 bug 類型(舉例,非窮舉) |
|---|---|---|
| **M1** | **視覺決策前必消費 SSOT**(元件 / token / pattern / spec)。強制跑 `# SSOT 消費 canonical` 清單,沒列出 = 自創。 | `variant="bare"` 自發明 / chrome-header token 漏用 / Row 沒用 item-anatomy(詳 historical-bugs.md) |
| **M2** | **消費 3rd-party lib 必驗 rendered DOM**(不信 docs)。任何 `[&\[data-...\]]:` attribute selector 針對第三方元件前,inspect 真實 DOM 有無該 attribute。Library API(fit / zoom / wheel step)先寫 3 行 POC 驗證行為,再寫到元件裡。 | react-day-picker `data-range-*` 不存在 / react-zoom-pan-pinch fit-to-page 算錯(詳 historical-bugs.md) |
| **M3** | **Portal 逃逸 subtree context**(theme / density / provider)。任何 overlay 元件(DropdownMenu / Popover / Dialog / HoverCard)走 Portal 到 document body **不繼承觸發點的 subtree attribute**;theme 預設從 `<html data-theme>` 經 CSS 繼承(Portal 後 CSS chain 從 app root 起算)— 需要 override 才顯式 set `data-theme` on Portal Content;`data-density` 部分 overlay 刻意 lock `md`(詳 `density.spec.md`)。 | DropdownMenu 在 dark subtree 變亮 / Avatar HoverCard NameCard 文字白色(詳 historical-bugs.md) |
| **M4** | **`_Group` 元件必隔離單 item 的 fieldCtx**。當 Group 元件(CheckboxGroup / RadioGroup / SwitchGroup)包在 Field 內,其 child items **不可共用 fieldCtx.id / fieldCtx.hasFieldWrapper**;Group 必建自己的 Context 告訴 items「你在 group 裡」。 | CheckboxGroup 共 fieldCtx.id,label 全抑制 / 點擊只 toggle 第一個(詳 historical-bugs.md) |
| **M5** | **視覺 canonical 必 spec 聲明所有 state 疊加組合**。單一 state(today / selected / hover / disabled)有視覺定義不夠;**所有兩兩疊加、三疊加組合也要在 spec 有明文**。 | DatePicker today+selected 隱形 / hover+disabled ring 仍顯示(詳 historical-bugs.md) |
| **M6** | **Stakeholder-visible 產出 → 強制進階稽核才出稿**(不是 merge 後補)。任何「有視覺可以給 stakeholder 看」的產出(新元件 / 元件新功能 / 新產品頁 / 比稿)**必過進階完整稽核**(6 維 + 全截圖視覺驗證)。日常 dev 可用高效模式,stakeholder gate 不可。 | FileViewer 初版 8+ 項給人看才發現(詳 historical-bugs.md) |
| **M7** | **新 protocol / skill / rule 寫完,必反向 cross-check 既有 Meta-Principle 是否該套用**。尤其:consistency-class 的 protocol 必走「一致性類稽核必先全掃再判」(本章節);audit skill 必加「Self-improvement capture」Phase F step;Rule 觸及「canonical」「SSOT」「rationale」keyword → 必明示 substantive vs 表達層分權。**+ Sub-rule M34 (folded 2026-05-22)**:Hook detection regex 必對齊 spec wording 廣度。Triple test before merge new hook — (1) Spec rule wording 是「一般類別」(broad)還是「特定 keyword」(narrow)?(2) Hook regex 匹配「一般類別」還是只「特定 keyword subset」?(3) Spec broad + Hook narrow → **gap**,必擴 hook regex(unicode pattern / negative-list approach / counter-example DS-wide scan)。Propose 新 hook 必先寫 3-column table:`Spec wording` / `Hook regex` / `Gap?(broad-vs-narrow)`。 | principle-audit-protocol v1 漏套既有 Phase 0 全掃;2026-05-17 story name `照妳` `決策N` 等中英人話 detection regex 漏 |
| **M8** | **訂立 / 修改 cross-component canonical 前必 world-class benchmark**。任何 predicate / decision tree / taxonomy 類 spec,**必先 grep 至少 3 家世界級 DS**(Polaris / Material / Atlassian / Ant Design / Carbon / Apple HIG / VS Code / Figma 等)列對照表,再訂 rule。**絕對禁止**憑直覺開場寫 predicate,user 問才補對照。每個 category / variant / case 必附世界級 reference(實作名或 API 指向),沒有對照的 rule 視同未成熟,走 Checkpoint 3。 | item-anatomy Inline Action 疊代 4 次才有世界級對照 |
| **M9** | **Predicate / decision tree 寫完,present 前必 4 題自測**,防 membership drift。(a) 每 example 回跑決策樹;(b) cap / constraint cross-check;(c) 每 example 對 ≥3 家 world-class DS;(d) 每 category ≥1 example。任一題失敗 → 重收斂,**禁止 present**。 | Cat 1 IA 塞 endAction / FileItem sm 違 ≤24 cap |
| **M10** | **Proactive exhaustive scan**:canonical migration 完成前禁止只改「直覺相關」元件;final report 前禁止省略「我知道但沒講」的 tech debt。**Mechanical 落地**:每 fix commit 後 `/scan-similar-bugs` skill 強制 grep DS-wide。 | dismiss migration 漏 FileViewer / 7 題 silent tech debt user 一次炸 |
| **M11** | **User-perspective interactive state walk**:改完 UI 後 present 前必親自走 7 題 self-test(static / hover / focus-visible / active / keyboard / 範例真實性 / CSS 對稱)。每 UI 改動未跑 7 題就 commit = 違反。 | ListBody 修完 user 連抓 5 波 |
| **M12** | **Binary strict rule + fix-time root-invariant pre-question(「必 X」/「禁 Y」/ bug fix)前必 benchmark + invariant test**。3 題自測:≥3 家世界級一致 / counter-example scan / root invariant vs surface observation。震盪症狀(A→not A→A)= meta invariant 沒抓到,**停下 present**。**Fix-time 延伸**(2026-05-12 absorbs 原 M32(b)):visual / behavior bug 改前必 inline 答 3 題 — Q1「root invariant 是什麼?」Q2「symptom 在哪 layer?」Q3「fix 是 root-layer 還是 surface-layer?」。surface-only 修(改 symptom 不動 invariant)違反。對齊 5-whys / Toyota TPS / Linux kernel「fix the root not symptom」canonical。 | hover bg 震盪 4 次(bg-edge vs content-padding invariant);2026-05-12 cell-align fix surface-modify Field padding 不動 inline-flex `!h-full` root invariant |
| **M13** | **User 第 2 次提相關問題 → 自動截圖 verify**。當 user 就同一視覺 / 行為主題第 2 次問 / 糾正,AI 必 invoke 截圖 verify(`visual-audit.mjs --scope=component:XXX`)。第 3 次才 verify = 違反。**Corollary**:user 指定「所有 X 都要 Y」,同 session 全部做完 + 建 hook 防線。 | avatar-NameCard migration 分批拖延 user 第 2 次催才全改 |
| **M14** | **對話結論 → AUTO integrate pipeline**(不等 user 催)。每次 canonical / 設計決策 / 新 rule 結論時必執行 5-layer pipeline ≥ 3 層落地:M8 benchmark / SSOT home 識別 / spec / code / hook / CLAUDE.md / memory / 驗證。User 問「有沒有整合到 X」= M14 violation。**Governance auto-trigger**:`session_start_governance_check.sh` 檢查 hook / memory / CLAUDE.md / 上次 prune 達標 → 自動 inject「建議 /knowledge-prune」directive(soft 提示;hard cap 升 BLOCKER)。**數值 SSOT**:`session_start_governance_check.sh`(L19-22 + L173)+ CLAUDE.md `# 治理 canonical` 行數預算表;本 M-rule 不重述,避免 drift。 | chrome-header / dismiss / hoverCard 每個都 user 提醒才整合 |
| **M15** | **Product UI flow 必須 visual-audit coverable**。任何 stakeholder-facing flow 必含 OpenSnapshot 類 stories(`defaultOpen` / `useState(true)` / `play()`)。禁留「需真人點擊才能看到的 state」未截圖。 | Sheet / FileViewer 只截 trigger 缺 OpenSnapshot |
| **M16** | **訂 standalone card/pill 容器 canonical 必同步訂 multi-instance gap canonical**(`@watch` 2026-05-22)。3 條公式:同類 standalone → 必 gap;同類 permanent flush → 0 gap OK;混合語言 → 必取最保守 gap。Hook `check_item_list_gap.sh` 預警 + audit dim verify。**@watch 2026-05-22**:單 bug source(FileItem rich/compact)— 1 quarter 觀察是否 absorb ≥3 同類 bug,否則 demote 為 item-anatomy.spec.md 子規則。 | FileItem rich card + compact bg 連續相連 |
| **M17** | **SSOT 必可傳播**(非僅 markdown)。同值 / 同公式 hard-code 在 3+ consumer = 必抽成 token / primitive / utility class。**兩層 SSOT 架構**:底層 token(值可調)+ primitive(結構封裝 + 消費 token);世界級對照 Material/Carbon/Ant/Polaris 共識。 | mt-0.5 canonical 13 consumer hard-code 假 SSOT |
| **M18** | **Propose-time 6 題自檢 gate**(2026-05-18 升 4→6 加 Q0 + Q5)。列 option / 建議前必 inline 跑 **Q0 Pre-ASK self-verify problem 真存在**(2026-05-18 加,absorbs Sheet/inline-action/SurfaceBody 三題誤判)/ Q1 M8 benchmark / Q1' M23 DS canonical / Q2 M17 SSOT / Q3 Rule-of-3 / Q4 M10 下游吸收 / Q5 Issue 100% mapped。Reject 不列出,通過寫 6-Q 證據表。**Q0 強制動作**:propose 給 user 拍板前必 grep DS-wide + Read 相關 spec.md + Read consumer usage 確認 problem 真存在,沒 grep 就斷言「N 元件缺 X / 該 migrate」= 撤回 propose。SSOT → `.claude/skills/propose-options/SKILL.md`。Hook `check_propose_pre_grep_verify.sh` 機械強制 Q0。 | 2026-05-18:Sheet 補 / 5 元件 inline-action migrate / 5 元件 SurfaceBody migrate 三題全錯誤 propose 給 user 拍板,grep 後 0 個真 gap(Sheet 已完整 / 6 元件全消費 inline action / Dialog 走 ScrollArea canonical 不該用 SurfaceBody / HoverCard 是 behavior primitive / DatePicker TimePicker 是專用 layout / Sidebar 是 chrome 不是浮層)。User verbatim「不是老早就跟你說過要我決策前請先基於我們所有的檔案包括設計原則包括 ssot 包括所有實作代碼,自主自動驗證這些問題是否真的是問題」 |
| **M19** | **Trigger phrase auto-pipeline**。「確保 / 一定 / 永不漂移 / ensure / always」trigger → 自動 5-layer ≥ 3 層落地 + M8 + M17 + M10。Substantive 走 STOP。SSOT → `.claude/skills/ensure-canonical/SKILL.md`。 | story splitting 2026-04-26 user 第 N 次強調才落地 |
| **M20** | **AI 自問 best-practice + 自動 self-improve**(不靠 user 提醒)。Stop hook `rule_infra_best_practice_score`(R5 in `stop_passive_logging.sh`,2026-05-13 folded from retired `stop_meta_self_audit.sh`)每 turn 跑 score → < 80 / regression ≥ 5 log to `score-history.jsonl`;next-turn UserPromptSubmit `inject_pending_self_audit.sh` 注入 BLOCKER prompt。**Threshold 數值 SSOT**:`session_start_governance_check.sh`(L19-22 + L173)+ CLAUDE.md `# 治理 canonical` 行數預算表;本 M-rule 不重述具體 cap,避免多 home 漂移(2026-05-22 prune codify per Rule-of-3 violation fix)。**+ Sub-rule M33 (folded 2026-05-22)**:Stop hook overfire → AI conservative-defer 反 pattern。同 stop hook fire ≥ 5 次 within session → AI 自動 hedge / 撤回 claim / 「下個 session」defer **可做工作**。真理由 vs 偽 prereq 區辨 — (a)真 prereq 缺(cross-frame test fixture 等)= 具體 deliverable need;(b)偽 prereq(「context budget」「省工」「下個 session」)= conditioned hedge,user 反覆催 = 真理由不存在。**Rule**:AI reply 含「下個 session」「context budget」「省工」keyword 且前 1 turn user 已拍板「全部做完」/「繼續」/「沒理由不做」→ BLOCKER。對齊 Atlassian「stop using vague defer」+ Linux kernel patch review。 | user 10 次問「best-practice 嗎」直到外部 benchmark 確認真 gap;2026-05-13 claim-verify-gap stop hook fire 12+ 次 → 我每 reply 自動 hedge → user 多次糾正「沒理由不做」 |
| **M21** | **新元件 / 新 sub-component 抽象前必過 prop variant test**。當新元件名 = `<Existing>+suffix`(Time / Range / Color / Light / Dark / Filled / Outline / Compact / Rich)→ 強烈 signal 應為 prop variant on `<Existing>`。3-test 通過才能分(全失敗 → prop):(1) `<Existing>` 加 prop 無法達成同 DOM/behavior?(2) ≥3 家 world-class DS 用分離元件而非 prop(必 cite source)?(3) value 結構或 contract 真的不同(如 Range = [start, end])?Hook check_premature_abstraction(retired/未實作;mindset enforcement)。 | DateTimePicker 從 DatePicker 拆 → 撤回合併 `<DatePicker showTime>`(2026-05-02);DataTableFilterPanel 5-file → 撤回 sub-file pattern |
| **M22** | **Benchmark claim 必附 inline source citation**(不可憑印象)。寫 spec / tsx 含「Ant / Material / Polaris / Atlassian / Carbon / shadcn / Radix」等 world-class DS claim,必同段附:(a) inline URL(domain 對應 DS 官網 / GitHub source);(b) GitHub source path + line ref `#L42`;(c) screenshot reference `snapshots/...`;(d) 顯式撤回 `@benchmark-unverified`。Hook `check_benchmark_citation.sh` 機械化警告(P1 soft)。每次 implement 前跑 WebFetch 取真 source,不憑印象解碼。 | claim「Ant showTime range = 2 calendars」憑印象,實證 source code `multiplePanel = false` = 1 calendar(2026-05-02 鬼話事件)|
| **M23** | **DS 內既有 canonical 優先於外部 benchmark**。寫 visual decision(color / size / spacing / typography / state)/ prop name namespace 前必先 grep DS 既有 codified token / variant / pattern / prop;命中 → 必對齊;沒命中 → 才引 world-class + 同步補 canonical。**禁止**:外部 benchmark(M22 cite OK)直接覆蓋 DS 內已有 canonical。Mindset #2「優先消費既有」的 visual layer。判斷流程:(a) grep 該屬性 / prop 既有 token/variant/usage;(b) 命中 canonical?有 → 用,沒 → 走 M22 cite 然後 codify;(c) **prop name conflict 子規則**(former M27,2026-05-15 collapsed):外部 framework prop name(TanStack `size` / Radix `disabled` / dnd-kit attrs 等)跟 DS 既有 prop 同字不同義 → wrap-and-rename(DS-internal naming + pre-process map);(d) **nearest same-purpose canonical wins 子規則**(former M35,2026-05-22 folded):寫 stories / UI composition wrap 既有 primitive 前必先 grep + Read primitive 的「完整佈局」production canonical story(eg. `sidebar.stories.tsx#IconCollapse`)抄 archetype 結構 / helper / variant — 不准憑記憶寫 simplified mock。**Cite 存在 ≠ consume 落實**(codex 2026-05-20 verdict)。最相近同目的 canonical 用法 > 泛用 component spec / 寬鬆 pattern wording。**手刻浮層 / chrome header 子規則(2026-06-04 加)**:做「像 popover / dialog 的浮層面板」前必先 grep + Read `patterns/overlay-surface`(SurfaceHeader/Body/Footer)+ `Popover`(chrome token + PopoverHeader/PopoverTitle)SSOT;**手刻 `<div px-loose border-b border-divider>` header 或 `<div rounded bg-surface shadow-elevation>` 殼 = drift**,必消費 primitive。Registry SSOT `.claude/references/story-baseline-registry.json` + hook `check_story_invariants.sh R8 story_archetype_registry` **+ R9 hand_craft_overlay_header(零誤判 px-loose+border-divider 簽名,BLOCKER)**。**forcing-function 教訓**:M1/M23(d) 是 mindset,但 mindset 沒有完整 hook 兜底 = 紙老虎(會憑印象手刻);新場景若既有 hook 無 antiPattern 覆蓋 → 補 hook rule 才算落地。 | 2026-05-03 chevron color:DS `text-foreground` (icon-only Button neutral-9 85%) vs 我憑「Ant 5 家 muted」覆蓋 → 自開新 tier 違反一致設計語言。2026-05-06 column width:DS 49+ 處 `size: 'sm'\|'md'\|'lg'` density vs TanStack `size: 280` px = 同 prop 不同義 → `meta.width` wrap。2026-05-20 AppShell-vs-Sidebar drift:simplified mock + jargon + wrong variant + 不消費 primitive props。**2026-06-04 upload-manager 面板手刻 header + 殼**(`py-2`≠`py-tight` / `rounded-md`≠`lg` / `border-divider`≠`border` / `bg-surface`≠`raised`),既有 3 道網全漏(R1-C 要 absolute+dismiss / `_chrome_header_handcraft` skip stories / R7-R8 只比已註冊 primitive 名)→ adversarial workflow 抓 + 加 R9 補洞。Hook `check_data_table_size_num_to_meta_width.sh` + `check_story_invariants.sh R8/R9` |
| **M24** | **State 顯著性 precedence:disabled > muted > emphasis**。元件在 disabled state 時,內部所有文字載體(label / value / placeholder / icon)統一切 disabled token(`text-fg-disabled` neutral-6),**不**繼續 muted token(`text-fg-muted` neutral-7)。muted 是裝飾,disabled 是語意 state — state 勝 emphasis。同理:error / warning state 內 placeholder 應對應 state token。Hook `check_field_family_invariants.sh` A.4(原 check_disabled_placeholder_color folded,live P1 stderr)。 | 2026-05-04 5+ violation:`bareInputStyles` 永遠 muted / `select.tsx` 3 處 plain&tag empty 不分 mode / `textarea.tsx` 同;Input.tsx 唯一做對。User 5+ 次糾正才 codify |
| **M25** | **Layered chain invariant 必整鏈 forward(viewport-aware overlay scroll 範例)**。Overlay surface(Popover / HoverCard / Dialog / Sheet)的 viewport-aware scroll 機制要求 root → SurfaceBody 之間**所有中間 wrapper 都 forward `flex flex-col h-full`**;任何中間 div 沒 forward → SurfaceBody flex-1 失效 → body 不 scroll。同類 chain pattern:density 透傳 / fieldCtx 鏈 / theme subtree(M3 portal 逃逸對偶)。Hook `check_pattern_invariants.sh` C.1(原 check_overlay_panel_scroll_chain folded,live P1 WARN)。 | 2026-05-04:Filter / Sort panel root `<div w-[640px]>` 無 flex-col → user 縮 viewport 時 body 不 scroll。NameCard 因自設 max-h flex-col 才繞過(無中間 wrapper) |
| **M26** | **Behavior / visual canonical decision 前必跑 WebFetch + WebSearch 取 ≥ 3 source,不可憑印象 propose**。M22 升級版 — M22 管「寫 spec / tsx 含 claim 必附 cite」(實作後),M26 管「propose / 決策前必先 fetch」(實作前)。Pipeline:(1) WebFetch 3 家世界級 source(Atlassian / Material / Polaris / Ant / Carbon / Apple HIG / shadcn / Radix);(2) 全 403 → WebSearch fallback 用 snippet,**明示「search-only confidence」**;(3) WebFetch + WebSearch 都失敗 → STOP propose,告知 user「無法 verify,要看 screenshot/實機」。Hook `check_propose_without_benchmark.sh`(2026-05-26 backfill — 前期 doc claim 但 file missing;UserPromptSubmit 偵測 user prompt 含 propose / visual / behavior decision keyword + 近 20 turn WebFetch/WebSearch < 2 → soft inject 提醒)。 | 2026-05-05:user 反覆糾「為什麼每次都沒 webfetch 只憑印象」— Jira drag handle / cell display 兩題我憑印象 propose 多輪;升級成硬規範 |
<!-- M27 retired 2026-05-15(per /knowledge-prune D3 audit):self-flagged「M23 子規則」 → collapsed into M23 sub-bullet (c) "framework prop name namespace conflict"。Original case (TanStack size vs DS density) + hook `check_data_table_size_num_to_meta_width.sh` retained 在 M23 children。 -->

| **M28** | **Solo-work git ops 必先 grep canonical**(mindset #2 AI-ops 子規則)。AI 自己 git/branch/PR/merge ops(`git checkout -b` / `gh pr create` / `git push origin main` / `mcp__github__create_pull_request` / `mcp__github__merge_pull_request`)前必 grep `.claude/memory/feedback_solo_dev_workflow.md` + CLAUDE.md `# Git solo-work canonical`,**不憑直覺反射開新 branch / 開 PR / 自決 merge**。Solo work 鐵律:1 chat = 1 working branch / no PR / 等 user「push」 trigger 才 merge main。Hook `check_solo_workflow.sh` 機械化攔(R1 第 2 個 branch / R2 PR creation / R3 merge 無 user trigger keyword)+ override `CLAUDE_BYPASS_SOLO_WORKFLOW=1` audit-logged。 | 2026-05-08:同 session AI 開 5 branch + 2 PR (#7 #8),user 第 3 次糾正才升 mechanical;memory file 2026-05-04 codified 但 markdown 級 + AI 沒 grep 直接憑印象 = mindset #2 違反 |
| **M29** | **DS Anchor Preflight invariant — 視覺 / 結構 propose 前必 grep `*.spec.md` 找 owner SSOT**。動 component / pattern / token 視覺結構前,**必先**:(a) `rg <touched component> + <behavior keyword>` in `packages/design-system/src/**/*.spec.md` (b) 出 **3-column owner table**(`candidate owner spec` / `canonical sentence/table row` / `conflicting code/comment if any`)(c) 若 spec ≠ code → STOP 寫 RFC 不直接 propose implementation。沒 3-column = anti-pattern,提案不被接受。SSOT index `.claude/references/ssot-index.md`(high-risk interface owner mapping)Step 0.1 先查再 grep verify。Hook `check_ds_anchor_preflight.sh` soft warn。codex-collab/SKILL.md Step 0.1 mandatory pre-grep。對齊 Carbon「design spec is source of truth」+ Atlassian「system-wide coordination first」。 | 2026-05-08:Claude+Codex 連 5 round 跳過 spec anchor pre-grep,直覺加 primitive(D path / Path A);user 抓「為何沒研讀設計原則」 |
| **M30** | **Wrapper-vs-primitive schema unify invariant — wrapper API option / config schema 必 `extends` primitive SSOT,且 wrapper 內部轉換 mapping 必 forward 全 primitive surface field**。Primitive(`SelectMenuOption` / `MenuItemProps` / `ItemAnatomyProps` 等)宣告 SSOT 後,所有 wrapper(`Select.SelectOption` / `Combobox.SelectOption` / `PeoplePicker` 等)若有同類 schema,(a) 用 TypeScript `extends primitive` 機械繼承,**不可平行 declare** weak schema(同名 / 部分欄位)(b) wrapper 內部 `xxxToYyy()` mapping 必 forward 全 primitive surface field(不可只 forward `value` + `label`,silently drop avatar / description / disabled 等)(c) wrapper-only field 加在 `extends body`(不污染 primitive)。Hook `check_wrapper_primitive_schema_drift.sh` 機械強制(P0 BLOCKER):grep `export interface .*Option \{` cross components/,同名 ≥ 2 處且未 `extends` primitive → BLOCK。對齊 Polaris ChoiceList / Material Autocomplete / Carbon Dropdown wrapper-vs-primitive schema-extension idiom。 | 2026-05-10 PeoplePicker multi-mode 漏 avatar:`Combobox.SelectOption = { value, label }` weak schema(跟 `Select.SelectOption` 同名不同 fields)+ `Combobox.menuOptions` mapping 只 forward 2 fields → dropdown rows 永遠純文字。user 抓「為什麼之前會把 people picker 改壞 + 還有沒有其他東西也改壞」。Round 1 commit `561945b` 修(Combobox extends + forward 全 field)+ Round 2 codify。 |
| **M32** | **Audit script 必 pixel-quantified verify ≠ attribute existence**(2026-05-12)。Audit 必驗 `rect.top / .left / .height` numeric pixel,**不**可只驗 `getAttribute('data-state')` / `class.includes(...)` = false-positive trap(DOM-pass ≠ visual-pass)。對齊 Material X-DataGrid / AG Grid playwright pixel snapshot / Polaris visual diff canonical。Hook `check_pixel_quantified_audit.sh` 機械強制(scans `getAttribute(` without paired `getBoundingClientRect(`)。**+ Sub-invariant(2026-05-30,doc-claim layer)**:story/anatomy/a11y/spec 的**文字宣稱 ≠ code 真實**——audit 必 adversarial **讀元件 .tsx +(其 wrap 的 Radix/cmdk/react-day-picker 等 lib)source**,逐句驗 keyboard map/ARIA role/focus 行為/prop 存在性/native-vs-custom;prose-skim「looks fine」= false-pass(prose-pass ≠ source-verified)。**「無 code 改動」≠ 可跳過**。`/deep-audit-cross-codex` A.1b + CP-A1b + report-validator F 機械強制。Anchor:2026-05-30 獨立 adversarial 抓 403 findings/64 單元/202 FALSE_CLAIM(前期 prose-skim story dim 全漏);prop-existence deterministic detector 因 passthrough over-flag 證實此類本質需 LLM 讀 source → 用 mandatory-dim + report-validator 保證真跑。**Split note**:原 mega 8 sub-invariants 拆 4 home — (b) fix-time root-invariant → M12 extension / (c)(d)(h) batch + parallel + claim-verify → `/bug-fix-rhythm` skill / (e) tool preflight → memory `feedback_tool_binary_preflight_sweep.md` / (f) ship gate → CLAUDE.md `# 稽核 canonical` / (g) Layer marker → M31 + hook。git blame 2026-05-12 commit 留 audit trail。 | 2026-05-12 4 audit-vs-visual gap absorbed:cell-align / divider 2px / breadcrumb tooltip / row-alignment 全 audit「Δ=0 ALL PASS」但 user 抓視覺壞(詳 historical-bugs.md)。|
| **M31** | **Adversarial dual-track 5-step canonical**(2026-05-10 user directive,verbatim quotes → `memory/feedback_codex_dual_track_synthesizer.md`)。**Step 0 入口 gate**:Claude 自試(grep / read source / cite DS canonical / WebFetch)完;啟 codex collab criteria 兩種:(a)自試卡 root cause / design tradeoff,OR(b)user 明確 keyword「跟 codex 討論 / 比稿 / 辯論 / dual-track」。**禁** auto-fire。**Step 1-5**(啟動後每題必過):(1)各自熟讀 spec/canonical/source(M29 anchor pre-grep + M23 既有 canonical 優先)(2)各自驗證(`tsc -b` + invariant + audit;codex `exec -s read-only`)— **不可只一方 verify**(M20)(3)各自視覺稽核(playwright + DOM inspect + pixel-level)(4)各自 3-column cite propose(`spec.md path:line / 引文 quote / reasoning`)— hand-wave 無 cite 自動撤回(5)整合「完美完整版本」**not pass-through**:agree → synthesize 補對方缺漏;disagree → cite battle,evidence stronger 勝。**禁**:pass-through codex propose(M28「被牽著走」);commit 無 3-column cite verdict。Hook `check_codex_collab_5step.sh` 機械化攔(P1 soft)。對齊 RFC 學術同儕審查 / Linux kernel-mailinglist cite source / Google ML eng-design-review。 | 2026-05-10 Issue 8 cell border:codex propose「Field edit border 透明」Claude pass-through ship → user「被 codex 牽著走」→ cite battle: `field-controls.spec.md` state machine + `item-anatomy.spec.md` cell 4-edge grid not in Field scope → 落地雙 owner;Issue 11 同 pattern cite battle ship retire + RFC backfill。 |
<!-- M33 retired 2026-05-22(per /knowledge-prune deep audit Lens 1+2):folded into M20 as sub-rule「Stop hook overfire defer anti-pattern」。Original session context(2026-05-13 claim-verify-gap)+ hook `stop_self_audit.sh` P0 detection retained at M20 entry。Single-bug rule → 與 M20 同類「AI self-correction under feedback signals」合併。 -->

<!-- M34 retired 2026-05-22(per /knowledge-prune deep audit Lens 1+2):folded into M7 as sub-rule「Hook detection regex 必對齊 spec wording 廣度」。Original Triple test + 錨例(story-rules.md name field detection)retained at M7 entry。Single-bug rule + same-class「rule-authoring hygiene」與 M7 合併。 -->

<!-- M35 retired 2026-05-22(per /knowledge-prune deep audit Lens 1+2):folded into M23(d) as sub-rule「Nearest same-purpose canonical wins」。Original verdict(codex 2026-05-20「Cite 存在 ≠ consume 落實」)+ Triple test + registry SSOT + hook R8 retained at M23(d)。Single-bug rule + same-class「優先消費既有」與 M23 合併。 -->

## 判斷 meta-principle 是否漏寫的 test

- 同類 bug 一年內被糾正 3 次 → meta-principle 漏寫或沒執行,檢討本清單
- 某 bug 跟現有 M-rules 任一條對不上 → **先評估 meta-merge 既有 M-rule(velocity ≤ 3/quarter,單 M-rule 必吸收 ≥ 3 prior bugs)**;真無上游覆蓋才考慮新增 M-rule。M-rule 不該無限膨脹

## 與失敗記憶索引的關係

Meta-principle 是**上游**(預防);具體 bug 歷史詳解移到 `.claude/skills/design-system-audit/references/historical-bugs.md`。CLAUDE.md 只留 meta-principle one-liner anchor + pointer。
