Document the privilege-escalation and silent-overwrite hazards; keep the reject-routing task in_progress pending real UI rerun. Co-authored-by: Cursor <cursoragent@cursor.com>
2.2 KiB
2.2 KiB
title, status, created, updated
| title | status | created | updated |
|---|---|---|---|
| 权威文档职责 + 打开时基线 ETag | in_progress | 2026-09-13 | 2026-09-13 |
权威文档职责 + 打开时基线 ETag
背景
链到 ../audit/2026-09-13-document-revision-duty-etag-overwrite.md。
陌生人/审核人被抬成编制人可改受控正文;保存时重取最新 ETag 会掩盖 409 并覆盖并发编辑。
目标
- 列表 summary 返回台账 author/reviewer/approver 的 id+name;前端保留权威字段,禁止用当前登录用户伪造 author。
currentDocRole按权威 user id 解析;name 仅兼容旧本地文档;未知身份 fail-closed 为viewer;viewer 无编辑/审核/批准动作。- 受控正文 hydrate 同时取 revision-state ETag 写入 AST/缓存;人工 PATCH 只用该基线;成功后用响应
state.etag更新;冲突保留编辑器与文本。无账本 bootstrap/freeform 仍可用0:0。 - UI-13b:A1 保存前两窗口已加载相同 r/etag,且 A2 编辑器已打开并填入文本。
分波次计划
| 波次 | 内容 | 验收 |
|---|---|---|
| Wave 1 | Go summary 投影职责 + 单测 | B 不是 author;A 仍是 author |
| Wave 2 | 前端 merge / UserRole=viewer / resolveCurrentDocRole |
B/陌生人不成 author;viewer 无动作 |
| Wave 3 | hydrate 基线 ETag + PATCH 不再 GET | stale ETag 单测;不能用最新 ETag 掩盖冲突 |
| Wave 4 | UI-13b 真实竞争脚本 | A2 先开编辑器再 A1/A2 保存 |
| Wave 5 | 占槽真实 UI(本轮不做) | UI-13a/13b 实战 PASS 后才可 done |
验收标准
- Go
ListWorkflowDocumentsIncludesAuthoritativeDuties - 前端 merge +
resolveCurrentDocRole单测 - stale hydrate ETag 用于保存(纯函数 + hydrate 单测)
- UI-13b 脚本不降级(本轮不跑真实 E2E)
- 真实 UI 重跑 PASS