@aldegad/safedeps 2.1.1 → 2.2.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/README.ko.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **모든 install 을 미확정 블록으로 본다 — `safedeps` 는 안전한 것만 승인하고, 그렇지 않으면 reorg 한다.**
4
4
  >
5
- > OSV / CISA KEV / GitHub Advisory 로 의존성 spec 을 사전 승인하고, Claude Code 와 Codex CLI 의 hook 에서 승인된 spec 강제하며, 승인과 어긋난 install 은 자동으로 마지막 안전 snapshot 으로 롤백한다.
5
+ > OSV / CISA KEV / GitHub Advisory 로 의존성 spec 을 사전 승인하고, Claude Code 와 Codex CLI 의 hook 에서 실제 설치 closure 강제하며, 승인과 어긋난 install 은 자동으로 마지막 안전 snapshot 으로 롤백한다.
6
6
 
7
7
  *Detailed reference → [README.md](./README.md) (영문, SSoT)*
8
8
 
@@ -12,28 +12,50 @@
12
12
 
13
13
  블록체인에서 **reorg (재편성)** 은 미확정 블록 시퀀스를 무효화하고 마지막 확정된 안전 상태로 체인을 되돌린다. `safedeps` 는 같은 원리를 `node_modules` 에 적용한다 — 모든 install 은 일련의 공급망 보안 검사를 통과하기 전까지는 **미확정 블록 후보** 로 취급된다. 의심스러우면 도구가 **reorg** 를 수행한다 — lock 파일, `package.json`, `node_modules` 를 마지막 확정된 안전 snapshot 으로 되돌린다.
14
14
 
15
- 수동 리뷰 없음. 잔여 악성 코드 없음. 완전 자동.
15
+ 빠른 advisory 피드백, 관측 가능한 rollback, silent fallback 없음. command guard 는 best-effort UX 이고, 설치 결과 effect 가 backstop 이다.
16
+
17
+ ---
18
+
19
+ ## 두 lane
20
+
21
+ `safedeps` 는 두 보안 lane 을 소유한다 (전체 설계: [`ARCHITECTURE.md`](./ARCHITECTURE.md) §1):
22
+
23
+ - **install-time** (이 README 의 초점) — advisory check + approved-spec ledger + 빠른 PreToolUse guard + PostToolUse effect enforcement + post-install reorg. 패키지 단위, install 명령과 실제 lockfile effect 주변.
24
+ - **release-time** — `safedeps gates run`, `safedeps scan secrets [--repo|--worktree|--staged]`, `safedeps audit npm`, `safedeps hooks install|check`. repo 트리 secret scan, 의존성 audit, repo-local git hook 설치/검사 (push/release 전). repo-specific policy(gitleaks config, privacy 경로)는 대상 repo 에 남고 safedeps 는 실행 owner. *(옛 `security-release-gates` 흡수.)*
16
25
 
17
26
  ---
18
27
 
19
28
  ## 어떻게 동작
20
29
 
30
+ `safedeps` 는 모든 install 을 두 동작으로 감싼다:
31
+
32
+ - **설치 전** — `safedeps check` 가 패키지를 OSV(canonical) + CISA KEV + GitHub Advisory 로 검사하고 로컬 ledger 에 승인을 기록한다. npm 은 패키지의 전체 의존성 closure 를 풀어 딸린 모든 transitive 패키지까지 검사한다.
33
+ - **설치 후** — PostToolUse hook 이 실제 `package-lock.json` 에 뭐가 깔렸는지 다시 읽고, ledger 에 없거나 advisory DB 가 새로 취약하다고 답하는 패키지를 reorg(롤백)한다.
34
+
35
+ 설치 전 command hook(PreToolUse)은 빠른 advisory 넛지다 — 명백한 미승인 install 과 위험한 명령 형태를 막아 에이전트에게 즉시 피드백을 준다. 하지만 npm 의 진짜 권위는 설치 후 effect gate 다: 명령이 *어떻게 생겼는지* 가 아니라 *실제로 뭐가 깔렸는지* 를 보기 때문에, wrapper 나 난독화된 install 명령으로도 패키지를 통과시킬 수 없다.
36
+
37
+ **스크립트 안전 (무실행 설치).** Claude Code 에서는 PreToolUse hook 이 npm install 에 `--ignore-scripts` 를 붙여 rewrite 한다 — 그래서 설치가 **무실행(inert)** 으로 돈다(패키지는 디스크에 앉되 lifecycle script 는 아직 안 돎). 그다음 effect gate 가 closure 를 검증하고, 통과했을 때만 PostToolUse 가 `npm rebuild` 로 이제서야 검증된 스크립트를 실행한다. 게이트가 거부한 패키지는 *스크립트가 한 번도 돌기 전에* reorg 된다. (Claude Code 의 hook `updatedInput` 기능을 쓴다. Codex CLI 는 이 기능이 없어 Codex 에서는 install 이 정상 실행되고 effect gate 는 detect-and-rollback 이다 — 악성 install script 가 롤백 전에 1회 실행될 수 있다.)
38
+
39
+ 이 effect-primary 모델은 현재 npm 한정이다. `pip`, `cargo`, `go`, `gem`, `maven`, `nuget` 은 closure resolver 가 붙기 전까지 v2.1 command-gate + reorg 모델을 유지한다.
40
+
21
41
  ```
22
42
  PreToolUse PostToolUse
23
43
  (safedeps-pre-guard.sh) (safedeps-post-verify.sh)
24
44
  | |
25
- install cmd ──> [ Advisory / ledger gate ] ──> [ Execute ] ──> [ Verify ]
45
+ install cmd ──> [ Advisory / ledger UX ] ──> [ Execute ] ──> [ npm effect gate ]
26
46
  | | | |
27
- 미승인이면 lock / manifest 깨끗? 의심?
28
- block snapshot | |
47
+ 명백한 miss/ lock / manifest 깨끗? 의심?
48
+ risk block snapshot | |
29
49
  Confirm REORG
30
50
  ```
31
51
 
32
52
  ### 3 단계 구성
33
53
 
