Files
Agent-System/.doc/system-design/document-revision-management.md
T
weichenandCursor 7778559201 docs(docrev): freeze version boundary ADR and Wave 0 task
Accept DOCREV decision gates, archive design short-term, and mark
FEATURE-MATRIX partial as implementation starts on feature branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 05:58:49 +00:00

36 KiB
Raw Blame History

title, status, created, updated, owner
title status created updated owner
文档修改、智能体版本与差异认知系统设计 in_progress 2026-09-13 2026-09-13 Codex

文档修改、智能体版本与差异认知系统设计

1. 设计结论

采用“智能体版本(Version)+ 人工修订(Revision)+ 不可变快照(Snapshot)”三层模型:

  • 模板或智能体/智能体小队成功产物开启一个版本;
  • 用户每次服务端保存产生该版本内的修订,不增加版本号;
  • 下次智能体产物提交时封存旧版本当前 head,并以新产物开启下一版本;
  • 右侧正文的人工修改标记始终比较“当前版本 baseline → 当前 head”;
  • 任意版本比较默认使用每个版本的最终 head;
  • 智能体变更说明比较“上一版本最终 head → 新版本 baseline”,与随后人工修改严格分离。

版本、正文、变更报告、影响计算和负责人通知必须在同一数据库事务中提交;智能体工作区 output.md 只作为候选产物和兼容投影,不再是唯一事实源。

2. 目标与非目标

2.1 目标

  1. 逐次记录用户、单智能体、智能体小队、模板和系统迁移的正文修改。
  2. 默认视图只标记相对最新智能体 baseline 的人工修改,并能按修改人筛选。
  3. 支持任意两个业务版本的可信对比,能定位到章节、段落、列表、表格单元格和代码/图表行。
  4. 每次智能体生成同时形成结构化改动摘要、风险、项目影响和其他文档影响。
  5. 生成完成后可靠通知文档负责人,并为受影响文档负责人提供最小必要信息。
  6. 在并发、重试、进程重启和多实例部署下不静默覆盖、不重复建版本、不伪造修改主体。

2.2 非目标

  • 首期不做 Google Docs 式多人实时协同光标或 CRDT;继续使用租约 + 乐观并发。
  • 不记录每次键盘输入;只记录服务端成功提交的 revision。
  • 不让 LLM 决定真实 diff、最终风险级别、权限或上下游依赖。
  • 不允许“恢复旧版本”覆盖历史;未来恢复只能把旧快照复制为新的受控 revision/agent candidate。
  • 不把自由文档塞入 DocGov 的编制/审核/批准状态机。

3. 统一术语和版本语义

术语 定义 是否可变
Snapshot 某一时刻完整、规范化 Markdown 与 block map 的内容快照 不可变
Baseline 当前版本由模板或智能体建立的起点快照 不可变
Head 当前版本最新一次成功提交后的快照指针 随 revision 前进
Revision 一个版本内的服务端成功修改事件,主要承载人工保存 事件不可变
Version 从一次模板/智能体 baseline 到下一次智能体提交前最终 head 的业务周期 开放时 head 可前进,封存后不可变
Agent candidate 智能体已生成但尚未获准/尚未通过门禁的候选快照 不成为正文 head
Change report 绑定确定 before/after 快照的智能体变更说明 发布后不可变,可追加更正报告
Review snapshot 提交审核时冻结的精确 head 不可变指针,不额外增加 Version

3.1 示例时间线

时点 动作 当前显示 baseline head 人工标记
T0 项目激活并复制模板 V1 · r0 S0 template S0 0
T1 张工修改两处并保存 V1 · r1 S0 S1 S0→S1 的两处
T2 李工获授权后再修改一处 V1 · r2 S0 S2 S0→S2 的累计人工修改,可按人筛选
T3 智能体小队基于 S2 生成 S3 并提交 V2 · r0 S3 squad S3 0;V1 以 S2 封存
T4 张工修改 S3 V2 · r1 S3 S4 只显示 S3→S4,不再显示 S0→S2
T5 比较 V1 与 V2 V1.final=S2 → V2.head=S4 — — 展示版本最终内容差异

这正是核心规则:

V1 = 模板/上一次智能体 baseline S0 + T1/T2 的人工修订,最终封存为 S2
V2 = 下一次智能体 baseline S3 + T4 之后的人工修订,当前 head 为 S4

