# 執行防護

與沙箱並行的寫入防護、argv-only 子程序 schema 與 timeout。

## 檔案系統寫入 guard

`go-pkg/filesystem` 的寫入 API（`WriteFile`、`WriteJSON`、`AppendText`、`CheckDir`）全部在內部強制 `IsDenied`。任何繞過 `go-pkg/filesystem`、直接透過 `os.WriteFile` 寫入的 agenvoy code 都會**逃脫 policy** — 這是禁止的。

`internal/filesystem` package 僅保留路徑計算、執行期上限與 domain wrapper。它不重複 read/write 邏輯。

在 `$HOME` 之外，`run_command` 必須事先宣告路徑：該次呼叫帶上 `write_paths`（僅限絕對路徑），使用者以系統密碼核准後，這些路徑才會為該 session 以讀寫方式綁進 sandbox。寫入未核准的路徑會得到明確訊息；對未綁定的 `$HOME` 外路徑出現權限錯誤時，會附上改帶 `write_paths` 重跑的提示，而非讓模型把裸錯誤誤判成擁有者問題。

## 子程序 argv-only schema

`run_command` 只接受 `argv: string[]`（minItems 1）與選填的 `write_paths`，以及自 v1.0.25 起的 `network`（布林值，預設關閉）。它**不**接受帶自動 tokenize 的 `command: string`。此零解析做法移除了 agent 層的 shell-injection surface。

在最外層，`sudo` 會被拒絕（改為宣告 `write_paths`），`rm` 轉為移入垃圾桶，`cd` 則在驗證路徑後切換工作目錄。

Shell 功能（pipe、redirect）需明確發出 `["sh", "-c", "cmd | pipe"]`（或 `bash -c`）。該腳本以 `mvdan.cc/sh` **解析**而非字串比對，且其中每個命令節點都會被檢查：

| 規則 | 效果 |
|---|---|
| 只接受裸指令名 | `/usr/bin/curl` 會被拒絕——binary 必須寫成 `curl` |
| 不接受動態指令 | 由變數或命令替換組出的指令一律拒絕 |
| 不接受 `rm` 與 `sudo` | 兩者在 `sh -c` 內一律拒絕 |
| 拒絕清單上的 binary | 列於 `denied_command` 者一律拒絕，`sh -c` 內亦然 |
| Shell 內建指令 | 固定集合（`cd`、`echo`、`test`、`export` ...）無需 allowlist 條目即可通過 |
| 巢狀 `sh -c` | 以相同規則遞迴驗證；非靜態字串的巢狀腳本一律拒絕 |

## Timeout

每個工具都有自己的 timeout，預設 1 分鐘，並可在註冊時逐一覆寫（`open_file` 10 秒、`html_template` 30 秒、`fetch_page` 與 `search_web` 90 秒、`generate_audio` 5 分鐘、`download_file` 10 分鐘、`generate_image` 15 分鐘、`run_command` 60 分鐘；`ask_user` 無上限）。Subagent 呼叫含等待空位時間，由 `MaxSubagentTimeoutMin`（30 分鐘）設限。

這些皆為套件層級的值——過去用來控制它們的環境變數覆寫已移除。
