@wooojin/forgen 0.4.0 → 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 (76) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +30 -0
  3. package/README.ja.md +58 -1
  4. package/README.ko.md +58 -1
  5. package/README.md +83 -15
  6. package/README.zh.md +26 -0
  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 +22 -2
  14. package/dist/core/auto-compound-runner.js +75 -11
  15. package/dist/core/dashboard.js +9 -2
  16. package/dist/core/doctor.js +26 -5
  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 +1 -2
  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/stats-cli.d.ts +21 -0
  32. package/dist/core/stats-cli.js +121 -10
  33. package/dist/core/uninstall.js +2 -1
  34. package/dist/engine/compound-cli.js +1 -0
  35. package/dist/engine/compound-export.js +8 -3
  36. package/dist/engine/learn-cli.js +1 -4
  37. package/dist/engine/lifecycle/lifecycle-cli.js +4 -4
  38. package/dist/engine/lifecycle/meta-reclassifier.js +3 -3
  39. package/dist/engine/lifecycle/orchestrator.js +2 -2
  40. package/dist/engine/lifecycle/signals.js +6 -6
  41. package/dist/engine/meta-learning/session-quality-scorer.d.ts +1 -6
  42. package/dist/engine/meta-learning/session-quality-scorer.js +2 -21
  43. package/dist/engine/skill-promoter.js +3 -6
  44. package/dist/hooks/context-guard.js +1 -1
  45. package/dist/hooks/dangerous-patterns.json +3 -3
  46. package/dist/hooks/db-guard.js +18 -2
  47. package/dist/hooks/intent-classifier.js +1 -1
  48. package/dist/hooks/keyword-detector.js +1 -1
  49. package/dist/hooks/notepad-injector.js +1 -1
  50. package/dist/hooks/permission-handler.js +1 -1
  51. package/dist/hooks/post-tool-failure.js +1 -1
  52. package/dist/hooks/post-tool-use.d.ts +6 -0
  53. package/dist/hooks/post-tool-use.js +37 -19
  54. package/dist/hooks/pre-compact.js +1 -1
  55. package/dist/hooks/pre-tool-use.d.ts +7 -0
  56. package/dist/hooks/pre-tool-use.js +24 -6
  57. package/dist/hooks/rate-limiter.js +1 -1
  58. package/dist/hooks/secret-filter.js +1 -1
  59. package/dist/hooks/session-recovery.js +1 -1
  60. package/dist/hooks/shared/command-parser.d.ts +44 -0
  61. package/dist/hooks/shared/command-parser.js +50 -0
  62. package/dist/hooks/shared/hook-response.d.ts +12 -2
  63. package/dist/hooks/shared/hook-response.js +30 -3
  64. package/dist/hooks/skill-injector.js +1 -1
  65. package/dist/hooks/slop-detector.js +2 -2
  66. package/dist/hooks/solution-injector.d.ts +9 -0
  67. package/dist/hooks/solution-injector.js +48 -5
  68. package/dist/hooks/stop-guard.js +137 -13
  69. package/dist/hooks/subagent-tracker.js +1 -1
  70. package/dist/i18n/index.js +3 -5
  71. package/dist/store/evidence-store.js +11 -0
  72. package/dist/store/implicit-feedback-store.d.ts +59 -0
  73. package/dist/store/implicit-feedback-store.js +153 -0
  74. package/dist/store/rule-store.js +8 -0
  75. package/package.json +2 -2
  76. package/plugin.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://claude.ai/schemas/claude-plugin.json",
3
3
  "name": "forgen",
