docs(B01): record scoped delivery and offline acceptance evidence

This commit is contained in:
Codex committed 2026-10-21 13:13:49 +09:00
1 parent 51531dcae8
commit ec99ecc656
2 files changed
+117

No files matched your search

+60
View File
@@ -0,0 +1,60 @@
# B01 交付 01:问答分发、嵌套折叠与回答内容壳
日期:2026-10-21。开发端接单;**已实现、离线自测通过,待指定提交的独立验收,不关闭 A01/A03/A04**。
## 范围、授权与版本
- 用户确认:开发端先接 A01、A03、A04 问答与折叠修复;保留撤回骨架修复的决定。用户答复“对”。
- 基线完整 SHA:`21ca0e0fc379e7a71639b5160c1b7cd168b9d6fa`,开始时 master 源码工作区干净。
- 需求入口:[Windows 复测与后续开发](../对话输入对齐复测与后续开发-2026-10-21.md) A01、A03、A04;[完整方案](../WorkBuddy对话与输入交互统一对齐方案-2026-10-21.md) 第三节;协作流程见同目录文档。
- **完整代码 SHA:`51531dcae8d8ade85db9e203bc8c0f712805b2ae`。** 开发主对话与独立代码审查已完成;本记录另行文档提交,代码提交不包含本记录。
- 唯一交接源 `gitea/master`;推送状态以交接通知及远端 SHA 核验为准。验收应等待开发端明确通知代码 SHA。
- 不做:A02、A05~A09;不恢复撤回的 `6956e47` 骨架补丁;不改内核、依赖锁文件或历史数据;不启动外部模型、SDK query/CLI 或真实授权服务。
## 改动与实现边界
- A01:共享 `isQuestionToolName` 做只读身份匹配,原生 `AskUserQuestion` 和既有小写别名进入问答卡;MessageBubble 分类与 renderer 使用同一身份层。普通工具仍走原匹配/原始输出通道,存储名称、参数、metadata 不被改写。既有投影、历史导入和未知位置算法未修改。
- A03:CompletedFold 持有仅属于该消息的 disclosure store;按稳定 part/tool ID 与控件槽位保存状态,无 ID 的旧 part 保留位置 fallback。问答、普通工具、思考、局部摘要、MCP 明细、Task 与 Plan 展开状态在外层结构重排后恢复;不同消息不共享。仍采用既有时间顺序/正文锚点模型,不复制隐藏组件树、不恢复全局展开布尔值。Task 审批状态未迁移或放宽。
- A04:标题使用既有 SourceToolHeader/chevron,位于独立问答内容壳外;去掉旧 `?`、`+/-`、外层灰底与分隔边框。内容复用已恢复 ToolExpandable CSS:16px 圆角、12px 16px padding、主题背景、300px 上限和纵向滚动。保留问题/答案 14px、400、1.75;键盘 Enter/Space、aria-controls、aria-hidden、inert 均有回归。
- 原版依据仅引用已有证据:WorkBuddy 5.8.3 目标截图及历史 5.8.2 REA 提取范围;`tool-result-source.css` 中 JavaScript Evidence `ev_717fa5e846e64d67ac19c8925d121bff632c0d3aefb3603b10858559cabb2dcb`,CSS Evidence `ev_377c8790468b3c67dad8577aabb327f98d3140659f0fffdbabfcff5a40cc9e94`。未新增原版采集,也未直接读取原版安装包或调试端口。
## 验收矩阵与复现
| 项目 | 可重跑场景/证据 | 本轮状态 |
| --- | --- | --- |
| A01 原生名称完整链 | `question-identity-regression.tsx`:真实 MessageBubble,原生名称待答→已答→完成→展开→收起重开,无 RAW SDK ANSWER | jsdom 已通过;真实 Windows 待验 |
| A01 兼容与不可变性 | 原生/小写别名、导入答案、关联去重、无 parts 未知位置标签与单份展示;普通工具原始输出和输入快照不变 | SSR+jsdom+导入回归通过 |
| A03 嵌套状态 | `completed-fold-nested-regression.tsx`:真实 CompletedFold+问答/普通工具/ThinkingBlock/ToolGroup/Task/Plan,外层切换、后续事件、独立局部组、流式→完成、消息 ID 隔离 | jsdom 已通过;真实 Windows 待验 |
| A03 可访问性 | 外层 Enter/Space 切换,收起内容 inert/aria-hidden;不复制问答节点 | jsdom 已通过 |
| A04 内容壳 | `question-answer-shell-regression.tsx`:标题不在内容壳内、复用 CSS 参数及主题变量、无旧符号/边框;链接与键盘行为 | SSR/CSS 来源断言+jsdom 通过;非布局像素结果 |
| 整体构建 | `npm run build` 含两个 tsconfig 类型检查 | Linux 通过,不代表 Windows 安装/Electron 通过 |
| Windows/原版对照 | 固定代码 SHA、浅/深主题、窄窗、相同窗口/缩放/字体、回答长内容滚动 | **未验证,待验收端** |
## 环境与命令
Linux x86_64,Node `v24.19.0`,npm `11.9.0`。主项目使用已安装依赖(此前 ignore-scripts 安装,Electron 无 GUI);没有更改 package.json/package-lock.json。DOM 依赖 jsdom `30.1.3` 独立安装在 `/tmp/ycode-b01-dom`,`--ignore-scripts`,不混入交付依赖。DOM 依赖从官方 npm 安装;测试运行不调用外部模型。
```sh
# 仅验收者缺少 DOM 依赖时,按其安装授权独立安装;不改项目依赖
npm install --prefix /tmp/ycode-b01-dom --ignore-scripts --no-audit --no-fund jsdom@30.1.3
YCODE_TEST_DOM_MODULE=/tmp/ycode-b01-dom/node_modules/jsdom npm run test:alignment
npm run test:conversation
npm run test:workbuddy-import
npm run test:artifacts
npm run build
git -c core.whitespace=cr-at-eol diff --check
```
以上最终命令退出 0。对齐 runner 的宿主/SDK 接口部分是 mock,明确不启动真实 SDK/CLI;运行这些测试不构成 A09 授权验收。新 DOM 脚本等待断言、unmount 与 DOM close 后显式退出,避免既有 renderer imports 的长驻句柄使成功测试超时。两份原有 CRLF 源文件保持行尾;diff 检查用单次 `cr-at-eol` 选项,未改 Git 全局配置或批量归一化。
可复核证据:[本轮命令及输出摘要](evidence/B01-01/verification.txt),测试源码均纳入交付,不依赖开发机 `.tmp` 作为唯一证据。初次开发中的类型错误、测试选择器错误和测试退出句柄问题已修正并重跑;最终结果以该摘要与指定代码 SHA 为准。
## 独立 Windows 验收步骤与阻塞
1. 收到完整代码 SHA 后,在干净的固定 SHA 检出独立 `npm ci --legacy-peer-deps`、`npm run build`,记录系统/Node/npm/目录/实际启动端口。
2. 真正启动前检查 `src/main/index.ts` 数据初始化逻辑;在同一 PowerShell 中设置全新绝对 `YCODE_USER_DATA_DIR`(如 `C:\ycode-qa\B01-run01`),只用脱敏夹具和专用 workspace,确认进程继承变量。
3. 重跑上述离线测试;以原生名称构建待答/已答消息,完成后打开外层,分别操作问答、工具、思考、两个局部摘要,再收起重开并追加事件;确认选择独立保留、正文顺序未变。
4. 用真实 Windows Electron 计算样式与截图复核 A04:标题在灰卡外、问题/答案 typography、16px/12px 16px、长内容滚动,浅深色及窄窗;对照既定原版版本/同状态截图。
5. 原 Windows `window-report.json`、`answered-expanded.png` 等只在历史 `.tmp` 中,本环境没有这些附件。请验收端提供/定位原附件并记录 REA/截图索引;未拿到相应证据不得宣称完整 1:1 或像素通过。
状态:**已本地提交、待推送通知与独立验收**。本批实现无 mock 问答替代逻辑;测试夹具是模拟消息,不是真实模型请求。Windows、安装包、真实 SDK 与当前原版像素对照均未执行。
@@ -0,0 +1,57 @@
B01-01 offline verification — 2026-10-21
Baseline: 21ca0e0fc379e7a71639b5160c1b7cd168b9d6fa
Code SHA (same tested source): 51531dcae8d8ade85db9e203bc8c0f712805b2ae
Linux x86_64; Node v24.19.0; npm 11.9.0; external jsdom 30.1.3.
No Electron GUI / Windows / model / SDK query / pixel acceptance.
$ YCODE_TEST_DOM_MODULE=/tmp/ycode-b01-dom/node_modules/jsdom npm run test:alignment
exit: 0
PASS model alignment: fresh/legacy migration, new/edit/default/delete/reload, valid selection (offline host fixtures)
PASS model settings: deferred owner switch, rename mapping, addition selection, empty deletion, immutable history
PASS session factory: first-send preference, mode preservation, invalid permission rejection (isolated ports)
{"historyMessages":10000,"bytes":747781,"parseMs":2.793482999999995,"storeHydrationMs":0.12718700000000638,"note":"Node parsing/store benchmark only, not browser rendering or Windows IPC performance"}
session-composer-alignment: loading/cache/retry/races/model/permissions/modes/SSR passed
alignment-conversation: local groups, original expanded order, question projection and truthful status passed
A01 native MessageBubble identity aliases, immutable inputs and ordinary raw output passed
A01 imported native card, linked dedup and unknown-position compatibility passed
question-answer-shell: structural and recovered CSS contracts passed
question-answer-shell: DOM hierarchy, controls linkage, click, Enter, Space and inert contracts passed
Runtime progress, session-grant scope and approval lifecycle regressions passed
Permission intercept static rendering passed; interactive keyboard/focus remains UI acceptance
Claude host approval policy unit checks passed (no SDK process/application/matching verification)
Mock SDK replay lifecycle passed: fail closed, retry, session isolation, independent mode guard
task popconfirm DOM regression: 28 checks passed (jsdom, not pixel validation)
question-interaction: 24 DOM behavioral checks passed
question-identity: 30 A01 DOM checks passed (not Electron/pixel/SDK acceptance)
completed-fold-nested: real question/tool/thinking/local-summary remount, event, keyboard and identity contracts passed
Permission intercept DOM: 14 checks passed (not pixel/SDK verification)
$ npm run test:conversation
exit: 0
Conversation specialized renderer SSR regression checks passed
Composer/message action regression cases passed
streaming-footer-regression: persistent stream status, delayed/paused rotation, brand/locale mapping, source CSS, and completed model footer passed
Completed-fold model and SSR regression checks passed
$ npm run test:workbuddy-import
exit: 0
WorkBuddy import regression passed
$ npm run test:artifacts
exit: 0
Artifact diff recovery regression checks passed
Artifact routing, content loading, full write projection and renderer regressions passed
Specialized block icon and label SSR regression checks passed
$ npm run build
exit: 0
Includes: tsc --noEmit -p tsconfig.node.json && tsc --noEmit -p tsconfig.web.json
✓ 444 modules transformed.
✓ built in 226ms
✓ 2 modules transformed.
✓ built in 11ms
✓ 3039 modules transformed.
✓ built in 1.88s
$ git -c core.whitespace=cr-at-eol diff --check
exit: 0; no output. Existing CRLF retained.