第 14 章:可靠性、构建与测试体系
1. 可靠性的对象不是“页面不报错”
Orca 中更严重的失败包括:
- 重复启动昂贵或有副作用的 Agent;
- renderer reload 后丢失后台 PTY;
- SSH 断线被误判为进程退出;
- stale session 复活已关闭 terminal;
- 大量输出拖死 event loop;
- 更新时杀死用户正在运行的任务;
- secret 进入 renderer/log;
- 新 Git/relay 特性让旧 host 无法工作。
所以可靠性设计围绕身份、边界、恢复和兼容,而不仅是 try/catch。
2. Failure taxonomy
| 失败类别 | 典型处理 |
|---|---|
| 明确未执行 | 可安全 retry/fallback |
| 已提交 | 返回/保存 canonical result |
| 结果未知 | fence,禁止复制副作用 |
| 资源明确不存在 | 清理/创建新资源 |
| 资源不可观察 | 保留 claim,等待重连 |
| stale generation | 静默丢弃迟到结果 |
| schema/协议不兼容 | capability fallback 或显式阻断 |
“unknown” 是独立状态,而不是 error 的同义词。这一点贯穿 SSH、spawn、automation 和 orchestration。
3. 有界性清单
源码大量常量不是随意优化,而是服务长期运行:
- JSON payload byte/depth/token;
- hook body slowloris timeout;
- status history、closed pane set;
- terminal hidden backlog;
- plugin message size/rate;
- browser capture log;
- transcript cache bytes/entries;
- SSH frame size/turn budget;
- orchestration receipt retention;
- worktree scan concurrency/timeout;
- Git maxBuffer。
设计一个新缓存或队列时,必须回答:按什么 key 增长、什么时候清理、断线时能否继续增长、上限到达后如何降级。
4. Event loop 保护
Electron main 卡住意味着 PTY、SSH、IPC、窗口都一起卡。Orca 使用:
- frame decoder 每 turn 时间/字节预算;
- terminal foreground write budget;
- watcher batching/coalescing;
- 大解析放 worker;
- event-loop stall probe;
- main-thread churn probe;
- hang watchdog 与 marker;
- renderer heap highwater profile。
性能问题会进入 breadcrumb/diagnostic,而不只靠用户描述“卡了”。
5. Diagnostics 与 Telemetry 分离
Diagnostics 面向本地故障证据;Telemetry 面向匿名产品/错误事件。源码明确让 diagnostics handler 只依赖 observability,不与 telemetry 共用路径。
这样用户关闭 telemetry 时,本地诊断仍可用;也避免“为了 debug 必须上传数据”的隐性绑定。
6. Crash recovery
Renderer crash
检测 process-gone,记录 breadcrumb,按分类 reload;PTY 在 main/daemon,使用 snapshot 恢复。
Main hang/crash
watchdog marker、crash store、GPU fallback;daemon-backed PTY 可跨 main 生命周期保留。
GPU crash
在时间窗口内计数候选 crash,达到阈值提示/应用 GPU fallback 开关,避免无限 crash loop。
Remote runtime replacement
runtime id/epoch 变化使 capability cache 和旧 connection generation 失效,重新同步 graph 与 owner listing。
7. Cross-platform contract
Orca 明确支持 macOS、Windows、Linux、WSL、SSH。主要差异:
- shortcut:Cmd/Meta vs Ctrl;
- path:POSIX、Win32、UNC、WSL;
- shell:zsh/bash、PowerShell/cmd、WSL;
- process tree kill;
- terminal ConPTY 行为;
- keychain/DPAPI/secret service;
- native modules 与 glibc;
- app update/install mode;
- file ACL 与 code signing。
平台判断需要在资源实际执行的 host 上完成,不能只读桌面 renderer 的 navigator.platform。
8. Linux glibc 与 native module
Linux 构建的 native binary 若在新 runner 编译,可能引用 Ubuntu 20.04 / glibc 2.31 不支持的 symbol。发布流程检查 bundled native binary 的 GLIBC symbol floor。
这比 package.json 声明支持 Linux 更真实:native module 的 ABI 才决定是否能启动。
9. 构建图
主要 target:
- main/preload/renderer;
- CLI;
- SSH relay;
- web client;
- computer/notification native helpers;
- platform package;
- mobile 独立 Expo pipeline。
配置脚本承担 native runtime 切换,因为 node-pty 等需要针对 Node 或 Electron ABI 重建。
10. 测试金字塔
Unit tests
与实现同目录,覆盖 parser、state machine、admission、migration、race。很多复杂文件都有数千行测试。
Contract tests
验证 main/preload/renderer schema parity、CLI spec registry、Git capability、plugin manifest、protocol version。
Integration / reproduction
真实启动 headless Electron、daemon、SSH docker 或子进程,复现远程 Agent session、PTY early exit、hook relay 等。
Playwright E2E
Electron headless/headful,覆盖 workspace、terminal rendering、IME、webgl、source-control scale、mobile emulator、browser。
Benchmarks
startup、idle CPU、daemon cold start、main jank、worktree deletion、typing、memory、terminal park/reveal。
11. 为 race 写测试
Orca 最有价值的测试不是 happy path,而是明确排列时序:
- response 前 exit;
- disconnect 后旧 generation event;
- 两个并发 capability probe;
- snapshot 与 live bytes 交叉;
- 两个客户端 create 同一 claim;
- preflight 后外部修改;
- unsubscribe 与 watcher callback 同时发生;
- renderer stale save 晚于 host retirement。
这类测试通常使用 deferred promise、fake clock 和直接访问内部 store,而不是依赖不稳定 UI sleep。
12. Lint 与代码质量门
脚本包括:
- oxlint + type-aware rules;
- React Doctor;
- changed-only quality checks;
- reliability gates;
- max-lines ratchet;
- localization catalog/extraction/coverage;
- bundled skill manifest 验证;
- feature wall asset 检查。
max-lines 采用 ratchet 而非一次性要求全部重构:现有大文件有 baseline,新改动不能继续无界增长或通过 disable 绕过。
13. 更新不能破坏运行会话
更新流程区分 check、download、install、remote server update 与 relaunch。关键问题:
- 是否有 live Agent/PTY;
- renderer 是否准备好 unload;
- daemon session 是否能保留;
- headless serve supervisor 是否接管;
- remote server 与 client 能否滚动升级;
- quit teardown 是否有 deadline。
“有更新”是状态,不等于立即退出进程。
14. 安全审查清单
对新增功能至少检查:
- renderer/guest/plugin 是否拿到不需要的能力;
- path 是否在资源 host 上规范化并防穿越;
- payload 是否有大小和结构上限;
- retry 是否会复制副作用;
- secret 是否进入日志/renderer/persistence 明文;
- stale event 是否有 generation/incarnation;
- remote unknown 是否被误判 dead;
- Windows/WSL/SSH 是否有不同执行路径;
- teardown 是否有 deadline 且幂等;
- 测试是否覆盖失败时序。
15. 源码导航
- package scripts:
package.json - build config:
config/ - observability:
src/main/observability/ - crash reporting:
src/main/crash-reporting/ - hang watchdog:
src/main/hang-watchdog/ - E2E:
tests/e2e/ - benchmarks:
tools/benchmarks/