oh-my-customcode 2.0.7 → 2.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +3 -2
  2. package/dist/cli/index.js +28 -7
  3. package/dist/index.js +28 -7
  4. package/package.json +1 -1
  5. package/templates/.claude/hooks/hooks.json +28 -12
  6. package/templates/.claude/hooks/scripts/auto-continue-guard.sh +5 -5
  7. package/templates/.claude/hooks/scripts/auto-dev-token-tracker.sh +12 -1
  8. package/templates/.claude/hooks/scripts/bash-cd-advisor.sh +172 -0
  9. package/templates/.claude/hooks/scripts/fail-axis-cause-advisor.sh +2 -2
  10. package/templates/.claude/hooks/scripts/failure-ledger.sh +18 -0
  11. package/templates/.claude/hooks/scripts/file-change-validator.sh +6 -3
  12. package/templates/.claude/hooks/scripts/omcustom-auto-update.sh +19 -5
  13. package/templates/.claude/hooks/scripts/rule-deletion-guard.sh +118 -1
  14. package/templates/.claude/hooks/scripts/session-env-check.sh +20 -5
  15. package/templates/.claude/hooks/scripts/stall-detection-advisor.sh +9 -5
  16. package/templates/.claude/hooks/scripts/stuck-detector.sh +21 -4
  17. package/templates/.claude/hooks/scripts/subagent-failure-advisor.sh +48 -29
  18. package/templates/.claude/hooks/scripts/task-outcome-recorder.sh +15 -8
  19. package/templates/.claude/ontology/agents.yaml +71 -7
  20. package/templates/.claude/ontology/graphs/agent-skill.json +64 -5
  21. package/templates/.claude/ontology/graphs/full-graph.json +236 -3
  22. package/templates/.claude/ontology/skills.yaml +65 -1
  23. package/templates/.claude/rules/MUST-enforcement-policy.md +3 -3
  24. package/templates/.claude/rules/MUST-orchestrator-coordination.md +1 -1
  25. package/templates/.claude/rules/SHOULD-memory-integration.md +1 -1
  26. package/templates/.claude/settings.json +28 -12
  27. package/templates/.claude/skills/fsd/SKILL.md +10 -9
  28. package/templates/.claude/skills/goal/SKILL.md +5 -5
  29. package/templates/.claude/skills/omcustom-loop/SKILL.md +4 -4
  30. package/templates/.claude/skills/pipeline/workflows/auto-dev.yaml +13 -0
  31. package/templates/guides/claude-code/04-agent-skills.md +1 -1
  32. package/templates/guides/claude-code/15-version-compatibility.md +46 -46
  33. package/templates/manifest.json +1 -1
  34. package/templates/workflows/auto-dev.yaml +13 -0
@@ -17,7 +17,9 @@
17
17
  "lang-typescript-expert": [
18
18
  "typescript-best-practices"
19
19
  ],
20
- "lang-java-expert": [],
20
+ "lang-java-expert": [
21
+ "java-best-practices"
22
+ ],
21
23
  "be-fastapi-expert": [
22
24
  "fastapi-best-practices"
23
25
  ],
@@ -105,7 +107,32 @@
105
107
  "claude-code-bible"
106
108
  ],
107
109
  "sys-memory-keeper": [],
108
- "sys-naggy": []
110
+ "sys-naggy": [],
111
+ "agora-runner": [
112
+ "agora"
113
+ ],
114
+ "be-django-expert": [
115
+ "django-best-practices"
116
+ ],
117
+ "db-alembic-expert": [
118
+ "alembic-best-practices",
119
+ "postgres-best-practices"
120
+ ],
121
+ "fe-design-expert": [
122
+ "impeccable-design",
123
+ "web-design-guidelines",
124
+ "diagram-design"
125
+ ],
126
+ "sec-codeql-expert": [
127
+ "cve-triage",
128
+ "adversarial-review"
129
+ ],
130
+ "slack-cli-expert": [],
131
+ "tracker-checkpoint": [
132
+ "dag-orchestration",
133
+ "pipeline-guards"
134
+ ],
135
+ "wiki-curator": []
109
136
  },
