跳转至

18 · Documents、Artifacts 与 Work Products

DocumentsRevisionsAttachmentsArtifactsWorkspace Files

一句话结论: Paperclip 把“正在编辑的结构化文档”“上传附件”“工作目录中的文件引用”和“供审查的工作产物”分别建模,既保留完整历史,也不把本地路径误当成远程可交付结果。

1. 为什么需要四种输出对象

Agent 完成工作后,可能得到:

对象 典型内容 是否依赖本地工作区
Document 计划、决策、说明、Case 文档 否,内容存储在 DB
Attachment / Asset 图片、视频、PDF、压缩包 否,内容由 storage provider 管理
Workspace File Resource 源码、报告、变更文件的相对路径 是,需注册 workspace 才能解析
Work Product PR、branch、preview、artifact、文档等交付摘要 可能,通常带 provider/ref

如果把这些全塞进 Issue description,会失去版本、权限、下载、清理、外部链接与审查状态。

2. Document 是版本化的可编辑对象

documents 表保存:

  • company/title/format;
  • latestBody、latestRevisionId、latestRevisionNumber;
  • created/updated actor;
  • lock actor/time;
  • source trust;
  • timestamps。

document_revisions 保存:

  • document + revision number;
  • title/format/body;
  • change summary;
  • created actor/run;
  • created time。

当前 body 是快速读模型,revision 是历史事实。(documentId, revisionNumber) 唯一约束防止并发保存同一版本。

3. Document 的保存路径

sequenceDiagram
  participant U as User / Agent
  participant R as Route
  participant D as Document Service
  participant DB as PostgreSQL
  participant E as Activity / Annotation

  U->>R: PUT document body + expected revision
  R->>D: validate actor + resource membership
  D->>DB: lock/compare current revision
  D->>DB: insert revision + update latest pointer
  D->>E: activity / mention / annotation effects
  DB-->>R: current document + revision
  R-->>U: canonical response

如果当前文档已锁定或 revision 不匹配,服务应返回冲突而不是静默覆盖他人编辑。

4. Document Annotation

Annotations 把评论绑定到文档中的 anchor:

  • thread/comment;
  • text position/quote selector;
  • anchor snapshot;
  • confidence/state;
  • open/resolved status。

它们不直接修改正文;解决 thread 也不等同接受文本变更。这使文档 review 可以与 revision 独立演进。

5. Legacy Plan 与 Issue Document

旧 Issue 描述中可能嵌有 plan body。Document service 提供 extractLegacyPlanBody 等兼容路径,把历史内容逐步映射到独立 Issue document,而不要求一次迁移所有任务。

这是一种重要的迁移策略:先提供读兼容,再让新写路径使用版本化对象。

6. Attachment 与 Asset

issue_attachments 只保存 Issue、Comment 和 Asset 的关系;实际文件由 assets 和 storage provider 管理。

上传流程通常是:

  1. 检查 company/issue 写权限;
  2. 校验 MIME、大小和 attachment limit;
  3. 流式写入 local disk/S3;
  4. 保存 asset 元数据;
  5. 建立 issue attachment/comment 关联;
  6. 生成可审查的 artifact/work product(按调用方式)。

普通 activity/log 不应内联二进制或完整 base64。

7. Artifact 与 Workspace File 的根本差异

内部交付手册把规则说得很清楚:

  • Board/reviewer 要检查的生成文件应上传成 artifact;
  • 本地 workspace path 不是云端用户可访问的交付物;
  • 只有需要继续在项目中使用的源文件才适合 workspace_file metadata;
  • workspace file link 必须携带 company/issue/workspace 语境,不能是 host absolute path。
本地生成 → 验证/渲染 → 上传 attachment → 创建 artifact work product → 评论中链接

8. Work Product 模型

issue_work_products 记录:

  • company/project/issue;
  • execution workspace/runtime service;
  • type、provider、external ID;
  • title/url/status/reviewState;
  • primary 标记;
  • health status;
  • summary/metadata/source trust;
  • creator run。

可表达:

  • GitHub PR;
  • branch/commit;
  • preview URL;
  • runtime service;
  • uploaded artifact;
  • document;
  • workspace file。

它是“任务交付物索引”,不是再次存储所有内容。

9. 交付物为什么关联 Execution Workspace

PR、preview、artifact 常常来源于某次具体 run/workspace。关联它们能回答:

  • 哪次执行生成;
  • 哪个 workspace/branch;
  • 哪个 runtime service 提供 preview;
  • workspace 关闭后哪些外部产物仍保留;
  • 哪个 source trust 等级产生了它。