34
- 1. **Phase 1 — Advisory Gate** (사용자 또는 에이전트 단계): `safedeps check <ecosystem> <pkg>@<range>` OSV (canonical) + CISA KEV (hard-risk overlay) + GHSA (enrichment) 를 조회. 안전한 (또는 안전 버전으로 좁힌) spec 을 `~/.safedeps/approved-specs/<hash>.json` 에 30일 TTL 로 기록.
35
- 2. **Phase 2 — Hook 강제** (`safedeps-pre-guard.sh`): PreToolUse hook 이 install 명령 본문의 `pkg@version` 토큰을 승인 ledger 와 매칭. miss / expired 면 modern PreToolUse decision JSON 으로 차단하고, 에이전트가 다음에 실행할 정확한 `safedeps check ...` 명령을 reason 에 박는다 → 에이전트는 그 메시지 받아 check → 다시 install 의 자동 루프.
36
- 3. **Phase 3 Post-install Reorg** (`safedeps-post-verify.sh`): install lockfile diff + 의심 install script / native binary 검사. 어긋나면 마지막 confirmed snapshot 으로 자동 reorg.
54
+ **① Advisory check (`safedeps check`)** `safedeps check <ecosystem> <pkg>@<range>` OSV(canonical) + CISA KEV(hard-risk overlay) + GHSA(enrichment) 를 조회한다. npm temp dir 에서 `npm install --package-lock-only --ignore-scripts` 로 스크립트 실행 없는 lockfile 만들어 전체 closure 를 뽑고 OSV `/v1/querybatch` 로 묶어 검사한다. 깨끗하면 direct spec 과 `transitive_specs` 를 `~/.safedeps/approved-specs/<hash>.json` 에 30일 TTL 로 기록한다.
55
+
56
+ **② 빠른 command guard (`safedeps-pre-guard.sh`, PreToolUse)** install 명령의 `pkg@version` 토큰을 ledger 와 대조하고 lockfile/manifest snapshot 한다. 미승인이면 차단하고, 다음에 실행할 `safedeps check ...` 명령을 차단 사유에 박아준다 (PATH 에 있으면 `safedeps`, 없으면 절대경로). 에이전트는 그 메시지로 check → 재시도하면 된다. 이 단계는 빠른 advisory/UX 일 뿐 최종 권위는 아니다.
57
+
58
+ **③ Effect gate + reorg (`safedeps-post-verify.sh`, PostToolUse)** — 설치 후 실제 `package-lock.json` closure 전체를 ledger 의 direct entry + `transitive_specs` 와 대조하고 OSV batch 로 재확인한다. **npm 에서는 이 effect gate 가 primary 권위다.** 미승인·취약·provider fail-closed, 또는 의심스러운 install script·native binary 가 있으면 마지막 confirmed snapshot 으로 자동 reorg 한다.
37
59
 
38
60
  ---
39
61
 
@@ -119,16 +141,16 @@ node scripts/install/install-safedeps-recheck-agent.mjs install --hour 9 --minut
119
141
  전형적인 흐름:
120
142
 
121
143
  1. 에이전트가 `npm install foo@1.2.3` 같은 명령을 작성한다.
122
- 2. PreToolUse hook 이 spec 이 승인 ledger 있는지 확인. 없으면 install 을 **차단**하고, 다음에 실행할 정확한 `safedeps check npm foo@1.2.3` 명령을 reason 에 박아 에이전트에게 돌려준다.
144
+ 2. PreToolUse hook 이 빠른 advisory ledger check 를 수행한다. direct spec 이 없거나 만료됐거나 명백히 위험하면 install 을 **차단**하고, 다음에 실행할 정확한 `safedeps check npm foo@1.2.3` 명령을 reason 에 박아 에이전트에게 돌려준다.
123
145
  3. 에이전트가 그 안내를 받아 `safedeps check` 를 호출 → OSV / CISA KEV / GitHub Advisory 조회 → 안전하면 **허용목록 (ledger) 에 박는다**. KEV 매치면 hard-block (override 불가), CVE 에 patch 가 있으면 안전 버전으로 자동 narrow.
124
146
  4. 다시 install 시도 → 이번엔 ledger 매치되어 **통과**.
125
- 5. install 후 PostToolUse hook 이 lockfile / install script / native binary 를 검증. 어긋나면 마지막 안전 snapshot 으로 **자동 reorg**.
147
+ 5. install 후 PostToolUse hook 이 npm primary authority 로 실제 lockfile closure 를 direct ledger / `transitive_specs` / OSV batch 와 대조하고, install script / native binary 를 검증한다. 어긋나면 마지막 안전 snapshot 으로 **자동 reorg**.
126
148
 
127
- 이 흐름으로 에이전트는 임의의 패키지를 즉시 깔지 못하고, install 마다 advisory 통과를 강제로 거친다. 사람이 PR 리뷰에서 잡을 의심 패키지가 install 시점에 이미 잡힌다. SaaS 의존 없이 로컬 + 공개 DB (OSV / KEV / GHSA) 만 쓴다.
149
+ 이 흐름으로 일반적인 package-manager install 명령은 실행 전에 빠른 advisory 피드백을 받고, npm install 실행 effect-time closure enforcement 받는다. 다만 command hook best-effort 명령 휴리스틱이지 sandbox 가 아니다. 비정상 wrapper/interpreter 경로나 같은 사용자 권한으로 로컬 safedeps 상태를 조작하는 공격은 ledger 서명/강화 전까지 trust boundary 밖이다. npm effect-primary 모델은 아직 `pip`, `cargo`, `go`, `gem`, `maven`, `nuget` 에 적용되지 않으며, 이 ecosystem 들은 v2.1 command-gate + reorg 모델을 유지한다. SaaS 의존 없이 로컬 + 공개 DB (OSV / KEV / GHSA) 만 쓴다.
128
150
 
129
151
  ---
130
152
 
131
- ## Legacy 마이그레이션 (v1 사용자만)
153
+ ## Legacy / Migration: v1 `npm-reorg-guard`
132
154
 
133
155
  v1 시절 이름이 `npm-reorg-guard` 였고 state 디렉토리가 `~/.npm-reorg-guard/` 였다. v2 로 rename 되면서 state 도 `~/.safedeps/` 로 옮겨야 하는데, 그 1회 이전을 자동화한 명령이 있다:
134
156
 
package/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  > **Treat every install as an unconfirmed block — `safedeps` approves the safe ones, reorgs the rest.**
4
4
  >
5
- > Pre-approve dependency installs against OSV / CISA KEV / GitHub Advisory, enforce that approval from Claude Code and Codex CLI hooks, and auto-rollback any install that diverges from the approved spec. *(한국어 README → [README.ko.md](./README.ko.md))*
5
+ > Pre-approve dependency installs against OSV / CISA KEV / GitHub Advisory, enforce the installed closure from Claude Code and Codex CLI hooks, and auto-rollback any install that diverges from the approved closure. *(한국어 README → [README.ko.md](./README.ko.md))*
6
6
 
7
7
  ## Why "reorg"?
8
8
 