4
- "version": "0.4.0",
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",
package/CHANGELOG.md CHANGED
@@ -5,6 +5,36 @@ All notable changes to forgen will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.1] - 2026-04-24
9
+
10
+ ### v0.4.1 — 하네스가 당신을 담고 간다
11
+
12
+ v0.4.0 이 Trust Layer (Claude 가 "완료"라고 하면 forgen 이 증명하게 한다) 를 세웠다면, v0.4.1 은 **구매자가 첫 block 을 즉시 경험**하고 **README 만 봐도 "하네스가 당신을 담고 간다" 는 비전을 이해**하게 만드는 릴리스. 내부적으로는 직전 회차에서 scope-out 했던 측정 갭 3건을 정직하게 재평가 → 실제로 닫았고, 10 시나리오 실 Claude signal 누적으로 검증.
13
+
14
+ **3개 구조적 갭 마감** (`feat`)
15
+ - `recall_referenced` 측정: name literal 단일 매칭 → identifier / 복합 태그 2개 교차 fallback 추가. Claude 가 slug 이름 대신 solution content 만 인용해도 잡힘. 일반 단어 단독은 false-positive 방지 위해 제외.
16
+ - `Rule.lifecycle` 자동 초기화: `saveRule` 이 lifecycle 없으면 `phase='active'` + counters=0 주입. suppressed rule 의 audit trail (누가 언제 왜) 추적 가능.
17
+ - `forgen compound list` 출력: `inj: / ref: / neg:` 컬럼에 "ref 측정은 v0.4.1+ 부터 시작됨" 주석. legacy 데이터 `ref:0` 을 "도움 안 됨" 으로 오독하는 혼란 해소.
18
+
19
+ **README 리프레시** (`docs`)
20
+ - **The harness carries you 섹션 신설**: "대화 → 추출 → 주입 → 반복" cycle + `forgen compound export/import` (개인 철학 번들을 tar.gz 로 이식) 연결. forgen 을 "rule 주입 tool" 로 축소 해석하는 오독 해소.
21
+ - 한국어/일본어/중국어 README 동기화 ("하네스가 당신을 담고 간다" / "ハーネスがあなたを運ぶ" / "这个 harness 装载的是你").
22
+ - **The first block 데모 일반화**: forgen-repo 전용 L1 rule → v0.4.1 내장 `builtin:self-score-inflation` (TEST-2) 기반 일반 시나리오로 교체. 구매자가 rule 작성 없이도 첫 block 을 바로 체감.
23
+ - Commands 섹션에 `forgen recall` / `forgen migrate` / `forgen init` 추가.
24
+ - Cold-start boost 설명: champion/active 솔루션 < 5 이면 `MIN_INJECT_RELEVANCE` 0.3 → 0.2 완화.
25
+
26
+ **natural-accumulation e2e** (`test`)
27
+ - 격리 `FORGEN_HOME` + 실 Claude API 10 시나리오로 "시간이 답" 이던 open signal 4종을 수십 분 내 실증:
28
+ - `recall_referenced` 0 → 2 (33% 참조율)
29
+ - `recommendation_surfaced` 1 → 6 (60% 주입률, cold-start boost 실효 확인)
30
+ - TEST-2 자연 block 0 → 3
31
+ - TEST-3 자연 block 0 → 2
32
+ - hook-errors 0 (전 경로 clean)
33
+
34
+ **회귀**: vitest 2114/2114 (신규 테스트 4건 포함). typecheck 0.
35
+
36
+ ---
37
+
8
38
  ## [0.4.0] - 2026-04-23
9
39
 
10
40
  ### v0.4.0 — The Trust Layer
package/README.ja.md CHANGED
@@ -15,6 +15,7 @@
15
15
 
16
16
  <p align="center">
17
17
  <a href="#最初のブロック-30秒">最初のブロック</a> &middot;
18
+ <a href="#ハーネスがあなたを運ぶ">ビジョン</a> &middot;
18
19
  <a href="#クイックスタート">クイックスタート</a> &middot;
19
20
  <a href="#仕組み">仕組み</a> &middot;
20
21
  <a href="#4軸パーソナライゼーション">4軸</a> &middot;
@@ -74,6 +75,31 @@ asciinema play docs/demo/mech-b-block-unblock.cast
74
75
 
75
76
  上記の Trust Layer は柱の1つです。もう1つはパーソナライゼーション — 最初のブロック後に forgen を使い続ける理由です。
76
77
 
78
+ ---
79
+
80
+ ## ハーネスがあなたを運ぶ
81
+
82
+ パーソナライゼーションは表面です。より深いアイデア: **すべてのセッションが痕跡を残し、その痕跡が蓄積されてあなたのように判断するハーネスになります。** 修正、規約、トレードオフの好み — 会話から抽出され、`~/.forgen/me/` に保存され、次のセッションで Claude に再注入されます。
83
+
84
+ ```
85
+ 会話 ──► 抽出: solution / rule / behavior / profile 更新
86
+ ────────────────────────────────────────────
87
+
88
+
89
+ 次のセッション ◄── 注入: UserPromptSubmit コンテキスト + レンダリングされた
90
+ ルール + あなたの基準に合わせた Stop-hook ガード
91
+ ```
92
+
93
+ 数週間経つと、このハーネスは「ルールを強制するツール」ではなく、**あなたが仕事を判断する方法が詰まった持ち運べるバンドル** になります。一行で export:
94
+
95
+ ```bash
96
+ forgen compound export # → forgen-knowledge-YYYY-MM-DD.tar.gz
97
+ # (rules + solutions + behavior — あなたの哲学)
98
+ forgen compound import <path> # 別のマシンで再現
99
+ ```
100
+
101
+ これが北極星: *ノートパソコン上で、あなたのように判断する Claude と、持ち運べる tarball.*
102
+
77
103
  開発者 A は慎重派です。Claude にすべてのテストを実行させ、理由を説明させ、現在のファイル以外を変更する前に必ず確認を求めます。
78
104
 
79
105
  開発者 B はスピード重視です。Claude に前提を置いて判断させ、関連ファイルも直接修正させ、結果を2行で報告させます。
@@ -171,7 +197,38 @@ forgen
171
197
  - **Node.js** >= 20(SQLite セッション検索には >= 22 を推奨)
172
198
  - **Claude Code** インストール・認証済み(`npm i -g @anthropic-ai/claude-code`)