如果只存一个 URL,审计者无法判断它是否真的来自本次任务。

10. Company Artifact Read Model

Company artifacts service 会:

  • 按 cursor 分页;
  • 按 media kind/content type 分类;
  • 读取文本 attachment preview;
  • 按 Issue 根/父任务分组;
  • 生成带 company prefix 的 deep link;
  • 处理 group-by issue/project 等过滤。

Cursor 使用 (updatedAt, id),比 offset 更适合不断产生新产物的时间线。

11. Workspace File Resource 安全路径

flowchart TD
  REQ["issue + relativePath"] --> CAND["authorized workspace candidates"]
  CAND --> NORM["normalize relative path"]
  NORM --> ROOT["realpath workspace root"]
  ROOT --> TARGET["realpath target"]
  TARGET --> INSIDE{"inside root?"}
  INSIDE -->|no| DENY["deny"]
  INSIDE -->|yes| SIZE{"kind/size/preview policy"}
  SIZE --> READ["read/list/download resource"]

它拒绝绝对路径、..、symlink escape、系统/秘密路径,并对 unknown binary 做类型 sniff 和 preview 上限。

远端 workspace 只能返回 provider-backed resource 或 unavailable 状态,不能伪造本地 fs.readFile。

12. Artifact upload 的可审查闭环

一份视频/PDF/截图等交付物应该经历:

生成 → 本地渲染/验证 → 上传 → canonicalize metadata
→ 创建 artifact work product → issue comment/link → final status

如果先把 Issue 标为 done,再上传失败,Board 会看到一个没有证据的完成任务。因此上传和 work product 创建应在最终 disposition 前完成。

13. Source Trust 传播

Document、Work Product、Issue attachment 可以保存 source trust metadata。它表达内容来自:

  • 用户;
  • Agent;
  • 外部 webhook/tool;
  • untrusted PR/remote source。

后续 low-trust promotion/review 会据此决定是否可进入更高信任的流程。复制内容时不能丢掉 provenance。

14. 外部对象与 Work Product

GitHub/Linear 等 provider 对象通常通过 external_objects + mentions/link 归一。Work Product 保存人类可点的外部 URL/status,external object service 负责刷新状态、回写 activity 和治理上下文。

外部 provider 更新不应直接覆盖 Issue status;它们之间通过映射规则和显式 sync/automation 关联。

15. 删除、归档与保留

  • Document revision 和 activity 通常保留;
  • Attachment asset 可按 retention/storage policy 清理,但关系与审计要有明确结果;
  • Work product 更偏向 archive/health 状态,外部 PR 不随 Issue 删除;
  • Workspace file 只是引用,workspace 关闭后可变为 unavailable;
  • Artifact upload 是独立持久化,不应因临时 workspace cleanup 被删。

16. 常见失败

失败 结果
文件超 attachment limit 上传前拒绝,不产生半个 artifact
storage upload 成功但 DB 关联失败 reconciliation/孤儿 asset 检查,不能标记已交付
workspace path 不可见 返回 unavailable/授权错误,而非 host path
文档 revision 冲突 409,用户重新加载/合并
preview service 已终止 work product health 更新,URL 可保留但标记 unhealthy
外部 PR 状态变化 refresh external object/work product,不伪造本地完成

17. 可复用经验

  1. 正文、文件、路径引用和交付摘要要分对象。
  2. Artifact 是给审查者看的 durable upload,不是本地路径的别名。
  3. Document 使用 latest read model + immutable revisions。
  4. Work Product 记录 provider/ref/status/health,并关联生成它的 run/workspace。
  5. Workspace file resolver 只允许注册 workspace root 内的相对路径。
  6. 交付物上传应在最终状态前完成,失败要可见。
  7. provenance/trust 随内容传播,不能复制时丢失。

源码入口

  • packages/db/src/schema/documents.ts、document_revisions.ts
  • packages/db/src/schema/assets.ts、issue_attachments.ts
  • packages/db/src/schema/issue_work_products.ts
  • server/src/services/documents.ts
  • server/src/services/company-artifacts.ts
  • server/src/services/work-products.ts
  • server/src/services/workspace-file-resources.ts
  • server/src/services/company-artifacts.ts
  • doc/AGENT-ARTIFACTS.md

下一章说明怎样从本地命令启动并部署控制面:19 · CLI、配置与部署形态。