110
137
  "reverse": {
111
138
  "go-best-practices": [
@@ -136,7 +163,8 @@
136
163
  "fe-vercel-agent"
137
164
  ],
138
165
  "web-design-guidelines": [
139
- "fe-vercel-agent"
166
+ "fe-vercel-agent",
167
+ "fe-design-expert"
140
168
  ],
141
169
  "vercel-deploy": [
142
170
  "fe-vercel-agent"
@@ -163,7 +191,8 @@
163
191
  "de-pipeline-expert"
164
192
  ],
165
193
  "postgres-best-practices": [
166
- "db-postgres-expert"
194
+ "db-postgres-expert",
195
+ "db-alembic-expert"
167
196
  ],
168
197
  "redis-best-practices": [
169
198
  "db-redis-expert"
@@ -225,7 +254,37 @@
225
254
  "lists": [],
226
255
  "monitoring-setup": [],
227
256
  "result-aggregation": [],
228
- "status": []
257
+ "status": [],
258
+ "java-best-practices": [
259
+ "lang-java-expert"
260
+ ],
261
+ "agora": [
262
+ "agora-runner"
263
+ ],
264
+ "django-best-practices": [
265
+ "be-django-expert"
266
+ ],
267
+ "alembic-best-practices": [
268
+ "db-alembic-expert"
269
+ ],
270
+ "impeccable-design": [
271
+ "fe-design-expert"
272
+ ],
273
+ "diagram-design": [
274
+ "fe-design-expert"
275
+ ],
276
+ "cve-triage": [
277
+ "sec-codeql-expert"
278
+ ],
279
+ "adversarial-review": [
280
+ "sec-codeql-expert"
281
+ ],
282
+ "dag-orchestration": [
283
+ "tracker-checkpoint"
284
+ ],
285
+ "pipeline-guards": [
286
+ "tracker-checkpoint"
287
+ ]
229
288
  },
230
289
  "nodes": [],
231
290
  "links": []
@@ -433,6 +433,66 @@
433
433
  "R005": {
434
434
  "type": "Rule",
435
435
  "class": "MayRule"
436
+ },
437
+ "java-best-practices": {
438
+ "type": "Skill",
439
+ "class": "BestPracticeSkill"
440
+ },
441
+ "agora": {
442
+ "type": "Skill"
443
+ },
444
+ "django-best-practices": {
445
+ "type": "Skill",
446
+ "class": "BestPracticeSkill"
447
+ },
448
+ "alembic-best-practices": {
449
+ "type": "Skill",
450
+ "class": "BestPracticeSkill"
451
+ },
452
+ "impeccable-design": {
453
+ "type": "Skill"
454
+ },
455
+ "diagram-design": {
456
+ "type": "Skill"
457
+ },
458
+ "cve-triage": {
459
+ "type": "Skill"
460
+ },
461
+ "adversarial-review": {
462
+ "type": "Skill"
463
+ },
464
+ "dag-orchestration": {
465
+ "type": "Skill"
466
+ },
467
+ "pipeline-guards": {
468
+ "type": "Skill"
469
+ },
470
+ "agora-runner": {
471
+ "type": "Agent"
472
+ },
473
+ "be-django-expert": {
474
+ "type": "Agent",
475
+ "class": "BackendExpert"
476
+ },
477
+ "db-alembic-expert": {
478
+ "type": "Agent",
479
+ "class": "DatabaseExpert"
480
+ },
481
+ "fe-design-expert": {
482
+ "type": "Agent",
483
+ "class": "FrontendExpert"
484
+ },
485
+ "sec-codeql-expert": {
486
+ "type": "Agent"
487
+ },
488
+ "slack-cli-expert": {
489
+ "type": "Agent"
490
+ },
491
+ "tracker-checkpoint": {
492
+ "type": "Agent"
493
+ },
494
+ "wiki-curator": {
495
+ "type": "Agent"
436
496
  }
437
497
  },
438
498
  "edges": [
@@ -721,6 +781,66 @@
721
781
  "target": "flutter-best-practices",
722
782
  "relation": "requires"
723
783
  },
784
+ {
785
+ "source": "lang-java-expert",
786
+ "target": "java-best-practices",
787
+ "relation": "requires"
788
+ },
789
+ {
790
+ "source": "agora-runner",
791
+ "target": "agora",
792
+ "relation": "requires"
793
+ },
794
+ {
795
+ "source": "be-django-expert",
796
+ "target": "django-best-practices",
797
+ "relation": "requires"
798
+ },
799
+ {
800
+ "source": "db-alembic-expert",
801
+ "target": "alembic-best-practices",
802
+ "relation": "requires"
803
+ },
804
+ {
805
+ "source": "db-alembic-expert",
806
+ "target": "postgres-best-practices",
807
+ "relation": "requires"
808
+ },
809
+ {
810
+ "source": "fe-design-expert",
811
+ "target": "impeccable-design",
812
+ "relation": "requires"
813
+ },
814
+ {
815
+ "source": "fe-design-expert",
816
+ "target": "web-design-guidelines",
817
+ "relation": "requires"
818
+ },
819
+ {
820
+ "source": "fe-design-expert",
821
+ "target": "diagram-design",
822
+ "relation": "requires"
823
+ },
824
+ {
825
+ "source": "sec-codeql-expert",
826
+ "target": "cve-triage",
827
+ "relation": "requires"
828
+ },
829
+ {
830
+ "source": "sec-codeql-expert",
831
+ "target": "adversarial-review",
832
+ "relation": "requires"
833
+ },
834
+ {
835
+ "source": "tracker-checkpoint",
836
+ "target": "dag-orchestration",
837
+ "relation": "requires"
838
+ },
839
+ {
840
+ "source": "tracker-checkpoint",
841
+ "target": "pipeline-guards",
842
+ "relation": "requires"
843
+ },
724
844
  {
725
845
  "source": "dev-lead-routing",
726
846
  "target": "be-fastapi-expert",
@@ -884,7 +1004,9 @@
884
1004
  ]