3.2 不产生版本的情况

  • 智能体输出与输入 SHA 相同:记录 agent_noop 事件和报告,不增加 Version。
  • 智能体失败、超时、报告校验失败:保存候选/失败证据,不改变 Version 或 head。
  • 只增加批注、查看、认领、租约心跳:进入既有审计,不是正文 Revision。
  • 标题、可见性等元数据变化:进入 metadata audit;除非正文也改变,否则不进入正文 diff。

4. 领域状态机

版本状态与文档生命周期是正交的两套状态,不得混入同一状态机(这正是 gap analysis §5.2 指出的根因之一):

stateDiagram-v2
    direction TB
    state "版本状态 document_versions.status(仅 open/sealed)" as VS {
        [*] --> open: template/agent baseline 建立新版本行
        open --> open: 人工 revision 提交(head 前进)
        open --> sealed: 智能体提交,同事务原子封存
        sealed --> [*]: 只读历史;恢复=复制为新受控修订
    }
    state "文档生命周期 document_records.current_state" as DS {
        [*] --> drafting
        drafting --> reviewing: submit_review(冻结 review snapshot)
        reviewing --> drafting: 驳回回编制
        reviewing --> approving
        approving --> approved: 批准(终点)
    }

状态约束:

  1. 一个文档至多一个 open Version、一个 current head;sealed 行永久只读。
  2. 版本状态只有 open/sealed;reviewing/approving/approved 属于 document_records 生命周期,不改变版本状态——送审时版本保持 open,仅冻结 review_snapshot_id(CHECK 约束与状态机必须一致,迁移中校验)。
  3. “封存→新版本”是插入新行(旧版行置 sealed、新版行置 open),不是同一行状态回转;两者必须在同一事务内完成。
  4. agent candidate 必须记录 input_snapshot_id,提交时 current head 仍须等于该输入;否则标记 stale,禁止自动重放或覆盖。
  5. reviewing/approving/approved 状态禁止正文 revision 和 agent commit;驳回回 drafting 后可在当前 Version 继续人工修订;下一次智能体提交仍是唯一的新 Version 边界。
  6. submit_review 保存 review_snapshot_id=head_snapshot_id;审核、批准和导出都引用该快照。

5. 总体架构

右侧 Block Editor / Agent Task Run
              │ expected head + idempotency key
              ▼
DocumentRevisionService ── DocumentPolicyAdapter
              │             ├─ controlled: DocGov + stage duty
              │             └─ freeform: owner/share policy
              ├─ SnapshotStore (PostgreSQL immutable content)
              ├─ DiffEngine (server-authoritative)
              ├─ ImpactEngine (workflow + lineage)
              ├─ RiskPolicy (deterministic floor)
              └─ ChangeReportValidator
                              │ same transaction
                              ▼
    version + event + report + lineage/stale + outbox
                              │
                              ▼
             notification fanout / SSE cache invalidation

5.1 写模型与读模型

  • document_records / freeform_documents 继续是各自治理根;
  • 新的 revision ledger 是共享基础设施,不共享两类文档的权限和生命周期;
  • PostgreSQL 内的规范化 Markdown snapshot 是内容真源;
  • 工作区 output.md、Block AST、DOCX/XLSX 都是从 snapshot 派生的投影;
  • 旧 API 在兼容期从 current head 读写,但内部必须委托 DocumentRevisionService,禁止双写两套权威。

6. 数据模型

迁移号在实施时取 Goose 最新可用号;按当前基线下一号是 00028,不得在并行合并后硬占用旧号。

6.1 document_content_blobs

字段 类型/约束 说明
content_sha256 CHAR(64) PK 规范化 Markdown 内容寻址
content_markdown TEXT NOT NULL 首期直接存 PostgreSQL,事务一致
byte_size BIGINT CHECK >= 0 限额与性能判断
created_at TIMESTAMPTZ 首次出现时间

相同正文只存一次。未来迁移对象存储时保留 hash,新增 storage_key;在完成校验前不删除 DB 内容。

6.2 document_snapshots

字段 类型/约束 说明
id BIGSERIAL PK 快照标识
doc_id TEXT NOT NULL 全局业务文档 ID
content_sha256 FK content blobs 完整正文
parent_snapshot_id FK self nullable 直接父快照
block_map JSONB NOT NULL 稳定 block id、类型、字符范围、heading path、业务键
source_kind CHECK template/human/agent/agent_squad/migration/system
actor_user_id FK nullable 人工主体,仅来自服务端 session
actor_ref TEXT agent key / squad run id / template version
actor_snapshot JSONB 当时名称、角色、agent/squad 配置版本,不随配置漂移
source_run_id TEXT nullable 绑定 task run
created_at TIMESTAMPTZ 创建时间

