fix(v2): 浏览器端到端验证——修掉模块页在浏览器里渲染不出内容的缺陷

首次用真实 Chrome 打开 /trajectory-center(新增可选脚本 scripts/browser-e2e.cjs),
暴露 5 个源码守卫与生产构建都看不出的缺陷,全部修复:

1. 三个模块页读 `list.items`,而 /projects 返回的是 {projects, identity}——
   项目列表恒为空,prescreen-workbench / experience-center / trajectory-center
   整页渲染不出任何面板,只显示"当前身份没有可访问的项目"这种看着正常的空态。
   (第二/三批引入)改为 list.projects。
2. TrajectoryPanel 没被传 identity,canRecord 恒假 → 会议结果录入表单永不出现。
3. ImprovementPanel 草稿下拉以组件 id 作 key/value,同一组件多版本草稿时撞 React key,
   且选不准要发布哪一版;改以 `组件id@版本` 为键值。
4. JSX 文本里的 `**强调**` 会原样显示星号(JSX 不渲染 Markdown),共 9 处;
   改为 <b>(字符串上下文处直接去掉标记)。
5. 深色导航模块名被 flex 压缩折行("AI 预审"断成两行);
   加 flex:0 0 auto + white-space:nowrap。

另修一个既有测试脆弱点:test_trajectory.py 的更正用例断言"哪条排前面",
两条记录同刻度时排序翻转,曾让 verify.py 偶发失败;改为断言"两条都在、更正指向旧记录"。

回归防线:第 5 项补进 test_module_shell_ui.cjs 源码断言;
test_ui_readability.cjs 的导航字号断言改为不把 min-height 钉在规则首位。

