@wooojin/forgen 0.3.2 → 0.4.0
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.
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +64 -0
- package/README.ja.md +61 -7
- package/README.ko.md +15 -1
- package/README.md +92 -6
- package/README.zh.md +61 -7
- package/dist/cli.js +137 -5
- package/dist/core/auto-compound-runner.js +10 -2
- package/dist/core/doctor.js +64 -10
- package/dist/core/inspect-cli.js +65 -5
- package/dist/core/state-gc.d.ts +19 -0
- package/dist/core/state-gc.js +48 -4
- package/dist/core/stats-cli.d.ts +15 -0
- package/dist/core/stats-cli.js +143 -0
- package/dist/core/uninstall.d.ts +1 -0
- package/dist/core/uninstall.js +24 -1
- package/dist/core/v1-bootstrap.js +9 -1
- package/dist/engine/classify-enforce-cli.d.ts +8 -0
- package/dist/engine/classify-enforce-cli.js +61 -0
- package/dist/engine/enforce-classifier.d.ts +31 -0
- package/dist/engine/enforce-classifier.js +123 -0
- package/dist/engine/lifecycle/bypass-detector.d.ts +34 -0
- package/dist/engine/lifecycle/bypass-detector.js +82 -0
- package/dist/engine/lifecycle/lifecycle-cli.d.ts +7 -0
- package/dist/engine/lifecycle/lifecycle-cli.js +102 -0
- package/dist/engine/lifecycle/meta-cli.d.ts +4 -0
- package/dist/engine/lifecycle/meta-cli.js +7 -0
- package/dist/engine/lifecycle/meta-reclassifier.d.ts +78 -0
- package/dist/engine/lifecycle/meta-reclassifier.js +351 -0
- package/dist/engine/lifecycle/orchestrator.d.ts +32 -0
- package/dist/engine/lifecycle/orchestrator.js +131 -0
- package/dist/engine/lifecycle/signals.d.ts +30 -0
- package/dist/engine/lifecycle/signals.js +142 -0
- package/dist/engine/lifecycle/trigger-t1-correction.d.ts +23 -0
- package/dist/engine/lifecycle/trigger-t1-correction.js +78 -0
- package/dist/engine/lifecycle/trigger-t2-violation.d.ts +18 -0
- package/dist/engine/lifecycle/trigger-t2-violation.js +42 -0
- package/dist/engine/lifecycle/trigger-t3-bypass.d.ts +17 -0
- package/dist/engine/lifecycle/trigger-t3-bypass.js +39 -0
- package/dist/engine/lifecycle/trigger-t4-decay.d.ts +18 -0
- package/dist/engine/lifecycle/trigger-t4-decay.js +40 -0
- package/dist/engine/lifecycle/trigger-t5-conflict.d.ts +16 -0
- package/dist/engine/lifecycle/trigger-t5-conflict.js +78 -0
- package/dist/engine/lifecycle/types.d.ts +52 -0
- package/dist/engine/lifecycle/types.js +7 -0
- package/dist/engine/rule-toggle-cli.d.ts +13 -0
- package/dist/engine/rule-toggle-cli.js +76 -0
- package/dist/forge/evidence-processor.js +10 -2
- package/dist/hooks/context-guard.js +71 -0
- package/dist/hooks/post-tool-use.js +62 -0
- package/dist/hooks/pre-tool-use.js +57 -1
- package/dist/hooks/secret-filter.d.ts +10 -0
- package/dist/hooks/secret-filter.js +20 -0
- package/dist/hooks/shared/atomic-write.d.ts +8 -1
- package/dist/hooks/shared/atomic-write.js +17 -3
- package/dist/hooks/shared/hook-response.d.ts +11 -0
- package/dist/hooks/shared/hook-response.js +18 -0
- package/dist/hooks/shared/safe-regex.d.ts +25 -0
- package/dist/hooks/shared/safe-regex.js +50 -0
- package/dist/hooks/shared/stop-triggers.d.ts +19 -0
- package/dist/hooks/shared/stop-triggers.js +19 -0
- package/dist/hooks/stop-guard.d.ts +84 -0
- package/dist/hooks/stop-guard.js +482 -0
- package/dist/mcp/tools.js +19 -2
- package/dist/store/evidence-store.d.ts +15 -0
- package/dist/store/evidence-store.js +50 -1
- package/dist/store/rule-lifecycle.d.ts +23 -0
- package/dist/store/rule-lifecycle.js +63 -0
- package/dist/store/rule-store.d.ts +21 -0
- package/dist/store/rule-store.js +128 -8
- package/dist/store/types.d.ts +83 -0
- package/dist/store/types.js +7 -1
- package/hooks/hook-registry.json +1 -0
- package/hooks/hooks.json +6 -1
- package/package.json +10 -2
- package/plugin.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,70 @@ 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.0] - 2026-04-23
|
|
9
|
+
|
|
10
|
+
### v0.4.0 — The Trust Layer
|
|
11
|
+
|
|
12
|
+
**When Claude says "done", forgen makes it prove it.** v0.4.0 adds turn-level self-verification at the Stop hook: Claude's completion claims get checked against rules you define, and blocks are fed back as `reason` that Claude reads and complies with on the next turn — **zero extra API calls**. Verified end-to-end on 10 scenarios at $1.74 total ([A1 spike report](docs/spike/mech-b-a1-verification-report.md)).
|
|
13
|
+
|
|
14
|
+
Built on top of the v0.3.x personalization core (4-axis profile + compound knowledge + rule rendering): the Trust Layer = 3-axis enforcement (Mech-A/B/C) + rule lifecycle (T1-T5 + Meta) + release self-gate. Interview rounds 9~10 mission "forgen 이 자기 규칙을 forgen 자신에게 강제 적용" achieved — this repo's own development was stopped mid-commit by its own L1 rule when the maintainer claimed "완결" without running Docker e2e (evidence preserved in `.forgen/state/enforcement/violations.jsonl`).
|
|
15
|
+
|
|
16
|
+
**ADR-001 — Mech-A/B/C 3축 강제 메커니즘** (Accepted)
|
|
17
|
+
- Mech-A (hook-BLOCK): 기계 판정 가능 규칙 — PreToolUse deny / Stop artifact_check.
|
|
18
|
+
- Mech-B (self-check prompt-inject): 자연어 판정 규칙 — Stop hook `decision:"block"` + `reason` 으로 Claude 자가점검 강제. **β1 ($0): 외부 LLM 호출 없음.**
|
|
19
|
+
- Mech-C (drift-measure): 정량 판정 불가 규칙 — 장기 편향만 측정.
|
|
20
|
+
- A1 검증 스파이크 10/10 PASS ($1.74, 3분): block 수용률 1.00, FP 0.00, hook p95 7ms, 추가 API 0.
|
|
21
|
+
|
|
22
|
+
**신규 타입** (`src/store/types.ts`):
|
|
23
|
+
- `EnforcementMech`, `HookPoint`, `VerifierSpec`, `EnforceSpec` — `Rule.enforce_via` 에 붙음 (optional, 기존 rule 하위 호환).
|
|
24
|
+
- `EnforceSpec.trigger_keywords_regex` / `trigger_exclude_regex` / `system_tag` — Stop hook 전용 발화 조건.
|
|
25
|
+
- `LifecyclePhase`, `LifecycleState`, `MetaPromotion` — `Rule.lifecycle` 에 붙음.
|
|
26
|
+
|
|
27
|
+
**신규 Hook**:
|
|
28
|
+
- `src/hooks/stop-guard.ts` — Stop hook. Production `rulesFromStore(loadActiveRules())` 로드, spike scenarios.json fallback. `last_assistant_message` 직접 read. stuck-loop guard (threshold 3 초과 시 force approve + drift 이벤트). `compoundCritical: true` (보호 hook).
|
|
29
|
+
- `src/hooks/shared/hook-response.ts::blockStop(reason, systemMessage?)` helper.
|
|
30
|
+
|
|
31
|
+
**ADR-002 — Rule Lifecycle Engine** (Accepted)
|
|
32
|
+
- T1 explicit_correction: `evidence-store.appendEvidence` → `detectT1` → rule retire/supersede/flag. axis + render_key 이중 매칭으로 FP 차단.
|
|
33
|
+
- T2 repeated_violation: 30d rolling window `violations_30d ≥ 3 AND rate > 0.3` → flag. 데이터 소스: `~/.forgen/state/enforcement/violations.jsonl` (stop-guard block 시 자동 append).
|
|
34
|
+
- T3 user_bypass: `post-tool-use` 에서 `bypass-detector.scanForBypass` → `recordBypass`. 7d `bypass_count ≥ 5` → suppress.
|
|
35
|
+
- T4 time_decay: `state-gc.runDailyT4Decay` — `forgen doctor --prune-state` 실행 시 90d 미주입 rule retire (별도 scheduler 없음; 사용자가 명시적으로 실행).
|
|
36
|
+
- T5 conflict_detected: `rule-store.appendRule` 에서 T5 감지, 양쪽 `conflict_refs` 기록.
|
|
37
|
+
- Meta 양방향: drift.jsonl 누적 → 강등 (A→B→C); rolling 20 injects + 0 violations → 승급 (B→A, C→B).
|
|
38
|
+
- Orchestrator `applyEvent` / `foldEvents` pure — rule 파일 쓰기는 호출자 책임.
|
|
39
|
+
- `src/store/rule-store.ts::markRulesInjected` — `v1-bootstrap` 이 renderRules 후 호출해 Meta 롤링 카운터를 채움.
|
|
40
|
+
|
|
41
|
+
**ADR-003 — Release Self-Gate** (Accepted)
|
|
42
|
+
- `.github/workflows/self-gate.yml` — push main / PR main / tag v* 에서 3-stage 검증.
|
|
43
|
+
- `scripts/self-gate.cjs` — 정적 스캔: mock-in-production, secrets-leak (AWS 공식 EXAMPLE fixture allow list), enforce_via-missing, release-artifact.
|
|
44
|
+
- `scripts/self-gate-runtime.cjs` — 6 hook 시나리오 smoke (완료 선언 block / retraction approve / shipped block / mock-context approve 등). 격리 HOME.
|
|
45
|
+
- `scripts/self-gate-release.cjs` — tag-only: version/tag match, CHANGELOG section, dist freshness, .forgen-release/e2e-report.json.
|
|
46
|
+
|
|
47
|
+
**신규 CLI**:
|
|
48
|
+
- `forgen rule <list|suppress|activate|scan|health-scan|classify>` — 규칙 관리 네임스페이스. 기존 플랫 커맨드(suppress-rule, activate-rule, lifecycle-scan, rule-meta-scan, classify-enforce)는 하위 호환 alias 로 유지.
|
|
49
|
+
- `forgen stats` — 한 화면 대시보드 (active rules, corrections, blocks/bypass/drift 7d, retired 7d, last extraction). 기존 jsonl 집계; 신규 telemetry 없음.
|
|
50
|
+
- `forgen inspect corrections` — `forgen inspect evidence` 의 사용자 친화 이름. evidence 는 alias 로 유지.
|
|
51
|
+
- `forgen last-block` — 가장 최근 block 이벤트 상세.
|
|
52
|
+
|
|
53
|
+
**내부 CLI (하위 호환, alias 로 유지)**:
|
|
54
|
+
- `forgen classify-enforce [--apply] [--force]` → `forgen rule classify`.
|
|
55
|
+
- `forgen rule-meta-scan [--apply]` → `forgen rule health-scan`.
|
|
56
|
+
- `forgen lifecycle-scan [--apply]` → `forgen rule scan`.
|
|
57
|
+
|
|
58
|
+
**Upgrade notes (v0.3.x → v0.4.0)**:
|
|
59
|
+
- 첫 `forgen` 실행 시 기존 rule 파일 (`~/.forgen/me/rules/*.json`) 에 `lifecycle` 블록이 자동 주입됩니다 (inject_count, phase='active' 등). 기존 필드는 보존됨.
|
|
60
|
+
- 프로젝트 로컬 `.forgen/rules/*.json` 이 자동 로드됩니다 (runtime 병합). 팀 dogfood 경로. 테스트/격리 필요 시 `FORGEN_DISABLE_PROJECT_RULES=1`.
|
|
61
|
+
- `FORGEN_USER_CONFIRMED=1` 으로 Mech-A PreToolUse 우회 시 violations.jsonl 에 `kind:'correction'` audit 엔트리 기록.
|
|
62
|
+
|
|
63
|
+
**운영 지표**:
|
|
64
|
+
- 전체 회귀 1973/1973 pass (169 files), TypeScript clean.
|
|
65
|
+
- forgen doctor 20/20 hooks active; legacy `~/.forgen/rules/` orphan 감지 추가.
|
|
66
|
+
- Self-gate 정적 ✓ + 런타임 7/7 (SG-ACK round-trip 포함); Docker e2e 77/77 (Phase 9 R9 전체 검증).
|
|
67
|
+
- `npm pack` tarball 539.3 kB, 332 파일, v0.4.0 메타데이터 확인.
|
|
68
|
+
|
|
69
|
+
**관측성**:
|
|
70
|
+
- `acknowledgments.jsonl` 신규 — Mech-B block → retract → pass 루프가 실제 작동한 세션 기록. `forgen stats` 의 `X% acknowledged` 라벨로 집계.
|
|
71
|
+
|
|
8
72
|
## [0.3.2] - 2026-04-21
|
|
9
73
|
|
|
10
74
|
### Security — Audit findings landed
|
package/README.ja.md
CHANGED
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<strong>Claude
|
|
7
|
-
|
|
6
|
+
<strong>Claude が「完了しました」と言ったら、forgen がそれを証明させる。</strong><br/>
|
|
7
|
+
ターンレベルの自己検証 + パーソナライズドルール、<strong>追加 API コスト $0</strong>。
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
|
-
<a href="https://www.npmjs.com/package
|
|
11
|
+
<a href="https://www.npmjs.com/package/@wooojin/forgen"><img src="https://img.shields.io/npm/v/@wooojin/forgen.svg" alt="npm version"/></a>
|
|
12
12
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"/></a>
|
|
13
13
|
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg" alt="Node.js >= 20"/></a>
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<a href="
|
|
17
|
+
<a href="#最初のブロック-30秒">最初のブロック</a> ·
|
|
18
18
|
<a href="#クイックスタート">クイックスタート</a> ·
|
|
19
19
|
<a href="#仕組み">仕組み</a> ·
|
|
20
20
|
<a href="#4軸パーソナライゼーション">4軸</a> ·
|
|
@@ -32,8 +32,48 @@
|
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
+
## 最初のブロック (30秒)
|
|
36
|
+
|
|
37
|
+
あなたは何度も騙されてきました。Claude は「テスト通過、実装完了」と言う — 実際に動かすと — 動かない。forgen はそのギャップを塞ぎます。
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
You: 「ログインハンドラを実装してください。」
|
|
41
|
+
Claude: ...編集中...
|
|
42
|
+
Claude: "구현 완료했습니다。"
|
|
43
|
+
|
|
44
|
+
[forgen:stop-guard/L1-e2e-before-done]
|
|
45
|
+
Docker e2e 証拠 (~/.forgen/state/e2e-result.json, 1時間以内) がありません。
|
|
46
|
+
実行してから再応答してください。
|
|
47
|
+
|
|
48
|
+
Claude: 「完了宣言を取り消します。証拠ファイルがありません。e2e を先に実行します...」
|
|
49
|
+
...bash tests/e2e/docker/run-test.sh 実行...
|
|
50
|
+
「63/63 通過。구현 완료했습니다。」
|
|
51
|
+
|
|
52
|
+
[forgen] ✓ approved
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**何が起きたか**: Claude の Stop フックが、あなたが定義したルール (`L1-e2e-before-done`) によってブロックされました。Claude はブロック `reason` を読み、早すぎた完了宣言を撤回し、証拠を生成して再提出しました。**追加 API コール 0** — Claude が元々生成する予定だった同じセッションのターン内で全て起きました。
|
|
56
|
+
|
|
57
|
+
これが **Mech-B セルフチェックプロンプトインジェクト** です。Claude Code の Stop フックが `decision: "block"` + `reason` を受け入れ、Claude が次のターンでその reason を入力として読むから成り立ちます。10 シナリオ $1.74 で end-to-end 検証済み ([A1 spike report](docs/spike/mech-b-a1-verification-report.md))。
|
|
58
|
+
|
|
59
|
+
🎬 **動作を見る** (27秒):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# 実際のフック・実際のルール・実際の block/approve サイクルをライブで
|
|
63
|
+
bash docs/demo/mech-b-demo.sh
|
|
64
|
+
|
|
65
|
+
# または録画済み asciinema キャストを再生
|
|
66
|
+
asciinema play docs/demo/mech-b-block-unblock.cast
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
デモの「本物/シミュレーション」の区別は [`docs/demo/README.md`](docs/demo/README.md) を参照。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
35
73
|
## 2人の開発者。同じ Claude。まったく異なる振る舞い。
|
|
36
74
|
|
|
75
|
+
上記の Trust Layer は柱の1つです。もう1つはパーソナライゼーション — 最初のブロック後に forgen を使い続ける理由です。
|
|
76
|
+
|
|
37
77
|
開発者 A は慎重派です。Claude にすべてのテストを実行させ、理由を説明させ、現在のファイル以外を変更する前に必ず確認を求めます。
|
|
38
78
|
|
|
39
79
|
開発者 B はスピード重視です。Claude に前提を置いて判断させ、関連ファイルも直接修正させ、結果を2行で報告させます。
|
|
@@ -57,7 +97,7 @@ forgen がこれを実現します。作業スタイルをプロファイリン
|
|
|
57
97
|
### 初回実行(1回のみ、約1分)
|
|
58
98
|
|
|
59
99
|
```bash
|
|
60
|
-
npm install -g /forgen
|
|
100
|
+
npm install -g @wooojin/forgen
|
|
61
101
|
forgen
|
|
62
102
|
```
|
|
63
103
|
|
|
@@ -117,7 +157,7 @@ Claude が `correction-record` MCP ツールを呼び出します。修正は、
|
|
|
117
157
|
|
|
118
158
|
```bash
|
|
119
159
|
# 1. インストール
|
|
120
|
-
npm install -g /forgen
|
|
160
|
+
npm install -g @wooojin/forgen
|
|
121
161
|
|
|
122
162
|
# 2. 初回実行 — 4問オンボーディング(英語/韓国語選択)
|
|
123
163
|
forgen
|
|
@@ -403,13 +443,27 @@ forgen forge --export # プロファイルをエクスポート
|
|
|
403
443
|
### 状態確認
|
|
404
444
|
|
|
405
445
|
```bash
|
|
446
|
+
forgen stats # 1画面 Trust Layer ダッシュボード (ルール・修正・block 7日)
|
|
447
|
+
forgen last-block # 直近のブロックイベント詳細
|
|
406
448
|
forgen inspect profile # 4軸プロファイル + パック + ファセット
|
|
407
449
|
forgen inspect rules # アクティブ/抑制されたルール
|
|
408
|
-
forgen inspect
|
|
450
|
+
forgen inspect corrections # 修正履歴 (alias: evidence)
|
|
409
451
|
forgen inspect session # 現在のセッション状態
|
|
452
|
+
forgen inspect violations # 最近のブロック記録 (--last N)
|
|
410
453
|
forgen me # パーソナルダッシュボード(inspect profile のショートカット)
|
|
411
454
|
```
|
|
412
455
|
|
|
456
|
+
### ルール管理
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
forgen rule list # アクティブ + suppressed ルール一覧
|
|
460
|
+
forgen rule suppress <id> # ルールを無効化 (hard ルールは拒否)
|
|
461
|
+
forgen rule activate <id> # suppressed ルールを再アクティブ化
|
|
462
|
+
forgen rule scan [--apply] # ライフサイクルトリガー実行 (昇格/降格/引退)
|
|
463
|
+
forgen rule health-scan # drift → Mech 降格候補をスキャン
|
|
464
|
+
forgen rule classify # 既存ルールに enforce_via を自動提案
|
|
465
|
+
```
|
|
466
|
+
|
|
413
467
|
### 知識管理
|
|
414
468
|
|
|
415
469
|
```bash
|
package/README.ko.md
CHANGED
|
@@ -414,13 +414,27 @@ forgen forge --export # 프로필 내보내기
|
|
|
414
414
|
### 상태 확인
|
|
415
415
|
|
|
416
416
|
```bash
|
|
417
|
+
forgen stats # 한 화면 Trust Layer 대시보드 (규칙·교정·block 7일)
|
|
418
|
+
forgen last-block # 가장 최근 block 이벤트와 rule 상세
|
|
417
419
|
forgen inspect profile # 4축 프로필 + 팩 + facet
|
|
418
420
|
forgen inspect rules # 활성/비활성 규칙
|
|
419
|
-
forgen inspect
|
|
421
|
+
forgen inspect corrections # 교정 기록 (alias: evidence)
|
|
420
422
|
forgen inspect session # 현재 세션 상태
|
|
423
|
+
forgen inspect violations # 최근 block 기록 (--last N)
|
|
421
424
|
forgen me # 개인 대시보드 (inspect profile 단축키)
|
|
422
425
|
```
|
|
423
426
|
|
|
427
|
+
### 규칙 관리
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
forgen rule list # 활성 + suppressed 규칙 목록
|
|
431
|
+
forgen rule suppress <id> # 규칙 비활성화 (hard 규칙은 거부)
|
|
432
|
+
forgen rule activate <id> # suppressed 규칙 재활성화
|
|
433
|
+
forgen rule scan [--apply] # 수명주기 트리거 실행 (승격/강등/은퇴)
|
|
434
|
+
forgen rule health-scan # drift → Mech 강등 후보 스캔
|
|
435
|
+
forgen rule classify # 레거시 규칙에 enforce_via 자동 제안
|
|
436
|
+
```
|
|
437
|
+
|
|
424
438
|
### 지식 관리
|
|
425
439
|
|
|
426
440
|
```bash
|
package/README.md
CHANGED
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<strong>
|
|
7
|
-
|
|
6
|
+
<strong>When Claude says "done", forgen makes it prove it.</strong><br/>
|
|
7
|
+
Turn-level self-verification + personalized rules, at <strong>$0 extra API cost</strong>.
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
|
-
<a href="https://www.npmjs.com/package
|
|
11
|
+
<a href="https://www.npmjs.com/package/@wooojin/forgen"><img src="https://img.shields.io/npm/v/@wooojin/forgen.svg" alt="npm version"/></a>
|
|
12
12
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"/></a>
|
|
13
13
|
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg" alt="Node.js >= 20"/></a>
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<a href="#
|
|
17
|
+
<a href="#the-first-block-30-seconds">First Block</a> ·
|
|
18
18
|
<a href="#quick-start">Quick Start</a> ·
|
|
19
19
|
<a href="#how-it-works">How It Works</a> ·
|
|
20
20
|
<a href="#4-axis-personalization">4-Axis</a> ·
|
|
@@ -32,8 +32,48 @@
|
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
+
## The first block (30 seconds)
|
|
36
|
+
|
|
37
|
+
You've been burned: Claude says "tests pass, implementation done" — you run it — it doesn't work. forgen closes that gap.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
You: "Implement the login handler."
|
|
41
|
+
Claude: ...makes edits...
|
|
42
|
+
Claude: "구현 완료했습니다."
|
|
43
|
+
|
|
44
|
+
[forgen:stop-guard/L1-e2e-before-done]
|
|
45
|
+
Docker e2e 증거(~/.forgen/state/e2e-result.json, 1시간 이내)가 없습니다.
|
|
46
|
+
지금 실행 후 재응답하라.
|
|
47
|
+
|
|
48
|
+
Claude: "완료 선언을 취소합니다. 증거 파일이 없습니다. e2e 를 먼저 실행합니다..."
|
|
49
|
+
...runs bash tests/e2e/docker/run-test.sh...
|
|
50
|
+
"63/63 pass. 구현 완료했습니다."
|
|
51
|
+
|
|
52
|
+
[forgen] ✓ approved
|
|
53
|
+
```
|
|
54
|
+
|
|
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
|
+
|
|
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
|
+
|
|
59
|
+
🎬 **See it happen** (27 seconds):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Watch the full loop live — actual hook, actual rule, actual block/approve cycle
|
|
63
|
+
bash docs/demo/mech-b-demo.sh
|
|
64
|
+
|
|
65
|
+
# Or replay the pre-recorded asciinema cast
|
|
66
|
+
asciinema play docs/demo/mech-b-block-unblock.cast
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
See [`docs/demo/README.md`](docs/demo/README.md) for what's real vs simulated in the demo.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
35
73
|
## Two developers. Same Claude. Completely different behavior.
|
|
36
74
|
|
|
75
|
+
The Trust Layer above is one pillar. The other is personalization — still the reason you'd keep forgen around after the first block.
|
|
76
|
+
|
|
37
77
|
Developer A is careful. They want Claude to run all tests, explain reasoning, and ask before touching anything outside the current file.
|
|
38
78
|
|
|
39
79
|
Developer B moves fast. They want Claude to make assumptions, fix related files automatically, and report results in two lines.
|
|
@@ -48,7 +88,7 @@ fix the session handler? Here's timeout not covered. Done."
|
|
|
48
88
|
my analysis of each..."
|
|
49
89
|
```
|
|
50
90
|
|
|
51
|
-
Forgen
|
|
91
|
+
Forgen profiles your work style, learns from your corrections, and renders personalized rules that Claude follows every session.
|
|
52
92
|
|
|
53
93
|
---
|
|
54
94
|
|
|
@@ -451,13 +491,27 @@ forgen forge --export # Export profile
|
|
|
451
491
|
### Inspection
|
|
452
492
|
|
|
453
493
|
```bash
|
|
494
|
+
forgen stats # One-screen trust-layer dashboard (rules, corrections, blocks 7d)
|
|
495
|
+
forgen last-block # Most recent block event with rule detail
|
|
454
496
|
forgen inspect profile # 4-axis profile with packs and facets
|
|
455
497
|
forgen inspect rules # Active and suppressed rules
|
|
456
|
-
forgen inspect
|
|
498
|
+
forgen inspect corrections # Correction history (alias: evidence)
|
|
457
499
|
forgen inspect session # Current session state
|
|
500
|
+
forgen inspect violations # Recent block events (--last N)
|
|
458
501
|
forgen me # Personal dashboard (shortcut for inspect profile)
|
|
459
502
|
```
|
|
460
503
|
|
|
504
|
+
### Rule management
|
|
505
|
+
|
|
506
|
+
```bash
|
|
507
|
+
forgen rule list # List active + suppressed rules
|
|
508
|
+
forgen rule suppress <id> # Disable a rule (hard rules refused)
|
|
509
|
+
forgen rule activate <id> # Re-activate a suppressed rule
|
|
510
|
+
forgen rule scan [--apply] # Run lifecycle triggers (promote/demote/retire)
|
|
511
|
+
forgen rule health-scan # Scan drift → Mech downgrade candidates
|
|
512
|
+
forgen rule classify # Propose enforce_via for legacy rules
|
|
513
|
+
```
|
|
514
|
+
|
|
461
515
|
### Knowledge management
|
|
462
516
|
|
|
463
517
|
```bash
|
|
@@ -478,6 +532,7 @@ forgen skill list # List promoted skills
|
|
|
478
532
|
```bash
|
|
479
533
|
forgen init # Initialize project
|
|
480
534
|
forgen doctor # System diagnostics (10 categories + harness maturity)
|
|
535
|
+
forgen doctor --prune-state # Daily hygiene: state GC + T4 rule decay (90d idle → retire)
|
|
481
536
|
forgen dashboard # Knowledge overview (6 sections)
|
|
482
537
|
forgen config hooks # View hook status + context budget
|
|
483
538
|
forgen config hooks --regenerate # Regenerate hooks
|
|
@@ -488,6 +543,37 @@ forgen notepad show # View session notepad
|
|
|
488
543
|
forgen uninstall # Remove forgen cleanly
|
|
489
544
|
```
|
|
490
545
|
|
|
546
|
+
### Rule lifecycle (v0.4.0, ADR-001/002)
|
|
547
|
+
|
|
548
|
+
```bash
|
|
549
|
+
forgen classify-enforce # Preview enforce_via proposals for existing rules
|
|
550
|
+
forgen classify-enforce --apply # Save proposed enforce_via (skips already-set rules)
|
|
551
|
+
forgen classify-enforce --apply --force # Overwrite existing enforce_via
|
|
552
|
+
forgen rule-meta-scan # Preview Mech demotion candidates (drift.jsonl → A→B→C)
|
|
553
|
+
forgen rule-meta-scan --apply # Persist demotions + meta_promotions history
|
|
554
|
+
forgen lifecycle-scan # Preview T2~T5 + Meta (T1 fires inline on correction, not via CLI)
|
|
555
|
+
forgen lifecycle-scan --apply # Apply all lifecycle state transitions
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
Rule enforcement is 3-axis (ADR-001):
|
|
559
|
+
- **Mech-A** (hook-BLOCK) — mechanical checks (`rm -rf`, artifact presence). Violation blocks immediately.
|
|
560
|
+
- **Mech-B** (self-check) — natural-language rules. Stop hook feeds self-check question back to Claude via `decision: "block"` + `reason`. Zero extra API cost.
|
|
561
|
+
- **Mech-C** (drift-measure) — long-term bias tracking only.
|
|
562
|
+
|
|
563
|
+
Rule lifecycle (ADR-002): rules auto-flag / suppress / retire / merge / supersede based on T1~T5 + Meta signals. Details in [docs/adr/ADR-002-rule-lifecycle-engine.md](docs/adr/ADR-002-rule-lifecycle-engine.md).
|
|
564
|
+
|
|
565
|
+
### Release self-gate (v0.4.0, ADR-003)
|
|
566
|
+
|
|
567
|
+
Three CI gates prove forgen does not violate its own L1 rules before release:
|
|
568
|
+
|
|
569
|
+
```bash
|
|
570
|
+
node scripts/self-gate.cjs # Static: mock-in-prod, secrets, enforce_via, release-artifact
|
|
571
|
+
node scripts/self-gate-runtime.cjs # Runtime smoke: 6 hook scenarios
|
|
572
|
+
node scripts/self-gate-release.cjs # Tag-only: version/tag/CHANGELOG/dist/e2e-report consistency
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
Triggered by `.github/workflows/self-gate.yml` on push main / PR main / tag v*. Dogfood opt-in: see [.forgen/README.md](.forgen/README.md).
|
|
576
|
+
|
|
491
577
|
### MCP tools (available to Claude during sessions)
|
|
492
578
|
|
|
493
579
|
| Tool | Purpose |
|
package/README.zh.md
CHANGED
|
@@ -3,18 +3,18 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<strong
|
|
7
|
-
<strong
|
|
6
|
+
<strong>当 Claude 说"完成了", forgen 让它拿出证据。</strong><br/>
|
|
7
|
+
按轮次的自我验证 + 个性化规则, <strong>额外 API 成本 $0</strong>。
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
|
-
<a href="https://www.npmjs.com/package
|
|
11
|
+
<a href="https://www.npmjs.com/package/@wooojin/forgen"><img src="https://img.shields.io/npm/v/@wooojin/forgen.svg" alt="npm version"/></a>
|
|
12
12
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"/></a>
|
|
13
13
|
<a href="https://nodejs.org"><img src="https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg" alt="Node.js >= 20"/></a>
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
|
-
<a href="
|
|
17
|
+
<a href="#第一次拦截-30秒">第一次拦截</a> ·
|
|
18
18
|
<a href="#快速开始">快速开始</a> ·
|
|
19
19
|
<a href="#工作原理">工作原理</a> ·
|
|
20
20
|
<a href="#4轴个性化">4轴</a> ·
|
|
@@ -32,8 +32,48 @@
|
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
+
## 第一次拦截 (30秒)
|
|
36
|
+
|
|
37
|
+
你被骗过很多次了: Claude 说"测试通过, 实现完成" — 真正运行 — 却不工作。forgen 填补这个缺口。
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
You: "实现登录 handler。"
|
|
41
|
+
Claude: ...编辑文件...
|
|
42
|
+
Claude: "구현 완료했습니다。"
|
|
43
|
+
|
|
44
|
+
[forgen:stop-guard/L1-e2e-before-done]
|
|
45
|
+
没有 Docker e2e 证据 (~/.forgen/state/e2e-result.json, 1小时内)。
|
|
46
|
+
立即执行后再回答。
|
|
47
|
+
|
|
48
|
+
Claude: "撤回完成声明。证据文件不存在。先执行 e2e..."
|
|
49
|
+
...bash tests/e2e/docker/run-test.sh 执行...
|
|
50
|
+
"63/63 通过。구현 완료했습니다。"
|
|
51
|
+
|
|
52
|
+
[forgen] ✓ approved
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**刚刚发生了什么**: Claude 的 Stop hook 被你定义的规则 (`L1-e2e-before-done`) 拦截。Claude 读取了 block `reason`, 撤回过早的完成声明, 产生证据, 重新提交。**零额外 API 调用** — 全部发生在 Claude 本来就会产出的同一个 session turn 内。
|
|
56
|
+
|
|
57
|
+
这就是 **Mech-B 自检 prompt-inject**。它工作是因为 Claude Code 的 Stop hook 接受 `decision: "block"` + `reason`, 而 Claude 在下一轮把那个 reason 作为输入读取。我们用 10 个场景、$1.74 总成本端到端验证 ([A1 spike report](docs/spike/mech-b-a1-verification-report.md))。
|
|
58
|
+
|
|
59
|
+
🎬 **观看实际运行** (27秒):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# 现场观看完整循环 — 真实的 hook、真实的规则、真实的 block/approve 周期
|
|
63
|
+
bash docs/demo/mech-b-demo.sh
|
|
64
|
+
|
|
65
|
+
# 或重放预录制的 asciinema cast
|
|
66
|
+
asciinema play docs/demo/mech-b-block-unblock.cast
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
关于 demo 中"真实 vs 模拟"的详情见 [`docs/demo/README.md`](docs/demo/README.md)。
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
35
73
|
## 两个开发者。同一个 Claude。完全不同的行为。
|
|
36
74
|
|
|
75
|
+
上述 Trust Layer 是一根支柱。另一根是个性化 — 第一次拦截之后继续使用 forgen 的理由。
|
|
76
|
+
|
|
37
77
|
开发者 A 做事谨慎。他希望 Claude 运行所有测试、解释原因,在触碰当前文件以外的内容前先征求确认。
|
|
38
78
|
|
|
39
79
|
开发者 B 追求速度。他希望 Claude 自行假设、直接修复相关文件、用两行汇报结果。
|
|
@@ -57,7 +97,7 @@ forgen 实现了这一切。它对你的工作风格进行画像、从你的纠
|
|
|
57
97
|
### 首次运行(仅一次,约1分钟)
|
|
58
98
|
|
|
59
99
|
```bash
|
|
60
|
-
npm install -g /forgen
|
|
100
|
+
npm install -g @wooojin/forgen
|
|
61
101
|
forgen
|
|
62
102
|
```
|
|
63
103
|
|
|
@@ -117,7 +157,7 @@ Claude 调用 `correction-record` MCP 工具。纠正作为结构化证据存储
|
|
|
117
157
|
|
|
118
158
|
```bash
|
|
119
159
|
# 1. 安装
|
|
120
|
-
npm install -g /forgen
|
|
160
|
+
npm install -g @wooojin/forgen
|
|
121
161
|
|
|
122
162
|
# 2. 首次运行 — 4题引导问卷(英语/韩语选择)
|
|
123
163
|
forgen
|
|
@@ -403,13 +443,27 @@ forgen forge --export # 导出档案
|
|
|
403
443
|
### 状态查看
|
|
404
444
|
|
|
405
445
|
```bash
|
|
446
|
+
forgen stats # 单屏 Trust Layer 仪表盘 (规则·纠正·block 7天)
|
|
447
|
+
forgen last-block # 最近一次拦截事件详情
|
|
406
448
|
forgen inspect profile # 4轴档案 + pack + facet
|
|
407
449
|
forgen inspect rules # 活跃/抑制的规则
|
|
408
|
-
forgen inspect
|
|
450
|
+
forgen inspect corrections # 纠正历史 (alias: evidence)
|
|
409
451
|
forgen inspect session # 当前会话状态
|
|
452
|
+
forgen inspect violations # 最近的拦截记录 (--last N)
|
|
410
453
|
forgen me # 个人仪表盘(inspect profile 的快捷方式)
|
|
411
454
|
```
|
|
412
455
|
|
|
456
|
+
### 规则管理
|
|
457
|
+
|
|
458
|
+
```bash
|
|
459
|
+
forgen rule list # 列出活跃 + suppressed 规则
|
|
460
|
+
forgen rule suppress <id> # 禁用规则 (hard 规则拒绝)
|
|
461
|
+
forgen rule activate <id> # 重新激活 suppressed 规则
|
|
462
|
+
forgen rule scan [--apply] # 运行生命周期触发器 (晋升/降级/退役)
|
|
463
|
+
forgen rule health-scan # 扫描 drift → Mech 降级候选
|
|
464
|
+
forgen rule classify # 为旧规则自动提议 enforce_via
|
|
465
|
+
```
|
|
466
|
+
|
|
413
467
|
### 知识管理
|
|
414
468
|
|
|
415
469
|
```bash
|