pi-codex-auto-review 0.1.4 → 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.
Files changed (127) hide show
  1. package/NOTICE +4 -2
  2. package/README.ko.md +85 -0
  3. package/README.md +51 -52
  4. package/dist/approval-commands.d.ts +3 -3
  5. package/dist/approval-commands.js +112 -58
  6. package/dist/approval-commands.js.map +1 -1
  7. package/dist/approval-settings.d.ts +1 -1
  8. package/dist/approval-settings.js +17 -10
  9. package/dist/approval-settings.js.map +1 -1
  10. package/dist/approvals.d.ts +9 -9
  11. package/dist/approvals.js +195 -75
  12. package/dist/approvals.js.map +1 -1
  13. package/dist/audit.d.ts +1 -1
  14. package/dist/audit.js +37 -13
  15. package/dist/audit.js.map +1 -1
  16. package/dist/cli.js +60 -31
  17. package/dist/cli.js.map +1 -1
  18. package/dist/context-files.d.ts +2 -2
  19. package/dist/context-files.js +40 -19
  20. package/dist/context-files.js.map +1 -1
  21. package/dist/contracts.d.ts +39 -39
  22. package/dist/contracts.js +117 -51
  23. package/dist/contracts.js.map +1 -1
  24. package/dist/index.d.ts +9 -9
  25. package/dist/index.js +145 -48
  26. package/dist/index.js.map +1 -1
  27. package/dist/pi-host.js +3 -3
  28. package/dist/pi-host.js.map +1 -1
  29. package/dist/policy/domains.js +17 -7
  30. package/dist/policy/domains.js.map +1 -1
  31. package/dist/policy/index.d.ts +7 -7
  32. package/dist/policy/index.js +379 -141
  33. package/dist/policy/index.js.map +1 -1
  34. package/dist/policy/paths.js +31 -18
  35. package/dist/policy/paths.js.map +1 -1
  36. package/dist/policy/rule-engine.d.ts +2 -0
  37. package/dist/policy/rule-engine.js +283 -0
  38. package/dist/policy/rule-engine.js.map +1 -0
  39. package/dist/policy/rule-types.d.ts +30 -0
  40. package/dist/policy/rule-types.js +2 -0
  41. package/dist/policy/rule-types.js.map +1 -0
  42. package/dist/policy/rules-sync.d.ts +1 -0
  43. package/dist/policy/rules-sync.js +14 -0
  44. package/dist/policy/rules-sync.js.map +1 -0
  45. package/dist/policy/rules-worker.d.ts +1 -0
  46. package/dist/policy/rules-worker.js +14 -0
  47. package/dist/policy/rules-worker.js.map +1 -0
  48. package/dist/policy/rules.d.ts +4 -31
  49. package/dist/policy/rules.js +126 -38
  50. package/dist/policy/rules.js.map +1 -1
  51. package/dist/policy/shell.js +70 -41
  52. package/dist/policy/shell.js.map +1 -1
  53. package/dist/policy/starlark/builtins.d.ts +6 -0
  54. package/dist/policy/starlark/builtins.js +764 -0
  55. package/dist/policy/starlark/builtins.js.map +1 -0
  56. package/dist/policy/starlark/evaluator.d.ts +18 -0
  57. package/dist/policy/starlark/evaluator.js +518 -0
  58. package/dist/policy/starlark/evaluator.js.map +1 -0
  59. package/dist/policy/starlark/lexer.d.ts +14 -0
  60. package/dist/policy/starlark/lexer.js +189 -0
  61. package/dist/policy/starlark/lexer.js.map +1 -0
  62. package/dist/policy/starlark/parser.d.ts +140 -0
  63. package/dist/policy/starlark/parser.js +508 -0
  64. package/dist/policy/starlark/parser.js.map +1 -0
  65. package/dist/policy/starlark/validation.d.ts +4 -0
  66. package/dist/policy/starlark/validation.js +183 -0
  67. package/dist/policy/starlark/validation.js.map +1 -0
  68. package/dist/policy/starlark/values.d.ts +46 -0
  69. package/dist/policy/starlark/values.js +363 -0
  70. package/dist/policy/starlark/values.js.map +1 -0
  71. package/dist/reports.d.ts +1 -1
  72. package/dist/reports.js +66 -30
  73. package/dist/reports.js.map +1 -1
  74. package/dist/review/context.d.ts +3 -3
  75. package/dist/review/context.js +207 -71
  76. package/dist/review/context.js.map +1 -1
  77. package/dist/review/investigation.d.ts +2 -2
  78. package/dist/review/investigation.js +57 -16
  79. package/dist/review/investigation.js.map +1 -1
  80. package/dist/review/lifecycle.d.ts +1 -1
  81. package/dist/review/lifecycle.js +70 -27
  82. package/dist/review/lifecycle.js.map +1 -1
  83. package/dist/review/policy.js +10 -5
  84. package/dist/review/policy.js.map +1 -1
  85. package/dist/review/upstream-policy.js +1 -1
  86. package/dist/review/upstream-policy.js.map +1 -1
  87. package/dist/review/user-input.d.ts +3 -3
  88. package/dist/review/user-input.js +39 -16
  89. package/dist/review/user-input.js.map +1 -1
  90. package/dist/reviewer.d.ts +8 -8
  91. package/dist/reviewer.js +253 -75
  92. package/dist/reviewer.js.map +1 -1
  93. package/dist/signals.js +24 -9
  94. package/dist/signals.js.map +1 -1
  95. package/dist/startup.d.ts +4 -4
  96. package/dist/startup.js +139 -41
  97. package/dist/startup.js.map +1 -1
  98. package/dist/tools/controller.d.ts +16 -12
  99. package/dist/tools/controller.js +432 -121
  100. package/dist/tools/controller.js.map +1 -1
  101. package/dist/tools/environment.js +3 -1
  102. package/dist/tools/environment.js.map +1 -1
  103. package/dist/tools/executor.d.ts +1 -1
  104. package/dist/tools/executor.js +45 -28
  105. package/dist/tools/executor.js.map +1 -1
  106. package/dist/tools/external.d.ts +8 -8
  107. package/dist/tools/external.js +22 -11
  108. package/dist/tools/external.js.map +1 -1
  109. package/dist/tools/mcp.d.ts +6 -6
  110. package/dist/tools/mcp.js +208 -80
  111. package/dist/tools/mcp.js.map +1 -1
  112. package/dist/tools/mutation-queue.js.map +1 -1
  113. package/docs/publishing.ko.md +114 -0
  114. package/docs/publishing.md +49 -47
  115. package/docs/security/dependencies.ko.md +54 -0
  116. package/docs/security/dependencies.md +27 -26
  117. package/docs/testing/auto-review-protection.ko.md +158 -0
  118. package/docs/testing/auto-review-protection.md +104 -99
  119. package/docs/usage.ko.md +242 -0
  120. package/docs/usage.md +125 -121
  121. package/package.json +106 -95
  122. package/dist/native/darwin-arm64/artifact.json +0 -5
  123. package/dist/native/darwin-arm64/pi-guard-execpolicy +0 -0
  124. package/dist/native/linux-x64/artifact.json +0 -5
  125. package/dist/native/linux-x64/pi-guard-execpolicy +0 -0
  126. package/native/execpolicy/LICENSE +0 -201
  127. package/native/execpolicy/NOTICE +0 -6