正文和 block_map 不允许 UPDATE/DELETE。相同内容的 no-op 不建新 snapshot。

6.3 document_versions

字段 类型/约束 说明
id BIGSERIAL PK 内部版本 ID
doc_id TEXT NOT NULL 文档
version_no INT NOT NULL 用户看到的 V1/V2...
status CHECK open/sealed
origin_kind CHECK template/agent/agent_squad/migration
baseline_snapshot_id FK snapshot 人工高亮基准
head_snapshot_id FK snapshot 当前/封存最终正文
human_revision_count INT 快速展示
source_run_id TEXT nullable 创建本版本的 run
change_report_id FK nullable 上一最终 head → 本 baseline 报告
opened_at/sealed_at TIMESTAMPTZ 周期边界

关键约束:

  • UNIQUE(doc_id, version_no);
  • partial unique:每个 doc_id 只有一个 status='open';
  • baseline/head snapshot 必须属于同一 doc;
  • sealed 后 head_snapshot_id 不可变。

6.4 document_change_events

字段 说明
id/doc_id/version_id/event_no 单文档严格递增事件序列
from_snapshot_id/to_snapshot_id 可复算 diff 的精确前后状态
change_kind human_revision/agent_commit/agent_noop/import/restore_as_new
actor_kind human/agent/agent_squad/template/migration/system
actor_user_id/actor_ref/actor_snapshot 人员或执行单元归属
change_set 服务端计算的结构化 hunk 摘要;不是内容真源
edit_session_id UI 聚合连续自动保存
request_id/idempotency_key 重试幂等与追踪
created_at 服务端时间

UNIQUE(doc_id, idempotency_key) 防止网络重试重复生成 revision。UI 可把同一用户同一 edit_session_id 的连续事件折叠成一组,但审计事件不合并、不删除。

6.5 document_agent_candidates

字段 说明
id/doc_id/input_snapshot_id/output_snapshot_id 候选前后正文
run_id/proposal_id 绑定真实任务和既有授权提案
status ready/needs_confirmation/committed/rejected/stale/quality_failed
authorized_scope 编制人批准的修改范围
quality_result 质量门禁结果
change_report_id 实际 before/after 的说明
created_at/decided_at 时间

候选不改变 document_records、Version 或 head。候选被拒绝也永久保留元数据和 hash;正文保留期按安全策略执行。

6.6 document_change_reports

字段 说明
from_snapshot_id/to_snapshot_id 报告唯一事实范围
schema_version 首期 1
summary 3–8 条快速摘要
risk_level/risk_items low/medium/high/critical + 结构化原因
project_impacts/document_impacts 项目、阶段、任务、其他文档影响
open_questions 需负责人判断事项
analysis_status complete/fallback/unassessed/corrected
model_snapshot/prompt_version 模型与提示词可审计来源
deterministic_facts diff 统计、规则风险下限、血缘影响集合

原报告不可覆盖;纠错创建新报告并用 corrects_report_id 关联。

6.7 根表指针

document_records 和 freeform_documents 增加统一命名的 ledger 指针列:

  • ledger_version_id(FK → document_versions.id,NULL=尚未导入);
  • head_snapshot_id(FK → document_snapshots.id);
  • head_revision_no;
  • review_snapshot_id(仅 controlled);
  • revision_schema_version;
  • row_revision(乐观并发)。

命名冲突与旧列退役(实施红线):

  • freeform_documents.current_version_id 已在迁移 00008_2026-09-11-freeform-documents.sql 中存在,语义是“每次保存 +1 的 legacy 版本号”,不得同名复用承载新语义;新指针列一律用 ledger_*/head_* 命名,旧列迁移时改名为 legacy_version_id(或保留原名并降级为只读投影);
  • document_records.version/content_sha256/work_dir 与 freeform_documents.current_sha256 在兼容期由同一事务投影为旧值,稳定后只读并最终退役;
  • 自由文档 legacy freeform_document_versions.version_no 与新 document_versions.version_no 是不同表的独立编号;新 Version 起点规则在 DR-06 契约冻结时确认(推荐从 legacy 最大 version_no+1 起算,UI 对 legacy checkpoint 加前缀区分)。

7. 修改主体归属

