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

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.
@@ -74,6 +74,28 @@ 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)──
78
+ # Why: 重複 failure mode — AI 在「剛做完那件事」邊界就宣告「全做完/全部完成」,沒先跑 M10
79
+ # 「改一處看三處」全庫 stale-ref 掃描 → user 問「真的做完?」才補掃出 loose end(CF model 漏 3 ref
80
+ # / iceberg 等)。觸發器該是「我要宣告全做完」自己,不是 user pushback。
81
+ # per self-verify.md Pre-final + meta-patterns M10 + mindset #6「tell me once」。
82
+ if [ "${LAST_USER_LINE:-0}" -gt 0 ] && [ -n "$LAST_ASSISTANT" ]; then
83
+ COMPLETION_CLAIM_RE='(全做完|全部做完|都做完了|全部完成|所有任務.{0,6}(做完|完成)|100%.{0,4}完整|真的.{0,4}做完|全做到完)'
84
+ if echo "$LAST_ASSISTANT" | grep -qE "$COMPLETION_CLAIM_RE"; then
85
+ THIS_TURN_FULL=$(tail -n +$((LAST_USER_LINE+1)) "$TRANSCRIPT_PATH" 2>/dev/null)
86
+ EDIT_COUNT=$(echo "$THIS_TURN_FULL" | grep -oE '"name":"(Edit|Write|MultiEdit)"' | wc -l | tr -d ' ')
87
+ HAS_COMMIT=$(echo "$THIS_TURN_FULL" | grep -cE 'git commit|git merge --ff')
88
+ if [ "${EDIT_COUNT:-0}" -ge 2 ] || [ "${HAS_COMMIT:-0}" -gt 0 ]; then
89
+ # 全庫掃描證據:grep -r/-rn / rg 跨目錄掃 stale ref,OR claim-verify 表 marker
90
+ SCAN_RE='(grep -[a-zA-Z]*r|rg -|claim-verify|完整性掃描|改一處看三處|stale.?ref|DS-wide|全庫掃)'
91
+ if ! echo "$THIS_TURN_FULL" | grep -qiE "$SCAN_RE"; then
92
+ WARNINGS="${WARNINGS}\n • 🚨 完整性宣告閘:你宣告「全做完/全部完成」+ 本 turn 實質改動,但無「全庫掃描」證據(無 grep -r/rg 掃 stale ref、無 claim-verify 表)。per self-verify.md Pre-final + M10「改一處看三處」:宣告全做完前必先自己跑 DS-wide stale-ref 掃描 + claim-verify,不等 user 問第二次。"
93
+ CRITICAL_COMPLETENESS=1
94
+ fi
95
+ fi
96
+ fi
97
+ fi
98
+
77
99
  # ── Mechanism 2: Auto-prune trigger ─────────────────────────────────────────
78
100
  if [ -f CLAUDE.md ]; then
79
101
  L=$(wc -l < CLAUDE.md | tr -d ' ')
@@ -472,4 +494,20 @@ if [ "${CRITICAL_CODEX_TRANSPORT:-0}" = "1" ] && [ -n "$LAST_ASSISTANT" ]; then
472
494
  fi
473
495
  fi
474
496
 
497
+ # ── BLOCKER for Mechanism 6 completeness-claim-without-scan(2026-06-03 user-authorized)──
498
+ if [ "${CRITICAL_COMPLETENESS:-0}" = "1" ] && [ -n "$LAST_ASSISTANT" ]; then
499
+ COMPLETE_HASH=$(echo "$LAST_ASSISTANT" | tail -c 200 | shasum -a 256 | cut -c1-16)
500
+ LAST_BLOCKED_COMPLETE_FILE="$PROJECT_DIR/.claude/logs/.last-blocked-completeness.txt"
501
+ LAST_BLOCKED_COMPLETE=""
502
+ [ -f "$LAST_BLOCKED_COMPLETE_FILE" ] && LAST_BLOCKED_COMPLETE=$(cat "$LAST_BLOCKED_COMPLETE_FILE" 2>/dev/null || echo "")
503
+ if [ "$COMPLETE_HASH" != "$LAST_BLOCKED_COMPLETE" ]; then
504
+ echo "$COMPLETE_HASH" > "$LAST_BLOCKED_COMPLETE_FILE" 2>/dev/null || true
505
+ 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 不結束。" \
507
+ "本機制起因:重複 failure — user 每次問『真的全做完?』我才補掃出 loose end(CF model 漏 3 ref / iceberg)。觸發器改成『宣告完成』本身,非 user pushback。")
508
+ printf '{"decision":"block","reason":%s}\n' "$(printf '%s' "$REASON" | jq -Rs .)"
509
+ exit 0
510
+ fi
511
+ fi
512
+
475
513
  exit 0