9
9
  In blockchain networks, a **reorganization (reorg)** invalidates a sequence of blocks and reverts the chain to a previously confirmed safe state. `safedeps` applies the same principle to your `node_modules`: every install is treated as an unconfirmed block candidate until it passes a battery of supply-chain security checks. If anything looks wrong, the tool performs a **reorg** -- rolling back lock files, `package.json`, and `node_modules` to the last confirmed safe snapshot.
10
10
 
11
- No manual review. No leftover malicious code. Fully automatic.
11
+ Fast advisory feedback, observable rollback, and no hidden fallback. The command guard is best-effort UX; the installed effect is the backstop.
12
12
 
13
13
  ## Distribution Model
14
14
 
@@ -19,19 +19,35 @@ Safedeps has two distribution surfaces:
19
19
 
20
20
  Use the GitHub release when you want the full skill/hook source tree as the canonical artifact. Use npm when you mainly want a versioned global CLI.
21
21
 
22
+ ## Two Lanes
23
+
24
+ `safedeps` owns two security lanes (full design in [`ARCHITECTURE.md`](./ARCHITECTURE.md) §1):
25
+
26
+ - **Install-time** (the focus of this README) — advisory check + approved-spec ledger + fast PreToolUse guard + PostToolUse effect enforcement + post-install reorg. Per-package, around the install command and its actual lockfile effect.
27
+ - **Release-time** — `safedeps gates run`, `safedeps scan secrets [--repo|--worktree|--staged]`, `safedeps audit npm`, `safedeps hooks install|check`. Repo-tree secret scan, dependency audit, and repo-local git hook install/check before push/release. Repo-specific policy (gitleaks config, privacy paths) stays in the target repo; safedeps owns execution. *(Absorbed the former `security-release-gates`.)*
28
+
22
29
  ## How It Works
23
30
 
24
- `safedeps` plugs into Claude Code and Codex CLI hooks as a pair of **PreToolUse** and **PostToolUse** hooks that wrap package install commands. The CLI owns provider lookups and the approved-spec ledger; hooks enforce that ledger and run post-install rollback checks.
31
+ `safedeps` works in two moves around every install:
32
+
33
+ - **Before** — `safedeps check` clears a package against OSV (canonical), CISA KEV, and GitHub Advisory, then records the approval in a local ledger. For npm it resolves the package's full dependency closure and checks every transitive package too.
34
+ - **After** — the PostToolUse hook re-reads what actually landed in `package-lock.json` and reorgs (rolls back) anything that isn't in the ledger or that the advisory databases now flag.
35
+
36
+ The pre-install command hook (PreToolUse) is a fast advisory nudge — it blocks obvious unapproved installs and risky command forms so the agent gets immediate feedback. But for npm the real authority is the post-install effect gate: it judges what was *actually installed*, not what the command looked like, so a wrapped or obfuscated install command can't slip a package past it.
37
+
38
+ **Script safety (inert install).** On Claude Code, the PreToolUse hook rewrites an npm install to add `--ignore-scripts`, so the install runs **inert** — packages land on disk but no lifecycle script runs yet. The effect gate then verifies the closure; only if it passes does the PostToolUse hook run `npm rebuild` to execute the now-verified scripts. A package the gate rejects is reorged before any of its scripts run. (This uses the Claude Code hook `updatedInput` capability. Codex CLI does not expose it, so on Codex the install runs normally and the effect gate is detect-and-rollback — a malicious install script can run once before the rollback.)
39
+
40
+ This effect-primary model is npm-only for now. `pip`, `cargo`, `go`, `gem`, `maven`, and `nuget` stay on the v2.1 command-gate + reorg model until their closure resolvers land.
25
41
 
26
42
  ```
27
43
  PreToolUse PostToolUse
28
44
  (safedeps-pre-guard.sh) (safedeps-post-verify.sh)
29
45
  | |
30
- install cmd ──> [ Advisory/ledger gate ] ──> [ Execute ] ──> [ Verify ]
46
+ install cmd ──> [ Advisory/ledger UX ] ──> [ Execute ] ──> [ npm effect gate ]
31
47
  | | | |
32
- Block if Snapshot Clean? Suspicious?
33
- unapproved lock/manifest files, | |
34
- or risky package listings Confirm REORG
48
+ Block obvious Snapshot Clean? Suspicious?
49
+ misses/risk lock/manifest files, | |
50
+ package listings Confirm REORG
35
51
  | |
36
52
  | v v
37
53
  +--- parent_snapshot_id ──> confirmed
@@ -40,7 +56,7 @@ Use the GitHub release when you want the full skill/hook source tree as the cano
40
56
  confirmed snapshot
41
57
  ```
42
58
 
43
- ### Phase 1: Advisory Gate + Pre-flight (PreToolUse)
59
+ ### Phase 1: Advisory Check (`safedeps check`)
44
60
 
45
61
  Before an agent installs a dependency, it should run:
46
62
 
@@ -48,40 +64,44 @@ Before an agent installs a dependency, it should run:
48
64
  safedeps check <ecosystem> <pkg>@<version|range> --json
