09 · Workspace、Environment 与隔离¶
一句话结论: Paperclip 把长期代码根、一次执行位置、计算环境、租约和伴随服务建成不同对象;选择策略由 Project 默认、Issue 覆盖和 Trust Preset 联合决定,执行结束后还要显式 finalize/sync/cleanup。
1. 先区分五个对象¶
| 对象 | 生命周期 | 回答的问题 |
|---|---|---|
| Project Workspace | 长期、项目级 | 这个项目的代码/文件根在哪里 |
| Execution Workspace | 一次任务或一组相关任务 | 这次实际在哪个副本/分支/远端路径工作 |
| Environment | 可复用能力定义 | 用本机、SSH、sandbox 还是插件 provider 执行 |
| Environment Lease | Run 级占用 | 哪次执行暂时拥有哪个环境实例 |
| Runtime Service | 与 workspace/run 关联的进程/服务 | preview、dev server、browser 等怎样启动和复用 |
它们分开的原因是生命周期不同。把它们全叫 cwd 无法表达远端、租约、复用和清理。
2. Project Workspace:稳定锚点¶
project_workspaces 记录:
- company/project;
- name、cwd;
- repo URL/default ref;
- setup/cleanup command;
- remote provider/ref;
- shared workspace key;
- primary 标记;
- runtime config。
Project 可以有零个、一个或多个 workspace。没有 workspace 的非代码项目仍然合法;monorepo 也可以为多个包配置不同根。
3. Execution Workspace:运行事实¶
execution_workspaces 记录:
- company/project/project workspace/source issue;
- mode/strategy/status;
- cwd、repo/base/branch;
- provider kind/reference;
- derived workspace 关系;
- cleanup state;
- 可复用/关闭语义。
典型形态:
flowchart TD
PW["Project Workspace\nmain checkout / remote source"]
PW --> SHARED["Shared execution\nsame root"]
PW --> ISO1["Isolated workspace\nissue A worktree"]
PW --> ISO2["Isolated workspace\nissue B sandbox"]
PW --> BR["Reusable operator branch\nseveral related issues"]
Issue 可以继承 Project policy、强制 shared/isolated、或复用已有 execution workspace。
4. Policy 选择过程¶
可以把最终模式理解为:
Project executionWorkspacePolicy
+ Issue executionWorkspacePreference/settings
+ Adapter capability
+ Environment availability
+ Source trust preset
+ Existing compatible workspace/session
= Effective execution plan
4.1 Trust 会收紧而不会放宽¶
低信任来源可强制 isolated workspace、禁用共享目录或要求 review。即使 Project 默认 shared,trust policy 也能将结果收紧。
4.2 Issue override 受 Project policy 约束¶
如果项目禁止 Issue 覆盖,Issue 不能自行选择更宽松的 shared/reuse;服务端计算 effective policy,UI 选项只是输入建议。
5. Environment:在哪里执行¶
Environment 描述执行驱动和配置,常见 driver:
- local;
- SSH;
- sandbox provider;
- plugin-contributed environment driver。
环境可声明:
- 配置、镜像、网络与 filesystem 能力;
- provisioning/probe;
- command execution/file transfer;
- lease/cleanup 机制;
- custom image template。
环境记录本身是可复用定义,不等同某次动态 sandbox 实例。
6. Lease:环境占用的事务边界¶
environment_leases 将 company、environment、execution workspace、issue 和 run 关联,并记录:
- status/policy;
- provider lease reference;
- acquired/last used/expires/released 时间;
- failure/cleanup metadata。
stateDiagram-v2
[*] --> Acquiring
Acquiring --> Active: provider allocated
Acquiring --> Failed: provision error
Active --> Active: heartbeat / lastUsed
Active --> Releasing: run terminalized
Active --> Expired: lease timeout
Releasing --> Released: sync + cleanup
Releasing --> Failed: cleanup failure recorded
Lease 让环境清理可以重试和审计,而不依赖某个 finally 恰好成功。
7. Realization:把抽象 workspace 变成可执行目录¶
不同 transport 的 realization 不同:
直接使用 project cwd 或创建 Git worktree/派生目录;通常不需要上传下载。
通过远程命令建立目录,必要时用 Git bundle/import/export 传递 repository 状态。
通过 archive upload/download 同步文件,在 provider 内创建隔离实例。
由 environment driver 定义 provision、exec、sync 和 cleanup,但仍返回核心可理解的 workspace/lease 记录。
核心 contract 明确不假设远端拥有 Git remote 凭据,也不自动 push。
8. Workspace Operation 是持久化步骤账本¶
workspace_operations 记录 prepare/finalize 等命令:
- phase;
- command/cwd;
- status;
- run/issue/workspace;
- log metadata;
- started/completed/error。
这解决两个问题:
- setup/cleanup 失败不再只存在 Server log;
- blocker completion 可以等待上游 finalize 真正 settled。
9. 一个隔离执行的时序¶
sequenceDiagram
participant H as Heartbeat
participant P as Policy Resolver
participant W as Workspace Service
participant E as Environment Driver
participant DB as PostgreSQL
participant A as Adapter
H->>P: project + issue + trust + adapter
P-->>H: isolated workspace plan
H->>W: find or create execution workspace
W->>DB: persist preparing workspace
W->>E: acquire lease + provision
E-->>W: providerRef / remote cwd
W->>E: upload/bundle + setup command
W->>DB: operation succeeded, workspace ready
H->>A: execute in realized target
A-->>H: terminal result
H->>W: finalize
W->>E: export/download changes + cleanup
W->>DB: finalize operation settled
H->>E: release lease
10. Runtime Service:伴随执行的可管理进程¶
Agent 可能启动 dev server、preview、browser bridge 等。workspace_runtime_services 记录:
- scope/service kind;
- status/lifecycle/reuse policy;
- command/cwd/port/url;
- provider、owner、run;
- health/stop metadata。
如果只让 Agent npm run dev &:
- Server 不知道进程属于谁;
- 下轮可能重复占端口;
- workspace 关闭时无法清理;
- UI 无法把 preview 作为 work product;
- server restart 后会变成孤儿。
Runtime service 把这类进程纳入控制面。
11. Local service supervisor¶
本地 service supervisor 负责:
- 启动命令并保存 PID/process group;
- 端口/URL 分配;
- stdout/stderr 与健康状态;
- reuse 或冲突处理;
- 有界 stop;
- startup orphan reconciliation。
远端 provider 可用 provider reference 代替本地 PID,但需要给核心提供同等生命周期信号。
12. Custom Image Setup 是另一条受控运行链¶
Environment custom image 允许交互式构建运行环境。它有专门的:
- template;
- setup session;
- terminal session token;
- terminal WebSocket;
- finish/cancel/rollback。
Terminal WebSocket 自己做 token、session 和 environment 校验,不复用普通 live event socket。构建完成后才更新可选镜像版本,避免半成品成为默认环境。
13. Workspace 文件访问的安全边界¶
File resource service 不接受任意 host path。它:
- 只从 Issue 关联的 execution/project workspace 候选中选根;
- 对输入做相对路径规范化;
- 拒绝绝对路径、
..逃逸、home/system/secret 目录; realpath后再次确认目标仍在根内,抵抗 symlink escape;- 对内容和 preview 设置大小上限;
- 远端 workspace 返回 provider resource,而不是假装本地可读。
用户路径
→ normalize segments
→ select authorized workspace root
→ realpath(root), realpath(target)
→ target must be inside root
→ type/size/content policy
→ preview/download
14. 多 Project Workspace 的当前边界¶
Issue 的主执行 workspace 可以被完整 realization。引用的附加 project workspace 在本地更容易直接可见;远端 transport 未必会把所有附加 workspace 一并同步。
这是阅读能力声明时要注意的边界:数据模型支持多 workspace,不等于每个 remote adapter 已实现多根一致同步。
15. Cleanup 不是删除目录这么简单¶
关闭 execution workspace 前要判断:
- 是否还有 live run/lease;
- runtime service 是否仍在使用;
- pending finalize 是否完成;
- work product/preview 是否需要保留;
- reusable workspace 是否被其他 Issue 引用;
- provider cleanup 能否重试;
- 本地路径是否确实由 Paperclip 管理。
所以 UI 有 close-readiness,Server 有 workspace instance cleanup 与 operation ledger。系统不会对不明确的 host path 做激进递归删除。
16. Workspace 与 Work Product 的边界¶
Execution workspace 是工作发生地,Work product 是人应审查的输出摘要:
- PR/branch/commit;
- preview URL/runtime service;
- uploaded artifact;
- workspace file reference。
关闭 workspace 不应自动抹去已上传 artifact 和外部 PR 记录;反过来,文件仍在 workspace 也不代表已交付。
17. 常见故障与收敛¶
| 故障 | 处理方向 |
|---|---|
| worktree 创建失败 | operation failed,run setup error,不进入 adapter |
| sandbox acquire timeout | lease failed/expired,按 provider 分类 retry |
| upload 完成但 DB 未 ready | reconciliation 检查 provider ref 与 operation |
| adapter 成功但 download/finalize 失败 | run 与 workspace finalize 分开记录;下游依赖继续等待 |
| cleanup 失败 | 保留 workspace/lease 失败状态,后台重试/人工处置 |
| runtime service 变孤儿 | supervisor/recovery 按 PID/provider reference 扫描 |
| symlink 指向 workspace 外 | file resolver realpath 检查拒绝 |
18. 可复用经验¶
- 长期项目根、执行副本、计算环境和租约要分对象。
- Effective policy 应由默认、覆盖、capability 和 trust 共同解析。
- Workspace prepare/finalize 要有持久化 operation,而非隐藏 shell hook。
- Run 终态和 workspace finalize 是两个事实,下游 readiness 要看后者。
- 远端同步 contract 不应默认拥有 Git push 权限。
- 文件浏览必须基于注册 root + realpath containment,不能接收任意绝对路径。
- Runtime service 也需要 owner、health、reuse 和 cleanup。
源码入口¶
packages/db/src/schema/project_workspaces.tspackages/db/src/schema/execution_workspaces.tspackages/db/src/schema/environments.tspackages/db/src/schema/environment_leases.tspackages/db/src/schema/workspace_operations.tspackages/db/src/schema/workspace_runtime_services.tsserver/src/services/workspace-realization.tsserver/src/services/execution-workspaces.tsserver/src/services/environment-run-orchestrator.tsserver/src/services/workspace-runtime.tsserver/src/services/workspace-file-resources.ts
执行位置确定后,还必须回答谁能做什么:10 · 身份、认证与细粒度授权。