173
199
 
174
- > **ベンダー依存:** forgen は Claude Code をラップします。Anthropic API または Claude Code の変更が動作に影響する可能性があります。Claude Code 1.0.x でテスト済みです。
200
+ > **ベンダー依存:** forgen は Claude Code をラップします。Anthropic API または Claude Code の変更が動作に影響する可能性があります。Claude Code 1.0.x / 2.1.x でテスト済み。
201
+
202
+ ### 隔離 / CI / Docker での利用
203
+
204
+ forgen のホームはデフォルト `~/.forgen` ですが、プロセス毎に上書き可能:
205
+
206
+ ```bash
207
+ # クリーンな隔離ホーム — 実 ~/.forgen は触らない
208
+ FORGEN_HOME=/tmp/forgen-clean forgen init # starter-pack 15件を自動配置
209
+ FORGEN_HOME=/tmp/forgen-clean forgen stats # 隔離ホームの統計のみ表示
210
+ FORGEN_HOME=/tmp/forgen-clean claude -p "…" # フックが env を継承 → ログ隔離
211
+ ```
212
+
213
+ Claude Code のフックプロセスは親 env を継承するため、`FORGEN_HOME=...` プレ
214
+ フィックス一つで全状態 (rules/solutions/behavior/enforcement) がそのディレ
215
+ クトリに隔離されます。用途:
216
+
217
+ - CI パイプラインで固定シードに対する forgen 検証
218
+ - 実ホーム汚染なしの「新規ユーザー初日体験」再現
219
+ - 1 台のマシンで複数ペルソナ運用
220
+
221
+ **Docker / リモートサーバー (OAuth 制約):** Claude Code は OAuth セッションを
222
+ **OS キーチェーン** (macOS Keychain / libsecret / Windows Credential Manager)
223
+ に保存するため、新規 Linux コンテナで `~/.claude.json` のみマウントしても
224
+ refresh トークンが無く認証できません。コンテナ環境では `ANTHROPIC_API_KEY`
225
+ env を使ってください。ホスト環境 (macOS/Linux ワークステーション) は通常の
226
+ `claude login` フローで動作 — API キー不要。
227
+
228
+ ### マイグレーション
229
+
230
+ `forgen migrate implicit-feedback` — pre-v0.4.1 ログの `category` フィールド
231
+ バックフィル。冪等 (idempotent) — 複数回実行しても安全。
175
232
 
176
233
  ---
177
234
 
package/README.ko.md CHANGED
@@ -14,6 +14,7 @@
14
14
  </p>
15
15
 
16
16
  <p align="center">
17
+ <a href="#하네스가-당신을-담고-간다">비전</a> &middot;
17
18
  <a href="#forgen를-쓰면-일어나는-일">동작 흐름</a> &middot;
18
19
  <a href="#빠른-시작">빠른 시작</a> &middot;
19
20
  <a href="#동작-방식">동작 방식</a> &middot;
@@ -52,6 +53,31 @@ forgen가 이것을 가능하게 합니다. 작업 스타일을 프로파일링
52
53
 
53
54
  ---
54
55
 
56
+ ## 하네스가 당신을 담고 간다
57
+
58
+ 개인화는 표면입니다. 더 깊은 아이디어: **매 세션이 흔적을 남기고, 그 흔적들이 쌓여 당신처럼 판단하는 하네스가 됩니다.** 교정, 컨벤션, 트레이드오프 선호 — 대화에서 추출되어 `~/.forgen/me/` 에 저장되고, 다음 세션마다 Claude 에 다시 주입됩니다.
59
+
60
+ ```
61
+ 대화 ──► 추출: solution / rule / behavior / profile 업데이트
62
+ ──────────────────────────────────────────────
63
+
64
+
65
+ 다음 세션 ◄── 주입: UserPromptSubmit 컨텍스트 + 렌더된 규칙
66
+ + 당신의 기준에 맞춘 Stop-hook 가드
67
+ ```
68
+
69
+ 몇 주가 지나면 이 하네스는 "규칙을 강제하는 도구"가 아니라 **당신이 일을 판단하는 방식이 담긴 휴대 가능한 번들** 이 됩니다. 한 줄로 export:
70
+
71
+ ```bash
72
+ forgen compound export # → forgen-knowledge-YYYY-MM-DD.tar.gz
73
+ # (rules + solutions + behavior — 당신의 철학)
74
+ forgen compound import <path> # 다른 머신에서 그대로 재연
75
+ ```
76
+
77
+ 그게 북극성입니다: *노트북 위에 있는, 당신처럼 판단하는 Claude, 그리고 들고 다닐 수 있는 tarball.*
78
+
79
+ ---
80
+
55
81
  ## forgen를 쓰면 일어나는 일
56
82
 
57
83
  ### 첫 실행 (1회, 약 1분)
@@ -131,7 +157,38 @@ forgen
131
157
  - **Node.js** >= 20 (SQLite 세션 검색은 >= 22 권장)