@@ -16,8 +16,8 @@ run_test() {
16
16
  printf '%s\n' "$transcript_content" > "$transcript"
17
17
  local input
18
18
  input=$(printf '{"transcript_path":"%s","session_id":"test"}' "$transcript")
19
- # Reset state to avoid block-once dedup interference
20
- rm -f "$PROJECT_DIR/.claude/logs/.last-blocked-claim.txt" 2>/dev/null
19
+ # Reset state to avoid block-once dedup interference(all mechanisms' .last-blocked-*)
20
+ rm -f "$PROJECT_DIR"/.claude/logs/.last-blocked-*.txt 2>/dev/null
21
21
  local stdout; stdout=$(echo "$input" | bash "$HOOK" 2>/dev/null)
22
22
  if [ "$expect_block" = "1" ]; then
23
23
  if echo "$stdout" | grep -q '"decision":"block"'; then
@@ -69,8 +69,23 @@ 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
73
+ T7="$USER_MSG
74
+ "'{"message":{"role":"assistant","content":[{"type":"tool_use","name":"Edit","input":{}}]}}
75
+ {"message":{"role":"assistant","content":[{"type":"tool_use","name":"Write","input":{}}]}}
76
+ {"message":{"role":"assistant","content":[{"type":"text","text":"全部做完了,beta 已上架,tree 乾淨。"}]}}'
77
+ run_test "Test 7: M6 完整性宣告+多改+無掃描 → block" 1 "$T7"
78
+
79
+ # Test 8: 同上但本 turn 有 grep -rn 全庫掃描 → no block(掃描證據被認列)
80
+ T8="$USER_MSG
81
+ "'{"message":{"role":"assistant","content":[{"type":"tool_use","name":"Edit","input":{}}]}}
82
+ {"message":{"role":"assistant","content":[{"type":"tool_use","name":"Bash","input":{"command":"grep -rn foo .claude packages"}}]}}
83
+ {"message":{"role":"assistant","content":[{"type":"tool_use","name":"Write","input":{}}]}}
84
+ {"message":{"role":"assistant","content":[{"type":"text","text":"全部做完了,已全庫掃描確認無 loose end。"}]}}'
85
+ run_test "Test 8: M6 完整性宣告+多改+有全庫掃描 → no block" 0 "$T8"
86
+
72
87
  # Cleanup state file
73
- rm -f "$PROJECT_DIR/.claude/logs/.last-blocked-claim.txt" 2>/dev/null
88
+ rm -f "$PROJECT_DIR"/.claude/logs/.last-blocked-*.txt 2>/dev/null
74
89
 
75
90
  echo "Results: $PASS PASS, $FAIL FAIL"
76
91
  [ "$FAIL" -eq 0 ] || exit 1
@@ -33,6 +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
37
  - **Pre-commit**:`scripts/audit-content-quality.mjs --check` + `scripts/extract-canonical-rules.mjs` 各 fail = block
37
38
 
38
39
  ## Anti-pattern(永久 ban)
@@ -42,6 +43,7 @@
42
43
  - ❌ 改 hook 沒跑 syntax check + smoke test
43
44
  - ❌「下個 session 補」defer 可做的 verify(M33 違反)
44
45
  - ❌ pass-through Explore / codex propose 沒 own-version 比稿
46
+ - ❌ 宣告「全做完 / 全部完成」前沒自己跑 M10「改一處看三處」全庫 stale-ref 掃描 → 等 user 問「真的做完?」才補掃出 loose end(M6 BLOCKER;anchor:CF model 改完漏 3 ref / iceberg)
45
47
 
46
48
  ## 對齊歷史
47
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-02T16:12:11.748Z"
10
+ "generatedAt": "2026-06-02T17:00:15.835Z"
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.49",
3
+ "version": "0.1.0-beta.50",
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",