885
1005
  },
886
1006
  "lang-java-expert": {
887
- "requires": [],
1007
+ "requires": [
1008
+ "java-best-practices"
1009
+ ],
888
1010
  "routed_by": [
889
1011
  "dev-lead-routing"
890
1012
  ]
@@ -1219,7 +1341,8 @@
1219
1341
  },
1220
1342
  "web-design-guidelines": {
1221
1343
  "required_by": [
1222
- "fe-vercel-agent"
1344
+ "fe-vercel-agent",
1345
+ "fe-design-expert"
1223
1346
  ],
1224
1347
  "depends_on": []
1225
1348
  },
@@ -1267,7 +1390,8 @@
1267
1390
  },
1268
1391
  "postgres-best-practices": {
1269
1392
  "required_by": [
1270
- "db-postgres-expert"
1393
+ "db-postgres-expert",
1394
+ "db-alembic-expert"
1271
1395
  ],
1272
1396
  "depends_on": []
1273
1397
  },
@@ -1527,6 +1651,115 @@
1527
1651
  },
1528
1652
  "R018": {
1529
1653
  "referenced_by": []
1654
+ },
1655
+ "java-best-practices": {
1656
+ "required_by": [
1657
+ "lang-java-expert"
1658
+ ],
1659
+ "depends_on": []
1660
+ },
1661
+ "agora": {
1662
+ "required_by": [
1663
+ "agora-runner"
1664
+ ],
1665
+ "depends_on": []
1666
+ },
1667
+ "django-best-practices": {
1668
+ "required_by": [
1669
+ "be-django-expert"
1670
+ ],
1671
+ "depends_on": []
1672
+ },
1673
+ "alembic-best-practices": {
1674
+ "required_by": [
1675
+ "db-alembic-expert"
1676
+ ],
1677
+ "depends_on": []
1678
+ },
1679
+ "impeccable-design": {
1680
+ "required_by": [
1681
+ "fe-design-expert"
1682
+ ],
1683
+ "depends_on": []
1684
+ },
1685
+ "diagram-design": {
1686
+ "required_by": [
1687
+ "fe-design-expert"
1688
+ ],
1689
+ "depends_on": []
1690
+ },
1691
+ "cve-triage": {
1692
+ "required_by": [
1693
+ "sec-codeql-expert"
1694
+ ],
1695
+ "depends_on": []
1696
+ },
1697
+ "adversarial-review": {
1698
+ "required_by": [
1699
+ "sec-codeql-expert"
1700
+ ],
1701
+ "depends_on": []
1702
+ },
1703
+ "dag-orchestration": {
1704
+ "required_by": [
1705
+ "tracker-checkpoint"
1706
+ ],
1707
+ "depends_on": []
1708
+ },
1709
+ "pipeline-guards": {
1710
+ "required_by": [
1711
+ "tracker-checkpoint"
1712
+ ],
1713
+ "depends_on": []
1714
+ },
1715
+ "agora-runner": {
1716
+ "requires": [
1717
+ "agora"
1718
+ ],
1719
+ "routed_by": []
1720
+ },
1721
+ "be-django-expert": {
1722
+ "requires": [
1723
+ "django-best-practices"
1724
+ ],
1725
+ "routed_by": []
1726
+ },
1727
+ "db-alembic-expert": {
1728
+ "requires": [
1729
+ "alembic-best-practices",
1730
+ "postgres-best-practices"
1731
+ ],
1732
+ "routed_by": []
1733
+ },
1734
+ "fe-design-expert": {
1735
+ "requires": [
1736
+ "impeccable-design",
1737
+ "web-design-guidelines",
1738
+ "diagram-design"
1739
+ ],
1740
+ "routed_by": []
1741
+ },
1742
+ "sec-codeql-expert": {
1743
+ "requires": [
1744
+ "cve-triage",
1745
+ "adversarial-review"
1746
+ ],
1747
+ "routed_by": []
1748
+ },
1749
+ "slack-cli-expert": {
1750
+ "requires": [],
1751
+ "routed_by": []
1752
+ },
1753
+ "tracker-checkpoint": {
1754
+ "requires": [
1755
+ "dag-orchestration",
1756
+ "pipeline-guards"
1757
+ ],
1758
+ "routed_by": []
1759
+ },
1760
+ "wiki-curator": {
1761
+ "requires": [],
1762
+ "routed_by": []
1530
1763
  }
1531
1764
  }
1532
1765
  }
@@ -17,7 +17,8 @@ classes:
17
17
  go-backend-best-practices, docker-best-practices, aws-best-practices,
18
18
  postgres-best-practices, redis-best-practices, supabase-postgres-best-practices,
19
19
  airflow-best-practices, dbt-best-practices, kafka-best-practices,
20
- spark-best-practices, snowflake-best-practices, pipeline-architecture-patterns
20
+ spark-best-practices, snowflake-best-practices, pipeline-architecture-patterns,
21
+ java-best-practices, django-best-practices, alembic-best-practices
21
22
  ]
