Files
ycode/docs/对话输入对齐复测与后续开发-2026-10-21.md
T

19 KiB
Raw Blame History

对话与输入对齐:Windows 复测与后续开发

后续由开发端修复、当前对话复测并规划,Git 交接统一使用 gitea/master。具体职责、记录模板与推送规则见开发与验收协作流程。本文保留针对 37ddb2c 的原始审查结论,不代表后续版本状态;A01~A09尚未因先前中止的本地修复而关闭。

日期:2026-10-21(Asia/Shanghai)。本轮任务是测试和更新开发指引,没有修改产品源码、安装版或用户数据,没有发起真实供应商模型请求,也没有提交、推送或合并分支。

1. 先确认测试的是哪个版本

实际审查的是 gitea/master / gitea/main 指向的 37ddb2c,不是当前本地 master 的 771ca54。

  • 771ca54:保存十项方案;本地工作目录 C:/Users/Administrator/code/YCode 和 origin/master 的本地跟踪记录均停留在此。
  • 308b98d:十项对齐实现;c7231be:实现与验收说明;37ddb2c:竞态与状态修复。
  • 三个新提交已经在本地 Git 对象库中。本轮在独立检出 C:/Users/Administrator/.codex/worktrees/workbuddy-alignment-audit/YCode 测试 37ddb2c,未切换原工作目录、未覆盖三个原有未跟踪文件。
  • 下文源码行号全部针对 37ddb2c。不能直接在旧 master 查同一行,再把已修复的旧问题重新列为缺陷。
  • 后续启动 dev 前先执行 git rev-parse --short HEAD;若仍是 771ca54,看到的不是本轮开发成果。此次没有自动合并或切换用户工作区。

目标仍以完整方案为准。开发方原报告位于审查版本的 docs/对话输入统一对齐实现与验收-2026-10-21.md;该报告已经说明授权 mock、像素及原版证据的边界,本轮不把其“部分实现”误读成“全量已验收”。

2. 结论与十项状态

当前是“核心结构和离线行为已落地,仍有可复现功能缺陷及明显样式差异”。绿色回归不能作为十项验收完成的依据。

方案项 本轮确认已实现或通过 仍不一致/未验收
会话加载 已消费 loading;不再误进首页;两组骨架;延迟 IPC 下标题和输入区保留;缓存/乱序/失败状态测试通过 骨架几何和原版不同;大历史只测了 Node 解析和 store,没有真实渲染帧耗时
模型选择 新增自动选择、编辑不抢选、空模型入口、legacy 鉴别、删除 reconcile 和 pending 保存竞态回归通过 未做真实供应商首发;不能从离线 registry 测试推导全部 UI/请求协议验收
权限保存与首发 factory 已传递并校验权限;权威保存值和设置序列化已有实现,离线首发/模式测试通过 客户端重启后的实际界面→真实内核首发仍待端到端验证
模式输入栏 plan/ask 可见、craft 隐藏、清除动作、权限禁用及偏好保留已接 Chip 的背景、圆角、图标与关闭按钮位置不符原版,见 A05
过程分组 全局 latest 过滤、单工具成组和 containsToolCall 强制折叠均已移除;局部顺序回归通过 外层收起重开会重置内层状态,见 A03
底部状态 已有真实本地 progress、等待问答/权限及终态清理,不再是全程固定文案 工具完成不退役、正文仍为思考、SDK 重试被忽略,见 A02;原版全阶段文案仍未完整恢复
问答展示 文本实际已为 14px/400/1.75;结构化答案投影及历史去重已有实现 原生大小写工具名漏分发,见 A01;灰卡层级与参考图不同,见 A04
完成态 默认完成折叠、正文锚点、实际终态时间已接 内层状态保持未达标;完整操作栏及同状态视觉仍未验收
授权卡及会话允许 卡片已换 Intercept 结构;主机侧有 session+workspace 隔离规则和重放;失败/取消等 mock 通过 详情不是浮层,默认选中表现仍有差异,见 A08;真实 SDK 匹配和重建效果未验收,见 A09
归档/删除 真实 Windows Electron 47 项行为通过:240px 右侧浮层、箭头、归档/删除实际落库等 按钮样式未生效、局部排版与文案有差异,见 A06;现有测试接受了这些差异

3. 下一轮必须处理的偏差

