# 자동 검토 보호 경계 검증

[English](auto-review-protection.md) | **한국어**

이 검증은 **정책 판단, 실제 Pi 도구 결과, 파일·네트워크 효과**를 함께 확인합니다. 허용 대조군이 먼저 성공해야 차단 결과도 의미가 있습니다. 예외나 오류 메시지만 보고 보호에 성공했다고 판정하지 않습니다.

현재 소스는 승인을 돕는 확장입니다. OS 격리·네트워크 프록시·재귀 디렉터리 검사를 하지 않으며, 승인된 도구는 Pi의 원래 실행기를 씁니다. 아래의 이전 샌드박스 검증 기록은 현재 실행 구조를 보장하지 않습니다.

## 현재 승인·실행 검증

| 대상 | 확인하는 결과 |
| --- | --- |
| `/approve` | Codex 원문 설명·영문 화면·좁은 터미널 줄바꿈, 선택한 승인 방식의 실제 파일 효과와 저장 |
| `/approve-model` | 현재 `/scoped-models` 범위, 사용 불가·중복 모델 제외, 선택 도중 범위 변경 거부, 실제 Pi 검토자 적용과 주 모델 유지 |
| 설정 변경 | 동시 선택 병합, 저장 실패 시 기존 설정 유지, 이전 검토의 늦은 승인 차단 |
| Pi 실행 | 원래 SDK 실행, cwd·환경·출력·시간 제한·취소 신호 유지 |
| 시작 | 관계없는 탐색 불가 디렉터리가 있어도 전수 탐색 없이 실행 |
| 보호·거부 | 직접 보호 경로·금지 규칙은 검토 전 거부, 실패·취소·시간 초과는 실행으로 이어지지 않음 |
| 네트워크 사전 검토 | 스킴을 생략했거나 설정 파일을 쓰거나 허용 URL과 설정 파일을 함께 쓴 curl 요청도 자동·사용자 검토를 거침. 허용 대조군만 소유한 HTTP 서버에 도달 |
| PowerShell | Codex `powershell_lowering.json` 사례를 재생하고, Codex가 해석하지 않는 스크립트와 Codex가 변환(lowering)하는 주석 형태를 바깥 호출 전체(`[<powershell 실행 파일>, "-Command", 스크립트]`)로만 대조하는지 확인. cmdlet·별칭의 경로·네트워크·규칙 분류, 읽기 캐시 재사용, 선택 활성화, 컨트롤러 실행도 확인 |
| Windows 경로 | 플랫폼을 주입한 단위 검증으로 MSYS·Cygwin·WSL 인자 대응, Windows 경로 별칭, 대소문자·정규화 무시 보호, `/tmp` 루트, 실행 파일 이름을 확인. Windows 전용 검증은 실제 `canonicalPath()`와 Git Bash 판단을 확인 |
| TypeScript 규칙 | 고정한 Codex 실행 파일의 실제 결과 280건을 재생해 규칙 출력·입력 거부·취소·자원 한도·요청 형식 검증을 확인 |
| 배포 패키지 | 실제 Pi 로더로 시작하고 압축 파일 안의 동기·작업 스레드 규칙 평가 실행. Rust 결과물·`.node`·샌드박스 결과·묶인 의존성 부재 |

검토자와 UI를 재생하는 검증은 실제 Pi와 파일 결과를 쓰지만, 실제 모델의 판단 정확도를 증명하지는 않습니다. 승인된 셸 내부의 간접 파일 접근, 하드링크, 실행 중 네트워크 변경은 OS가 제한하지 않습니다. 호출자의 환경 변수는 실행할 때 그대로 두고, 검토 증거에서만 인증 변수를 뺍니다.

이전 저장소에서는 `verify:guard`가 현재 운영체제의 결과와 소스 해시·감사 기록을 저장했습니다. 다른 운영체제와 실제 모델은 따로 실행한 결과가 필요하며, 실행하지 않은 범위는 통과로 표시하지 않습니다.