22
23
  description: "Language/framework best practices and architecture patterns"
23
24
 
@@ -533,3 +534,66 @@ skills:
533
534
  summary: "UI code review guidelines for accessibility, performance, and UX best practices"
534
535
  keywords: [ui, accessibility, ux, performance, design]
535
536
  rule_references: []
537
+
538
+ java-best-practices:
539
+ class: BestPracticeSkill
540
+ description: "Modern Java 25 LTS patterns from Virtual Threads, Pattern Matching, Records, and Sealed Classes"
541
+ user_invocable: false
542
+ model_invocable: true
543
+ scope: core
544
+
545
+ agora:
546
+ description: "Use when a design or decision needs adversarial multi-round scrutiny from several independent model vendors. Runs anonymized A/B/C reviewer rounds with a rotating judge and produces a consensus report."
547
+ user_invocable: true
548
+ model_invocable: true
549
+ scope: core
550
+
551
+ django-best-practices:
552
+ class: BestPracticeSkill
553
+ description: "Django patterns for production-ready Python web applications"
554
+ user_invocable: false
555
+ model_invocable: true
556
+ scope: core
557
+
558
+ alembic-best-practices:
559
+ class: BestPracticeSkill
560
+ description: "Alembic migration patterns for naming conventions, safety checks, expand-contract, env.py configuration, and CI integration"
561
+ user_invocable: false
562
+ model_invocable: true
563
+ scope: core
564
+
565
+ impeccable-design:
566
+ description: "AI design language for production-grade UI — 10 commands covering typography, color, motion, layout, and UX writing quality"
567
+ user_invocable: false
568
+ model_invocable: true
569
+ scope: core
570
+
571
+ diagram-design:
572
+ description: "Brand-consistent editorial diagrams — SVG generation for release notes, architecture docs, and marketing materials"
573
+ user_invocable: true
574
+ model_invocable: true
575
+ scope: package
576
+
577
+ cve-triage:
578
+ description: "CVE triage workflow for vulnerability analysis, reproduction assessment, and patch verification"
579
+ user_invocable: false
580
+ model_invocable: true
581
+ scope: core
582
+
583
+ adversarial-review:
584
+ description: "Adversarial code review using attacker mindset — trust boundary, attack surface, business logic, and defense evaluation"
585
+ user_invocable: true
586
+ model_invocable: true
587
+ scope: core
588
+
589
+ dag-orchestration:
590
+ description: "YAML-based DAG workflow engine with topological execution and failure strategies"
591
+ user_invocable: false
592
+ model_invocable: true
593
+ scope: core
594
+
595
+ pipeline-guards:
596
+ description: "Safety constraints and quality gates for pipeline and workflow execution"
597
+ user_invocable: false
598
+ model_invocable: true
599
+ scope: core
@@ -16,12 +16,12 @@ oh-my-customcode uses an **advisory-first enforcement model**. Most rules are en
16
16
 
17
17
  | Tier | Mechanism | Rules | Behavior |
18
18
  |------|-----------|-------|----------|
19
- | Hard Block | PreToolUse hook, exit 2 | stage-blocker, dev-server tmux, rule-deletion-guard | Prevents tool execution |
19
+ | Hard Block | PreToolUse hook, exit 2 | stage-blocker, rule-deletion-guard | Prevents tool execution |
20
20
  | Soft Block | Stop hook prompt | R011 session-end saves | Auto-performs then approves |
21
21
  | Conversation Block | PostToolUse hook + `continueOnBlock` (CC v2.1.139+), exit 2 | stuck-detector, context-budget-advisor, cost-cap-advisor | Feeds rejection reason into conversation; Claude continues with awareness |
22
22
  | Advisory | PostToolUse hooks | R007, R008, R009, R010, R018 | Warns via stderr, never blocks |
