fix(agent): 同一地址卡片重复手机号节点误判入口不唯一 #229

Open
opened 2026-09-05 18:13:43 +08:00 by ila · 3 comments
Owner

基本信息

  • 类型:缺陷(地址入口去重)
  • 所属 Epic:#32
  • 所属 MVP / 版本:采购 Agent
  • 阶段:进行中

依赖与并行

  • 关联:#152 已验收;基于 #228 提交 5ee3b62
  • 是否允许并行:是;#228 已使 CG94 越过最终规格复核,本单只处理后续地址入口解析。

子项目影响

  • 仅影响:android
  • 是否跨子项目:否
  • 是否修改共享接口或契约:否
  • 验证:PurchaseLiveAutomationTest、Android 全量单测和 APK 构建

原始需求

  • 来源:用户对话
  • 提出时间:2026-09-05
  • 摘要:最新版 Agent 执行 CG94,规格选择成功后报“收货地址入口不唯一,未创建订单”。用户要求建工单修复。

当前事实与根因

  • 当前 updateShippingAddress 直接收集所有包含脱敏手机号的可见节点,只合并边界近乎完全重叠的节点;合并后数量大于 1 就判定地址入口歧义。
  • PDD 可把同一地址的手机号同时暴露在父子语义节点、固定层和滚动层中,这些节点边界不同但可能归属同一地址卡片,导致肉眼一个地址、代码按多个文本节点误判。
  • 错误发生在地址入口点击之前,未修改地址,也未进入创建订单边界。

目标与方案

  1. 不再按手机号文本节点数判断入口;把节点沿父链解析到最近的可点击地址卡片,同一可点击祖先归为一个卡片。
  2. 没有可点击祖先时,仅把相同脱敏手机号且边界重叠/包含的节点归为同一空间卡片;相隔的独立节点不合并。
  3. 连续两个新快照都稳定解析为同一唯一卡片后才执行一次新鲜动作:有可点击卡片时执行无障碍点击;无可点击祖先时保留唯一手机号区域的受控中心点击。
  4. 两个独立地址卡片、稳定结果变化、目标歧义或点击后没有进入唯一地址页时继续失败。
  5. 错误诊断只增加 phoneNodes、addressCards、tapTargets 数量,不记录手机号、地址、控件树或截图。

预计修改:

  • android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseLiveAutomation.kt
  • android/app/src/test/java/cn/ilapage/goauto/agent/PurchaseLiveAutomationTest.kt
  • android/app/build.gradle.kts

做什么 / 不做什么

  • 做:语义归并、稳定读取、新鲜唯一点击、脱敏计数诊断、回归测试、升版构建安装。
  • 不做:不选择多个真实地址中的第一个;不改服务端、数据库、规则或接口;不自动重试 CG94、不修改真实地址、不创建订单、不付款。

设计与原型门禁

  • 修改类型:恢复既有地址入口行为的 Bug
  • 设计证据:CG94 结构化错误与现有节点计数代码
  • 状态:用户于 2026-09-05 已确认建单修复
  • 无需 UI 原型:无页面、组件或交互变化。

文档影响

  • 不影响长期文档,原因:恢复既有唯一地址入口安全语义,不改变 API、业务规则或安全边界。

交付文档影响

  • 无交付文档影响,原因:入口、配置、部署和运维不变。

任务记录

  • 单次事实来源:本工单正文和评论
  • 默认不创建任务快照

验收标准

  • 同一地址卡片中的多个手机号父子/重复节点归并为一个入口并只点击一次。
  • 两个独立地址卡片即使手机号相同仍明确失败,点击次数为零。
  • 唯一入口必须连续两个快照稳定,并通过新鲜节点执行动作。
  • 点击后仍要求唯一收货地址页,后续地址与订单门禁不放宽。
  • 诊断只包含候选数量,不包含手机号或地址。
  • 定向与完整 Android 测试通过,Debug APK 构建并覆盖安装目标设备;不自动执行 live 任务。

风险和回退

地址修改和采购属于高风险流程。本单不增加下单能力,只修复地址入口唯一性解析;用户已明确授权实施。真实多地址保持 fail-closed,付款永久禁止。回退本单 Android 提交即可恢复旧逻辑。

工具说明

当前环境无 Gitea MCP 工单工具,按规则回退项目配置的 Gitea API;凭据仅从忽略的 gitea.env 读取。