@@ -1,130 +1,135 @@
1
- # 자동 검토 보호 경계 검증
1
+ # Automatic review protection verification
2
2
 
3
- 이 검증은 **정책 판단, 실제 Pi 도구 결과, 파일·네트워크 효과**를 함께 확인한다. 허용 대조군이 먼저 성공해야 차단 결과도 유효하다. 예외나 오류 메시지만 확인하고 보호 성공으로 판정하지 않는다.
3
+ **English** | [한국어](auto-review-protection.ko.md)
4
4
 
5
- 현재 소스는 승인 보조 확장이다. OS 격리·네트워크 프록시·재귀 디렉터리 검사를 수행하지 않는다. 승인된 도구는 원래 Pi 실행기를 사용한다. 아래 이전 샌드박스 검증 기록을 현재 실행 구조의 보장으로 사용하지 않는다.
5
+ Verification checks **policy decisions, actual Pi tool results, and file and network effects** together. An allowed control case must succeed before a blocked result is meaningful. Exceptions or error messages alone do not establish successful protection.
6
6
 
7
- ## 현재 승인·실행 검증
7
+ The current source is an approval assistance extension. It does not enforce OS isolation, configure a network proxy, or recursively inspect directories. Approved tools use Pi's original executor. The earlier sandbox verification records below do not establish guarantees for the current execution structure.
8
8
 
9
- | 대상 | 확인하는 결과 |
9
+ ## Current approval and execution checks
10
+
11
+ | Target | Result checked |
10
12
  | --- | --- |
11
- | `/approve` | Codex 원문 설명·영문 화면·좁은 터미널 줄바꿈, 선택한 승인 방식의 실제 파일 효과와 저장 |
12
- | `/approve-model` | 현재 `/scoped-models` 범위, 사용 불가·중복 모델 제외, 선택 도중 범위 변경 거부, 실제 Pi 검토자 적용과 주 모델 유지 |
13
- | 설정 변경 | 동시 선택 병합, 저장 실패 시 기존 설정 유지, 이전 검토의 늦은 승인 차단 |
14
- | Pi 실행 | 원래 SDK 실행, cwd·환경·출력·시간 제한·취소 신호 유지 |
15
- | 시작 | 관계없는 탐색 불가 디렉터리가 있어도 전수 탐색 없이 실행 |
16
- | 보호·거부 | 직접 보호 경로·금지 규칙은 검토 전 거부, 실패·취소·시간 초과는 실행으로 이어지지 않음 |
17
- | 네트워크 사전 검토 | 스킴 생략·설정 파일·허용 URL과 설정 파일을 함께 쓴 curl 요청도 자동·사용자 검토를 거침. 허용 대조군만 소유한 HTTP 서버에 도달 |
18
- | 배포 패키지 | 실제 Pi 로더로 시작, 샌드박스 빌드 결과와 묶인 의존성 부재 |
13
+ | `/approve` | Original Codex descriptions, English UI, narrow-terminal wrapping, actual file effects of the selected approval method, and persistence |
14
+ | `/approve-model` | Current `/scoped-models` scope; exclusion of unavailable and duplicate models; rejection of scope changes during selection; actual Pi reviewer selection without changing the main model |
15
+ | Settings changes | Concurrent selection merging, preservation on save failure, and blocking late approvals from previous reviews |
16
+ | Pi execution | Original SDK execution with cwd, environment, output, timeout, and cancellation signal preserved |
17
+ | Startup | Execution without an exhaustive scan even when unrelated directories cannot be traversed |
18
+ | Protection and denial | Direct protected paths and deny rules rejected before review; failures, cancellation, and timeouts never lead to execution |
19
+ | Network review before execution | curl requests with omitted schemes, configuration files, or both allowed URLs and configuration files pass through automatic or user review. Only the allowed control reaches the owned HTTP server |
20
+ | TypeScript rules | Replay 280 actual results captured from the pinned Codex helper; preserve rule outputs and rejected inputs, cancellation, budgets, and strict request validation |
21
+ | Distribution package | Startup through the actual Pi loader; synchronous and worker-based rule evaluation from the archive; absence of Rust artifacts, `.node` files, sandbox output, and bundled dependencies |
22
+
23
+ Checks that replay the reviewer and UI use actual Pi and file results, but do not establish the judgment accuracy of a live model. The OS does not restrict indirect file access inside approved shells, hard links, or network changes during execution. Caller environment values are preserved for execution; authentication variables are excluded only from review evidence.
19
24
 
20
- 검토자·UI를 재생하는 검증은 실제 Pi와 파일 결과를 사용하지만 실모델의 판단 정확도를 증명하지 않는다. 승인된 셸 내부의 간접 파일 접근, 하드링크와 실행 중 네트워크 변경은 OS가 제한하지 않는다. 호출자의 환경은 실행에 유지하고 검토 증거에서만 인증 변수를 제외한다.
25
+ `verify:guard` saves the current operating system's results, source hash, and audit records. Other operating systems and live models require separate results. Unexecuted scopes are not marked as passed.
21
26
 