23
23
  | Advisory (proactive) | UserPromptSubmit + SubagentStop + PostToolUse hooks | R007, R008 (`r007-r008-drift-advisor.sh` — #1229 UserPromptSubmit, #1545 SubagentStop, #1553 PostToolUse) | Reads last assistant turn; emits advisory if header/prefix absent. SubagentStop wiring (#1545) covers subagent stops in no-user-input loops (`/fsd`); PostToolUse (#1553) covers the orchestrator-only stretch before the first subagent spawn. Complements retroactive Stop-hook (`session-reflection.sh`, #1190). **v1.1.43부터 실제 발화**(파서 셀렉터 `.role`→`.message.role` 수정 — 상세는 Read 도구로 원문 주석 참조). v1.1.49부터 역방향(announce > tool_use) 신호 포함, 기본 off 옵트인 (#1595 #6). v1.1.73의 narration 채널 분리 옵션(`OMCUSTOM_R008_NARRATION`, #1701 #2)은 실 세션 5건(CC 2.1.233~2.1.274) 실측에서 narration 마커 매칭 0/354·판정 on/off 동일로 전제가 성립하지 않아 v1.1.74에서 은퇴했습니다(#1703) — R008 누락은 채널 오선택이 아니라 마커 미직렬화 형태입니다. **v1.1.62(#1650 D)부터 서브에이전트 세션에서는 침묵**: hook stdin의 `agent_id`(CC 스키마상 서브에이전트 내부 발화에만 존재)가 있으면 exit 0 — 단 `SubagentStart`/`SubagentStop`은 `agent_id`가 대상 식별자라 예외(판정 수행). 중첩 서브에이전트 안의 SubagentStop은 억제 못 함(R010 정책상 도달 불가 경로). 완료 보고가 advisory 응답으로 대체되던 훅 피드백 잠식(R020 8항, #1652 #3)의 advisory 계열 차단. |
24
- | Advisory (telemetry) | PostToolUseFailure hook | — (계측 전용, 규칙 강제 없음) | `failure-ledger.sh` (#1561, v1.1.44) — 도구 실패를 JSONL 원장에 append. stdout/stderr 무출력이라 모델에 도달하지 않으며 절대 차단하지 않음 |
24
+ | Advisory (telemetry + advisory) | PostToolUseFailure hook | — (계측+어드바이저리, 규칙 강제 없음) | `failure-ledger.sh` (#1561, v1.1.44) — 실패를 JSONL 원장에 append, 무출력(모델 미도달)·비차단. 같은 이벤트의 `subagent-failure-advisor.sh`(Agent/Task)는 additionalContext advisory 전달 |
25
25
  | Advisory (proactive) | UserPromptSubmit hook | R020 (원인 진단) | `fail-axis-cause-advisor.sh` (#1561, v1.1.44) — 원장에 실패 기록이 있는데 원인 진술 없는 재촉 프롬프트가 오면 `hookSpecificOutput.additionalContext`로 "원인 가설 되묻기" advisory 전달. 원장 부재 시 조용히 통과 |
26
26
  | Prompt-based | CLAUDE.md + rules/ + `SessionStart` 재주입(matcher `*`; PostCompact 이벤트 배선은 유지되나 효과 미보장[^postcompact]) | All MUST rules | Behavioral guidance in context |
27
27
 
@@ -54,7 +54,7 @@ oh-my-customcode uses an **advisory-first enforcement model**. Most rules are en
54
54
  <!-- DETAIL: CC version notes (v2.1.211-v2.1.275)
55
55
  > **v2.1.211/212/214+**: 훅의 enforcement 결정이 auto/unattended 모드에서 안정적으로 존중되도록 세 건이 수정되었습니다 — (211) auto mode가 unsandboxed Bash에 대한 PreToolUse 훅의 `ask` 결정을 덮어쓰던 문제가 수정되어 훅 `ask`가 최소 prompt로 floor되고, (212) `continue:false` 훅의 halt가 도구 실패·중간 완료 시 누락되던 문제 및 훅 인프라 오류가 user rejection으로 오보고되던 문제가 수정되었으며, (214) 훅 stdout JSON이 스키마 검증에 실패할 때 exit code 2가 문서대로 차단하지 못하던 문제가 수정되었습니다. R021 Enforcement Tiers(Hard Block=exit 2, Conversation Block=continueOnBlock exit 2, Advisory)가 훅의 block/ask 결정 존중에 의존하므로, 세 수정 모두 hard-block·advisory 훅(stage-blocker, rule-deletion-guard, stuck-detector 등)의 강제 신뢰성을 강화합니다 — v2.1.210 훅 timeout phantom-rejection 수정의 연장선.
56
56
 
57
- > **v2.1.222+**: PreToolUse auto-allow 훅이 background agent task(summaries/compaction/renames)에서 tool restriction을 우회하던 문제가 수정되었습니다. 즉 위 Enforcement Tiers 표의 **Hard Block 계층(stage-blocker, dev-server tmux, rule-deletion-guard)이 background agent task 경로에서 우회될 수 있었다**는 뜻이며, background agent를 쓰는 장기 무인 루프에서 hard-block 훅이 실제로는 강제되지 않는 구간이 존재했습니다. v2.1.211/212/214 훅 결정 존중 체인의 연장선입니다.
57
+ > **v2.1.222+**: PreToolUse auto-allow 훅이 background agent task(summaries/compaction/renames)에서 tool restriction을 우회하던 문제가 수정되었습니다. 즉 위 Enforcement Tiers 표의 **Hard Block 계층(stage-blocker, rule-deletion-guard)이 background agent task 경로에서 우회될 수 있었다**는 뜻이며, background agent를 쓰는 장기 무인 루프에서 hard-block 훅이 실제로는 강제되지 않는 구간이 존재했습니다. v2.1.211/212/214 훅 결정 존중 체인의 연장선입니다.
58
58
 
59
59
  > **v2.1.247+**: 훅 또는 background agent가 수 메가바이트의 error 출력을 찍어 대화를 overflow시켜 세션이 "Prompt is too long"으로 멈추던 결함이 수정되었습니다. 같은 릴리즈에서 hook/background task의 output file을 쓸 수 없을 때 무한 메모리 증가하던 문제도 수정되어, 이제 출력이 소실된 위치를 파일에 남깁니다. 이 저장소는 advisory 훅(`r007-r008-drift-advisor.sh`, `failure-ledger.sh`, `fail-axis-cause-advisor.sh` 등)을 다수 운용하므로, 훅 출력 폭주가 세션 자체를 wedge시키는 이 실패 클래스에 해당합니다 — v2.1.211/212/214/222 훅 신뢰성 계열의 연장선입니다.
60
60
 
@@ -209,7 +209,7 @@ When the user explicitly signals full-delegation intent, the orchestrator operat
209
209
  - **R001 (Safety)**: All safety rules remain absolute — no exceptions
210
210
  - **R007/R008 (Identification)**: Agent/tool identification still required for traceability
211
211
  - **File Write/Edit delegation**: Still requires specialist agents — autonomous mode only relaxes git and gate overhead
212
- - **Hard-block hooks**: stage-blocker, dev-server tmux, .md creation blocker remain active
212
+ - **Hard-block hooks**: stage-blocker, rule-deletion-guard remain active
213
213
  - **R009 (Parallel execution)**: Still required for efficiency
214
214
 
215
215
  ### Scope and Lifetime
@@ -549,7 +549,7 @@ References: #1226 (item 3), #1227.
549
549
  -->
550
550
 
551
551
  <!-- DETAIL: v2.1.271/273+ background dedup/resume file-read/blockReadsOutside
552
- > **v2.1.271/273+**: (271) 대화가 compact된 뒤에도 계속 돌고 있던 백그라운드 명령(watch task, dev server)의 **중복 사본**이 새로 시작되던 결함이 수정되었습니다 — 구버전에서 post-compact 중복 프로세스는 지시가 아니라 compaction 아티팩트였습니다(cross-ref R010 dev-server tmux hard block). (271) `/resume`·`/teleport`가 이전 대화의 파일-읽음 추적을 그대로 유지해, 재개된 대화가 **한 번도 읽지 않은 파일**을 편집할 수 있던 결함이 수정되었습니다(cross-ref R005 v2.1.228 read-before-write 노트). (271) claude.ai에서 동기화된 스킬이 로그아웃 후에도 디스크에 남아있던 결함이 수정되어, `cleanupPeriodDays` 내 갱신되지 않은 사본은 이제 복구 가능한 휴지통으로 이동합니다. (273) `permissions.blockReadsOutsideWorkingDirectories`: 저장소 settings가 지정한 메모리 디렉토리는 더 이상 프롬프트에 로드·회상·색인·memory extraction에 사용되지 않습니다 — 이 규칙의 `autoMemoryDirectory`와 관련됩니다: 이 설정 하에서는 저장소가 지정한 메모리 디렉토리가 제외됩니다.
552
+ > **v2.1.271/273+**: (271) 대화가 compact된 뒤에도 계속 돌고 있던 백그라운드 명령(watch task, dev server)의 **중복 사본**이 새로 시작되던 결함이 수정되었습니다 — 구버전에서 post-compact 중복 프로세스는 지시가 아니라 compaction 아티팩트였습니다(cross-ref #1856: dev-server tmux hook is an advisory). (271) `/resume`·`/teleport`가 이전 대화의 파일-읽음 추적을 그대로 유지해, 재개된 대화가 **한 번도 읽지 않은 파일**을 편집할 수 있던 결함이 수정되었습니다(cross-ref R005 v2.1.228 read-before-write 노트). (271) claude.ai에서 동기화된 스킬이 로그아웃 후에도 디스크에 남아있던 결함이 수정되어, `cleanupPeriodDays` 내 갱신되지 않은 사본은 이제 복구 가능한 휴지통으로 이동합니다. (273) `permissions.blockReadsOutsideWorkingDirectories`: 저장소 settings가 지정한 메모리 디렉토리는 더 이상 프롬프트에 로드·회상·색인·memory extraction에 사용되지 않습니다 — 이 규칙의 `autoMemoryDirectory`와 관련됩니다: 이 설정 하에서는 저장소가 지정한 메모리 디렉토리가 제외됩니다.
553
553
  -->
554
554
 
555
555
  <!-- DETAIL: v2.1.275+ CHANGELOG memory age note/resume malformed block
@@ -15,11 +15,11 @@
15
15
  "hooks": [
16
16
  {
17
17
  "type": "command",
18
- "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.command // \"\") | test(\"(npm run dev|pnpm( run)? dev|yarn dev|bun run dev)\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/bash\ninput=$(cat)\ncmd=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.command // \"\"')\n\n# Block dev servers that aren't run in tmux\necho '[Hook] BLOCKED: Dev server must run in tmux for log access' >&2\necho '[Hook] Use this command instead:' >&2\necho \"[Hook] tmux new-session -d -s dev 'npm run dev'\" >&2\necho '[Hook] Then: tmux attach -t dev' >&2\nexit 1\n )\nelse\n printf '%s' \"$input\"\nfi"
18
+ "command": "input=$(cat)\nif printf '%s' \"$input\" | jq -e '((.tool_input.command // \"\") | test(\"(npm run dev|pnpm( run)? dev|yarn dev|bun run dev)\"))' >/dev/null 2>&1; then\n printf '%s' \"$input\" | (\n#!/bin/sh\ninput=$(cat)\ncmd=$(printf '%s' \"$input\" | jq -r '.tool_input.command // \"\"' 2>/dev/null)\nbg=$(printf '%s' \"$input\" | jq -r '.tool_input.run_in_background // false' 2>/dev/null)\n\n# Advisory only: never blocks (always exit 0). Stay silent for background runs, tmux-wrapped commands,\n# mentions of the dev command in other commands, and variants like dev:test / develop / devtools.\n[ \"$bg\" = \"true\" ] && exit 0\nif printf '%s' \"$cmd\" | grep -Eq '^[[:space:]]*tmux([[:space:]]|$)'; then exit 0; fi\n\n# Drop quoted strings, then split into segments at && || ; | ( ) and newlines\nsegs=$(printf '%s' \"$cmd\" | sed -e 's/\"[^\"]*\"//g' -e \"s/'[^']*'//g\" -e 's/&&/;/g' -e 's/||/;/g' | tr ';|()\\n' '\\n\\n\\n\\n\\n')\n\n# Command position (optionally after VAR=value), word boundary after the dev command, segment not backgrounded with &\nhit=$(printf '%s\\n' \"$segs\" | grep -E '^[[:space:]]*([A-Za-z_][A-Za-z0-9_]*=[^[:space:]]*[[:space:]]+)*(npm run dev|pnpm( run)? dev|yarn dev|bun run dev)([[:space:])]|$)' | grep -Ev '(^|[^>&])&([^&>]|$)' | head -n 1)\n\nif [ -n \"$hit\" ]; then\n printf '%s\\n' '{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"additionalContext\":\"[Hook] 포그라운드 dev 서버 시작이 감지되었습니다. 로그 접근을 위해 run_in_background: true 로 실행하거나 tmux 세션(예: tmux new-session -d -s dev) 안에서 실행하는 것을 권장합니다. 이 알림은 차단하지 않습니다.\"}}'\nfi\nexit 0\n )\nelse\n printf '%s' \"$input\"\nfi"
19
19
  }
20
20
  ],
21
21
  "matcher": "Bash",
22
- "description": "Block dev servers outside tmux - ensures you can access logs"
22
+ "description": "Advise (additionalContext, never blocks) when a foreground dev server starts outside tmux/run_in_background - keeps logs accessible"
23
23
  },
24
24
  {
25
25
  "hooks": [
@@ -45,11 +45,11 @@
45
45
  "hooks": [
46
46
  {
47
47
  "type": "command",
48
- "command": "#!/bin/bash\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\nif [[ \"$file_path\" =~ \\.(md|txt)$ ]] && [[ ! \"$file_path\" =~ (README|CLAUDE|AGENT|SKILL)\\.md$ ]]; then\n echo \"[Hook] BLOCKED: Unnecessary documentation file creation\" >&2\n echo \"[Hook] File: $file_path\" >&2\n echo \"[Hook] Use README.md or AGENT.md for documentation instead\" >&2\n exit 1\nfi\n\nprintf '%s\\n' \"$input\""
48
+ "command": "#!/bin/sh\ninput=$(cat)\nfile_path=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.file_path // \"\"')\n\ncase \"$file_path\" in\n *README.md|*CLAUDE.md|*AGENT.md|*SKILL.md) ;;\n *.md|*.txt)\n echo \"[Hook] NOTICE (non-blocking): new documentation file - the write is not blocked\" >&2\n echo \"[Hook] File: $file_path\" >&2\n echo \"[Hook] Prefer README.md or AGENT.md for documentation if this is not a deliberate new doc\" >&2\n exit 1\n ;;\nesac\n\nprintf '%s\\n' \"$input\""
49
49
  }
50
50
  ],
51
51
  "matcher": "Write",
52
- "description": "Block creation of random .md files - keeps docs consolidated"
52
+ "description": "Non-blocking notice on new .md/.txt files (exit 1) - keeps docs consolidated"
53
53
  },
54
54
  {
55
55
  "hooks": [
@@ -101,6 +101,16 @@
101
101
  "matcher": "Bash",
102
102
  "description": "Block rule file deletion — requires individual user confirmation per rule (R001 safety)"
103
103
  },
104
+ {
105
+ "hooks": [
106
+ {
107
+ "type": "command",
108
+ "command": "bash \"${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/scripts/bash-cd-advisor.sh\""
109
+ }
110
+ ],
111
+ "matcher": "Bash",
112
+ "description": "Advise against top-level (non-subshell) cd in Bash commands; cd persists as session cwd (R005, #1834/#1816 H2)"
113
+ },
104
114
  {
105
115
  "hooks": [
106
116
  {
@@ -272,14 +282,10 @@
272
282
  {
273
283
  "type": "command",
274
284
  "command": "bash \"${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/scripts/r007-r008-drift-advisor.sh\""
275
- },
276
- {
277
- "type": "command",
278
- "command": "bash \"${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/scripts/subagent-failure-advisor.sh\""
279
285
  }
280
286
  ],
281
287
  "matcher": "*",
282
- "description": "Record agent outcomes + auto-continue workflow + R007/R008 drift advisory + failure advisory on subagent completion (autonomous-loop re-entry, #1545; #1631 replaced the self-referential prompt-type judge hook with an advisory-only command hook)"
288
+ "description": "Record agent outcomes + stall and consecutive-completion advisories + R007/R008 drift advisory on subagent completion — advisory-only, never continues or blocks the workflow (autonomous-loop re-entry, #1545; #1631 replaced the self-referential prompt-type judge hook with an advisory-only command hook; #1880)"
283
289
  }
284
290
  ],
285
291
  "CwdChanged": [
@@ -302,8 +308,8 @@
302
308
  "command": "bash \"${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/scripts/file-change-validator.sh\""
303
309
  }
304
310
  ],
305
- "matcher": "*",
306
- "description": "Validate externally modified files — advisory staleness warning (v2.1.83+)"
311
+ "matcher": "CLAUDE.md|bun.lock|yarn.lock|Cargo.lock|poetry.lock|package-lock.json|pnpm-lock.yaml",
312
+ "description": "Warn on external changes to CLAUDE.md and the bun/yarn/Cargo/poetry/npm/pnpm lock files in the working directory — stderr shown to the user only, never blocks; the matcher lists literal filenames because CC registers each |-separated segment as a literal file to watch (v2.1.83+, #1775)"
307
313
  }
308
314
  ],
309
315
  "Notification": [
@@ -383,7 +389,7 @@
383
389
  "hooks": [
384
390
  {
385
391
  "type": "command",
386
- "command": "#!/bin/bash\ninput=$(cat)\ncmd=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.command')\n\nif echo \"$cmd\" | grep -qE 'gh pr create'; then\n output=$(printf '%s\\n' \"$input\" | jq -r '.tool_output.output // \"\"')\n pr_url=$(echo \"$output\" | grep -oE 'https://github.com/[^/]+/[^/]+/pull/[0-9]+')\n \n if [ -n \"$pr_url\" ]; then\n echo \"[Hook] PR created: $pr_url\" >&2\n echo \"[Hook] Checking GitHub Actions status...\" >&2\n repo=$(echo \"$pr_url\" | sed -E 's|https://github.com/([^/]+/[^/]+)/pull/[0-9]+|\\1|')\n pr_num=$(echo \"$pr_url\" | sed -E 's|.*/pull/([0-9]+)|\\1|')\n echo \"[Hook] To review PR: gh pr review $pr_num --repo $repo\" >&2\n fi\nfi\n\nprintf '%s\\n' \"$input\""
392
+ "command": "#!/bin/bash\ninput=$(cat)\ncmd=$(printf '%s\\n' \"$input\" | jq -r '.tool_input.command')\n\nif echo \"$cmd\" | grep -qE 'gh pr create'; then\n output=$(printf '%s\\n' \"$input\" | jq -r '.tool_response.stdout // .tool_output.output // \"\"')\n pr_url=$(echo \"$output\" | grep -oE 'https://github.com/[^/]+/[^/]+/pull/[0-9]+')\n \n if [ -n \"$pr_url\" ]; then\n echo \"[Hook] PR created: $pr_url\" >&2\n echo \"[Hook] Checking GitHub Actions status...\" >&2\n repo=$(echo \"$pr_url\" | sed -E 's|https://github.com/([^/]+/[^/]+)/pull/[0-9]+|\\1|')\n pr_num=$(echo \"$pr_url\" | sed -E 's|.*/pull/([0-9]+)|\\1|')\n echo \"[Hook] To review PR: gh pr review $pr_num --repo $repo\" >&2\n fi\nfi\n\nprintf '%s\\n' \"$input\""
387
393
  }
388
394
  ],
389
395
  "matcher": "Bash",
@@ -631,6 +637,16 @@
631
637
  ],
632
638
  "matcher": "*",
633
639
  "description": "FAIL-axis instrumentation — append tool failures to the error ledger (JSONL). Never blocks; feeds fail-axis-cause-advisor.sh (#1561)"
640
+ },
641
+ {
642
+ "hooks": [
643
+ {
644
+ "type": "command",
645
+ "command": "bash \"${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/scripts/subagent-failure-advisor.sh\""
646
+ }
647
+ ],
648
+ "matcher": "Task|Agent",
649
+ "description": "Advise on failed Agent/Task spawns via additionalContext (e.g. unknown subagent_type). Advisory only (additionalContext); the script's only explicit exit is exit 0 (#1775)"
634
650
  }
635
651
  ]
636
652
  }