## 基本信息 - 类型:缺陷(地址入口去重) - 所属 Epic:#32 - 所属 MVP / 版本:采购 Agent - 阶段:进行中 ## 依赖与并行 - 关联:#152 已验收;基于 #228 提交 `5ee3b62` - 是否允许并行:是;#228 已使 CG94 越过最终规格复核,本单只处理后续地址入口解析。 ## 子项目影响 - 仅影响:android - 是否跨子项目:否 - 是否修改共享接口或契约:否 - 验证:`PurchaseLiveAutomationTest`、Android 全量单测和 APK 构建 ## 原始需求 - 来源:用户对话 - 提出时间:2026-09-05 - 摘要:最新版 Agent 执行 CG94,规格选择成功后报“收货地址入口不唯一,未创建订单”。用户要求建工单修复。 ## 当前事实与根因 - 当前 `updateShippingAddress` 直接收集所有包含脱敏手机号的可见节点,只合并边界近乎完全重叠的节点;合并后数量大于 1 就判定地址入口歧义。 - PDD 可把同一地址的手机号同时暴露在父子语义节点、固定层和滚动层中,这些节点边界不同但可能归属同一地址卡片,导致肉眼一个地址、代码按多个文本节点误判。 - 错误发生在地址入口点击之前,未修改地址,也未进入创建订单边界。 ## 目标与方案 1. 不再按手机号文本节点数判断入口;把节点沿父链解析到最近的可点击地址卡片,同一可点击祖先归为一个卡片。 2. 没有可点击祖先时,仅把相同脱敏手机号且边界重叠/包含的节点归为同一空间卡片;相隔的独立节点不合并。 3. 连续两个新快照都稳定解析为同一唯一卡片后才执行一次新鲜动作:有可点击卡片时执行无障碍点击;无可点击祖先时保留唯一手机号区域的受控中心点击。 4. 两个独立地址卡片、稳定结果变化、目标歧义或点击后没有进入唯一地址页时继续失败。 5. 错误诊断只增加 `phoneNodes`、`addressCards`、`tapTargets` 数量,不记录手机号、地址、控件树或截图。 预计修改: - `android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseLiveAutomation.kt` - `android/app/src/test/java/cn/ilapage/goauto/agent/PurchaseLiveAutomationTest.kt` - `android/app/build.gradle.kts` ## 做什么 / 不做什么 - 做:语义归并、稳定读取、新鲜唯一点击、脱敏计数诊断、回归测试、升版构建安装。 - 不做:不选择多个真实地址中的第一个;不改服务端、数据库、规则或接口;不自动重试 CG94、不修改真实地址、不创建订单、不付款。 ## 设计与原型门禁 - 修改类型:恢复既有地址入口行为的 Bug - 设计证据:CG94 结构化错误与现有节点计数代码 - 状态:用户于 2026-09-05 已确认建单修复 - 无需 UI 原型:无页面、组件或交互变化。 ## 文档影响 - [x] 不影响长期文档,原因:恢复既有唯一地址入口安全语义,不改变 API、业务规则或安全边界。 ## 交付文档影响 - [x] 无交付文档影响,原因:入口、配置、部署和运维不变。 ## 任务记录 - 单次事实来源:本工单正文和评论 - [x] 默认不创建任务快照 ## 验收标准 - [ ] 同一地址卡片中的多个手机号父子/重复节点归并为一个入口并只点击一次。 - [ ] 两个独立地址卡片即使手机号相同仍明确失败,点击次数为零。 - [ ] 唯一入口必须连续两个快照稳定,并通过新鲜节点执行动作。 - [ ] 点击后仍要求唯一收货地址页,后续地址与订单门禁不放宽。 - [ ] 诊断只包含候选数量,不包含手机号或地址。 - [ ] 定向与完整 Android 测试通过,Debug APK 构建并覆盖安装目标设备;不自动执行 live 任务。 ## 风险和回退 地址修改和采购属于高风险流程。本单不增加下单能力,只修复地址入口唯一性解析;用户已明确授权实施。真实多地址保持 fail-closed,付款永久禁止。回退本单 Android 提交即可恢复旧逻辑。 ## 工具说明 当前环境无 Gitea MCP 工单工具,按规则回退项目配置的 Gitea API;凭据仅从忽略的 `gitea.env` 读取。
Author
Owner

#229 实施完成,待人工验收。

实现:

  • 将收货地址入口从“手机号节点数量”改为“可操作地址卡片”解析;同一可点击祖先内的重复父/子手机号节点归并为一个入口。
  • 没有可点击祖先时,仅对同一脱敏手机号且空间重叠/包含的节点归并,并继续使用受控坐标点击。
  • 点击前间隔 200ms 进行双快照稳定性校验;快照结构变化则重新定位,不使用陈旧节点。
  • 两个真实独立地址卡片仍返回 PURCHASE_ADDRESS_ENTRY_AMBIGUOUS,不点击、不修改地址、不创建订单。
  • 诊断信息仅包含 phoneNodes/addressCards/tapTargets 数量,不记录手机号或原始控件树。