49
65
  ```
50
66
 
51
- That command queries OSV (canonical), CISA KEV (hard-risk overlay), and GitHub Advisory (enrichment). Clean or safely narrowed specs are written to `~/.safedeps/approved-specs/`.
67
+ That command queries OSV (canonical), CISA KEV (hard-risk overlay), and GitHub Advisory (enrichment). For npm, it first creates a script-free temp lockfile with `npm install --package-lock-only --ignore-scripts`, extracts the full dependency closure, and queries OSV `/v1/querybatch`. Clean or safely narrowed specs are written to `~/.safedeps/approved-specs/`; npm entries also record `transitive_specs`.
68
+
69
+ ### Phase 2: Fast Command Guard + Snapshots (PreToolUse)
52
70
 
53
- When Claude Code or Codex CLI is about to run `npm install`, `pip install`, `cargo add`, `go get`, `gem install`, or similar commands, the guard hook:
71
+ When Claude Code or Codex CLI is about to run `npm install`, `pip install`, `cargo add`, `go get`, `gem install`, or similar commands, the guard hook provides a fast advisory/UX layer:
54
72
 
55
73
  1. **Snapshots** the current `package-lock.json`, `pnpm-lock.yaml`, `yarn.lock`, and `package.json` into `~/.safedeps/snapshots/`.
56
74
  2. **Records metadata** including a `parent_snapshot_id` linking to the previous confirmed snapshot (forming a chain, just like blocks).
57
75
  3. **Captures pre-install state** of `node_modules` (package listings and binary listings) for diff-based detection later.
58
- 4. **Enforces the approved-spec ledger** for explicit `pkg@version` install commands.
76
+ 4. **Fast-checks the approved-spec ledger** for explicit `pkg@version` install commands.
59
77
  5. **Runs pre-flight checks** and **blocks** the command entirely if it detects:
60
78
  - Typosquatting package names (`lod_sh`, `reacct`, `axois`, etc.)
61
79
  - Non-standard `--registry` URLs (anything outside `registry.npmjs.org` and `registry.yarnpkg.com`)
62
80
  - Piped remote execution patterns (`curl ... | bash`)
63
81
  - Explicit disabling of install script safety (`npm config set ignore-scripts false`)
64
82
 
65
- If the ledger gate or a pre-flight check fails, the command is **blocked before execution** -- nothing is installed.
83
+ If the ledger gate or a pre-flight check fails, the command is **blocked before execution** -- nothing is installed. This command guard is intentionally best-effort; it improves the agent loop and catches direct misses, while npm authority lives in the post-install effect gate.
84
+
85
+ ### Phase 3: Post-install Effect Enforcement (`safedeps-post-verify.sh` -- PostToolUse)
66
86
 
67
- ### Phase 2: Post-install verification (`safedeps-post-verify.sh` -- PostToolUse)
87
+ After the install command completes, the verify hook analyzes what changed. For npm, this is the primary enforcement surface: it reads the actual `package-lock.json` closure, verifies every package against approved direct entries and their `transitive_specs`, and re-checks the closure with OSV batch.
68
88
 
69
- After the install command completes, the verify hook analyzes what changed:
89
+ 1. **npm effect gate** -- Reorgs if any lockfile package is unapproved, KEV-blocked, vulnerable, or cannot be verified fail-closed.
70
90
 
71
- 1. **Install script analysis** -- Scans newly added packages for `preinstall`, `install`, and `postinstall` scripts containing:
91
+ 2. **Install script analysis** -- Scans newly added packages for `preinstall`, `install`, and `postinstall` scripts containing:
72
92
  - Network access (`curl`, `wget`, `fetch`, `http`, `socket`, `dns`)
73
93
  - Dynamic code execution (`eval`, `exec`, `spawn`, `child_process`, `Function()`)
74
94
  - Sensitive path access (`~/.ssh`, `.env`, `.aws`, `credentials`)
75
95
  - Obfuscated content (`base64`, `atob`, `Buffer.from`, hex/unicode escapes)
76
96
 
77
- 2. **Lock file diff analysis** -- Compares the snapshotted lock file content against the post-install version:
97
+ 3. **Lock file diff analysis** -- Compares the snapshotted lock file content against the post-install version:
78
98
  - Resolved URLs pointing to non-standard registries
79
99
  - Insecure protocols (`http://`, `git://`) in resolved URLs
80
100
  - Unusually large dependency additions (>50 new resolved entries, indicating potential dependency confusion)
81
101
 
82
- 3. **Binary inspection** -- Checks `node_modules/.bin/` for newly added native binaries (ELF, Mach-O, shared objects) that should not appear in a JavaScript project.
102
+ 4. **Binary inspection** -- Checks `node_modules/.bin/` for newly added native binaries (ELF, Mach-O, shared objects) that should not appear in a JavaScript project.
83
103
 
84
- ### Phase 3: Confirm or Reorg
104
+ ### Confirm or Reorg
85
105
 
86
106
  - **All checks pass** -- The snapshot is marked as **confirmed** in `~/.safedeps/confirmed`. This becomes the new safe baseline.
87
107
  - **Any check fails** -- A **reorg** is triggered:
@@ -96,7 +116,7 @@ After the install command completes, the verify hook analyzes what changed:
96
116
  | Blockchain Concept | Safedeps Equivalent |
97
117
  |---|---|
98
118
  | **Block candidate** | Snapshot taken before `npm install` |
99
- | **Block validation** | Post-install security checks (scripts, lock diff, binaries) |
119
+ | **Block validation** | Post-install effect checks (npm closure, scripts, lock diff, binaries) |
100
120
  | **Finality / confirmation** | Snapshot ID written to `~/.safedeps/confirmed` |
101
121
  | **Chain reorganization** | Rollback to last confirmed snapshot + `node_modules` rebuild |
102
122
  | **Parent hash linking** | `parent_snapshot_id` in each snapshot's `_meta.json` |
@@ -106,18 +126,20 @@ After the install command completes, the verify hook analyzes what changed:
106
126
 
107
127
  | Category | What it catches | Phase | Action |
108
128
  |---|---|---|---|
109
- | Typosquatting | Known misspelling patterns of popular packages | Pre-flight | **Block** |
110
- | Pipe execution | `curl \| bash`, `wget \| sh` | Pre-flight | **Block** |
111
- | Registry hijack | `--registry` pointing to unofficial sources | Pre-flight | **Block** |
112
- | Script safety bypass | `npm config set ignore-scripts false` | Pre-flight | **Block** |
113
- | Command indirection | `eval "npm install ..."`, subshell expansion, variable indirection | Pre-flight | **Guard** |
114
- | npx/dlx execution | `npx`, `pnpm dlx`, `yarn dlx` package execution | Pre-flight | **Guard** |
115
- | Malicious install scripts | Network calls, `eval`/`exec`, sensitive path access in hooks | Post-install | **Reorg** |
116
- | Obfuscated code | Base64, hex encoding, `Buffer.from` in install scripts | Post-install | **Reorg** |
117
- | Lock file tampering | Resolved URLs from non-standard registries | Post-install | **Reorg** |
118
- | Insecure protocols | `http://` or `git://` resolved URLs | Post-install | **Reorg** |
119
- | Dependency confusion | >50 new dependencies in a single install | Post-install | **Reorg** |
120
- | Native binaries | Compiled executables in `node_modules/.bin/` | Post-install | **Reorg** |
129
+ | Typosquatting | Known misspelling patterns of popular packages | PreToolUse advisory guard | **Block** |
130
+ | Pipe execution | `curl \| bash`, `wget \| sh` | PreToolUse advisory guard | **Block** |
131
+ | Registry hijack | `--registry` pointing to unofficial sources | PreToolUse advisory guard | **Block** |
132
+ | Script safety bypass | `npm config set ignore-scripts false` | PreToolUse advisory guard | **Block** |
133
+ | Command indirection | `eval "npm install ..."`, subshell expansion, variable indirection | PreToolUse advisory guard | **Guard** |
134
+ | npx/dlx execution | `npx`, `pnpm dlx`, `yarn dlx` package execution | PreToolUse advisory guard | **Guard** |
135
+ | Unapproved transitive dependency | npm `package-lock.json` package missing from direct ledger or `transitive_specs` | PostToolUse npm primary effect gate | **Reorg** |
136
+ | Vulnerable closure package | npm direct/transitive package with OSV/KEV hit | PostToolUse npm primary effect gate | **Reorg** |
137
+ | Malicious install scripts | Network calls, `eval`/`exec`, sensitive path access in hooks | PostToolUse effect verify | **Reorg** |
138
+ | Obfuscated code | Base64, hex encoding, `Buffer.from` in install scripts | PostToolUse effect verify | **Reorg** |
139
+ | Lock file tampering | Resolved URLs from non-standard registries | PostToolUse effect verify | **Reorg** |
140
+ | Insecure protocols | `http://` or `git://` resolved URLs | PostToolUse effect verify | **Reorg** |
141
+ | Dependency confusion | >50 new dependencies in a single install | PostToolUse effect verify | **Reorg** |
142
+ | Native binaries | Compiled executables in `node_modules/.bin/` | PostToolUse effect verify | **Reorg** |
121
143
 