132
158
  - **Claude Code** 설치 및 인증 (`npm i -g @anthropic-ai/claude-code`)
133
159
 
134
- > **벤더 의존성:** forgen은 Claude Code를 래핑합니다. Anthropic API 또는 Claude Code 변경이 동작에 영향을 줄 수 있습니다. Claude Code 1.0.x 기준으로 테스트되었습니다.
160
+ > **벤더 의존성:** forgen은 Claude Code를 래핑합니다. Anthropic API 또는 Claude Code 변경이 동작에 영향을 줄 수 있습니다. Claude Code 1.0.x / 2.1.x 에서 테스트됨.
161
+
162
+ ### 격리 / CI / Docker 사용
163
+
164
+ forgen 홈은 기본 `~/.forgen` 이지만 프로세스별 override 가능:
165
+
166
+ ```bash
167
+ # 깨끗한 격리 홈 — 실제 ~/.forgen 은 건드리지 않음
168
+ FORGEN_HOME=/tmp/forgen-clean forgen init # starter-pack 15개 자동 배포
169
+ FORGEN_HOME=/tmp/forgen-clean forgen stats # 격리 홈의 통계만 표시
170
+ FORGEN_HOME=/tmp/forgen-clean claude -p "…" # 훅이 env 상속 → 격리된 로그
171
+ ```
172
+
173
+ Claude Code 훅 프로세스가 부모 env 를 상속하므로 `FORGEN_HOME=...` 프리픽스
174
+ 하나면 모든 상태(rules/solutions/behavior/enforcement)가 해당 디렉터리로 격리.
175
+ 쓰임새:
176
+
177
+ - CI 파이프라인에서 고정 시드로 forgen 검증
178
+ - 실 홈 오염 없이 "신규 사용자 첫날 경험" 재현
179
+ - 한 머신에서 여러 페르소나 운영
180
+
181
+ **Docker / 원격 서버 (OAuth 제약):** Claude Code 는 OAuth 세션을 **OS 키체인**
182
+ (macOS Keychain / libsecret / Windows Credential Manager) 에 저장하므로, 새
183
+ Linux 컨테이너에서 `~/.claude.json` 만 마운트하면 refresh 토큰이 없어서 인증이
184
+ 안 됩니다. 컨테이너 환경에서는 `ANTHROPIC_API_KEY` env 를 사용하세요. 호스트
185
+ 기반 사용(macOS/Linux 워크스테이션) 은 `claude login` 흐름 그대로 동작 — API
186
+ 키 불필요.
187
+
188
+ ### 마이그레이션
189
+
190
+ `forgen migrate implicit-feedback` — pre-v0.4.1 로그의 `category` 필드 백필.
191
+ 멱등(idempotent) — 여러 번 실행 안전.
135
192
 
136
193
  ---
137
194
 
package/README.md CHANGED
@@ -18,6 +18,7 @@
18
18
  <a href="#quick-start">Quick Start</a> &middot;
19
19
  <a href="#how-it-works">How It Works</a> &middot;
20
20
  <a href="#4-axis-personalization">4-Axis</a> &middot;
21
+ <a href="#the-harness-carries-you">Harness Vision</a> &middot;
21
22
  <a href="#commands">Commands</a> &middot;
22
23
  <a href="#architecture">Architecture</a> &middot;
23
24
  <a href="#safety">Safety</a>
@@ -37,24 +38,26 @@
37
38
  You've been burned: Claude says "tests pass, implementation done" — you run it — it doesn't work. forgen closes that gap.
38
39
 
39
40
  ```
40
- You: "Implement the login handler."
41
- Claude: ...makes edits...
42
- Claude: "구현 완료했습니다."
41
+ You: "Update the auth middleware."
42
+ Claude: ...makes edits to src/middleware/auth.ts...
43
+ Claude: "구현 완료. 신뢰도 95/100."
43
44
 
44
- [forgen:stop-guard/L1-e2e-before-done]
45
- Docker e2e 증거(~/.forgen/state/e2e-result.json, 1시간 이내)가 없습니다.
46
- 지금 실행 재응답하라.
45
+ [forgen:stop-guard/builtin:self-score-inflation]
46
+ 자가 점수 상승 선언 1건 (95/100). 측정 도구 호출 0회 — 숫자를 뒷받침할
47
+ 실행/확인 증거 없음. 테스트/빌드/curl 실행 결과를 턴에 포함해 재응답.
47
48
 
48
- Claude: "완료 선언을 취소합니다. 증거 파일이 없습니다. e2e 를 먼저 실행합니다..."
49
- ...runs bash tests/e2e/docker/run-test.sh...
50
- "63/63 pass. 구현 완료했습니다."
49
+ Claude: "측정 없이 점수를 매겼습니다. 테스트부터 실행합니다..."
50
+ $ npm test
51
+ "31 passed / 0 failed. auth middleware 구현 완료."
51
52
 
52
53
  [forgen] ✓ approved
53
54
  ```