승인 설명은 [공식 승인 선택 화면](https://learn.chatgpt.com/docs/security-administration)을 따릅니다. 검토자 분리, 거부 피드백, 3회 연속 또는 최근 50회 중 10회 거부 시 중단, 취소는 [공식 Auto-review 문서](https://learn.chatgpt.com/docs/sandboxing/auto-review)와 대조합니다. 현재 구현은 OS 경계를 강제하지 않으므로 Codex 샌드박스와 같은 수준의 보안을 보장하지 않습니다.

원본 결과는 [`tests/fixtures/execpolicy-reference.json`](../../tests/fixtures/execpolicy-reference.json)에 있습니다. 원본 실행 파일의 리비전과 SHA-256을 기록하고, 유니코드 공백·잘못된 유니코드 이스케이프·숫자 변환 경계를 포함해 성공 201건·거부 79건을 담고 있습니다. TypeScript 구현은 공개 비동기 API로 대조하며, 테스트와 빌드에 원본 실행 파일이 더 이상 필요하지 않습니다. POSIX 전용 경로 사례는 Windows 재생에서 빼고, 기존 Windows 전용 경로 검사는 그대로 실행합니다. 이는 기록된 호환성 사례이며 모든 Starlark 프로그램에서 동등하다는 증명은 아닙니다.

## 검증 실행

[pi-packages](https://github.com/buYoung/pi-packages) 저장소 루트에서 실행합니다. 이 명령은 실제 자격 증명을 쓰지 않습니다.

```sh
pnpm install
pnpm --filter "@buyong/pi-codex-auto-review..." build
pnpm --filter @buyong/pi-codex-auto-review test:unit
```

`test:unit`은 현재 운영체제에서 단위·통합·적합성·실행·종단 간 검증을 실행합니다. 로컬에서 통과해도 다른 플랫폼·이미지·실제 모델 결과를 대신하지 않습니다. 저장소 workflow는 이 패키지가 선택되면 Ubuntu·macOS·Windows(Git Bash)에서, Codex 통합 패키지만 선택되면 macOS·Windows에서만 같은 검증을 실행합니다. Windows 체크아웃은 LF 줄 끝을 유지합니다.

아래 과거 기록을 만든 Docker(`verify:docker`), 플랫폼(`verify:platform`, `verify:windows`), 증거(`verify:guard`) 명령은 이전 [pi-codex-auto-review](https://github.com/buYoung/pi-codex-auto-review) 저장소에 남아 있으며 이 저장소에는 없습니다.

## 이전 OS 격리 검증 기록(v0.1.2 이하)

다음 기록은 샌드박스가 있던 `v0.1.2` 이하 소스에 관한 것입니다. GLM5.3 검증은 SDK 경로 4개와 CLI 1개 사례를 구분했습니다. 이전 플랫폼 검증은 [운영체제 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/17-platform-qualification.json)에, 이전 112개 검증은 [보호 경계 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/10-protection-matrix.json)에 있습니다. 현재 소스의 실행 결과는 소스 해시가 일치하는 최신 실행 기록으로 확인하세요.

개선 전 `85008b0` 시점에는 같은 소스가 macOS, 실제 Linux x64, 네이티브 Docker, 에뮬레이션 Docker에서 각각 142개를 통과했습니다. GLM5.3 네 사례와 Windows의 별도 규칙·사전 거부 검증도 통과했고, 감사 기록 217건과 실제 모델 로그·보고서 7개에 키가 드러나지 않았음을 확인했습니다. 이후 전체 검토에서 기존 검사에 없던 결함이 발견되었습니다. 이 과거 결과는 아래 회귀 사례나 현재 소스의 통과 결과를 대신하지 않습니다.

그 전체 개선의 수정 내역, 최종 실행 근거, 남은 플랫폼 조건은 [Pi 실행 개선 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/25-pi-runtime-alignment.md)에 정리했습니다.

### 이전 구조에서 보호되는 경우와 허용되는 경우

| 경계 | 허용 대조군 | 차단 또는 검토 대상 | 최종 관찰 |
| --- | --- | --- | --- |
| 파일 도구 6종 | 작업 공간의 `read`, `grep`, `find`, `ls`, `write`, `edit` | 절대 보호 경로의 같은 도구 호출 | 도구 오류, 검토자 호출 0회, 보호 파일 불변, 내용 비노출 |
| 기본 읽기·임시 경로 | 일반 외부 파일 읽기, 기본 임시 경로 쓰기 | 임시 쓰기 루트를 제외한 뒤 같은 쓰기 | 읽기는 유지되고 쓰기는 검토 후 거부 |
| 읽기 전용 프로필 | 명시적으로 승인한 기존 파일 쓰기 | 승인하지 않은 작업 공간·임시 경로의 형제 파일, 다음 호출 | 승인 파일만 변경되고 나머지 불변 |
| 검토 중 경로 변경 | 처음 검토한 심볼릭 링크 대상 | 검토 중 다른 형제 경로나 보호 경로로 링크 교체 | 오래된 승인 거부, 세 대상 모두 불변 |
| 위험·인가 판단 | 높은 위험이라도 충분한 인가가 있는 합성 사례 | 낮은 위험의 명시적 정책 거부, 인가 부족, 최고 위험 | 주 모델에 전달된 도구 결과와 실제 쓰기 일치 |
| 검토 기술 오류 | 정상 구조의 승인 응답 | 공급자 오류, 잘못된 JSON, 권한 추가 필드 삽입, 시간 초과 | 정책 거부와 구별되는 실패, 파일 불변 |
| 승인 경로 설정 | 일반 작업 공간 쓰기·셸 출력 | 비활성화한 샌드박스·명령 규칙 승인 범주 | 검토자를 호출하지 않고 거부 |
| 명령 규칙 | 규칙에 걸리지 않는 정상 명령 | 허용 규칙과 동시에 일치하는 금지 규칙, 중첩 셸 | 직접·중첩 실행 모두 거부, 대상 파일 미생성 |
| 검토 취소 | 실제 Pi 직접 도구·`codemode`에서 검토 시작 | 검토 중 취소 후 늦게 도착한 승인 | 취소 신호 전달, 쓰기 미실행 |
| 파일 변조 7종 | 작업 공간의 추가 쓰기·길이 변경·삭제·이동·복사·모드 변경·하드링크 생성 | 같은 작업의 범위 밖 대상 | 내용·존재·모드·원본 파일을 각각 확인 |
| 네트워크 목적지 | 허용 와일드카드의 하위 도메인 | 루트 도메인, 비슷한 접미사, 명시적 거부 도메인 | 소유한 서버의 실제 수신 횟수 |
| HTTP 리다이렉트 | 허용 호스트의 최초 요청 | 거부 호스트로의 리다이렉트 | 최초 요청만 도착하고 거부 대상은 미도달 |
| 환경 변수 | 명시적인 일반 값이 자식 인터프리터에 전달 | 인증·로더·사용자 프록시 변수의 합성 비밀 값 | 자식 환경에 비밀 값 부재, 일반 값 보존 |
| Docker 프로세스 정리 | `--init`이 종료된 고아 프로세스를 회수 | PID 1이 고아를 회수하지 못하는 컨테이너 | 제한 시간 안에 `/proc/<pid>` 소멸, 실패하면 본 검증 진입 차단 |
| 사전 생성 하드링크 | 모든 이름이 허용 범위 안에 있는 같은 inode | 보호 파일 별칭, 범위 밖 쓰기 별칭, 좁게 승인한 파일의 형제 별칭 | 실행 전 차단, 외부 내용 불변. 모든 별칭을 포함한 디렉터리 승인은 허용 |
| 탐색 불가 디렉터리 | 접근 불가 하위 트리 옆의 정상 파일 쓰기 | 하위 트리의 권한 변경·읽기, 이름을 알면 접근 가능한 미검증 트리 | 접근 불가 트리는 OS 경계에서도 차단. 검색 가능 범위를 다 확인하지 못하면 시작 거부 |
| HTTPS CONNECT | 합성 인증서를 검증한 소유 서버 요청 | 허용하지 않은 목적지, 신뢰하지 않은 인증서 | 실제 HTTPS 응답과 서버 수신 횟수, 인증 실패 시 HTTP 효과 없음 |
| SOCKS5·UDP | 허용 SOCKS5 TCP, 호스트의 UDP 대조 요청 | 명시적으로 거부한 SOCKS5 목적지, 샌드박스의 직접 UDP | 허용 TCP만 도달, 직접 UDP 추가 수신 없음 |
| IPv6 | 동등한 IPv6 표기의 프록시 허용, 실행 중 정확한 목적지 승인 | 명시적 IPv6 거부, 직접 IPv6 통신 | 주소·포트가 검토에 전달되고 허용 요청만 서버 도달 |
| 원본 `.rules` | Starlark 함수·문자열 보간·대안 인자·실행 파일 경로·네트워크 규칙 | 틀린 예제, 경로 제약 위반, 잘못된 규칙, 취소 | 고정한 Codex 엔진의 결과가 실제 정책과 네이티브 설정에 전달 |
| 자동 컨텍스트 | 신뢰한 루트부터 현재 위치까지의 지침, 전역·파일 우선순위 | 신뢰하지 않은 프로젝트, 보호 경로 별칭, 초과 바이트 | 출처와 내용이 Pi·검토자에 전달되며 다시 불러온 뒤 갱신 |
| MCP 최종 실행 | 일반 읽기 전용·설정상 허용, 검토로 승인된 정확한 호출 | 엄격 요청에서 annotation·이전 승인으로 검토 생략, 거부, 등록 변경, 검토 취소 | 실제 Pi 클라이언트와 stdio 서버의 호출·파일 효과 일치 |
| 프로젝트 MCP 시작 | 저장된 신뢰 또는 명시적인 신뢰 선택 | 결정 없는 프로젝트, 명시적인 비신뢰 선택 | 도구 호출 전 서버 시작 효과도 신뢰 결정으로 제한 |
| MCP 추가 승인 | 원래 도구·연결·실제 입력과 일치하는 추가 요청 | 위조된 호출 ID, 다른 도구·커넥터 지목, 필수 사용자 입력의 자동 처리 | 원래 호출에 묶인 새 승인만 허용 |
| MCP 동시 호출 | 서로 다른 입력의 동시 호출 중 승인된 파일 변경 | 호출자 ID 재사용으로 다른 요청의 승인 차용 | 내부 연결 ID가 다르고, 거부 대상 파일은 불변 |
| MCP 이름 충돌 | `node_repl/js`에 대한 명시적 사용자 승인 | 승인 UI 없음, 명시적 거부 | 실제 stdio 서버의 대상 파일 변경 여부와 승인 창 횟수 일치 |
| Pi 제어 파일 | 사용자가 호스트에서 직접 바꾼 MCP 설정 | 모델의 MCP 설정·신뢰한 확장 진입점·상대 import 모듈 변경 | 파일 불변, 다시 불러온 뒤 외부 효과 차단. 사용자 변경은 다음 시작에 적용 |
| 검토 응답 타입 | 문자열 위험 등급과 정상 승인 | 배열·`null` 등 잘못된 등급·승인 수준 | 외부 파일 불변, 기술 실패가 다음 모델 요청에 전달 |
| 문자 그대로의 경로 | 허용된 작업 공간 안의 `[route]`와 `*` 파일명 | 패턴 문자가 포함된 추가 권한 루트와 SDK 직접 프로필 | 승인 전·실행 전 차단, 비슷한 이름의 형제 파일 불변 |
| 거부 중단 후 직접 명령 | 사용자가 새로 요청한 직접 셸 명령 | 중단된 모델의 후속 실행, 호출자 취소, 오래된 세션 | 모델 쓰기 미실행, 직접 명령 성공, 원래 취소 계약 유지 |
| 감사 기록 | 따옴표가 들어간 검토 사유의 정상 승인 | 합성 비밀 값의 기록 | JSON 파싱 성공, 값 가림, 승인된 파일 변경 |
| 일반 Pi·CLI 진입점 | 패키지 기본 확장의 공식 MCP, CLI의 명시적 공급자·모델 선택 | 중복 MCP 연결, 존재하지 않는 모델의 대체 실행 | 실제 Pi·CLI 도구 효과와 모델·검토 호출 일치 |
| Pi 자원 | 전역 skills와 신뢰한 프로젝트의 skills·프롬프트·테마 | 신뢰하지 않은 프로젝트 자원, 확장 자동 실행 | 모델 문맥과 펼쳐진 프롬프트에 전달, 신뢰하지 않은 코드의 효과 없음 |
| MCP 재연결 정리 | 출력 모드에서 RPC로 재연결한 뒤 승인 호출 | 이전 서버 프로세스 잔류 | 정상 종료 뒤 생성한 두 PID 모두 부재 |

### 이전 구조에서 Codex를 참고한 하네스

기준은 공개 소스 `rust-v0.160.0`, 커밋 `a956835d020762cb2b570053af06f643a11c0ecc`입니다. 공개 하네스의 검증 계약을 Pi의 스트림·도구 경로에 맞게 옮겼습니다. 이전 버전은 실제 Rust `codex-execpolicy`로 `.rules`를 평가했고, 현재 소스는 앞서 설명한 TypeScript 이식과 원본 결과 대조를 씁니다. 어느 기록도 upstream의 Rust 테스트 전체를 실행했다는 뜻은 아닙니다.

| Codex 기준 | 반영한 검증 |
| --- | --- |
| [`responses.rs::mount_sse_sequence`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/common/responses.rs#L1466) | 응답을 정해진 순서로 재생하고, 주 모델·검토자 호출이 넘치거나 빠지면 실패로 처리합니다. |
| [`exec_policy.rs::execpolicy_blocks_shell_invocation`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/exec_policy.rs#L517) | 정책 거부가 다음 주 모델 요청에 도구 결과로 전달되는지 확인합니다. |
| [`request_permissions.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/request_permissions.rs#L834) | 읽기 전용 추가 권한이 승인하지 않은 작업 공간·임시 경로 쓰기로 넓어지지 않는지 확인합니다. |
| [`guardian_review_cancellation.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/tests/suite/guardian_review_cancellation.rs#L39) | 직접 도구와 중첩 코드 실행에서 검토를 취소한 뒤 늦게 온 승인이 실행으로 이어지지 않는지 확인합니다. |
| [`execpolicy`](https://github.com/openai/codex/tree/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/execpolicy) | 이전 Rust 기반 버전에서 원본 Starlark 엔진과 예제 검증·실행 파일 경로·네트워크 규칙 변환을 연결했습니다. |
| [`agents_md.rs`](https://github.com/openai/codex/blob/a956835d020762cb2b570053af06f643a11c0ecc/codex-rs/core/src/agents_md.rs) | 프로젝트 루트·지침 우선순위·바이트 한도·신뢰 상태를 확인합니다. |
| [`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 우선순위, 엄격한 자동 검토, 민감한 중첩 승인과 호출 출처 결합을 확인합니다. |

현재 재생 하네스는 [`tests/harness/scenarios.mjs`](../../tests/harness/scenarios.mjs)에, 시나리오는 [`tests/conformance/protection.test.mjs`](../../tests/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)에 남아 있습니다. 하네스 자체도 호출 누락·초과와 이미 취소된 요청을 검사합니다.

확장 검증 중 Docker PID 1 아래에 좀비 프로세스 131개가 쌓이고 `grep`이 스레드를 만들지 못하는 문제를 재현했습니다. 하네스의 `--init`과 고아 프로세스 회수 사전 검사로 해결했으며, PID 한도 256개와 내부 파일·네트워크·seccomp 제한은 그대로 두었습니다.

후속 검사에서는 미리 만든 하드링크가 macOS에서 보호 파일 읽기와 외부 파일 쓰기를 우회하는 것을 재현했습니다. 실행 전에 링크 수와 허용 범위 안의 이름을 대조해 해결했습니다. 또 Pi의 기본 신뢰값으로는 새 프로젝트의 MCP 서버가 승인 도구 호출 전에 시작되는 것을 재현해, 저장된 신뢰나 명시적 선택이 있을 때만 시작하도록 제한했습니다. 재현과 수정 근거는 [하드링크 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/15-hard-links.json)과 [운영체제 후속 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/18-platform-followups.json)에 있습니다.

실제 Ubuntu Docker에서는 외부 AppArmor 정책이 내부 `bwrap`의 마운트를 막았습니다. 하네스는 AppArmor 지원 여부를 확인하고, 소유한 검증 컨테이너에만 `apparmor=unconfined`를 지정합니다. 요청값과 실제 프로필은 실행 보고서에 기록하며, 내부 샌드박스의 파일·네트워크·seccomp 검사는 그대로 실행합니다. 이는 [Docker의 컨테이너별 프로필 선택](https://docs.docker.com/engine/security/apparmor/)을 쓰는 검증 환경 설정입니다. 수정 전후 실행은 [AppArmor 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/20-docker-apparmor.json)에 있습니다.

ARM64 커널에서 x64 프로그램을 실행한 추가 검증에서는 142개 중 정상 셸 출력 사례 하나가 3초 제한을 넘겼습니다. 그 기능 검사에서 호출자가 지정한 제한을 15초로 조정했습니다. 별도의 생명주기 검사는 실제 2초 제한, 3.5초 반환 상한, 지연된 파일 변경 차단을 계속 확인합니다. 실행기의 제한 시간 처리는 바꾸지 않았습니다. 처음 실패와 집중 검사 결과는 [에뮬레이션 시간 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/22-emulated-shell-timing.json)에 있습니다.

macOS의 첫 최종 집계는 패키지 검사의 20초 관찰 시간을 넘겼습니다. 관찰 시간을 늘린 진단용 사본은 12.6초에 정상 완료되었고, 원래 검사와 20초 제한을 유지한 재집계도 통과했습니다. 처음 지연된 구체적 원인은 밝히지 못했습니다. [패키지 시간 관찰 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/24-macos-package-timing.json)에 처음 실패와 이후 성공을 함께 남겼습니다.

일반 MCP 승인과 엄격 검토는 다릅니다. Codex의 일반 경로는 자동 검토자를 써도 annotation과 승인 모드를 따르지만, 엄격 검토는 그런 생략 조건을 허용하지 않습니다. 중첩 요청은 원래 호출의 엄격 검토 요구를 낮출 수 없습니다. 바로잡은 동작과 회귀 검사는 [MCP 승인 경로 검증 기록](https://github.com/buYoung/pi-packages/blob/main/docs/verification/auto-review/19-mcp-routing.json)에 있습니다.

현재 E2E 검사는 [`tests/e2e/guard.test.mjs`](../../tests/e2e/guard.test.mjs)에 있습니다. 수정 전에 실제 Pi·OS 경로에서 배열 위험 등급이 외부 파일을 바꾸는 현상, 제한된 경로의 `[]`가 형제 파일 쓰기를 허용하는 현상, `node_repl/js`가 승인 없이 MCP 효과를 내는 현상을 재현했습니다. 감사 JSON 실패와 거부 중단 후 직접 명령 실패도 같은 방식으로 재현했습니다. 기본 패키지 검사를 공개 Pi 세션과 실제 MCP 서버까지 실행하도록 넓혔기 때문에, 하위 프로세스 관찰 한도를 20초에서 60초로 바꿨습니다. 실제 실행기의 취소·제한 시간 검사는 따로 유지합니다.

CLI 관찰기는 Pi 0.99.1의 확장 호환 레지스트리가 가리키는 실제 `ModelRuntime`을 계측합니다. 그 레지스트리만 감싸면 주 에이전트 호출을 놓치기 때문입니다. 로컬 HTTP 공급자 대조군으로 실제로 받은 주 실행 2회·검토 1회 요청과 관찰 기록을 비교합니다. 통과하려면 검토 출력 한도 `777`과 주 실행 상한 4096토큰이 HTTP 요청에 전달되고, 최종 파일이 바뀌어야 합니다. 이 계측은 고정한 버전을 위한 검증 코드이며 제품의 응답을 대신하지 않습니다.

각 테스트 프로세스는 그 실행에서 만든 디렉터리를 `TMPDIR`로 쓰고 종료할 때 지웁니다. 호스트의 공유 임시 경로가 디렉터리 검사 한도인 10만 개를 넘는 환경을 관찰했기 때문입니다. 실행기의 검사 한도와 불완전한 검사를 막는 정책은 그대로이며, 기본 임시 루트 허용과 명시적 제외는 별도 대조군으로 검사합니다.

첫 ARM64 Docker 실행에서는 154개 중 정상 `grep` 대조군 하나가 실패했습니다. 추가 검사와 실제 마운트 관찰로, 존재하지 않는 `.git`이 `/dev/null`에 바인딩되고 `nodev` 때문에 읽기가 거부된다는 것을 확인했습니다. `.git/HEAD` 하위 차단도 함께 넘겨 런타임이 읽기 전용 빈 디렉터리를 만들도록 해결했습니다. 원래 부모 차단은 유지했고, 읽기 선언을 늘린 초기 수정은 별도 대조군에서 필요 없음을 확인한 뒤 되돌렸습니다. SDK 호출자가 고른 읽기 전용 경로도 보존합니다. 추가 대조군은 정상 검색, 일반 디렉터리 생성, Pi 설정 생성 차단을 함께 확인합니다. 허용 루트와 절대 차단 루트가 직접 또는 별칭으로 겹치면 실제 경로로 정규화한 뒤 실행 전에 거부합니다.

추가 승인 연결 검사에서는 같은 호출자 ID를 쓴 두 MCP 요청이 겹칠 때 거부 대상 파일이 바뀌는 것을 재현했습니다. MCP 전송마다 내부에서 만든 고유 ID로 추가 승인을 연결하도록 고쳤습니다. 실제 Pi에 등록한 도구를 동시에 호출해, 두 검토 입력이 각각 보존되고 승인된 파일만 바뀌는지 확인합니다.

### 이전 OS 격리 검증의 범위

- 주 모델과 검토자를 재생하는 시나리오는 실제 Pi와 OS 샌드박스를 썼습니다. 이 결과는 실제 GLM5.3의 판단 정확도를 뜻하지 않습니다. 실제 모델 SDK 4개와 CLI 1개 사례는 따로 실행·집계했습니다. 통합 판정에는 CLI의 실제 검토 호출, 파일 변경, 자격 증명 미기록도 필요했습니다.
- 기본 임시 디렉터리 쓰기와 일반 외부 파일 읽기는 기본 프로필이 허용하는 동작입니다. 작업 공간 밖이라는 이유만으로 항상 차단된다고 가정하지 않았습니다.
- 셸 실행은 트랜잭션이 아닙니다. 허용된 첫 번째 쓰기 뒤 두 번째 쓰기가 거부되어도 첫 번째 변경은 남으며, 테스트는 이 부분 효과도 명시적으로 확인했습니다.
- Linux에서 새 파일을 만들려면 부모 디렉터리 범위의 승인이 필요할 수 있습니다. 기존 파일에 대한 좁은 승인과 새 파일 생성은 다른 범위입니다.
- 미리 만든 하드링크와 좁게 승인한 파일의 다른 이름을 검사했습니다. 실행 중 격리 밖의 호스트 프로그램이 동시에 링크 구조를 바꾸는 경우는 다루지 않았습니다. 검사 실패와 한도 초과는 실행을 막았습니다.
- Linux x64 호스트 실행과 ARM64 커널의 x64 실행은 기록을 나눴습니다. 최종 집계에는 같은 소스의 실제 Linux x64 호스트 결과가 필요했습니다.
- Windows 검증은 실제 운영체제에서 원본 규칙 엔진, 승인 정책, 지원하지 않는 네이티브 실행의 사전 거부를 따로 확인했습니다. Windows 네이티브 격리가 성공한다는 뜻은 아닙니다.
- 외부 MCP 실행기는 신뢰하는 통합 계층입니다. 이미 외부 서버로 보낸 요청의 취소 효과나 모든 공급자의 계정 식별·부수 효과는 보장하지 않습니다. 비어 있는 승인 폼은 처리하고, 일반 입력 폼과 URL elicitation은 거부했습니다. Pi에 없는 Computer Use 분류와 승인 예외는 제거했습니다.
- 패턴 문자가 들어간 네이티브 권한 루트는 런타임이 문자 그대로 표현할 수 없어 차단했습니다. 일반 작업 공간 안의 특수 문자 파일명 지원과는 별개입니다. 신뢰한 확장의 디렉터리는 제어 코드로 보호하지만, 임의의 신뢰 확장이 그 밖의 위치에서 실행하거나 import하는 의존 관계를 모두 자동으로 분석하지는 않습니다.
- HTTPS CONNECT, SOCKS5 TCP, IPv6, 직접 UDP 차단을 검사했습니다. SOCKS5 UDP나 모든 네트워크 프로토콜을 지원·검증했다는 뜻은 아닙니다.
- 독점 Codex 모델과 모든 판단이 같다고 보장하지 않습니다. 공개 정책·흐름과, 선택한 GLM5.3 모델에서 관찰한 결과는 구분됩니다.