7.1 人工修改

  • actor_kind=human;actor_user_id 只取认证 principal;
  • actor_snapshot 保存当时显示名、项目角色和文档 duty;
  • 客户端提交的 user_id/user_name/user_role 一律忽略并逐步移除;
  • 同一 hunk 被多人先后覆盖时,当前视图标注最后修改人,历史面板仍保留完整事件链。

7.2 单智能体修改

  • actor_kind=agent,保存 agent key、配置版本、模型、tool policy、on-behalf-of 用户和 run id;
  • 若任务由人发起,触发者不是内容作者;界面分别显示“发起人”和“执行智能体”。

7.3 智能体小队修改

  • 文档基线整体归属 actor_kind=agent_squad 与唯一 run_id;
  • actor_snapshot 固化 squad name/version、参与 agent role/name/model 和 StepManifest hash;
  • 只有执行链能证明某 agent 直接产出某 block 时,hunk 才显示该 agent contributor;否则显示“小队共同产出”,禁止根据最终文案猜测个人贡献。

8. 写入流程

8.1 人工保存

  1. API 根据 doc id 加载资源上下文并执行项目、阶段、文档 duty、状态权限判定。
  2. 校验 human lease token、expected_head_snapshot_id、expected_revision_no 和 idempotency key。
  3. 服务端规范化 Markdown、校验大小和危险内容,计算 SHA。
  4. SELECT ... FOR UPDATE 锁定文档根;再次检查 head,冲突则返回 409 和三方比较所需指针,绝不自动覆盖。
  5. 写 content blob、snapshot、change event;更新 open Version head 和根表 current pointer。
  6. 同事务写审计与必要的 cache invalidation outbox;提交后再更新工作区投影。
  7. 返回新 head、revision、人工累计修改统计和增量 decorations。

推荐自动保存每 5–10 秒或失焦触发;同一编辑会话在 UI 时间线折叠显示,服务端仍逐次留痕。

8.2 智能体/小队生成

  1. L2 解析文档、阶段、任务实例和 actor;按既有认领/提案规则取得修改授权。
  2. 短事务捕获 current input_snapshot_id,获取服务端签发的 squad lease;任务只能读取该不可变输入。
  3. L3 同时生成 output.md 和 change_report.json;输出落在 candidate workspace。
  4. 服务端规范化输出并计算真实 diff;ImpactEngine 读取 workflow snapshot 与 document lineage;RiskPolicy 给出不可被模型降低的风险下限。
  5. 校验 change report schema、内容范围、引用 doc 可见性和 authorized scope。失败可重试报告生成,不重复生成正文。
  6. 若需要二次确认,创建 candidate_ready 通知并释放租约;正文 head 不变。
  7. 提交时锁根记录并验证 head == input_snapshot、生命周期仍 drafting、授权/提案仍有效。
  8. 同一事务:封存旧 Version head → 新建 Version 与 agent baseline → 写 event/report/lineage stale/outbox → 更新 current pointers → 标记 candidate committed。
  9. 提交后异步投影 output.md、刷新右侧读模型并通知负责人。

8.3 与既有变更提案衔接

  • 既有 document_change_proposals 继续表达“是否允许智能体动这份已认领文档”;
  • 新 candidate/report 表达“智能体实际改出了什么”;二者不能合并成一条自由文本;
  • 未认领模板可按策略自动提交;已认领或由非编制人触发时必须先有有效 proposal;
  • 实际 diff 超出授权范围、规则风险达到 high/critical、或影响已批准下游文档时,再次要求编制负责人确认实际 diff;
  • 任何确认都绑定 candidate id + input/output SHA,不能批准一个会漂移的“最新内容”。

8.4 失败与并发

场景 行为
人工保存 head 冲突 409 DOCUMENT_HEAD_CONFLICT,返回 base/current 指针,显示三方 diff,不自动重试
Agent 运行期间输入已变化 candidate=stale,不提交;负责人选择重新生成
Agent 正文成功、报告失败 正文留 candidate;重试报告。最终降级时标 unassessed/high,受控文档不得直接送审
Outbox 写失败 整个版本事务回滚,不出现“版本成功但负责人未进入通知队列”
通知投递失败 outbox 重试,不回滚已经提交的版本;站内通知具有最终一致性
工作区投影失败 DB head 仍权威,标 projection lag 并重建,读取不回退旧文件
相同 run 重试 finalize 由 (doc_id, run_id, output_sha) 幂等,只能提交一个 Version

9. Diff 引擎与稳定块定位

9.1 服务端权威

