fix(android): 下单前规格复核统一括号与空白规范化,只认已选中的规格选项 #374

Open
opened 2026-10-09 12:05:35 +08:00 by ila · 4 comments
Owner

This was generated by AI during triage.

基本信息

  • 类型:缺陷(Android 采购:下单前最后一道规格复核误判,规格正确时也报 PURCHASE_SPEC_NOT_MATCHED)。
  • 风险等级:高(这道复核紧挨创建订单,改动直接影响能否下单、会不会下错)。实施、装机和真机验证都需要用户另行确认。
  • 状态:已合并并推送 main,联合验证通过,待真机验收;未安装、未发布。2026-10-09 用户在 v2 复审后授权「补充工单」;此前仅授权补方案与验收;2026-10-09 用户现已明确授权按 v3 实施、测试、提交和推送,不包含安装、真实采购、合并及发布。2026-10-09 用户确认「把 Codex 的意见并入 #373 和 #374 正文」,方案与验收已按 Codex 审核(SynapBus #123/#124)和评论 9065 修订。
  • 来源:2026-10-09 用户要求分析「最后一批的 7 个采购任务重试都失败」的原因。Claude Code 分析后,用户确认:「1和2建工单」(本单为第 2 项)。
  • 关联:#373(正式采购阶段复用其他任务商品页,第 1 项)。

已核验事实

线上数据与失败现场(只读,2026-10-09)

  • 任务 2128(attempt 4133)和 2126(attempt 4140)都是 PURCHASE_SPEC_NOT_MATCHED「创建订单前规格复核失败」。现场在 PDD 下单面板上,颜色和尺码都已正确选中(选项 selected=true),已经走过地址修改和前面所有复核。
  • 现场「已选」文字是 已选: [纯白]RW圆领 3XL码[145-165斤]、已选: [香槟]RW圆领 L码[105-115斤]:PDD 把规格里的全角【】显示成了英文 [ ](逐字符核对过,是 0x5B/0x5D)。下发的规格是 【纯白】RW圆领 / 3XL码【145-165斤】 和 【香槟】RW圆领 / L码【105-115斤】。
  • 此时颜色选项已滑出可视区域,visible-to-user=false;尺码选项可见。
  • 2130、2129 在更早的重试中也多次报同样的错误码,规格同样带【】(【新品闪购*夏日大卖】黑色 等),推测原因相同;那几次的快照没有查看,未证实。
  • 快照只在本机解析规格面板文字,未输出地址和姓名,用完已删除。

代码事实(origin/main e26743c817275137f7dc8a3659461d552371b9e3)

  • PurchaseLiveAutomation.kt:323-327 finalConfirmation:对 mappedColor、mappedSize 各自判断「selectedSummary 包含原文」或「任意可见控件文字包含原文」,都不满足就失败。比较不做任何规范化。
  • 所以:颜色在「已选」里因【】/[ ] 不同匹配不上,颜色选项又不可见 → 失败。
  • 前面的 VERIFY_ORDER_SUMMARY(PurchaseRehearsalExecutor.verifySummary)用规范化目标和点击时记录的精确选中证据,已经通过。两处判断标准不一致。
  • 另一个方向的问题:「任意可见控件包含原文」过于宽松。页面上的推荐商品标题、活动文案等只要包含规格原文(例如短尺码「M」「L」或常见颜色「黑色」),就会让复核通过,即使规格实际没有选中。
  • 解析器把选项的选中状态按 selected || checked 处理,并聚合子节点状态(PddProductDetailCollector.kt:279-280、:401)。
  • selectedSummary(PddProductDetailCollector.kt:544-547)取的是全屏可见文字中第一个以「已选」等前缀开头的文字,没有限定在当前规格面板内。

目标

  1. 规格确实选中时,最后一道复核不因【】/[ ]、全角半角或多余空格的差异而失败。
  2. 复核不能因为页面上其他无关文字碰巧包含规格值、或只匹配到规格的一部分而通过。