122
144
  ## Installation
123
145
 
@@ -151,7 +173,7 @@ cd safedeps
151
173
  node scripts/install/install-safedeps-hooks.mjs
152
174
  ```
153
175
 
154
- The installer is idempotent. It symlinks the skill into `~/.claude/skills/safedeps` and `~/.codex/skills/safedeps` when those roots exist, patches the matching hook config, and can also place `safedeps` on PATH through `~/.local/bin`.
176
+ The installer is idempotent. It symlinks the skill into `~/.claude/skills/safedeps` and `~/.codex/skills/safedeps` when those roots exist, patches the matching hook config, and — with `--link-bin` — can also place `safedeps` on PATH through `~/.local/bin`. That PATH link is optional: the hooks name an absolute fallback path in their block messages, so the gate is self-contained and works with zero PATH setup.
155
177
 
156
178
  **3. Manual hook registration, if needed:**
157
179
 
@@ -286,8 +308,8 @@ safedeps/
286
308
  providers/ # OSV / CISA KEV / GHSA adapters
287
309
  ledger/ # approved-spec ledger
288
310
  scripts/
289
- safedeps-pre-guard.sh # PreToolUse hook -- snapshot + ledger enforcement
290
- safedeps-post-verify.sh # PostToolUse hook -- post-install verification + reorg
311
+ safedeps-pre-guard.sh # PreToolUse hook -- advisory ledger UX + snapshots
312
+ safedeps-post-verify.sh # PostToolUse hook -- npm primary effect verification + reorg
291
313
  install/install-safedeps-hooks.mjs
292
314
  install/install-safedeps-recheck-agent.mjs
293
315
  install/migrate-safedeps-state.mjs
@@ -305,14 +327,19 @@ safedeps/
305
327
  Typical flow:
306
328
 
307
329
  1. The agent writes `npm install foo@1.2.3` (or any of the other supported install verbs).
308
- 2. The PreToolUse hook checks whether that spec is in the approved-spec ledger. If not, it **blocks** the install and returns the exact `safedeps check npm foo@1.2.3` command the agent should run next, in the block reason.
330
+ 2. The PreToolUse hook does a fast advisory ledger check. If the direct spec is missing, expired, or obviously risky, it **blocks** the install and returns the exact `safedeps check npm foo@1.2.3` command the agent should run next, in the block reason.
309
331
  3. The agent runs `safedeps check`. The CLI queries OSV / CISA KEV / GitHub Advisory and, if safe, **adds the spec to the ledger**. KEV matches are hard-block (no override). CVEs with an available patch are auto-narrowed to the fixed version.
310
332
  4. The agent retries the install. The ledger entry now matches, so the install **proceeds**.
311
- 5. After the install, the PostToolUse hook diffs the lockfile, checks install scripts and native binaries, and **auto-reorgs** to the last confirmed snapshot if anything diverged.
333
+ 5. After the install, the PostToolUse hook is the npm primary authority: it verifies the actual lockfile closure against direct ledger entries, `transitive_specs`, and OSV batch, then checks install scripts and native binaries and **auto-reorgs** to the last confirmed snapshot if anything diverged.
334
+
335
+ Every install command gets fast advisory feedback before it runs; every npm install gets closure-level enforcement after it runs. The suspicious package a human would catch at PR review is already caught at install time — and there is no SaaS dependency, only the local CLI plus public databases (OSV / KEV / GHSA).
336
+
337
+ Two honest boundaries:
312
338
 
313
- With this loop, the agent cannot install arbitrary packages on demand. Every install is forced through an advisory check. The suspicious package a human would catch at PR review time is already caught at install time. No SaaS dependency only the local CLI plus public databases (OSV / KEV / GHSA).
339
+ - **The command hook is a heuristic, not a sandbox.** Unusual wrappers, shell interpreters, or same-user tampering with local `~/.safedeps` state sit outside its trust boundary. The npm effect gate is the backstop it catches what the command hook misses, because it inspects the installed result rather than the command text.
340
+ - **Effect-primary enforcement is npm-only today.** `pip`, `cargo`, `go`, `gem`, `maven`, and `nuget` stay on the v2.1 command-gate + reorg model until their closure resolvers land.
314
341
 
315
- ## Legacy State Migration (v1 only)
342
+ ## Legacy / Migration: v1 `npm-reorg-guard`
316
343
 
317
344
  The v1 product was named `npm-reorg-guard` and used `~/.npm-reorg-guard/` as the state directory. v2 moves state to `~/.safedeps/`. A one-shot migration is provided:
318
345
 
package/ROADMAP.md CHANGED
@@ -1,131 +1,126 @@
1
1
  # Safedeps Roadmap
2
2
 
3
- > 시간축 + 우선순위. **왜·어떻게** `ARCHITECTURE.md`, **언제·뭐 먼저** 파일.
3
+ > Timeline and priorities. The **why / how** lives in [`ARCHITECTURE.md`](./ARCHITECTURE.md); the **when / what first** lives here. *(한국어 → [ROADMAP.ko.md](./ROADMAP.ko.md))*
4
4
 
5
5
  ---
6
6
 
7
- ## 결정 SSoT
7
+ ## Scope
8
8
 
9
- **스코프 = 개발 의존성만** (npm / pip / cargo / go / gem / maven / nuget).
10
- OS-level (nginx / apt / brew / system binary) 은 **별도 도구로 분리**. SRP 측면 더 깔끔.
9
+ Safedeps gates **development dependency installs** (npm / pip / cargo / go / gem / maven / nuget). At release time it also runs a repo-tree secret scan, dependency audit, and git-hook install/check (the lane absorbed from the former `security-release-gates`).
11
10
 
12
- 근거: dev 의존성과 OS 패키지는 운영 결이 다름.
13
- - dev = "새 기능 → install 명령 → 매번 새 패키지 진입" (install 순간 게이트가 의미 큼).
14
- - OS = "기존 패키지 security update" (cron 주기 audit + RSS 알람이 더 맞음).
15
-
16
- → safedeps = dev 의존성 install 단계 결.
17
- → OS-level 은 별도 (가칭 `infra-cve-monitor` — 미래 v3+).
11
+ Out of scope: OS / system packages, container images, runtime sandboxing, registry integrity, and reputation analysis. Those are different security layers and stay in different tools — see [`ARCHITECTURE.md`](./ARCHITECTURE.md) §1 for the boundary.
18
12
 
19
13
  ---
20
14
 
21
- ## v1 (출시 완료)
22
-
23
- **이름**: `npm-reorg-guard`
24
- **Status**: shipped as v1. GitHub repo has since been renamed to `aldegad/safedeps`.
15
+ ## v1 — `npm-reorg-guard` (shipped)
25
16
 
26
- - npm ecosystem 전용.
27
- - PreToolUse hook (guard.sh): typosquat / curl|bash / 비표준 registry 등 **hardcoded pattern** 차단.
28
- - PostToolUse hook (verify.sh): lockfile diff + install script 검사의심 시 **reorg** (rollback).
29
- - 외부 vuln DB 조회 0. self-contained.
17
+ - npm-only, self-contained, no external advisory database.
18
+ - PreToolUse hook: typosquat / `curl | bash` / non-standard registry pattern blocks.
19
+ - PostToolUse hook: lockfile diff + install-script analysis → reorg (rollback) on suspicion.
30
20
 
31
- **한계**:
32
- - npm 만.
33
- - 알려진 CVE 검사 X (pattern matching 위주).
34
- - adversarial 회피 가능.
21
+ Limits: npm only, no CVE lookup (pattern matching), evadable by a determined adversary. The GitHub repo has since been renamed `aldegad/safedeps`.
35
22
 
36
23
  ---
37
24
 
38
- ## v2 — Safedeps (현재 작업 중)
25
+ ## v2 — `safedeps` (shipped, v2.1.x)
39
26
 
40
- **이름**: `safedeps`, 내부 engine = `reorg-guard` (v1 자산 보존).
41
- **Status**: `ARCHITECTURE.md` v2 작성 완료, v2.1 provider/ledger 구현 시작.
27
+ The internal engine keeps the v1 `reorg-guard` assets.
42
28
 
43
- ### 핵심 변화
44
- - ecosystem 통합: npm / yarn / pnpm / pip (poetry, uv, pipenv) / cargo / go / gem / maven / nuget.
45
- - **외부 vuln DB 결합**: OSV.dev (primary) + CISA KEV (hard-risk overlay) + GHSA (cross-check). NVD / deps.dev / Snyk = enrichment.
46
- - **3-phase defense**:
47
- 1. Advisory Gate (`safedeps check`) — install 명령 *작성 전* vuln DB 조회 → 안전 spec 결정 → `~/.safedeps/approved-specs/<hash>.json` ledger 기록.
48
- 2. Hook Enforcement (`safedeps-pre-guard.sh`) — ledger 일치 검증.
49
- 3. Post-Install Reorg (`safedeps-post-verify.sh`) — v1 engine 그대로 (rollback fallback).
50
- - Approved spec **TTL** (30일) + **daily re-check** cron (새 CVE 발견 시 revoke + 알람).
51
- - **No silent fallback**: provider fail = fail-closed + `--allow-unverified` explicit override (observable).
29
+ ### What changed
52
30
 
53
- ### 구현 마일스톤
31
+ - **Multi-ecosystem**: npm / yarn / pnpm / pip (poetry, uv, pipenv) / cargo / go / gem / maven / nuget.
32
+ - **External advisory databases**: OSV.dev (canonical) + CISA KEV (hard-risk overlay) + GitHub Advisory (enrichment).
33
+ - **Three-phase defense**:
34
+ 1. Advisory gate (`safedeps check`) — query the advisory databases before the install command is written, decide a safe spec, and record it to the `~/.safedeps/approved-specs/` ledger.
35
+ 2. Hook enforcement (`safedeps-pre-guard.sh`) — verify the install matches the ledger.
36
+ 3. Post-install reorg (`safedeps-post-verify.sh`) — the v1 engine, rolling back on divergence.
37
+ - **Approved-spec TTL** (30 days) + **daily re-check** (revoke + alert when a new CVE appears).
38
+ - **No silent fallback**: a provider failure is fail-closed; any override is explicit and observable.
54
39
 
55
- | 마일스톤 | 산출물 | 의존 |
56
- |---|---|---|
57
- | **v2.0-doc** ✅ | `ARCHITECTURE.md` v2 작성·push | — |
58
- | **v2.0-roadmap** ✅ | 이 문서 | — |
59
- | **v2.1-rename** ✅ | GitHub repo rename `aldegad/npm-reorg-guard` → `aldegad/safedeps` ✅. 로컬 repo/skill id/path `safedeps` ✅. `safedeps migrate` 로 legacy `~/.npm-reorg-guard` → `~/.safedeps` 이전 + legacy hook cleanup. | v2.0-doc |
60
- | **v2.1-providers** ✅ | `lib/providers/` 신규 — OSV / KEV / GHSA adapter. 단일 query interface. 응답 cache (TTL 24h). | — |
61
- | **v2.1-ledger** ✅ | `lib/ledger/` 신규 — approved spec JSON I/O (atomic write, hash 계산, TTL 검사). | v2.1-providers |
62
- | **v2.1-cli** ✅ | `bin/safedeps` 신규 — `check`, `ledger`, `revoke`, `re-check`, `migrate`, `version` 서브커맨드. | v2.1-providers, v2.1-ledger |
63
- | **v2.1-guard-patch** ✅ | `scripts/safedeps-pre-guard.sh` 갱신 — ledger 일치 검증 추가 + v1 pattern 유지. | v2.1-ledger |
64
- | **v2.1-verify-patch** ✅ | `scripts/safedeps-post-verify.sh` 갱신 — approved spec 과 lockfile diff 비교 추가 + v1 reorg 유지. | v2.1-ledger |
65
- | **v2.1-multi-ecosystem** ✅ | pip / cargo / go / gem / maven / nuget 명령 파싱 + lockfile snapshot. `safedeps-pre-guard.sh` 는 install 분류와 typosquat pattern 을 확장했고, `safedeps-post-verify.sh` 는 monitored dependency files 기준으로 rollback truth 를 공유한다. | v2.1-guard-patch |
66
- | **v2.1-hook-rename** ✅ | hook 파일 namespacing (`guard.sh` → `safedeps-pre-guard.sh`, `verify.sh` → `safedeps-post-verify.sh`) + cross-engine installer (`scripts/install/install-safedeps-hooks.mjs`, ~/.claude + ~/.codex 자동 등록, idempotent, --uninstall). | v2.1-cli |
67
- | **v2.1-recheck-cron** ✅ | daily re-check launchd — 전체 approved spec 재 query → 새 CVE/KEV/provider-skip 시 revoke + macOS 알림. | v2.1-providers, v2.1-ledger |
68
- | **v2.1-tests** ✅ | end-to-end 테스트 — fixture provider 응답 → 명령 시뮬레이션 → ledger / hook / re-check / migration 동작 검증. | 모든 v2.1 |
69
- | **v2.1-release** | npm package publish (`@aldegad/safedeps`) + GitHub release v2.1.0. | 모든 v2.1 |
40
+ ### Milestones (all shipped)
70
41
 
71
- ### 2026-05-18 릴리즈 정리 메모
42
+ | Milestone | Output |
43
+ |---|---|
44
+ | `v2.0-doc` | `ARCHITECTURE.md` v2 written and pushed. |
45
+ | `v2.1-rename` | Repo / skill id / paths renamed to `safedeps`; `safedeps migrate` moves legacy `~/.npm-reorg-guard` state to `~/.safedeps` and cleans up legacy hooks. |
46
+ | `v2.1-providers` | `lib/providers/` — OSV / KEV / GHSA adapters behind one query interface, with a 24h response cache. |
47
+ | `v2.1-ledger` | `lib/ledger/` — approved-spec JSON I/O (atomic write, hash, TTL check). |
48
+ | `v2.1-cli` | `bin/safedeps` — `check`, `ledger`, `revoke`, `re-check`, `migrate`, `version` subcommands. |
49
+ | `v2.1-guard-patch` | `safedeps-pre-guard.sh` — ledger enforcement on top of the v1 pattern blocks. |
50
+ | `v2.1-verify-patch` | `safedeps-post-verify.sh` — lockfile-diff comparison against the approved spec on top of the v1 reorg. |
51
+ | `v2.1-multi-ecosystem` | pip / cargo / go / gem / maven / nuget command parsing + lockfile snapshots, shared as rollback truth across both hooks. |
52
+ | `v2.1-hook-rename` | Hook file namespacing + cross-engine installer (`install-safedeps-hooks.mjs`, idempotent, `--uninstall`). |
53
+ | `v2.1-recheck-cron` | Daily re-check LaunchAgent — re-queries every approved spec, revokes + notifies on new CVE/KEV/provider-skip. |
54
+ | `v2.1-tests` | End-to-end tests — fixture provider responses drive ledger / hook / re-check / migration checks. |
55
+ | `v2.1-release` | npm publish (`@aldegad/safedeps`) + GitHub release. |
72
56
 
73
- - npm package metadata 는 v2.1.0 기준으로 정합화한다 (`package.json` version + `bin.safedeps`).
74
- - `npm test` 는 release smoke suite 를 실행한다. full fixture E2E 는 `v2.1-tests` 후속으로 남긴다.
75
- - daily re-check 는 토큰을 쓰지 않는다. 알렉스가 opt-in 하면 macOS `launchd` user agent 로 `safedeps re-check --json` 을 매일 실행하는 구조가 기본이다. 네트워크는 OSV/CISA/GHSA provider query 에만 사용된다.
76
- - 실제 local background job 은 `scripts/install/install-safedeps-recheck-agent.mjs` 로 atomic install 한다. wrapper 는 `~/.safedeps/recheck.log` 와 `~/.safedeps/recheck-alerts.jsonl` 를 쓰고, 새 CVE/KEV/revoke/provider-skip 이 있으면 macOS notification 을 띄운다.
57
+ ### Release notes
77
58
 
78
- ### 후속 로드맵 전체 workspace inventory audit
59
+ - The npm package version in `package.json` is the single source of truth. `bin/safedeps` `SAFEDEPS_VERSION` tracks it and the smoke test reads `package.json` to compare (current: v2.2.0).
60
+ - `npm test` runs the release smoke suite; the full fixture E2E lives under `v2.1-tests`.
61
+ - The daily re-check uses no LLM tokens. It is opt-in: a macOS `launchd` user agent runs `safedeps re-check --json` daily, installed atomically by `install-safedeps-recheck-agent.mjs`. It writes `~/.safedeps/recheck.log` and `~/.safedeps/recheck-alerts.jsonl` and raises a macOS notification on a new CVE/KEV/revoke/provider-skip. Network is used only for OSV / CISA / GHSA queries.
79
62
 
80
- 전체 repo/lockfile inventory scan 은 safedeps v2.1 daily re-check 분리한다. 후보 설계는 최초 one-shot inventory scan 으로 workspace 의 manifest/lockfile 을 발견하고, 사용자가 채택한 spec 만 approved ledger 또는 별도 inventory ledger 에 넣은 뒤 주기 re-check 대상으로 삼는 방식이다. 이렇게 해야 safedeps 의 현재 책임인 install approval gate 와 이미 디스크에 존재하는 dependency audit 의 책임 소재가 섞이지 않는다.
63
+ ## v2.2 effect-based enforcement (npm)
81
64
 
82
- ### 우선순위
65
+ Status: shipped as v2.2.0 (npm-first).
83
66
 
84
- 1. v2.1-release: commit / tag / GitHub release / npm publish.
67
+ ### What changed
85
68
 
86
- ---
69
+ - **Authority moved to effects**: PostToolUse now reads the actual `package-lock.json` closure and compares every installed `pkg@version` against approved direct specs plus their `transitive_specs`.
70
+ - **Full closure approval for npm**: `safedeps check npm <pkg>@<version>` resolves a script-free lockfile in a temp dir with `npm install --package-lock-only --ignore-scripts`, extracts the full closure, and queries OSV `/v1/querybatch`.
71
+ - **Batch + cache**: OSV batch responses are written back into the same per `pkg@version` 24h cache used by single-package provider queries.
72
+ - **No blind trust for transitives**: a clean direct package with an unapproved or vulnerable transitive dependency is not enough; the full closure must be clean and recorded.
73
+ - **PreToolUse demoted to fast UX guard**: command parsing still blocks obvious unapproved install attempts and keeps the bypass regression coverage, but PostToolUse is the primary enforcement surface.
74
+ - **Inert install (Claude Code)**: the PreToolUse hook rewrites an npm install to add `--ignore-scripts` via the hook `updatedInput` capability, so the install runs inert; PostToolUse runs `npm rebuild` only after the closure is verified clean, so a rejected package's lifecycle scripts never run. Codex CLI lacks `updatedInput`, so it stays on detect-and-rollback.
87
75
 
88
- ## v3 (미래 — 알렉스 결정 시점)
76
+ ### npm-only boundary
89
77
 
90
- - **plugin model** 사용자 정의 provider (회사 내부 vuln DB, private registry).
91
- - **policy file** — `.safedeps.toml` 로 \"우리 팀 정책: KEV hit 자동 block, CVSS 7+ 사용자 컨펌, 특정 패키지 allowlist\" 명시.
92
- - **CI mode** — `safedeps check --ci` 로 GitHub Actions / CircleCI fail-fast.
93
- - **transitive risk score** — deps.dev graph 통합. 직접 dep 만 아니라 transitive dep 의 \"위험 점수\" 시각화.
78
+ This phase covers npm lockfile closure only. pip / cargo / go / gem / maven / nuget keep the v2.1 command/ledger/reorg behavior until each ecosystem has an explicit closure resolver and script/no-execution policy.
94
79
 
95
- ---
80
+ ### Verification
81
+
82
+ - closure approval records `transitive_specs`
83
+ - unapproved transitive package in `package-lock.json` triggers post-verify reorg
84
+ - approved full-closure install passes without false reorg
85
+ - heredoc / echo text does not trigger install detection
86
+ - existing smoke + fixture E2E regression suite remains green
96
87
 
97
- ## v4+ (장기)
88
+ ### Current focus
98
89
 
99
- - **team-shared ledger** — multi-machine approved spec sync (회사 dev 모두가 같은 ledger 공유).
100
- - **AI agent integration** — Claude / Codex 가 vuln 발견 시 \"대체 모듈 X 권장\" 직접 제안 (LLM-as-judge).
101
- - **diff visualization UI** — 두 approved spec snapshot 사이의 dep tree diff 시각화.
90
+ 1. `v2.2.0-release`: merge `safedeps-security-hardening`, tag `v2.2.0`, GitHub release, `npm publish`.
102
91
 
103
92
  ---
104
93
 
105
- ## 명시적 NON-GOAL (이 도구는 하지 않는다)
94
+ ## v3 (future)
106
95
 
107
- - **OS-level CVE 감시** (nginx, apt 패키지, system binary). → 별도 도구 `infra-cve-monitor` 결로 분리.
108
- - **컨테이너 이미지 스캔**. → Trivy / Grype.
109
- - **runtime 권한 sandbox**. → lavamoat / firejail.
110
- - **registry 자체의 손상 감지**. → registry 운영사 책임.
111
- - **사용자 평판 분석 (behavioral)**. → socket.dev.
96
+ ### Ledger tamper resistance
112
97
 
113
- safedeps = **\"개발 의존성 install 단계의 advisory + spec gate + rollback\"** 줄. 다른 결로 확장하지 않는다 SRP 측면 다른 도구로 분리.
98
+ Defends the second-order attack where a malicious package's `postinstall` (running as the user) forges a "B approved" ledger entry so a later install of B skips the advisory check. The package cannot do this *before* it runs, so closing the install-time gate is the first line of defense; this hardens the case where a first compromise already happened.
114
99
 
115
- ---
100
+ Approach — **treat OSV as the authority and the ledger as a cache**, plus tamper detection. Cheap, layers onto existing infra:
101
+
102
+ 1. **Re-validate at enforcement / re-check** — verify the stored evidence against OSV instead of trusting the ledger verdict. A forged entry with no real evidence (or for a package OSV reports as vulnerable) is caught and revoked. Reduces the ledger to memoization with OSV as SSoT.
103
+ 2. **Watch `~/.safedeps/` in the post-install scan** — the post-verify hook already flags `postinstall` scripts that touch `~/.ssh` / `.env`; add `~/.safedeps/` so a package that writes the ledger trips a reorg — catching the forge in the act.
104
+ 3. **Provenance cross-check in daily re-check** — flag ledger entries with no matching `advisory.log` record (i.e. no real `safedeps check` ever ran) as suspected forgeries.
105
+
106
+ Explicit non-approach: **cryptographic ledger signing is not pursued** — a same-uid attacker can read the signing key and re-sign forgeries, so a local HMAC/signature adds no real boundary. The defense is authority-elsewhere (OSV) + detection, not local secrets.
107
+
108
+ ### Other v3 work
116
109
 
117
- ## 관련 미래 도구 (분리 권장)
110
+ - **Plugin providers** user-defined advisory sources (internal vuln DB, private registry).
111
+ - **Policy file** — `.safedeps.toml` for team policy (auto-block on KEV hit, user confirm on CVSS 7+, per-package allowlist).
112
+ - **CI mode** — `safedeps check --ci` for fail-fast in GitHub Actions / CircleCI.
113
+ - **Closure expansion beyond npm** — pip / cargo / go / gem / maven / nuget closure resolvers with explicit no-script/no-build policies.
114
+ - **Transitive risk score** — deps.dev graph integration; risk visualization beyond direct dependencies.
118
115
 
119
- | 도구 | 결 | 관계 |
120
- |---|---|---|
121
- | `safedeps` (이것) | dev 의존성 (npm/pip/cargo/...) install 단계 | 현재 작업 |
122
- | `infra-cve-monitor` (가칭) | nginx / apt / OS package 주기적 audit + RSS 알람 | 미래 별 도구 |
123
- | `container-scan-bridge` (가칭) | Trivy / Grype wrapper, 컨테이너 이미지 결 | 미래 별 도구 |
116
+ ## v4+ (long-term)
124
117
 
125
- 도구가 같은 (\"보안\") 다른 layer. 한 skill 에 통합하지 않고 분리.
118
+ - **Team-shared ledger** multi-machine approved-spec sync.
119
+ - **Agent remediation** — Claude / Codex suggests a safer replacement when a vuln is found (LLM-as-judge).
120
+ - **Diff visualization** — dependency-tree diff between two approved-spec snapshots.
126
121
 
127
122
  ---
128
123
 
129
- ## 변경 history
124
+ ## History
130
125
 
131
- - 2026-05-18: ROADMAP.md 최초 작성. v1 → v2 결정 + v3 / v4 / NON-GOAL 명시. (코덱시 surface:195 합의 + 클로디시 surface:61 작성.)
126
+ - 2026-05-18: Initial ROADMAP v1 → v2 decision plus v3 / v4 outline.