验证:scripts/verify.py 14/14 PASS(backend-unit 572 项),
证据 test-evidence/20261001-030127-ff59d7e/;scripts/browser-e2e.cjs 19/19 PASS
(截图在 test-evidence/e2e-batch4/)。该 E2E 脚本刻意不接入 verify.py。

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
2026-10-01 03:04:18 +08:00
co-authored by Claude Code
parent ff59d7e8f1
commit 4720d72965
14 changed files with 294 additions and 44 deletions
+40 -10
View File
@@ -271,11 +271,14 @@ XINGBANG_LOCAL_MODEL_KEY=<你的 DeepSeek API Key>
## 第四批:接通评审反馈与改进发布
状态:**部分完成**。会议结果可从页面录入并与材料版本对照;改进候选走**真实知识发布入口**,
发布后新运行使用新版本、旧运行仍可回放——两条断言都由真实执行链(enqueue + worker)证明。
**未闭合**:界面仍未经浏览器点击/截图验证(同 F11);会议结果是**模拟录入**,未经真实会议系统。
状态:**部分完成**(较本轮初版有实质性推进)。会议结果可从页面录入并与材料版本对照;
改进候选走**真实知识发布入口**,发布后新运行使用新版本、旧运行仍可回放——两条断言都由
真实执行链(enqueue + worker)证明。**本批首次做了真实浏览器端到端验证(F11 对这两个表面已关闭)**,
并因此发现并修掉 5 个源码守卫与生产构建都看不出的缺陷(见下「浏览器验证发现的问题」)。
**未闭合**:会议结果是**模拟录入**,未经真实会议系统;`/experience-center` 与 `/prescreen-workbench`
虽在同一次浏览器验证中被顺带修好,但其自身交互仍未逐项点过。
覆盖:AC-56、AC-57、BR-51。
覆盖:AC-56、AC-57、BR-51;并顺带修复 AC-53/AC-55 的运行时缺陷。
### 页面入口
@@ -336,14 +339,41 @@ AC-53 又要求恰好三个模块入口。`AgentNav.tsx` 未改动。
| 自报版本号被拒(API 层) | `backend/test_improvements.py` `test_client_supplied_released_ref_is_rejected` |
| 界面源码守卫(新增) | `scripts/test_improvement_panel.cjs`(已登记 `scripts/verify.py`,共 **14** 项检查) |
| 轨迹面板守卫(改:区分「回放只读」与「结果只可追加」) | `scripts/test_module_shell_ui.cjs` |
| 全量验证 | `test-evidence/20261001-013517-3e15bda/`(`scripts/verify.py` **14/14 PASS**,含 `backend-unit` 全量 **572** 项) |
| 全量验证 | `test-evidence/20261001-030127-ff59d7e/`(`scripts/verify.py` **14/14 PASS**,含 `backend-unit` 全量 **572** 项) |
| 真实服务器冒烟 | `scripts/xingbang_batch4_smoke.py`(对 127.0.0.1:8012 实跑,退出码 0) |
| **真实浏览器端到端** | `scripts/browser-e2e.cjs`(系统 Chrome;**19/19 PASS**);截图与 `result.json` 在 `test-evidence/e2e-batch4/` |
### 浏览器验证发现的问题(源码守卫与生产构建都查不出来)
首次用真实 Chrome 打开 `/trajectory-center` 后暴露的缺陷。「看起来正常的空态」是它们的共同点——
`/projects` 读错了字段,页面安静地显示"当前身份没有可访问的项目",构建与守卫全都通过。
| # | 问题 | 归属 | 处理 |
|---|---|---|---|
| 1 | 三个模块页读 `list.items`,而 `/projects` 返回的是 `{projects, identity}` → 项目列表恒为空,**整个模块页渲染不出任何面板** | 第二/三批引入(prescreen-workbench、experience-center、trajectory-center 三处) | 改为 `list.projects` |
| 2 | `TrajectoryPanel` 没被传 `identity`,`canRecord` 恒假 → **会议结果录入表单永远不出现** | 本批 | 传入 `identity` |
| 3 | `ImprovementPanel` 的草稿下拉以组件 id 作 key/value,同一组件有多个版本草稿时**撞 React key**,也选不准要发布哪一版 | 本批 | 改以 `组件id@版本` 为键值 |
| 4 | JSX 文本里写 `**强调**` 会**原样显示星号**(JSX 不渲染 Markdown),共 9 处 | 第一/二批 5 处、本批 4 处 | 改为 `<b>`(字符串上下文处直接去掉标记) |
| 5 | 深色导航的模块名被 flex 压缩**折行**("AI 预审"断成两行),三个入口读不清 | 第三批 | `flex:0 0 auto; white-space:nowrap` |
此外还修掉一个**既有测试脆弱点**:`test_trajectory.py` 的更正用例断言"哪条排前面",
而两条记录可能落在同一时钟刻度、排序随之翻转,曾让 `scripts/verify.py` 偶发失败。
改为断言"两条都在、更正指向旧记录",与排序无关;连跑 5 次稳定通过。
回归防线:第 5 项已补进 `scripts/test_module_shell_ui.cjs` 的源码断言;
`scripts/test_ui_readability.cjs` 的导航字号断言改为不把 `min-height` 钉在规则首位
(否则它会因新增属性而误报)。第 1–4 项属于"只有浏览器能看见"的一类,
目前只由 `scripts/browser-e2e.cjs` 覆盖——该脚本**刻意不接入 verify.py**。
### 剩余缺口
- **界面仍未经浏览器验证(F11 未变)**:本批新增的两个表面只有「源码守卫 + 生产构建
(`/trajectory-center` 3.87 → 8.86 kB)+ 真实服务器接口冒烟」三层证据,**没有浏览器点击或截图**;
表单交互、按钮、权限隐藏这些路径没有端到端证明。
- **F11 对本批两个表面已关闭,但未全面关闭**:`/trajectory-center` 已由 `scripts/browser-e2e.cjs`
在真实 Chrome 里走过(19/19),有截图;`/experience-center` 与 `/prescreen-workbench`
只验证到"能被本次路由改动修好、能渲染",其自身交互没有逐项点过,**仍记 F11 未闭合**。
另外该脚本**不在 `verify.py` 里**,也就是说这条证据不会随强制门禁自动重跑——
它需要本机 Chrome 与一次性 `npm i --no-save puppeteer-core`。
- **浏览器验证只覆盖到"能走通"这一层**:没有做视觉回归(无基线截图比对)、没有多分辨率、
没有键盘可达性与屏幕阅读器检查。深色导航对比度仍是守卫内按 WCAG 实算,不是实测。
- **会议结果是模拟录入**:AC-56 验的是"录入后与材料版本对照"的机制,不是真实会议系统对接;
真实标签映射与客户身份权限仍待确认(M5/M6)。
- **对照样本是人工录入的 JSON**,不是真实保留集;`evaluation.independent` 仍是**客户端声明**
@@ -354,5 +384,5 @@ AC-53 又要求恰好三个模块入口。`AgentNav.tsx` 未改动。
(现有 API 测试以 `manager` 身份调用),**未擅自扩大改动**,留待确认。安全上真正关键的
"不自批"已由服务端强制(`must_not_self_approve` + `registry.release()` 的 `edited_by == actor`)。
- **题库/编排无真实发布入口**:已按 409 诚实拒绝,非假接通;需要时另行设计。
- **顺带发现、未修**:`backend/test_trajectory.py:173` 依赖 `recorded_at` 排序,两条记录落在
同一时钟刻度时顺序会翻转(本次全量跑中出现过一次,重跑即通过)。属既有测试脆弱性,非本批引入。
- **浏览器 E2E 尚未固化为项目门禁**:是否把它接进 `verify.py`、是否把 `puppeteer-core`
写进 `package.json`,是产品/工程决策,本批**没有替用户决定**,只提供可选脚本。