真实增删改必须由服务端根据两个 immutable snapshot 计算;change_report.json 的描述不能替代 diff。Diff 结果按两种用途输出:

  • manual_overlay:current baseline → current head,仅保留 human events;
  • version_compare:任意 A.final/head → B.final/head,包含所有主体,并按 event 归属着色。

9.2 block map

当前随机 blk_* 不能跨刷新使用。新流程为每个 snapshot 保存 block map:

  1. 首次解析按类型、heading path、结构位置、业务键(如 REQ-ID/表格主键)生成 node;
  2. 人工编辑携带当前 stable block id;服务端验证后继承;
  3. 智能体 Markdown 重新解析时,用“业务键精确匹配 → heading path/type → 内容指纹相似度 → 邻近顺序”对齐旧节点;
  4. 无法可靠匹配的节点分配新 UUID,并标记 insert/delete,不伪造延续关系。

9.3 粒度

内容 比较粒度 展示
标题/段落 Unicode grapheme + 中英文词组 字词增删、整段移动
列表 item,再到 item 内字词 新增/删除/改写条目
表格 row key/位置 → cell → cell 内字词 单元格角标、整行增删
Mermaid/代码/公式 行级,必要时 token 级 行号和语法安全转义
块移动 stable id + 顺序 “从 2.1 移至 3.2”,不误判为删后新增

算法以 Myers/patience line diff 为基础,中文正文再做 grapheme/词组 diff;输出 JSON hunks,不输出未清洗 HTML。前端只用 React 节点渲染,不用不可信 dangerouslySetInnerHTML。

9.4 版本选择规则

  • final:sealed Version 取封存 head,open Version 取当前 head;默认。
  • baseline:用于查看某次智能体刚生成时的原始内容。
  • revision:高级历史中可选择某一人工保存点。

因此“比较 V1 和 V3”不会因为 V1 曾有多个自动保存而含糊;默认就是 V1.final 对 V3.final/head。

10. 智能体变更报告

10.1 产物契约

每次生成要求 L3 输出两个目标:

output.md
change_report.json

change_report.json 建议 schema:

{
  "schema_version": 1,
  "summary": ["补充系统边界条件", "调整三项验收阈值"],
  "changes": [{
    "section_locator": "3.2 性能要求 / REQ-PERF-007",
    "change_type": "modified",
    "rationale": "依据新增用户材料与法规检索证据",
    "evidence_refs": ["material:123#sha256", "kb:GB9706#8.4"]
  }],
  "risk": {
    "level": "high",
    "items": [{"category": "verification", "description": "阈值变化会使既有用例失效", "mitigation": "重跑 TC-007"}]
  },
  "project_impact": {
    "schedule": "可能增加验证工作量",
    "cost": "待评估",
    "scope": "影响性能验证范围",
    "compliance": "需复核风险管理文件"
  },
  "document_impacts": [{
    "doc_id": "doc_proj1_test_manager",
    "impact_type": "stale_candidate",
    "reason": "引用的 REQ-PERF-007 已改变",
    "recommended_action": "由测试方案编制人复核并重新基线"
  }],
  "open_questions": ["阈值是否已获得硬件负责人确认"]
}

禁止在报告中复制大段 before/after 正文;精确内容由 diff API 提供。

10.2 双层校验

层 权威职责
确定性层 SHA、真实 hunk、增删统计、workflow/lineage 影响集合、敏感章节规则、风险最低级别
智能体层 修改理由、可读摘要、业务含义、潜在风险、建议动作和开放问题

最终风险:max(rule_risk, model_risk)。模型遗漏真实变更、引用不存在文档、报告说“未修改”但 SHA 改变,均触发校验失败或 conservative fallback。

10.3 风险规则下限

  • 删除/降低法规、风险控制、验收标准、关键技术参数:至少 high;
  • 改变需求 ID、上游已批准输入、成本/报价、阶段 gate:至少 high;
  • 仅格式、错别字且无结构/数值变化:low;
  • 影响已批准下游文档、跨阶段范围或职责:critical/high,按政策要求确认;
  • 无法评估:unassessed,UI 按 high 呈现,不能显示绿色安全结论。

11. 通知设计

11.1 事件类型

  • document.agent_candidate_ready:实际 diff 已生成,等待负责人确认;
  • document.agent_version_committed:新智能体 Version 已生效;
  • document.human_revision_conflict:本人编辑发生并发冲突;
  • document.downstream_impact_detected:其他文档因上游变化需复核;
  • document.change_report_degraded:报告未完整评估,阻断送审。