54
55
 
55
- **What just happened**: Claude's Stop hook was blocked by a rule you defined (`L1-e2e-before-done`). Claude read the block `reason`, retracted its premature claim, produced evidence, and re-submitted. **Zero extra API calls** — it all happened in the same session turn Claude was going to produce anyway.
56
+ **What just happened**: Claude's Stop hook detected a score claim (`95/100`) without any measurement tool call (`Bash` / `NotebookEdit`) in the turn — one of forgen's **three built-in meta guards** (TEST-1 fact vs agreement, **TEST-2 self-score inflation**, TEST-3 conclusion/verification ratio). Claude read the block `reason`, retracted, ran the real test, and re-submitted. **Zero extra API calls** — it all happened in the same session turn Claude was going to produce anyway.
56
57
 
57
- This is **Mech-B self-check prompt-inject**. It works because Claude Code's Stop hook accepts `decision: "block"` + `reason`, and Claude in the next turn reads that reason as input. We verified it end-to-end on 10 scenarios at $1.74 total cost ([A1 spike report](docs/spike/mech-b-a1-verification-report.md)).
58
+ The same mechanism also fires when Claude writes conclusions faster than evidence ("done. passed. shipped. verified." with no measurement context), or claims facts ("테스트가 통과합니다") without ever having executed them. You can also define **custom rules** (e.g. "require npm test evidence before saying 'done' in this repo") via `forgen compound --rule` — they slot into the same Stop-hook dispatcher.
59
+
60
+ This is **Mech-B self-check prompt-inject**. It works because Claude Code's Stop hook accepts `decision: "block"` + `reason`, and Claude in the next turn reads that reason as input. We verified it end-to-end on 10 scenarios at $1.74 total cost ([A1 spike report](docs/spike/mech-b-a1-verification-report.md)), and v0.4.1 added built-in guards so you get the first block **without writing any rule**.
58
61
 
59
62
  🎬 **See it happen** (27 seconds):
60
63
 
@@ -92,6 +95,31 @@ Forgen profiles your work style, learns from your corrections, and renders perso
92
95
 
93
96
  ---
94
97
 
98
+ ## The harness carries you
99
+
100
+ Personalization is the surface. The deeper idea: **every session leaves a trace, and those traces compound into a harness that reasons like you do.** Your corrections, your conventions, your trade-off preferences — extracted from conversation, stored under `~/.forgen/me/`, and replayed back to Claude on every future session.
101
+
102
+ ```
103
+ Conversation ──► Extracted: solution / rule / behavior / profile update
104
+ ─────────────────────────────────────────────────────
105
+
106
+
107
+ Next session ◄── Injected: UserPromptSubmit context + rendered rules
108
+ + Stop-hook guards calibrated to *your* standards
109
+ ```
110
+
111
+ After a few weeks this harness stops being "a tool that enforces rules" and starts being **a portable bundle of how you judge work**. One command exports it:
112
+
113
+ ```bash
114
+ forgen compound export # → forgen-knowledge-YYYY-MM-DD.tar.gz
115
+ # (rules + solutions + behavior — your philosophy)
116
+ forgen compound import <path> # replay it on another machine
117
+ ```
118
+
119
+ That's the north star: *a Claude on your laptop that judges like you do, and a tarball you can carry.*
120
+
121
+ ---
122
+
95
123
  ## What happens when you use forgen
96
124
 
97
125
  ### First run (one time, ~1 minute)
@@ -171,7 +199,39 @@ forgen
171
199
  - **Node.js** >= 20 (>= 22 recommended for SQLite session search)
172
200
  - **Claude Code** installed and authenticated (`npm i -g @anthropic-ai/claude-code`)
173
201
 
174
- > **Vendor dependency:** Forgen wraps Claude Code. Anthropic API or Claude Code changes may affect behavior. Tested with Claude Code 1.0.x.
202
+ > **Vendor dependency:** Forgen wraps Claude Code. Anthropic API or Claude Code changes may affect behavior. Tested with Claude Code 1.0.x / 2.1.x.
203
+
204
+ ### Isolated / CI / Docker usage
205
+
206
+ Forgen's home directory is `~/.forgen` by default, but can be overridden per-process:
207
+
208
+ ```bash
209
+ # Fresh isolated home — does NOT touch your real ~/.forgen
210
+ FORGEN_HOME=/tmp/forgen-clean forgen init # provisions 15-solution starter pack
211
+ FORGEN_HOME=/tmp/forgen-clean forgen stats # shows stats from the isolated home
212
+ FORGEN_HOME=/tmp/forgen-clean claude -p "..." # hooks inherit the env → isolated logs
213
+ ```
214
+
215
+ Claude Code hook processes inherit the parent env, so any `claude` command
216
+ prefixed with `FORGEN_HOME=...` routes all state (rules, solutions, behavior,
217
+ enforcement logs) into that directory. Useful for:
218
+
219
+ - CI pipelines validating forgen against a pinned seed set
220
+ - Reproducing buyer-first-day experience without polluting your real home
221
+ - Running multiple personas on one machine
222
+
223
+ **Docker / remote servers (OAuth limitation):** Claude Code stores its OAuth
224
+ session in the **OS keychain** (macOS Keychain / libsecret / Windows Credential
225
+ Manager). Mounting `~/.claude.json` alone is **not enough** in a fresh Linux
226
+ container because the keychain-bound refresh is missing. For container use, set
227
+ `ANTHROPIC_API_KEY` in the container env instead. Host-native usage (macOS,
228
+ Linux workstations) works with the normal `claude login` flow — no API key
229
+ needed.
230
+
231
+ ### Migrations
232
+
233
+ `forgen migrate implicit-feedback` backfills the `category` field on pre-v0.4.1
234
+ entries in `~/.forgen/state/implicit-feedback.jsonl`. Idempotent — safe to re-run.
175
235
 