A01 — P1:原生 AskUserQuestion 没有进入专用问答卡

  • 位置:src/renderer/src/workbuddy/conversation/ToolCallRenderer.tsx:135 的 question 别名只有小写,:138 的 getCapturedToolKind 按大小写精确匹配。MessageBubble 分类时 lowercase,但渲染仍传原名。
  • 最小反例使用未导入的真实 SDK 名称 AskUserQuestion,带结构化答案和 RAW SDK ANSWER。实测结果:kind=undefined、专用问答卡不存在、原始 SDK 输出出现;换成 askuserquestion 才正确。整条 MessageBubble 也复现,不能只验投影数组。
  • 开发要求:在统一工具身份/别名层支持真实 SDK 名称;保持普通工具名称和原始历史不被误改。不要为了通过测试而只把 fixture 名称改成小写。
  • 验收:原生名称→回答完成→展开外层完成过程,应看到问题与回答卡,且没有原始工具输出;同时覆盖历史导入、小写别名、关联去重和无位置历史。
  • 证据:render-repro.log、repro.tsx。

A02 — P2:进度状态还没有闭环

三条独立的离线事件反例均复现,直接调用当前内核消息处理和共享 reducer,禁止启动 SDK query/CLI:

  1. 最后一个工具返回成功后,只发 tool_result,工具已为 ok,footer 仍为“正在运行 Read”。位置:claude-kernel.ts:823、src/shared/message-parts.ts:63。应按仍运行的工具集合退役状态,不能无条件覆盖另一个并行工具。
  2. 注入已安装 SDK 的真实 system/api_retry 事件形状后,events=[],旧工具状态不变。SDK 类型已有 attempt/max_retries/retry_delay_ms/error_status/no_response;这不是“没有数据源所以不实现”的情况。位置:claude-kernel.ts:667 的 system 分支和 src/shared/types.ts:225。
  3. message_start 后收到正文 text_delta,正文已经是 answer,状态仍为 thinking,footer 仍为“思考中”。位置:claude-kernel.ts:719、:738 及共享进度类型。

开发要求:补齐工具完成、模型输出、真实重试及恢复的状态转换;重试原因不明确或是限流时,不能统一描述成网络故障。等待用户/权限、取消及终态优先级要继续成立。原版词典和 reasoning-only 边界按既定 REA 证据恢复,不能将本地手写简化文案标成完整原版对齐。

验收至少覆盖工具结果→模型等待→正文→重试→恢复→终态,并穿插并行工具、审批、取消及乱序事件。证据:backend-progress.log、audit-backend-progress-builder.mjs。

A03 — P2:外层完成块切换会重置内层展开状态

  • 位置:CompletedFold.tsx:185 的展开态和 :211 起的收起态使用不同组件子树,切换造成内层重新挂载。
  • 用真实 CompletedFold+AskUserQuestion 的 DOM 反例:内层展开为 true→外层收起再展开→内层变 false。
  • 开发要求:按消息/part 的稳定身份保留工具、思考和局部摘要的状态;外层开关不能销毁用户的内层选择,也不能借修复恢复成全局一个展开布尔值。
  • 验收真实嵌套组件,不只验两个独立 LiveEventDisclosure;分别覆盖问答、工具、思考和局部摘要,以及后续事件到达后的稳定性。
  • 证据:fold-state.log、fold-state.tsx。

A04 — P2:已回答问答的灰卡包住了标题

  • 位置:conversation.css:343 把灰底、圆角、padding 施加在整个 .ask-user-question--completed;AskUserQuestion.tsx:97 的 section 同时包含标题和问答内容。
  • Windows 实测:整个卡片灰底,含 ?、“向用户提问”、+/- 及分隔线;外层 padding 为 8px 12px,问题区没有独立灰底。这与参考图“标题在灰卡外、仅问题/答案在卡内”不同。
  • 文本字号已经修好:实际问题与答案均为 14px/400/24.5px,不能继续报“仍12px/600”。
  • 开发要求:恢复 ToolExpandable 风格的标题与独立问答内容壳;仅内容区使用16px圆角、12px 16px内边距、原版主题色和滚动限制,移除无依据的旧 ?/+/- 结构与边框。
  • 证据:window-report.json 的 question、answered-expanded.png。为隔离此布局问题,窗口 fixture 使用已能命中 renderer 的小写别名;原生名称问题单独由 A01 覆盖。

A05 — P2:ModeChip 有功能,但外观和交互仍是本地版本

  • 位置:workbuddy/composer/ModeChip.tsx:5、mode-chip.css:1。
  • 实测已满足32px高、13px/500/20px文字、8px水平内边距和16px图标。不同处是常驻灰底、8px圆角、主文字颜色,以及在右上角额外出现的“×”。聚焦后原模式图标仍在,未切换成同位置关闭图标。
  • 既定原版要求是透明默认背景、pill 圆角、次级文字,hover/focus 后在图标槽位切换为 X;当前 SVG 源码也明确注释为 local geometry。
  • 开发要求:按已经记录的原版组件/SVG证据恢复,不只检查类名存在;保持 craft 隐藏、plan/ask 权限禁用、清除模式及草稿不丢。
  • 证据:window-report.json 的 mode/focusedMode、plan-focus.png。