11.2 收件人矩阵

场景 必须通知 条件通知
Agent candidate 就绪 当前文档编制负责人 发起人(若不同)
Agent Version 生效 当前文档编制负责人 发起人;high/critical 时项目创建人
影响下游文档 每份受影响文档的编制负责人 当前 reviewer/approver、项目创建人
报告降级 当前文档编制负责人 QA/项目监督角色(若配置)

受影响人只能看到自己有权访问的文档名称和摘要;无权资源只返回“另有 N 份受限文档受影响”,防止侧信道泄露。

11.3 通知内容

通知卡片包含:文档名、Vn-1→Vn、执行主体/发起人、3 条摘要、风险徽章、项目影响一句话、受影响文档数量、查看修改 和 查看完整分析。不把正文片段、Prompt 或私密材料写入 notification body。

去重键:doc_agent_version:{doc_id}:{version_no}:{recipient_id};candidate 使用 candidate id。版本与通知先同事务写入 outbox,worker 幂等 fanout。用户当前正打开文档时可以抑制 toast,但站内通知记录仍必须创建。

12. API 契约

所有端点先通过统一 DocumentAccessDecider,path 中 project/doc/version/snapshot 归属必须一致。

GET  /api/v1/documents/{doc_id}/revision-state
     -> current version/baseline/head/revision/manual change count/capabilities

GET  /api/v1/documents/{doc_id}/versions?cursor=&limit=
     -> version timeline; no full content

GET  /api/v1/documents/{doc_id}/versions/{version_no}?view=final|baseline
     -> immutable snapshot content + ETag

GET  /api/v1/documents/{doc_id}/diff
     ?from_version=1&to_version=3&from_view=final&to_view=final&mode=structured
     -> summary, hunks, actor attribution, report refs

GET  /api/v1/documents/{doc_id}/manual-overlay
     ?version=current&actor=all|me
     -> baseline→head decorations

PATCH /api/v1/documents/{doc_id}/content
     If-Match: "<head_snapshot_id>:<revision_no>"
     Idempotency-Key: <uuid>
     body: { markdown, edit_session_id, client_block_map_version }

GET  /api/v1/documents/{doc_id}/agent-candidates/{candidate_id}
POST /api/v1/documents/{doc_id}/agent-candidates/{candidate_id}/decision
     body: { decision, expected_input_sha, expected_output_sha, reason }

GET  /api/v1/documents/{doc_id}/change-reports/{report_id}
PATCH /api/v1/notifications/{id}
     body: { status: read|acted|dismissed }

内部服务接口(不暴露为普通用户 HTTP):

CommitHumanRevision(ctx, principal, docRef, expectedHead, markdown, idempotencyKey)
CreateAgentCandidate(ctx, servicePrincipal, onBehalfOf, runID, inputSnapshot, output, report)
CommitAgentVersion(ctx, servicePrincipal, candidateID, decisionToken)

12.1 主要错误码

HTTP code UI 行为
403 DOCUMENT_EDIT_FORBIDDEN 只读并解释职责/阶段
409 DOCUMENT_HEAD_CONFLICT 打开三方差异,不自动覆盖
409 DOCUMENT_BUSY 显示 holder 类型和可重试时间
409 AGENT_CANDIDATE_STALE 提示重新生成,不允许直接应用
422 CHANGE_REPORT_INVALID 候选保留,显示分析待补全
423 DOCUMENT_LIFECYCLE_LOCKED 跳转审核/变更流程
413 DOCUMENT_TOO_LARGE 分块或附件化建议

13. 右侧栏交互设计

13.1 默认阅读态

┌ 文档 Tab ───────────────────────────────────────────┐
│ V3 · 当前  r4   [7 处人工修改]  [版本历史] [比较]  │
│ 基准:智能体小队 · 10:42     风险:中   影响 2 文档 │
├─────────────────────────────────────────────────────┤
│ ▌ 3.2 性能要求                         张工 · 11:03 │
│   温控范围为 38–45℃,精度由 ±1℃ 改为 ±0.5℃         │
│                  ~~~~~~~~~~~~~  (浅琥珀底 + 实线下划线)│
│                                                     │
│ ◀ 删除 1 处  在锚点处显示小型删除标记,悬浮看原文   │
├─────────────────────────────────────────────────────┤
│ [纯净阅读] [人工修改] [全部变更]   [仅我] [所有人]  │
└─────────────────────────────────────────────────────┘