176
236
  ---
177
237
 
@@ -283,7 +343,11 @@ Claude has your accumulated patterns in context while drafting the response.
283
343
 
284
344
  Precision gates (v0.3.2+): matches below relevance 0.3 or with only a single
285
345
  common-word tag overlap are filtered before injection so Claude's context
286
- doesn't get polluted by low-signal hits.
346
+ doesn't get polluted by low-signal hits. **Cold-start boost (v0.4.1+)**: when
347
+ your outcome history has < 5 champion/active solutions (first days after
348
+ install), the injection threshold is relaxed to 0.2 so starter-pack solutions
349
+ can actually surface; once your own patterns accumulate the threshold returns
350
+ to the standard 0.3.
287
351
 
288
352
  ### 10 built-in skills
289
353
 
@@ -491,7 +555,9 @@ forgen forge --export # Export profile
491
555
  ### Inspection
492
556
 
493
557
  ```bash
494
- forgen stats # One-screen trust-layer dashboard (rules, corrections, blocks 7d)
558
+ forgen stats # Trust-layer dashboard (rules, corrections, blocks 7d, assist today, philosophy)
559
+ forgen recall [--limit N] [--show]
560
+ # Recent compound recalls surfaced to Claude (with body preview)
495
561
  forgen last-block # Most recent block event with rule detail
496
562
  forgen inspect profile # 4-axis profile with packs and facets
497
563
  forgen inspect rules # Active and suppressed rules
@@ -530,7 +596,9 @@ forgen skill list # List promoted skills
530
596
  ### System
531
597
 
532
598
  ```bash
533
- forgen init # Initialize project
599
+ forgen init # Initialize project (+ 15 starter-pack solutions)
600
+ forgen migrate [implicit-feedback|all]
601
+ # One-shot schema migrations (idempotent)
534
602
  forgen doctor # System diagnostics (10 categories + harness maturity)
535
603
  forgen doctor --prune-state # Daily hygiene: state GC + T4 rule decay (90d idle → retire)
536
604
  forgen dashboard # Knowledge overview (6 sections)
package/README.zh.md CHANGED
@@ -18,6 +18,7 @@
18
18
  <a href="#快速开始">快速开始</a> &middot;
19
19
  <a href="#工作原理">工作原理</a> &middot;
20
20
  <a href="#4轴个性化">4轴</a> &middot;
21
+ <a href="#这个-harness-装载的是你">愿景</a> &middot;
21
22
  <a href="#命令">命令</a> &middot;
22
23
  <a href="#架构">架构</a> &middot;
23
24
  <a href="#安全">安全</a>
@@ -92,6 +93,31 @@ forgen 实现了这一切。它对你的工作风格进行画像、从你的纠
92
93
 
93
94
  ---
94
95
 
96
+ ## 这个 harness 装载的是你
97
+
98
+ 个性化只是表面。更深层的想法:**每次会话都留下痕迹,这些痕迹累积起来成为一个像你一样判断的 harness。** 你的修正、你的规范、你的权衡偏好 — 从对话中提取,存储在 `~/.forgen/me/` 下,并在每次后续会话中回放给 Claude。
99
+
100
+ ```
101
+ 对话 ──► 提取: solution / rule / behavior / profile 更新
102
+ ────────────────────────────────────────────
103
+
104
+
105
+ 下一次会话 ◄── 注入: UserPromptSubmit 上下文 + 渲染的规则
106
+ + 校准到你标准的 Stop-hook 守卫
107
+ ```
108
+
109
+ 几周之后,这个 harness 不再是"强制执行规则的工具",而是 **承载你如何判断工作的可携带包裹**。一条命令导出:
110
+
111
+ ```bash
112
+ forgen compound export # → forgen-knowledge-YYYY-MM-DD.tar.gz
113
+ # (rules + solutions + behavior — 你的哲学)
114
+ forgen compound import <path> # 在另一台机器上重放
115
+ ```
116
+
117
+ 这就是北极星:*你的笔记本上,一个像你一样判断的 Claude,还有你能随身携带的 tarball。*
118
+
119
+ ---
120
+
95
121
  ## 使用 forgen 会发生什么
