pi-codex-auto-review 0.1.3 → 0.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/NOTICE +4 -2
- package/README.ko.md +85 -0
- package/README.md +51 -52
- package/dist/approval-commands.d.ts +3 -3
- package/dist/approval-commands.js +161 -34
- package/dist/approval-commands.js.map +1 -1
- package/dist/approval-settings.d.ts +1 -1
- package/dist/approval-settings.js +17 -10
- package/dist/approval-settings.js.map +1 -1
- package/dist/approvals.d.ts +10 -9
- package/dist/approvals.js +196 -75
- package/dist/approvals.js.map +1 -1
- package/dist/audit.d.ts +1 -1
- package/dist/audit.js +37 -13
- package/dist/audit.js.map +1 -1
- package/dist/cli.js +63 -34
- package/dist/cli.js.map +1 -1
- package/dist/context-files.d.ts +2 -2
- package/dist/context-files.js +40 -19
- package/dist/context-files.js.map +1 -1
- package/dist/contracts.d.ts +39 -39
- package/dist/contracts.js +117 -51
- package/dist/contracts.js.map +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +147 -43
- package/dist/index.js.map +1 -1
- package/dist/pi-host.js +3 -3
- package/dist/pi-host.js.map +1 -1
- package/dist/policy/domains.js +17 -7
- package/dist/policy/domains.js.map +1 -1
- package/dist/policy/index.d.ts +7 -7
- package/dist/policy/index.js +382 -139
- package/dist/policy/index.js.map +1 -1
- package/dist/policy/paths.js +31 -18
- package/dist/policy/paths.js.map +1 -1
- package/dist/policy/rule-engine.d.ts +2 -0
- package/dist/policy/rule-engine.js +283 -0
- package/dist/policy/rule-engine.js.map +1 -0
- package/dist/policy/rule-types.d.ts +30 -0
- package/dist/policy/rule-types.js +2 -0
- package/dist/policy/rule-types.js.map +1 -0
- package/dist/policy/rules-sync.d.ts +1 -0
- package/dist/policy/rules-sync.js +14 -0
- package/dist/policy/rules-sync.js.map +1 -0
- package/dist/policy/rules-worker.d.ts +1 -0
- package/dist/policy/rules-worker.js +14 -0
- package/dist/policy/rules-worker.js.map +1 -0
- package/dist/policy/rules.d.ts +4 -31
- package/dist/policy/rules.js +126 -38
- package/dist/policy/rules.js.map +1 -1
- package/dist/policy/shell.js +70 -41
- package/dist/policy/shell.js.map +1 -1
- package/dist/policy/starlark/builtins.d.ts +6 -0
- package/dist/policy/starlark/builtins.js +764 -0
- package/dist/policy/starlark/builtins.js.map +1 -0
- package/dist/policy/starlark/evaluator.d.ts +18 -0
- package/dist/policy/starlark/evaluator.js +518 -0
- package/dist/policy/starlark/evaluator.js.map +1 -0
- package/dist/policy/starlark/lexer.d.ts +14 -0
- package/dist/policy/starlark/lexer.js +189 -0
- package/dist/policy/starlark/lexer.js.map +1 -0
- package/dist/policy/starlark/parser.d.ts +140 -0
- package/dist/policy/starlark/parser.js +508 -0
- package/dist/policy/starlark/parser.js.map +1 -0
- package/dist/policy/starlark/validation.d.ts +4 -0
- package/dist/policy/starlark/validation.js +183 -0
- package/dist/policy/starlark/validation.js.map +1 -0
- package/dist/policy/starlark/values.d.ts +46 -0
- package/dist/policy/starlark/values.js +363 -0
- package/dist/policy/starlark/values.js.map +1 -0
- package/dist/reports.d.ts +1 -1
- package/dist/reports.js +66 -30
- package/dist/reports.js.map +1 -1
- package/dist/review/context.d.ts +16 -3
- package/dist/review/context.js +254 -48
- package/dist/review/context.js.map +1 -1
- package/dist/review/investigation.d.ts +2 -2
- package/dist/review/investigation.js +57 -16
- package/dist/review/investigation.js.map +1 -1
- package/dist/review/lifecycle.d.ts +1 -1
- package/dist/review/lifecycle.js +72 -29
- package/dist/review/lifecycle.js.map +1 -1
- package/dist/review/policy.js +27 -5
- package/dist/review/policy.js.map +1 -1
- package/dist/review/upstream-policy.js +1 -1
- package/dist/review/upstream-policy.js.map +1 -1
- package/dist/review/user-input.d.ts +5 -0
- package/dist/review/user-input.js +54 -0
- package/dist/review/user-input.js.map +1 -0
- package/dist/reviewer.d.ts +16 -6
- package/dist/reviewer.js +258 -70
- package/dist/reviewer.js.map +1 -1
- package/dist/signals.js +24 -9
- package/dist/signals.js.map +1 -1
- package/dist/startup.d.ts +4 -4
- package/dist/startup.js +139 -41
- package/dist/startup.js.map +1 -1
- package/dist/tools/controller.d.ts +19 -13
- package/dist/tools/controller.js +460 -118
- package/dist/tools/controller.js.map +1 -1
- package/dist/tools/environment.d.ts +1 -0
- package/dist/tools/environment.js +5 -0
- package/dist/tools/environment.js.map +1 -1
- package/dist/tools/executor.d.ts +1 -1
- package/dist/tools/executor.js +45 -28
- package/dist/tools/executor.js.map +1 -1
- package/dist/tools/external.d.ts +9 -8
- package/dist/tools/external.js +22 -11
- package/dist/tools/external.js.map +1 -1
- package/dist/tools/mcp.d.ts +6 -6
- package/dist/tools/mcp.js +208 -79
- package/dist/tools/mcp.js.map +1 -1
- package/dist/tools/mutation-queue.js.map +1 -1
- package/docs/publishing.ko.md +114 -0
- package/docs/publishing.md +49 -47
- package/docs/security/dependencies.ko.md +54 -0
- package/docs/security/dependencies.md +27 -26
- package/docs/testing/auto-review-protection.ko.md +158 -0
- package/docs/testing/auto-review-protection.md +105 -97
- package/docs/usage.ko.md +242 -0
- package/docs/usage.md +127 -111
- package/package.json +106 -95
- package/dist/native/darwin-arm64/artifact.json +0 -5
- package/dist/native/darwin-arm64/pi-guard-execpolicy +0 -0
- package/dist/native/linux-x64/artifact.json +0 -5
- package/dist/native/linux-x64/pi-guard-execpolicy +0 -0
- package/native/execpolicy/LICENSE +0 -201
- package/native/execpolicy/NOTICE +0 -6
package/docs/publishing.md
CHANGED
|
@@ -1,75 +1,77 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Publishing to npm
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**English** | [한국어](publishing.ko.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Choose a version in `pnpm release` and confirm the commit, tag, and push. GitHub Actions then builds and verifies the JavaScript package and publishes to npm. The local command does not use npm credentials. Version `0.2.0` uses this JavaScript-only workflow; the published `0.1.4` still contains the earlier native executables.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## One-time setup
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
### Source and dependencies
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Commit release configuration, scripts, package changes, and workflows to `master`, and push them to the remote repository. The release branch must track `origin/master`. The release command stops if the working tree or index has changes.
|
|
12
|
+
|
|
13
|
+
Use a terminal with Node.js 24.14.0 and pnpm 10 available. Install dependencies from the repository root.
|
|
12
14
|
|
|
13
15
|
```sh
|
|
14
16
|
npm ci --ignore-scripts
|
|
15
17
|
```
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
Dependency installation and CI builds use the existing `package-lock.json`. `pnpm` serves as the entry point for the release script; it does not switch installation to `pnpm-lock.yaml`. The current package does not bundle sandbox dependencies and uses the Pi host as a peer dependency.
|
|
18
20
|
|
|
19
21
|
### npm Trusted Publisher
|
|
20
22
|
|
|
21
|
-
|
|
23
|
+
Add a GitHub Actions connection in **Settings → Trusted publishing** for `pi-codex-auto-review` on npm.
|
|
22
24
|
|
|
23
|
-
|
|
|
24
|
-
|
|
25
|
+
| Field | Value |
|
|
26
|
+
| --- | --- |
|
|
25
27
|
| Organization or user | `buYoung` |
|
|
26
28
|
| Repository | `pi-codex-auto-review` |
|
|
27
29
|
| Workflow filename | `npm-package.yml` |
|
|
28
|
-
| Environment name |
|
|
29
|
-
| Allowed actions |
|
|
30
|
+
| Environment name | Leave empty |
|
|
31
|
+
| Allowed actions | Allow direct publishing with `npm publish` |
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
Enter only the workflow filename, without the `.github/workflows/` path. Allowing only the default `npm stage publish` permission causes this workflow's direct publishing to fail.
|
|
32
34
|
|
|
33
|
-
|
|
35
|
+
The publish job has `id-token: write` permission and checks for npm 11.5.1 or later. It uses OIDC authentication issued by a GitHub-hosted runner, so do not add `NPM_TOKEN` as a GitHub Secret. npm does not validate the connection when it is saved; confirm it during the first actual publish. See the [official npm Trusted Publishing guide](https://docs.npmjs.com/trusted-publishers/).
|
|
34
36
|
|
|
35
|
-
##
|
|
37
|
+
## Version selection and release
|
|
36
38
|
|
|
37
|
-
|
|
39
|
+
Run after committing changes on `master`.
|
|
38
40
|
|
|
39
41
|
```sh
|
|
40
42
|
pnpm release
|
|
41
43
|
```
|
|
42
44
|
|
|
43
|
-
1.
|
|
44
|
-
2.
|
|
45
|
-
3. `v
|
|
46
|
-
4. `master
|
|
45
|
+
1. Review the current version and concrete next versions, then select one. For a release from `0.1.1` to `0.1.2`, choose **patch**. If no local version tag exists, **현재 준비 버전 출시** (release the currently prepared version) is also available.
|
|
46
|
+
2. Confirm the commit and create a release commit. Releasing the current version unchanged creates an empty commit to record the release.
|
|
47
|
+
3. Confirm creation of the `v<version>` tag and create an annotated tag.
|
|
48
|
+
4. Confirm pushing `master` and that tag. Approval pushes both references atomically and starts npm publishing in Actions.
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
Each confirmation defaults to approval. Entering `n` or pressing `Ctrl+C` stops that operation and all later steps. Skipping questions through `--ci`, version arguments, or automatic answers is unsupported.
|
|
49
51
|
|
|
50
|
-
|
|
52
|
+
Version selection does not automatically apply a version such as `0.1.2`. release-it updates versions in `package.json` and `package-lock.json` without running npm version lifecycle scripts. The local process does not rebuild the package or publish to npm.
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
An npm version cannot be published again. If the currently prepared version has already been published, choose a higher version. Prereleases use npm's `next` tag; stable releases use `latest`.
|
|
53
55
|
|
|
54
|
-
## GitHub Actions
|
|
56
|
+
## What GitHub Actions does
|
|
55
57
|
|
|
56
|
-
`v*`
|
|
58
|
+
Pushing a `v*` tag starts `.github/workflows/npm-package.yml`.
|
|
57
59
|
|
|
58
|
-
1.
|
|
59
|
-
2.
|
|
60
|
-
3. npm
|
|
61
|
-
4.
|
|
62
|
-
5.
|
|
60
|
+
1. Install the official development dependencies from the npm lockfile on `ubuntu-22.04`.
|
|
61
|
+
2. Check that the tag matches the version in `package.json` and that the tagged commit is included in `origin/master`, then build TypeScript and run policy tests, including the captured Codex result corpus.
|
|
62
|
+
3. The `npm pack` prepack step compiles TypeScript, checks required files, and exercises the JavaScript rule worker. It removes obsolete sandbox/native output and rejects archives containing native binaries, `.node` or `.wasm` files, or bundled dependencies.
|
|
63
|
+
4. Save the verified `pi-codex-auto-review-<version>.tgz` in the `npm-package` artifact.
|
|
64
|
+
5. A separate publish job downloads that same artifact and publishes it to npm through OIDC.
|
|
63
65
|
|
|
64
|
-
**Actions → npm 배포 → Run workflow
|
|
66
|
+
Running **Actions → npm 배포 → Run workflow** manually prepares the archive only and skips publishing. For tag publishing, use a tag-triggered run of the same workflow.
|
|
65
67
|
|
|
66
|
-
|
|
68
|
+
One JavaScript archive serves all platforms; it has no rule-engine CPU or libc dependency. Actual Pi availability, path behavior, and shell support still depend on the host. The separate OS workflow retains Linux and Windows execution checks without installing Rust. Follow the [verification guide](testing/auto-review-protection.md) for the executed scope.
|
|
67
69
|
|
|
68
|
-
##
|
|
70
|
+
## After cancellation or failure
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
When the local command exits, it reports file and index changes, current HEAD, local tags, and push attempt status. Rejecting a prompt or cancelling preserves version, index, commit, and tag changes already made.
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
After a failed push, release-it may attempt to clean up remote tags. Do not infer remote state from that output alone; check the following results.
|
|
73
75
|
|
|
74
76
|
```sh
|
|
75
77
|
git status --short
|
|
@@ -77,24 +79,24 @@ git log -1
|
|
|
77
79
|
git ls-remote origin refs/heads/master 'refs/tags/v*'
|
|
78
80
|
```
|
|
79
81
|
|
|
80
|
-
|
|
82
|
+
If Actions fails after the tag push, inspect that run's logs and rerun the failed job. First check whether npm publishing actually succeeded. Do not repeat a published version; use a new version for new changes.
|
|
81
83
|
|
|
82
|
-
##
|
|
84
|
+
## Checking publication and Pi installation
|
|
83
85
|
|
|
84
|
-
`0.
|
|
86
|
+
After publishing `0.2.0`, verify with these commands.
|
|
85
87
|
|
|
86
88
|
```sh
|
|
87
|
-
npm view pi-codex-auto-review@0.
|
|
88
|
-
pi install npm:pi-codex-auto-review@0.
|
|
89
|
+
npm view pi-codex-auto-review@0.2.0 version --registry=https://registry.npmjs.org/
|
|
90
|
+
pi install npm:pi-codex-auto-review@0.2.0
|
|
89
91
|
pi list
|
|
90
92
|
pi
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
For later releases, replace the version with the one selected. `0.1.2` uses the earlier sandbox structure; `0.1.3` removes the sandbox and adds approval settings commands. `0.1.4` improves English approval descriptions, model scope integration, user reapproval, and review context passing and restoration. `0.2.0` replaces the Rust rule engine with TypeScript compiled to JavaScript and removes the repackaged development SDK. After installation, check `/approve`'s English descriptions, `/approve-model`'s `/scoped-models` integration, and that saved choices survive a restart. See the [usage guide](usage.md) for settings files and the SDK entry point.
|
|
94
96
|
|
|
95
|
-
##
|
|
97
|
+
## Preparing an archive locally
|
|
96
98
|
|
|
97
|
-
|
|
99
|
+
Use this when you need to inspect the publishable archive directly. Install the development dependencies first; no platform artifacts are required.
|
|
98
100
|
|
|
99
101
|
```sh
|
|
100
102
|
npm run build
|
|
@@ -102,11 +104,11 @@ mkdir -p tmp/npm-release
|
|
|
102
104
|
npm pack --pack-destination tmp/npm-release
|
|
103
105
|
```
|
|
104
106
|
|
|
105
|
-
`npm run build
|
|
107
|
+
`npm run build` creates the JavaScript modules and rule evaluation entry points. Prepack verifies their inclusion and rejects leftover native artifacts. Do not skip prepack with `--ignore-scripts` when preparing an actual release.
|
|
106
108
|
|
|
107
|
-
##
|
|
109
|
+
## References
|
|
108
110
|
|
|
109
111
|
- [release-it 21.0.1](https://github.com/release-it/release-it/tree/21.0.1)
|
|
110
112
|
- [npm Trusted Publishing](https://docs.npmjs.com/trusted-publishers/)
|
|
111
|
-
- [GitHub-hosted runner
|
|
112
|
-
- [Pi
|
|
113
|
+
- [GitHub-hosted runner types](https://docs.github.com/en/actions/reference/runners/github-hosted-runners)
|
|
114
|
+
- [Pi package registration](https://github.com/earendil-works/pi/blob/v0.99.1/packages/coding-agent/docs/packages.md)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# 의존성 보안 수정
|
|
2
|
+
|
|
3
|
+
[English](dependencies.md) | **한국어**
|
|
4
|
+
|
|
5
|
+
현재 소스는 `@anthropic-ai/sandbox-runtime`, 그 하위 `node-forge`, `bundleDependencies`를 제거했다. 배포 패키지에 `node_modules`를 포함하지 않으며 Pi 호스트는 peer dependency로 사용한다. 설치된 Pi의 의존성을 이 확장이 교체하지 않는다.
|
|
6
|
+
|
|
7
|
+
## 0.1.3 배포 전 감사
|
|
8
|
+
|
|
9
|
+
2026-10-04 잠금 파일 기준으로 `npm audit --omit=dev --audit-level=high`는 취약점 0건이다. 개발 의존성을 포함한 `npm audit --audit-level=high`는 `release-it 21.0.1`의 `basic-ftp`·`undici` 하위 의존성과 그 상위 경로에서 높은 심각도 6건을 보고했다. 이 개발 도구들은 배포 압축 파일에 포함되지 않는다.
|
|
10
|
+
|
|
11
|
+
`npm audit fix --force`가 제안하는 조치는 `release-it 20.2.0`으로의 주요 버전 변경이므로 이번 릴리스에서 적용하지 않았다. 개발 도구의 감사 항목은 미해결로 남기며, 배포 의존성의 감사 통과와 구분한다.
|
|
12
|
+
|
|
13
|
+
## 이전 샌드박스 버전의 조치 기록
|
|
14
|
+
|
|
15
|
+
아래는 샌드박스 제거 전의 기록이다. 당시 높은 심각도 3개 감사 항목을 조치했고, 설치된 `node-forge 1.4.1-0`, `brace-expansion 5.0.12`와 감사 0건을 기록했다. 현재 개발 의존성 전체의 감사 결과를 뜻하지 않는다. 원래 근거는 [보안 인계](https://github.com/buYoung/pi-codex-auto-review/blob/HEAD/docs/handoffs/auto-review/11-dependency-security.json)에 보존한다.
|
|
16
|
+
|
|
17
|
+
| 항목 | 적용한 수정 | 배포 상태 |
|
|
18
|
+
| --- | --- | --- |
|
|
19
|
+
| `node-forge` 및 이를 사용하는 `sandbox-runtime` | RSA `DigestAlgorithm`의 추가 요소를 거부하는 [수정 PR](https://github.com/digitalbazaar/forge/pull/1152)의 커밋 `ceba34402e329f0365134f23fe19898756527d65`을 고정 | **미병합 개발 버전**이다. 공식 수정 릴리스로 표현하지 않는다. 기존 1.4.0 대비 라이브러리 코드 변경은 RSA 검증부 한 곳이다. |
|
|
20
|
+
| `brace-expansion` | 공식 수정 버전 `5.0.12` 사용 | [공식 보안 공지](https://github.com/advisories/GHSA-q2hr-2g5m-vwhr)에 기재된 수정 버전이다. |
|
|
21
|
+
|
|
22
|
+
당시 `node-forge`는 [공식 공지](https://github.com/advisories/GHSA-86w9-cpqp-85rv)에 수정 릴리스가 없다고 표시돼 있었다. 버전 문자열을 임의로 올리거나 감사를 억제하지 않았다. 실제 패치 소스를 고정하고 정상 PKCS#1·PSS 서명, 네이티브 암호 모듈이 거부하는 변형 서명을 함께 검사했다.
|
|
23
|
+
|
|
24
|
+
## Pi 패키지의 잠금 보정
|
|
25
|
+
|
|
26
|
+
공식 Pi 0.99.1의 `npm-shrinkwrap.json`은 `brace-expansion 5.0.9`를 고정한다. 이전 조치에서는 당시 확인한 설치 경로에서 루트 보정이 유지되지 않아 개발용 아카이브를 재포장했다. 이 우회 구성은 0.1.4까지 포함돼 있었다.
|
|
27
|
+
|
|
28
|
+
현재 소스는 **공식 `@earendil-works/pi-coding-agent@0.99.1`을 직접 사용**하고 레지스트리 무결성 값을 `package-lock.json`에 기록한다. 루트 보정과 커밋된 의존성 잠금으로 `brace-expansion 5.0.12`를 유지한다. 별도 디렉터리의 깨끗한 `npm ci --ignore-scripts`에서 공식 SDK와 해당 버전이 설치됐고, `npm install --package-lock-only --ignore-scripts`로 잠금을 갱신해도 유지됐다. 기존 의존성 보안 검사 2개도 통과했다. SDK API 버전은 그대로이며 `vendor` 아카이브·메타데이터·재포장 스크립트는 제거했다.
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
npm ci --ignore-scripts
|
|
32
|
+
npm ls brace-expansion --all
|
|
33
|
+
npm run build
|
|
34
|
+
npm run test:contracts
|
|
35
|
+
npm audit --json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Docker와 CI도 같은 잠금 파일로 `npm ci`를 실행한다. SDK 아카이브 생성이나 설치 중 패치는 필요하지 않다. 의존성을 갱신하면 실제 설치 버전을 확인하고 보안 회귀 검사를 다시 수행한다. 이전 아카이브의 출처 기록은 [0.1.4 소스](https://github.com/buYoung/pi-codex-auto-review/blob/v0.1.4/vendor/pi-sdk-security.json)에 보존돼 있다.
|
|
39
|
+
|
|
40
|
+
## 확인한 결과
|
|
41
|
+
|
|
42
|
+
- 수정 전 정상 서명은 통과했으나 변형 서명이 `true`로 승인됐다. 중괄호 확장 입력은 5초 제한으로 중단됐다.
|
|
43
|
+
- 수정 후 정상 서명은 유지되고 변형 서명은 거부됐다. 같은 중괄호 입력도 제한 안에 완료됐다.
|
|
44
|
+
- 기존 계약·Pi 통합·네이티브 격리·패키지 실행을 합친 로컬 검증 58개가 통과했다. 플랫폼 전체 집계와 실모델 재검증은 후속 기능 변경을 합친 최종 소스에서 수행한다.
|
|
45
|
+
|
|
46
|
+
이 보정은 저장소의 잠금 파일로 설치한 환경에 적용된다. 별도로 설치된 Pi 호스트나 다른 프로젝트의 의존성을 자동으로 바꾸지는 않는다. 다른 환경에서는 실제로 해석되는 의존성과 해당 환경의 감사 결과를 별도로 확인해야 한다.
|
|
47
|
+
|
|
48
|
+
## 현재 npm 배포
|
|
49
|
+
|
|
50
|
+
설치된 의존성의 `overrides`는 소비자 프로젝트에 적용되지 않고 `package-lock.json`도 게시되지 않는다. 이전 패키지에 묶었던 샌드박스 런타임은 현재 소스에서 제거했다. 게시 전 검사는 샌드박스 코드와 `node_modules`가 압축 파일에 남지 않는지 확인한다.
|
|
51
|
+
|
|
52
|
+
Pi 호스트는 `peerDependencies`로 유지하고 묶지 않는다. 저장소의 개발용 잠금 파일은 별도로 설치된 Pi의 `brace-expansion` 버전을 변경하거나 보장하지 않는다.
|
|
53
|
+
|
|
54
|
+
저장소 루트에서 `npm pack`을 실행하면 게시 전 검사가 적용된다. 현재 소스는 Rust 컴파일러나 플랫폼별 실행 파일 없이 JavaScript를 빌드·패키징한다. 소비자 설치에도 보안 보정을 위한 설치 스크립트를 요구하지 않는다. [배포 안내](../publishing.ko.md)를 따른다.
|
|
@@ -1,53 +1,54 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Dependency security fixes
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**English** | [한국어](dependencies.ko.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The current source removes `@anthropic-ai/sandbox-runtime`, its transitive `node-forge` dependency, and `bundleDependencies`. The distribution does not include `node_modules` and uses the Pi host as a peer dependency. This extension does not replace dependencies in an installed Pi host.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Audit before the 0.1.3 release
|
|
8
8
|
|
|
9
|
-
`npm audit
|
|
9
|
+
For the lockfile dated 2026-10-04, `npm audit --omit=dev --audit-level=high` reported zero vulnerabilities. Including development dependencies, `npm audit --audit-level=high` reported six high-severity findings in `release-it 21.0.1`'s transitive `basic-ftp` and `undici` dependencies and their parent paths. These development tools are not included in the distribution archive.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
The action proposed by `npm audit fix --force` changes the major version to `release-it 20.2.0`, so it was not applied in this release. Development tool findings remain unresolved and are separate from the passing production dependency audit.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Remediation record for the earlier sandbox version
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
The following record predates sandbox removal. At that time, three high-severity audit findings were addressed, with installed versions `node-forge 1.4.1-0` and `brace-expansion 5.0.12` and zero audit findings recorded. It does not describe the current audit of all development dependencies. The original evidence is preserved in the [security handoff](https://github.com/buYoung/pi-codex-auto-review/blob/HEAD/docs/handoffs/auto-review/11-dependency-security.json).
|
|
16
|
+
|
|
17
|
+
| Item | Applied fix | Release status |
|
|
16
18
|
| --- | --- | --- |
|
|
17
|
-
| `node-forge`
|
|
18
|
-
| `brace-expansion` |
|
|
19
|
+
| `node-forge` and its `sandbox-runtime` consumer | Pinned commit `ceba34402e329f0365134f23fe19898756527d65` from the [fix PR](https://github.com/digitalbazaar/forge/pull/1152), which rejects extra RSA `DigestAlgorithm` elements | An **unmerged development version**, not an official fixed release. Compared with 1.4.0, library code changed only in RSA verification. |
|
|
20
|
+
| `brace-expansion` | Used official fixed version `5.0.12` | Listed as a fixed version in the [official security advisory](https://github.com/advisories/GHSA-q2hr-2g5m-vwhr). |
|
|
19
21
|
|
|
20
|
-
`node-forge
|
|
22
|
+
At the time of that record, the [official `node-forge` advisory](https://github.com/advisories/GHSA-86w9-cpqp-85rv) listed no fixed release. The version was not arbitrarily increased, and audit findings were not suppressed. The actual patch source was pinned and checked with valid PKCS#1 and PSS signatures and malformed signatures rejected by the native crypto module.
|
|
21
23
|
|
|
22
|
-
## Pi
|
|
24
|
+
## Pi package lock adjustment
|
|
23
25
|
|
|
24
|
-
Pi 0.99.1
|
|
26
|
+
Pi 0.99.1's published `npm-shrinkwrap.json` pins `brace-expansion 5.0.9`. Earlier remediation used a repackaged development archive because the installation paths checked at that time did not retain the root override. That workaround was included through 0.1.4.
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
The current source uses **official `@earendil-works/pi-coding-agent@0.99.1` directly**, with its registry integrity recorded in `package-lock.json`. The root override and committed dependency lock retain `brace-expansion 5.0.12`. A fresh isolated `npm ci --ignore-scripts` installed that version from the official SDK; regenerating the lockfile with `npm install --package-lock-only --ignore-scripts` retained it. Both existing dependency security checks passed. The SDK API version is unchanged, and the `vendor` archive, metadata, and repackaging script have been removed.
|
|
27
29
|
|
|
28
30
|
```sh
|
|
29
|
-
python3 scripts/vendor-pi-sdk.py
|
|
30
|
-
npm install --package-lock-only --ignore-scripts
|
|
31
31
|
npm ci --ignore-scripts
|
|
32
|
+
npm ls brace-expansion --all
|
|
32
33
|
npm run build
|
|
33
34
|
npm run test:contracts
|
|
34
35
|
npm audit --json
|
|
35
36
|
```
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
Docker and CI use the same committed lockfile with `npm ci`; no generated SDK archive or install-time patch is needed. When updating dependencies, check the installed version and run the security regression checks again. The earlier archive's provenance remains available in the [0.1.4 source](https://github.com/buYoung/pi-codex-auto-review/blob/v0.1.4/vendor/pi-sdk-security.json).
|
|
38
39
|
|
|
39
|
-
##
|
|
40
|
+
## Recorded results
|
|
40
41
|
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
42
|
+
- Before the fix, valid signatures passed, but a malformed signature was accepted as `true`. Brace expansion input was stopped by a five-second limit.
|
|
43
|
+
- After the fix, valid signatures still passed and the malformed signature was rejected. The same brace input completed within the limit.
|
|
44
|
+
- Fifty-eight local checks covering contracts, Pi integration, native isolation, and package execution passed. Full platform aggregation and live model revalidation were deferred to the final source incorporating later feature changes.
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
This adjustment applies to environments installed with this repository's lockfile. It does not automatically change dependencies in separately installed Pi hosts or other projects. In other environments, inspect the dependencies actually resolved and that environment's audit results separately.
|
|
46
47
|
|
|
47
|
-
##
|
|
48
|
+
## Current npm distribution
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
An installed dependency's `overrides` do not apply to the consumer project, and `package-lock.json` is not published. The sandbox runtime bundled in the earlier package has been removed from the current source. Prepack checks ensure that sandbox code and `node_modules` are absent from the archive.
|
|
50
51
|
|
|
51
|
-
Pi
|
|
52
|
+
The Pi host remains in `peerDependencies` and is not bundled. This repository's development lockfile does not change or guarantee the `brace-expansion` version of a separately installed Pi.
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
Run `npm pack` from the repository root to apply prepack checks. The current source builds and packages JavaScript without a Rust compiler or platform executable. Consumer installation needs no security patch script. See the [publishing guide](../publishing.md).
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# 자동 검토 보호 경계 검증
|
|
2
|
+
|
|
3
|
+
[English](auto-review-protection.md) | **한국어**
|
|
4
|
+
|
|
5
|
+
이 검증은 **정책 판단, 실제 Pi 도구 결과, 파일·네트워크 효과**를 함께 확인한다. 허용 대조군이 먼저 성공해야 차단 결과도 유효하다. 예외나 오류 메시지만 확인하고 보호 성공으로 판정하지 않는다.
|
|
6
|
+
|
|
7
|
+
현재 소스는 승인 보조 확장이다. OS 격리·네트워크 프록시·재귀 디렉터리 검사를 수행하지 않는다. 승인된 도구는 원래 Pi 실행기를 사용한다. 아래 이전 샌드박스 검증 기록을 현재 실행 구조의 보장으로 사용하지 않는다.
|
|
8
|
+
|
|
9
|
+
## 현재 승인·실행 검증
|
|
10
|
+
|
|
11
|
+
| 대상 | 확인하는 결과 |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `/approve` | Codex 원문 설명·영문 화면·좁은 터미널 줄바꿈, 선택한 승인 방식의 실제 파일 효과와 저장 |
|
|
14
|
+
| `/approve-model` | 현재 `/scoped-models` 범위, 사용 불가·중복 모델 제외, 선택 도중 범위 변경 거부, 실제 Pi 검토자 적용과 주 모델 유지 |
|
|
15
|
+
| 설정 변경 | 동시 선택 병합, 저장 실패 시 기존 설정 유지, 이전 검토의 늦은 승인 차단 |
|
|
16
|
+
| Pi 실행 | 원래 SDK 실행, cwd·환경·출력·시간 제한·취소 신호 유지 |
|
|
17
|
+
| 시작 | 관계없는 탐색 불가 디렉터리가 있어도 전수 탐색 없이 실행 |
|
|
18
|
+
| 보호·거부 | 직접 보호 경로·금지 규칙은 검토 전 거부, 실패·취소·시간 초과는 실행으로 이어지지 않음 |
|
|
19
|
+
| 네트워크 사전 검토 | 스킴 생략·설정 파일·허용 URL과 설정 파일을 함께 쓴 curl 요청도 자동·사용자 검토를 거침. 허용 대조군만 소유한 HTTP 서버에 도달 |
|
|
20
|
+
| TypeScript 규칙 | 고정 Codex 실행 파일의 실제 결과 280건을 재생해 규칙 출력·입력 거부·취소·자원 한도·요청 형식 검증을 확인 |
|
|
21
|
+
| 배포 패키지 | 실제 Pi 로더로 시작하고 압축 파일 안의 동기·작업 스레드 규칙 평가 실행. Rust 결과물·`.node`·샌드박스 결과·묶인 의존성 부재 |
|
|
22
|
+
|
|
23
|
+
검토자·UI를 재생하는 검증은 실제 Pi와 파일 결과를 사용하지만 실모델의 판단 정확도를 증명하지 않는다. 승인된 셸 내부의 간접 파일 접근, 하드링크와 실행 중 네트워크 변경은 OS가 제한하지 않는다. 호출자의 환경은 실행에 유지하고 검토 증거에서만 인증 변수를 제외한다.
|
|
24
|
+
|
|
25
|
+
`verify:guard`는 현재 운영체제의 결과와 소스 해시·감사 기록을 저장한다. 다른 운영체제와 실모델 실행은 별도 결과이며 수행하지 않은 범위를 통과로 표시하지 않는다.
|
|
26
|
+
|
|
27
|
+
승인 설명은 [공식 승인 선택 화면](https://learn.chatgpt.com/docs/security-administration)을 따르고, 검토자 분리·거부 피드백·3회 연속 또는 최근 50회 중 10회 거부 시 중단·취소는 [공식 Auto-review 문서](https://learn.chatgpt.com/docs/sandboxing/auto-review)와 대조한다. 현재 구현은 OS 경계를 강제하지 않으므로 Codex의 샌드박스와 동등한 보안을 보장한다는 의미가 아니다.
|
|
28
|
+
|
|
29
|
+
원본 결과는 [`test/fixtures/execpolicy-reference.json`](../../test/fixtures/execpolicy-reference.json)에 있다. 원본 실행 파일의 리비전·SHA-256과 유니코드 공백·잘못된 유니코드 이스케이프·숫자 변환 경계를 포함한 성공 201건·거부 79건을 기록했다. TS 구현은 공개 비동기 API로 대조하며 테스트와 빌드에 원본 바이너리가 필요하지 않다. POSIX 경로 사례는 Windows 재생에서 제외하고 기존 Windows 전용 경로 검사는 유지한다. 이는 기록된 호환성 사례이며 모든 Starlark 프로그램의 동등성을 증명하는 것은 아니다.
|
|
30
|
+
|
|
31
|
+
## 이전 OS 격리 검증 기록
|
|
32
|
+
|
|
33
|
+
다음 기록은 샌드박스가 있던 `v0.1.2` 및 이전 소스에 관한 것이다. GLM5.3 검증은 SDK 경로 4개와 CLI 1개 사례를 구분했다. 이전 플랫폼 검증은 [운영체제 검증 인계](../handoffs/auto-review/17-platform-qualification.json), 이전 112개 검증은 [이전 보호 경계 인계](../handoffs/auto-review/10-protection-matrix.json)에 보존한다. 새 소스의 실행 결과는 소스 해시가 일치하는 최신 실행 기록으로 확인한다.
|
|
34
|
+
|
|
35
|
+
개선 전 `85008b0` 시점에는 같은 소스의 macOS·실제 Linux x64·네이티브 및 에뮬레이션 Docker가 각각 142개를 통과했다. GLM5.3 네 사례와 Windows의 별도 규칙·사전 거부 검증도 통과했고, 감사 기록 217건과 실모델 로그·보고서 7개의 키 비노출을 확인했다. 이후 전체 검토에서 기존 검사에 없던 결함이 발견됐다. 이 과거 결과는 아래 회귀 사례와 현재 소스의 통과를 대신하지 않는다.
|
|
36
|
+
|
|
37
|
+
이번 전체 개선의 수정 내역, 최종 실행 근거와 남은 플랫폼 조건은 [Pi 실행 개선 인계](../handoffs/auto-review/25-pi-runtime-alignment.md)에 정리했다.
|
|
38
|
+
|
|
39
|
+
### 이전 구조에서 보호되는 경우와 허용되는 경우
|
|
40
|
+
|
|
41
|
+
| 경계 | 허용 대조군 | 차단 또는 검토 대상 | 최종 관찰 |
|
|
42
|
+
| --- | --- | --- | --- |
|
|
43
|
+
| 파일 도구 6종 | 작업 공간의 `read`, `grep`, `find`, `ls`, `write`, `edit` | 절대 보호 경로의 같은 도구 호출 | 도구 오류, 검토자 호출 0회, 보호 파일 불변, 내용 비노출 |
|
|
44
|
+
| 기본 읽기·임시 경로 | 일반 외부 파일 읽기, 기본 임시 경로 쓰기 | 임시 쓰기 루트를 제외한 뒤 같은 쓰기 | 읽기는 유지되고 쓰기는 검토 후 거부 |
|
|
45
|
+
| 읽기 전용 프로필 | 명시적으로 승인한 기존 파일 쓰기 | 승인하지 않은 작업 공간·임시 경로의 형제 파일, 다음 호출 | 승인 파일만 변경되고 나머지 불변 |
|
|
46
|
+
| 검토 중 경로 변경 | 처음 검토한 심볼릭 링크 대상 | 검토 중 다른 형제 경로나 보호 경로로 링크 교체 | 오래된 승인 거부, 세 대상 모두 불변 |
|
|
47
|
+
| 위험·인가 판단 | 높은 위험이라도 충분한 인가가 있는 합성 사례 | 낮은 위험의 명시적 정책 거부, 인가 부족, 최고 위험 | 주 모델에 전달된 도구 결과와 실제 쓰기 일치 |
|
|
48
|
+
| 검토 기술 오류 | 정상 구조의 승인 응답 | 공급자 오류, 잘못된 JSON, 권한 추가 필드 삽입, 시간 초과 | 정책 거부와 구별되는 실패, 파일 불변 |
|
|
49
|
+
| 승인 경로 설정 | 일반 작업 공간 쓰기·셸 출력 | 비활성화한 샌드박스·명령 규칙 승인 범주 | 검토자를 호출하지 않고 거부 |
|
|
50
|
+
| 명령 규칙 | 규칙에 걸리지 않는 정상 명령 | 허용 규칙과 동시에 일치하는 금지 규칙, 중첩 셸 | 직접·중첩 실행 모두 거부, 대상 파일 미생성 |
|
|
51
|
+
| 검토 취소 | 실제 Pi 직접 도구·`codemode`에서 검토 시작 | 검토 중 취소 후 늦게 도착한 승인 | 취소 신호 전달, 쓰기 미실행 |
|
|
52
|
+
| 파일 변조 7종 | 작업 공간의 추가 쓰기·길이 변경·삭제·이동·복사·모드 변경·하드 링크 생성 | 같은 작업의 범위 밖 대상 | 내용·존재·모드·원본 파일을 각각 확인 |
|
|
53
|
+
| 네트워크 목적지 | 허용 와일드카드의 하위 도메인 | 루트 도메인, 비슷한 접미사, 명시적 거부 도메인 | 소유한 서버의 실제 수신 횟수 |
|
|
54
|
+
| HTTP 리다이렉트 | 허용 호스트의 최초 요청 | 거부 호스트로의 리다이렉트 | 최초 요청만 도착하고 거부 대상은 미도달 |
|
|
55
|
+
| 환경변수 | 명시적인 일반 값이 자식 인터프리터에 전달 | 인증·로더·사용자 프록시 변수의 합성 비밀 값 | 자식 환경에 비밀 값 부재, 일반 값 보존 |
|
|
56
|
+
| Docker 프로세스 정리 | `--init`이 종료된 고아 프로세스를 회수 | PID 1이 고아를 회수하지 못하는 컨테이너 | 제한 시간 내 `/proc/<pid>` 소멸, 실패 시 본 검증 진입 차단 |
|
|
57
|
+
| 사전 생성 하드링크 | 모든 이름이 허용 범위 안에 있는 같은 inode | 보호 파일 별칭, 범위 밖 쓰기 별칭, 좁은 승인 파일의 형제 별칭 | 실행 전 차단, 외부 내용 불변; 모든 별칭을 포함한 디렉터리 승인은 허용 |
|
|
58
|
+
| 탐색 불가 디렉터리 | 접근 불가 하위 트리 옆의 정상 파일 쓰기 | 하위 트리의 권한 변경·읽기, 이름을 알면 접근 가능한 미검증 트리 | 접근 불가 트리는 OS 경계에서도 차단; 불완전한 검색 가능 범위는 시작 거부 |
|
|
59
|
+
| HTTPS CONNECT | 합성 인증서를 검증한 소유 서버 요청 | 허용하지 않은 목적지, 신뢰하지 않은 인증서 | 실제 HTTPS 응답과 서버 수신 횟수, 인증 실패 시 HTTP 효과 없음 |
|
|
60
|
+
| SOCKS5·UDP | 허용 SOCKS5 TCP, 호스트의 UDP 대조 요청 | 명시적으로 거부한 SOCKS5 목적지, 샌드박스의 직접 UDP | 허용 TCP만 도달, 직접 UDP 추가 수신 없음 |
|
|
61
|
+
| IPv6 | 동등한 IPv6 표기의 프록시 허용, 실행 중 정확한 목적지 승인 | 명시적 IPv6 거부, 직접 IPv6 통신 | 주소·포트가 검토에 전달되고 허용 요청만 서버 도달 |
|
|
62
|
+
| 원본 `.rules` | Starlark 함수·문자열 보간·대안 인자·실행 파일 경로·네트워크 규칙 | 틀린 예제, 경로 제약 위반, 잘못된 규칙, 취소 | 고정 Codex 엔진의 결과가 실제 정책과 네이티브 설정에 전달 |
|
|
63
|
+
| 자동 컨텍스트 | 신뢰한 루트부터 현재 위치까지의 지침, 전역·파일 우선순위 | 비신뢰 프로젝트, 보호 경로 별칭, 초과 바이트 | 출처와 내용이 Pi·검토자에 전달되며 새로고침 후 갱신 |
|
|
64
|
+
| MCP 최종 실행 | 일반 읽기 전용·설정상 허용, 검토로 승인된 정확한 호출 | 엄격 요청에서 표시·이전 승인으로 검토 생략, 거부, 등록 변경, 검토 취소 | 실제 Pi 클라이언트와 stdio 서버의 호출·파일 효과 일치 |
|
|
65
|
+
| 프로젝트 MCP 시작 | 저장된 신뢰 또는 명시적인 신뢰 선택 | 결정 없는 프로젝트, 명시적인 비신뢰 선택 | 도구 호출 전 서버 시작 효과도 신뢰 결정에 의해 제한 |
|
|
66
|
+
| MCP 추가 승인 | 원래 도구·연결·실제 입력과 일치하는 추가 요청 | 위조된 호출 ID, 다른 도구·커넥터 지목, 필수 사용자 입력의 자동 처리 | 원래 호출에 결합한 새 승인만 허용 |
|
|
67
|
+
| MCP 동시 호출 | 서로 다른 입력의 동시 호출 중 승인된 파일 변경 | 호출자 ID 재사용으로 다른 요청의 승인 차용 | 내부 연결 ID가 다르고, 거부 대상 파일은 불변 |
|
|
68
|
+
| MCP 이름 충돌 | `node_repl/js`에 대한 명시적 사용자 승인 | 승인 UI 없음, 명시적 거부 | 실제 stdio 서버의 대상 파일 불변·변경과 승인 창 횟수 일치 |
|
|
69
|
+
| Pi 제어 파일 | 사용자가 호스트에서 직접 변경한 MCP 설정 | 모델의 MCP 설정·신뢰한 확장 진입점·상대 import 모듈 변경 | 파일 불변, 재로딩 후 외부 효과 차단; 사용자 변경은 다음 시작에 적용 |
|
|
70
|
+
| 검토 응답 타입 | 문자열 위험 등급과 정상 승인 | 배열·`null` 등 잘못된 등급·승인 수준 | 외부 파일 불변, 기술 실패가 다음 모델 요청에 전달 |
|
|
71
|
+
| 문자 그대로의 경로 | 허용된 작업 영역 안의 `[route]`와 `*` 파일명 | 패턴 문자가 포함된 추가 권한 루트와 SDK 직접 프로필 | 승인 전·실행 전 차단, 비슷한 이름의 형제 파일 불변 |
|
|
72
|
+
| 거부 중단 후 직접 명령 | 사용자가 새로 요청한 직접 쉘 명령 | 중단된 모델의 후속 실행, 호출자 취소, 오래된 세션 | 모델 쓰기 미실행, 직접 명령 성공, 원래 취소 계약 유지 |
|
|
73
|
+
| 감사 기록 | 따옴표가 포함된 검토 사유의 정상 승인 | 합성 비밀 값의 기록 | JSON 파싱 성공, 값 가리기, 승인된 파일 변경 |
|
|
74
|
+
| 일반 Pi·CLI 진입점 | 패키지 기본 확장의 공식 MCP, CLI 명시적 공급자·모델 선택 | 중복 MCP 연결, 존재하지 않는 모델의 대체 실행 | 실제 Pi·CLI 도구 효과와 모델·검토 호출 일치 |
|
|
75
|
+
| Pi 자원 | 전역 skills와 신뢰한 프로젝트의 skills·프롬프트·테마 | 비신뢰 프로젝트 자원, 자동 확장 실행 | 모델 문맥과 펼쳐진 프롬프트에 전달, 비신뢰 코드 효과 없음 |
|
|
76
|
+
| MCP 재연결 정리 | 출력 모드에서 RPC로 재연결 후 승인 호출 | 이전 서버 프로세스 잔류 | 정상 종료 후 생성한 두 PID 모두 부재 |
|
|
77
|
+
|
|
78
|
+
### 이전 구조에서 Codex를 참고한 하네스 방식
|
|
79
|
+
|
|
80
|
+
기준은 공개 소스 `rust-v0.160.0`, 커밋 `a956835d020762cb2b570053af06f643a11c0ecc`다. 공개된 하네스의 검증 계약을 Pi의 스트림·도구 경로에 맞게 구현했다. 이전 버전은 실제 Rust `codex-execpolicy`로 `.rules`를 평가했고, 현재 소스는 앞서 설명한 TS 이식과 원본 결과 대조를 사용한다. 어느 기록도 상류의 전체 Rust 테스트 스위트를 실행했다는 의미는 아니다.
|
|
81
|
+
|
|
82
|
+
| Codex 기준 | 반영한 검증 |
|
|
83
|
+
| --- | --- |
|
|
84
|
+
| [`responses.rs::mount_sse_sequence`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/common/responses.rs#L1466) | 응답을 정해진 순서로 재생하고 주 모델·검토자 호출의 초과와 누락을 실패 처리한다. |
|
|
85
|
+
| [`exec_policy.rs::execpolicy_blocks_shell_invocation`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/exec_policy.rs#L517) | 정책 거부 결과가 다음 주 모델 요청에 도구 결과로 전달되는지 확인한다. |
|
|
86
|
+
| [`request_permissions.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/request_permissions.rs#L834) | 읽기 전용 상태의 추가 권한이 승인하지 않은 작업 공간·임시 경로 쓰기로 넓어지지 않는지 확인한다. |
|
|
87
|
+
| [`guardian_review_cancellation.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/guardian_review_cancellation.rs#L39) | 직접 도구와 중첩 코드 실행의 검토를 취소한 뒤 늦은 승인이 실행으로 이어지지 않는지 확인한다. |
|
|
88
|
+
| [`execpolicy`](https://github.com/openai/codex/tree/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/execpolicy) | 원본 Starlark 엔진과 예제 검증·실행 파일 경로·네트워크 규칙 변환을 연결한다. |
|
|
89
|
+
| [`agents_md.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/src/agents_md.rs) | 프로젝트 루트·지침 우선순위·바이트 한도·신뢰 상태를 확인한다. |
|
|
90
|
+
| [`mcp_tool_call.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/src/mcp_tool_call.rs), [`session/mcp.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/src/session/mcp.rs) | annotation 우선순위, 엄격한 자동 검토, 민감한 중첩 승인과 호출 출처 결합을 확인한다. |
|
|
91
|
+
|
|
92
|
+
현재 재생 하네스는 [`test/harness/scenarios.mjs`](../../test/harness/scenarios.mjs), 시나리오는 [`test/conformance/protection.test.mjs`](../../test/conformance/protection.test.mjs)에 있다. 이전 OS 격리 검사는 [`v0.1.2`의 테스트](https://github.com/buYoung/pi-codex-auto-review/blob/v0.1.2/test/native/sandbox.test.mjs)에 보존했다. 하네스 자체도 호출 누락·초과, 이미 취소된 요청을 검사한다.
|
|
93
|
+
|
|
94
|
+
확장 검증 중 Docker PID 1 아래 좀비 프로세스 131개가 누적되고 `grep`의 스레드 생성이 실패하는 문제를 재현했다. 하네스의 `--init`과 고아 회수 사전 검증으로 수정하며, PID 한도 256개와 내부 파일·네트워크·seccomp 제한을 유지한다.
|
|
95
|
+
|
|
96
|
+
후속 검증에서는 실행 전에 만든 하드링크가 macOS의 보호 파일 읽기와 외부 파일 쓰기를 우회하는 것을 재현했다. 실행 전 링크 수와 허용 범위의 이름을 대조해 수정했다. 또 Pi의 기본 신뢰값을 그대로 사용하면 새 프로젝트의 MCP 서버가 승인 도구 호출 전에 시작되는 것을 재현해, 저장된 신뢰와 명시적 선택으로 제한했다. 재현·수정 근거는 [하드링크 인계](../handoffs/auto-review/15-hard-links.json)와 [운영체제 후속 인계](../handoffs/auto-review/18-platform-followups.json)에 있다.
|
|
97
|
+
|
|
98
|
+
실제 Ubuntu Docker에서는 내부 `bwrap`의 마운트가 외부 AppArmor 정책에 차단됐다. 하네스는 AppArmor 지원 여부를 확인하고 소유한 검증 컨테이너에만 `apparmor=unconfined`를 지정한다. 요청값과 실제 프로필을 실행 보고서에 기록하며, 내부 샌드박스의 파일·네트워크·seccomp 검증은 그대로 수행한다. 이는 [Docker의 컨테이너별 프로필 선택](https://docs.docker.com/engine/security/apparmor/)을 사용하는 검증 환경 설정이다. 수정 전후 실행은 [AppArmor 인계](../handoffs/auto-review/20-docker-apparmor.json)에 보존했다.
|
|
99
|
+
|
|
100
|
+
ARM64 커널에서 x64 프로그램을 실행한 추가 검증에서는 142개 중 정상 셸 출력 사례 하나가 3초 제한을 넘겼다. 해당 기능 검사의 호출자 지정 제한을 15초로 보정했다. 별도 생명주기 검사는 실제 2초 제한, 3.5초 반환 상한, 지연된 파일 변경 차단을 계속 확인한다. 실행기의 제한 처리 코드는 변경하지 않았다. 최초 실패와 집중 검사 결과는 [에뮬레이션 시간 인계](../handoffs/auto-review/22-emulated-shell-timing.json)에 있다.
|
|
101
|
+
|
|
102
|
+
macOS의 첫 최종 집계에서는 패키지 검사의 20초 관찰 시간이 초과됐다. 관찰 시간을 늘린 진단 복사본은 12.6초에 정상 완료됐으며, 원본 검사와 20초 제한을 유지한 재집계도 통과했다. 최초 지연의 세부 원인은 특정하지 못했다. [패키지 시간 관찰 인계](../handoffs/auto-review/24-macos-package-timing.json)에 초기 실패와 후속 성공을 함께 보존했다.
|
|
103
|
+
|
|
104
|
+
일반 MCP 승인과 엄격 검토는 구분한다. Codex의 일반 경로는 검토자가 자동 모델이어도 annotation과 승인 모드를 따르며, 엄격 검토는 이런 생략 조건을 허용하지 않는다. 중첩 요청은 원래 호출의 엄격 검토 요구를 낮출 수 없다. 정정한 동작과 회귀 검증은 [MCP 승인 경로 인계](../handoffs/auto-review/19-mcp-routing.json)에 기록했다.
|
|
105
|
+
|
|
106
|
+
현재 E2E는 [`test/e2e/guard.test.mjs`](../../test/e2e/guard.test.mjs)에 있다. 배열 위험 등급이 외부 파일을 변경하는 현상, 제한된 경로의 `[]`가 형제 파일 쓰기를 허용하는 현상, `node_repl/js`가 승인 없이 MCP 효과를 실행하는 현상을 수정 전 실제 Pi·OS 경로에서 재현했다. 감사 JSON 실패와 거부 중단 후 직접 명령 실패도 같은 방식으로 재현했다. 기본 패키지 검사는 공개 Pi 세션과 실제 MCP 서버까지 실행하도록 확장했으므로, 하위 프로세스 관찰 한도를 기존 20초에서 60초로 조정했다. 실제 실행기의 취소·시간 제한 검사는 별도로 유지한다.
|
|
107
|
+
|
|
108
|
+
CLI 관찰기는 Pi 0.99.1의 확장용 호환 레지스트리가 가리키는 실제 `ModelRuntime`을 계측한다. 호환 레지스트리만 감싸면 주 에이전트 호출을 놓치므로, 로컬 HTTP 공급자 대조군으로 주 실행 2회·검토 1회의 실제 수신과 관찰 기록을 대조한다. 검토 출력 한도 `777`과 주 실행의 4096토큰 상한이 HTTP 요청에 전달되고, 최종 파일이 변경돼야 통과한다. 이 계측은 고정 버전용 검증 코드이며 제품의 응답을 대체하지 않는다.
|
|
109
|
+
|
|
110
|
+
테스트 프로세스의 `TMPDIR`은 해당 실행이 만든 디렉터리로 지정하고 종료 시 정리한다. 호스트의 공유 임시 경로가 디렉터리 검사 한도 10만 개를 넘는 환경을 관찰했기 때문이다. 실행기의 검사 한도와 불완전한 검사의 차단 정책은 유지하며, 기본 임시 루트 허용과 명시적 제외를 별도 대조군으로 검사한다.
|
|
111
|
+
|
|
112
|
+
첫 ARM64 Docker 실행에서는 154개 중 정상 `grep` 대조군 하나가 실패했다. 추가 검사와 실제 마운트 관찰에서, 존재하지 않는 `.git`이 `/dev/null` 장치로 바인딩되고 `nodev`로 인해 읽기가 거부되는 것을 확인했다. `.git/HEAD` 하위 차단을 함께 전달해 런타임이 읽기 전용 빈 디렉터리를 만들도록 수정했다. 원래 부모 차단은 유지하며, 읽기 선언을 늘리는 초기 수정은 별도 대조군에서 불필요함을 확인하고 되돌렸다. SDK 호출자의 읽기 전용 경로 선택도 보존한다. 추가 대조군은 정상 검색·일반 디렉터리 생성·Pi 설정 생성 차단을 함께 확인한다. 허용 루트와 절대 차단 루트가 직접 겹치거나 별칭으로 겹치는 경우는 실제 경로로 정규화한 뒤 실행 전에 거부한다.
|
|
113
|
+
|
|
114
|
+
추가 승인 연결 검사에서는 같은 호출자 ID를 사용한 두 MCP 요청이 겹칠 때 거부 대상 파일이 변경되는 것을 재현했다. MCP 전송마다 내부에서 생성한 고유 ID로 추가 승인을 연결하도록 수정했다. 실제 Pi에 등록된 도구를 동시에 실행해, 두 검토 입력이 각각 보존되고 승인된 파일만 변경되는지 확인한다.
|
|
115
|
+
|
|
116
|
+
### 이전 OS 격리 검증이 보장했던 범위
|
|
117
|
+
|
|
118
|
+
- 주 모델과 검토자를 재생하는 시나리오는 실제 Pi와 OS 샌드박스를 사용한다. 이 결과를 실제 GLM5.3의 판단 정확도로 표시하지 않는다. 실모델 SDK 4개와 CLI 1개 사례는 별도 실행·집계한다. 통합 판정에는 CLI의 실제 검토 호출·파일 변경·자격 증명 미기록도 필요하다.
|
|
119
|
+
- 기본 임시 디렉터리 쓰기와 일반 외부 파일 읽기는 기본 프로필이 허용하는 동작이다. 작업 공간 밖이라는 이유만으로 항상 차단된다고 가정하지 않는다.
|
|
120
|
+
- 셸 실행은 트랜잭션이 아니다. 허용된 첫 번째 쓰기 뒤 두 번째 쓰기가 거부되어도 첫 번째 변경은 남는다. 이 부분 효과도 테스트에서 명시적으로 확인한다.
|
|
121
|
+
- Linux에서 새 파일 생성은 승인할 부모 디렉터리 범위가 필요할 수 있다. 좁은 기존 파일 승인과 새 파일 생성의 범위를 구분한다.
|
|
122
|
+
- 사전 생성 하드링크와 좁은 승인 파일의 다른 이름을 검사한다. 실행 중 격리 밖의 호스트 프로그램이 동시에 링크 구조를 바꾸는 공격까지 보장하지 않는다. 검사 실패·한도 초과는 실행 차단으로 처리한다.
|
|
123
|
+
- Linux x64 호스트 실행과 ARM64 커널의 x64 실행은 기록을 분리한다. 최종 집계에는 같은 소스의 실제 Linux x64 호스트 결과가 필요하다.
|
|
124
|
+
- Windows는 실제 운영체제에서 원본 규칙 엔진·승인 정책과 미지원 네이티브 실행의 사전 거부를 확인하는 별도 검증이다. Windows 네이티브 격리의 성공을 뜻하지 않는다.
|
|
125
|
+
- 외부 MCP 실행기는 신뢰한 통합 계층이다. 이미 외부 서버에 전송된 요청의 취소 효과나 모든 공급자의 계정 식별·부수 효과를 보장하지 않는다. 비어 있는 승인 폼은 처리하지만 일반 입력 폼·URL elicitation은 거부한다. Pi에 없는 Computer Use 분류와 승인 예외는 제거했다.
|
|
126
|
+
- 패턴 문자가 들어간 네이티브 권한 루트는 런타임에서 문자 그대로 표현할 수 없어 차단한다. 일반 작업 영역 안의 특수문자 파일명 지원과 구분한다. 신뢰한 확장의 디렉터리는 제어 코드로 보호하지만, 임의의 신뢰 확장이 그 밖의 파일을 실행하거나 import하는 모든 의존 관계를 자동 분석하지는 않는다.
|
|
127
|
+
- HTTPS CONNECT·SOCKS5 TCP·IPv6와 직접 UDP 차단을 검사한다. SOCKS5 UDP 및 모든 네트워크 프로토콜을 지원·검증했다고 주장하지 않는다.
|
|
128
|
+
- 독점 Codex 모델과의 모든 판단 동일성은 보장하지 않는다. 공개 정책·흐름과 선택한 GLM5.3의 관찰 결과를 구분한다.
|
|
129
|
+
|
|
130
|
+
## 실행
|
|
131
|
+
|
|
132
|
+
저장소 루트에서 실행한다. 아래 명령은 모두 실제 자격 증명을 사용하지 않는다.
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
npm run build
|
|
136
|
+
npm run test:conformance
|
|
137
|
+
npm run test:execution
|
|
138
|
+
npm run verify:docker -- --mode offline --platform linux/amd64
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
실모델 검증은 `OLLAMA_API_KEY`가 export된 셸에서 실행한다. `.zshrc`에 저장했다면 해당 셸에서 먼저 불러온다. 키 값은 명령 인자에 넣지 않는다. 앞선 오프라인 실행의 출력에서 확인한 이미지 식별자를 사용한다.
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
export OLLAMA_API_KEY
|
|
145
|
+
npm run verify:docker -- --mode conformance --platform linux/amd64 --model glm-5.3 --image <imageDigest>
|
|
146
|
+
npm run verify:guard
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`verify:platform`은 실행한 운영체제의 전체 결과를 남기고, Windows의 `verify:windows`는 규칙 엔진·파일 실행·취소 결과를 남긴다. GitHub Actions에는 Ollama 키를 보내지 않는다.
|
|
150
|
+
|
|
151
|
+
Docker 엔진에 따라 이미지를 내보낼 때와 불러온 뒤의 ID가 다를 수 있다. 이번 실행에서는 CI의 설정 해시를 로컬 매니페스트가 참조하고, 19개 레이어가 모두 같음을 확인했다. 이 경우에는 `docker image load`가 반환한 ID로 오프라인 검증을 다시 실행하고, 같은 ID로 실모델 검증을 실행한다.
|
|
152
|
+
|
|
153
|
+
```sh
|
|
154
|
+
npm run verify:docker -- --mode offline --platform linux/amd64 --image <loadedImageID>
|
|
155
|
+
npm run verify:docker -- --mode conformance --platform linux/amd64 --model glm-5.3 --image <loadedImageID>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
`verify:guard`는 현재 운영체제에서 같은 소스의 결과를 기록한다. 다른 플랫폼·이미지·실모델 결과를 로컬 통과로 대신하지 않는다. 실행 기록은 `.reports/pi-guard/runs/`에 별도로 남긴다.
|