默认开启“人工修改”,只展示 current baseline→head:

  • 左侧 3px gutter 标记整块受影响;
  • 字词新增用浅琥珀背景 + 下划线,修改同时显示原/新值的 popover;
  • 删除不把大段旧文塞回正文,在原锚点显示删除标记,点击查看;
  • 右上角显示修改人、时间和 revision;多人修改显示头像堆叠;
  • 颜色之外同时使用线型、图标和文字,满足色觉无障碍;深色/浅色主题分别校验对比度;
  • “纯净阅读”一键关闭所有 decoration,导出默认纯净正文;审计版导出可附变更表。

13.2 版本历史抽屉

版本卡片展示:

  • V3 当前 / V2 已封存;
  • baseline 来源(模板、单智能体、智能体小队)和 actor snapshot;
  • 开始/封存时间、人工 revision 数/人数;
  • 最终 SHA 短码、生命周期 checkpoint;
  • 智能体摘要、风险徽章、影响数量;
  • 选择为 A / 选择为 B / 查看生成时原稿。

人工自动保存默认折叠在版本卡片内,展开才显示 r1...rN,避免版本噪声。

13.3 两版本比较

  • 宽屏默认左右双栏:A 在左、B 在右,同步滚动和章节对齐;
  • 窄屏/右栏宽度不足时使用 unified diff;
  • 顶栏允许交换 A/B、只看改动、按主体筛选、跳到上一/下一处;
  • 摘要区固定展示“新增/删除/修改/移动块数、人工/Agent 占比、风险、影响文档”;
  • 点击任一 hunk 可打开来源事件、修改主体、run、提案、报告和审计记录;
  • 比较视图只读,不允许在历史版本上直接编辑。

13.4 智能体完成卡

生成完成后,中间对话与右侧栏显示同一 report id 的摘要卡:

V2 已由「产品经理智能体小队」生成
改动 12 处 · 风险 高 · 影响 3 份文档
摘要:补齐需求边界;调整 3 项验收阈值;新增 2 个开放问题
[查看逐项修改] [风险与影响] [若需:确认应用]

卡片不能只靠 SSE 临时状态;刷新后从 version/report/notification 读模型恢复。

14. 权限和安全

动作 Controlled Freeform
查看版本/正文/diff active 项目成员 + 阶段可见 + 文档可见 owner;shared 时需 active 项目成员
人工编辑 指定 author + drafting + human lease owner(首期)
Agent 候选 service identity + on-behalf-of 用户有触发权限 + active task instance service identity + owner 明确触发
提交 Agent Version 服务端 task finalizer;必要时绑定 author 决策 owner 授权策略
查看完整影响 对每个受影响资源逐一授权 同左
历史恢复 后续受控动作,永不 UPDATE 历史 owner 新建 revision

安全要求:

  • holder id、actor kind、agent id、run id、project/stage/workdir 不信任客户端;
  • snapshot/diff/report API 必须复用列表、正文、导出、RAG 和 Agent tool read 的同一授权决策;
  • 日志、通知和 metrics 不记录正文、diff 片段或 Prompt;
  • 防止通过版本数量、影响文档名和 actor 名称泄露无权资源;
  • DB 层限制 immutable 表 UPDATE/DELETE,审计修正只追加;
  • 规范化 Markdown 后再计算 SHA,避免换行/Unicode 形式导致伪差异;
  • 所有渲染继续执行 Markdown/Mermaid/XSS 安全策略。

15. 一致性、性能与保留

15.1 事务边界

Agent commit 的最小原子集合:

seal old version
+ create new baseline snapshot/version
+ change event/report
+ update document head/version/hash
+ lineage/stale changes
+ outbox event

任务终态只有在该事务成功后才可从 finalizing 进入 completed。这补上当前“先写工作区,再分别更新文档和消息”的分裂窗口。

15.2 性能

  • 列表/时间线不返回正文;正文和 diff 分页/按章节懒加载;
  • diff cache key=algorithm_version:from_sha:to_sha:mode,内容更新天然失效;
  • 大于阈值的文档异步计算 diff,API 返回 job id,前端显示可恢复进度;
  • content blob 按 SHA 去重,snapshot 只存引用和 block map;
  • 对极大表格采用 windowed rows,禁止一次渲染全部 cell diff;
  • 下载/导出使用选定 snapshot,不从浏览器当前 DOM 拼装。

建议首期限制:Markdown 10 MiB、单次 change report 256 KiB、diff hunks 10,000;超限进入分章节比较,不截断审计正文。