非目标

  • 不改前面的规格选择、verifySummary、地址、价格、数量和提交按钮的判断。
  • 不改 normalizeColor、normalizeSize 等现有公共规范化函数(它们影响采集、候选查找和点击)。
  • 不使用 attempt 内的历史选中证明,不扩大本单范围。
  • 不改商品页复用(#373),不处理其他根因未明的点击失败(如 2131)。
  • 不改服务端、API、数据库和 Web。
  • 不实现任何支付动作。

方案(v3,补齐面板范围、摘要适用条件与确定性边界)

  1. 新增仅供最终复核使用的规范化函数,只做:全角【】〔〕[]()转成对应英文括号;全角字母、数字和空格转半角;连续空白合并为一个空格;去掉首尾空白。不删除括号内容,不做同义词、大小写折叠或通用 NFKC 等额外等价。
  2. 先确定当前完整规格面板范围,再逐维度判断:
    • ParsedPddScreen.specPanelContainer 在当前代码中赋值为 panelScrollable(规格滚动区域),不等于整个规格面板。摘要可能位于滚动区域上方或同一弹层中的兄弟节点;非滚动面板也可能没有该容器。以既有页面结构证据识别受限的完整面板范围,不得直接要求摘要必须是滚动容器的子节点,也不得退化为全屏或根节点搜索。无法可靠确定归属时,不使用该摘要;当前可确认的面板内选项证据仍按下述规则判断。补正常滚动、摘要在滚动区外、无滚动确认面板的夹具,不改变原采集解析行为。
    • 仅检查下发值非空的维度,按如下顺序判断;原本不需要某个维度时不虚构该维度。
    1. 冲突/歧义优先:先按现有解析器完成同一物理选项的父子聚合;规范化后的同维度非目标值明确处于选中状态(selected || checked)时直接失败,摘要不能覆盖。仅括号/全半角显示差异本身不算非目标冲突。若发现多个不同实际候选归一化为同一目标值、或已有候选证据表明摘要可以分解为不同规格组合,则按歧义拒绝,不选第一个;同一选项的父子文本重复不算多个候选。目标已明确不可选时也拒绝。
    2. 选项证据:当前规格面板内,同维度有处于选中状态的选项,规范化后与目标完全相等 → 该维度通过。不再扫描面板外的任意控件。
    3. 摘要证据:第 2 步未取得目标选中证明,但没有第 1 步的明确冲突/不可用/歧义时,可使用唯一可信的面板内摘要;不要求该维度完全没有可见选项。目标颜色滑出视口、其他未选中颜色仍可见,或控件没有暴露选中标志,均不能仅因此禁用摘要;不能把未暴露选中标志直接当作已选中另一个值。
      • 仅从开头去掉已识别的「已选」前缀及其紧随的可选 :/:、外围空白,再按专用规则规范化;不删除规格正文中的冒号、逗号、括号或内容。不新增全屏无前缀文本兜底;已有无前缀摘要只有在现有结构识别及本单完整面板归属均成立时才可使用。
      • 颜色和尺码都非空时,整段必须等于按已证实页面顺序组合的完整值,中间限定单个空格或单个逗号;不凭猜测枚举顺序。单个维度非空时,整段必须恰等于该完整值,不追加分隔符。不得拆开规格正文中的空格或逗号;不得删除数量后缀来强行相等。两维都空不构造空摘要成功证明,维持原规则资格限制。
      • 多个不一致的面板内摘要、已知规范化碰撞或组合歧义均拒绝;不宣称缺失候选数据时整段字符串相等能证明所有潜在 SKU 身份。多出/缺少内容均失败,不做子串匹配,不使用历史 attempt 证明。
    4. 其余情况一律失败,报 PURCHASE_SPEC_NOT_MATCHED。错误信息附上不含页面文字的诊断:哪个维度、走到哪一步、是否有面板内摘要、是否找到选中项、是否有冲突。
  3. 示例:本次现场「已选: [香槟]RW圆领 L码[105-115斤]」规范化后整段等于「[香槟]RW圆领 L码[105-115斤]」,通过。目标「黑色 + XL」遇到摘要「黑色 加绒 XL」不通过,因为实际颜色可能是「黑色 加绒」。

子项目影响、依赖与并行

  • Android:PurchaseLiveAutomation.kt、SpecValueNormalizer.kt(只新增函数)、必要时 PddProductDetailCollector.kt(只读取面板内摘要和选项,不改现有解析行为),以及对应测试。
  • Server/Web:无。数据库、API:无。
  • 无前置依赖;与 #373 可并行,合并时注意冲突。Codex 建议先实施 #373。

设计证据

非 UI 改动,无需原型;以本正文为准。

验收标准

以下勾选代表合成自动化及受影响回归完成,不代表真机采购验收。

  • 单元测试(用本次现场的脱敏形态构造):「已选: [香槟]RW圆领 L码[105-115斤]」在面板内 + 颜色选项不可见 + 尺码选项已选中 → 通过。
  • 单元测试:只有 checked、没有 selected 的目标选项 → 通过。
  • 单元测试:同维度另一个值处于选中状态,即使摘要匹配 → 失败。
  • 单元测试:「已选」里是另一个颜色(如 [纯白]RW圆领)→ 失败。
  • 单元测试:摘要不在规格面板内(面板外的伪摘要)→ 不作为证据。
  • 单元测试:同前缀的长规格——目标「黑色」遇到选项或摘要「黑色 加绒」→ 不通过;【白色】 不匹配 [白色+黑色]超值两件装;尺码 L 不匹配 XL。
  • 单元测试:规格正文带内部空格或逗号(如 2xl 110-125斤、黑色,加绒)→ 按完整值比较,正确通过或拒绝。
  • 单元测试:同一实际选项及目标的【】/[ ]显示差异 → 可匹配;多个不同实际候选规范化为同一目标值 → 歧义拒绝;同一选项父子文本重复按既有聚合处理,不能误算碰撞。
  • 单元测试:摘要位于滚动区域上方/兄弟节点但属于完整面板 → 可用;真正面板外伪摘要 → 不可用;无滚动面板按真实结构范围判断。
  • 单元测试:目标颜色不可见、其他未选中颜色可见,可信整段摘要完全一致 → 可通过;另一个颜色明确被选中 → 即使摘要一致也拒绝。
  • 单元测试:只有颜色、只有尺码时整段等于单一完整值 → 通过;多余维度/数量后缀、多个不一致摘要、已知组合歧义 → 拒绝。
  • 单元测试:「已选」「已选:」「已选:」前缀及外围空白按规则处理,规格正文内的冒号/空格/逗号保持原义,不靠拆词比较。
  • 单元测试:「已选」缺失,页面上只有推荐商品标题包含规格值、没有选中的选项 → 失败(原逻辑会通过)。
  • 回归:数量、地址、价格的拒绝路径和现有 finalConfirmation 测试保持通过;现有 normalizeColor/normalizeSize 测试不变;Android 构建通过,如实记录。
  • 真机验证需用户另行授权(正式采购可能真实下单);未执行时如实记录。

待实施时确认

  • PDD 摘要里颜色和尺码之间的分隔方式。本次现场只有空格一种,其他形态(逗号、带数量后缀等)需要用现有夹具或真机确认。不符合时一律失败,宁可误拦,不可误放。
  • 完整面板的结构归属须有既有夹具/真机证据,不能将现有 specPanelContainer 的滚动区域当作完整弹层。新增范围识别仅服务最终复核,若证据不足明确记录不支持场景,不扩大到通用解析器重构。
  • 双维摘要顺序及允许的逗号形态须有夹具依据;没有证据不自行扩大格式。整段比较与冲突优先的范围、成功及拒绝案例应在实施测试中逐项兑现。

风险与回退

  • 规范化过宽会让不同规格被当成相同;本方案只统一括号、全半角和空白,要求完全相等或整段相等,并且冲突优先。
  • 收紧后,原来靠无关文字「碰巧通过」的情况会改为失败;摘要格式与预期不同也会失败。失败率可能短期上升,但这是更安全的方向。
  • 回退:恢复原比较逻辑;无数据迁移。

文档影响

  • 更新 Wiki Business-Rules-and-Glossary(采购执行):下单前规格复核的判断顺序(冲突优先、面板内选中选项、面板内摘要整段相等)和规范化范围。
  • 先改线上 Wiki 并回读 revision,再执行一次 sync 与 sync --check。

备注

本单由 Claude Code 依据线上只读查询、失败现场快照(本机解析后已删除)、代码阅读和 Codex 审核意见起草;不含账号、地址、Cookie 或 Token。

实施结果(2026-10-09)

实现 6f1af70d0d2a4c70c31ba42e05c4321f08c6a78e,Wiki 镜像 1c67f3f;分支 fix/374-final-spec-confirmation 已推送。仅 Android 最终规格复核及相应测试改变,独立基于 main e26743c,不包含 #373。366项受影响单测通过、debug构建与release单测编译通过;规格及代码质量独立复审通过。完整单测因未修改的图搜返回测试忙循环而中止,未宣称全量通过。

最终选项沿用解析后的 text(既有 UI 尾价分离),再执行本单窄规范化;摘要与目标不新增内容删除。当前有证据支持的双维摘要只有颜色在前、空格分隔,不支持逗号或反序猜测。详情及未验证项见交付评论。工单保持待验收。

合并 main(2026-10-09)

用户授权按 #373 → #374 → 处理镜像冲突 → 联合回归与构建 → 推送 main 执行。main 合并提交 555a954605a83c12457ed1ada86eb732fe3bb023,最新文档提交 3ee8dfc0aa93ef9020786244cce29c487631ddbe,远端已确认。联合25套件478项全通过,APK构建与release单测源码编译通过。未安装、未执行真实采购、未部署或重启服务;工单仍待人工验收。

> *This was generated by AI during triage.* ## 基本信息 - 类型:缺陷(Android 采购:下单前最后一道规格复核误判,规格正确时也报 `PURCHASE_SPEC_NOT_MATCHED`)。 - 风险等级:**高**(这道复核紧挨创建订单,改动直接影响能否下单、会不会下错)。实施、装机和真机验证都需要用户另行确认。 - 状态:**已合并并推送 main,联合验证通过,待真机验收;未安装、未发布**。2026-10-09 用户在 v2 复审后授权「补充工单」;此前仅授权补方案与验收;2026-10-09 用户现已明确授权按 v3 实施、测试、提交和推送,不包含安装、真实采购、合并及发布。2026-10-09 用户确认「把 Codex 的意见并入 #373 和 #374 正文」,方案与验收已按 Codex 审核(SynapBus #123/#124)和评论 9065 修订。 - 来源:2026-10-09 用户要求分析「最后一批的 7 个采购任务重试都失败」的原因。Claude Code 分析后,用户确认:「1和2建工单」(本单为第 2 项)。 - 关联:#373(正式采购阶段复用其他任务商品页,第 1 项)。 ## 已核验事实 ### 线上数据与失败现场(只读,2026-10-09) - 任务 2128(attempt 4133)和 2126(attempt 4140)都是 `PURCHASE_SPEC_NOT_MATCHED`「创建订单前规格复核失败」。现场在 PDD 下单面板上,颜色和尺码都已**正确选中**(选项 `selected=true`),已经走过地址修改和前面所有复核。 - 现场「已选」文字是 `已选: [纯白]RW圆领 3XL码[145-165斤]`、`已选: [香槟]RW圆领 L码[105-115斤]`:PDD 把规格里的全角【】显示成了英文 `[` `]`(逐字符核对过,是 0x5B/0x5D)。下发的规格是 `【纯白】RW圆领` / `3XL码【145-165斤】` 和 `【香槟】RW圆领` / `L码【105-115斤】`。 - 此时颜色选项已滑出可视区域,`visible-to-user=false`;尺码选项可见。 - 2130、2129 在更早的重试中也多次报同样的错误码,规格同样带【】(`【新品闪购*夏日大卖】黑色` 等),推测原因相同;那几次的快照没有查看,未证实。 - 快照只在本机解析规格面板文字,未输出地址和姓名,用完已删除。 ### 代码事实(`origin/main` `e26743c817275137f7dc8a3659461d552371b9e3`) - `PurchaseLiveAutomation.kt:323-327` `finalConfirmation`:对 `mappedColor`、`mappedSize` 各自判断「`selectedSummary` 包含原文」**或**「任意可见控件文字包含原文」,都不满足就失败。比较不做任何规范化。 - 所以:颜色在「已选」里因【】/[ ] 不同匹配不上,颜色选项又不可见 → 失败。 - 前面的 `VERIFY_ORDER_SUMMARY`(`PurchaseRehearsalExecutor.verifySummary`)用规范化目标和点击时记录的精确选中证据,已经通过。两处判断标准不一致。 - 另一个方向的问题:「任意可见控件包含原文」过于宽松。页面上的推荐商品标题、活动文案等只要包含规格原文(例如短尺码「M」「L」或常见颜色「黑色」),就会让复核通过,即使规格实际没有选中。 - 解析器把选项的选中状态按 `selected || checked` 处理,并聚合子节点状态(`PddProductDetailCollector.kt:279-280`、`:401`)。 - `selectedSummary`(`PddProductDetailCollector.kt:544-547`)取的是**全屏**可见文字中第一个以「已选」等前缀开头的文字,没有限定在当前规格面板内。 ## 目标 1. 规格确实选中时,最后一道复核不因【】/[ ]、全角半角或多余空格的差异而失败。 2. 复核不能因为页面上其他无关文字碰巧包含规格值、或只匹配到规格的一部分而通过。 ## 非目标 - 不改前面的规格选择、`verifySummary`、地址、价格、数量和提交按钮的判断。 - 不改 `normalizeColor`、`normalizeSize` 等现有公共规范化函数(它们影响采集、候选查找和点击)。 - 不使用 attempt 内的历史选中证明,不扩大本单范围。 - 不改商品页复用(#373),不处理其他根因未明的点击失败(如 2131)。 - 不改服务端、API、数据库和 Web。 - 不实现任何支付动作。 ## 方案(v3,补齐面板范围、摘要适用条件与确定性边界) 1. **新增仅供最终复核使用的规范化函数**,只做:全角【】〔〕[]()转成对应英文括号;全角字母、数字和空格转半角;连续空白合并为一个空格;去掉首尾空白。不删除括号内容,不做同义词、大小写折叠或通用 NFKC 等额外等价。 2. **先确定当前完整规格面板范围,再逐维度判断**: - `ParsedPddScreen.specPanelContainer` 在当前代码中赋值为 `panelScrollable`(规格滚动区域),**不等于整个规格面板**。摘要可能位于滚动区域上方或同一弹层中的兄弟节点;非滚动面板也可能没有该容器。以既有页面结构证据识别受限的完整面板范围,不得直接要求摘要必须是滚动容器的子节点,也不得退化为全屏或根节点搜索。无法可靠确定归属时,不使用该摘要;当前可确认的面板内选项证据仍按下述规则判断。补正常滚动、摘要在滚动区外、无滚动确认面板的夹具,不改变原采集解析行为。 - 仅检查下发值非空的维度,按如下顺序判断;原本不需要某个维度时不虚构该维度。 1. **冲突/歧义优先**:先按现有解析器完成同一物理选项的父子聚合;规范化后的同维度非目标值明确处于选中状态(`selected || checked`)时直接失败,摘要不能覆盖。仅括号/全半角显示差异本身不算非目标冲突。若发现多个不同实际候选归一化为同一目标值、或已有候选证据表明摘要可以分解为不同规格组合,则按歧义拒绝,不选第一个;同一选项的父子文本重复不算多个候选。目标已明确不可选时也拒绝。 2. **选项证据**:当前规格面板内,同维度有处于选中状态的选项,规范化后与目标**完全相等** → 该维度通过。不再扫描面板外的任意控件。 3. **摘要证据**:第 2 步未取得目标选中证明,但没有第 1 步的明确冲突/不可用/歧义时,可使用唯一可信的面板内摘要;**不要求该维度完全没有可见选项**。目标颜色滑出视口、其他未选中颜色仍可见,或控件没有暴露选中标志,均不能仅因此禁用摘要;不能把未暴露选中标志直接当作已选中另一个值。 - 仅从开头去掉已识别的「已选」前缀及其紧随的可选 `:`/`:`、外围空白,再按专用规则规范化;不删除规格正文中的冒号、逗号、括号或内容。不新增全屏无前缀文本兜底;已有无前缀摘要只有在现有结构识别及本单完整面板归属均成立时才可使用。 - 颜色和尺码都非空时,整段必须等于按已证实页面顺序组合的完整值,中间限定单个空格或单个逗号;不凭猜测枚举顺序。单个维度非空时,整段必须恰等于该完整值,不追加分隔符。不得拆开规格正文中的空格或逗号;不得删除数量后缀来强行相等。两维都空不构造空摘要成功证明,维持原规则资格限制。 - 多个不一致的面板内摘要、已知规范化碰撞或组合歧义均拒绝;不宣称缺失候选数据时整段字符串相等能证明所有潜在 SKU 身份。多出/缺少内容均失败,不做子串匹配,不使用历史 attempt 证明。 4. 其余情况一律失败,报 `PURCHASE_SPEC_NOT_MATCHED`。错误信息附上不含页面文字的诊断:哪个维度、走到哪一步、是否有面板内摘要、是否找到选中项、是否有冲突。 3. 示例:本次现场「已选: [香槟]RW圆领 L码[105-115斤]」规范化后整段等于「[香槟]RW圆领 L码[105-115斤]」,通过。目标「黑色 + XL」遇到摘要「黑色 加绒 XL」不通过,因为实际颜色可能是「黑色 加绒」。 ## 子项目影响、依赖与并行 - Android:`PurchaseLiveAutomation.kt`、`SpecValueNormalizer.kt`(只新增函数)、必要时 `PddProductDetailCollector.kt`(只读取面板内摘要和选项,不改现有解析行为),以及对应测试。 - Server/Web:无。数据库、API:无。 - 无前置依赖;与 #373 可并行,合并时注意冲突。Codex 建议先实施 #373。 ## 设计证据 非 UI 改动,无需原型;以本正文为准。 ## 验收标准 以下勾选代表合成自动化及受影响回归完成,不代表真机采购验收。 - [x] 单元测试(用本次现场的脱敏形态构造):「已选: [香槟]RW圆领 L码[105-115斤]」在面板内 + 颜色选项不可见 + 尺码选项已选中 → 通过。 - [x] 单元测试:只有 `checked`、没有 `selected` 的目标选项 → 通过。 - [x] 单元测试:同维度另一个值处于选中状态,即使摘要匹配 → 失败。 - [x] 单元测试:「已选」里是另一个颜色(如 `[纯白]RW圆领`)→ 失败。 - [x] 单元测试:摘要不在规格面板内(面板外的伪摘要)→ 不作为证据。 - [x] 单元测试:同前缀的长规格——目标「黑色」遇到选项或摘要「黑色 加绒」→ 不通过;`【白色】` 不匹配 `[白色+黑色]超值两件装`;尺码 `L` 不匹配 `XL`。 - [x] 单元测试:规格正文带内部空格或逗号(如 `2xl 110-125斤`、`黑色,加绒`)→ 按完整值比较,正确通过或拒绝。 - [x] 单元测试:同一实际选项及目标的【】/[ ]显示差异 → 可匹配;多个不同实际候选规范化为同一目标值 → 歧义拒绝;同一选项父子文本重复按既有聚合处理,不能误算碰撞。 - [x] 单元测试:摘要位于滚动区域上方/兄弟节点但属于完整面板 → 可用;真正面板外伪摘要 → 不可用;无滚动面板按真实结构范围判断。 - [x] 单元测试:目标颜色不可见、其他未选中颜色可见,可信整段摘要完全一致 → 可通过;另一个颜色明确被选中 → 即使摘要一致也拒绝。 - [x] 单元测试:只有颜色、只有尺码时整段等于单一完整值 → 通过;多余维度/数量后缀、多个不一致摘要、已知组合歧义 → 拒绝。 - [x] 单元测试:「已选」「已选:」「已选:」前缀及外围空白按规则处理,规格正文内的冒号/空格/逗号保持原义,不靠拆词比较。 - [x] 单元测试:「已选」缺失,页面上只有推荐商品标题包含规格值、没有选中的选项 → 失败(原逻辑会通过)。 - [x] 回归:数量、地址、价格的拒绝路径和现有 `finalConfirmation` 测试保持通过;现有 `normalizeColor`/`normalizeSize` 测试不变;Android 构建通过,如实记录。 - [ ] 真机验证需用户另行授权(正式采购可能真实下单);未执行时如实记录。 ## 待实施时确认 - PDD 摘要里颜色和尺码之间的分隔方式。本次现场只有空格一种,其他形态(逗号、带数量后缀等)需要用现有夹具或真机确认。不符合时一律失败,宁可误拦,不可误放。 - 完整面板的结构归属须有既有夹具/真机证据,不能将现有 `specPanelContainer` 的滚动区域当作完整弹层。新增范围识别仅服务最终复核,若证据不足明确记录不支持场景,不扩大到通用解析器重构。 - 双维摘要顺序及允许的逗号形态须有夹具依据;没有证据不自行扩大格式。整段比较与冲突优先的范围、成功及拒绝案例应在实施测试中逐项兑现。 ## 风险与回退 - 规范化过宽会让不同规格被当成相同;本方案只统一括号、全半角和空白,要求完全相等或整段相等,并且冲突优先。 - 收紧后,原来靠无关文字「碰巧通过」的情况会改为失败;摘要格式与预期不同也会失败。失败率可能短期上升,但这是更安全的方向。 - 回退:恢复原比较逻辑;无数据迁移。 ## 文档影响 - 更新 Wiki Business-Rules-and-Glossary(采购执行):下单前规格复核的判断顺序(冲突优先、面板内选中选项、面板内摘要整段相等)和规范化范围。 - 先改线上 Wiki 并回读 revision,再执行一次 sync 与 sync --check。 ## 备注 本单由 Claude Code 依据线上只读查询、失败现场快照(本机解析后已删除)、代码阅读和 Codex 审核意见起草;不含账号、地址、Cookie 或 Token。 ## 实施结果(2026-10-09) 实现 `6f1af70d0d2a4c70c31ba42e05c4321f08c6a78e`,Wiki 镜像 `1c67f3f`;分支 `fix/374-final-spec-confirmation` 已推送。仅 Android 最终规格复核及相应测试改变,独立基于 main `e26743c`,不包含 #373。366项受影响单测通过、debug构建与release单测编译通过;规格及代码质量独立复审通过。完整单测因未修改的图搜返回测试忙循环而中止,未宣称全量通过。 最终选项沿用解析后的 text(既有 UI 尾价分离),再执行本单窄规范化;摘要与目标不新增内容删除。当前有证据支持的双维摘要只有颜色在前、空格分隔,不支持逗号或反序猜测。详情及未验证项见交付评论。工单保持待验收。 ## 合并 main(2026-10-09) 用户授权按 #373 → #374 → 处理镜像冲突 → 联合回归与构建 → 推送 main 执行。main 合并提交 `555a954605a83c12457ed1ada86eb732fe3bb023`,最新文档提交 `3ee8dfc0aa93ef9020786244cce29c487631ddbe`,远端已确认。联合25套件478项全通过,APK构建与release单测源码编译通过。未安装、未执行真实采购、未部署或重启服务;工单仍待人工验收。
Author
Owner

2026-10-09 Claude Code 复核 Codex 审核意见(SynapBus #123/#124)

结论:Codex 对 #374 的 5 项意见核实成立,正文方案 2、3 需要修改后再实施。以下行号以 origin/main e26743c 为准。

已核实

  1. 选中语义:解析器把选中状态按 selected || checked 处理,并把子节点的状态聚合到选项上(PddProductDetailCollector.kt:279-280、:401)。正文写的「只认 selected=true」会误拦只有 checked 的控件,应改为沿用解析器的选项和选中语义。
  2. 「空白边界」不够:目标「黑色」会匹配摘要「黑色 加绒 XL」,而实际颜色可能是「黑色 加绒」;摘要「黑色,XL」又匹配不上。正文方案 2 不成立。
  3. 摘要来源不可靠:selectedSummary(:544-547)取的是全屏可见文字中第一个以「已选」等前缀开头的文字,没有限定在当前规格面板内。
  4. 冲突优先:同一维度明确选中了另一个值时,应直接拒绝,不能因为摘要匹配就放行。
  5. 不改公共规范化:同意新增只给最终复核用的规范化函数,不改 normalizeColor/normalizeSize 等现有行为。

建议修订正文(需用户确认后修改)

每个维度按以下顺序判断:

  1. 冲突:当前规格面板内,解析器识别出的同维度选项中,有非目标值处于选中状态 → 失败。
  2. 选项证据:当前面板内,同维度有选项(selected || checked)规范化后与目标完全相等 → 该维度通过。
  3. 摘要证据(只在第 2 条没有可见选项时使用,例如本次颜色已经滑出可视区):摘要必须来自当前规格面板。去掉「已选」前缀并规范化后,整段必须等于下发规格按页面顺序的组合,比如「颜色 尺码」,中间只允许一个空格或逗号。多出或缺少内容都算不通过,不做子串匹配。本次现场「已选: [香槟]RW圆领 L码[105-115斤]」规范化后正好等于「[香槟]RW圆领 L码[105-115斤]」,可以通过;Codex 举的「黑色 加绒 XL」对目标「黑色 + XL」不能通过。
  4. 其余情况一律失败。不使用 attempt 内的历史证明,以免扩大本单范围。

规范化只做:全角【】〔〕[]()转对应英文括号,全角字母数字和空格转半角,连续空白合并,去首尾空白。不删除括号内容,不做同义词、大小写折叠或通用 NFKC。

验收补充 Codex 列出的反例:只有 checked 的控件、同维度选中冲突、不在面板内的伪摘要、同前缀的长规格(「黑色」与「黑色 加绒」)、带内部空格或逗号的规格、规范化后发生碰撞的值,以及数量、地址、价格拒绝路径的回归。

待实施时确认

  • PDD 摘要里颜色和尺码之间的分隔方式。本次现场只有空格一种,其他形态(逗号、带数量后缀等)需要用现有夹具或真机确认。不符合时一律失败,宁可误拦,不可误放。

未验证

未运行测试,未操作真机。

## 2026-10-09 Claude Code 复核 Codex 审核意见(SynapBus #123/#124) **结论**:Codex 对 #374 的 5 项意见核实成立,正文方案 2、3 需要修改后再实施。以下行号以 `origin/main` `e26743c` 为准。 ### 已核实 1. **选中语义**:解析器把选中状态按 `selected || checked` 处理,并把子节点的状态聚合到选项上(`PddProductDetailCollector.kt:279-280`、`:401`)。正文写的「只认 `selected=true`」会误拦只有 `checked` 的控件,应改为沿用解析器的选项和选中语义。 2. **「空白边界」不够**:目标「黑色」会匹配摘要「黑色 加绒 XL」,而实际颜色可能是「黑色 加绒」;摘要「黑色,XL」又匹配不上。正文方案 2 不成立。 3. **摘要来源不可靠**:`selectedSummary`(`:544-547`)取的是全屏可见文字中第一个以「已选」等前缀开头的文字,没有限定在当前规格面板内。 4. **冲突优先**:同一维度明确选中了另一个值时,应直接拒绝,不能因为摘要匹配就放行。 5. **不改公共规范化**:同意新增只给最终复核用的规范化函数,不改 `normalizeColor`/`normalizeSize` 等现有行为。 ### 建议修订正文(需用户确认后修改) 每个维度按以下顺序判断: 1. **冲突**:当前规格面板内,解析器识别出的同维度选项中,有非目标值处于选中状态 → 失败。 2. **选项证据**:当前面板内,同维度有选项(`selected || checked`)规范化后与目标**完全相等** → 该维度通过。 3. **摘要证据**(只在第 2 条没有可见选项时使用,例如本次颜色已经滑出可视区):摘要必须来自当前规格面板。去掉「已选」前缀并规范化后,**整段**必须等于下发规格按页面顺序的组合,比如「颜色 尺码」,中间只允许一个空格或逗号。多出或缺少内容都算不通过,不做子串匹配。本次现场「已选: [香槟]RW圆领 L码[105-115斤]」规范化后正好等于「[香槟]RW圆领 L码[105-115斤]」,可以通过;Codex 举的「黑色 加绒 XL」对目标「黑色 + XL」不能通过。 4. 其余情况一律失败。不使用 attempt 内的历史证明,以免扩大本单范围。 规范化只做:全角【】〔〕[]()转对应英文括号,全角字母数字和空格转半角,连续空白合并,去首尾空白。不删除括号内容,不做同义词、大小写折叠或通用 NFKC。 验收补充 Codex 列出的反例:只有 `checked` 的控件、同维度选中冲突、不在面板内的伪摘要、同前缀的长规格(「黑色」与「黑色 加绒」)、带内部空格或逗号的规格、规范化后发生碰撞的值,以及数量、地址、价格拒绝路径的回归。 ### 待实施时确认 - PDD 摘要里颜色和尺码之间的分隔方式。本次现场只有空格一种,其他形态(逗号、带数量后缀等)需要用现有夹具或真机确认。不符合时一律失败,宁可误拦,不可误放。 ### 未验证 未运行测试,未操作真机。
Author
Owner

#374 v3 交付 / 待验收(2026-10-09)

实现与范围

  • 用户授权按 v3 实施、测试、提交及推送。本单独立基于 origin/main e26743c,分支 fix/374-final-spec-confirmation 已推送:实现 6f1af70d0d2a4c70c31ba42e05c4321f08c6a78e,文档 1c67f3f。
  • 新增最终专用窄规范化与 PurchaseFinalSpecVerifier:结构限定完整面板,冲突/不可用/碰撞/已知组合歧义优先,当前精确选中证明优先,缺证维度才使用可信完整摘要。移除任意可见文本包含目标的兜底。异常附固定无原文诊断。
  • 解析器仅增加默认 false 的最终复核模式,沿用 optionBlock 与 selected/checked,保留独立同名候选;同值、同矩形、真实祖先链才合并。同维度多组统一检查。既有采集默认行为不变。
  • 独立复审发现的“rawText尾价导致合法选项误拒绝”已以新失败测试验证后修正为沿用 parsed text;摘要与目标不新增尾价/数量删除。错误信息缺安全诊断也已补齐。
  • 不改 Server/Web、API、数据库、#373导航、前面的规格选择/verifySummary、地址/价格/数量/提交判断及支付边界。

实际验证

  • 基线相关测试86项通过。
  • 实现代理真实RED:首轮19项中15项失败;复审新增断言后24项中16项失败(包含尾价与错误诊断问题),随后修复。主Agent独立检查最终代码及重新执行GREEN。
  • 最终8套件 366项,0失败、0错误、0跳过。包括采集器100、最终规格复核24、PurchaseLiveAutomation84、PurchaseRehearsalExecutor91、SpecOptionDedup2、SpecPanelRecognition42、SpecValueNormalizer3、TruncatedSpecCard20。
  • 命令:在android目录设置本机ANDROID_HOME后,执行 :app:testDebugUnitTest(上述8套件过滤)、:app:compileReleaseUnitTestKotlin、:app:assembleDebug,BUILD SUCCESSFUL。主Agent独立重跑退出0;git diff --check通过。
  • 完整单测未完成:未修改的 ImageSearchBackRecoveryTest.kt:49 → PinduoduoImageSearchAutomation.awaitPage:312 持续忙循环,jstack显示worker CPU约151.9秒;仅中止该次Gradle会话,未停共享daemon、未改图搜代码。不能宣称全量单测通过。
  • 独立规格复审、代码质量复审均PASS;评审者只读核验,没有冒称运行Gradle或真机。

APK、边界与文档

  • APK:D:/OPC/goauto-worktrees/issue-374/android/app/build/outputs/apk/debug/app-debug.apk。SHA256 f9c30674b345a74a342f7f720348999a6b635d5e4ca340bc3954b5511e4f2888。
  • 保留main的版本标识 0.9.69-370-diag1 / code82,本包不是 #373+#374 集成包,不能靠版本文字辨别代码,也未安装。后续合并装机须另行授权并构建对应集成版本。
  • 完整面板形态依据 SpecPanelFixtures.sheet/taskOptionDedupSheet;无前缀摘要仅复用 PddProductDetailCollectorTest.prefixlessPanel 的quantity/header结构。未知完整范围禁用摘要,仍可用独立有界选项;双维只支持已证实的颜色+空格+尺码,不猜测逗号/反序。
  • 单个不匹配摘要没有补证能力;全部必需维度已精确选中且无冲突/已知组合歧义时可按选中证据通过。多个冲突摘要仍拒绝。不宣称可从缺失候选证明所有潜在SKU身份。
  • Wiki Business-Rules-and-Glossary 在线更新并回读一致,revision f8a5ca861965f5da9bdec2235205f23fb9a00840。一次sync及sync --check通过,17映射一致。镜像提交保留同步取得的既有发布、#373记录,不代表本分支包含其实现。
  • 未安装、未操作手机、未执行真实采购/付款、未合并main、未发布或重启服务。 分支未合并,worktree保留。等待人工验收,不关闭工单。
## #374 v3 交付 / 待验收(2026-10-09) ### 实现与范围 - 用户授权按 v3 实施、测试、提交及推送。本单独立基于 origin/main `e26743c`,分支 `fix/374-final-spec-confirmation` 已推送:实现 `6f1af70d0d2a4c70c31ba42e05c4321f08c6a78e`,文档 `1c67f3f`。 - 新增最终专用窄规范化与 `PurchaseFinalSpecVerifier`:结构限定完整面板,冲突/不可用/碰撞/已知组合歧义优先,当前精确选中证明优先,缺证维度才使用可信完整摘要。移除任意可见文本包含目标的兜底。异常附固定无原文诊断。 - 解析器仅增加默认 false 的最终复核模式,沿用 optionBlock 与 selected/checked,保留独立同名候选;同值、同矩形、真实祖先链才合并。同维度多组统一检查。既有采集默认行为不变。 - 独立复审发现的“rawText尾价导致合法选项误拒绝”已以新失败测试验证后修正为沿用 parsed text;摘要与目标不新增尾价/数量删除。错误信息缺安全诊断也已补齐。 - 不改 Server/Web、API、数据库、#373导航、前面的规格选择/verifySummary、地址/价格/数量/提交判断及支付边界。 ### 实际验证 - 基线相关测试86项通过。 - 实现代理真实RED:首轮19项中15项失败;复审新增断言后24项中16项失败(包含尾价与错误诊断问题),随后修复。主Agent独立检查最终代码及重新执行GREEN。 - 最终8套件 **366项,0失败、0错误、0跳过**。包括采集器100、最终规格复核24、PurchaseLiveAutomation84、PurchaseRehearsalExecutor91、SpecOptionDedup2、SpecPanelRecognition42、SpecValueNormalizer3、TruncatedSpecCard20。 - 命令:在android目录设置本机ANDROID_HOME后,执行 `:app:testDebugUnitTest`(上述8套件过滤)、`:app:compileReleaseUnitTestKotlin`、`:app:assembleDebug`,BUILD SUCCESSFUL。主Agent独立重跑退出0;`git diff --check`通过。 - **完整单测未完成**:未修改的 `ImageSearchBackRecoveryTest.kt:49` → `PinduoduoImageSearchAutomation.awaitPage:312` 持续忙循环,jstack显示worker CPU约151.9秒;仅中止该次Gradle会话,未停共享daemon、未改图搜代码。不能宣称全量单测通过。 - 独立规格复审、代码质量复审均PASS;评审者只读核验,没有冒称运行Gradle或真机。 ### APK、边界与文档 - APK:`D:/OPC/goauto-worktrees/issue-374/android/app/build/outputs/apk/debug/app-debug.apk`。SHA256 `f9c30674b345a74a342f7f720348999a6b635d5e4ca340bc3954b5511e4f2888`。 - 保留main的版本标识 `0.9.69-370-diag1 / code82`,本包不是 #373+#374 集成包,不能靠版本文字辨别代码,也未安装。后续合并装机须另行授权并构建对应集成版本。 - 完整面板形态依据 `SpecPanelFixtures.sheet/taskOptionDedupSheet`;无前缀摘要仅复用 `PddProductDetailCollectorTest.prefixlessPanel` 的quantity/header结构。未知完整范围禁用摘要,仍可用独立有界选项;双维只支持已证实的颜色+空格+尺码,不猜测逗号/反序。 - 单个不匹配摘要没有补证能力;全部必需维度已精确选中且无冲突/已知组合歧义时可按选中证据通过。多个冲突摘要仍拒绝。不宣称可从缺失候选证明所有潜在SKU身份。 - Wiki Business-Rules-and-Glossary 在线更新并回读一致,revision `f8a5ca861965f5da9bdec2235205f23fb9a00840`。一次sync及sync --check通过,17映射一致。镜像提交保留同步取得的既有发布、#373记录,不代表本分支包含其实现。 - **未安装、未操作手机、未执行真实采购/付款、未合并main、未发布或重启服务。** 分支未合并,worktree保留。等待人工验收,不关闭工单。
Author
Owner

按授权顺序合并 / 联合验证完成

  • #373 合并提交 1e924fa41195281a3223003a69c8c16ae37f8aa5;#374 合并提交 555a954605a83c12457ed1ada86eb732fe3bb023;main 最新 3ee8dfc0aa93ef9020786244cce29c487631ddbe 已推送。两单原提交及分支历史保留,未压缩或强推。
  • 源码自动合并无冲突;3份Wiki镜像冲突选择 #374 已生成的较新完整镜像(包含 #373),没有手工改写业务正文。随后在线更新合并事实并回读,再完成一轮sync/check,17映射全部一致。
  • 集成环境 D:/OPC/goauto-worktrees/release-373-374,未切换或覆盖根仓库用户旧分支/本地改动,未更新Supervisor运行目录。

集成验证

  • 主Agent实际运行联合筛选:Purchase*、PddLaunchFallback、PddNavigation、PddProductDetailCollector、CurrentPageCollection、SpecPanelRecognition、SpecOptionDedup、TruncatedSpecCard、SpecValueNormalizer、NavigationProbe、BrowserProbeClickPolicy、AgentDiagnostic*、TaskExecutionMutex。
  • 25套件478项,0失败、0错误、0跳过;:app:compileReleaseUnitTestKotlin、:app:assembleDebug成功。存在原有弃用/未使用变量编译警告,未扩大范围修改。git diff检查通过。
  • 本轮未重跑已记录卡住的无关图搜全量用例,不宣称完整单测或真机采购通过。
  • APK D:/OPC/goauto-worktrees/release-373-374/android/app/build/outputs/apk/debug/app-debug.apk,SHA256 6e2d0e0ed1eb943b3f168bb16d628d2c2bb4ce3b7c7c8b9e567dcdf8259150f8。版本保留 0.9.69-373-fix1 / code82,同时包含#374,不与单独#373包混淆。
  • apksigner验证通过,原签名证书SHA256 bf86d7465c6092be74ce9c4187eb30c9a7d045c3b91891a547e2598429766dec。没有安装或清手机数据。

文档与清理

  • Business-Rules-and-Glossary revision a47b6b3b7ef7745417d1c2c88932f5bb12228f27;Deployment-and-Operations revision 3f69f2e39675752dfd43dc38de41cb7defb74a42,回读一致、镜像检查通过。
  • 清理前已确认两工单HEAD是origin/main祖先、status为空、没有未跟踪任务资料/数据库、没有进程或Supervisor配置引用、没有外部链接;仅有可再生成的Gradle/build和Python缓存。集成APK保留在release工作区。
  • 分别执行非force的 git worktree remove,均遇Windows Filename too long,Git登记已移除但 D:/OPC/goauto-worktrees/issue-373、D:/OPC/goauto-worktrees/issue-374 留有部分目录,未强删。分支与提交保留,源码可恢复;按规则记录残留待后续清理。
  • 首次main推送曾遇一次认证失败,未改凭据/权限,原命令重试成功;远端main已回读确认。

本轮不涉及业务库迁移、Admin发布、服务重启、手机安装或真实采购/付款。仍保留#373非goodsId身份核验及#374结构/摘要格式的已知边界。工单不关闭,待用户验收。

## 按授权顺序合并 / 联合验证完成 - #373 合并提交 `1e924fa41195281a3223003a69c8c16ae37f8aa5`;#374 合并提交 `555a954605a83c12457ed1ada86eb732fe3bb023`;main 最新 `3ee8dfc0aa93ef9020786244cce29c487631ddbe` 已推送。两单原提交及分支历史保留,未压缩或强推。 - 源码自动合并无冲突;3份Wiki镜像冲突选择 #374 已生成的较新完整镜像(包含 #373),没有手工改写业务正文。随后在线更新合并事实并回读,再完成一轮sync/check,17映射全部一致。 - 集成环境 `D:/OPC/goauto-worktrees/release-373-374`,未切换或覆盖根仓库用户旧分支/本地改动,未更新Supervisor运行目录。 ### 集成验证 - 主Agent实际运行联合筛选:Purchase*、PddLaunchFallback、PddNavigation、PddProductDetailCollector、CurrentPageCollection、SpecPanelRecognition、SpecOptionDedup、TruncatedSpecCard、SpecValueNormalizer、NavigationProbe、BrowserProbeClickPolicy、AgentDiagnostic*、TaskExecutionMutex。 - **25套件478项,0失败、0错误、0跳过**;`:app:compileReleaseUnitTestKotlin`、`:app:assembleDebug`成功。存在原有弃用/未使用变量编译警告,未扩大范围修改。git diff检查通过。 - 本轮未重跑已记录卡住的无关图搜全量用例,不宣称完整单测或真机采购通过。 - APK `D:/OPC/goauto-worktrees/release-373-374/android/app/build/outputs/apk/debug/app-debug.apk`,SHA256 `6e2d0e0ed1eb943b3f168bb16d628d2c2bb4ce3b7c7c8b9e567dcdf8259150f8`。版本保留 `0.9.69-373-fix1 / code82`,**同时包含#374,不与单独#373包混淆**。 - apksigner验证通过,原签名证书SHA256 `bf86d7465c6092be74ce9c4187eb30c9a7d045c3b91891a547e2598429766dec`。没有安装或清手机数据。 ### 文档与清理 - Business-Rules-and-Glossary revision `a47b6b3b7ef7745417d1c2c88932f5bb12228f27`;Deployment-and-Operations revision `3f69f2e39675752dfd43dc38de41cb7defb74a42`,回读一致、镜像检查通过。 - 清理前已确认两工单HEAD是origin/main祖先、status为空、没有未跟踪任务资料/数据库、没有进程或Supervisor配置引用、没有外部链接;仅有可再生成的Gradle/build和Python缓存。集成APK保留在release工作区。 - 分别执行非force的 `git worktree remove`,均遇Windows `Filename too long`,Git登记已移除但 `D:/OPC/goauto-worktrees/issue-373`、`D:/OPC/goauto-worktrees/issue-374` 留有部分目录,未强删。分支与提交保留,源码可恢复;按规则记录残留待后续清理。 - 首次main推送曾遇一次认证失败,未改凭据/权限,原命令重试成功;远端main已回读确认。 本轮不涉及业务库迁移、Admin发布、服务重启、手机安装或真实采购/付款。仍保留#373非goodsId身份核验及#374结构/摘要格式的已知边界。工单不关闭,待用户验收。
Author
Owner

2026-10-09 按用户授权完成合并版真机覆盖安装(未执行采购):

  • 使用 adb install -r,返回 Success;未卸载、未清除数据。
  • 版本 0.9.69-373-fix1 / code 82,包含 #373 + #374;基于已推送 main 3ee8dfc0aa93ef9020786244cce29c487631ddbe 的集成构建。
  • 新旧签名证书 SHA256 一致;安装后设备 base.apk SHA256 与构建文件一致:6e2d0e0ed1eb943b3f168bb16d628d2c2bb4ce3b7c7c8b9e567dcdf8259150f8。
  • 安装前运行状态 ONLINE、无 current_task_id 标记。设置、设备身份、界面偏好三个文件安装前后 SHA256 完全一致。
  • 仅完成安装验证,未触发采集、采购、下单或付款,未发布/重启服务端。采购业务真机效果仍待用户验收;工单保持开放。
  • 本次仅增加安装证据,无新增长期契约或运维流程变化,不重复更新 Wiki。
2026-10-09 按用户授权完成合并版真机覆盖安装(未执行采购): - 使用 `adb install -r`,返回 Success;未卸载、未清除数据。 - 版本 `0.9.69-373-fix1` / code 82,包含 #373 + #374;基于已推送 main `3ee8dfc0aa93ef9020786244cce29c487631ddbe` 的集成构建。 - 新旧签名证书 SHA256 一致;安装后设备 base.apk SHA256 与构建文件一致:`6e2d0e0ed1eb943b3f168bb16d628d2c2bb4ce3b7c7c8b9e567dcdf8259150f8`。 - 安装前运行状态 ONLINE、无 current_task_id 标记。设置、设备身份、界面偏好三个文件安装前后 SHA256 完全一致。 - 仅完成安装验证,未触发采集、采购、下单或付款,未发布/重启服务端。采购业务真机效果仍待用户验收;工单保持开放。 - 本次仅增加安装证据,无新增长期契约或运维流程变化,不重复更新 Wiki。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#374