@wooojin/forgen 0.3.2 → 0.4.1

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 (124) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +94 -0
  3. package/README.ja.md +119 -8
  4. package/README.ko.md +73 -2
  5. package/README.md +163 -9
  6. package/README.zh.md +87 -7
  7. package/dist/checks/conclusion-verification-ratio.d.ts +37 -0
  8. package/dist/checks/conclusion-verification-ratio.js +86 -0
  9. package/dist/checks/fact-vs-agreement.d.ts +47 -0
  10. package/dist/checks/fact-vs-agreement.js +92 -0
  11. package/dist/checks/self-score-deflation.d.ts +38 -0
  12. package/dist/checks/self-score-deflation.js +108 -0
  13. package/dist/cli.js +158 -6
  14. package/dist/core/auto-compound-runner.js +85 -13
  15. package/dist/core/dashboard.js +9 -2
  16. package/dist/core/doctor.js +90 -15
  17. package/dist/core/extraction-notice.d.ts +18 -0
  18. package/dist/core/extraction-notice.js +64 -0
  19. package/dist/core/init-cli.d.ts +26 -0
  20. package/dist/core/init-cli.js +104 -0
  21. package/dist/core/init.js +17 -0
  22. package/dist/core/inspect-cli.js +64 -5
  23. package/dist/core/migrate-cli.d.ts +10 -0
  24. package/dist/core/migrate-cli.js +34 -0
  25. package/dist/core/paths.d.ts +8 -1
  26. package/dist/core/paths.js +11 -2
  27. package/dist/core/recall-cli.d.ts +26 -0
  28. package/dist/core/recall-cli.js +125 -0
  29. package/dist/core/recall-reference-detector.d.ts +43 -0
  30. package/dist/core/recall-reference-detector.js +65 -0
  31. package/dist/core/state-gc.d.ts +19 -0
  32. package/dist/core/state-gc.js +48 -4
  33. package/dist/core/stats-cli.d.ts +36 -0
  34. package/dist/core/stats-cli.js +254 -0
  35. package/dist/core/uninstall.d.ts +1 -0
  36. package/dist/core/uninstall.js +25 -1
  37. package/dist/core/v1-bootstrap.js +9 -1
  38. package/dist/engine/classify-enforce-cli.d.ts +8 -0
  39. package/dist/engine/classify-enforce-cli.js +61 -0
  40. package/dist/engine/compound-cli.js +1 -0
  41. package/dist/engine/compound-export.js +8 -3
  42. package/dist/engine/enforce-classifier.d.ts +31 -0
  43. package/dist/engine/enforce-classifier.js +123 -0
  44. package/dist/engine/learn-cli.js +1 -4
  45. package/dist/engine/lifecycle/bypass-detector.d.ts +34 -0
  46. package/dist/engine/lifecycle/bypass-detector.js +82 -0
  47. package/dist/engine/lifecycle/lifecycle-cli.d.ts +7 -0
  48. package/dist/engine/lifecycle/lifecycle-cli.js +102 -0
  49. package/dist/engine/lifecycle/meta-cli.d.ts +4 -0
  50. package/dist/engine/lifecycle/meta-cli.js +7 -0
  51. package/dist/engine/lifecycle/meta-reclassifier.d.ts +78 -0
  52. package/dist/engine/lifecycle/meta-reclassifier.js +351 -0
  53. package/dist/engine/lifecycle/orchestrator.d.ts +32 -0
  54. package/dist/engine/lifecycle/orchestrator.js +131 -0
  55. package/dist/engine/lifecycle/signals.d.ts +30 -0
  56. package/dist/engine/lifecycle/signals.js +142 -0
  57. package/dist/engine/lifecycle/trigger-t1-correction.d.ts +23 -0
  58. package/dist/engine/lifecycle/trigger-t1-correction.js +78 -0
  59. package/dist/engine/lifecycle/trigger-t2-violation.d.ts +18 -0
  60. package/dist/engine/lifecycle/trigger-t2-violation.js +42 -0
  61. package/dist/engine/lifecycle/trigger-t3-bypass.d.ts +17 -0
  62. package/dist/engine/lifecycle/trigger-t3-bypass.js +39 -0
  63. package/dist/engine/lifecycle/trigger-t4-decay.d.ts +18 -0
  64. package/dist/engine/lifecycle/trigger-t4-decay.js +40 -0
  65. package/dist/engine/lifecycle/trigger-t5-conflict.d.ts +16 -0
  66. package/dist/engine/lifecycle/trigger-t5-conflict.js +78 -0
  67. package/dist/engine/lifecycle/types.d.ts +52 -0
  68. package/dist/engine/lifecycle/types.js +7 -0
  69. package/dist/engine/meta-learning/session-quality-scorer.d.ts +1 -6
  70. package/dist/engine/meta-learning/session-quality-scorer.js +2 -21
  71. package/dist/engine/rule-toggle-cli.d.ts +13 -0
  72. package/dist/engine/rule-toggle-cli.js +76 -0
  73. package/dist/engine/skill-promoter.js +3 -6
  74. package/dist/forge/evidence-processor.js +10 -2
  75. package/dist/hooks/context-guard.js +72 -1
  76. package/dist/hooks/dangerous-patterns.json +3 -3
  77. package/dist/hooks/db-guard.js +18 -2
  78. package/dist/hooks/intent-classifier.js +1 -1
  79. package/dist/hooks/keyword-detector.js +1 -1
  80. package/dist/hooks/notepad-injector.js +1 -1
  81. package/dist/hooks/permission-handler.js +1 -1
  82. package/dist/hooks/post-tool-failure.js +1 -1
  83. package/dist/hooks/post-tool-use.d.ts +6 -0
  84. package/dist/hooks/post-tool-use.js +94 -14
  85. package/dist/hooks/pre-compact.js +1 -1
  86. package/dist/hooks/pre-tool-use.d.ts +7 -0
  87. package/dist/hooks/pre-tool-use.js +79 -5
  88. package/dist/hooks/rate-limiter.js +1 -1
  89. package/dist/hooks/secret-filter.d.ts +10 -0
  90. package/dist/hooks/secret-filter.js +21 -1
  91. package/dist/hooks/session-recovery.js +1 -1
  92. package/dist/hooks/shared/atomic-write.d.ts +8 -1
  93. package/dist/hooks/shared/atomic-write.js +17 -3
  94. package/dist/hooks/shared/command-parser.d.ts +44 -0
  95. package/dist/hooks/shared/command-parser.js +50 -0
  96. package/dist/hooks/shared/hook-response.d.ts +23 -2
  97. package/dist/hooks/shared/hook-response.js +48 -3
  98. package/dist/hooks/shared/safe-regex.d.ts +25 -0
  99. package/dist/hooks/shared/safe-regex.js +50 -0
  100. package/dist/hooks/shared/stop-triggers.d.ts +19 -0
  101. package/dist/hooks/shared/stop-triggers.js +19 -0
  102. package/dist/hooks/skill-injector.js +1 -1
  103. package/dist/hooks/slop-detector.js +2 -2
  104. package/dist/hooks/solution-injector.d.ts +9 -0
  105. package/dist/hooks/solution-injector.js +48 -5
  106. package/dist/hooks/stop-guard.d.ts +84 -0
  107. package/dist/hooks/stop-guard.js +606 -0
  108. package/dist/hooks/subagent-tracker.js +1 -1
  109. package/dist/i18n/index.js +3 -5
  110. package/dist/mcp/tools.js +19 -2
  111. package/dist/store/evidence-store.d.ts +15 -0
  112. package/dist/store/evidence-store.js +61 -1
  113. package/dist/store/implicit-feedback-store.d.ts +59 -0
  114. package/dist/store/implicit-feedback-store.js +153 -0
  115. package/dist/store/rule-lifecycle.d.ts +23 -0
  116. package/dist/store/rule-lifecycle.js +63 -0
  117. package/dist/store/rule-store.d.ts +21 -0
  118. package/dist/store/rule-store.js +136 -8
  119. package/dist/store/types.d.ts +83 -0
  120. package/dist/store/types.js +7 -1
  121. package/hooks/hook-registry.json +1 -0
  122. package/hooks/hooks.json +6 -1
  123. package/package.json +11 -3
  124. package/plugin.json +1 -1