15.3 保留策略

  • 受控文档:随项目、质量体系和法规适用策略保留;默认不自动硬删版本、事件和报告;
  • 自由文档:默认 365 天可配置,删除文档先进入回收站,历史清理由后台策略和审计事件驱动;
  • agent candidate:未提交正文可按较短策略清理,但保留 hash、run、决策和报告元数据;
  • 法规适用性、电子签名和法定年限需由组织另行确认,本设计不宣称自动满足特定法规。

16. 迁移与兼容

16.1 历史受控文档

  1. 对每条 document_records 解析服务端规范 workdir,读取当前 output.md;
  2. 文件 SHA 与 DB SHA 一致才导入 snapshot;不一致进入 quarantine report,禁止静默选择一方;
  3. 建立 V1 r0 origin=migration,baseline=head=当前 snapshot;历史人工修改无法可靠推断,因此不伪造高亮;
  4. is_template_only=true 的文档优先从激活时冻结的 template version 创建 template snapshot;若历史没有冻结模板,标 baseline_unavailable;
  5. 回填报告记录成功、缺文件、hash mismatch、无模板四类数量,并支持 dry-run。

16.2 自由文档

现有 freeform_document_versions 每次保存均是不可变内容,可无损导入 snapshot/change event。为避免改写用户历史:

  • 旧每-save版本在 UI 标记为 legacy checkpoint;
  • 切换新模型时以当前版本建立一个 origin=migration 的开放 Version;
  • 后续人工保存变为 revision,下一次智能体生成才增加业务 Version;
  • 首期可先完成底层导入和 API,第二波再切换自由文档 UI 语义。

16.3 模板

项目激活时必须把冻结的 workflow template version 内容复制/引用为文档 V1 baseline,不能继续仅在浏览器用 templateFactory 临时生成。这样模板与后续人工修改才可比较、可审计。

17. 可观测性

指标:

  • document_revision_commit_total{actor_kind,result};
  • document_head_conflict_total{mode};
  • agent_candidate_total{status,risk};
  • change_report_validation_total{result};
  • document_diff_duration_seconds{size_bucket,mode};
  • document_notification_lag_seconds{event_type};
  • workspace_projection_lag_total。

结构化日志只写 doc/project/run/request/version/revision/hash 短码,不写正文。告警关注:版本事务失败、candidate stale 激增、报告 fallback 比例、通知积压和投影不一致。

18. 验收场景

ID 场景 预期
AC-01 模板后用户保存 3 次 仍为 V1,r3;三事件可审计;overlay=template→head
AC-02 squad 基于 V1 r3 生成 V1 封存于 r3,V2 r0;人工 overlay 清零
AC-03 V2 再人工修改 只显示 V2 baseline→V2 head,不重复显示 V1 人工修改
AC-04 比较 V1 与 V2 默认 V1.final→V2.final/head,可切换 V2 baseline
AC-05 单 agent 与 squad 各生成一次 时间线正确显示主体;squad 参与成员快照可查看
AC-06 两用户并发保存 只成功一个;另一方 409 + 三方 diff;无自动覆盖
AC-07 agent 输入后用户抢先改变 head candidate stale,不建新 Version
AC-08 生成报告漏报真实删除 validator 拒绝/降级;规则风险不可被降低
AC-09 新 Version 影响下游 lineage/stale 与 outbox 同事务;对应负责人收到授权内通知
AC-10 刷新、重登、服务重启 版本、overlay、报告、通知完全恢复,不依赖内存/SSE
AC-11 非成员猜 doc/version/snapshot id 统一 403/404 策略,无内容/元数据侧信道
AC-12 已批准文档直接修改 423;历史、head、通知均不变
AC-13 同一 run finalize 重试 只产生一个 Version/报告/通知
AC-14 历史 hash mismatch 回填 进入隔离报告,不伪造 baseline
AC-15 DOCX/Markdown 导出历史版本 内容和所选 snapshot SHA 一致,默认无 UI 高亮污染

19. 评审决策点

建议本轮审核确认以下三项,其他细节可在实施中按本设计收敛:

  1. 版本语义:采用推荐的“智能体/模板开启 Version,人工保存只增加 Revision”。
  2. 高风险应用:high/critical 智能体实际 diff 必须由编制负责人二次确认;低/中风险按既有提案授权自动提交。
  3. 上线范围:Wave 1 先覆盖受控工作流文档;自由文档完成底层兼容后在后续 Wave 切换 UI,避免一次性重写两个治理域。

20. 关联文档