22
- `verify:guard`는 현재 운영체제의 결과와 소스 해시·감사 기록을 저장한다. 다른 운영체제와 실모델 실행은 별도 결과이며 수행하지 않은 범위를 통과로 표시하지 않는다.
27
+ Approval descriptions follow the [official approval picker](https://learn.chatgpt.com/docs/security-administration). Reviewer separation, denial feedback, stopping after three consecutive denials or ten in the latest fifty reviews, and cancellation are compared with the [official Auto-review documentation](https://learn.chatgpt.com/docs/sandboxing/auto-review). The current implementation does not enforce OS boundaries; this does not guarantee security equivalent to Codex's sandbox.
23
28
 
24
- 승인 설명은 [공식 승인 선택 화면](https://learn.chatgpt.com/docs/security-administration)을 따르고, 검토자 분리·거부 피드백·3회 연속 또는 최근 50회 중 10회 거부 시 중단·취소는 [공식 Auto-review 문서](https://learn.chatgpt.com/docs/sandboxing/auto-review)와 대조한다. 현재 구현은 OS 경계를 강제하지 않으므로 Codex의 샌드박스와 동등한 보안을 보장한다는 의미가 아니다.
29
+ The reference corpus is [`test/fixtures/execpolicy-reference.json`](../../test/fixtures/execpolicy-reference.json). It records the original executable's revision and SHA-256 hash and contains 201 accepted and 79 rejected cases, including Unicode whitespace, invalid Unicode escapes, and numeric conversion boundaries. The TypeScript implementation is checked through its public asynchronous API; the original binary is no longer required by tests or builds. POSIX-specific path cases are excluded from Windows replay, where the existing platform-specific path tests still run. This is a recorded compatibility corpus, not proof of equivalence for every possible Starlark program.
25
30
 
26
- ## 이전 OS 격리 검증 기록
31
+ ## Historical OS isolation verification
27
32
 
28
- 다음 기록은 샌드박스가 있던 `v0.1.2` 및 이전 소스에 관한 것이다. GLM5.3 검증은 SDK 경로 4개와 CLI 1개 사례를 구분했다. 이전 플랫폼 검증은 [운영체제 검증 인계](../handoffs/auto-review/17-platform-qualification.json), 이전 112개 검증은 [이전 보호 경계 인계](../handoffs/auto-review/10-protection-matrix.json)에 보존한다. 새 소스의 실행 결과는 소스 해시가 일치하는 최신 실행 기록으로 확인한다.
33
+ The following records concern `v0.1.2` and earlier source versions that included a sandbox. GLM5.3 verification distinguished four SDK cases and one CLI case. Earlier platform verification is preserved in the [platform qualification handoff](../handoffs/auto-review/17-platform-qualification.json), and the earlier 112 checks in the [protection matrix handoff](../handoffs/auto-review/10-protection-matrix.json). Check current execution results against the latest run records with a matching source hash.
29
34
 
30
- 개선 전 `85008b0` 시점에는 같은 소스의 macOS·실제 Linux x64·네이티브 및 에뮬레이션 Docker가 각각 142개를 통과했다. GLM5.3 네 사례와 Windows의 별도 규칙·사전 거부 검증도 통과했고, 감사 기록 217건과 실모델 로그·보고서 7개의 키 비노출을 확인했다. 이후 전체 검토에서 기존 검사에 없던 결함이 발견됐다. 이 과거 결과는 아래 회귀 사례와 현재 소스의 통과를 대신하지 않는다.
35
+ Before the improvements, at `85008b0`, the same source passed 142 checks each on macOS, actual Linux x64, native Docker, and emulated Docker. Four GLM5.3 cases and separate Windows rule and pre-execution denial checks also passed. The record confirmed that 217 audit entries and seven live model logs and reports did not expose keys. A later comprehensive review found defects not covered by those checks. These historical results do not replace the regression cases below or passing results for the current source.
31
36
 
32
- 이번 전체 개선의 수정 내역, 최종 실행 근거와 남은 플랫폼 조건은 [Pi 실행 개선 인계](../handoffs/auto-review/25-pi-runtime-alignment.md)에 정리했다.
37
+ The changes from that comprehensive improvement, final execution evidence, and remaining platform conditions are documented in the [Pi runtime alignment handoff](../handoffs/auto-review/25-pi-runtime-alignment.md).
33
38
 
34
- ### 이전 구조에서 보호되는 경우와 허용되는 경우
39
+ ### Protected and allowed cases in the earlier structure
35
40
 
36
- | 경계 | 허용 대조군 | 차단 또는 검토 대상 | 최종 관찰 |
41
+ | Boundary | Allowed control | Blocked or reviewed target | Final observation |
37
42
  | --- | --- | --- | --- |
38
- | 파일 도구 6종 | 작업 공간의 `read`, `grep`, `find`, `ls`, `write`, `edit` | 절대 보호 경로의 같은 도구 호출 | 도구 오류, 검토자 호출 0회, 보호 파일 불변, 내용 비노출 |
39
- | 기본 읽기·임시 경로 | 일반 외부 파일 읽기, 기본 임시 경로 쓰기 | 임시 쓰기 루트를 제외한 뒤 같은 쓰기 | 읽기는 유지되고 쓰기는 검토 후 거부 |
40
- | 읽기 전용 프로필 | 명시적으로 승인한 기존 파일 쓰기 | 승인하지 않은 작업 공간·임시 경로의 형제 파일, 다음 호출 | 승인 파일만 변경되고 나머지 불변 |
41
- | 검토 중 경로 변경 | 처음 검토한 심볼릭 링크 대상 | 검토 중 다른 형제 경로나 보호 경로로 링크 교체 | 오래된 승인 거부, 세 대상 모두 불변 |
42
- | 위험·인가 판단 | 높은 위험이라도 충분한 인가가 있는 합성 사례 | 낮은 위험의 명시적 정책 거부, 인가 부족, 최고 위험 | 주 모델에 전달된 도구 결과와 실제 쓰기 일치 |
43
- | 검토 기술 오류 | 정상 구조의 승인 응답 | 공급자 오류, 잘못된 JSON, 권한 추가 필드 삽입, 시간 초과 | 정책 거부와 구별되는 실패, 파일 불변 |
44
- | 승인 경로 설정 | 일반 작업 공간 쓰기·셸 출력 | 비활성화한 샌드박스·명령 규칙 승인 범주 | 검토자를 호출하지 않고 거부 |
45
- | 명령 규칙 | 규칙에 걸리지 않는 정상 명령 | 허용 규칙과 동시에 일치하는 금지 규칙, 중첩 셸 | 직접·중첩 실행 모두 거부, 대상 파일 미생성 |
46
- | 검토 취소 | 실제 Pi 직접 도구·`codemode`에서 검토 시작 | 검토 중 취소 후 늦게 도착한 승인 | 취소 신호 전달, 쓰기 미실행 |
47
- | 파일 변조 7종 | 작업 공간의 추가 쓰기·길이 변경·삭제·이동·복사·모드 변경·하드 링크 생성 | 같은 작업의 범위 밖 대상 | 내용·존재·모드·원본 파일을 각각 확인 |
48
- | 네트워크 목적지 | 허용 와일드카드의 하위 도메인 | 루트 도메인, 비슷한 접미사, 명시적 거부 도메인 | 소유한 서버의 실제 수신 횟수 |
49
- | HTTP 리다이렉트 | 허용 호스트의 최초 요청 | 거부 호스트로의 리다이렉트 | 최초 요청만 도착하고 거부 대상은 미도달 |
50
- | 환경변수 | 명시적인 일반 값이 자식 인터프리터에 전달 | 인증·로더·사용자 프록시 변수의 합성 비밀 값 | 자식 환경에 비밀 값 부재, 일반 값 보존 |
51
- | Docker 프로세스 정리 | `--init`이 종료된 고아 프로세스를 회수 | PID 1이 고아를 회수하지 못하는 컨테이너 | 제한 시간 내 `/proc/<pid>` 소멸, 실패 시 본 검증 진입 차단 |
52
- | 사전 생성 하드링크 | 모든 이름이 허용 범위 안에 있는 같은 inode | 보호 파일 별칭, 범위 밖 쓰기 별칭, 좁은 승인 파일의 형제 별칭 | 실행 전 차단, 외부 내용 불변; 모든 별칭을 포함한 디렉터리 승인은 허용 |
53
- | 탐색 불가 디렉터리 | 접근 불가 하위 트리 옆의 정상 파일 쓰기 | 하위 트리의 권한 변경·읽기, 이름을 알면 접근 가능한 미검증 트리 | 접근 불가 트리는 OS 경계에서도 차단; 불완전한 검색 가능 범위는 시작 거부 |
54
- | HTTPS CONNECT | 합성 인증서를 검증한 소유 서버 요청 | 허용하지 않은 목적지, 신뢰하지 않은 인증서 | 실제 HTTPS 응답과 서버 수신 횟수, 인증 실패 시 HTTP 효과 없음 |
55
- | SOCKS5·UDP | 허용 SOCKS5 TCP, 호스트의 UDP 대조 요청 | 명시적으로 거부한 SOCKS5 목적지, 샌드박스의 직접 UDP | 허용 TCP만 도달, 직접 UDP 추가 수신 없음 |
56
- | IPv6 | 동등한 IPv6 표기의 프록시 허용, 실행 중 정확한 목적지 승인 | 명시적 IPv6 거부, 직접 IPv6 통신 | 주소·포트가 검토에 전달되고 허용 요청만 서버 도달 |
57
- | 원본 `.rules` | Starlark 함수·문자열 보간·대안 인자·실행 파일 경로·네트워크 규칙 | 틀린 예제, 경로 제약 위반, 잘못된 규칙, 취소 | 고정 Codex 엔진의 결과가 실제 정책과 네이티브 설정에 전달 |
58
- | 자동 컨텍스트 | 신뢰한 루트부터 현재 위치까지의 지침, 전역·파일 우선순위 | 비신뢰 프로젝트, 보호 경로 별칭, 초과 바이트 | 출처와 내용이 Pi·검토자에 전달되며 새로고침 후 갱신 |
59
- | MCP 최종 실행 | 일반 읽기 전용·설정상 허용, 검토로 승인된 정확한 호출 | 엄격 요청에서 표시·이전 승인으로 검토 생략, 거부, 등록 변경, 검토 취소 | 실제 Pi 클라이언트와 stdio 서버의 호출·파일 효과 일치 |
60
- | 프로젝트 MCP 시작 | 저장된 신뢰 또는 명시적인 신뢰 선택 | 결정 없는 프로젝트, 명시적인 비신뢰 선택 | 도구 호출 전 서버 시작 효과도 신뢰 결정에 의해 제한 |
61
- | MCP 추가 승인 | 원래 도구·연결·실제 입력과 일치하는 추가 요청 | 위조된 호출 ID, 다른 도구·커넥터 지목, 필수 사용자 입력의 자동 처리 | 원래 호출에 결합한 새 승인만 허용 |
62
- | MCP 동시 호출 | 서로 다른 입력의 동시 호출 중 승인된 파일 변경 | 호출자 ID 재사용으로 다른 요청의 승인 차용 | 내부 연결 ID가 다르고, 거부 대상 파일은 불변 |
63
- | MCP 이름 충돌 | `node_repl/js`에 대한 명시적 사용자 승인 | 승인 UI 없음, 명시적 거부 | 실제 stdio 서버의 대상 파일 불변·변경과 승인 창 횟수 일치 |
64
- | Pi 제어 파일 | 사용자가 호스트에서 직접 변경한 MCP 설정 | 모델의 MCP 설정·신뢰한 확장 진입점·상대 import 모듈 변경 | 파일 불변, 재로딩 후 외부 효과 차단; 사용자 변경은 다음 시작에 적용 |
65
- | 검토 응답 타입 | 문자열 위험 등급과 정상 승인 | 배열·`null` 등 잘못된 등급·승인 수준 | 외부 파일 불변, 기술 실패가 다음 모델 요청에 전달 |
66
- | 문자 그대로의 경로 | 허용된 작업 영역 안의 `[route]`와 `*` 파일명 | 패턴 문자가 포함된 추가 권한 루트와 SDK 직접 프로필 | 승인 전·실행 전 차단, 비슷한 이름의 형제 파일 불변 |
67
- | 거부 중단 후 직접 명령 | 사용자가 새로 요청한 직접 쉘 명령 | 중단된 모델의 후속 실행, 호출자 취소, 오래된 세션 | 모델 쓰기 미실행, 직접 명령 성공, 원래 취소 계약 유지 |
68
- | 감사 기록 | 따옴표가 포함된 검토 사유의 정상 승인 | 합성 비밀 값의 기록 | JSON 파싱 성공, 값 가리기, 승인된 파일 변경 |
69
- | 일반 Pi·CLI 진입점 | 패키지 기본 확장의 공식 MCP, CLI 명시적 공급자·모델 선택 | 중복 MCP 연결, 존재하지 않는 모델의 대체 실행 | 실제 Pi·CLI 도구 효과와 모델·검토 호출 일치 |
70
- | Pi 자원 | 전역 skills와 신뢰한 프로젝트의 skills·프롬프트·테마 | 비신뢰 프로젝트 자원, 자동 확장 실행 | 모델 문맥과 펼쳐진 프롬프트에 전달, 비신뢰 코드 효과 없음 |
71
- | MCP 재연결 정리 | 출력 모드에서 RPC로 재연결 후 승인 호출 | 이전 서버 프로세스 잔류 | 정상 종료 후 생성한 두 PID 모두 부재 |
72
-
73
- ### 이전 구조에서 Codex를 참고한 하네스 방식
74
-
75
- 기준은 공개 소스 `rust-v0.160.0`, 커밋 `a956835d020762cb2b570053af06f643a11c0ecc`다. 공개된 하네스의 검증 계약을 Pi의 스트림·도구 경로에 맞게 구현했다. `.rules`는 이 리비전의 `codex-execpolicy`를 실제 Rust 의존성으로 연결해 평가한다. 상류의 전체 Rust 테스트 스위트를 실행했다는 의미는 아니다.
76
-
77
- | Codex 기준 | 반영한 검증 |
43
+ | Six file tools | Workspace `read`, `grep`, `find`, `ls`, `write`, and `edit` | Same tool calls on absolutely protected paths | Tool error, zero reviewer calls, protected files unchanged, no content exposure |
44
+ | Default read and temporary paths | Ordinary external file reads and default temporary-path writes | Same write after excluding the temporary writable root | Reads still work; writes are reviewed and denied |
45
+ | Read-only profile | Explicitly approved write to an existing file | Unapproved sibling workspace or temporary files, and the next call | Only the approved file changes |
46
+ | Path changes during review | Initially reviewed symbolic-link target | Link replaced with a sibling or protected path during review | Stale approval rejected; all three targets unchanged |
47
+ | Risk and authorization | Synthetic high-risk case with sufficient authorization | Explicit low-risk policy denial, insufficient authorization, or critical risk | Tool results delivered to the main model agree with actual writes |
48
+ | Technical review errors | Correctly structured approval response | Provider error, invalid JSON, injected additional permission fields, or timeout | Failure distinct from policy denial; files unchanged |
49
+ | Approval path settings | Ordinary workspace writes and shell output | Disabled sandbox or command-rule approval categories | Rejected without calling the reviewer |
50
+ | Command rules | Normal command matching no rule | Deny rule matching alongside an allow rule, or nested shell | Direct and nested execution rejected; no target file created |
51
+ | Review cancellation | Review begins through actual Pi direct tools or `codemode` | Late approval after cancellation during review | Cancellation signal propagated; no write executed |
52
+ | Seven file mutations | Workspace append, resize, delete, move, copy, mode change, and hard-link creation | Same operations outside scope | Contents, existence, mode, and original file checked separately |
53
+ | Network destinations | Subdomain of an allowed wildcard | Root domain, similar suffix, or explicitly denied domain | Actual receive counts on an owned server |
54
+ | HTTP redirects | Initial request to an allowed host | Redirect to a denied host | Only initial request arrives; denied target is not reached |
55
+ | Environment variables | Explicit ordinary values passed to a child interpreter | Synthetic secrets in authentication, loader, or user proxy variables | Secrets absent from child environment; ordinary values preserved |
56
+ | Docker process cleanup | `--init` reaps exited orphan processes | Container whose PID 1 cannot reap orphans | `/proc/<pid>` disappears within the limit; failure blocks entry into verification |
57
+ | Preexisting hard links | Same inode with all names inside the allowed scope | Protected-file alias, out-of-scope write alias, or sibling alias of a narrowly approved file | Blocked before execution; external content unchanged. Directory approval covering every alias is allowed |
58
+ | Untraversable directories | Normal file write beside an inaccessible subtree | Subtree permission change or read; unverified tree accessible with a known name | OS boundary also blocks inaccessible tree; startup rejected for incompletely verified searchable scope |
59
+ | HTTPS CONNECT | Owned-server request with a verified synthetic certificate | Disallowed destination or untrusted certificate | Actual HTTPS response and server receive count; authentication failure produces no HTTP effect |
60
+ | SOCKS5 and UDP | Allowed SOCKS5 TCP and a host UDP control request | Explicitly denied SOCKS5 destination or direct sandbox UDP | Only allowed TCP arrives; no additional direct UDP receipt |
61
+ | IPv6 | Proxy approval of equivalent IPv6 notation; exact destination approval during execution | Explicit IPv6 denial or direct IPv6 communication | Address and port reach review; only allowed requests reach the server |
62
+ | Original `.rules` | Starlark functions, string interpolation, alternative arguments, executable paths, and network rules | Incorrect examples, path violations, invalid rules, or cancellation | Pinned Codex engine results reach actual policy and native settings |
63
+ | Automatic context | Instructions from a trusted root to cwd; global instructions and file precedence | Untrusted project, protected-path alias, or byte-limit overflow | Source and content reach Pi and reviewer; updated after refresh |
64
+ | Final MCP execution | Ordinary read-only or configured allowed call; exact reviewed and approved call | Strict request skipping review using annotations or past approval; denial, registration change, or review cancellation | Actual Pi client and stdio server calls agree with file effects |
65
+ | Project MCP startup | Saved trust or explicit trust selection | Project with no decision, or explicit distrust | Trust decision limits server startup effects before tool invocation |
66
+ | Additional MCP approval | Request matching original tool, connection, and actual input | Forged call ID, another tool or connector, or automatic handling of required user input | Only fresh approval bound to the original call is allowed |
67
+ | Concurrent MCP calls | Approved file change among concurrent calls with different inputs | Borrowing another request's approval by reusing caller IDs | Internal connection IDs differ; denied file stays unchanged |
68
+ | MCP name collision | Explicit user approval for `node_repl/js` | Missing approval UI or explicit denial | Actual stdio server file effects agree with approval dialog counts |
69
+ | Pi control files | MCP settings directly changed by the user on the host | Model changes to MCP settings, trusted extension entry points, or relative imports | Files unchanged; external effects blocked after reload. User changes apply at next startup |
70
+ | Review response types | String risk level and valid approval | Invalid risk or authorization level such as arrays or `null` | External file unchanged; technical failure reaches the next model request |
71
+ | Literal paths | `[route]` and `*` filenames inside the allowed workspace | Additional permission roots containing pattern characters and direct SDK profiles | Blocked before approval and execution; similarly named siblings unchanged |
72
+ | Direct command after denial stop | Newly requested direct user shell command | Follow-up execution by stopped model, caller cancellation, or stale session | No model write; direct command succeeds; original cancellation contract preserved |
73
+ | Audit records | Valid approval with a quoted review reason | Recording synthetic secrets | Valid JSON, masked values, and approved file changes |
74
+ | Normal Pi and CLI entry points | Official MCP through default package extension; explicit CLI provider and model selection | Duplicate MCP connection or fallback execution for a nonexistent model | Actual Pi and CLI effects agree with model and review calls |
75
+ | Pi resources | Global skills and trusted project skills, prompts, and themes | Untrusted project resources or automatic extension execution | Resources reach model context and expanded prompts; no untrusted code effects |
76
+ | MCP reconnection cleanup | Approved call after reconnecting from output mode to RPC | Leftover previous server processes | Both created PIDs absent after normal shutdown |
77
+
78
+ ### Codex-based harness in the earlier structure
79
+
80
+ The baseline is public source `rust-v0.160.0`, commit `a956835d020762cb2b570053af06f643a11c0ecc`. The public harness's verification contracts were adapted to Pi's stream and tool paths. The earlier versions evaluated `.rules` with the actual Rust `codex-execpolicy` dependency; the current source uses the TypeScript port and reference corpus described above. Neither record means that the entire upstream Rust test suite was run.
81
+
82
+ | Codex baseline | Adapted verification |
78
83
  | --- | --- |
79
- | [`responses.rs::mount_sse_sequence`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/common/responses.rs#L1466) | 응답을 정해진 순서로 재생하고 주 모델·검토자 호출의 초과와 누락을 실패 처리한다. |
80
- | [`exec_policy.rs::execpolicy_blocks_shell_invocation`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/exec_policy.rs#L517) | 정책 거부 결과가 다음 주 모델 요청에 도구 결과로 전달되는지 확인한다. |
81
- | [`request_permissions.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/request_permissions.rs#L834) | 읽기 전용 상태의 추가 권한이 승인하지 않은 작업 공간·임시 경로 쓰기로 넓어지지 않는지 확인한다. |
82
- | [`guardian_review_cancellation.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/guardian_review_cancellation.rs#L39) | 직접 도구와 중첩 코드 실행의 검토를 취소한 뒤 늦은 승인이 실행으로 이어지지 않는지 확인한다. |
83
- | [`execpolicy`](https://github.com/openai/codex/tree/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/execpolicy) | 원본 Starlark 엔진과 예제 검증·실행 파일 경로·네트워크 규칙 변환을 연결한다. |
84
- | [`agents_md.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/src/agents_md.rs) | 프로젝트 루트·지침 우선순위·바이트 한도·신뢰 상태를 확인한다. |
85
- | [`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 우선순위, 엄격한 자동 검토, 민감한 중첩 승인과 호출 출처 결합을 확인한다. |
84
+ | [`responses.rs::mount_sse_sequence`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/common/responses.rs#L1466) | Replays responses in a fixed sequence and fails on excess or missing main-model or reviewer calls. |
85
+ | [`exec_policy.rs::execpolicy_blocks_shell_invocation`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/exec_policy.rs#L517) | Checks that policy denials reach the next main-model request as tool results. |
86
+ | [`request_permissions.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/request_permissions.rs#L834) | Checks that additional read-only permissions do not expand to unapproved workspace or temporary writes. |
87
+ | [`guardian_review_cancellation.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/guardian_review_cancellation.rs#L39) | Checks that late approval cannot execute after cancelling review in direct tools or nested code execution. |
88
+ | [`execpolicy`](https://github.com/openai/codex/tree/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/execpolicy) | Connects the original Starlark engine, example validation, executable paths, and network rule conversion. |
89
+ | [`agents_md.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/src/agents_md.rs) | Checks project root, instruction precedence, byte limits, and trust state. |
90
+ | [`mcp_tool_call.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/mcp_tool_call.rs), [`session/mcp.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/src/session/mcp.rs) | Checks annotation precedence, strict automatic review, sensitive nested approval, and binding to the call source. |
86
91
 
87
- 현재 재생 하네스는 [`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)에 보존했다. 하네스 자체도 호출 누락·초과, 이미 취소된 요청을 검사한다.
92
+ The current replay harness is in [`test/harness/scenarios.mjs`](../../test/harness/scenarios.mjs), and scenarios are in [`test/conformance/protection.test.mjs`](../../test/conformance/protection.test.mjs). Earlier OS isolation checks are preserved in the [`v0.1.2` tests](https://github.com/buYoung/pi-codex-auto-review/blob/v0.1.2/test/native/sandbox.test.mjs). The harness itself checks missing and excess calls and requests already cancelled.
88
93
 
89
- 확장 검증 중 Docker PID 1 아래 좀비 프로세스 131개가 누적되고 `grep`의 스레드 생성이 실패하는 문제를 재현했다. 하네스의 `--init`과 고아 회수 사전 검증으로 수정하며, PID 한도 256개와 내부 파일·네트워크·seccomp 제한을 유지한다.
94
+ Extension verification reproduced 131 zombie processes accumulating under Docker PID 1 and `grep` failing to create threads. Harness `--init` and a preliminary orphan-reaping check addressed this while retaining the 256-PID limit and internal file, network, and seccomp restrictions.
90
95
 
91
- 후속 검증에서는 실행 전에 만든 하드링크가 macOS의 보호 파일 읽기와 외부 파일 쓰기를 우회하는 것을 재현했다. 실행 전 링크 수와 허용 범위의 이름을 대조해 수정했다. 또 Pi의 기본 신뢰값을 그대로 사용하면 새 프로젝트의 MCP 서버가 승인 도구 호출 전에 시작되는 것을 재현해, 저장된 신뢰와 명시적 선택으로 제한했다. 재현·수정 근거는 [하드링크 인계](../handoffs/auto-review/15-hard-links.json)와 [운영체제 후속 인계](../handoffs/auto-review/18-platform-followups.json)에 있다.
96
+ Follow-up checks reproduced preexisting hard links bypassing protected-file reads and external-file writes on macOS. Comparing link counts with names in the allowed scope before execution addressed this. Pi's default trust value also allowed a new project's MCP server to start before approval tool calls; startup was restricted to saved trust or explicit selection. Reproduction and fix evidence is in the [hard-link handoff](../handoffs/auto-review/15-hard-links.json) and [platform follow-up handoff](../handoffs/auto-review/18-platform-followups.json).
92
97
 
93
- 실제 Ubuntu Docker에서는 내부 `bwrap`의 마운트가 외부 AppArmor 정책에 차단됐다. 하네스는 AppArmor 지원 여부를 확인하고 소유한 검증 컨테이너에만 `apparmor=unconfined`를 지정한다. 요청값과 실제 프로필을 실행 보고서에 기록하며, 내부 샌드박스의 파일·네트워크·seccomp 검증은 그대로 수행한다. 이는 [Docker의 컨테이너별 프로필 선택](https://docs.docker.com/engine/security/apparmor/)을 사용하는 검증 환경 설정이다. 수정 전후 실행은 [AppArmor 인계](../handoffs/auto-review/20-docker-apparmor.json)에 보존했다.
98
+ In actual Ubuntu Docker, external AppArmor policy blocked internal `bwrap` mounts. The harness checks AppArmor availability and sets `apparmor=unconfined` only for owned verification containers. Requested values and actual profiles are recorded in run reports, while internal sandbox file, network, and seccomp checks still run. This is a verification environment setting using [Docker's per-container profile selection](https://docs.docker.com/engine/security/apparmor/). Before-and-after runs are preserved in the [AppArmor handoff](../handoffs/auto-review/20-docker-apparmor.json).
94
99
 
95
- ARM64 커널에서 x64 프로그램을 실행한 추가 검증에서는 142개 중 정상 셸 출력 사례 하나가 3초 제한을 넘겼다. 해당 기능 검사의 호출자 지정 제한을 15초로 보정했다. 별도 생명주기 검사는 실제 2초 제한, 3.5초 반환 상한, 지연된 파일 변경 차단을 계속 확인한다. 실행기의 제한 처리 코드는 변경하지 않았다. 최초 실패와 집중 검사 결과는 [에뮬레이션 시간 인계](../handoffs/auto-review/22-emulated-shell-timing.json)에 있다.
100
+ Additional verification running x64 programs on an ARM64 kernel found that one normal shell-output case out of 142 exceeded a three-second limit. The caller-specified timeout for that functional check was adjusted to fifteen seconds. A separate lifecycle check continues to verify an actual two-second timeout, a 3.5-second return limit, and blocking delayed file changes. Executor timeout handling was unchanged. The initial failure and focused results are in the [emulated shell timing handoff](../handoffs/auto-review/22-emulated-shell-timing.json).
96
101
 
97
- macOS의 첫 최종 집계에서는 패키지 검사의 20초 관찰 시간이 초과됐다. 관찰 시간을 늘린 진단 복사본은 12.6초에 정상 완료됐으며, 원본 검사와 20초 제한을 유지한 재집계도 통과했다. 최초 지연의 세부 원인은 특정하지 못했다. [패키지 시간 관찰 인계](../handoffs/auto-review/24-macos-package-timing.json)에 초기 실패와 후속 성공을 함께 보존했다.
102
+ The first final macOS aggregation exceeded the package check's twenty-second observation window. A diagnostic copy with a longer window completed normally in 12.6 seconds. Reaggregation retaining the original check and twenty-second limit also passed. The specific cause of the initial delay was not determined. The [package timing handoff](../handoffs/auto-review/24-macos-package-timing.json) preserves both the initial failure and subsequent success.
98
103
 
99
- 일반 MCP 승인과 엄격 검토는 구분한다. Codex의 일반 경로는 검토자가 자동 모델이어도 annotation과 승인 모드를 따르며, 엄격 검토는 이런 생략 조건을 허용하지 않는다. 중첩 요청은 원래 호출의 엄격 검토 요구를 낮출 수 없다. 정정한 동작과 회귀 검증은 [MCP 승인 경로 인계](../handoffs/auto-review/19-mcp-routing.json)에 기록했다.
104
+ Normal MCP approval and strict review are distinct. Codex's normal path follows annotations and approval modes even with an automatic reviewer; strict review does not allow those skip conditions. Nested requests cannot lower the original call's strict-review requirement. Corrected behavior and regression checks are recorded in the [MCP routing handoff](../handoffs/auto-review/19-mcp-routing.json).
100
105
 
101
- 현재 E2E는 [`test/e2e/guard.test.mjs`](../../test/e2e/guard.test.mjs)에 있다. 배열 위험 등급이 외부 파일을 변경하는 현상, 제한된 경로의 `[]`가 형제 파일 쓰기를 허용하는 현상, `node_repl/js`가 승인 없이 MCP 효과를 실행하는 현상을 수정 전 실제 Pi·OS 경로에서 재현했다. 감사 JSON 실패와 거부 중단 후 직접 명령 실패도 같은 방식으로 재현했다. 기본 패키지 검사는 공개 Pi 세션과 실제 MCP 서버까지 실행하도록 확장했으므로, 하위 프로세스 관찰 한도를 기존 20초에서 60초로 조정했다. 실제 실행기의 취소·시간 제한 검사는 별도로 유지한다.
106
+ Current E2E checks are in [`test/e2e/guard.test.mjs`](../../test/e2e/guard.test.mjs). Before fixes, actual Pi and OS paths reproduced array risk levels changing external files, `[]` in restricted paths allowing sibling writes, and `node_repl/js` producing MCP effects without approval. Audit JSON failures and direct command failures after a denial stop were also reproduced this way. The default package check was expanded to run a public Pi session and actual MCP server, so its subprocess observation limit changed from twenty to sixty seconds. Actual executor cancellation and timeout checks remain separate.
102
107
 
103
- CLI 관찰기는 Pi 0.99.1의 확장용 호환 레지스트리가 가리키는 실제 `ModelRuntime`을 계측한다. 호환 레지스트리만 감싸면 주 에이전트 호출을 놓치므로, 로컬 HTTP 공급자 대조군으로 주 실행 2회·검토 1회의 실제 수신과 관찰 기록을 대조한다. 검토 출력 한도 `777`과 주 실행의 4096토큰 상한이 HTTP 요청에 전달되고, 최종 파일이 변경돼야 통과한다. 이 계측은 고정 버전용 검증 코드이며 제품의 응답을 대체하지 않는다.
108
+ The CLI observer instruments the actual `ModelRuntime` referenced by Pi 0.99.1's extension compatibility registry. Wrapping only that registry misses main-agent calls. A local HTTP provider control compares two main execution calls and one review call actually received with observation records. Passing requires the review output limit `777` and main execution limit of 4096 tokens to reach HTTP requests and the final file to change. This instrumentation is verification code for the pinned version; it does not replace product responses.
104
109
 
105
- 테스트 프로세스의 `TMPDIR`은 해당 실행이 만든 디렉터리로 지정하고 종료 시 정리한다. 호스트의 공유 임시 경로가 디렉터리 검사 한도 10만 개를 넘는 환경을 관찰했기 때문이다. 실행기의 검사 한도와 불완전한 검사의 차단 정책은 유지하며, 기본 임시 루트 허용과 명시적 제외를 별도 대조군으로 검사한다.
110
+ Each test process uses a `TMPDIR` directory created for that run and removes it on exit. This followed an observation that shared host temporary paths exceeded the 100,000-entry directory inspection limit. The executor's inspection limit and blocking policy for incomplete inspection remain intact. Separate controls check default temporary-root access and explicit exclusion.
106
111
 
107
- 첫 ARM64 Docker 실행에서는 154개 중 정상 `grep` 대조군 하나가 실패했다. 추가 검사와 실제 마운트 관찰에서, 존재하지 않는 `.git`이 `/dev/null` 장치로 바인딩되고 `nodev`로 인해 읽기가 거부되는 것을 확인했다. `.git/HEAD` 하위 차단을 함께 전달해 런타임이 읽기 전용 빈 디렉터리를 만들도록 수정했다. 원래 부모 차단은 유지하며, 읽기 선언을 늘리는 초기 수정은 별도 대조군에서 불필요함을 확인하고 되돌렸다. SDK 호출자의 읽기 전용 경로 선택도 보존한다. 추가 대조군은 정상 검색·일반 디렉터리 생성·Pi 설정 생성 차단을 함께 확인한다. 허용 루트와 절대 차단 루트가 직접 겹치거나 별칭으로 겹치는 경우는 실제 경로로 정규화한 뒤 실행 전에 거부한다.
112
+ In the first ARM64 Docker run, one normal `grep` control out of 154 failed. Further checks and actual mount observation showed that a nonexistent `.git` was bound to `/dev/null` and denied reads because of `nodev`. Passing a `.git/HEAD` child block as well made the runtime create an empty read-only directory. The original parent block remained. An initial change expanding read declarations was reverted after a separate control showed it was unnecessary. SDK callers' read-only path choices were preserved. Additional controls check normal searches, ordinary directory creation, and blocked Pi settings creation together. Allowed and absolutely blocked roots that overlap directly or through aliases are normalized to actual paths and rejected before execution.
108
113
 
109
- 추가 승인 연결 검사에서는 같은 호출자 ID를 사용한 두 MCP 요청이 겹칠 때 거부 대상 파일이 변경되는 것을 재현했다. MCP 전송마다 내부에서 생성한 고유 ID로 추가 승인을 연결하도록 수정했다. 실제 Pi에 등록된 도구를 동시에 실행해, 두 검토 입력이 각각 보존되고 승인된 파일만 변경되는지 확인한다.
114
+ Additional approval binding checks reproduced a denied file changing when two MCP requests overlapped with the same caller ID. Additional approvals now bind to a unique ID generated internally for each MCP transmission. Concurrent calls to tools registered in actual Pi verify that both review inputs are preserved separately and only the approved file changes.
110
115
 
111
- ### 이전 OS 격리 검증이 보장했던 범위
116
+ ### Scope of the earlier OS isolation verification
112
117
 
113
- - 주 모델과 검토자를 재생하는 시나리오는 실제 Pi와 OS 샌드박스를 사용한다. 이 결과를 실제 GLM5.3의 판단 정확도로 표시하지 않는다. 실모델 SDK 4개와 CLI 1개 사례는 별도 실행·집계한다. 통합 판정에는 CLI의 실제 검토 호출·파일 변경·자격 증명 미기록도 필요하다.
114
- - 기본 임시 디렉터리 쓰기와 일반 외부 파일 읽기는 기본 프로필이 허용하는 동작이다. 작업 공간 밖이라는 이유만으로 항상 차단된다고 가정하지 않는다.
115
- - 셸 실행은 트랜잭션이 아니다. 허용된 첫 번째 쓰기 뒤 두 번째 쓰기가 거부되어도 첫 번째 변경은 남는다. 이 부분 효과도 테스트에서 명시적으로 확인한다.
116
- - Linux에서 새 파일 생성은 승인할 부모 디렉터리 범위가 필요할 수 있다. 좁은 기존 파일 승인과 새 파일 생성의 범위를 구분한다.
117
- - 사전 생성 하드링크와 좁은 승인 파일의 다른 이름을 검사한다. 실행 중 격리 밖의 호스트 프로그램이 동시에 링크 구조를 바꾸는 공격까지 보장하지 않는다. 검사 실패·한도 초과는 실행 차단으로 처리한다.
118
- - Linux x64 호스트 실행과 ARM64 커널의 x64 실행은 기록을 분리한다. 최종 집계에는 같은 소스의 실제 Linux x64 호스트 결과가 필요하다.
119
- - Windows는 실제 운영체제에서 원본 규칙 엔진·승인 정책과 미지원 네이티브 실행의 사전 거부를 확인하는 별도 검증이다. Windows 네이티브 격리의 성공을 뜻하지 않는다.
120
- - 외부 MCP 실행기는 신뢰한 통합 계층이다. 이미 외부 서버에 전송된 요청의 취소 효과나 모든 공급자의 계정 식별·부수 효과를 보장하지 않는다. 비어 있는 승인 폼은 처리하지만 일반 입력 폼·URL elicitation은 거부한다. Pi에 없는 Computer Use 분류와 승인 예외는 제거했다.
121
- - 패턴 문자가 들어간 네이티브 권한 루트는 런타임에서 문자 그대로 표현할 수 없어 차단한다. 일반 작업 영역 안의 특수문자 파일명 지원과 구분한다. 신뢰한 확장의 디렉터리는 제어 코드로 보호하지만, 임의의 신뢰 확장이 그 밖의 파일을 실행하거나 import하는 모든 의존 관계를 자동 분석하지는 않는다.
122
- - HTTPS CONNECT·SOCKS5 TCP·IPv6와 직접 UDP 차단을 검사한다. SOCKS5 UDP 및 모든 네트워크 프로토콜을 지원·검증했다고 주장하지 않는다.
123
- - 독점 Codex 모델과의 모든 판단 동일성은 보장하지 않는다. 공개 정책·흐름과 선택한 GLM5.3의 관찰 결과를 구분한다.
118
+ - Scenarios replaying the main model and reviewer use actual Pi and an OS sandbox. They do not establish live GLM5.3 judgment accuracy. Four live SDK cases and one CLI case are executed and aggregated separately. Integrated passing results also require actual CLI review calls, file changes, and no credential recording.
119
+ - Default temporary-directory writes and ordinary external-file reads are allowed by the default profile. Operations are not assumed always blocked solely because they are outside the workspace.
120
+ - Shell execution is not transactional. If a first allowed write succeeds and a second write is denied, the first change remains. Tests explicitly check these partial effects.
121
+ - Creating new files on Linux may require approval of the parent directory scope. Narrow approval of an existing file and creation of a new file are distinct scopes.
122
+ - Preexisting hard links and alternative names for narrowly approved files are checked. Concurrent changes to link structure by host programs outside isolation during execution are not covered. Inspection failures and limit overflows block execution.
123
+ - Linux x64 host execution and x64 execution on an ARM64 kernel are recorded separately. Final aggregation requires actual Linux x64 host results from the same source.
124
+ - Windows verification separately checks the original rule engine, approval policy, and pre-execution rejection of unsupported native execution on the actual OS. It does not establish successful Windows native isolation.
125
+ - External MCP executors are trusted integration layers. Cancellation of requests already sent to external servers, and every provider's account identification or side effects, are not guaranteed. Empty approval forms are handled; ordinary input forms and URL elicitation are rejected. Computer Use classifications and approval exceptions absent from Pi were removed.
126
+ - Native permission roots containing pattern characters are blocked because the runtime cannot represent them literally. This is distinct from support for special-character filenames in ordinary workspaces. Trusted extension directories are protected as control code, but all dependencies that arbitrary trusted extensions execute or import elsewhere are not automatically analyzed.
127
+ - HTTPS CONNECT, SOCKS5 TCP, IPv6, and direct UDP blocking are checked. This does not claim support or verification of SOCKS5 UDP or every network protocol.
128
+ - Identical decisions to the proprietary Codex model are not guaranteed. Public policies and flows are distinct from observed results of the selected GLM5.3 model.
124
129
 
125
- ## 실행
130
+ ## Running verification
126
131
 
127
- 저장소 루트에서 실행한다. 아래 명령은 모두 실제 자격 증명을 사용하지 않는다.
132
+ Run from the repository root. None of these commands uses actual credentials.
128
133
 
129
134
  ```sh
130
135
  npm run build
@@ -133,7 +138,7 @@ npm run test:execution
133
138
  npm run verify:docker -- --mode offline --platform linux/amd64
134
139
  ```
135
140
 
136
- 실모델 검증은 `OLLAMA_API_KEY`가 export된 셸에서 실행한다. `.zshrc`에 저장했다면 해당 셸에서 먼저 불러온다. 키 값은 명령 인자에 넣지 않는다. 앞선 오프라인 실행의 출력에서 확인한 이미지 식별자를 사용한다.
141
+ Run live model verification in a shell with `OLLAMA_API_KEY` exported. If it is saved in `.zshrc`, load that file in the shell first. Do not put the key value in command arguments. Use the image identifier from the preceding offline run's output.
137
142
 
138
143
  ```sh
139
144
  export OLLAMA_API_KEY
@@ -141,13 +146,13 @@ npm run verify:docker -- --mode conformance --platform linux/amd64 --model glm-5
141
146
  npm run verify:guard
142
147
  ```
143
148
 
144
- `verify:platform`은 실행한 운영체제의 전체 결과를 남기고, Windows의 `verify:windows`는 규칙 엔진·파일 실행·취소 결과를 남긴다. GitHub Actions에는 Ollama 키를 보내지 않는다.
149
+ `verify:platform` records complete results for the operating system where it runs. Windows `verify:windows` records rule engine, file execution, and cancellation results. No Ollama key is sent to GitHub Actions.
145
150
 
146
- Docker 엔진에 따라 이미지를 내보낼 때와 불러온 뒤의 ID가 다를 수 있다. 이번 실행에서는 CI의 설정 해시를 로컬 매니페스트가 참조하고, 19개 레이어가 모두 같음을 확인했다. 이 경우에는 `docker image load`가 반환한 ID로 오프라인 검증을 다시 실행하고, 같은 ID로 실모델 검증을 실행한다.
151
+ Depending on the Docker engine, image IDs may differ between export and loading. In the recorded run, the local manifest referenced the CI configuration hash, and all nineteen layers matched. In this case, rerun offline verification with the ID returned by `docker image load`, then use the same ID for live verification.
147
152
 
148
153
  ```sh
149
154
  npm run verify:docker -- --mode offline --platform linux/amd64 --image <loadedImageID>
150
155
  npm run verify:docker -- --mode conformance --platform linux/amd64 --model glm-5.3 --image <loadedImageID>
151
156
  ```
152
157
 
153
- `verify:guard`는 현재 운영체제에서 같은 소스의 결과를 기록한다. 다른 플랫폼·이미지·실모델 결과를 로컬 통과로 대신하지 않는다. 실행 기록은 `.reports/pi-guard/runs/`에 별도로 남긴다.
158
+ `verify:guard` records results for the same source on the current operating system. A local pass does not replace other platform, image, or live model results. Execution records are kept separately under `.reports/pi-guard/runs/`.