代码:

  • 分支:fix/229-address-entry-dedup
  • 提交:c9aaade fix(agent): deduplicate address entry nodes (#229)
  • Agent:0.9.51(versionCode 64)

验证:

  • 定向 PurchaseLiveAutomationTest:通过;覆盖同卡重复节点归并、两个独立地址卡片安全失败。
  • scripts/verify.ps1 -Component android:通过(Debug/Release 单测与 Debug APK 构建)。
  • python dev_scripts/harness.py check --strict:通过。
  • git diff --check:通过。
  • APK:6,289,848 bytes;SHA-256 0767D2B930D32913802A2F9996048FA87D58C8CB826C1DD444A5010B3856147A。
  • 已覆盖安装到 192.168.0.173:41751,回读 0.9.51(64),GoAuto 无障碍服务仍启用。

安全与未验证项:

  • 未自动重试 CG94,未执行地址修改、创建订单或支付;真机业务验收需采购员手动重试。
  • 无长期 Wiki 影响:本次仅恢复既定的唯一地址入口判定与失败关闭行为,因此跳过 Wiki 更新/同步。
  • 工作区原有无关改动与未跟踪文件均未纳入提交。
#229 实施完成,待人工验收。 实现: - 将收货地址入口从“手机号节点数量”改为“可操作地址卡片”解析;同一可点击祖先内的重复父/子手机号节点归并为一个入口。 - 没有可点击祖先时,仅对同一脱敏手机号且空间重叠/包含的节点归并,并继续使用受控坐标点击。 - 点击前间隔 200ms 进行双快照稳定性校验;快照结构变化则重新定位,不使用陈旧节点。 - 两个真实独立地址卡片仍返回 `PURCHASE_ADDRESS_ENTRY_AMBIGUOUS`,不点击、不修改地址、不创建订单。 - 诊断信息仅包含 `phoneNodes/addressCards/tapTargets` 数量,不记录手机号或原始控件树。 代码: - 分支:`fix/229-address-entry-dedup` - 提交:`c9aaade fix(agent): deduplicate address entry nodes (#229)` - Agent:0.9.51(versionCode 64) 验证: - 定向 `PurchaseLiveAutomationTest`:通过;覆盖同卡重复节点归并、两个独立地址卡片安全失败。 - `scripts/verify.ps1 -Component android`:通过(Debug/Release 单测与 Debug APK 构建)。 - `python dev_scripts/harness.py check --strict`:通过。 - `git diff --check`:通过。 - APK:6,289,848 bytes;SHA-256 `0767D2B930D32913802A2F9996048FA87D58C8CB826C1DD444A5010B3856147A`。 - 已覆盖安装到 `192.168.0.173:41751`,回读 0.9.51(64),GoAuto 无障碍服务仍启用。 安全与未验证项: - 未自动重试 CG94,未执行地址修改、创建订单或支付;真机业务验收需采购员手动重试。 - 无长期 Wiki 影响:本次仅恢复既定的唯一地址入口判定与失败关闭行为,因此跳过 Wiki 更新/同步。 - 工作区原有无关改动与未跟踪文件均未纳入提交。
Author
Owner

v2 根因与方案更新(CG94 真机回归)

CG94 在 Agent 0.9.51(64)仍失败。服务端结构化事实为 phoneNodes=2;addressCards=2;tapTargets=2:PDD 将视觉上的同一地址卡暴露为两套不同路径、不同可点击祖先的无障碍节点,v1 仅按祖先路径分组,仍会误判为两个地址。

v2 调整:

  • 在已确认的订单规格面板内,为手机号候选提取其地址卡后代的临时语义指纹;只在 Agent 内存比较,不记录、不上传手机号或地址正文。
  • 嵌套/视觉重叠,或具有相同且充分地址语义的不同无障碍子树,合并为一个逻辑地址;真实语义不同的两张地址卡继续 fail-closed。
  • 保留双快照稳定校验;动作前按快照路径重新获取准确节点并再次校验标签、类型、边界、可见/启用状态,再点击该节点的最近可点击祖先,避免相同文字/坐标导致通用 fresh locator 再次歧义。
  • 点击后仍必须以地址编辑/选择页证据确认转场,才能执行既有地址修改与保存;不放宽保存地址、创建订单或支付门禁。
  • 自动测试增加:不同路径的同语义双层地址卡可进入一次;相同手机号但地址语义不同继续拒绝;路径漂移或节点校验失败不得点击;错误只含脱敏计数。

文档影响仍为:无长期规则/契约变化,只修复既有唯一地址入口的实现偏差,不更新 Wiki。

## v2 根因与方案更新(CG94 真机回归) CG94 在 Agent 0.9.51(64)仍失败。服务端结构化事实为 `phoneNodes=2;addressCards=2;tapTargets=2`:PDD 将视觉上的同一地址卡暴露为两套不同路径、不同可点击祖先的无障碍节点,v1 仅按祖先路径分组,仍会误判为两个地址。 v2 调整: - 在已确认的订单规格面板内,为手机号候选提取其地址卡后代的临时语义指纹;只在 Agent 内存比较,不记录、不上传手机号或地址正文。 - 嵌套/视觉重叠,或具有相同且充分地址语义的不同无障碍子树,合并为一个逻辑地址;真实语义不同的两张地址卡继续 fail-closed。 - 保留双快照稳定校验;动作前按快照路径重新获取准确节点并再次校验标签、类型、边界、可见/启用状态,再点击该节点的最近可点击祖先,避免相同文字/坐标导致通用 fresh locator 再次歧义。 - 点击后仍必须以地址编辑/选择页证据确认转场,才能执行既有地址修改与保存;不放宽保存地址、创建订单或支付门禁。 - 自动测试增加:不同路径的同语义双层地址卡可进入一次;相同手机号但地址语义不同继续拒绝;路径漂移或节点校验失败不得点击;错误只含脱敏计数。 文档影响仍为:无长期规则/契约变化,只修复既有唯一地址入口的实现偏差,不更新 Wiki。
Author
Owner

v2 实施完成,待验收

  • 分支:fix/229-address-entry-dedup
  • v1:c9aaade
  • v2:1f40a7f
  • Agent:0.9.52(versionCode 65)

实现结果:

  • 不同无障碍路径/祖先的地址卡先按视觉重叠或充分且一致的临时地址语义归并;语义仅驻留内存,不写日志、不上传、不持久化。
  • 真正不同语义的两个地址继续返回 PURCHASE_ADDRESS_ENTRY_AMBIGUOUS。
  • 唯一逻辑地址使用稳定快照中的精确节点路径重新获取,并复核标签、类型、中心位置、可见与启用状态后,才点击最近可点击祖先;路径漂移直接失败,不降级为地址坐标手势。
  • 点击后的既有地址页面强证据、地址保存复核、创建订单门禁和永久禁止支付保持不变。

验证:

  • PurchaseLiveAutomationTest 定向测试通过(38 项),新增覆盖跨子树同语义归并、不同语义拒绝、路径漂移无手势降级。
  • scripts/verify.ps1 -Component android 通过:Debug/Release 单元测试与 Debug APK 构建成功。
  • python dev_scripts/harness.py check --strict 与 git diff --check 通过。
  • 安装前设备 10(PKG110)无 running/order_submit_started 采购任务、无 running 采集任务。
  • APK:6,293,317 bytes;SHA-256 11EFB5141AAD969397D5C07AA3777B7FB5BBDC16CA15C87652DFF5740C916420。
  • 已覆盖安装到 192.168.0.173:41751,回读为 0.9.52(65),GoAuto 无障碍服务仍启用。

未自动重试 CG94,未修改真实地址、未创建订单、未支付。请由用户手动重试同任务验收。无长期规则/契约变化,按工单方案跳过 Wiki 更新。无关工作区改动保持未动。

## v2 实施完成,待验收 - 分支:`fix/229-address-entry-dedup` - v1:`c9aaade` - v2:`1f40a7f` - Agent:`0.9.52`(versionCode 65) 实现结果: - 不同无障碍路径/祖先的地址卡先按视觉重叠或充分且一致的临时地址语义归并;语义仅驻留内存,不写日志、不上传、不持久化。 - 真正不同语义的两个地址继续返回 `PURCHASE_ADDRESS_ENTRY_AMBIGUOUS`。 - 唯一逻辑地址使用稳定快照中的精确节点路径重新获取,并复核标签、类型、中心位置、可见与启用状态后,才点击最近可点击祖先;路径漂移直接失败,不降级为地址坐标手势。 - 点击后的既有地址页面强证据、地址保存复核、创建订单门禁和永久禁止支付保持不变。 验证: - `PurchaseLiveAutomationTest` 定向测试通过(38 项),新增覆盖跨子树同语义归并、不同语义拒绝、路径漂移无手势降级。 - `scripts/verify.ps1 -Component android` 通过:Debug/Release 单元测试与 Debug APK 构建成功。 - `python dev_scripts/harness.py check --strict` 与 `git diff --check` 通过。 - 安装前设备 10(PKG110)无 running/order_submit_started 采购任务、无 running 采集任务。 - APK:6,293,317 bytes;SHA-256 `11EFB5141AAD969397D5C07AA3777B7FB5BBDC16CA15C87652DFF5740C916420`。 - 已覆盖安装到 `192.168.0.173:41751`,回读为 0.9.52(65),GoAuto 无障碍服务仍启用。 未自动重试 CG94,未修改真实地址、未创建订单、未支付。请由用户手动重试同任务验收。无长期规则/契约变化,按工单方案跳过 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#229