A06 — P2:Popconfirm 的按钮没有获得对应样式

  • 位置:TaskPopconfirm.tsx:55 使用 wb-button--secondary/primary,但 portal 宿主没有使这些按钮变体的样式生效;task-popconfirm.css:30 只补了尺寸。已有 .wb-button 变体样式多在其他限定作用域,不能凭 class 名认定已经加载。
  • 稳定等待动画结束后实测:主按钮背景透明、文字黑色、圆角0;取消最小宽度仅52px,padding仅0 8px。原版要求的主/次/危险按钮视觉以及66px最小宽度、19px水平padding未恢复。
  • 同时实际浮层圆角12px、标题字重500;旧对齐计划的目标为16px圆角及600标题。额外 compatibility 说明使内容和高度也与此前确认的原文不同,不能计为全文1:1。
  • 开发要求:复用能在 portal 中正确加载的已验证按钮原语/样式作用域,修复变体和主题;保留240px、右侧锚定、点击吞掉、焦点、失败及忙状态行为。用户曾明确选择原版归档说明,额外解释应作为产品差异处理,不能暗中写进对齐通过项。
  • 测试盲区:现有 verify-task-menu.cjs 47项全绿,却只检查宽度/padding/圆角12px及行为,未检查主按钮背景、次按钮边框、最小宽度和标题字重。必须更正目标断言,不要让实际输出反向定义期望。
  • 证据:task-menu-report.json、window-report.json 的 popconfirm、archive-settled.png。原脚本的第一张抓图处于淡入中,故本轮另等透明度1并稳定后截图,未将抓图时机误报成透明度缺陷。

A07 — P2:加载行为已有,但骨架几何没有原样恢复

  • 位置:SessionLoading.tsx:12、session-loading.css:7。
  • Windows 延迟1200ms本地 IPC 实测:骨架可见、不显示首页、标题与输入区均在,属于已通过行为。
  • 实际名称占位64×14px,原版记录为80×12px;正文长度100%/100%/65%,原版为90%/70%/45%;当前用户占位和组间距也采用本地token重绘。不能仅凭“两组、1.5秒、300ms”认定样式一致。
  • 开发要求:按原DOM/CSS恢复尺寸、内外间距和淡出曲线,并测缓存到达及快速切换不闪屏。不要凭Node的10,000条消息解析/状态注入耗时宣称浏览器不卡;另测真实消息挂载、滚动和长任务。
  • 证据:window-report.json 的 skeleton/switching、loading.png。

A08 — P2:授权详情与默认选中展示仍有偏差

  • 位置:PermissionConfirm.tsx:177 将“查看拦截规则”展开成卡内普通 div,不是既定右上锚定规则详情浮层;permission-intercept.css:7 的入口实际12px,原版记录为14px/22px。
  • 实测卡片已是24px圆角、标题16px/500/25px、选项40px高/12px圆角,不能再报“仍是高额度卡或居中模态”。
  • 当前只以 hover/focus-visible 控制行背景和箭头,没有原版 defaultChoice 的稳定选中状态;鼠标路径进入 fixture 时第一行没有参考图的灰底/箭头。
  • 当前规则卡下仍保留完整独立输入框;参考图只有输入区授权卡。需补同状态布局验收,确认拦截卡替换/占位规则,不以纯SSR认定完成。
  • 开发要求:保留真实原因/规则详情,不编造命中规则;按原版恢复 headerAction 浮层与选中表现,同时保留安全请求的默认拒绝边界及数字键/焦点/失败行为。
  • 证据:window-report.json 的 permission/permissionRule、approval-rule.png。该窗口注入的是隔离审批快照,仅证明 renderer 布局,不证明规则匹配、工具执行或用户授权生效。

A09 — P1验收缺口,尚非已证故障:会话始终允许没有真实 SDK 匹配证据

  • 新版本已有 session-grants.ts 的进程内 session+workspace 隔离和 applyFlagSettings 重放,不能继续使用“完全没接/切换一定丢失”的旧结论。
  • 但 claude-grant-replay-regression.ts 和 policy fixture 替换了 query/apply 接口;claude-kernel-integration.ts:235 的 approval 回调还直接抛出 approval was not expected。因此绿色测试没有覆盖用户反馈的真实 SDK 路径。
  • 下一轮必须用独立工作区、真实本地SDK/CLI和可控loopback模型服务验证:一次允许后再问;会话允许后相同范围不问;不匹配范围及另一会话仍问;跨回合、切走返回、内核重建;显式询问/拒绝及plan/ask限制;更新失败、取消、重复/并发提交。
  • 验收证据应包括请求、响应和第二次工具是否触发审批,不能只检查 updatedPermissions 对象或按钮成功。不得用全工具白名单/字符串模糊匹配扩大范围来让测试变绿。
  • 客户端重启后的会话grant生命周期仍需原版证据;本轮不要求改成用户级/项目级永久授权。模式偏好持久化与会话grant生命周期是两件事。

