# Sandbox

每次 `run_command`、script 工具與 `test_tool` 的執行都由 `go-pkg/sandbox` 包裹：

| 平台 | 機制 |
|---|---|
| Linux | bubblewrap（`bwrap`） |
| macOS | `sandbox-exec` |

Sandbox 限制：不可特權執行、受限的檔案系統寫入範圍、逐次開放的網路存取、可配置的 CPU/記憶體上限。

自 v1.0.25 起 `run_command` 預設在網路關閉（`NetworkDeny`）下執行，除非該次呼叫設定 `network: true` —— 此時僅該次呼叫改為 `NetworkAllow`，且因連網呼叫永不視為唯讀，一律經過確認 gate。Script 工具（`script_*`、`ext_*`）與 `test_tool` 以不帶 option 的方式呼叫 `sandbox.Wrap`，因此仍保有網路存取。v1.0.25 開發期間短暫存在的連網 `run_script` 工具從未進入正式版本；請改用帶 `network: true` 的 `run_command`。

## 三個呼叫者，單一進入點

Sandbox 恰有三個呼叫者，全部直接呼叫 `sandbox.Wrap(ctx, binary, args, workDir, opt)`：

1. `run_command` —— 任意使用者發出的命令（`internal/tools/runCommand.go`）
2. `toolAdapter/script` 的 execute —— script 工具擴充（`script_*`、`ext_*`）
3. `test_tool` —— script 工具 `script.py` 的試跑（上限 60 秒）

呼叫者與 `sandbox.Wrap` 之間沒有 wrapper 層。新增行為（例如新的資源上限）意味著貢獻至 `go-pkg/sandbox`，而非在 agenvoy 中加 shim。

## Policy 注入

`filesystem.LoadRuntime()` 在啟動時讀取 `~/.config/agenvoy/config.json`，並把合併後的 policy 交給 `go-pkg/sandbox` 與 `go-pkg/filesystem`。部分 policy 有編譯進執行檔的預設值並與使用者項目合併，其餘僅存在於使用者設定。

| Policy | 內嵌預設 | config.json 鍵 | 用途 |
|---|---|---|---|
| 敏感路徑 | `configs/jsons/sensitive_path.json` | `sensitive_path` | 存放憑證或金鑰的路徑——需經密碼驗證的 per-session 授權才能存取。分四類：`dirs`、`files`、`prefixes`、`extensions` |
| 排除清單 | `configs/jsons/exclude_list.json` | — | 從列目錄 / 走訪 / 搜尋中排除的路徑 |
| 唯讀指令 | `configs/jsons/read_only_command.json`（410 筆） | `read_only_command` | 跳過 confirm gate 的指令。自 v1.0.25 起，`run_command` 的執行檔本身、執行檔加第一個參數、或執行檔加前兩個參數任一在清單上即算命中（`git` 的全域旗標如 `-C <dir>` 會先略過）；任一參數為敏感路徑，或設定 `network: true` 時取消命中 |
| 拒絕指令 | — | `denied_command` | `run_command` 一律拒絕的 binary，`sh -c` 內亦然 |
| 拒絕路徑 | — | `denied_path` | 讀寫皆永久禁止的路徑；任何提示都無法核准。項目必須是絕對路徑或以 `~/` 開頭，拒收根目錄，symlink 的實際目標也一併拒絕 |
| SSRF 豁免 | — | `net_white_list` | 豁免 `http_request` SSRF 防護的 host |

指令政策為**拒絕清單**。不存在 binary 允許清單：`white_list` 與 `path_white_list` 已移除，`sensitive_map` 已更名為 `sensitive_path`；設定檔若仍留有這些鍵會在啟動時記警告，而非靜默套用。`$HOME` 以外的路徑存取是透過確認提示逐 session 授權，不是靠設定檔清單。

`denied_path` 會作為 denied map 交給 `go-pkg/sandbox`；agenvoy 端則由 `boundary.Resolve` 與 `boundary.WriteBinds` 在任何檔案工具或 `write_paths` 綁定前先行檢查。
