From 5466f2cddb4b4a5bc9b9d0371ad692d01fc924f1 Mon Sep 17 00:00:00 2001 From: weichen Date: Fri, 16 Oct 2026 06:03:17 +0000 Subject: [PATCH] Document visualization cockpit design --- .task/feature-document-visualization-plan.md | 54 ++--- ...26-10-16-document-visualization-rollout.md | 112 ++++++++++ ...026-10-16-document-visualization-design.md | 162 ++++++++++++++ ...ument-visualization-read-model-contract.md | 210 ++++++++++++++++++ ...-10-16-document-visualization-view-spec.md | 137 ++++++++++++ 5 files changed, 649 insertions(+), 26 deletions(-) create mode 100644 docs/superpowers/plans/2026-10-16-document-visualization-rollout.md create mode 100644 docs/superpowers/specs/2026-10-16-document-visualization-design.md create mode 100644 docs/superpowers/specs/2026-10-16-document-visualization-read-model-contract.md create mode 100644 docs/superpowers/specs/2026-10-16-document-visualization-view-spec.md diff --git a/.task/feature-document-visualization-plan.md b/.task/feature-document-visualization-plan.md index 79464216..ed4c5e02 100644 --- a/.task/feature-document-visualization-plan.md +++ b/.task/feature-document-visualization-plan.md @@ -7,17 +7,19 @@ - 权威仓:ssh://git@git-ssh.u1680832.nyat.app:31411/weichen/Agent-System-Dev.git;目标分支:main;R0(initial_base_sha)= 9edb011e63ab9bf104360379e52c30075bd2f344 - 工作区:/home/weichen/projects/Agent-System-Dev-wt-feature-document-visualization-plan(worktree);分支:feature/document-visualization-plan -- 授权与交付终点:<本次允许的动作与终点;未授权事项写明> +- 授权与交付终点:形成并交付文档可视化展示的详细设计系列;允许只读源审计、写入 `docs/superpowers/specs/**`、`docs/superpowers/plans/**` 和本任务卡;不实施业务代码、数据迁移、部署、运行验收或生产环境修改。 - 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进) - 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md) - 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入) - 人工决策点:仅限目标/范围/验收变更、重大取舍、高后果操作或无法自动判定的业务验收 -- 当前阶段:需求拆解;当前增量:I1(待定义) +- 当前阶段:方案设计;当前增量:D1(四份设计文档,待用户评审) - 流程依据:仓库根目录 policy/delivery.md(归档后仍按仓库根目录定位) ## 目标与非目标 -<预期结果、受影响入口/模块/契约;明确不做什么。> +- 目标:补齐此前缺失的文档可视化设计,覆盖项目驾驶舱、结构全景、文档阅读器、聚合读取模型、来源/冲突/影响展示、权限、一致性和实施验收路径。 +- 产物:总设计规格、读取模型与接口契约、双视图交互规格、分阶段实施与验收计划。 +- 非目标:不修改业务代码、组件 gitlink、数据库、部署、模型路由、文档生成/审批流程或运行环境;所有实现与业务验收保持 `NOT_RUN`。 ## Agent 实施收据 @@ -25,34 +27,34 @@ | 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 | |---|---|---|---|---|---|---|---|---|---|---| -| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — | +| D1 设计文档系列 | `docs/superpowers/specs/2026-10-16-document-visualization-*.md`, `docs/superpowers/plans/2026-10-16-document-visualization-rollout.md` | design | Codex 主模型 | 不适用(主模型规划/设计) | 1 | Codex | 完成(待用户评审) | 本地工作区 | 不适用 | — | ## 关联方向与规划 -- 适用状态:待核对(无适用规划时说明原因) -- 主记录路径/版本:待核对(路径按仓库根目录定位,归档后不变;只引用唯一正文) -- 对应里程碑:待核对 +- 适用状态:已有 RDM 两树一网追溯审计方案、既有三栏工作台和 UI 设计令牌;本次仅补齐其缺失的文档可视化展示设计。 +- 主记录路径/版本:`modules/documents/docs/proposals/2026-10-11-rdm-two-trees-trace-audit-integration.md`(当前 Dev 组合指针;实现前需重新核对) +- 对应里程碑:待用户评审后拆分 I1 聚合读取、I2 全景、I3 阅读器、I4 组合验收 ## 需求分析 | ID | 描述 | 项目符合度及依据 | 优先级 | 验收条件 | 依赖 | 结论 | |---|---|---|---|---|---|---| -| R1 | 待填写 | 待评估 | 待定 | 待定义 | 待确认 | 待评审 | +| DV-R01–DV-R08 | 见 `docs/superpowers/specs/2026-10-16-document-visualization-design.md` §11 | 复用 RDM 两树一网、三栏工作台和 UI 令牌;实现前需核对当前组件源码 | P0/P1 | 见总规格、契约和交互规格对应验收条款 | RDM 读服务、项目授权、Frontend/UI 当前 pin | 待用户评审 | ## 方案与计划 -- 方案引用:待填写(含对象版本) -- 实施计划引用:待填写(含增量与需求 ID) -- 测试计划引用:待填写(含需求 ID 与验收条件) +- 方案引用:`docs/superpowers/specs/2026-10-16-document-visualization-design.md`、`...-read-model-contract.md`、`...-view-spec.md` +- 实施计划引用:`docs/superpowers/plans/2026-10-16-document-visualization-rollout.md`(I1–I4,待用户评审) +- 测试计划引用:实施计划 §4–§5;当前所有业务/浏览器/CI 验证 `NOT_RUN` ## 阶段记录 | 阶段 | 对象版本 | 状态 | 决策/执行者 | 时间 | 依据 | |---|---|---|---|---|---| -| 需求拆解 | 待定 | 待执行 | — | — | — | -| 需求评估 | 待定 | 待执行 | — | — | — | -| 需求表确认 | 待定 | 待执行 | — | — | — | -| 方案设计 | 待定 | 待执行 | — | — | — | +| 需求拆解 | `9edb011e63` | 完成(SELF) | Codex 主模型 | 2026-10-16 | 用户提示与现有 RDM/Workbench 源审计 | +| 需求评估 | `9edb011e63` | 完成(SELF) | Codex 主模型 | 2026-10-16 | 现有四入口能力与可视化缺口核对 | +| 需求表确认 | `9edb011e63` | 完成(SELF) | Codex 主模型 | 2026-10-16 | DV-R01–DV-R08 与范围/非目标冻结 | +| 方案设计 | 工作区未提交候选 | 完成(待用户评审) | Codex 主模型 | 2026-10-16 | 四份设计/计划文档;git diff --check 通过 | | 实施计划 | 待定 | 待执行 | — | — | — | | 实施与自检 | 待定 | 待执行 | — | — | — | | 正式测试与验收 | 待定 | 待执行 | — | — | — | @@ -64,7 +66,7 @@ | 增量/试验 | 假设 | 范围 | 判断和停止条件 | 授权/决策依据 | 结果 | 变更影响 | 需重审补测 | |---|---|---|---|---|---|---|---| -| 待定义 | — | — | — | 待核对 | NOT_RUN | 待评估 | 待评估 | +| 本次未做探索试验 | — | — | — | 不适用:本任务只形成方案文档 | NOT_RUN | 无业务试验 | 不适用 | ## 同步记录 @@ -88,19 +90,19 @@ ## 结果与验证(完成后填写) -- 结果: -- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表> -- 影响与剩余项: +- 结果:已形成四份可评审文档;未修改业务代码、组件 pin、数据库或部署。 +- 验证:`git diff --check` PASS(SELF);文档/接口/浏览器/CI/部署/运行验收 NOT_RUN。 +- 影响与剩余项:需用户评审并冻结实施计划 §7 的四个公开契约取舍;批准后另立 I1–I4 实施任务。 ## 规划进展与下一步 -- 本次推进/剩余:待核对(依据实际成果更新适用方案/规划) -- 首选下一任务:待核对(无适用规划、已完成或受阻时如实说明,不虚构任务) -- 推荐依据:待填写 -- 前置条件/待确认:待核对 -- 预期产物/验收条件:待定义 -- 重复任务核对:待核对(已有/在途任务、PR 与规划记录) -- 启动授权:未授权(建议不自动启动新任务,仍须明确授权) +- 本次推进/剩余:补齐文档驾驶舱的结构、读取契约、双视图和实施验收设计;实现与运行验收未启动。 +- 首选下一任务:用户评审四份文档并冻结完成度分母、置信度枚举、冲突范围和首屏摘要暴露边界。 +- 推荐依据:这些取舍会改变 I1 公开 DTO 和首屏用户结果,必须在实现前冻结。 +- 前置条件/待确认:实施计划 §7 四项决策;当前 Dev/RDM/Frontend/UI 组件 pin 在实现前重新核对。 +- 预期产物/验收条件:批准后的 I1–I4 任务卡、聚合读取服务、双视图浏览器验收和精确 HEAD CI。 +- 重复任务核对:既有 RDM 四入口和 Workbench 方案是依赖/复用,不替代本次文档驾驶舱方案;未发现同名在途实现任务。 +- 启动授权:本次仅授权方案文档;业务实施需用户评审后另行确认。 ## 合入与清理 diff --git a/docs/superpowers/plans/2026-10-16-document-visualization-rollout.md b/docs/superpowers/plans/2026-10-16-document-visualization-rollout.md new file mode 100644 index 00000000..c8b95fba --- /dev/null +++ b/docs/superpowers/plans/2026-10-16-document-visualization-rollout.md @@ -0,0 +1,112 @@ +# 文档驾驶舱可视化分阶段实施与验收计划 r1 + +状态:待评审;本计划描述后续执行顺序,不构成业务实施授权。真实实现、迁移、部署、模型数据和浏览器验收均为 `NOT_RUN`。 + +## 1. 目标 + +按四个可独立验证的增量,把既有 RDM 文档树/追溯读取能力提升为项目文档驾驶舱。每个增量都必须保持旧四入口可用,并且不新建写入权威或绕过授权的接口。 + +## 2. 依赖与边界 + +- 依赖既有 RDM 项目绑定、文档树、关系、事件历史和权限合同;先重新核对当前组件 pin 和接口,再实现。 +- 复用 Frontend/UI 的三栏工作台、`@ui` tokens、`Collapsible` 和现有异步状态所有者。 +- 不在本计划内修改模型路由、文档生成/审批、数据库主存储或部署配置。 +- 任何跨仓 gitlink、领域 schema、权限语义或导出行为变化都要单独建立任务和评审记录。 + +## 3. 增量分解 + +### I1:聚合读取服务和 DTO + +**产物**:`CockpitOverview`、`TreePage`、`NodeDetail`、来源/历史/影响/冲突分页接口;适配既有 RDM 读取命令;项目/资源/字段级授权;快照 revision、cursor、截断和错误契约。 + +**直接验证**: + +- 同一节点在不同项目请求下返回 404/拒绝,不泄露存在性。 +- 统计、树、详情和面板使用相同 `snapshotRevision`/`asOfSeq`。 +- 空、部分、受限、过期、上游失败和关系截断都有可判定 DTO。 +- 历史查询不会落在未提交批次中间序号。 + +**停止条件**:若现有领域数据无法提供某字段,返回明确 `unavailable`/`partial`,不得在服务中生成猜测值。 + +### I2:共享选择与全景投影 + +**产物**:项目统计带、文档结构树、全景中央概览、筛选和分页;共享 `selectedNodeRef`、`filterHash`、`snapshotRevision`;过期/刷新提示。 + +**直接验证**: + +- 展开、分页、选择和筛选不会让旧响应覆盖新项目或新筛选。 +- 树徽标和统计来自同一快照;刷新不重置用户选择。 +- 无文档、无权限、部分加载和截断状态可读。 + +**停止条件**:如果真实数据没有段落级结构,使用实际可用层级并标注 structural gap,不伪造段落。 + +### I3:阅读器与右侧依据/影响面板 + +**产物**:连续正文阅读、版本摘要/差异折叠、来源/历史/影响/冲突标签页、全景↔阅读器定位、个人视图偏好。 + +**直接验证**: + +- 从全景选择段落切换阅读器后,正文、面板和 URL/内存状态指向同一 `nodeRef`。 +- 私有来源正文按字段级披露脱敏;受限不显示为空。 +- 乱序事件、断线和后台更新不会抢占滚动位置。 +- 所有折叠、颜色、字号和动效通过设计令牌守护。 + +**停止条件**:不增加第四栏或独立关系图;关系仅在右栏局部展开。 + +### I4:组合验证与浏览器验收 + +**产物**:跨 RDM/Frontend/UI 的组合测试、权限负例、快照一致性测试、Playwright 场景和设计守护证据。 + +**最小场景集**: + +1. 首次进入项目:统计、树、全景可见。 +2. 选中文档→章节→段落:全景与阅读器双向定位。 +3. 来源、历史、影响、冲突展开并正确显示计数/截断。 +4. 未核实来源和冲突状态改变后,所有投影一致。 +5. 过期/断线/部分失败保留旧快照并给出刷新入口。 +6. 未授权项目、节点、来源和下载均失败或脱敏。 +7. 320/390/736/1024/1440 宽度、18px UI 字号、键盘和减少动效。 + +## 4. 测试矩阵 + +| 类别 | 必测内容 | 结果来源 | +|---|---|---| +| DTO/服务 | schema、分页、错误、截断、快照一致性 | 单元/集成测试;最终以 CI 为准 | +| 授权 | 项目越界、成员/职责、字段级来源披露、下载/导出 | 后端负例与独立重放 | +| 状态 | 旧响应、乱序事件、上下文切换、断线、过期快照 | Frontend store 测试 | +| 设计门禁 | 裸色、私有 keyframes、行内字号、`details` 禁止 | UI/Frontend design-guard | +| 浏览器 | 双视图、定位、面板、窄屏和键盘 | Playwright;真实后端链路另记 | +| 组合 | 固定组件 SHA、`make test`、`make build` | Dev 当前 HEAD CI/GATE | + +## 5. 需求到验收映射 + +| 需求 | 计划增量 | 验收 | +|---|---|---| +| DV-R01 | I1/I2 | 项目统计与不可用原因测试 + 首屏浏览器场景 | +| DV-R02 | I1/I2 | 树分页/展开/状态测试 | +| DV-R03 | I2/I3 | 共享选中节点与视图切换场景 | +| DV-R04 | I1/I3 | 四面板分页、计数、截断与定位场景 | +| DV-R05 | I1/I2/I3 | 快照 revision、seq、旧响应丢弃测试 | +| DV-R06 | I1/I3/I4 | 项目/字段/下载授权负例 | +| DV-R07 | I3/I4 | 五宽度、18px、键盘、减少动效浏览器场景 | +| DV-R08 | I1/I2/I3 | 空、部分、过期、失败和截断状态场景 | + +## 6. 交付门禁 + +每个增量在实现前需有独立任务卡、当前基线和明确文件范围;实现单元按仓库 `AGENT-EXECUTION.md` 路由,主模型负责集成和验证。请求审核、合入和完成声明前分别执行 `make task-sync`,命令输出通过 `make evidence` 写入任务卡。作者本地测试只能标 `SELF`;精确 HEAD 的 CI 标 `GATE`,独立复跑标 `REPLAY`。 + +## 7. 未决决策 + +以下问题会改变公开契约或用户结果,在实现前需要用户/项目 owner 选择: + +1. 文档完成度的分母:只统计已有叶节点,还是把模板要求的缺失章节也纳入分母。 +2. 来源置信度是否沿用现有枚举,还是由本次读模型固定为 `high/medium/low/unknown`。 +3. 冲突计算的首期范围:字段级断言,还是先只显示领域已登记的冲突关系。 +4. 全景首屏是否允许直接显示段落摘要,还是只显示章节概览以降低敏感内容暴露。 + +在这些决策未冻结前,不启动 I1 的公开 DTO 实现;可以继续做只读源审计和示例数据映射,但不得把示例当作运行能力。 + +## 8. 当前状态与下一步 + +本计划已形成可评审的设计交付,所有 I1–I4、测试、CI、部署和业务验收均为 `NOT_RUN`。下一步是先评审四份文档并冻结第 7 节取舍;批准后再把 I1 拆成实际实施单元和独立任务卡。 + diff --git a/docs/superpowers/specs/2026-10-16-document-visualization-design.md b/docs/superpowers/specs/2026-10-16-document-visualization-design.md new file mode 100644 index 00000000..727b9c66 --- /dev/null +++ b/docs/superpowers/specs/2026-10-16-document-visualization-design.md @@ -0,0 +1,162 @@ +# 项目文档可视化驾驶舱设计规格 r1 + +状态:待评审;本文件只冻结设计,不授权业务代码、数据库迁移、部署或运行验收。 + +## 1. 目标与背景 + +当前 RDM 已有项目级“笔记树 / 文档树 / 追溯 / 操作记录”读取入口,`RdmAuditWorkspace` 可以按树节点加载详情和关系。但这些入口仍以逐项查询为主,不能在进入项目后回答“项目文档完成到哪里、哪里缺内容、哪些来源未核实、哪些地方冲突、最近发生了什么”。本次目标是为文档内容建立一个项目级可视化驾驶舱:它是文档工作的聚合读取和审阅界面,不是目录列表,也不是另一个文档编辑器。 + +设计基线来自已确认的方向: + +- 默认进入结构全景;全景和阅读器共享同一项目上下文、筛选条件和选中节点。 +- 结构全景用于整体关系、完成度、风险和影响面;文档阅读器用于连续阅读和审阅正文。 +- 两种视图消费同一个服务器权威聚合快照,不各自拼接一套状态。 +- 个人视图偏好只决定恢复哪种视图,不扩大项目或文档权限。 +- 思维导图式关系画布是后续模式,不作为第一期主界面;第一期仍采用可扫描的结构树和局部关系展开。 + +## 2. 用户与成功标准 + +主要用户是项目成员、文档作者、审阅者和项目管理员。用户进入项目后的前 10 秒内应能判断: + +1. 项目有哪些受控文档及其完成度。 +2. 哪些章节/段落为空、待确认、来源不足或存在冲突。 +3. 最近哪些内容被谁修改,以及修改是否已核实。 +4. 选中一个节点后,正文、来源、历史和影响对象是否可在同一屏继续阅读。 + +成功标准不是“显示更多信息”,而是减少用户在多个列表、弹窗和导出报告之间来回拼接上下文的次数。默认层只显示结论和下一步,原始来源、差异和工具记录按需展开。 + +## 3. 范围与非目标 + +### 3.1 本次范围 + +- 项目级文档聚合读取模型(Document Cockpit Read Model)。 +- 文档→章节→小节→段落的结构树,带状态徽标和更新时间。 +- 结构全景与文档阅读器两种视图,以及两者之间的定位跳转。 +- 内容来源、核实状态、置信度、冲突、影响关系和历史摘要的统一展示。 +- 按来源类型、状态、负责人、风险和最近更新的筛选。 +- 个人视图/密度/展开状态的恢复;权限仍由服务器按项目和资源判定。 +- 空数据、部分数据、过期快照、无权限和读取失败的诚实展示。 + +### 3.2 非目标 + +- 本阶段不增加文档生成、提交、审签、审批或导出动作。 +- 不替换现有 RDM 事件日志、关系存储、文档正文存储或权限系统。 +- 不把私人对话、上传原件或个人草稿直接公开到项目驾驶舱。 +- 不引入第三种主布局、独立“后台任务页”或全局关系图。 +- 不声称真实模型、真实浏览器、部署或运行环境已经验收。 + +## 4. 设计原则 + +1. **结论先行。** 顶部统计和节点摘要先给可行动结论;原始命令、内部 ID、隐藏推理和长日志默认不占据阅读层。 +2. **一份事实,多种投影。** 全景、阅读器、右侧依据面板都来自同一快照和同一 `snapshotRevision`。 +3. **来源可追溯但不越权。** 展示来源类型、摘要、验证状态和可见定位;私人原文依权限字段级隐藏。 +4. **不把未知显示成成功。** 未读取、被截断、冲突未决和权限过滤都必须有明确状态。 +5. **渐进式密度。** 紧凑总览适合扫描,完整内容适合审阅;展开使用现有 `@ui` `Collapsible` 原语。 +6. **视觉克制。** 遵守 `DESIGN.md` 和 `@ui/tokens.css`:灰白层级、单色主操作、清晰留白、语义色只表达语义,不自造颜色或动效。 + +## 5. 总体架构 + +```text +RDM 文档/章节/段落存储 +RDM 来源与关系存储 +RDM 原子事件与历史 +RDM 项目/成员/职责授权 + | + v +Document Cockpit Read Service + - scope + authorization + - node aggregation + - source normalization + - completeness/conflict/impact projection + - snapshot revision + truncation + | + +--> cockpit overview snapshot + +--> tree page / node detail + +--> source/history/impact panels + +--> local refresh / event invalidation + | + v +Frontend cockpit shell + - overview header + - panorama view + - reader view + - shared selection/filter state +``` + +读取服务只聚合已有领域事实。它可以建立可重建的读模型或查询投影,但不成为新的写入权威。任何写入(正文、来源核实、冲突裁定、职责变更)仍走现有领域命令和权限检查,并通过事件使读模型失效或刷新。 + +## 6. 核心对象 + +### 6.1 文档节点 + +节点层级固定为 `document -> section -> subsection -> paragraph`。若现有数据缺少某一层,读取服务返回实际层级和 `structuralGap`,前端不虚构空节点。每个节点至少有: + +- 稳定引用:`projectId`、`nodeRef {kind,id,version}`;UI 不显示内部 ID。 +- 可读标题、路径、父节点和子节点计数。 +- `contentState`: `complete | partial | empty | inaccessible | unavailable`。 +- `verificationState`: `verified | mixed | unverified | disputed | not_applicable`。 +- `sourceCount`、`conflictCount`、`impactCount`、`missingChildCount`。 +- `lastChangedAt`、`lastChangedBy`、`contentRevision`。 +- `visibility`: `full | redacted | metadata_only`。 + +### 6.2 来源 + +来源类型统一为 `conversation | file | web | tool | agent | human | derived`。来源记录包含来源摘要、采集时间、核实人/时间、置信度、定位信息和可见性;不能展示的私人原文只返回 `redactedReason` 和可审计的元数据。 + +### 6.3 冲突 + +冲突不是简单的“有两个来源”。只有当两个可见断言对同一节点/字段在同一有效范围内给出不兼容结论时才生成 `conflict`。记录冲突两侧的来源引用、差异摘要、发现时间、当前状态(`open | acknowledged | resolved | superseded`)和裁定依据引用。 + +### 6.4 影响对象 + +影响对象可为 `requirement | document | section | risk | task | trace_link`。关系带方向、类型、强度、状态和来源。默认只显示一跳;继续展开必须明确请求深度和上限,并返回 `truncated`。 + +## 7. 视图职责 + +### 7.1 结构全景 + +默认入口。左侧显示可展开结构树;中央显示当前项目或选中文档的章节概览、完成度和异常分布;右侧显示选中节点的来源、历史、影响和冲突。全景不把长正文铺满画布,而是显示摘要和可定位的内容片段。 + +### 7.2 文档阅读器 + +用于连续阅读。左侧目录保持当前位置;中央按章节渲染正文、段落状态和版本差异;右侧沿用同一个依据与影响面板。选中段落时,全景和阅读器的 `selectedNodeRef` 同步;切换视图后保留滚动锚点、筛选条件和权限范围。 + +### 7.3 个人偏好 + +只保存 `lastView`、`density`、`expandedNodeRefs`、`rightPanelTab` 和阅读锚点。偏好按用户和项目隔离,服务端不得把偏好当作授权依据。新用户默认 `panorama + compact`;进入项目后恢复最近一次视图。 + +## 8. 一致性与刷新 + +- 每次读取返回 `snapshotRevision`、`asOfSeq`、`generatedAt` 和各自的 `truncated` 标志。 +- 页面内异步请求必须绑定 `projectId`、筛选哈希、`snapshotRevision` 和请求代次;旧响应不得覆盖新上下文。 +- 领域事件到达时只使受影响节点和统计失效,不自动改变用户正在阅读的滚动位置;显示“有更新”提示,由用户刷新或在安全点合并。 +- 历史读取只能落在已提交操作批次的结束序号;落在批次中间时服务端拒绝或规范化到批次末尾。 +- 聚合失败时保留上一个可识别快照并显示其时间和过期状态,不把缓存当成当前事实。 + +## 9. 权限与隐私 + +服务端以项目为隔离根执行:项目访问、文档可见性、职责/资源 ACL 和字段级披露共同决定返回内容。客户端隐藏入口不构成授权。私人对话、上传原件和个人草稿默认不进入共享摘要;若某个受控文档引用了它们,只返回经授权的来源摘要和稳定定位。管理员能力不自动等同于作者、审阅者或批准者能力。 + +## 10. 分期边界 + +- V1:聚合快照、双视图、来源/历史/影响/冲突只读展示、筛选、权限和刷新一致性。 +- V1.1:局部关系展开、版本对照、来源核实入口(复用已有命令,另行授权)。 +- 后续:关系画布、批量审阅、文档导出和更多领域插件。 + +## 11. 需求与验收 ID + +| ID | 要求 | 验收判定 | +|---|---|---| +| DV-R01 | 首屏显示项目级完成度、缺项、冲突、未核实来源、待确认变更和最近更新 | 有真实快照时六项均可定位;缺数据时显示原因而非 0 值冒充 | +| DV-R02 | 结构树覆盖实际文档层级并显示节点状态 | 展开、选择、分页和空子节点均可用;不泄漏内部 ID | +| DV-R03 | 全景和阅读器共享选中节点、筛选和项目 | 双向切换后定位同一 `nodeRef` 和章节锚点 | +| DV-R04 | 来源、历史、影响、冲突可从选中节点继续展开 | 每个面板显示计数、权限状态、来源时间和截断状态 | +| DV-R05 | 快照具有可核验一致性 | 旧响应、乱序事件和历史中间序号不会覆盖当前状态 | +| DV-R06 | 私有数据和字段级披露受服务端授权保护 | 未授权读取返回拒绝/脱敏;客户端绕过入口不能得到原文 | +| DV-R07 | 窄屏、键盘、大字和减少动效可用 | 320/390/736/1024/1440 宽度无横向溢出,核心操作不依赖隐藏面板 | +| DV-R08 | 诚实处理过期、部分、冲突和失败 | UI 不生成虚假百分比、ETA、来源核实或完成结论 | + +## 12. 当前状态 + +本设计基于 Dev `9edb011e63ab9bf104360379e52c30075bd2f344` 的源代码和既有规划进行整理。设计文档、实现、业务测试、真实浏览器验收、CI、部署和生产数据验证均不在本文件中宣称完成。 + diff --git a/docs/superpowers/specs/2026-10-16-document-visualization-read-model-contract.md b/docs/superpowers/specs/2026-10-16-document-visualization-read-model-contract.md new file mode 100644 index 00000000..40cb398a --- /dev/null +++ b/docs/superpowers/specs/2026-10-16-document-visualization-read-model-contract.md @@ -0,0 +1,210 @@ +# 文档驾驶舱聚合读取模型与接口契约 r1 + +状态:待评审;只定义读取契约,不授权实现或迁移。 + +## 1. 契约定位 + +本契约把 RDM 已有树、正文、来源、关系和事件事实投影成一个面向 UI 的只读模型。它不替代 RDM 领域实体,也不允许前端根据多个旧接口自行拼装出第二套事实。所有接口都必须带项目上下文并在服务端完成授权。 + +## 2. 公共约定 + +```ts +type NodeKind = 'document' | 'section' | 'subsection' | 'paragraph' +type NodeRef = { kind: NodeKind; id: string; version?: string } +type ViewMode = 'panorama' | 'reader' +type Density = 'compact' | 'full' +type SourceKind = 'conversation' | 'file' | 'web' | 'tool' | 'agent' | 'human' | 'derived' +type ContentState = 'complete' | 'partial' | 'empty' | 'inaccessible' | 'unavailable' +type VerificationState = 'verified' | 'mixed' | 'unverified' | 'disputed' | 'not_applicable' + +interface SnapshotMeta { + schemaVersion: 'document-cockpit.v1' + projectId: string + snapshotRevision: string + asOfSeq: number + generatedAt: string + expiresAt?: string + truncated: boolean + truncationReasons: string[] +} + +interface TreePage { + meta: SnapshotMeta + items: TreeNode[] + nextCursor?: string + hasMore: boolean +} +``` + +`projectId` 是服务端解析后的项目定位,不是授权令牌。客户端提交的节点 ID、来源 ID 和 cursor 必须在同一项目范围重新解析。 + +## 3. 读取资源 + +### 3.1 项目概览 + +`GET /api/rdm/projects/{projectId}/document-cockpit/overview` + +返回项目统计、最近变化和顶层文档节点。统计字段必须区分“确实为 0”和“无法计算”: + +```ts +interface CockpitOverview { + meta: SnapshotMeta + project: { title: string; visibility: 'member' | 'restricted' } + stats: { + documentCount: number | null + completion: { known: number; total: number; state: 'known' | 'partial' | 'unavailable' } + emptyNodeCount: number | null + unverifiedSourceCount: number | null + conflictCount: number | null + pendingChangeCount: number | null + updatedAt?: string + } + documents: TreeNode[] + recentChanges: ChangeSummary[] +} +``` + +### 3.2 树分页 + +`GET /api/rdm/projects/{projectId}/document-cockpit/tree?parent=&cursor=&limit=&filter=` + +返回 `TreePage { meta, items: TreeNode[], nextCursor?, hasMore }`。服务端排序稳定为“文档顺序 / 章节顺序 / 最近更新时间”,不得按数据库内部 ID 作为用户可见排序。`filter` 是服务端解析后的来源、状态、负责人、风险和时间条件,未知过滤值拒绝而不是忽略。 + +```ts +interface TreeNode { + ref: NodeRef + title: string + path: string[] + parent?: NodeRef + childCount: number + state: { + content: ContentState + verification: VerificationState + sourceCount: number + conflictCount: number + impactCount: number + missingChildCount: number + } + lastChangedAt?: string + lastChangedBy?: ActorSummary + visibility: 'full' | 'redacted' | 'metadata_only' +} +``` + +### 3.3 节点详情 + +`GET /api/rdm/projects/{projectId}/document-cockpit/nodes/{kind}/{id}?version=` + +返回正文和面板摘要。正文必须区分 `contentState` 与 `body` 缺失;被权限过滤不能返回空字符串冒充空内容。 + +```ts +interface NodeDetail { + meta: SnapshotMeta + node: TreeNode + body?: ContentBlock[] + parent?: NodeRef + children: TreeNode[] + sources: SourceSummaryPage + history: HistorySummaryPage + impacts: ImpactPage + conflicts: ConflictPage + availableActions: string[] +} +``` + +### 3.4 面板分页 + +- `GET .../nodes/{kind}/{id}/sources` +- `GET .../nodes/{kind}/{id}/history` +- `GET .../nodes/{kind}/{id}/impacts?depth=1&cursor=` +- `GET .../nodes/{kind}/{id}/conflicts` + +每个分页资源返回同一 `SnapshotMeta`、`items`、`nextCursor`、`hasMore`、`truncated` 和 `redactions`。关系查询默认 `depth=1`、带服务端上限;超过上限只能返回明确的 `truncated=true`。 + +## 4. 内容与来源字段 + +```ts +interface SourceSummary { + ref: { kind: SourceKind; id: string } + label: string + excerpt?: string + locator?: { conversationId?: string; filePath?: string; url?: string; toolName?: string } + capturedAt?: string + verifiedAt?: string + verifiedBy?: ActorSummary + confidence: 'high' | 'medium' | 'low' | 'unknown' + verification: VerificationState + visibility: 'full' | 'redacted' | 'metadata_only' + redactedReason?: 'private' | 'forbidden' | 'expired' | 'not_loaded' +} +``` + +来源摘要不是来源原文缓存。`excerpt` 只有在当前用户拥有对应字段披露权限时返回;否则只返回标签、类型、时间和 `redactedReason`。 + +## 5. 变化与冲突 + +```ts +interface ChangeSummary { + node: NodeRef + title: string + changedAt: string + actor?: ActorSummary + kind: 'created' | 'content_changed' | 'source_added' | 'verification_changed' | 'conflict_opened' | 'conflict_resolved' + summary: string + version?: string +} + +interface ConflictSummary { + id: string + node: NodeRef + state: 'open' | 'acknowledged' | 'resolved' | 'superseded' + left: AssertionSummary + right: AssertionSummary + detectedAt: string + resolvedAt?: string + resolutionRef?: string +} +``` + +历史查询和导出只能使用已提交批次结束序号。读服务不得把正在写入的中间事件投影为“最近变化”。 + +## 6. 筛选、排序和缓存 + +- 筛选表达式必须序列化为稳定哈希 `filterHash`,并回显在响应中,防止旧筛选响应覆盖当前结果。 +- `ETag`/`If-None-Match` 可用于只读缓存,但缓存键必须包含用户可见范围、项目、筛选、版本和字段披露策略。 +- 允许短时缓存统计和树页;正文、来源和权限变化后必须以事件或 TTL 失效。缓存命中返回 `generatedAt` 和 `expiresAt`。 +- 任何 `null` 统计都必须伴随 `unavailableReason`,例如 `forbidden_source`、`projection_lag` 或 `upstream_error`。 + +## 7. 错误契约 + +| 场景 | HTTP/状态 | UI 处理 | +|---|---|---| +| 项目不存在或不可见 | 404(不泄露存在性) | 显示项目不可访问,不重试节点请求 | +| 节点属于其他项目 | 404 | 丢弃本地选择并刷新项目快照 | +| 权限允许元数据但禁止正文 | 200 + `metadata_only` | 显示标题/状态,正文和原文标为受限 | +| 快照过期 | 200 + `expired=true` 或 409 | 保留旧内容,显示刷新入口,不静默当当前事实 | +| cursor/过滤器非法 | 400 | 显示可理解的筛选错误,保留上一次有效筛选 | +| 上游读取失败 | 503/领域错误码 | 显示局部不可用和重试;不清空其他成功面板 | +| 关系超限 | 200 + `truncated=true` | 显示已截断及继续展开的明确上限 | + +## 8. 事件与前端状态 + +读模型可以通过现有项目事件/SSE 通知失效,事件只携带受影响 `projectId`、`nodeRef`、`seq` 和 `reason`。前端维护一个异步所有者: + +- `contextKey = projectId + filterHash + selectedNodeRef + viewMode`。 +- 每次请求拥有 `requestGeneration`;响应不匹配当前 generation 或 contextKey 时丢弃。 +- 每个事件流按 `seq` 严格递增应用;旧事件丢弃,缺口触发只读重拉而不是猜测中间状态。 +- 任何视图只读取同一快照缓存,不自行维护正文、统计或权限的第二份副本。 + +## 9. 版本兼容 + +响应顶层带 `schemaVersion`。新增字段向后兼容;状态枚举扩展必须先让旧客户端落入 `unknown` 安全分支。删除字段或改变字段语义必须提升版本并经过组合验证。契约初版不要求迁移旧 RDM 存储,读取服务通过适配器把既有 `rdm.inspect.tree/object/relations/events/history` 事实映射到新 DTO。 + +## 10. 安全验收 + +- 同一节点 ID 换项目提交时不得返回另一项目数据。 +- 仅有项目管理权而无正文/来源职责时,不得获得被保护原文。 +- `metadata_only`、`redacted` 和 `inaccessible` 三种状态在接口和 UI 中可区分。 +- 历史序号位于未提交批次时不得读取半个操作。 +- 导出、下载和关系展开沿用相同 scope/ACL 检查;本契约不新增绕过入口。 + diff --git a/docs/superpowers/specs/2026-10-16-document-visualization-view-spec.md b/docs/superpowers/specs/2026-10-16-document-visualization-view-spec.md new file mode 100644 index 00000000..337c8797 --- /dev/null +++ b/docs/superpowers/specs/2026-10-16-document-visualization-view-spec.md @@ -0,0 +1,137 @@ +# 文档驾驶舱双视图交互规格 r1 + +状态:待评审;这是界面与交互规格,不是实现稿。 + +## 1. 信息架构 + +```text +项目文档驾驶舱 +├── 顶部:项目名 / 视图切换 / 密度 / 全局筛选 / 刷新状态 +├── 项目统计带:完成度、空缺、未核实、冲突、待确认、最近更新 +├── 左栏:文档结构树(文档→章节→小节→段落) +├── 中栏: +│ ├── 全景:项目/文档概览、章节状态、关系摘要 +│ └── 阅读器:目录定位、正文、段落状态和版本变化 +└── 右栏:依据、历史、影响、冲突(同一选中节点) +``` + +不新增第四栏。窄屏时三栏变为同一工作区内的单栏导航:树、内容、依据面板依次进入,始终提供明确返回按钮和当前节点标题。 + +## 2. 顶部统计带 + +统计卡只展示数值和一句解释,不做装饰性大卡片。每个统计项可点击,点击后只改变共享筛选: + +- 完成度:已知完成节点 / 已知节点;数据不足时显示“部分计算”。 +- 空缺段落:内容为空或结构缺失的叶节点。 +- 未核实来源:有来源但验证状态不是 `verified` 的节点数。 +- 冲突:开放或待裁定冲突数。 +- 待确认变更:最近变化中需要人工确认的变更数。 +- 最近更新:最近一次可见变更时间和操作者。 + +点击统计不得直接执行写入或裁定;它只定位待处理内容。 + +## 3. 左侧结构树 + +### 默认显示 + +每行显示标题、层级缩进、内容状态、来源数、冲突/待确认徽标和最近更新时间。内部 ID、数据库类型名和技术状态码不显示。文档节点可以展开,章节和段落按需加载;加载失败只影响当前分支并保留重试。 + +### 交互 + +- 单击节点:更新共享 `selectedNodeRef`,中央和右侧同步加载。 +- 展开箭头:只加载子节点,不改变选中内容。 +- 键盘:方向键移动,Enter 选择,Space 展开,左/右折叠/展开。 +- 搜索:按标题、路径和可见摘要检索;搜索结果仍受项目权限和当前筛选约束。 +- 状态徽标:可作为筛选入口,但不隐藏结构树的其他节点。 + +## 4. 结构全景 + +### 中央内容 + +未选中节点时显示项目/文档概览:文档列表、章节完成度条、缺项摘要、最近变化和风险分布。选中节点时显示: + +1. 节点标题和路径。 +2. 一句话状态总结(内容、验证、冲突、影响)。 +3. 当前可见正文摘要或章节概览。 +4. 子节点状态表,可按缺项/冲突/负责人排序。 +5. “在阅读器中打开”按钮,带同一 `nodeRef` 和阅读锚点。 + +### 关系摘要 + +只在选中节点附近显示来源数量、影响对象数量和冲突数量;关系详情在右栏展开。大规模网络图不是默认内容。 + +## 5. 文档阅读器 + +### 中央内容 + +阅读器按章节连续渲染正文,段落之间显示轻量状态线:来源类型、验证状态、最近修改人/时间和冲突标记。版本变化默认以“当前版本 + 前一版本摘要”呈现,完整差异使用 `Collapsible` 展开。被权限过滤的段落显示“内容受限”,而不是空白。 + +### 阅读行为 + +- 从全景进入阅读器时定位到选中节点并保留章节滚动锚点。 +- 从对话卡片或来源跳转时,若目标是关系解释,进入全景;若目标是交付正文,进入阅读器。 +- 切换筛选后保留选中节点;若节点被筛掉,显示“当前节点不在筛选范围”并提供清除筛选。 +- 后台更新不抢占滚动位置;仅在标题旁显示“内容已更新”,用户选择刷新。 + +## 6. 右侧依据与影响面板 + +右侧使用四个标签,默认打开“内容来源”。每个标签显示数量和状态,详情按需展开。 + +### 内容来源 + +显示来源类型图标/文字、摘要、采集时间、核实状态、置信度和可见定位。私人来源只显示脱敏元数据;不展示隐藏原文或内部提示词。 + +### 修改历史 + +以自然语言时间线显示创建、正文修改、来源变化、验证变化和冲突状态变化。每条记录显示操作者、时间、版本和差异摘要;完整 diff 折叠。 + +### 影响对象 + +显示受影响要求、文档、风险、任务和追溯关系。默认一跳,显示关系类型、方向、状态和置信度;继续展开前提示数量上限。 + +### 冲突与风险 + +显示冲突双方摘要、各自来源、发现时间和当前裁定状态。没有权限看到一侧原文时仍显示“另一侧受限”,不把冲突误判成单方事实。 + +## 7. 状态与空态 + +| 状态 | 文案方向 | 禁止行为 | +|---|---|---| +| 加载中 | 加载项目文档概览 / 加载依据 | 不显示虚假的 0 统计 | +| 空项目 | 暂无受控文档 | 不显示导入或生成按钮,除非另有已批准入口 | +| 部分加载 | 已显示已读取内容,部分依据暂不可用 | 不把部分数据标为完整 | +| 受限 | 你可以看到节点状态,但正文受权限限制 | 不泄露原文存在性以外的私密信息 | +| 过期 | 内容来自某时间的快照,刷新以获取最新状态 | 不静默自动改写用户正在阅读的正文 | +| 失败 | 该面板暂时不可用,可重试 | 不清空其它已成功面板 | +| 截断 | 已显示前 N 条,继续展开有上限 | 不假装显示全部关系 | + +## 8. 视觉与可访问性门禁 + +- 颜色、圆角、字号只消费 `@ui/tokens.css`;字号使用 `--fs-ui-*`。 +- 折叠只使用 `@ui` `Collapsible`,动效只使用 `@ui/motion.css` 的 `mk-*` 类。 +- 主操作采用单色反色按钮;状态色只表达成功、警告、错误、等待和差异语义。 +- 320/390/736/1024/1440 宽度下不横向溢出;18px UI 字号下标题、按钮和徽标不重叠。 +- 所有图标按钮有可访问名称;树节点和标签页有键盘焦点;减少动效时只保留状态变化。 +- 不把三栏做成互相嵌套的卡片墙;页面区域使用无框布局,重复来源/变化项才使用轻量条目容器。 + +## 9. 视图切换规则 + +| 触发来源 | 默认视图 | 定位 | +|---|---|---| +| 第一次进入项目 | 结构全景 | 项目根节点 | +| 用户上次有偏好 | 上次视图 | 上次项目/节点锚点(仍需重新授权) | +| 对话解释关系 | 结构全景 | 目标关系节点 | +| 对话交付正文 | 文档阅读器 | 目标章节/段落 | +| 来源或冲突跳转 | 当前视图保持 | 选中节点 + 右栏对应标签 | +| 节点无正文但有关系 | 结构全景 | 节点摘要和影响面板 | + +## 10. 交互验收场景 + +1. 进入有多个文档的项目,首屏看到统计和树,不需要逐个打开弹窗。 +2. 在全景点选段落,切换阅读器后正文和右栏仍是同一段落。 +3. 从阅读器打开来源,返回后保持滚动位置和筛选。 +4. 一个来源被撤回或标为未核实,统计、树徽标、正文状态和来源面板一致变化。 +5. 两个来源冲突时,冲突面板显示双方摘要;无权限的一侧只显示脱敏状态。 +6. 读取超时或断线后,保留旧快照并明确显示过期,不出现空白页面。 +7. 在窄屏和键盘操作下,树、正文和依据面板都可进入和返回。 +