102 KiB
LazyBoy:共用/私人 Computer、混合工具與可安裝連接器實作計劃
- 文件版本:3.0(2026-09-10;保留共用/私人主機,新增逐項優化、TigerVNC 與外部工具安裝)
- 對象:接手 LazyBoy 的 coding agent 與 reviewer。
- 審查基準:
igs170911/LazyBoy,e6afa324530e19922909d4692c28fb005cc05a7a;沿用前次已核對的基準;本次另讀此 commit 的 display 啟動與 MCP 程式,未聲稱本機或最新遠端 HEAD 已改好。 - 文件性質:實作規格與驗收計劃;不是已套用的 patch、不是已通過的測試報告,也沒有實測提速倍數。
- 建議在 repository 內保存於
docs/agent-computer-implementation-plan.md。
最終目標:共用主機(Team Computer)與私人主機(Dedicated Computer)都是正式、長期支援的產品模式。 每個 agent 綁定自己獲准使用的持久 Computer 與工具;可以多個 agent 共用一台 Computer,也可以一個 agent 使用私人 Computer。實際任務與檔案操作在綁定的 Computer 內完成,不必每步在桌面演出,但必須有操作紀錄與結果驗證。工具可安裝、授權、更新與移除。
取代舊版:不要執行 2.0 中「移除 Team 模式、所有 agent 強制獨立容器、全面遷移 shared → dedicated」的要求。 本版已直接修正架構、資料約束、PR、測試與啟動指令,不只是附加例外。不要刪除既有共用 Computer 或使用者資料。
本版閱讀順序:第 0–3 節為產品與執行邊界;第 15 節為實作依賴;第 18 節為 48 項改善清單;第 19 節是 TigerVNC;第 20–21 節是外掛安裝與 Outlook;第 16 節含 64 個測試案例。
0. 給 coding agent 的執行指令
直接依本文件修改既有程式,不要只重新產生另一份計劃。先確認本地 HEAD、工作目錄與既有測試,再依第 15 節的 PR 順序逐段實作。不得覆蓋使用者未提交的修改。每個階段均須附上實際 diff、測試結果、已知限制及回滾方式。
本文件優先於先前健檢文件中以下已變更的假設:
- 不再要求所有動作在 VNC 或可見終端機演出。 正確的結構化紀錄即可;桌面是需要時可觀看、可接管的執行介面。
- 保留 shared 與 dedicated 兩種模式,禁止強制轉換或取消 Team Computer。 shared 允許多 agent 對一個 Computer,沿用 per-agent workspace/display/profile 與 shared/;dedicated 才要求獨立 Computer。共享資源與私人授權分開,不能把不同資料夾/DISPLAY 宣稱為惡意程式隔離。
- 不把「用 API/CLI 加速」解讀為在 LazyBoy API 主機上執行 agent 工作。連接器、MCP 子程序、檔案工具、命令與瀏覽器控制的實際執行端都在指定 Computer。
- 保留現有 Rust harness、Cua、Supervisor、SandboxProvider、React/noVNC、Vault、記憶、排程及 checkpoint;不做全面改寫。
- 自動操作的範圍是使用者授權、該 Computer 能提供的能力。不得將「任何事情」翻譯成繞過 CAPTCHA/2FA、任意取用其他 agent/主機資料,或免除高風險操作核准。
遇到外部 OAuth、GPU、GUI 或付費模型環境缺失時,完成能完成的程式、fixture、mock 與單元測試;對受影響整合項目記錄 BLOCKED_EXTERNAL 和精確缺項。不得把 mock 成功寫成真實服務已驗證;也不得為完成測試而操作真實主信箱。
1. 必須成立的產品契約
1.1 不可違反的條件
| ID | 條件 | 必要驗收證據 |
|---|---|---|
| I01 | agent 的 shared/dedicated 綁定正確;私人 Computer 不與其他 agent 隱式共用,共用 Computer 明確列 membership 與 per-agent 執行 scope | 兩模式建立/恢復測試;membership、slot、profile 與文件 scope 驗證 |
| I02 | 所有 agent 命令、任務檔案操作、連接器與本地 MCP 在該 Computer 執行 | API 與 Computer 放入不同 sentinel;程序/namespace 與 server-bound computer identity |
| I03 | agent 任意程式不能在 API/Supervisor 主機執行 | 偽造 target、host fallback、MCP spawn 測試;只保留可信任管理操作 |
| I04 | 工具是否可用取決於 agent grant、Computer 健康、account、scope 與 resource policy | 未授權、已撤銷、錯帳號與跨 agent 測試 |
| I05 | 每次工具呼叫可追蹤,包含失敗、拒絕、取消與結果未知 | operation ledger、UI timeline、outbox 重播/斷線測試 |
| I06 | 原生檔案與命令不需要 screenshot 或 vision 模型 | text-only 模型與 screenshot counter 測試 |
| I07 | 同一資源的寫入不競爭;不同 agent 不被全域鎖拖住 | 兩 agent 併行、慢 MCP、同頁雙寫測試 |
| I08 | 不確定的副作用不盲目重播 | 逾時但伺服器已執行、重送相同 operation、取消競爭測試 |
| I09 | 最終成功必須有任務層驗證證據 | file hash、表單確認值、讀回 label;工具 200 不足以完成 |
| I10 | 暫停、接管、取消與恢復涵蓋背景工具,不只涵蓋滑鼠 | barrier/fencing、background job、in-flight API 測試 |
| I11 | 密碼、token、broker key 不進一般 prompt、tool args、trace 或記憶 | secret canary、log/checkpoint/錯誤回應掃描 |
| I12 | 失敗、重啟或升級不得默默換電腦、換帳號或遺失產物 | container recreation、binding generation、artifact checksum 測試 |
| I13 | shared 與 dedicated 都支援原生工具加速;共用模式不得被降級成 GUI-only 或待淘汰模式 | shared 原生 file/exec/connector 與雙 display 並行測試 |
| I14 | 安裝套件、授權工具、綁定帳號是三個不同動作 | 共用安裝一次,未授權 agent 仍不能透過 broker 使用別人的帳號 |
| I15 | 任務執行、agent 截圖、人類桌面串流各自可量測,不混為一種延遲 | noVNC 關閉時 native 任務仍成功;VNC 與模型 critical path 分開 |
| I16 | 對「應用層 scope」與「OS 強隔離」誠實標示,不能用 prompt 承諾未知程式的安全 | 同 UID/任意 shell/第三方 MCP 的 threat-model 測試與限制說明 |
1.2 「檔案都在 Computer 內」的精確定義
任務檔案包含原始附件、下載檔、repo checkout、暫存檔、CSV、報表、程式輸出、完整工具輸出與任務執行產物。其讀寫、解析、壓縮、轉檔與掃描程序都必須在對應 Computer 執行。
允許持久 volume 的實體 bytes 由 Docker 管理並儲存在宿主機磁碟;這不等於 agent 可以直接讀寫宿主機路徑。不得把 API 主機的 /、任意 home 或 Docker socket 掛入 Computer。
控制面資料仍可保留在既有 PostgreSQL:agent 設定、授權 metadata、run/checkpoint、經脫敏的工具摘要、artifact reference、hash、耗時與事件狀態。API 可串流附件進 Computer、串流工具結果/下載給使用者、轉送模型需要的內容,但不得在主機暫存並處理任務檔案。大型原始輸出與 artifact 正本留在 Computer,API 只保存有權限的 reference。
使用外部模型或 SaaS API 仍會傳送必要資料;「在 Computer 執行」不是離線或零資料外送的承諾。模型推論及編排可在控制面;對 Gmail 等目標服務的工具請求由 Computer 內的連接器發出。
1.3 能力與安全邊界
「能做各種電腦工作」以能力可擴充為目標,不限定 Gmail 或某個網站。但容器中的硬體、GPU、音訊、USB、kernel、特定 GUI 或企業 SSO 是否可用,必須由 capability probe 回報,不能偽造已支援。
一般命令以非 root 使用者執行。額外套件優先裝在使用者環境;需系統權限的安裝由受控、可稽核的管理流程核准。不可為了可操作性讓 LLM 自行取得 Docker daemon、host root 或修改 Runner 的權限設定。
2. 現況與重用範圍
下列 F01、F03 於本次再次讀取原始碼確認;其餘為同一 commit 的前次健檢發現,coding agent 開始時仍須核對現行實作。來源見附錄 A。
| ID | 基準版本發現 | 修改方向 |
|---|---|---|
| F01 | tools.rs::pack_observation() 在 vision + 非 Identical 時回傳 None,條件反轉 |
先補紅燈測試,修正截圖交付;區分捕獲與交付狀態 [R1] |
| F02 | agent-facing shell/read_file/write_file/list_files 透過可見終端機與截圖 |
改接真正原生工具;GUI 終端機保留給 TUI/協作 [R1] |
| F03 | SandboxProvider 已存在 execute/list_files/read_file/write_file;Supervisor 已有容器內 exec 與檔案路徑 |
優先重用與強化,不必另造平行 sandbox 架構 [R2–R4] |
| F04 | runs.rs 將 email 歸 browser-first,MCP 另列,優先級重疊 |
capability-aware routing;prompt 只是配套 [R5] |
| F05 | DOM browser 與 saved login 被 vision_guard() 一併限制 |
分 semantic、visual 與 credential capability [R1] |
| F06 | browser 宣稱 CSS selector/waitMs,但 adapter 能力與使用方式不一致 | 修契約、型別化錯誤、fixture;不假設 driver 自動實作 [R6] |
| F07 | policy.rs 重複 wait/shell 可刷新進度,災難上限不能當短任務預算 |
驗證 milestone、時間預算、有限恢復 [R7] |
| F08 | API 的 mcp.rs 啟動 stdio 子程序;hub 的全域鎖跨遠端 await |
MCP runtime 搬進 Computer,授權隔離、局部鎖 [R8] |
| F09 | crates/sandbox/src/docker.rs 部分檔案通道以文字 JSON/lossy conversion 處理 bytes |
補 byte-safe 傳輸、大小限制、錯誤狀態與雜湊 [R3] |
| F10 | lazyboy-screen 已有 slot→display/VNC/websockify 對應、per-display Cua/DBus、獨立 profile;x11vnc 使用 -noxdamage |
保留既有多 display 語意;以可切換 Xvnc backend 測試,不把 Team 視為單一桌面 [R9] |
| F11 | lazyboy-screen 已用 xfwm4 --compositor=off;ensure_slot 會串行啟動桌面/VNC/Cua/終端機等 |
關 compositor 是現況,不是尚未做的新提速;按需拆 readiness 與修啟動 dependencies [R9] |
特別注意:F03 代表原生執行「有底層基礎」,不代表既有實作已完整提供取消、持續 session、原子寫入、byte-safe 傳輸、授權隔離或任務稽核。不可只把 shell() 改呼叫 execute() 就宣布整個計劃完成。
2.1 檔案落點
| 現有位置 | 主要修改 |
|---|---|
crates/contracts/src/ |
tool capability、operation、job、artifact、typed error 等可序列化契約 |
crates/control/src/sandbox.rs |
重用/擴充原生方法、job lifecycle、串流及限制 |
crates/controld/src/ |
Computer 內 Tool Runner 的路由、job 管理、檔案、browser adapter、local MCP/connectors |
crates/sandbox/src/docker.rs |
Rust API 到指定 Computer 的 transport;不得對錯誤回傳空成功 |
crates/supervisor/src/ |
provisioning、Computer 身分綁定、受控 transport、資源/lifecycle;不執行 agent 任意主機程式 |
crates/api/src/tools.rs |
agent-facing schema、具 grant 的 dispatch、structured outcome;拆出子模組避免繼續膨脹 |
crates/api/src/runs.rs |
tool discovery、執行路由、checkpoint、結果與驗證、operation ID |
crates/harness/src/policy.rs |
milestone/預算/loop guard 與 typed recovery |
crates/api/src/mcp.rs |
control-plane 設定與 runtime directory;不再在 API spawn agent MCP |
crates/api/src/monitor.rs、apps/web/src/run-monitor.tsx |
activity timeline、耗時分解、job/artifact 狀態 |
crates/api/src/computer.rs、vault.rs、workspace.rs、attachments.rs |
雙模式 Computer assignment/membership、scope、safe streaming、credential broker 整合 |
image/computer/、Compose、migrations/、tests/ |
runtime 啟動、版本固定、漸進遷移、測試與部署 |
新 module 名稱可依現有慣例調整;不得在 Rust 核心外再加一個完整 Python agent orchestrator。必要的 Node browser worker 可以是受控執行器,不是第二套總指揮。
3. 目標架構與責任分離
LazyBoy API + Rust Harness [控制面]
├─ 任務/模型/工具路由/grants/驗證
├─ Computer assignments + memberships
└─ PostgreSQL:操作紀錄、經脫敏 metadata、設定
↓ 受控 transport
Supervisor / SandboxProvider [管理面:生命週期、資源限制、身份驗證]
┌──────────┴────────────────┐
▼ ▼
Team Computer T [共用] Dedicated Computer P [私人]
├─ agent A context └─ agent C context
│ ├─ bots/A/ ├─ 私人持久 home/workspace
│ └─ display/profile A └─ 私人 display/profile C
├─ agent B context
│ ├─ bots/B/
│ └─ display/profile B
├─ shared/ [成員依 grant 存取]
└─ 版本化工具套件 [可共用程式,不隱含共用帳號]
│ │
└─ 各 Computer 內的 Runner/jobs/fs/MCP/connectors/Cua
工具資料、下載、暫存、完整輸出與執行產物留在該 Computer
3.1 執行位置
擴充既有 controld/SandboxProvider,不重建另一套總指揮。API 只管編排、授權與紀錄;Supervisor 可透過 Docker exec 啟動 Computer 內可信任 helper,不能把 LLM 指令放到自己的 shell。附件與產物允許受控串流,不在 API 主機暫存解析。remote SaaS 是獲准的目標服務,不是遠端檔案處理或遠端 code-interpreter fallback。
MCP/連接器的本地 client、下載、解壓、SDK 與檔案程序皆在目標 Computer。遠端 MCP 的伺服器程式仍在遠端,不能宣稱都在本機;只有使用者准許的遠端 SaaS 存取可啟用,會代處理本機 task files/代跑 shell 的遠端工具預設拒絕。
3.2 兩模式與資料約束
ComputerMode的既有 enum/儲存值先核對並保持相容;本文件用 shared/dedicated 表示產品語意,不要求隨意改資料庫字串。computer_id為邏輯電腦;provider_ref 可變。container 重建增加computer_generation。display/browser 重啟另有 session generation,不需連帶使所有原生 job 失效。- 每個 agent 同時有一個 active assignment。shared Computer 的 computer_id 可被多個 agent 參照;不能替此欄位無條件加 UNIQUE。
- dedicated 的排他性用對應 owner/部分約束/transaction enforce;shared 用明確 membership(相同核准 space/team)、display slot、workspace scope 與 grants。
- 保留使用者既有選擇和建立 agent 時的共用/私人選項;新的 hybrid executor 不應改變 ComputerMode 的預設或現有 assignment。
- provisioning/screen 啟動做 per-computer/per-slot single-flight;刪除 agent 只移除自己的 assignment 和資源。Team 仍有其他成員、job 或 viewer 時不得 stop/destroy 整台 Computer。
- Computer idle 由全部成員的 jobs、MCP、screens、writers、outbox 共同判斷;不能因 A 閒置就凍結 B。
runner_ready、browser_ready(profile)、desktop_ready(display)、viewer_ready(display)拆開。原生工作不等 XFCE/VNC;查看桌面也不能變成業務工作存活的必要條件。
3.3 共用的範圍,不等於什麼都共享
| 資源 | shared 模式預設 | dedicated 模式預設 |
|---|---|---|
| 容器與總 CPU/RAM | 同 Team Computer 共用、配額與公平排程 | 私人 Computer 的配額 |
| agent 工作目錄與 job 歸屬 | bots/<bot_id>/ 和 own jobs,tool API scope 分開 | 私人 workspace 和 own jobs |
| shared/ | 經 membership/read/write grant 分享 | 可保留本機 shared/ 名稱,但不自動跨 Computer |
| 瀏覽器、DISPLAY、DBus/AT-SPI session | 沿用各 agent 的 slot/profile,不能任意拿別人的 ref | 私人 slot/profile |
| 套件 bytes | 同版本可共用受保護唯讀 package store | 此 Computer 的 package store |
| 工具 instance/設定/OAuth | 依 agent/grant/account 分開;明確允許才共用 instance | 私人 agent scope |
| 記憶/run/操作紀錄 | agent 身份不合併;shared 檔案事件可依 membership 顯示 | agent scope |
shared/ 路徑需依既有 resolve_bot_workspace_path/scope 處理,不要直接重寫一套忽略舊路徑的 resolver。shared 寫入使用 canonical resource key 與版本衝突檢查,兩個 agent 看到的是同一份真正的檔案,不是各自副本卻叫 shared。
3.4 誠實的信任邊界
shared 是受信任團隊的協作 Computer。同容器、同 UID、可執行任意 shell 時,資料夾 scope 與不同 DISPLAY 不構成對惡意程式的強隔離。 不可宣稱 tool grant 能阻止所有自行寫腳本讀其他可讀檔案/X11 session 的行為。
保留 shared 的原生能力,但敏感 broker/Runner metadata 必須與 task user 分離保護;僅向批准的 connector instance 提供 scoped credential。對需要跨 agent 機密性的工作,使用 private Computer 或新增經測試的 per-agent OS user/工作沙盒;此選項不能變成刪除 shared 的理由。
同一共用主機安裝未受信任套件等於引入可執行程式,必須顯示受影響 Team/檔案/session 範圍;沒有可驗證的 sandbox 就不能宣稱只影響某一 agent。強化模式僅在對應 OS 行為真的測過後才能標為安全隔離。容器對宿主機的邊界仍依 Docker 權限/mount/network 實作 [E4]。
3.5 持久化與升級
兩模式都保留資料與 browser profile。user-space 工具使用版本化目錄與 lock manifest;OS 套件採 image/受控 recipe 重建,不承諾任意 apt 安裝跨 recreate 永久保留。
shared 和 private 都原地升級 schema/Runner,不做強制模式遷移。使用者日後明確要求換模式時,才啟動 dry-run、停止點、授權 copy、checksum、衝突處理與可回滾的 assignment 切換。
4. 契約:身份、工具結果與 operation ledger
以下為建議新增契約,不是現有 API。欄位命名可調整,但語意不能消失。
4.1 可信任執行 context
{
"space_id": "space-A",
"user_id": "user-A",
"bot_id": "bot-A",
"computer_id": "computer-A",
"computer_generation": 3,
"assignment_id": "assignment-A",
"computer_mode": "shared",
"display_session_id": "screen-A",
"workspace_scope_id": "scope-A-and-shared",
"run_id": "run-42",
"step_id": "step-3",
"operation_id": "op-17",
"attempt_id": "attempt-1",
"grant_id": "grant-9",
"control_epoch": 8,
"deadline_at": "2026-09-10T08:00:00Z"
}
這些身份由伺服器按登入 actor 與 run 綁定,LLM 不得填寫或更換 computer_id、grant、account mapping 或 filesystem 根目錄。工具參數只能是任務需要的業務參數。到 Runner 時再次驗證 token audience、agent、電腦 generation、grant、到期與 control epoch。
Supervisor shared token 不得進入 agent 的 env、home 或 prompt。每個 Computer 使用短效、限範圍認證;不要認為服務藏在 Docker 內網就等於有授權。
4.2 Capability descriptor
name: gmail.labels.apply_plan
version: "1"
execution_plane: computer
requires_vision: false
required_grants: [gmail.labels.write]
required_scopes: ["https://www.googleapis.com/auth/gmail.modify"]
side_effect: reversible_write
supports_batch: true
retry_mode: verify_before_retry
resource_key_template: "gmail:{account_ref}:mailbox"
result_schema: ToolResultV1
capability 必須區分:installed、runtime_connected、authenticated、authorized、healthy。MCP annotations、tool description、模型自評或網頁內容都不是可信任授權來源。registry 僅向模型暴露此 run 真正能用的少量工具。
4.3 Structured ToolResult
{
"schema_version": 1,
"operation_id": "op-17",
"status": "succeeded",
"effect": "confirmed",
"execution": {
"computer_id": "computer-A",
"computer_generation": 3,
"executor": "native_process",
"job_id": "job-7"
},
"data": {
"stdout": "12 files processed\n",
"stderr": "",
"exit_code": 0,
"signal": null,
"truncated": false,
"output_artifact_id": null
},
"artifacts": [],
"evidence": [{"kind": "process_exit", "exit_code": 0}],
"timing": {"queue_ms": 4, "execution_ms": 31},
"error": null
}
status:accepted、running、succeeded、failed、cancelled、timed_out、needs_auth、needs_approval、needs_human、policy_denied、unknown。effect:none、confirmed、partial、unknown。succeeded只表示該工具契約完成,不自動代表整個 task 完成。exit_code在未結束時為 null;因 signal 結束另記 signal。不得把 timeout 或空輸出視為 exit 0。- 所有結果共用 envelope;不能再讓任意錯誤文字看起來像正常
text_outcome。 - wrapper 外層 HTTP 非 2xx、解析失敗、schema mismatch 必須保留錯誤;不能回傳空 file list/空 file contents 冒充成功。
4.4 Operation identity、重送與恢復
operation_id 代表一次具體意圖,由 harness 產生並在網路重送時保持相同。attempt_id 區分傳輸嘗試。不可只 hash 相同 args 作 dedupe:使用者可能真的要求合法重做同一動作。
Runner 在副作用前,先將 accepted intent 寫入受保護的 durable journal;其後記錄 started、結果與驗證。控制面先記錄 dispatch intent,再傳送;UI 訂閱中央事件。中央斷線時由本地 outbox 補送,透過唯一 event key 去重。journal 無法可靠寫入時,不開始新的有副作用工作。
同一 operation 重送:running 回原 job,finished 回既有結果;never blindly rerun。Runner/容器崩潰或外部 API 回應丟失時,狀態可為 unknown,交給 verifier 做 read-back。沒有第三方 idempotency 或可觀察後置條件時,不可宣稱 exactly-once;需人工判斷或停止。
同一 operation ID 搭配不同 payload hash、帳號或 grant 必須拒絕。舊 computer_generation/control_epoch 的動作不得在新容器或相應接管 scope 後繼續執行。shared 模式使用 computer、agent 與 display 的分層 epoch,不能 A 接管就無條件使 B 的獨立工作失效。
5. 原生命令、檔案與背景工作
5.1 最小工具集合
| 工具群(建議名稱) | 行為 | 截圖需求 |
|---|---|---|
exec.run |
argv 或明確 shell mode,短作業直接回結果,長作業回 job_id | 無 |
exec.status/output/cancel |
查工作狀態、依 cursor 取輸出、確認取消 | 無 |
terminal.start/interact |
真正需要 PTY/TUI/持續互動的程序 | 文字優先,必要時 GUI |
fs.list/stat/read/write/patch/move |
原生 file API,byte-safe、有限讀取、原子變更 | 無 |
fs.search |
在 Computer 搜尋;binary/巨大資料有界處理 | 無 |
artifact.list/export |
回傳 Computer 內 artifact reference;下載串流 | 無 |
browser.* |
同一 Chromium 的 DOM/語意操作 | 按需 |
computer.observe/act |
AT-SPI/視覺桌面操作 | 視覺動作必需 |
account.*、gmail.*、mcp.* |
受控 account handle 與 per-agent grant | 通常無 |
既有工具名稱可保留為 versioned alias,以免破壞 skills。alias 亦須經同一 policy、audit 與 Computer dispatch;不能留下可繞過的新舊兩套入口。
5.2 Exec 與 session 的正確語意
- 一般命令優先 argv array,避免重新插入 host shell;需要 pipeline 時顯式
mode=shell,只在 Computer 內解譯。 cwd、HOME、PATH、locale、環境變數與 session scope 由 Computer runtime 管理。不自動繼承 API 的雲端金鑰、DB URL、Supervisor token。exec.run的 stdout、stderr、exit status 來自實際程序,不從 screenshot 或文字 prompt 猜測。- 預設 subprocess 非互動且不維持前次
export/cd。需要持續環境時顯式使用 scoped session;不得讓 UI 宣稱持續,實際卻每次新 shell。 - PTY 可能合併 stdout/stderr,需在 schema 註明。任意互動 shell 的 command completion 不可靠時回
running/unknown,不得用尾端$字元當完成證據。 - 背景 job 由 Runner 擁有 lifecycle。HTTP request 結束不是 job 結束;回傳 job_id,保留 stdout cursor、deadline、PID/starttime/process group identity。
- 使用 bounded streaming、背壓與磁碟 quota。模型預設只收到摘要/頭尾片段,完整輸出放 Computer artifact。
- 取消必須處理 process group/subprocess tree:TERM → grace → KILL,確認狀態後才回 cancelled。不要誤殺整個 desktop、其他 job 或 PID 回收後的新程序。
- request deadline 與 job runtime timeout 分離;達 runtime timeout 後依明確 policy 停止工作。transient network timeout 不等於工作已停止。
- API restart 可找回同一 Runner job;container recreate 後原程序不再存在,要標記 interrupted/unknown 並驗證產物,不得假裝還在 running。
- 對未知 arbitrary shell,
changes_state=unknown,不能因命令開頭是cat就假設無副作用;shell、子程序、網路都可能改變狀態。
5.3 原生檔案與產物
檔案工具在 Computer 的 filesystem namespace 內執行,不能由 API 直接打開 volume 對應的主機路徑。
預設任務可寫 root 為 assignment 對應 workspace 與專屬 tmp;shared 模式再加入明確授權的 shared/ 子樹。其他 Computer 內路徑依 OS 權限與 grant 開放,並遵守第 3.4 節的 shared 信任邊界。此限制不要求 agent 只能處理某個固定副檔名,也不禁止在自己的電腦使用已安裝的系統工具。
必要實作:
- Unicode、空白、引號、
$()、反引號、換行檔名都須以資料而非 shell 程式碼處理。 - byte-safe 讀寫;UTF-8 text API 與 binary API 分離。禁止
from_utf8_lossy無聲毀損 binary。小 binary 可用受限 base64,大型檔案用串流;不要將整份內容放 argv。 fs.read支援 line/byte range、最大回傳量與 continuation;二進位回 metadata/reference,不交模型亂解碼。fs.write/patch支援 expected version/hash、目標資源鎖、temporary file + same-filesystem atomic rename;需要 durability 的操作同步資料與目錄,讀回核對 hash。- 不存在檔案、權限不足、編碼錯誤、磁碟滿、大小超限必須各自回 typed error,不得變空字串成功。
- 路徑驗證須處理
..、symlink、TOCTOU、mount boundary。不要只做字串 prefix 或先 canonicalize 再無鎖 open;使用 descriptor-relative/capability-based 安全打開方式,依平台選受支援方案並測試。 - 對同一檔案的 read-modify-write,要用該次讀取的 version/hash 做 optimistic check;不同 run 並行修改會 conflict,不可覆蓋人類更新。
artifact_idserver 產生並綁 creator_bot/computer、visibility_scope、相對路徑、media type、size、hash、來源 operation、retention;記錄生成時 generation 作 provenance。持久檔案在重建後經重新核對 hash/scope 可重新解析,不能永久因 generation 變動而失聯。下載 API 不接受任意 host path。- 附件入站、UI 下載、connector attachment、browser download 都必須走 Computer 內串流路徑,帶大小/quota/雜湊驗證。不得把 task bytes 放 API
/tmp再處理。 - destructive file operation 額外依風險核准;一般使用者已明確要求且可逆的本機整理可在 run grant 內批次執行,不必每個檔案再問一次。
5.4 保留 GUI 能力但不再把 GUI 當萬用資料通道
移除「所有 shell/file output 都一定是 screenshot」的 system prompt。原生工具結果直接進模型;不為了視覺展示自動開 terminal、不重演指令、不額外截圖。
需要真正 TUI、GUI 終端機協作或使用者指定觀看時,才使用 terminal.*/Cua。相同 job output 可另做 UI viewer;不要求第一版將每個背景命令鏡像到桌面。
6. Capability-aware routing 與模型迴圈
6.1 工具選擇規則
在權限、資料位置與帳號已匹配的前提下,優先順序是:
服務提供的結構化 API(適用於該任務)
→ Computer 內原生程式/檔案/已安裝 CLI
→ 同一 browser 的 DOM/accessibility
→ Cua 原生 accessibility
→ 新鮮截圖 + 視覺座標
→ 需要人類協助
這是依任務的偏好,不是要求每件事逐層嘗試。例如讀本機 CSV 直接 fs/exec,無需先找 SaaS API;登入後操作 canvas 可直接進視覺路徑。路由針對每個子任務重算,不能整個 run 一次選 browser 後鎖死。
授權拒絕、帳號不符、缺少 capability scope 不是換另一工具繞過政策的理由。 同一服務操作的 policy 必須套用到 connector、browser、shell HTTP 與 MCP 等路徑。無 API 但使用者確實授權該網站的 GUI 操作,可在明確 GUI grant 下執行;不可把 POLICY_DENIED 當成這種情況。
6.2 小任務不要多套一圈 planner
- 簡單明確的 file/exec 任務,用既有模型回合或 deterministic intent-to-tool route,不再額外呼叫大模型做一份長計劃。
- 多步任務才持久化
TaskPlan{goal,steps,dependencies,success_checks,budget}。 - 每一步保存 input references、採用 route、已驗證 milestone、產物與 blockers。checkpoint 不只是聊天文字摘要。
- 工具 discovery 依任務載入;不要把所有 agent 的所有 MCP schema 塞進每次 prompt。
- schema cache 依 version/grant scope 快取;授權撤銷必須立即失效,不得因快取繼續使用。
- 分類、格式轉換、批次檔案處理在一次受控工具工作中完成;不是每一列、每個字、每個 click 都呼叫模型。
- 已知確定步驟可 executor-side macro,但需有限步數、每步 evidence/trace 與失敗即停;不是任意舊座標重播。
6.3 Typed errors 與處理規則
| Error | 行為 |
|---|---|
AUTH_REQUIRED/TOKEN_REVOKED |
進 NEEDS_AUTH,保留 task;停止有副作用請求 |
POLICY_DENIED/SCOPE_DENIED/ACCOUNT_MISMATCH |
明確拒絕此路徑;不改用 UI/shell 繞過 |
TARGET_STALE |
重新 snapshot/定位一次;只對尚未執行的操作重建動作 |
TARGET_NOT_FOUND |
有界重新觀察/定位;視覺 fallback 需新鮮截圖 |
SELECTOR_UNSUPPORTED |
換成受支援語意 locator;不再重送同一不支援 selector |
TARGET_DISABLED |
檢查可觀察的前置條件;僅有已知等待條件才 wait |
RATE_LIMITED/暫時服務錯誤 |
本地 bounded backoff + jitter/Retry-After;不由 LLM 空轉 |
TIMEOUT_EFFECT_UNKNOWN |
先 read-back;不能 blindly retry mutation |
COMPUTER_UNAVAILABLE |
恢復原 Computer,驗證 generation;不換 host 或另一 bot |
CONFLICT |
重新讀最新狀態,重規劃/重新核准差異 |
CAPABILITY_UNSUPPORTED |
回報缺少套件/裝置/模型能力;不宣稱已操作 |
CANCELLED/STALE_CONTROL_EPOCH |
不再派送;保留真實已發生效果 |
6.4 Model 使用策略
初版保留現有模型供應商與選模 UI,不綁定特定商業模型。原生/DOM 工具允許通過契約測試的 text-only 模型;視覺座標需要具有經驗證 vision 能力的模型。
優先減少模型回合與多餘圖片,再測模型速度。可選的高難度模型升級最多有界觸發;不能讓不同 agent 彼此委派形成無限 nested harness。
若模型不支援所需能力,誠實回 MODEL_CAPABILITY_MISMATCH;不得把 vision=true 假裝打開。prompt、schema 與 provider request 三者須有整合測試。
7. Browser 與 Cua:保留、修正、再測另一 backend
7.1 預設決策
先保留 Cua driver 與既有 Cua semantic browser,修好 screenshot、schema 與 stale refs。把 browser 操作抽成受控 BrowserExecutor 介面,供未來替換,不先承諾換 driver 一定更快。
可選對照方案固定為 Computer 內的 Playwright worker,連接該 Computer 現有 Chromium,避免第一版同時引入 agent-browser、Browser Use、Hermes 三套。需要比較其他方案時另外開 ADR/實驗,不能耽誤核心原生工具交付。
Playwright 官方支援 CDP attach 到既有 Chromium,但明確指出相較原生 Playwright protocol 功能完整度較低,必須對實際 browser launch flags、frames、downloads 與 input 做相容性測試 [E3]。若對照 backend 未通過 fixture,繼續用修好的 Cua,不擴大替換。
7.2 同一 browser/session 的規範
- 不要求使用者保持 VNC 開啟;但 agent 使用的 browser 必須屬於其 Computer,之後能在該桌面檢查及接管。
- 優先 attach 現有 browser instance;不得另啟程序同時占用同一份 profile。保存 computer-local session identity 與明確 tab/frame ref。
- Cua 與 Playwright 不得同時寫同一分頁/桌面,必須共享 lease。driver 換手後清掉舊 references 並重新觀察。
- CDP 與 Runner 不對主機公網發布,不交 LLM 任意 URL;由可信任 runtime 對指定 browser 建立連線。
- 不把 headless/remote browser 當作無提示替代登入狀態的方法。
- 登入、導航、frame 切換、人工接管與 browser restart 皆是 refs invalidation boundary。
7.3 修正截圖條件與交付狀態
基準版本 pack_observation() 修正為 vision 且畫面非 Identical 時才產生 image;純文字模型永不接收 image [R1]。
進一步拆開 last_captured_frame、last_delivered_frame、model/history identity。首次需要視覺、人工接管恢復、換 vision model、圖片歷史壓縮後,即使畫面 bytes 未變,也必須允許 force delivery。
只有圖片真正加入模型 request 後才更新 delivered 狀態。不可因背景監控抓過圖,就以為模型看過。沒有最新視覺依據時,不准猜座標。
7.4 語意與座標能力分開
DOM/accessibility 操作檢查有效語意 target、權限、origin、lease,不要求 vision。pixel-only 操作檢查 vision、最新 observation identity、viewport 尺寸與 control epoch。
browser locator 使用 tagged type,例如 snapshot_ref、role_name、css;只有 backend 真實支援的類型才暴露。不要在名稱相近時偷偷做模糊匹配。
wait_until 由 executor 觀察明確條件,設 deadline;避免所有工具固定 sleep 一秒。元素 disabled 的原因可能是缺欄位,不是時間到了就好。
可新增 bounded browser.fill_form:每欄重新定位並驗證,按鈕提交前驗證前置條件,提交後讀回確認。不可把五個會失效的數字 id 一次盲送。
7.5 底層可擴充,不預設全面操作保證
支援 normal click、type、scroll、drag、key、window focus、file upload/download、dialogs,以及 Cua 已提供的桌面能力。每一項提供 capability probe 與 fixture;不支援的 widget 明確回 unsupported。GPU、硬體或系統管理另外加受控 capability,不以一個 run_anything_as_root 代替設計。
8. Concurrency、Pause、Takeover 與 Cancel
8.1 按真實資源上鎖,不按整台共用主機一律上鎖
| 資源 | 建議 lock key/規則 |
|---|---|
| GUI/native input | (computer_id, display_session_id) 的 writer lease;同 display 排他、不同 display 可並行 |
| Browser | profile/session 對應 writer lease;涉及 OS focus/clipboard/upload dialog 時一併取 display lease |
| 檔案 | canonical resource identity/重疊 subtree;shared/ 同檔必須命中同一 lock,配合 expected hash |
| 信箱與連接器副作用 | provider + canonical account/tenant/mailbox;跨 Computer/agent 的同帳號亦要協調 |
| MCP client | instance + grant + account 的有限 semaphore,不跨 network await 持有全域 hub lock |
| 套件安裝/升級 | Computer/package/version;同包原子切換,active instance pin 原版本 |
| container stop/recreate | Computer lifecycle barrier,等待所有成員 writer/job 安全停下 |
同 display 的 Cua 與 DOM 不同時 mutation;不同 display 的 DOM 可以並行,不能因同 Computer 就全部串行。browser context 不可共享 mutable singleton。多資源依固定順序取鎖、設 deadline、避免 deadlock,長等待不占用無關 lease。
受控 file 工具與已驗證 scoped jobs 可按不重疊資源並行。任意 shell 不能靠 LLM 宣稱的路徑或 read_only 取得並行保證:有 OS sandbox 證據才降到 scope 鎖;無界且可能影響全 Computer 的腳本/系統安裝保守取得 Computer-wide lease。這是高權限工作例外,不是讓所有 shared 工作都上全域鎖。
初始併發為可調試驗:每 agent native jobs 2、service reads 4、每 display GUI writer 1,同時設定 per-Computer/provider 上限與公平排程。不可各 agent 自行放大到壓垮共用 Computer。
8.2 觀看、接管與暫停的不同 scope
- Watching 不暫停,也不授予寫入;noVNC 客戶端 viewOnly 只是 UI,伺服器仍須依 lease 拒絕未授權鍵鼠/resize/clipboard。
- 接管某 agent:保守暫停該 agent 的新 mutation 與 jobs,取得它的 display;其他 agent 的獨立 display/無衝突資源可繼續。
- 只接管某 display:暫停所有正在寫該 display 的工作,不偷偷取得其他 display;涉及相同帳號/共享檔案時透過資源衝突顯示等待。
- 暫停整台 Computer:對所有成員、jobs、MCP 與 display 建立 barrier;UI 顯示受影響 agents。只有具 Computer 管理權限的人能做。
- 人類若要在 shared Computer 任意改系統/全域檔案,應先選整台接管;不能保證其他 agent 不受無界人類 shell 影響。
8.3 Scope-aware pause barrier 與恢復
使用 (computer_epoch, agent_epoch, display_epoch) 的 scope-aware fencing 或等價機制;API 和 Runner 各驗證。對該 scope 停派新 mutation、取消未執行項,對 job 採已宣告且驗證過的 cancel/suspend policy。
已送出的 SaaS mutation 無法因斷線就撤銷;持續顯示 in-flight/unknown,read-back reconciliation 後才宣稱已完成接管。取消不是 rollback。不能 SIGSTOP 整台共用容器來模擬「暫停 A」。
恢復沿用原 run/step,重新檢查 assignment、membership、grants、generation、session 與未知效果;只做未完成步驟。共享檔案與 browser state 可能已變,重新讀回,禁止沿用舊 refs 或覆蓋 B/人類修改。
觀察、核准與安全 reconciliation 可走受限恢復路徑,不讓原模型繼續無界派工。
8.4 arbitrary code 與可觀察性的實際邊界
本計劃保證的是經過 LazyBoy 工具閘道的每次呼叫、受控子動作及 job lifecycle 有紀錄;不宣稱等同完整 kernel syscall 或每個應用內部操作稽核。任意 exec 內部腳本仍可能連網、啟動程序與寫檔。
因此 arbitrary exec 的 scope、網路與 OS 權限必須保守;需要逐 syscall/所有子程序網路行為的強制稽核時,另做 OS 級監控與測試。不能只改 prompt 就承諾「所有低階行為零漏記」。
9. 紀錄、Activity UI 與資料保護
9.1 必須記錄的事件
run.started、step.routed、tool.accepted、tool.started、tool.progress、tool.completed、tool.failed、tool.cancel_requested、tool.cancelled、tool.effect_unknown、verification.completed、artifact.created、authorization.required、takeover.requested/acquired/released、run.completed/partial/failed。
事件至少帶 server-bound identity、operation/attempt ID、tool/version、route、開始結束時間、resource scope、經脫敏 args summary、outcome、typed error、output reference、驗證證據與重試理由。
不保存模型隱藏推理;只記可稽核的 route rationale,例如「已有 Gmail labels scope,採批次 API」,不是整段思考鏈。
9.2 UI 顯示
在現有 run monitor 擴充,不重做整個前端:
14:20:10 原生檔案 讀取 orders.csv 成功 18 ms
14:20:10 原生命令 依規則整理 500 列 執行中 job-7
14:20:11 結果驗證 輸出列數與檔案 hash 符合 通過
14:20:12 Gmail 標籤修改預覽 80 封 等待核准
以上僅為 UI 示例,不是效能實測。
每個項目可展開看脫敏輸入、輸出摘要、差異、執行電腦、job、產物與驗證;不能只顯示「我正在努力」。背景 job 可取消;artifact 可從該 Computer 串流下載。觀看紀錄不要求開桌面。
9.3 稽核安全與 durable outbox
- 中央 ledger 存 metadata;原始 output/artifact 在 Computer。flush 有背壓、quota 和 retention;避免無上限 screenshot、base64 或郵件內容進 DB。
- secret redaction 在寫入 trace、logger、exception、MCP debug、checkpoint、UI 之前執行。secret type 使用 opaque handle;不靠事後 regex 當唯一防線。
- Runner 的 journal/outbox、broker keys 和管理憑證,必須置於 task shell 不可任意改寫的權限區域;中央 accepted intent 可協助查出本地結果缺口。
- 限制任務使用者對 broker/Runner proc env、memory、socket 與管理檔案存取;不能只因非 root 就假設同 UID 程序完全隔離。
- Browser 已登入狀態代表具有該帳號的存取權。若一般程式可以讀相同使用者的 browser profile/session 或控制 X11,就不能聲稱能抵抗惡意程式對所有 session 資料的窺探。部署要明確記錄此 threat model;更強隔離需 OS user/sandbox 與實測,不得僅用文案保證。
- 不記錄原始密碼、OAuth token、Authorization header、secret query、剪貼簿 secret。密碼相關操作停用或遮蔽自動 screenshot/recording;不可先拍下再只遮 log 字串。
- 檔案與郵件正文可能是敏感資料,依最小必要送模型,並提供 retention;secret canary 要掃所有正常與錯誤路徑。
10. MCP、帳號與憑證
10.1 MCP 在 Computer 執行與隔離
API 的 MCP 模組僅保存設定/授權 metadata 和 UI 狀態;stdio MCP 子程序與 remote MCP client 均由 Computer Runner 管理。兩模式都以 agent/grant 管理 MCP instance、env、working dir、account binding 與 capability set。shared 可重用唯讀套件 bytes;有狀態且含私人憑證的 instance 預設分開,明確授權且支援 request-level scope 的服務才共用 instance。安裝流程見第 20 節。
runtime key 至少包含 (space,user,bot,computer,generation,server_instance),tool 名稱只是顯示名稱,不可只靠 slug 找工具而跨 agent 命中同名 server。
- 只讓授權工具進 registry,dispatch 再檢查一次;
definitions()不合併全域所有人的工具。 - 在短臨界區取得 client handle,釋放 hub lock 再 await。必要 semaphore 只限制該 server,不堵住別的 agent。
- 持續連線與 schema cache;restart/reconnect 清掉舊 generation 的 handles。
- stdio 套件及版本固定,不在每次 tool call 執行不固定版本的
npx -y latest。首次安裝是獨立、有紀錄的準備工作。 - raw MCP 結果要映射成共用 envelope,保留
isError、typed output、截斷與 resource references;不可只當 pretty JSON 文字認為成功。 - 處理跨 agent server alias 碰撞、404、401、timeout、schema 變動。拒絕 connector 自己要求開放更多權限或修改控制面設定。
- unknown/未受稽核的 MCP 可執行任意程式時,視同 unknown exec scope,不相信它宣稱 read-only。
10.2 Credential broker
保留 Vault 的加密儲存與管理介面,但新增 per-agent/account grant。模型只取得 opaque handle。需要使用時,由可信任 broker 透過受保護 channel 交給 Computer 的受控 connector/欄位填入器;token 不暴露給 generic exec 或其他 MCP 的 env。經審查的第三方 MCP 若只支援環境變數認證,需明確批准其讀取該 token,以該 instance 的受保護 runtime 注入,記錄安全降級;無法阻止共用 task user 讀取時拒絕敏感 token 注入並回報原因,不假裝有 broker handle 即相容。
broker/trusted connector 應使用與 task shell 分離的 OS 權限(共享/私人皆適用),不放在任意工作程式可讀的 home、environment、debug output 或 task 可寫 journal。OAuth callback 可以由控制面接收與交換/安全保存授權憑證;之後真正的 Gmail 工具操作由 Computer connector 發出。不得為「全部在電腦內」而把長期 secret 塞給任意 shell。
原始密碼填入前檢查 HTTPS、精確核准 origin、frame、form target 與當前 control epoch;導航之後重新驗證。不要自動放寬成任意 Google 子網域。欄位辨識可用 input type/autocomplete/label/表單關聯,不只中文字串搜尋。
登入狀態要區分 ORIGIN_MISMATCH、FIELD_NOT_FOUND、AMBIGUOUS_FIELD、AUTH_REJECTED、NEEDS_HUMAN。密碼被拒不連續重送;2FA/Passkey/CAPTCHA 進人工接管。此專案不實作驗證繞過服務。
10.3 授權與便利性
使用者明確要求的低風險工作可以取得 run-scope grant,不要每個讀檔、click 都重新核准。敏感外送、寄信、付款、刪除、改帳號設定或大批外部寫入要有清楚 scope 與 policy;可設定長期授權,但必須有範圍、到期、撤銷與事件紀錄。
核准綁 plan hash、account、目標資源、允許的變更與期限;修改內容變了必須重新核准。generic shell、browser 和 MCP 不得成為其他工具 policy 的繞過通道。
**重要實際限制:**對具任意本機程式、已登入 browser、直接網路權限的工作者,只做工具層 allowlist 無法證明所有出站行為都受限。需以 OS 使用者、broker 隔離、網路 egress/proxy policy 實際限制敏感服務憑證與目標;對無法強制的 generic browser/exec 高權限能力明確標示並要求額外授權,不能虛稱與 narrow Gmail tool 同等安全。
11. Gmail:第一個端到端業務驗收案例
11.1 範圍
Gmail 只是驗證新架構的第一個 connector,不將 router 寫成 Gmail 特判,其他服務應能使用相同 grants、operation、audit 與 verifier。
第一版只做使用者自訂 labels 的預覽、核准、套用與讀回;不自動寄信、不刪除、不封存、不改已讀、不改系統分類分頁/企業 Classification Labels。Gmail labels 與 Inbox categories、Google Workspace 的 Classification Labels 是不同範圍。
使用使用者 OAuth,不假設 browser cookie 等於 API token。優先實作必要範圍的授權,使用 gmail.modify 時在產品層限制具體操作;該 scope 不只是標籤修改,gmail.labels 也不能替代套用郵件標籤所需權限 [E1–E2]。不要要求個人 Gmail 使用 Workspace domain-wide delegation。
公開分發/多人部署前檢查 Google 對 restricted scope 與資料處理的要求;開發 fixture 不代表真實 OAuth 發布審核完成 [E2]。
11.2 正確流程
確認 account 與 capability
→ search 指定 query/時間範圍,完整處理 pagination
→ 受限並行取得 headers;必要時才取得 snippet/body
→ 確定規則先分類,模糊案例送模型分批輸出 label enum
→ schema validation + 固定測試集校準 + 待確認類別
→ 保存不可變 label plan,顯示預覽
→ run grant 或使用者明確核准 plan hash
→ 依相同 add/remove label 組合分組
→ connector 在 Computer 內 batchModify
→ 逐筆 read-back 驗證,記錄 partial/unknown
→ 回報真實完成數、未處理數、例外與可用撤銷範圍
Google 官方 messages.batchModify 單次最多 1,000 個 message IDs,同一批使用同一組 add/remove label;成功回應為空,不帶每封郵件的完整結果,因此仍須另行讀回驗證 [E1]。
範例驗收採 100 封 fixture mail,不代表使用者授權處理整個真實信箱。生產查詢必須有明確範圍、結果上限、排除條件、pagination 與 preview。
11.3 權限、模型與準確度
郵件正文是不可信任資料。分類模型只回傳固定 schema 與允許 labels,不可直接 dispatch tools;正文要求轉寄/改系統規則/下載執行程式一律不構成授權。
不要只依 LLM 自報 confidence。建立含繁體中文、英文、帳單、廣告、工作與模糊內容的人工標註測試集;報告 precision、recall、coverage、abstention,避免把所有信放「待確認」就宣稱 100% 準確。
初始 target:自動套用類別 precision ≥ 95%,同時公布 coverage/recall;模型不達標時採 preview-only,而不是偷偷降低正確性門檻。此為驗收目標,不是目前已測結果。
11.4 Retry 與 Undo 的限制
每個 plan 包含 message IDs、account reference、原先 labels、requested delta、rule version、hash、到期與 grant。分批有 child operation ID,保存實際套用/驗證的狀態。
429/暫時錯誤採有界 backoff;回應丟失先 read-back,只執行仍缺少的核准 delta。token 撤銷停在 NEEDS_AUTH,不轉 GUI 硬闖。
撤銷只考慮本次實際新增/移除的 labels,不覆寫整個 label set。若使用者並行修改同一 label 或狀態/history 不清楚,標記 conflict,顯示預覽再核准;沒有原子 compare-and-swap/明確來源資訊時,不能保證任意並行情況下完全無損的一鍵 undo。
11.5 外部環境缺失
coding agent 使用本地 fake Gmail HTTP server 完成 pagination、batch、token revoked、rate limit、response lost、partial verification、concurrent change 與 prompt-injection tests。真實帳號測試單獨列為 opt-in integration,不要求密碼/token 貼到聊天,也不自行建立或刪除真實郵件。
12. Verifier、進度、有限恢復與預算
12.1 三層完成狀態
- Transport:呼叫是否收到合法回應。
- Operation effect:程序退出、欄位值改變、檔案 hash 符合、label 實際存在。
- Task success:使用者要求的所有必要結果與限制是否達成。
只有第 3 層完成才回 run.completed。部分成果回 partial,明確列已完成/未完成/阻礙,不用最後一句自然語言假裝通過。
12.2 Evidence-based progress
- file:輸入/輸出 hash、筆數、schema、測試結果。
- browser:特定欄位、URL/目標記錄、確認頁中的對應值;只有頁面換網址不足以驗證交易成功。
- Gmail/Outlook:已讀回 verified 的 message 數、仍待處理/待確認數;不能混用兩者批次/標籤模型。
- build:實際 job status、exit code、test summary;仍在輸出 log 不等於任務持續前進。
- wait/poll:heartbeat 可表示 worker 活著,但不刷新 milestone progress。
像畫面時鐘、游標閃爍或工具 args 換了,也不算任務進展。對沒有 deterministic verifier 的模糊視覺任務,可使用受限視覺驗證或人類確認,但標示證據較弱,不能當確定完成。
12.3 起始預算(新設定,可調整)
interactive:
max_llm_turns: 20
max_no_progress_seconds: 60
max_semantic_recovery_attempts: 2
max_route_switches_per_step: 2
wall_budget_seconds: 180
batch:
bounded_chunk_size: 100
max_semantic_recovery_attempts: 2
progress_source: verified_items
long_job:
lifecycle_owner: runner
completion_source: job_event
runtime_deadline: required
這些值是合理起始實驗,不是已測最佳設定。正式 task budget 與保險上限分離。長工作依 task 明確 deadline,不用 180 秒把正常編譯截斷;human_wait 另計。interactive 沒進度時重新路由一次,仍卡住就清楚暫停,不能把上限調回四小時當修復。
watchdog 必須能在慢模型/工具 await 期間運作,不只在下一輪才檢查。等待已知條件採本地事件/bounded polling,不反覆付費請 LLM 決定再等一秒。
13. 效能與正確性量測
13.1 必要指標
run/step/operation/model/tool_version/backend/computer_generation/mode/assignment/display_session。- cold/warm,queue、model TTFT/total、tool execute、observation、recovery、human wait。
- model input/output tokens(provider 沒回則標 unavailable)、schema 大小、LLM turns、tool calls、retry/route switches。
- screenshot count/bytes、artifact bytes、verified items/milestones、success/partial/failure rate。
- native CPU/memory/disk、每 agent/Computer 並行數、MCP server latency、display capture 與 VNC viewer latency。
並行存在時,不可把所有 span duration 相加當 run wall time;同時報 wall time、exclusive spans 與 critical path,避免重複計算 tool 與其內部 observe 的時間。
13.2 Benchmark gates
以下為待實測驗收 target,不是完成時間承諾。先固定 reference host、container quotas、CPU architecture、模型版本、網路條件及冷暖狀態,提交 baseline,再進行比較。
| Case | 正確性 gate | 效能/迴圈 gate |
|---|---|---|
| 1 MiB 本地讀寫/hash | byte-for-byte 正確;private 不跨 Computer,shared 按授權共享而非混用 | warm tool-only P95 target ≤ 500 ms;0 screenshot |
短命令 printf/非零退出 |
真實 stdout/stderr/status | warm tool-only P95 target ≤ 1,000 ms;0 screenshot |
| 500 列 CSV 整理 | deterministic expected output/schema/hash 通過 | 不逐列 LLM;同條件已驗證完成 median target ≤ baseline 50% |
| 本地五欄表單 | 每欄正確+提交確認 | bounded macro;模型決策回合 target ≤ 3,不含登入 |
| Gmail 100 封 fixture | requested label delta 逐筆驗證、不做額外修改 | 0 GUI;label write call 按組合/batch,而非每封一次 |
| 兩 agent 同時工作 | 結果分離、沒有 credential 或 artifact 混用 | 慢 A MCP 不阻塞 B client/registry;非全域串行 |
| 長命令與 reconnect | 狀態可找回,取消不留未知子程序 | 無需 LLM 忙碌 polling;模型次數不隨等待秒數增長 |
每一候選設定先固定種子/fixture 重跑至少 30 次;正式以 P95 當門檻前建議至少 100 次並附樣本數。少量樣本只作探索;有延遲或 rate limit 不隱藏。舊路徑若無法完成並驗證該任務,其相對提速列為 N/A,改報新路徑絕對耗時與成功率,不捏造 baseline 倍數。
只比較成功且驗證過的同一工作,同時列所有任務成功率與失敗耗時,避免只挑成功樣本或「更快失敗」造成假提速。未達 target 就提交 profiling、差距與修正項,不改 fixture 偷渡。
14. 持久化、設定與雙模式相容升級
14.1 資料模型
沿用既有表、ID 與 enum,migration 採 repository 下一號。不重命名既有 shared/team mode 就讓舊資料無法載入。
- Computers:mode/owner_team/generation/provider_ref/backend/readiness。
- Assignments/memberships:每 bot 一個 active assignment;shared computer 可多 bot,dedicated 有條件排他約束。保存 workspace scope、display slot、profile id。
- Grants:bot/team membership/Computer/account/operation/expiry;同 Computer 不等於同 grant。
- Package installations:Computer/package/version/digest/source/trust/status。Binding:安裝包 → agent(s)/server instance/account/capabilities;套件與認證分表。
- Jobs/operations/events:保留第 4 節與原有 schema,加入 assignment、display/resource scope 和版本 provenance。
- Artifacts:creator bot、visibility、relative path、hash、source op;重建後核對,不讓永續檔案被 generation 永久孤立。
- Display sessions:每 slot 的 display/backend/epoch、profile 和 lifecycle。MCP、package 與 desktop 各可單獨健康檢查和恢復。
14.2 設定
以下是新增設定的建議命名;必須實作 parser/validation/.env.example,不是當成目前已可用的環境變數:
LAZYBOY_EXECUTION_PROFILE=legacy|hybrid
LAZYBOY_DISPLAY_BACKEND=xvfb_x11vnc|tigervnc_xvnc
LAZYBOY_BROWSER_BACKEND=cua|playwright
LAZYBOY_TOOL_AUDIT_REQUIRED=true
LAZYBOY_NATIVE_JOB_CONCURRENCY=2
LAZYBOY_SERVICE_READ_CONCURRENCY=4
LAZYBOY_TOOL_INSTALL_ENABLED=true
LAZYBOY_TOOL_INSTALL_REQUIRE_APPROVAL=true
Computer mode 保留既有 UI/API 選擇與預設值;不加強制 dedicated 的 rollout。legacy/hybrid 是 executor 路徑版本,不是 shared/private 的替代名稱。
雙模式皆先 opt-in 測試,再 canary。不能用 feature flag 恢復截圖錯誤、secret 洩露或 host task fallback。
14.3 原地升級與可選模式切換
預設原地升級 shared 與 dedicated,保留 bot assignment、shared/、private workspace、登入、skills、排程和群聊。既有 Team 不標為待淘汰、migration_required,也不自動拆成多台私人電腦。
只對需要調整的 metadata/工作檔路徑做有測試的相容 migration,保留回滾資料。使用者明確要求換模式時才執行:dry-run → manifest → 停止相關 writers → 在來源 Computer 匯出/目標 Computer 匯入 → hash/permissions check → 原子切換 assignment → 恢復。共享 profile/credential 歸屬不明時列衝突,不複製給所有人。
共用 package 更新或整台 image recreate 必須先列出所有受影響 members/jobs;不要為單 agent 升級重啟別人的工作。移除一個 agent 不刪共享資料或共享安裝包;最後一個 reference 消失後仍需 retention/管理政策決定 GC。
15. 實作順序:可分段提交的 PR
不做「一次替換全部底層」的大型 PR。核心正確性先落地;TigerVNC 和第二 browser adapter 都有獨立開關,不把它們的相容性問題混入原生工具改動。
| PR | 實作與主要落點 | 依賴 | Gate/產出 |
|---|---|---|---|
| PR-00 | 核對 HEAD/git status/AGENTS.md/工具鏈;建立 shared/private baseline、紅燈 fixtures | 無 | 記錄原有失敗、可重現截圖/工具契約問題;不覆蓋未提交修改 |
| PR-01 | 修 tools.rs 截圖與 semantic/vision guard、browser contracts、typed result |
00 | 新圖交付、text-only DOM、unsupported/stale/disabled 正確區分 |
| PR-02 | 保留兩模式;assignment/membership/Runner identity/per-display context/protected broker boundary | 01 | shared A/B 仍同 Computer、private C 獨立;不能偽造 scope;沒強制模式轉換 |
| PR-03 | operation ledger/Computer outbox/Activity UI/事件與秘密脫敏 | 02 | 斷線補送/去重、rejected/partial/unknown 可見;失去 audit 不開始 mutation |
| PR-04 | 原生 exec/files/jobs/range & binary/artifact streaming/scope-aware cancel | 03 | 兩模式都能 text-only CSV 工作、0 screenshot、真 exit code、取消子程序;第一個核心可交付階段 |
| PR-05 | 可安裝 Tool Manager、Computer 內 MCP/連接器、版本 pin/grants/OAuth broker/hot reload | 04 | 本機 sample MCP 實際安裝可用;共用套件不共享帳號;更新回滾不重啟整台 Computer |
| PR-06 | per-step capability router、少量 schemas、milestone verifier/watchdog/有界恢復 | 05 | wait 不算進度、無 planner 套娃、policy denied 不繞路、未知副作用先讀回 |
| PR-07 | Browser session/profile/display leases、form macro、人類接管与恢復 | 06 | 同 display 排他、不同 display 可並行;接管 A 不凍結無衝突 B;resume 不重做 |
| PR-08A | Gmail labels adapter 作業務基準;沿用第 11 節 | 07 | fixture 預覽/核准/apply/read-back/衝突測試;不操作主信箱 |
| PR-08B | Outlook 外掛作擴充性驗收;走第 20 節安裝契約與 Graph adapter | 05;業務 E2E 需 07 | 不改核心 dispatch 也能載入外掛;read/categories/分頁/batch/401/429/共用模式授權測試 |
| PR-09 | DisplayBackend 介面+TigerVNC Xvnc 候選+舊 backend rollback;第 19 節 | 02/03 可先開始;整合 gate 需 07 | Cua/AT-SPI/X11/中文/多 display/noVNC 相容;benchmark 不退步才考慮 default |
| PR-10 | 雙模式原地升級、完整測試/效能與部署文件/rollout | 08A/08B/09 | 第 1 節契約與第 16 節測試有證據;Outlook 真實帳號或 GUI 缺環境須明確 blocked |
| PR-11(可選) | Playwright worker 對照;Selkies/Xpra/Wayland 分別另開 ADR | 核心不需等待 | 一次只換一層、無證據不採用;不能為完成清單全部安裝 |
每個 PR 可以拆小,但不可依賴尚不存在的安全邊界就先打開高權限工具。PR-04 的必要 job cancel/audit 不拖到 PR-07。PR-05 即使外部 OAuth 不可用,也必須能安裝並執行本機測試 MCP,證明「外部工具能加入」不是只有 UI。
15.1 Coding agent 執行方式
先建立進度檔,以 NOT_STARTED / IMPLEMENTED / PARTIAL / BLOCKED_EXTERNAL / VERIFIED / DEFERRED 表示真實狀態。先完成 PR-00/01 的程式與測試,再依 DAG 推進;不是再交一份更長的計劃。
逐項更新第 18 節的 O01–O48:採用/保留現況/實驗/延期/阻礙、實際 diff、測試命令與結果。標「已實作」不等於「已驗收」。有互斥候選時,只實作滿足目標的最小方案;不能同時把所有替代框架塞進主線。
16. 最小測試矩陣與 Definition of Done
| Test ID | 場景 | 必須證明 |
|---|---|---|
| T01 | vision × Changed/Similar/Identical | image 交付真值表正確 |
| T02 | 首次畫面/換模型/壓縮歷史/takeover resume | 未變但模型沒看過的圖仍交付 |
| T03 | 純文字模型 DOM/native tool | 可用語意工具、不收到圖、不猜座標 |
| T04 | selector unsupported/stale/disabled | 正確錯誤、有限恢復、無盲點 |
| T05 | private A/B 同路徑與 shared A/B 相同相對路徑 | 私人互隔離;共用 own workspace 不誤取,shared/ 依授權真共享 |
| T06 | 偽造 bot/computer/grant/generation | API 及 Runner 都拒絕 |
| T07 | host sentinel/Docker socket/管理 API | task 不可讀取或操作 |
| T08 | ../symlink race/奇異 Unicode 檔名 |
不逃逸/不 command injection |
| T09 | binary 含無效 UTF-8 與 1 MiB 檔案 | byte-for-byte 正確 |
| T10 | 權限不足/磁碟滿/HTTP 403/解析失敗 | 不回空成功 |
| T11 | 同檔並寫、expected hash 不符 | conflict 而非覆蓋 |
| T12 | stdout/stderr/非零退出/signal | 真實程序狀態 |
| T13 | timeout/子程序/cancel 競爭 | 停止程序樹,誠實回 pending/unknown |
| T14 | API restart/Runner reconnect | 原 job 不重做、output cursor 可續 |
| T15 | container recreation | generation 失效,舊 job 不假裝存活 |
| T16 | 同 operation 重送/相同 ID 不同 args | 去重;不同 payload 被拒絕 |
| T17 | central DB/網路中斷 | durable outbox 最終補送,不重做副作用 |
| T18 | journal 不可寫/quota 用盡 | 不開始新的 untracked mutation |
| T19 | 同名 MCP/慢 server | namespacing 正確,沒有全域 await lock |
| T20 | token revoked/wrong account/grant expiry | 停止並回 NEEDS_AUTH/denied |
| T21 | secret canary 在成功及 exception 路徑 | prompt/log/checkpoint/UI 無 secret |
| T22 | website/email/MCP prompt injection | 不把外部內容當授權與工具指令 |
| T23 | 同一 page 的 Cua+browser worker | mutation 排他,refs 不混用 |
| T24 | takeover 時 background job+HTTP in flight | barrier 真實,顯示未確定效果 |
| T25 | screenshot clock/重複 wait | 不刷新 milestone、不無限 loop |
| T26 | fake Gmail pagination/batch limits | 沒漏信、label 組合分批正確 |
| T27 | Gmail response lost/429/partial verify | bounded retry、read-back、如實 partial |
| T28 | Gmail concurrent same-label change/undo | conflict-aware,不宣稱無損無條件撤銷 |
| T29 | 兩模式原地升級;使用者要求模式切換的 dry-run | shared 不被強制拆開,原資料/profile/排程保留 |
| T30 | noVNC 關閉/desktop 未啟動 | native 工作仍完成且有紀錄 |
| T31 | 兩 agent/多 run 壓力 | 可量測並行、資源受控、結果不交叉 |
| T32 | 分類測試集含模糊郵件 | precision/recall/coverage/abstention 全部報告 |
| T33 | arbitrary exec 讀 broker env/socket/journal | 保護區不可見,不靠 prompt 擋 |
| T34 | UI download/附件串流 | 不使用 API host 暫存任務檔案 |
| T35 | 取消後 resume | 已驗證操作不重播;grant/ref 重新檢查 |
| T36 | 所有 aliases/native/MCP/browser 入口 | 都經統一 policy、operation、audit |
| T37 | 建立/恢復 shared 與 private agent | 兩模式維持原選擇;shared 允許多 assignment,不誤套 UNIQUE |
| T38 | shared A/B own workspace 相同檔名 | 透過受控 fs/exec context 正確命中,不因 cwd singleton 混用 |
| T39 | shared/ 同一檔案協作與未授權會員 | 成員獲准則可見;同檔 CAS/conflict,未授權工具請求被拒 |
| T40 | Team 不同 DISPLAY 的兩個 browser writer | 可並行;profile、DBus、AT-SPI、Cua socket 與截圖不串台 |
| T41 | 同一 DISPLAY/profile 的 browser/Cua/人類 | 排他 writer 與 server-side control epoch,有界排隊 |
| T42 | 暫停/接管 shared agent A | 無衝突 B 的 native/job/display 不被凍結;A 不再派送 |
| T43 | 整台 Team pause/recreate | 所有 members/jobs 被追蹤;無假暫停/孤兒 writer |
| T44 | 兩 agent 同時首次 provision/ensure screen | single-flight、slot 配置唯一、只有一個合法 instance |
| T45 | 刪除 Team 的一位成員 | 其他人的 Computer/shared files/package/jobs 不被刪 |
| T46 | 本機測試 MCP 匯入+實際安裝+執行 | 安裝程序和 bytes 在 Computer;有版本/hash/audit |
| T47 | 共用安裝包+不同 agent 帳號 grant | 只重用唯讀程式;未授權 agent 無 broker token/tool capability |
| T48 | 錯誤 digest/路徑逃逸/擴權 manifest | 啟用前拒絕,existing tool 不受影響,套件 hooks 無無界權限 |
| T49 | 安裝新版本時有 active jobs | active pin 舊版、新 run 用驗證新版;可 rollback、不全機 restart |
| T50 | 移除/撤銷一個 connector binding | 只停止相應授權;共用套件/其他 agent bindings 仍運作 |
| T51 | Outlook fake messages/categories adapter | 安裝後能 read/preview/apply/verify;未授權 send/delete 不可用 |
| T52 | Graph $batch HTTP 200 但子項 429/401/5xx | 逐子項結果/Retry-After/未知 read-back;不全批重做 |
| T53 | Outlook nextLink/deltaLink/token revoke | 完整分頁;delta 依 folder 綁定,失效需安全重同步/授權 |
| T54 | Outlook categories 並行修改/未支援 If-Match | 不假稱 CAS;偵測可見衝突、回報限制,不盲覆蓋 |
| T55 | TigerVNC Xvnc × Cua × XFCE fixture | 截圖/XTEST/AT-SPI/中文/鍵鼠/clipboard/視窗辨識通過 |
| T56 | X server restart/backend 切換 | 舊 refs、display epoch 失效;既有 GUI sessions 不宣稱無縫存活 |
| T57 | slot 0/1 的 DISPLAY 與 VNC port | 明確保留 :1→5900/:2→5901 對應,不依 Xvnc 預設推算 |
| T58 | noVNC CSS scaling/resize/高 DPI | 座標 transform/實際尺寸正確、文字可讀,不拿 viewer 有損畫面做驗證 |
| T59 | 未授權 VNC keyboard/resize/clipboard | 伺服器拒絕;不只靠客戶端 viewOnly;Xauthority 配置驗證 |
| T60 | 無人觀看、VNC proxy 未啟動 | native 與必要 browser 工作仍可做;不被 viewer readiness 阻塞 |
| T61 | 第三方 MCP 僅能接受 env token | 明確 trust review/保護 process env;不能保護就拒絕敏感注入 |
| T62 | shared 同 UID 無界 shell 的 threat model | 不把目錄 scope/tool annotations 宣稱強隔離;core secrets 不可讀 |
| T63 | 慢 agent/資源不足/renderer crash | 公平隊列/總配額;不因 A 閒置或 OOM 自動破壞 B 狀態 |
| T64 | Computer recreation 後套件與 artifact | manifest 可重建;persistent artifact 校驗後可取;不重用舊 jobs |
測試層次:unit → fake Runner/fake model/fake SaaS → disposable real Computer integration → explicit opt-in external account/model E2E。fixture 真實 GUI 測試無 display 時標 blocked,不改成假 assertions。
第一輪先從 repository 查實際工具鏈與 scripts。可用時執行:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
前端依 apps/web/package.json 已存在 scripts 跑 typecheck/build/tests;不要宣稱不存在的 npm/Make target 已通過。需要的 test-agent-computer、bench-agent-computer 等新入口必須在此實作中真的加入。
16.1 全案完成的最低定義
- shared Computer 上 A/B 協作、private Computer 上 C 獨立,兩模式關閉桌面仍可做工具工作。
- 檔案、exec、MCP、connector 在正確 Computer;不存在 host task fallback。
- API/工具/UI 的成功、失敗、partial、unknown、cancel、needs_auth 語意一致。
- Activity 看得到操作摘要、結果、耗時、電腦、job/artifact 與驗證。
- 原生檔案/命令能由 text-only 模型完成且不產生截圖。
- Cua 仍可處理必要桌面操作;語意和視覺工具的 boundary 正確。
- Gmail 與 Outlook fixture 預覽→核准→套用→驗證完成;Outlook 走可安裝外掛契約;外部帳號測試誠實標示。
- 核准、secret、timeout、並行、接管、重啟與撤銷都有測試,不以功能展示代替。
- TigerVNC 以候選 backend 通過兩模式相容性/readiness/noVNC 測試;是否切為預設依結果,不宣稱保證提速。
- 外部 MCP 安裝、授權、更新、撤銷、移除可在 UI/API 操作,active job 不被靜默換版本。
- O01–O48 逐項有 disposition/理由/證據;P2/P3 可有合理延期,不要求全部換掉。
- 實際 benchmark 附環境與成功率;沒有未測的速度倍數或「全網站皆可操作」宣稱。
17. Coding agent 的交付格式與停止點
每個 PR 更新 docs/agent-computer-progress.md:
## PR-XX:名稱
狀態:IMPLEMENTED / PARTIAL / BLOCKED_EXTERNAL
基準 commit:...
修改檔案與設計差異:...
新增/修改測試:...
實際執行命令與結果:...
未執行測試及原因:...
效能結果與樣本數:...
安全/相容性/雙模式/migration 影響:...
對應 Oxx/Txx 與 disposition:...
回滾方式:...
下一個可執行步驟:...
不要把「已寫測試」與「已執行且通過」混為一談。不要透過刪測試、跳過 auth、放大 retry budget、強制 vision 或把未知效果標成功來完成 gate。
沒有外部憑證時完成內部必要範圍,精確列出 integration blocker;不向聊天索取密碼。沒有使用者授權,不對真實信箱做寫入、不刪除 legacy 資料、不正式部署或 force push。
需要決策但沒有資料時,選擇符合本文件不變條件的最小改動;只有不可逆資料遷移/真實帳號核准等真正需要使用者的步驟才暫停。不要因架構工作較大就只交另一份計劃。
18. 逐項改善清單:48 項,不等於 48 項全部替換
P0:正確性/產品邊界;P1:核心交付;P2:量測後採用;P3:可選/延後。以下是本案的待辦與候選,沒有實測提速倍數。每項在進度檔有 disposition、證據和回滾;已存在的優化要標「保留」,不要再次算成新成果。
A. 原生執行與工作流程
| ID | 項目 | 優先級 | 具體改動 | 要改善的問題 | 驗收/限制 |
|---|---|---|---|---|---|
| O01 | 修正新圖交付 | P0/必做 | 修反轉條件,分 captured/delivered,接管/換模型強制交付 | 無圖硬做造成的錯誤與重試 | 真值表+模型 request fixture;[R1] |
| O02 | 原生 exec | P1/必做 | 命令在綁定 Computer 執行,直接取 stdout/stderr/exit | 消除終端機打字與讀圖 | 兩模式 text-only 命令 0 screenshot |
| O03 | 原生 files | P1/必做 | 重用並強化 SandboxProvider,不透過 sed 畫面讀檔 | 減少回合/避免 binary 毀損 | range、Unicode、binary、shared 路徑;[R2–R4] |
| O04 | 持續 jobs 與 PTY | P1/必做 | 短命令直接返回,長作業由 Runner 管理、事件通知/真取消 | 不請 LLM 反覆看是否做完 | API 重啟可追 job;process-tree cancel |
| O05 | 批次程序/form macro | P1/必做 | 已知步驟在受控 executor 內完成,有 pre/post checks | 不逐列/逐 click 呼叫模型 | 每個子動作有 trace;失敗即停 |
| O06 | 套件/連線常駐 | P1/必做 | 暖 MCP instance、HTTP pooling、版本化 cache | 降低啟動與重複連線成本 | warm/cold 分測;不共享私人 env |
| O07 | 穩定 Runner transport | P2/量測 | 優先現有安全 transport;高 overhead 才改持續 UDS/HTTP 通道 | 減少每次 docker exec 的啟動成本 | 實測 RPC 分解;不能公開 root socket |
| O08 | readiness 分層 | P1/必做 | Runner、browser、desktop、viewer 各自 ready,按需啟動 | 讀 CSV 不先等整個桌面 | no viewer/no desktop 的 native fixture |
B. 模型與瀏覽器
| ID | 項目 | 優先級 | 具體改動 | 要改善的問題 | 驗收/限制 |
|---|---|---|---|---|---|
| O09 | 按能力路由 | P1/必做 | 原生/已授權 API 優先,DOM 次之,必要時視覺 | 避免 Gmail/Outlook 走慢 UI | route rationale+權限拒絕不繞過 |
| O10 | 工具 schema 按需載入 | P1/必做 | 僅帶此 run 可用能力,版本/grant cache | 縮短 context、避免選錯工具 | revoke 後立即失效;記 schema tokens |
| O11 | 簡單任務不加 planner | P1/必做 | 用既有一輪決策,複雜任務才 TaskPlan | 避免多 agent/planner 套娃 | 記模型回合、TTFT、正確完成 |
| O12 | 條件等待 | P1/必做 | wait_until/job events 有 deadline,替代固定 sleep | 消除空等與毫無進度輪詢 | 未知 disabled 原因不無限等 |
| O13 | DOM snapshot 限量與增量 | P2/量測 | 聚焦相關區域,revision 與失效 refs 完整處理 | 減少重傳巨大 page text | 錯 revision 回 full;不能漏關鍵元素 |
| O14 | agent 圖片和 viewer 串流分離 | P1/必做 | 高可讀截圖按需取,不把 VNC frame 全塞模型 | 減少模型圖片成本且維持辨識 | 縮放映射/force image/小字 fixture |
| O15 | 既有 browser/session 穩定 attach | P1/必做 | profile/tab/frame 明確綁定,禁止亂開替代瀏覽器 | 減少重登入與 stale reference | 同 profile 不雙開;重啟正確失效 |
| O16 | 驗證、有限恢復與模型升級 | P1/必做 | 進度看 milestone;兩次同義錯誤換策略,難題才升級模型 | 停止二十分鐘空轉 | 未知副作用先讀回;無固定提速保證 |
C. 顯示與遠端桌面
| ID | 項目 | 優先級 | 具體改動 | 要改善的問題 | 驗收/限制 |
|---|---|---|---|---|---|
| O17 | Xvfb+x11vnc → TigerVNC Xvnc | P2/必做候選測試 | 一個 backend 同時提供 X server 與 VNC,保留 rollback | 可能減少顯示匯出層與維護負擔 | Cua/a11y/中文字/多 display/CPU/latency;[E5] |
| O18 | Xvfb+x0vncserver 備選 | P3/保留替代 | 只換 VNC 匯出層,不替換 X server | Xvnc 相容性卡住時較小改動 | 不能說已移除 Xvfb;[E6] |
| O19 | 檢查 -noxdamage | P2/對照 | 現有 x11vnc 關閉 XDamage;測啟用是否有重繪瑕疵 | 判斷掃描負擔能否降低 | 靜態/捲動/遮擋/影片測試;不可直接刪旗標;[R9] |
| O20 | noVNC/websockify 與畫質檔 | P2/調校 | 先保留;viewer FPS/壓縮可調,無 viewer 減少服務負載 | 改善觀看/頻寬,不假稱模型更快 | 文字清晰、輸入延遲、resize、proxy auth;[E7] |
| O21 | 精簡桌面而非先換 OS | P2/調校 | 保留 XFCE/a11y;已 compositor=off,評估不必要 autostart | 降低多 slot CPU/RAM | 不重做既有優化;不破壞 DBus/a11y;[R9] |
| O22 | Selkies 替代 viewer | P3/可選 | 有高幀率/音訊需求才測;目前有 WebSocket 與選用 WebRTC | 影音觀看可能較適合 | 硬體 encoder 實測、網路與前端成本;[E8] |
| O23 | Xpra 替代 viewer | P3/可選 | 需要單視窗發布/session forwarding 時測 | 另一路 remote app 體驗 | 非 noVNC drop-in;額外 client/輸入整合;[E9] |
| O24 | Wayland/全面換桌面 | P3/延後 | 保留 X11 driver 路徑,未有需求不全面搬遷 | 避免同時引入 capture/input 相容性變動 | 獨立 ADR/fixtures;不是目前速度主解法 |
D. 共用/私人與資源協調
| ID | 項目 | 優先級 | 具體改動 | 要改善的問題 | 驗收/限制 |
|---|---|---|---|---|---|
| O25 | 雙模式正式保留 | P0/必做 | shared 多 bot→同 Computer;private 排他;不強制遷移 | 符合產品且避免破壞資料 | assignment/member/slot/重建測試 |
| O26 | 按 display/檔案/account 鎖 | P1/必做 | 同資源排他、不同 display 與受控 job 並行 | 避免共用主機整機串行 | Cua/DOM/human 同鎖;canonical shared key |
| O27 | scope-aware pause | P1/必做 | 接管 A、接管 display、暫停整機分開 | B 不被 A 的無關操作凍結 | 真 barrier/fencing;HTTP unknown 誠實顯示 |
| O28 | 共享 lifecycle/single-flight | P1/必做 | 啟動、刪除、idle reaper 看全部 member/jobs | 避免重複建立與誤停他人工作 | member refcount、job/viewer 活性聚合 |
| O29 | 程式共享與帳號授權分離 | P0/必做 | 共享唯讀 package,per-agent runtime/bindings/grants | 省重複安裝、不共享私人帳號 | 未知程式不能靠 annotations 保證安全 |
| O30 | 公平排程與總配額 | P1/必做 | 每 agent/Computer 的 CPU/RAM/jobs/requests 有界 | 抑制單 agent 拖慢所有人 | 壓力/OOM/慢 MCP;不無界並行 |
| O31 | Chromium /dev/shm 與程序回收 | P2/量測 | 調 per-Computer shm、init/reaper、renderer 健康 | 減少可避免的崩潰與孤兒程序 | 不能盲開 ipc=host/SYS_ADMIN/no-sandbox;[E10] |
| O32 | X11/DBus/profile 權限與 session | P1/必做 | per-slot identity,評估 Xauthority,系統安裝有管理鎖 | 避免串台與共用 session 風險 | 同 UID 非強隔離;Xvnc :1 port 對應測試 |
E. 可安裝外部工具/Outlook
| ID | 項目 | 優先級 | 具體改動 | 要改善的問題 | 驗收/限制 |
|---|---|---|---|---|---|
| O33 | Tool Manager 安裝入口 | P1/必做 | catalog、manifest/受控 package URL、本地上傳三種入口 | 新增工具不改核心 dispatch | 實際 sample MCP 安裝,不只是設定畫面 |
| O34 | 來源版本與完整性 | P1/必做 | pin digest/version,審核 hooks,安全解壓與 quota | 更新可重現、防無界安裝 | 拒絕未審核 URL、路徑逃逸、錯 digest |
| O35 | 安裝/啟動/認證/授權分開 | P1/必做 | 每階段顯示狀態、failure reason 和 scope | 不再「裝好了卻不能用」 | installed ≠ connected ≠ authenticated ≠ authorized |
| O36 | 熱啟用與 registry 更新 | P1/必做 | health/schema 驗證,原子登錄能力;grant 撤銷失效 | 不為加工具重啟整個 LazyBoy | 正在執行 run 的能力版本與安全點更新 |
| O37 | 版本更新/回滾/移除 | P1/必做 | 新版本旁置,active job pin 舊版,bindings/reference GC | 共用主機其他 agent 不受破壞 | 新增權限重新核准;共享套件引用仍存活 |
| O38 | OAuth/token broker | P1/必做 | Microsoft/Google 正規授權,scoped token、refresh single-flight | 減少重登入與憑證混用 | MFA/admin policy 正常接管;secret canary;[E11] |
| O39 | Outlook Graph 外掛 | P1/必做驗收 | 讀信→categories preview/apply/verify;寄信另授權 | 驗證架構不只 Gmail 特判 | 個人/工作帳號對應 scopes;[E12–E14] |
| O40 | Outlook 批次/增量同步 | P1/P2 | Graph 20 子請求/逐項狀態;需要時 folder delta | 減少網路回合及每次全信箱掃描 | 429/Retry-After/分頁/ImmutableId;[E15–E18] |
F. 正確性、紀錄與可維護性
| ID | 項目 | 優先級 | 具體改動 | 要改善的問題 | 驗收/限制 |
|---|---|---|---|---|---|
| O41 | operation journal/outbox | P0/P1 | 副作用前記 intent;斷線 durable 補送與去重 | 避免掉紀錄與重做工作 | journal 故障不開始 mutation |
| O42 | 活動紀錄串流而非桌面演出 | P1/必做 | 工具與 job 的結構化事件、實際耗時/結果 | 人可追查、不逼每步打字 | noVNC 關閉仍可看進度 |
| O43 | artifact 存 Computer+脫敏 | P1/必做 | 全文输出在 Computer,API 存摘要/reference,限量保留 | 避免 DB/context 被圖片/日誌塞滿 | secret/大檔/retention/串流授權測試 |
| O44 | Task 驗證與郵件分類品質 | P1/必做 | API 200 不等於任務完成;測 precision/coverage/abstention | 速度與正確性一起看 | read-back/真實 fixture、失敗也計入 |
| O45 | 衝突與冪等/未知效果 | P1/必做 | 同 operation 不重做;same-file CAS;未知 API 先回讀 | 降低重送/覆蓋/重複外部副作用 | 不假稱通用 exactly-once/無損 undo |
| O46 | 部件健康與版本相容矩陣 | P1/P2 | Runner/display/Cua/browser/plugin 個別 probe/recover | 失敗不用重啟整台 Computer | 不影響其他成員;pin 上游版本 |
| O47 | 已驗證 skill/流程重用 | P2/後續 | 將常用流程保存語意步驟與 checks,環境變更可失效 | 降低每次從零探索 | 不保存密碼/舊座標;profile/版本變更重驗 |
| O48 | 端到端+viewer 雙 benchmark | P1/必做 | 分模型、工具、snapshot、queue、viewer,固定環境兩模式 | 找真瓶頸,不憑工具名字換底層 | 成功率/median/P95/CPU/RAM/可讀性;一項一改 |
19. TigerVNC 與桌面後端:實作規格
19.1 明確的兩條路
候選 A:Xvnc 取代 Xvfb+x11vnc。 TigerVNC 的 Xvnc 同時提供 X server 與 VNC server [E5]。此案希望減少虛擬顯示再由另一程序匯出的層次;收益是待測假設,不保證 agent 推理更快。
候選 B:保留 Xvfb,只用 x0vncserver 取代 x11vnc。 x0vncserver 是匯出既有 X display,不建立新的 display [E6]。它不是「Xvfb 一起換掉」。只有候選 A 遇相容性阻礙時再測 B,避免一次三套都當主線。
noVNC 是 viewer;websockify 是 WebSocket 到 VNC 的橋接。換 Xvnc 不代表可以直接刪掉這兩層;第一版保留既有 authenticated screen proxy 與 noVNC UI [E7]。
19.2 原始碼落點
image/computer/Dockerfile:加入發行版可用且 pin 的 TigerVNC 套件,保留 baseline fallback。安裝後記錄實際 binary 名稱/版本(不同套件可能叫 Xvnc 或 Xtigervnc),不是假設名字一定相同。image/computer/lazyboy-screen:將 start_xvfb/start_vnc 抽成 DisplayBackend,沿用 ensure_slot 和 per-slot identity/locking。保留顏色、中文、DBus/AT-SPI、Cua socket、profile、日誌。image/computer/start.sh/crates/controld:分 runner/display/viewer readiness;按需啟動而非工具讀檔前全部 boot。crates/control/src/screen.rs/supervisor:保留 slot→display/view port 契約,增加 backend/session epoch 與 capabilities。实际檔案/函式存在與否先核對,不盲插模板。screen_proxy.rs/noVNC UI:保留 server-side auth/membership/control lease、斷線恢復與鍵鼠權限;不要只有 viewOnly 前端旗標。
19.3 最容易踩錯的地方
- 基準 slot 0 是 DISPLAY
:1、RFB5900、web6080;slot 1 是:2、5901、6081。Xvnc 常用預設是 5900+display-number,不得拿預設值默默改掉既有對應;明確設定 rfbport,寫契約測試 [R9][E5]。 - 每 slot 的 X11、Cua、DBus、AT-SPI、XDG_RUNTIME_DIR 與 browser profile 一起綁定,不用全域可變 DISPLAY。不能以「共用主機」為由退回所有 agent 同一滑鼠。
- Cua 的 X11 截圖/輸入、XTEST、RANDR、clipboard、視窗 enumerations 需要在選定套件實際 probe;AT-SPI 是桌面/應用和 bus 的能力,不是 Xvnc 自動提供。
- 先固定現有 1280×800/24-bit 並保持一致 DPI/scale,避免把 backend 差異和解析度差異混在 benchmark。viewer 可 CSS fit,但座標需轉成實際 display pixels;resize 成功後 invalidate refs。
- human viewer 的有損壓縮/FPS 調整不能降低 agent 驗證圖的可讀性。模型 observation 仍由明確的高可讀 capture 路徑取得。
- X11/RFB 僅在受控邊界可達;不裸露公網的 5900/6080/CDP。評估移除
-ac需要同步實作 Xauthority/client credentials,不能只删旗標導致 Cua 壞掉。 - 現有
-noxdamage可能是舊相容性 workaround,只有在重繪 fixture 過關後才能改。xfwm4 --compositor=off已經存在,不能重複列提速成果 [R9]。 - Xvnc 是 X server,殺掉它就會中斷使用它的 X clients;無 viewer 時可以停/降頻 viewer bridge,但不能因此殺死仍在工作的 display。stop/recreate/backend 切換需受控停止點,不是無縫熱切 X server。
- 清理 stale pidfile/X lock/Chromium SingletonLock 前先確認對應程序與 profile ownership;不以 pgrep 字串近似或一律 rm lock 把活躍 session 搞壞。
- 大版本更換仍可能影響 Unicode clipboard、快捷鍵、drag、輸入焦點;測手機/桌面 reconnect、human takeover、雙 viewer read-only 與 writer。
19.4 對照測試與採用門檻
固定模型、任務、容器資源、Cua/Chromium/noVNC 版本、screen size 與 LAN/WAN 條件。至少含空桌面、靜態網頁、捲動、輸入表單、對話框、影片、兩個 Team displays 同時操作。
分開量測:
- Agent path:model time、工具時間、Cua snapshot latency、action→verified effect、完成率、重試數。
- Viewer path:input-to-present latency、frame update interval、重繪完整性、小字可讀性、reconnect、網路 bytes。
- 資源:每 display/整台 Computer CPU、RSS、程序數;有 viewer 與無 viewer 各測。
硬 gate 是既有 GUI/輸入/a11y 正確性不退步,不能用更模糊畫面換好看的 FPS。採用預設前提出量測理由;只有 viewer 變順時,報告 viewer 改善,不宣稱整個 agent 任務提速。無 GUI 環境則標 BLOCKED_EXTERNAL 並保留 baseline default。
19.5 不建議同時改的東西
Selkies、Xpra、Wayland、換整個 Linux 發行版是不同級別的變更。Selkies 目前官方文件列 WebSocket 為預設、WebRTC 為選用,不能只照舊 README 說一定需要 WebRTC/TURN;硬體編碼可用與否也要 probe [E8]。Xpra 有自己的 HTML5/session forwarding 架構,不是改一個 VNC executable 就完成 [E9]。沒有影音/單應用發布需求時,先保留 noVNC。
20. 可安裝外部工具:Tool Manager 與擴充契約
20.1 三種形式與真正的執行位置
| 形式 | 實作方式 | 限制 |
|---|---|---|
| stdio MCP | Computer 內啟動經審查的 Node/Python/Rust executable,generic MCP adapter 載入 schemas | MCP package 可執行程式;固定版本與 runtime grants;API 不 spawn |
| CLI/自製本機工具 | 套件裝在 Computer,manifest 把 argv/stdin/stdout/schema 接到受控 executor | 不能直接把任意 shell 字串當受信任 metadata;binary 必須在 scope 中 |
| HTTP MCP/SaaS connector | client 在 Computer;呼叫批准的外部服務,artifact/download 落在 Computer | remote MCP server 仍在遠端;不能外包本機任務檔案處理/code execution |
普通 REST SDK 不會自動變成 agent tool;需要一層 adapter/MCP server/manifest wrapper。完成通用載入後,新 MCP 不應每次修改 Rust 核心 dispatch;新 provider 的特殊 API 語意仍可能需要寫 adapter。
先支援手動來源與小型內建 catalog,不以「先蓋完整 marketplace」阻擋交付。來源可為受控 manifest URL、上傳套件、已知 catalog;下載與解包在指定 Computer。公開 registry 只協助 discovery,不等於套件已審核安全。
20.2 必須分開的四個層次
Package:程式、來源、版本、hash、相依
Installation:安裝在哪個 Computer、狀態、可重建資料
Binding:哪個 agent 可以看見/呼叫哪些 capabilities
Connection:哪個真實帳號、OAuth/secret grant、允許操作
shared Computer 可以一份唯讀 package 供 A/B 用;A 的 Outlook grant 不會因此授給 B。相同套件可有兩個私人 server instances/設定。shared/ 是否可讀寫另外核准,不因已安裝就自動全開。
20.3 安裝與啟用流程
- 選來源與目標:顯示 shared/private Computer、受影響 agent、package publisher、版本、雜湊、平台/CPU 架構需求。
- 驗 manifest:schema version、entrypoint、dependency lock、network/service domains、filesystem scope、工具名衝突、requested permissions。
- 核准安裝:套件程式執行與資料存取風險分開。不能由模型、網頁、郵件或外掛自己的提示自動授權。
- Computer 內 staging install:versioned 目錄、受限網路/CPU/磁碟、safe archive extraction,防 traversal/symlink/hardlink 逃逸和解壓炸彈;package install hooks 同樣受控。
- 健康/契約測試:啟動、tools/list、schema validation、read-only mock call、version/compatibility。不能在 healthcheck 時默默寄信或修改真實帳號。
- 登錄 registry:安裝及 schema 成功後原子啟用 binding。顯示 INSTALLED/CONNECTED/AUTH_REQUIRED/READY/DEGRADED,不用單一「成功」。
- 使用者 OAuth:核對 account/tenant/scopes;同意後 token 保存在 broker 保護區,模型只見 opaque handle;新增寫入權限再核准。
- 實際測試與紀錄:每次 tool call 綁 agent/computer/package version/account,透過統一 policy/audit/result;外掛失敗不讓整個 harness 崩潰。
工具入站權限、網路 egress 與 OS sandbox 由 host/runtime 強制;不能信 MCP annotations 的 readOnlyHint 就斷定沒有副作用 [E19–E20]。支援標準 MCP 不等於支援任意 auth 形態:HTTP OAuth discovery/PKCE 與 stdio 的本機憑證配置是不同流程;不把標示 SSE 的 server 當成一定可用 Streamable HTTP,按 negotiated transport 實测 [E20]。
20.4 狀態、更新與安全點
安裝狀態與連線狀態分開:PENDING_APPROVAL → INSTALLING → INSTALLED;instance 為 STARTING → CONNECTED → AUTH_REQUIRED/AUTHENTICATED → READY/DEGRADED/DISABLED。可用性是 installed + compatible + healthy + grant + account,不只 process alive。
更新採 staging → contract tests → permission diff → atomic activation。當前 operation 和長 job pin package_digest + schema_version + connection;新 run 才用新版,或在明確安全點重取 registry。外掛的 scope 變大或 tool schema 有 breaking change 要重新核准,不能默默延用舊 grant。
移除先撤銷 binding、阻止新呼叫、drain/cancel 對應 instance;其他 agent 使用的 package 不刪。若外掛持有 token,僅停止 process 不代表遠端 token 已撤銷;提供 provider logout/revoke 流程和殘留風險說明。
一般 user-space plugin 安裝/更新不重建 API image、不重啟整台 Computer。系統 package/顯示 driver/需 root 的改動另外走管理核准和 maintenance barrier,shared 時顯示全部受影響成員。
20.5 範例 manifest(設計範例,不是已發佈 npm 套件)
以下示範的是 要由 coding agent 實作/審查的本機 Outlook adapter。空的 artifact/digest 必須拒絕安裝,不能填想像中的套件名稱或把此範例當已可直接安裝:
manifest_version: 1
id: lazyboy.example.outlook
version: 0.0.0-example
source:
kind: reviewed_local_artifact
artifact_ref: null # 實作完成後填實際來源
sha256: null # 安裝器不可接受空 hash
runtime:
kind: stdio_mcp
execution_location: assigned_computer
entrypoint: [./outlook-adapter]
state_scope: agent_binding
installation:
supported_modes: [shared, dedicated]
share_immutable_package: true
permissions:
filesystem: [own_workspace]
shared_paths: []
network_services: [microsoft_graph, microsoft_identity]
needs_host_access: false
needs_root: false
connection:
provider: microsoft_graph
credential_delivery: broker
grant_scope: agent
capabilities:
- outlook.messages.list
- outlook.messages.read
- outlook.categories.preview
- outlook.categories.apply_plan
- outlook.categories.verify_plan
名稱、路徑與 manifest API 都是新設計;Graph 的官方 API/OAuth 不等於存在官方同名 MCP package。第三方工具若僅接受 env token,按第 10.2 節顯示權限與相容限制,不把未實作 broker 相容性藏起來。
20.6 MVP UI/API
UI 在 Computer/Agent 的 Tools 頁:新增來源、選安裝目標、分配 agent、連接帳號、權限摘要、測試、啟用/停用、版本/更新/回滾/移除、活動紀錄。流程可以跨頁引導,不要求先設計大型商店。
建議的內部 API 職責:validate manifest、install job、read installation status、create/revoke binding、start OAuth、list effective capabilities、update/rollback、remove。這些路由需新的 typed contracts/auth/idempotency,不讓 LLM 呼叫安裝管理 API 自行批准。
Registry 改變以 event 通知 harness/UI,授權撤銷立即阻止新 dispatch;活躍 run 在下一安全點讀取版本化 registry。不要每回合重連全部 MCP,也不要讓一次安裝把所有工具 schema 全塞入 prompt。
21. Outlook connector:第一個外部擴充驗收案例
21.1 產品選擇與帳號範圍
建議以 Microsoft Graph v1.0 + 使用者 delegated OAuth 建立 Computer-local adapter;將它包成通用 loader 能安裝的 MCP/本機工具,證明外掛模型不是只支援 built-in Gmail。個人 Outlook.com 與 Microsoft 365/Exchange Online 工作/學校帳號各測;實際 tenant policy、admin consent、MFA 或授權限制正常顯示,不承諾公司帳號一定免審。
「Outlook connector」是泛稱。Power Automate/Logic Apps 的 Outlook connector 是其平台整合,不是通用 Linux binary 可直接下載進 LazyBoy [E21]。本計劃不採外部 Power Automate 作本機檔案處理或 workflow 執行的隱性替代。Outlook 桌面程式裡加入的任意 IMAP/本機 Exchange 帳號,也不能由名稱就推定支援 Graph;以 mailbox provider probe 為準。
21.2 權限逐步增加
| 階段 | 權限/範圍 | 可用行為與限制 |
|---|---|---|
| 基本郵件列表 | 評估 Mail.ReadBasic 是否足夠 | headers/基本資料;不能假定包含分類所需正文/preview [E14] |
| 需讀內容分類 | delegated Mail.Read 或較高已核准 scope | 只取必要欄位,必要正文才取,資料是 untrusted content |
| 修改 message categories | delegated Mail.ReadWrite | tool 層只開放 categories,不因 broad scope 自動允許刪信/draft 等 [E12] |
| 建立 master categories | MailboxSettings.ReadWrite | 額外權限;第一版可先用既有分類,避免未必要的 scope [E13] |
| 寄信/搬資料夾/日曆 | 另外定義 capability 與核准 | 不列為郵件分類預設權限,不自動打開 |
OAuth 採正式 authorization code + PKCE/適用的受支援 auth library;按 app 類型正確保護 client credential,state/nonce/redirect URI 核對;是否申請 offline_access 依 refresh 需求 [E11]。不從 browser cookie 抽 token、不讀使用者密碼、不略過 MFA。
21.3 端到端流程
在指定 shared/private Computer 安裝 Outlook adapter
→ 對 agent 建 binding
→ 使用者授權 Microsoft 帳號
→ 檢查 mailbox/account identity 與 operation grant
→ 取指定範圍郵件、完整處理分頁
→ rule-first + model 批次分類、模糊結果留待確認
→ 產生只含 categories 變更的 immutable plan
→ 核准 plan hash/account/message 範圍
→ 執行 Graph 更新(有界批次)
→ 逐項讀回/驗證/記錄 changed/unchanged/failed/unknown
Graph 以 PATCH /me/messages/{id} 的 categories 屬性更新,這不是 Gmail label id 的 add/remove API [E12]。維持原有非本次變更分類,先讀當前 categories 計算目標;不要直接把固定分類陣列覆蓋其他人的分類。
對同 mailbox 使用 canonical account resource lock。若 API 支援可驗證的 conditional update,需實測其 If-Match/etag 語意;本計劃不預設 Graph message PATCH 支援通用 CAS。若無原子比較交換,外部 Outlook 客戶端仍有競爭窗口,必須標示 best-effort、遇可見衝突停止/重規劃;本地 lock/事後讀回不等於保證不丟失人類並行更新。
21.4 批次、分頁與常駐同步
- Graph JSON
$batch最多 20 個子請求,每個子項獨立狀態;batch HTTP 200 不代表全部成功。按子項處理 401/429/5xx 與 Retry-After;這與 Gmail 1,000 message IDs 的 batchModify 不同 [E15–E16]。 $select僅取必要欄位;完整跟隨 server 的@odata.nextLink,不自行拼接 skip/把第一頁當全部 [E14]。驗證 continuation URL 仍是允許的 provider,防 SSRF/account confusion。- 使用
Prefer: IdType="ImmutableId"需在需要的每個 request/batch 子 request 保持一致;它在同信箱移動 folder 時穩定,但跨 archive mailbox/匯出再匯入仍有例外 [E17]。 - recurring sync 後續用 每個 folder 的 message delta,維護相應 nextLink/deltaLink;不是任意 search 的全信箱通用增量游標。token 失效時有安全重同步流程 [E18]。
- pending/unknown write 先回讀,不能全批盲重送;分類 cache 需包含 mailbox/message/content version/taxonomy version,不能拿另一帳號或舊內容結果套用。
- 附件下載到 Computer,掃描/解析/資料轉換也在 Computer;長期不需要的信件原文不存中央 DB。
21.5 必需交付
fake Graph HTTP provider、固定測試 mailbox data、範例 package build、可安裝 manifest、read/preview/apply/verify tests、shared A 有權 B 無權的測試、版本更新/token 撤銷與恢復、完整 Activity 記錄。
真實 OAuth 不可用不阻擋上述內部實作,但必須將真實帳號 E2E 標 BLOCKED_EXTERNAL。不得把 fixture 的分類數字寫成真的已替使用者整理 Outlook。
附錄 A:依據與查核來源
以下是本計劃使用的基準原始碼與官方規格。coding agent 必須以其開始實作時的 HEAD 核對,不盲套行號;新設計與 target 不是上游已具備的功能。
Repository 與前次健檢
- 基準 repository:
https://github.com/igs170911/LazyBoy - Commit:
e6afa324530e19922909d4692c28fb005cc05a7a - [R1] 工具與截圖:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/api/src/tools.rs - [R2] SandboxProvider/原生契約:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/control/src/sandbox.rs - [R3] Sandbox transport/檔案 bytes:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/sandbox/src/docker.rs - [R4] Supervisor 容器內執行:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/supervisor/src/docker.rs;routes:https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/supervisor/src/main.rs - [R5] Harness loop/prompt:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/api/src/runs.rs - [R6] Browser adapter:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/control/src/cua/browser.rs - [R7] Run policy:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/harness/src/policy.rs - [R8] MCP:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/crates/api/src/mcp.rs - 前次本對話產物:
LazyBoy_Computer_Use_Healthcheck_2026-09-10.md。本文件已包含必要內容,可獨立交付;若與舊文件的 GUI 可見性或 Team 共用假設不一致,以本文件第 0–1 節為準。
官方外部文件(2026-09-10 查閱)
- [E1] Gmail batchModify/最大 1,000 IDs/空成功回應:
https://developers.google.com/workspace/gmail/api/reference/rest/v1/users.messages/batchModify - [E2] Gmail OAuth scopes 與受限資料說明:
https://developers.google.com/workspace/gmail/api/auth/scopes - [E3] Playwright connectOverCDP/現有 browser context/相容性限制:
https://playwright.dev/docs/api/class-browsertype - [E4] Docker isolation、安全邊界與 daemon 權限參考:
https://docs.docker.com/engine/security/
Docker 容器隔離不是不需測試的安全保證;應依威脅模型與官方指引配置權限、network、mounts、resource limits,並以本文件的跨 Computer 測試驗證 [E4]。
本版新增來源(2026-09-10 查閱;不是把官方支援當成 LazyBoy 已整合)
- [R9] LazyBoy display 啟動/Team slots/Xvfb/x11vnc/XFCE/Cua:
https://github.com/igs170911/LazyBoy/blob/e6afa324530e19922909d4692c28fb005cc05a7a/image/computer/lazyboy-screen - [E5] TigerVNC Xvnc:
https://tigervnc.org/doc/Xvnc.html - [E6] TigerVNC x0vncserver:
https://tigervnc.org/doc/x0vncserver.html - [E7] noVNC 與 WebSocket proxy:
https://novnc.com/info.html - [E8] Selkies 現行設計/transport/encoder:
https://docs.selkies.io/design;https://selkies-project.github.io/selkies/component - [E9] Xpra 應用與桌面轉送/HTML5:
https://xpra.org/index.html - [E10] Playwright Docker 與 Chromium/程序回收注意事項:
https://playwright.dev/docs/docker。本案不直接採測試容器常見的 host IPC/SYS_ADMIN 放寬,保留產品隔離要求。 - [E11] Microsoft authorization code/PKCE:
https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow - [E12] Graph message update/categories/Mail.ReadWrite:
https://learn.microsoft.com/en-us/graph/api/message-update?view=graph-rest-1.0 - [E13] Graph master categories 建立/MailboxSettings.ReadWrite:
https://learn.microsoft.com/en-us/graph/api/outlookuser-post-mastercategories?view=graph-rest-1.0 - [E14] Graph messages 列表/$select/分頁/permissions:
https://learn.microsoft.com/en-us/graph/api/user-list-messages?view=graph-rest-1.0 - [E15] Graph JSON batching/20 子請求:
https://learn.microsoft.com/en-us/graph/json-batching - [E16] Graph throttling/子請求失敗:
https://learn.microsoft.com/en-us/graph/throttling - [E17] Outlook immutable IDs 的範圍與例外:
https://learn.microsoft.com/en-us/graph/outlook-immutable-id - [E18] Graph folder message delta:
https://learn.microsoft.com/en-us/graph/api/message-delta?view=graph-rest-1.0 - [E19] MCP tools/annotations 信任限制:
https://modelcontextprotocol.io/specification/2025-11-25/server/tools - [E20] MCP HTTP authorization/transport:
https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization - [E21] Microsoft Office 365 Outlook 平台 connector:
https://learn.microsoft.com/en-us/connectors/office365/
研究只證明上游文件與基準程式呈現的行為;本機 Docker/GUI/企業帳號、實際效能及完整威脅邊界仍須 coding agent 按測試矩陣驗證。不存在單純換 VNC 就保證所有 agent 任務提速的證據。