@@ -14,7 +14,79 @@ export type RuleScope = 'me' | 'session';
14
14
  export type RuleStrength = 'soft' | 'default' | 'strong' | 'hard';
15
15
  export type RuleSource = 'onboarding' | 'explicit_correction' | 'behavior_inference' | 'pack_overlay';
16
16
  export type RuleStatus = 'active' | 'suppressed' | 'removed' | 'superseded';
17
+ export type EnforcementMech = 'A' | 'B' | 'C';
18
+ export type HookPoint = 'PreToolUse' | 'PostToolUse' | 'Stop' | 'UserPromptSubmit';
19
+ export type VerifierKind = 'file_exists' | 'pattern_match' | 'tool_arg_regex' | 'artifact_check' | 'self_check_prompt';
20
+ export interface VerifierSpec {
21
+ kind: VerifierKind;
22
+ /** 각 kind 별로 의미가 다름 — 예: self_check_prompt 는 `question`, artifact_check 는 `path`+`max_age_s`. */
23
+ params: Record<string, string | number | boolean>;
24
+ }
25
+ export interface EnforceSpec {
26
+ mech: EnforcementMech;
27
+ hook: HookPoint;
28
+ /** Mech-A/B 에서 필수, Mech-C 에서는 미사용. */
29
+ verifier?: VerifierSpec;
30
+ /** Mech-A BLOCK / Mech-B self-check 시 Claude 에게 전달할 reason. */
31
+ block_message?: string;
32
+ /** Mech-C drift-score.ts 키 — 정량 판정 불가 규칙의 장기 누적 편향 축. */
33
+ drift_key?: string;
34
+ /**
35
+ * Stop hook 전용: 어시스턴트 응답 텍스트에서 이 규칙을 발화시킬 정규식.
36
+ * 미지정 시 shared default (완료 선언 키워드 regex) 사용.
37
+ */
38
+ trigger_keywords_regex?: string;
39
+ /**
40
+ * Stop hook 전용: trigger 가 매칭되더라도 이 regex 가 매칭되면 발화 안 함.
41
+ * retraction/meta/테스트-맥락 등 false-positive 컨텍스트 차단용.
42
+ */
43
+ trigger_exclude_regex?: string;
44
+ /**
45
+ * UI 표시용 한 줄 태그 (Stop hook 의 `systemMessage` 로 전달).
46
+ * 예: "rule:R-B1 — e2e-before-done"
47
+ */
48
+ system_tag?: string;
49
+ }
50
+ export type LifecyclePhase = 'active' | 'flagged' | 'suppressed' | 'retired' | 'merged' | 'superseded';
51
+ export interface MetaPromotion {
52
+ at: string;
53
+ from_mech: EnforcementMech;
54
+ to_mech: EnforcementMech;
55
+ reason: 'consistent_adherence' | 'repeated_violation' | 'user_override' | 'stuck_loop_force_approve';
56
+ trigger_stats: {
57
+ window_n: number;
58
+ adherence_rate?: number;
59
+ violation_count?: number;
60
+ };
61
+ }
62
+ export interface LifecycleState {
63
+ phase: LifecyclePhase;
64
+ first_active_at: string;
65
+ last_inject_at?: string;
66
+ last_violation_at?: string;
67
+ inject_count: number;
68
+ accept_count: number;
69
+ violation_count: number;
70
+ /** T3: 사용자가 rule 과 반대로 행동한 횟수 */
71
+ bypass_count: number;
72
+ /** T5: 충돌하는 rule_id 목록 */
73
+ conflict_refs: string[];
74
+ /** T5: 이 rule 이 흡수된 대상 rule_id */
75
+ merged_into?: string;
76
+ /** T1: 이 rule 을 교체한 rule_id */
77
+ superseded_by?: string;
78
+ /** Meta: mech 변경 이력 */
79
+ meta_promotions: MetaPromotion[];
80
+ }
81
+ /**
82
+ * Rule JSON schema version. v0.4.0 introduces `enforce_via` + `lifecycle` — 이들을
83
+ * 포함하는 schema 의 공식 버전은 1. 누락된 rule 파일은 pre-v0.4.0 으로 취급 (optional fields
84
+ * 만 비어있을 뿐 로드 가능). 미래 breaking change 시 이 값을 증가시키고 `migrate()` 체인으로 흡수.
85
+ */
86
+ export declare const CURRENT_RULE_SCHEMA_VERSION = 1;
17
87
  export interface Rule {
88
+ /** R5-B3: 미래 breaking schema change 를 위한 version 필드. 없으면 v0 (pre-0.4.0) 으로 취급. */
89
+ schema_version?: number;
18
90
  rule_id: string;
19
91
  category: RuleCategory;
20
92
  scope: RuleScope;
@@ -27,6 +99,17 @@ export interface Rule {
27
99
  render_key: string;
28
100
  created_at: string;
29
101
  updated_at: string;
102
+ /**
103
+ * 이 rule 이 어떤 hook/verifier 로 강제되는가. optional — 기존 rule 은 null.
104
+ * `forgen classify-enforce` 명령이 기존 rule 을 자동 분류하여 채운다.
105
+ * ADR-001 §Data Model.
106
+ */
107
+ enforce_via?: EnforceSpec[];
108
+ /**
109
+ * Lifecycle 상태. optional — 기존 rule 은 load 시 phase='active' 로 auto-initialize.
110
+ * ADR-002 §Data Model.
111
+ */
112
+ lifecycle?: LifecycleState;
30
113
  }
31
114
  export type EvidenceType = 'explicit_correction' | 'behavior_observation' | 'session_summary';
32
115
  export interface Evidence {
@@ -4,4 +4,10 @@
4
4
  * Authoritative source: docs/plans/2026-04-03-forgen-data-model-storage-spec.md
5
5
  * Runtime contracts: docs/plans/2026-04-03-forgen-component-interface-design.md
6
6
  */
7
- export {};
7
+ // ── Rule ────────────────────────────────────────────────────────────────────
8
+ /**
9
+ * Rule JSON schema version. v0.4.0 introduces `enforce_via` + `lifecycle` — 이들을
10
+ * 포함하는 schema 의 공식 버전은 1. 누락된 rule 파일은 pre-v0.4.0 으로 취급 (optional fields
11
+ * 만 비어있을 뿐 로드 가능). 미래 breaking change 시 이 값을 증가시키고 `migrate()` 체인으로 흡수.
12
+ */
13
+ export const CURRENT_RULE_SCHEMA_VERSION = 1;
@@ -5,6 +5,7 @@
5
5
  { "name": "post-tool-use", "tier": "compound-core", "event": "PostToolUse", "matcher": "*", "script": "hooks/post-tool-use.js", "timeout": 3, "compoundCritical": true },
6
6
  { "name": "pre-compact", "tier": "compound-core", "event": "PreCompact", "matcher": "*", "script": "hooks/pre-compact.js", "timeout": 3, "compoundCritical": false },
7
7
  { "name": "context-guard-stop", "tier": "compound-core", "event": "Stop", "matcher": "*", "script": "hooks/context-guard.js", "timeout": 5, "compoundCritical": false },
8
+ { "name": "stop-guard", "tier": "compound-core", "event": "Stop", "matcher": "*", "script": "hooks/stop-guard.js", "timeout": 10, "compoundCritical": true },
8
9
  { "name": "pre-tool-use", "tier": "compound-core", "event": "PreToolUse", "matcher": "*", "script": "hooks/pre-tool-use.js", "timeout": 3, "compoundCritical": true },
9
10
  { "name": "secret-filter", "tier": "safety", "event": "PostToolUse", "matcher": "Write|Edit|Bash", "script": "hooks/secret-filter.js", "timeout": 3, "compoundCritical": false },
10
11
  { "name": "slop-detector", "tier": "safety", "event": "PostToolUse", "matcher": "Write|Edit", "script": "hooks/slop-detector.js", "timeout": 3, "compoundCritical": false },
package/hooks/hooks.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "Forgen harness hooks (auto-generated, 19/19 active)",
2
+ "description": "Forgen harness hooks (auto-generated, 20/20 active)",
3
3
  "hooks": {
4
4
  "UserPromptSubmit": [
5
5
  {
@@ -102,6 +102,11 @@
102
102
  "type": "command",
103
103
  "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/context-guard.js\"",
104
104
  "timeout": 5
105
+ },
106
+ {
107
+ "type": "command",
108
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/dist/hooks/stop-guard.js\"",
109
+ "timeout": 10
105
110
  }
106
111
  ]
107
112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wooojin/forgen",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "preferGlobal": true,
5
5
  "main": "dist/lib.js",
6
6
  "types": "./dist/lib.d.ts",
@@ -30,11 +30,11 @@
30
30
  "postinstall": "node scripts/postinstall.js",
31
31
  "prepare": "npm run build",
32
32
  "prepublishOnly": "npm test",
33
- "prepack": "node scripts/prepack-hooks.cjs"
33
+ "prepack": "npm run build && node scripts/prepack-hooks.cjs"
34
34
  },
35
35
  "author": "jang-ujin",
36
36
  "license": "MIT",
37
- "description": "Code, forged for you — personalized Claude Code harness",
37
+ "description": "When Claude says 'done', forgen makes it prove it turn-level self-verification + personalized rules, at $0 extra API cost.",
38
38
  "keywords": [
39
39
  "claude-code",
40
40
  "forgen",
@@ -86,5 +86,13 @@
86
86
  "@modelcontextprotocol/sdk": "^1.28.0",
87
87
  "js-yaml": "^4.1.1",
88
88
  "zod": "^4.3.6"
89
+ },
90
+ "peerDependencies": {
91
+ "@anthropic-ai/claude-code": ">=2.0.0"
92
+ },
93
+ "peerDependenciesMeta": {
94
+ "@anthropic-ai/claude-code": {
95
+ "optional": true
96
+ }
89
97
  }
90
98
  }
package/plugin.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://claude.ai/schemas/claude-plugin.json",
3
3
  "name": "forgen",
4
- "version": "0.3.2",
4
+ "version": "0.4.1",
5
5
  "description": "Claude Code harness — the more you use Claude, the better it gets",
6
6
  "author": {
7
7
  "name": "jang-ujin",