96
122
 
97
123
  ### 首次运行(仅一次,约1分钟)
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Forgen v0.4.1 — TEST-3: 결론 vs 검증 비율 가드
3
+ *
4
+ * Claude 응답 텍스트에서 **결론 키워드** 와 **검증 키워드** 빈도 비율을 측정.
5
+ * 결론 / 검증 > 3 이면 "결론을 쏟아내지만 검증이 부족한" 합의-기반 완료 선언
6
+ * 패턴 — stop-guard 에서 block.
7
+ *
8
+ * 배경 (RC3): v0.4.0 self-interview 에서 "통과했다 / 완료됐다" 같은 결론이
9
+ * 한 응답에 5~8회 반복되지만 "테스트 실행했나 / 증거가 뭔가" 관련 표현은
10
+ * 0회인 케이스 반복 관찰. TEST-1 이 "측정 도구 호출 0건" 을 봤다면, TEST-3
11
+ * 은 같은 문제를 **텍스트-내부** 비율로 잡는다 (도구 호출이 있어도 서술이
12
+ * 결론-편향이면 감지).
13
+ *
14
+ * 순수 함수 — Stop hook 이 `block_message` 로 주입할 수 있도록 reason 문자열을
15
+ * 직접 반환.
16
+ */
17
+ export interface RatioCheckInput {
18
+ text: string;
19
+ /** 비율 임계값. 기본 3 (결론이 검증의 3배 넘으면 block). */
20
+ threshold?: number;
21
+ /**
22
+ * 결론/검증 둘 다 합쳐 이 개수 미만이면 판정 보류 (sparse text).
23
+ * 기본 4 — 짧은 1-2줄 응답에 오탐 방지.
24
+ */
25
+ minTotal?: number;
26
+ }
27
+ export interface RatioCheckResult {
28
+ /** true = 결론 편향 감지 — block 후보. */
29
+ block: boolean;
30
+ conclusionCount: number;
31
+ verificationCount: number;
32
+ /** 검증이 0이면 Infinity, 아니면 결론/검증. */
33
+ ratio: number;
34
+ /** block 시 stop-guard block_message 로 주입할 사람-읽기 문장. */
35
+ reason: string;
36
+ }
37
+ export declare function checkConclusionVerificationRatio(input: RatioCheckInput): RatioCheckResult;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Forgen v0.4.1 — TEST-3: 결론 vs 검증 비율 가드
3
+ *
4
+ * Claude 응답 텍스트에서 **결론 키워드** 와 **검증 키워드** 빈도 비율을 측정.
5
+ * 결론 / 검증 > 3 이면 "결론을 쏟아내지만 검증이 부족한" 합의-기반 완료 선언
6
+ * 패턴 — stop-guard 에서 block.
7
+ *
8
+ * 배경 (RC3): v0.4.0 self-interview 에서 "통과했다 / 완료됐다" 같은 결론이
9
+ * 한 응답에 5~8회 반복되지만 "테스트 실행했나 / 증거가 뭔가" 관련 표현은
10
+ * 0회인 케이스 반복 관찰. TEST-1 이 "측정 도구 호출 0건" 을 봤다면, TEST-3
11
+ * 은 같은 문제를 **텍스트-내부** 비율로 잡는다 (도구 호출이 있어도 서술이
12
+ * 결론-편향이면 감지).
13
+ *
14
+ * 순수 함수 — Stop hook 이 `block_message` 로 주입할 수 있도록 reason 문자열을
15
+ * 직접 반환.
16
+ */
17
+ /** 결론 키워드 — 상태를 단정적으로 선언하는 어휘. */
18
+ const CONCLUSION_PATTERNS = [
19
+ /\b(pass(es|ed)?|passing)\b/gi,
20
+ /\b(done|ready|shipped|finished|complete)\b/gi,
21
+ /\bLGTM\b/g,
22
+ /\bconfirmed\b/gi,
23
+ /\bverified\b/gi,
24
+ /\bvalidated\b/gi,
25
+ /(통과(했|됐|함|합니다))/g,
26
+ /(완료(했|됐|됨|됐습니다))/g,
27
+ /(성공(했|했습니다|적))/g,
28
+ /(동작(합니다|함|한다))/g,
29
+ ];
30
+ /** 검증 키워드 — 측정/확인/실행 행위를 서술하는 어휘. */
31
+ const VERIFICATION_PATTERNS = [
32
+ /\b(test(s|ed|ing)?|tested)\b/gi,
33
+ /\b(verify|verifying|verification)\b/gi,
34
+ /\b(check(ed|ing)?)\b/gi,
35
+ /\b(run|ran|running)\b/gi,
36
+ /\b(measure(d|ment)?)\b/gi,
37
+ /\bevidence\b/gi,
38
+ /증거/g,
39
+ /테스트/g,
40
+ /확인/g,
41
+ /검증/g,
42
+ /실행/g,
43
+ /측정/g,
44
+ ];
45
+ function countMatches(text, patterns) {
46
+ let n = 0;
47
+ for (const p of patterns) {
48
+ const m = text.match(p);
49
+ if (m)
50
+ n += m.length;
51
+ }
52
+ return n;
53
+ }
54
+ export function checkConclusionVerificationRatio(input) {
55
+ const threshold = input.threshold ?? 3;
56
+ const minTotal = input.minTotal ?? 4;
57
+ const conclusionCount = countMatches(input.text, CONCLUSION_PATTERNS);
58
+ const verificationCount = countMatches(input.text, VERIFICATION_PATTERNS);
59
+ const total = conclusionCount + verificationCount;
60
+ const ratio = verificationCount === 0
61
+ ? (conclusionCount === 0 ? 0 : Infinity)
62
+ : conclusionCount / verificationCount;
63
+ // sparse text → 판정 보류
64
+ if (total < minTotal) {
65
+ return {
66
+ block: false,
67
+ conclusionCount,
68
+ verificationCount,
69
+ ratio,
70
+ reason: '',
71
+ };
72
+ }
73
+ // 결론이 전혀 없으면 비율 자체가 의미 없음
74
+ if (conclusionCount === 0) {
75
+ return { block: false, conclusionCount, verificationCount, ratio, reason: '' };
76
+ }
77
+ const block = ratio > threshold;
78
+ let reason = '';
79
+ if (block) {
80
+ reason =
81
+ verificationCount === 0
82
+ ? `결론 ${conclusionCount}건 vs 검증 0건. 완료 선언 전에 실제 실행/측정 증거 (npm test, curl, Read 결과 등) 를 턴에 포함시켜 재응답.`
83
+ : `결론/검증 비율 ${ratio.toFixed(1)} (${conclusionCount}/${verificationCount}) > ${threshold}. 결론에 비해 검증 서술이 적음 — 증거(실행 결과/측정값) 를 추가하여 재응답.`;
84
+ }
85
+ return { block, conclusionCount, verificationCount, ratio, reason };
86
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Forgen v0.4.1 — TEST-1: 사실 vs 합의 가드
3
+ *
4
+ * 목적: Claude 가 "동작합니다 / 통과했습니다 / 검증됐습니다" 같은 **사실 주장**을
5
+ * 내놓을 때, 그 턴(또는 최근 N턴)에 실제 측정/검증을 수행한 도구 호출이 있었는가?
6
+ * 측정 없이 합의(agreement)만으로 사실로 변환된다면 alert.
7
+ *
8
+ * 배경 (RC1): v0.4.0 릴리즈 직전 self-assessment 에서 점수가 조금씩 올라가는데
9
+ * 측정 도구 호출은 0건인 케이스가 반복. 메타 점수 인플레이션 (TEST-2 / US-13)
10
+ * 의 직전 단계. 여기서는 alert 레벨까지만 — block 은 TEST-2 에서.
11
+ *
12
+ * 순수 함수 설계: I/O 없이 텍스트 + 측정 신호 메타데이터만 받아 판정.
13
+ * Stop hook / session scorer / CLI 어느 쪽에서도 호출 가능.
14
+ */
15
+ /** TEST-1 판정 입력. */
16
+ export interface FactCheckInput {
17
+ /** Claude 의 최근 턴 응답 텍스트. */
18
+ text: string;
19
+ /**
20
+ * 최근 N 턴에서 실행된 도구 이름 목록 (중복 OK). 없으면 빈 배열.
21
+ * 호출지가 0턴/전체 세션 등 윈도우를 결정한다.
22
+ */
23
+ recentTools: string[];
24
+ /**
25
+ * optional: 측정으로 간주할 최소 tool count. 기본 1.
26
+ * 빌드/테스트같은 확정 측정 1회면 충분하다고 간주.
27
+ */
28
+ minMeasurements?: number;
29
+ }
30
+ export interface FactCheckResult {
31
+ /** true = 측정 없는 사실-주장 감지, alert 필요. */
32
+ alert: boolean;
33
+ /** 매칭된 사실-주장 키워드 (최대 3개). */
34
+ factAssertions: string[];
35
+ /** 감지된 합의/추측 신호 (최대 3개). */
36
+ agreementSofteners: string[];
37
+ /** 관찰된 측정성 도구 호출 수. */
38
+ measurementCount: number;
39
+ /** 호출지가 surface 하기 좋은 사람-읽기 이유. */
40
+ reason: string;
41
+ }
42
+ /**
43
+ * 핵심 판정 — 텍스트에 사실-주장이 있고 측정 도구가 없으면 alert.
44
+ * 측정이 있거나 사실-주장이 없으면 alert=false.
45
+ * 합의 softener 는 참고용 — softener 많을수록 reason 에 경고 추가.
46
+ */
47
+ export declare function checkFactVsAgreement(input: FactCheckInput): FactCheckResult;