@qijenchen/design-system 0.1.0-beta.50 → 0.1.0-beta.51

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.
@@ -552,7 +552,7 @@ rule_story_archetype_registry() {
552
552
  */Sidebar/*|*/DataTable/*|*/header-canonical/*|*/Dialog/*|*/Sheet/*|*/Popover/*) return 0 ;;
553
553
  esac
554
554
 
555
- local REGISTRY=".claude/references/story-baseline-registry.json"
555
+ local REGISTRY="${CLAUDE_PROJECT_DIR:-.}/.claude/references/story-baseline-registry.json"
556
556
  [ -f "$REGISTRY" ] || return 0
557
557
 
558
558
  local CONTENT=""
@@ -74,14 +74,17 @@ if [ -n "$TRANSCRIPT_PATH" ] && [ -f "$TRANSCRIPT_PATH" ]; then
74
74
  fi
75
75
  fi
76
76
 
77
- # ── Mechanism 6: Completeness-claim without DS-wide scan gate(2026-06-03 user-authorized)──
77
+ # ── Mechanism 7: Completeness-claim without DS-wide scan gate(2026-06-03 user-authorized)──
78
78
  # Why: 重複 failure mode — AI 在「剛做完那件事」邊界就宣告「全做完/全部完成」,沒先跑 M10
79
79
  # 「改一處看三處」全庫 stale-ref 掃描 → user 問「真的做完?」才補掃出 loose end(CF model 漏 3 ref
80
80
  # / iceberg 等)。觸發器該是「我要宣告全做完」自己,不是 user pushback。
81
81
  # per self-verify.md Pre-final + meta-patterns M10 + mindset #6「tell me once」。
82
82
  if [ "${LAST_USER_LINE:-0}" -gt 0 ] && [ -n "$LAST_ASSISTANT" ]; then
83
83
  COMPLETION_CLAIM_RE='(全做完|全部做完|都做完了|全部完成|所有任務.{0,6}(做完|完成)|100%.{0,4}完整|真的.{0,4}做完|全做到完)'
84
- if echo "$LAST_ASSISTANT" | grep -qE "$COMPLETION_CLAIM_RE"; then
84
+ # 否定/免責排除(對齊 Mechanism 1 RETRACT_RE 精神,2026-06-03 M7 自身 false-positive):
85
+ # 宣告含「還沒說全做完」「沒資格說全做完」「核心做完…待跑」「等 X 才全做完/落地」等 disclaimer = 非完成宣告 → 不 fire。
86
+ COMPLETION_NEG_RE='(還沒.{0,6}(說|宣告|算|到)|沒.{0,3}(說|算|資格).{0,8}(全做完|完整)|未.{0,3}全做完|不(敢|算|是|該).{0,6}全做完|核心做完|完整性(掃描)?待|待.{0,4}(跑|落地|驗)|等.{0,18}(才|再).{0,8}(全做完|完整|落地|上架)|尚未.{0,4}完成)'
87
+ if echo "$LAST_ASSISTANT" | grep -qE "$COMPLETION_CLAIM_RE" && ! echo "$LAST_ASSISTANT" | grep -qE "$COMPLETION_NEG_RE"; then
85
88
  THIS_TURN_FULL=$(tail -n +$((LAST_USER_LINE+1)) "$TRANSCRIPT_PATH" 2>/dev/null)
86
89
  EDIT_COUNT=$(echo "$THIS_TURN_FULL" | grep -oE '"name":"(Edit|Write|MultiEdit)"' | wc -l | tr -d ' ')
87
90
  HAS_COMMIT=$(echo "$THIS_TURN_FULL" | grep -cE 'git commit|git merge --ff')
@@ -494,7 +497,7 @@ if [ "${CRITICAL_CODEX_TRANSPORT:-0}" = "1" ] && [ -n "$LAST_ASSISTANT" ]; then
494
497
  fi
495
498
  fi
496
499
 
497
- # ── BLOCKER for Mechanism 6 completeness-claim-without-scan(2026-06-03 user-authorized)──
500
+ # ── BLOCKER for Mechanism 7 completeness-claim-without-scan(2026-06-03 user-authorized)──
498
501
  if [ "${CRITICAL_COMPLETENESS:-0}" = "1" ] && [ -n "$LAST_ASSISTANT" ]; then
499
502
  COMPLETE_HASH=$(echo "$LAST_ASSISTANT" | tail -c 200 | shasum -a 256 | cut -c1-16)
500
503
  LAST_BLOCKED_COMPLETE_FILE="$PROJECT_DIR/.claude/logs/.last-blocked-completeness.txt"
@@ -503,7 +506,7 @@ if [ "${CRITICAL_COMPLETENESS:-0}" = "1" ] && [ -n "$LAST_ASSISTANT" ]; then
503
506
  if [ "$COMPLETE_HASH" != "$LAST_BLOCKED_COMPLETE" ]; then
504
507
  echo "$COMPLETE_HASH" > "$LAST_BLOCKED_COMPLETE_FILE" 2>/dev/null || true
505
508
  REASON=$(printf '%s' \
506
- "🚨 COMPLETENESS-CLAIM-WITHOUT-SCAN BLOCKER(M6,2026-06-03 user-authorized):你宣告「全做完/全部完成」+ 本 turn 實質多檔改動,但無「全庫掃描」證據。per self-verify.md Pre-final + M10「改一處看三處」+ mindset #6:宣告全做完前必先自己跑 (1) DS-wide stale-ref grep(對你改的東西掃連帶 reference)(2) claim-verify 表(每『done』對應證據)。立刻補跑 OR 把『全做完』改成『核心做完,完整性掃描待跑』。否則 turn 不結束。" \
509
+ "🚨 COMPLETENESS-CLAIM-WITHOUT-SCAN BLOCKER(M7,2026-06-03 user-authorized):你宣告「全做完/全部完成」+ 本 turn 實質多檔改動,但無「全庫掃描」證據。per self-verify.md Pre-final + M10「改一處看三處」+ mindset #6:宣告全做完前必先自己跑 (1) DS-wide stale-ref grep(對你改的東西掃連帶 reference)(2) claim-verify 表(每『done』對應證據)。立刻補跑 OR 把『全做完』改成『核心做完,完整性掃描待跑』。否則 turn 不結束。" \
507
510
  "本機制起因:重複 failure — user 每次問『真的全做完?』我才補掃出 loose end(CF model 漏 3 ref / iceberg)。觸發器改成『宣告完成』本身,非 user pushback。")
508
511
  printf '{"decision":"block","reason":%s}\n' "$(printf '%s' "$REASON" | jq -Rs .)"
509
512
  exit 0
@@ -8,7 +8,7 @@
8
8
  # 排除 `packages/design-system/src/` + `node_modules/`
9
9
  # - Content:tool_input.new_string // tool_input.content
10
10
  # - Global escape:content 含 `@ds-misuse-allow:` → silent exit 0
11
- # - 6 anti-patterns(P1-P5 任何 .tsx/.ts;P6 僅 .stories.tsx):
11
+ # - 7 anti-patterns(P1-P5 + P8 任何 .tsx/.ts;P6 僅 .stories.tsx):
12
12
  # P1 <DS.CircularProgress size={N}> literal number override default 24
13
13
  # P2 <DS.RadioGroupItem> 沒 wrap SelectionItem 且無 label=
14
14
  # P3 <DS.DataTable columns={[single-col]}> minimal one-column
@@ -192,6 +192,32 @@ expect_silent "19. P6 nearmiss story <Dialog defaultOpen> → silent"
192
192
  run_hook "$PROD_TSX" 'export const L = () => <DS.CircularProgress size={48} />' "Edit"
193
193
  expect_block "20. Edit(new_string)<CircularProgress size={48}> → BLOCK"
194
194
 
195
+ # ── P8 硬寫色值/字級/shadow 繞 token(broad-vs-narrow symmetry,2026-06-02 CF conformance 主防線)──
196
+
197
+ # 21. POSITIVE:硬寫 hex 色 bg-[#hex] → BLOCK
198
+ run_hook "$PROD_TSX" 'export const C = () => <div className="bg-[#3b82f6] text-white">x</div>'
199
+ expect_block "21. P8 硬寫 hex 色 bg-[#hex] → BLOCK"
200
+
201
+ # 22. NEGATIVE over-broad guard:用 token bg-[var(--color-blue-6)] → silent
202
+ run_hook "$PROD_TSX" 'export const C = () => <div className="bg-[var(--color-blue-6)] text-body">x</div>'
203
+ expect_silent "22. P8 nearmiss bg-[var(--color-blue-6)] + text-body → silent"
204
+
205
+ # 23. POSITIVE:硬寫字級 text-[14px] → BLOCK
206
+ run_hook "$PROD_TSX" 'export const C = () => <p className="text-[14px]">x</p>'
207
+ expect_block "23. P8 硬寫字級 text-[14px] → BLOCK"
208
+
209
+ # 24. POSITIVE:raw shadow-md → BLOCK
210
+ run_hook "$PROD_TSX" 'export const C = () => <div className="shadow-md rounded">x</div>'
211
+ expect_block "24. P8 raw shadow-md → BLOCK"
212
+
213
+ # 25. NEGATIVE:用 elevation token shadow-[var(--elevation-100)] → silent
214
+ run_hook "$PROD_TSX" 'export const C = () => <div className="shadow-[var(--elevation-100)] rounded">x</div>'
215
+ expect_silent "25. P8 nearmiss shadow-[var(--elevation-100)] → silent"
216
+
217
+ # 26. NEGATIVE over-broad guard:arbitrary 非色/字級值(max-w-[600px] / grid layout)不該誤攔 → silent
218
+ run_hook "$PROD_TSX" 'export const C = () => <div className="max-w-[600px] grid-cols-[1fr_2fr]">x</div>'
219
+ expect_silent "26. P8 nearmiss max-w-[600px]/grid-cols-[...](非色字 shadow)→ silent"
220
+
195
221
  echo ""
196
222
  echo "=== Summary ==="
197
223
  echo "Passed: $PASS / $((PASS + FAIL))"
@@ -69,12 +69,12 @@ T6="$USER_MSG
69
69
  "'{"message":{"role":"assistant","content":[{"type":"text","text":"我這次明確不 claim verified,只 tsc 過,實際 browser 行為要 user 驗"}]}}'
70
70
  run_test "Test 6: preemptive claim denial → no block" 0 "$T6"
71
71
 
72
- # Test 7: Mechanism 6 完整性宣告閘 — 宣告「全部做完」+ 2 edits + 無全庫掃描 → BLOCK
72
+ # Test 7: Mechanism 7 完整性宣告閘 — 宣告「全部做完」+ 2 edits + 無全庫掃描 → BLOCK
73
73
  T7="$USER_MSG
74
74
  "'{"message":{"role":"assistant","content":[{"type":"tool_use","name":"Edit","input":{}}]}}
75
75
  {"message":{"role":"assistant","content":[{"type":"tool_use","name":"Write","input":{}}]}}
76
76
  {"message":{"role":"assistant","content":[{"type":"text","text":"全部做完了,beta 已上架,tree 乾淨。"}]}}'
77
- run_test "Test 7: M6 完整性宣告+多改+無掃描 → block" 1 "$T7"
77
+ run_test "Test 7: M7 完整性宣告+多改+無掃描 → block" 1 "$T7"
78
78
 
79
79
  # Test 8: 同上但本 turn 有 grep -rn 全庫掃描 → no block(掃描證據被認列)
80
80
  T8="$USER_MSG
@@ -82,7 +82,14 @@ T8="$USER_MSG
82
82
  {"message":{"role":"assistant","content":[{"type":"tool_use","name":"Bash","input":{"command":"grep -rn foo .claude packages"}}]}}
83
83
  {"message":{"role":"assistant","content":[{"type":"tool_use","name":"Write","input":{}}]}}
84
84
  {"message":{"role":"assistant","content":[{"type":"text","text":"全部做完了,已全庫掃描確認無 loose end。"}]}}'
85
- run_test "Test 8: M6 完整性宣告+多改+有全庫掃描 → no block" 0 "$T8"
85
+ run_test "Test 8: M7 完整性宣告+多改+有全庫掃描 → no block" 0 "$T8"
86
+
87
+ # Test 9: M7 negation 排除 — 含「全做完」字串但是 disclaimer(還沒說全做完)+ 多改 + 無掃描 → NO block
88
+ T9="$USER_MSG
89
+ "'{"message":{"role":"assistant","content":[{"type":"tool_use","name":"Edit","input":{}}]}}
90
+ {"message":{"role":"assistant","content":[{"type":"tool_use","name":"Write","input":{}}]}}
91
+ {"message":{"role":"assistant","content":[{"type":"text","text":"還沒說「全做完」——等 beta.51 落地 + 最後掃過才有資格。核心做完,完整性掃描待跑。"}]}}'
92
+ run_test "Test 9: M7 negation disclaimer(還沒說全做完)→ no block" 0 "$T9"
86
93
 
87
94
  # Cleanup state file
88
95
  rm -f "$PROJECT_DIR"/.claude/logs/.last-blocked-*.txt 2>/dev/null
@@ -33,7 +33,7 @@
33
33
 
34
34
  - **Pre-edit**:`check_substantive_edit_approval_preflight.sh`(production code)+ `stop_self_audit.sh`(spec/canonical 補位)+ `check_ds_anchor_preflight.sh`(M29 anchor)
35
35
  - **Post-edit**:`stop_self_audit.sh` Mechanism 1(claim-verify-gap)BLOCKER
36
- - **Pre-final(宣告完成前)**:`stop_self_audit.sh` Mechanism 6(完整性宣告閘)BLOCKER — 宣告「全做完 / 全部完成」+ 本 turn 實質改動但**無全庫 stale-ref 掃描證據** → block。**觸發器 = 「宣告完成」本身,非等 user 問第二次**(2026-06-03 user-authorized,根治重複 failure)
36
+ - **Pre-final(宣告完成前)**:`stop_self_audit.sh` Mechanism 7(完整性宣告閘)BLOCKER — 宣告「全做完 / 全部完成」+ 本 turn 實質改動但**無全庫 stale-ref 掃描證據** → block。**觸發器 = 「宣告完成」本身,非等 user 問第二次**(2026-06-03 user-authorized,根治重複 failure)
37
37
  - **Pre-commit**:`scripts/audit-content-quality.mjs --check` + `scripts/extract-canonical-rules.mjs` 各 fail = block
38
38
 
39
39
  ## Anti-pattern(永久 ban)
@@ -43,7 +43,7 @@
43
43
  - ❌ 改 hook 沒跑 syntax check + smoke test
44
44
  - ❌「下個 session 補」defer 可做的 verify(M33 違反)
45
45
  - ❌ pass-through Explore / codex propose 沒 own-version 比稿
46
- - ❌ 宣告「全做完 / 全部完成」前沒自己跑 M10「改一處看三處」全庫 stale-ref 掃描 → 等 user 問「真的做完?」才補掃出 loose end(M6 BLOCKER;anchor:CF model 改完漏 3 ref / iceberg)
46
+ - ❌ 宣告「全做完 / 全部完成」前沒自己跑 M10「改一處看三處」全庫 stale-ref 掃描 → 等 user 問「真的做完?」才補掃出 loose end(M7 BLOCKER;anchor:CF model 改完漏 3 ref / iceberg)
47
47
 
48
48
  ## 對齊歷史
49
49
 
@@ -7,7 +7,7 @@
7
7
  "scripts/composition-fidelity-visual-diff.mjs",
8
8
  "product-workspace apps/template/src/AllDsComponents.stories.tsx (DsCanonicalPortal)"
9
9
  ],
10
- "generatedAt": "2026-06-02T17:00:15.835Z"
10
+ "generatedAt": "2026-06-02T19:13:16.984Z"
11
11
  },
12
12
  "components": {
13
13
  "accordion": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qijenchen/design-system",
3
- "version": "0.1.0-beta.50",
3
+ "version": "0.1.0-beta.51",
4
4
  "private": false,
5
5
  "description": "World-class design system — components, patterns, tokens, hooks (single source of truth for team distribution).",
6
6
  "type": "module",