4. 本轮测试结果及其证明范围

命令/验证 结果 能证明什么
npm run build(含typecheck) 通过 Windows依赖下可编译、构建;不证明交互或授权
npm run test:alignment 通过 离线模型、会话状态、投影及宿主/SDK接口mock
设置 YCODE_TEST_DOM_MODULE 后 npm run test:alignment 通过,28任务确认+24问答+14授权DOM检查 jsdom行为,无真实布局/SDK匹配
npm run test:chat、test:sessions、test:persistence、test:model-metadata 均通过 当前对应状态/存储回归
npm run test:conversation、test:assistant-footer、test:tool-approvals 均通过 现有SSR/纯状态断言,不能否定A01~A09
node scripts/verify-task-menu.cjs Windows Electron 47项通过,0个renderer错误 本地真实主进程/preload/文件系统上的菜单、归档、删除;不等于样式一致
自定义窗口probe 通过执行,0个renderer错误,记录了偏差 1336×902、隔离数据、延迟IPC及审批快照下的计算样式/截图
问答分发/内层状态/progress最小反例 均复现偏差 A01、A02、A03具有当前代码可重复证据;probe退出0表示执行成功,不表示产品行为正确
npm run check:tokens 失败:相同6项既存问题 在原始771ca54和审查37ddb2c分别运行,失败集合相同;未刷新baseline、未放宽门禁
npm run test:fold-summary 隔离检出失败:CRLF摘要不匹配 core.autocrlf=true使生成模块出现717个CRLF。归一LF后的SHA与manifest、原工作区相同;是可复现性问题,非折叠算法回归

token既存问题:recommended-flow、skill-detail-shell、skills-host、capability-picker、composer、prompt-queue六份CSS。后续应按来源/token规范处理,不能整体update-baseline把问题隐藏。

fold-summary建议为生成证据模块声明LF并补干净Windows checkout验收;保留摘要校验,不以删除hash断言“修复”。本轮未修改生成物、manifest或行尾。

5. 建议的继续开发顺序与关闭条件

  1. 先消除A01并补真实名称渲染回归,再闭合A02事件状态机。 不再重复实现已修复的factory、模型选择及全局分组问题。
  2. 修A03稳定挂载和A04问答内容壳。 一条真实SDK名字轨迹贯穿提问、回答、完成、展开、外层收起重开,避免各组件测试通过而整条链路失败。
  3. 修A06按钮样式、A05模式Chip、A07骨架和A08授权详情/布局。 先验证CSS作用域和主题实际命中,再做几何及截图对照,不能仅增加同名class。
  4. 单列A09真实SDK验收。 通过匹配/不匹配与重建矩阵后,才可以宣称“本次会话始终允许已修复”;仍有原版生命周期未知时保留明确边界。
  5. 补发布验收环境。 干净Windows checkout、真实大历史渲染、深色/窄窗、共享Popover回归及token门禁分别留证。当前没有同版本原版成对运行截图,不作逐像素通过结论。

测试和修复应在37ddb2c或包含它的后续版本进行。保留本报告编号,将每项标记为“待修复/修复后待验/已验证关闭”,关闭时填写提交、命令、场景及证据,不用一条“全部测试通过”覆盖所有状态。

6. 本地证据与复现入口

本轮证据已复制到原工作目录的 .tmp/workbuddy-alignment-audit-20261021/,独立检出保留未归档。.tmp 不随Git提交,交接时需单独复制,不能只交接本文。

  • build.log、alignment.log、alignment-dom.log、tokens.log、tokens-baseline-771ca54.log、task-menu.log:主对话实际命令输出。
  • render-repro.log、fold-state.log、backend-progress.log:最小反例输出;对应源码为 repro.tsx、fold-state.tsx、audit-backend-progress-builder.mjs。
  • window-report.json:原生Windows窗口计算样式;task-menu-report.json:47项菜单行为结果。
  • 加载截图、模式标签聚焦、已回答记录展开、稳定后的归档浮层、授权详情展开。
  • window-probe.cjs:通过临时userData和workspace启动真实应用;延迟本地IPC,注入明确的审批fixture;未调用真实模型或审批确认按钮。

在隔离检出中可重跑 node .tmp/alignment-audit-20261021/window-probe.cjs。其余反例位于该检出的 .tmp/audit-render/ 与 .tmp/audit-backend-progress-builder.mjs。DOM环境使用 .tmp/alignment-audit-dom/node_modules/jsdom;该路径设置为 YCODE_TEST_DOM_MODULE 后可重跑可选DOM回归。

本轮没有新增WorkBuddy原版证据;差异判断引用完整方案及用户截图,不读取原版安装包、脚本导出或调试端口。本轮窗口和反例只操作YCode隔离测试环境。真实SDK匹配、当前原版运行对照、像素及安装发布均明确未验收。