Record top-level screenshots as 20 main/pre plus 1 post, and the full-package race as FAIL 109.279s instead of a cached ok line. Co-authored-by: Cursor <cursoragent@cursor.com>
19 KiB
文档版本账本运行时 UI 验收测试报告
轮次: Round20
日期: 2026-09-14
判定(文档运行时范围): PASS
整个系统 production_ready: no(保留 CHAT-INTENT 等无关 blocker;本报告不把运行时 PASS 写成全仓可发布)
证据只读根:
.doc/test-reports/assets/2026-09-13-document-revision-runtime-ui/本报告不引用本地phase-secrets.local.json的任何字段或内容;该文件不得提交。 历史失败目录(schema30-*/schema31-*/ui0*等)只增不删,不改写。
一、 测试背景 (Background)
Wave 0–6 账本内核合入后,真实工作台仍表现为「账本未就绪」、保存无效、overlay 空转、变更报告是静态假 JSON。后续工程修复覆盖:
- 假
doc-upload/ 模板槽误挂工具条,受控文档不同步; - 账本只在进程内 map,未 PG 持久化、GET 无 bootstrap;
- 保存 ETag / hydration / 投影顺序错误;
- overlay 未接到块样式;
- 任务 SSE 断线后同 turn 409、路由被法规关键词带偏、质量门禁自污染;
- 职责授权:reviewer 未写入
document_records、矩阵误判; - 最终:PG
RETURNING id未推进内存计数器,临时 ID 撞上 baseline 后无条件delete,CommitAgentVersiondocrevision: not found(项目 6158:baseline snapshot=249、candidate id=175、output snapshot id=250、report id=175,禁止把 250 写成 candidate)。
第 19 轮因此在首次生成失败。第 18 轮后 post-restart 曾因 phase-state.bodySnippet 仍是 UI-06 marker,而 UI-13b A1 已把最终正文写成 A1-win marker。Round20 在 dev@b258ab8(已含 PG ID remap 与最终持久 snippet)上重跑真实页面验收。
二、 测试目标 (Test Objectives)
- 页面-only、无 API/DB fixture /
page.routemock / stub 模型,真实pi-agent+ MiniMax; - UI-00…UI-16(含 05a/05b、13a/13b、15-pre/15)全部页面可见且可判定;
- 高风险 pending:确认升 V、拒绝不升;人工保存升 r 且硬刷新保留;三 overlay 可区分(仅人工时 manual===all 允许);
- 多文档与页面上传独立账本;C 隔离;B reviewer 只读;A/A 409 保留冲突稿;重登/重启恢复最终持久正文;
- 诚实区分:正文与对话回复来自真实 PI;change report
analysis_status=fallback是真实 diff + lineage 的确定性分析,不冒充 PI 叙事。
三、 测试方案与环境 (Test Plan & Environment)
| 项 | 值 |
|---|---|
| OS | Ubuntu Server(无图形桌面 / headless) |
| 浏览器 | mcr.microsoft.com/playwright:v1.63.0-noble;--network host --ipc host;BASE_URL http://127.0.0.1:3100;页面-only Chromium |
| 服务 | 测试前 ./scripts/env-service.sh dev rebuild 部署 b258ab8;主阶段后宿主仅 restart shuimu-agent-app-dev 一次,PG/PI 未动;文档收口阶段不再动容器 |
| Agent | 真实 PI,禁止 stub |
| 项目 | UI验收-超声微创系统-mu0gwiez(id 6159) |
| 首份受控文档 | doc_proj6159_intake(用户初始需求收集表) |
| 首轮任务 | run_1789343479579646533 |
| 第二份受控文档 | doc_proj6159_prelim_design |
| 页面上传 | doc-free-1789344210423570738-182 |
| 账号(仅用户名,无口令) | A=uia_mu0gwiez B=uib_mu0gwiez C=uic_mu0gwiez |
| 终态 phase-state | V3 / r2 / bodySnippet=A1-win-mu0gwiez |
| 结果账本 | ui-acceptance-results.json 21 条全部 PASS |
| Playwright main | 18 passed / 1 post skipped |
| Playwright post | 仅 restart app 后 1 passed / 18 skipped |
3.1 Ubuntu 无头方案
本轮采用:官方镜像 mcr.microsoft.com/playwright:v1.63.0-noble,--network host --ipc host,BASE_URL=http://127.0.0.1:3100,跑 web/e2e/document-revision-runtime.spec.ts。本次无需给 Ubuntu host 安装浏览器或 npx playwright install。
备选(未作为本轮执行路径):在宿主 web/ 执行 npx playwright install --with-deps chromium,仅当不能跑官方容器时使用。
两阶段:
- 测试前
./scripts/env-service.sh dev rebuild部署b258ab8。 RUN_UI_ACCEPTANCE=1 UI_PHASE=main BASE_URL=http://127.0.0.1:3100→playwright-output-main/playwright-report-main/ui-acceptance-results.json/phase-state.json- 宿主仅
restart shuimu-agent-app-dev一次(PG/PI 未动;不是再次 rebuild) RUN_UI_ACCEPTANCE=1 UI_PHASE=post-restart→playwright-output-post-restart/playwright-report-post-restart/ui-acceptance-results-post-restart.json- 文档收口阶段不再动容器。
3.2 用例矩阵与决策流
| 决策 | 期望 |
|---|---|
| 高风险候选「确认提交」 | pending 消失,版本前进(本轮 V2→V3) |
| 高风险候选「拒绝」 | pending 消失,版本不前进(本轮保持 V3) |
| 人工保存成功 | r 立即 +1,硬刷新正文仍在 |
| A/A 同 r 后写 | 409 DOCUMENT_HEAD_CONFLICT,后写编辑器保留草稿,成功方正文成为最终持久 marker |
三 overlay 语义(本轮实测):
- 纯净阅读:当前正文无标记。Round20 抽样 92 块均为
backgroundColor=rgba(0,0,0,0)、overlayKind空。 - 人工修改:当前 Version 内的人工修订(琥珀人工 hunk)。本轮 92 块带
modify/move,底色rgb(51, 41, 15)。 - 全部变更:相对基线 / 上一 Version 的智能体 + 人工变化。本轮另含
insert,与「人工」可区分。 - 仅人工 hunk 时:允许与人工模式视觉相同;不得因此判 FAIL。
3.3 证据清单(只读,不提交本报告附件目录)
| 类型 | 路径 |
|---|---|
| main 结果 | .../ui-acceptance-results.json(21 PASS) |
| post 结果 | .../ui-acceptance-results-post-restart.json(UI-15 PASS) |
| 阶段状态 | .../phase-state.json(无口令) |
| 截图 | 顶层 .../screenshots/ 21 个文件 = 主阶段 20 张(含 UI-15-pre,以及 UI-00…14 / UI-16)+ post-restart 1 张(UI-15-post-restart.png)。不要与 results JSON 的 21 条记录混为一谈 |
| 分离产物 | playwright-output-main/、playwright-output-post-restart/、playwright-report-main/、playwright-report-post-restart/(trace/video/html) |
| 历史失败 | 同根下 schema30-*、schema31-*、ui0*、pre-auth-*、post-auth-* 等 |
四、 预期结果 (Expected Results)
- 首轮真实小队完成后,intake 工具条
V2/r0,非「账本未就绪」; - 变更报告面板可见风险、项目影响、文档影响原因/建议、开放问题;
fallback不得写成完整 PI; - 二轮高风险:未确认保持 V2 + pending;确认后 V3;再一轮拒绝保持 V3;
- 人工保存 r0→r1 且硬刷新保留;UI-13b A1 成功后最终正文
A1-win-mu0gwiez、r2; - 第二文档
doc_proj6159_prelim_design与上传doc-free-*各自 revision-state 200; - C 看不到项目;B 为 reviewer、无正文编辑/保存;
- 重登与 restart 后仍为 V3/r2/最终正文,
revision-state/versions/manual-overlay/content200。
五、 实际测试结果与判定 (Actual Results & Evaluation)
下列 Input / Actual 摘自 ui-acceptance-results.json 与 post JSON,不是事后改写。Duration 为结果账本 durationMs。
UI-00 管理员开通 A/B/C
- 测试输入 (Input):admin UI 创建用户并完成首次口令重置(口令不入库、不写入本报告)。
- 实际输出 (Actual Output):
users uia_mu0gwiez,uib_mu0gwiez,uic_mu0gwiez ready。 - 评价判定 (Evaluation / Verdict):PASS
- 性能与耗时 (Duration & Latency):6684 ms
- 截图:
screenshots/UI-00-admin-logged-in.png
UI-01 页面创建立项工作台
- Input:A 登录;创建项目
UI验收-超声微创系统-mu0gwiez;勾选成员 B。 - Actual Output:模板提示可见;
doc-prevision-state 计数=0;无 revision-state 404。 - Verdict:PASS
- Duration:1121 ms
- 截图:
screenshots/01-project.png
UI-02 真实小队发任务
- Input:
请基于本项目编制首轮《用户需求》摸底文档,覆盖预期用途、关键性能与适用法规框架,直接生成受控交付物。 - Actual Output:
POST /api/v1/tasks/runs202;本轮助手 inflight。run=run_1789343479579646533。 - Verdict:PASS(真实 PI 请求,非 stub)
- Duration:235 ms
- 截图:
screenshots/UI-02-squad-started.png
UI-03 首份受控文档账本
- Input:等待小队完成;打开 intake 服务端文档槽。
- Actual Output:工具条 V2/r0;
docId=doc_proj6159_intake;标题「用户初始需求收集表」。GET .../revision-state|versions|manual-overlay与GET .../docgov/.../content均为 200。 - Verdict:PASS(相对 Round19
CommitAgentVersionnot found:本轮首次生成成功) - Duration:188989 ms
- 截图:
screenshots/03-first-doc.png
UI-04 变更报告完整字段
- Input:点击「变更报告」;点「关闭」。
- Actual Output:页面可见
risk=high、项目影响、文档影响/建议、开放问题;对话框关闭。GET /api/v1/documents/doc_proj6159_intake/change-reports/182200。 - Verdict:PASS
- Duration:218 ms
- 诚实声明:报告字段来自确定性 diff + lineage(
analysis_status=fallback)。不是完整 PI 业务叙事;不得把可见摘要写成「PI 已完成风险解释」。 - 截图:
screenshots/04-first-report.png
UI-05 高风险 pending(确认用例)
- Input:
请按 YY/T、GB 9706.1 与 NMPA 注册法规要求,大幅改写当前受控文档中的风险管理与电气安全章节,引用具体条款并重写适用性结论(二轮高风险候选-确认用例)。 - Actual Output:pending 徽章;版本仍为 V2。
POST /api/v1/tasks/runs202(run=run_1789343671958285314)。 - Verdict:PASS(高风险未确认不进版本历史)
- Duration:180437 ms
- 截图:
screenshots/05-second-report.png
UI-05a 确认提交升 V3
- Input:点「待确认报告」;断言 pending 动作;点「确认提交」。
- Actual Output:
risk=high;decision ok;版本 V3。GET change-reports/183200;POST .../agent-candidates/183/decision200。 - Verdict:PASS
- Duration:268 ms
- 截图:
screenshots/UI-05a-confirmed.png
UI-05b 拒绝不升版本
- Input:
请再次按医疗器械临床试验与注册检验法规,重写当前受控文档《用户初始需求收集表》中的电磁兼容与软件生存周期章节并给出条款级符合性判断(二轮高风险候选-拒绝用例)。;点「待确认报告」;点「拒绝」。 - Actual Output:
task_key=intake doc_id=doc_proj6159_intake;rejected;版本仍为 V3。GET change-reports/184200;POST .../agent-candidates/184/decision200。 - Verdict:PASS
- Duration:169617 ms
- 截图:
screenshots/UI-05b-rejected.png
UI-06 人工保存 + 硬刷新
- Input:双击块编辑 → 保存 → reload。
- Actual Output:
rr0→r1;marker 持久化。PATCH .../content200。 - Verdict:PASS
- Duration:1048 ms
- 截图:
screenshots/UI-06-after-refresh.png - 后续覆盖:此 marker 不是最终持久正文;UI-13b A1 成功后覆盖为
A1-win-mu0gwiez。
UI-07 / UI-08 / UI-09 三 overlay
三条结果键共享同一次取样(各记 2417 ms)。
- Input:切换纯净 / 人工 / 全部;抽样
document-block计算样式。 - Actual Output:
pure unmarked; manual/all marked; manual===all allowed when hunks match。- 纯净:92/92 无标记;
- 人工:92/92
modify|move; - 全部:92/92,额外出现
insert(本轮与人工可区分)。
- Verdict:PASS / PASS / PASS
- Duration:2417 ms(共享)
- 截图:
UI-07-pure.png、UI-08-manual.png、UI-09-all.png
UI-10 版本历史比较 V1/V2
- Input:打开「版本历史」;选两个 V 为 A/B;点「比较 A/B」;历史自动关闭后再关比较。
- Actual Output:
history entries=3; compared V1 vs V2; history auto-closed; compare closed。GET .../diff200。 - Verdict:PASS
- Duration:441 ms
- 截图:
screenshots/UI-10-history-compare.png
UI-11 第二文档 + 页面上传
- Input:对话生成第二份受控文档;页面上传附件并发送以注册 freeform。
- Actual Output:
用户初始需求收集表:V3/r1;系统初步设计方案:V2/r0(doc_proj6159_prelim_design);POST /api/v1/freeform-documents201;uploadedDocId=doc-free-1789344210423570738-182。两份受控 + 上传的 revision-state/versions 200。 - Verdict:PASS
- Duration:178358 ms
- 截图:
screenshots/UI-11-multi-doc.png
UI-12 C 隔离
- Input:登录
uic_mu0gwiez(非成员)。 - Actual Output:项目
UI验收-超声微创系统-mu0gwiez不可见。 - Verdict:PASS(不泄漏正文)
- Duration:1278 ms
- 截图:
screenshots/12-unauthorized-access.png
UI-13a B reviewer 只读
- Input:B 登录;打开 intake;看权限矩阵并双击。
- Actual Output:
duty=reviewer;无编制人编辑提示;无保存编辑器。 - Verdict:PASS
- Duration:1999 ms
- 截图:
screenshots/UI-13a-reviewer-readonly.png
UI-13b A/A 409 草稿保留
- Input:双窗同一 r/etag hydration;A2 先打开编辑器并填稿,A1 再保存,然后 A2 保存。
- Actual Output:
base r=r1 etag=261:1;A1 持久正文 A1-win-mu0gwiez;A2HTTP 409code=DOCUMENT_HEAD_CONFLICT;A2 编辑器保留冲突稿。A1PATCH .../content200。 - Verdict:PASS(冲突失败稿不得成为 phase-state 期望正文)
- Duration:2640 ms
- 截图:
screenshots/UI-13b-conflict-A2.png
UI-13 组合键
- Input:先 13a 再 13b。
- Actual Output:
see UI-13a and UI-13b;备注:B 是项目 reviewer,不得当正文编辑者。 - Verdict:PASS
- Duration:2644 ms
UI-14 退出后重登
- Input:点「退出当前登录」;再以 A 登录。
- Actual Output:账本 V3/r2 未变。
revision-state200。 - Verdict:PASS
- Duration:1357 ms
- 截图:
screenshots/UI-14-relogin.png
UI-15-pre 重启前落盘
- Input:采集项目/状态后结束 main suite。
- Actual Output:
state file written version=V3 revision=r2。phase-statebodySnippet=A1-win-mu0gwiez(UI-13b 成功修订覆盖 UI-06 marker)。 - Verdict:PASS
- Duration:74 ms
- 截图:
screenshots/UI-15-pre-restart-evidence.png - 备注:完整 UI-15 只在
UI_PHASE=post-restart计 PASS。
UI-16 已注册上传挂账本
- Input:分类=私密;打开精确 id
doc-free-1789344210423570738-182。 - Actual Output:pane 即该 id;工具条 V 可见;无
doc-uploadrevision-state。 - Verdict:PASS(禁止静默假 V1)
- Duration:383 ms
- 截图:
screenshots/UI-16-registered-upload.png
UI-15 post-restart(仅 restart app)
- Input:A 页面登录;打开
UI验收-超声微创系统-mu0gwiez。 - Actual Output:
version=V3 revision=r2;页面恢复正文,无「账本未就绪」。GET /api/v1/projects/6159/documents200;doc_proj6159_intake的content/revision-state/versions/manual-overlay均为 200。Playwright post:1 passed / 18 skipped。 - Verdict:PASS
- Duration:1445 ms
- 截图:
screenshots/UI-15-post-restart.png
六、 自动化测试套件汇总 (Test Suite Execution)
工程门禁不能替代上节真实 UI。下列为合入基线 dev@b258ab8 上已记录的工程结果(验收已 rebuild+restart;文档收口不再动容器)。
| 命令 | 结果 |
|---|---|
gofmt(相关包) |
PASS |
go vet ./... |
PASS |
go test -short ./... |
PASS |
cd web && npm test |
333 + 30 PASS |
cd web && npm run build |
PASS |
| 隔离 PG:schema 1→31 高序列首次生成 / 重启 hydration | PASS;临时库已 DROP |
go test -race ./internal/docrevision ./internal/bizdev |
PASS(日志含 cached) |
go test -race 全仓并行一次 |
FAIL 109.279s(chat-agent-system/internal/server);失败用例 TestCreateTaskRun_PreActivationAcceptedNot409,TempDir RemoveAll: directory not empty。不得写成 ok ... 110.723s 或全 race PASS |
该单测 -race -count=5 |
PASS;worker 日志可出现在 PASS 之后(测试基建/异步收口残留,绝不能写全 race PASS) |
Playwright(官方容器,真实 PI):
results JSON: 21/21 PASS
main: 18 passed, 1 skipped (post)
post: 1 passed, 18 skipped
七、 测试结论与后续优化建议 (Conclusion & Next Steps)
7.1 文档运行时范围
PASS / done。Round20 证明:首次生成可提交、高风险确认/拒绝、人工修订与冲突、三 overlay、多文档/上传、授权隔离、重登与 app restart 后 V3/r2/A1 正文可恢复。集成槽位应释放。
7.2 不得写成「全仓可发布」
CHAT-INTENT-STATE等无关 blocker 仍使production_ready=no;- change report 仍是 fallback(真实 diff,不是假 JSON,也不是完整 PI 叙事);
-race全包并行 flake 属于测试基建,不回滚本结论,也不假装 race 全绿。
7.3 影响
| 范围 | 影响 |
|---|---|
| 项目 6159 | 真实立项 + 两轮高风险决策 + 人工冲突后的最终账本 |
文档 doc_proj6159_intake |
终态 V3/r2,正文 marker A1-win-mu0gwiez |
doc_proj6159_prelim_design |
独立 V2/r0 |
doc-free-1789344210423570738-182 |
服务端注册后挂工具条,无 orphan doc-upload |
| 历史失败资产 | 仍用于根因追溯,禁止当本轮 FAIL |
7.4 风险
- high(产品):编制人必须理解 pending 确认才会升 Version;拒绝不会丢当前 V。
- medium(报告):用户若把 fallback 摘要当成「法规专家已审完」,会产生合规错觉——UI 与文档必须继续标明确定性分析。
- low(测试):server 包 TempDir 并行污染可在无关 PR 上闪红。
7.5 开放问题
DOCREV-RT-PI-NARRATIVE:业务叙事摘要 / 风险解释的真实 PI 链路仍未替代 fallback。- 跨设备用户目录仍可能缺成员候选(本轮同浏览器 admin→A 未暴露)。
- 仅 IndexedDB、从未
POST /freeform-documents的预览仍禁止静默假 V1(UI-16 验证的是已注册路径)。 go test -race全包并行时TestCreateTaskRun_PreActivationAcceptedNot409的 TempDir 异步收口。
7.6 建议
- 合入本报告后保持
production_ready=no,焦点转到CHAT-INTENT等系统 blocker; - 复跑无头 UI 继续用官方 Playwright noble 容器,宿主
npx playwright install仅作备选; - 不提交 assets、不提交/引用
phase-secrets.local.json内容。