缺陷:订单结果未知时丢失已验证单价和核单失败阶段 #167

Open
opened 2026-08-31 14:12:45 +08:00 by ila · 1 comment
Owner

原始需求摘要

来源:用户于 2026-08-31 反馈 CG-36 已成功创建待付款订单并最终进入 PDD 订单详情,但 Admin 没有订单编号、下单时间及其他动态执行数据;只读分析后确认按建议处理。

目的:当订单结果仍无法唯一确认时,保留创建订单前已经验证的非订单动态事实,并向 Server/Admin 提交不含敏感信息的稳定核单失败阶段;Admin 继续以数据库最终事实展示,不从页面或历史任务猜测订单号。

基线与已确认事实

代码基线:a3628df,Agent 0.9.31、PDD 8.22.0、CG30/device 5,核验时间 2026-08-31。

  • CG-36 为 live,状态 order_result_unknown;已有 orderSubmitRequestId、irreversibleAt,但 pddOrderNo、orderSubmittedAt、actualUnitPriceCent 均为空。
  • CG-36 的 SYB、虾皮、PDD 关联和地址后缀快照仍存在,说明 Agent→Server 提交及 Admin 查询链路正常;缺失的是动态核单结果和已验证实际单价。
  • Android order_result_unknown outcome 未携带先前 verifyUnitPrice 得到的 observedPrice;结果序列化只对 failed 写错误码/原因。
  • Server 的 order_result_unknown 分支只迁移状态,不保存 ActualUnitPriceCent、ErrorCode、ErrorMessage。
  • Admin 已直接映射上述数据库字段;当前不是前端漏字段。
  • 现有核单器以 nullable 结果折叠空窗口超时、微信恢复失败、未知应用、支付页返回失败、订单上下文缺失、订单号/时间缺失或歧义,现场无法区分。

目标

  1. order_result_unknown 仍携带并持久化创建订单前已经严格验证的实际单价;不得由订单详情推测或补算。
  2. Android 对核单失败输出稳定、脱敏的阶段码和可读原因,至少区分恢复/前台、支付页、订单上下文、订单号、下单时间和证据歧义。
  3. Agent Outbox、Server ResultRequest、任务/attempt、Admin 详情和 Agent 历史保持同一最终事实;未知结果不能伪装成 failed 或 order_created。
  4. 不保存或记录订单号候选、页面文字、地址、账号、控件树、坐标或截图;只有取得唯一订单号和有效下单时间时才进入 order_created。

非目标

  • 不修改或人工补写 CG-36。
  • 不重试任务、不再次创建订单、不取消订单、不支付。
  • 不放宽订单号唯一性、时间解析或未付款证据要求。
  • 不修改 Admin 页面布局;现有字段绑定足以显示持久化结果。
  • #163 负责微信恢复后的异步等待竞态,本单不重复修改其导航动作次数和安全边界。

实施方案

  • Android 核单器保留现有 PurchaseOrderEvidence? 成功契约,同时记录一次调用内的稳定失败阶段;每次调用前清空,所有失败出口显式设置。
  • 稳定阶段不包含页面原文或数据值,覆盖:空窗口超时、微信恢复失败/超时、未知应用、选择器返回失败、支付页返回失败/重复、订单上下文未出现、订单号缺失/歧义、下单时间缺失/无效、未付款证据缺失。
  • PurchaseExecutionOutcome(order_result_unknown) 携带阶段码、限长可读原因及 observedPrice;中断恢复没有可信价格时保持为空。
  • 结果 JSON 对 order_result_unknown 写入错误码/原因;Server 校验允许的稳定码、保存实际单价和错误字段,同时保持状态为 order_result_unknown、attempt 为 failed。
  • Admin/Agent 历史继续读取现有字段,无 UI 结构变化。

验收标准

  • 核单各失败出口都有稳定阶段,不记录页面原文、候选订单号、时间原文或个人数据。
  • order_result_unknown payload 包含稳定错误码/原因;存在已验证实际单价时同时携带,不存在时保持空。
  • Server 只在 live + order_submit_started 接受未知结果,并持久化实际单价与错误字段;非法状态仍拒绝。
  • order_created 仍强制唯一非空订单号和下单时间;未知结果不得写入这两个字段。
  • Admin 详情可通过现有映射读取实际单价和未知原因;无需页面改版。
  • Android、Server 单元/契约测试及构建通过;不执行 live 真机任务。

风险与安全门禁

本单处理订单不可逆边界后的结果契约。实现和自动化测试不触发设备下单;任何 CG-36 操作、live 重试、地址修改、创建订单或支付仍需独立人工授权。永久禁止支付。

设计证据

恢复既有 Admin 字段与核单审计行为,无新页面或交互,不需要 UI 原型。共享 API 和状态语义由代码测试及 Android-Agent-API-Contract 作为设计证据。

文档影响

有长期契约影响:order_result_unknown 新增稳定错误阶段并允许保留已验证实际单价。须先更新线上 Wiki Android-Agent-API-Contract、回读 revision,再执行一次 harness.py sync 和一次 sync --check。

状态

待验收(实现、自动化验证、构建与 Wiki 同步已完成;未执行 live 真机验收,不自动关闭)。

## 原始需求摘要 来源:用户于 2026-08-31 反馈 CG-36 已成功创建待付款订单并最终进入 PDD 订单详情,但 Admin 没有订单编号、下单时间及其他动态执行数据;只读分析后确认按建议处理。 目的:当订单结果仍无法唯一确认时,保留创建订单前已经验证的非订单动态事实,并向 Server/Admin 提交不含敏感信息的稳定核单失败阶段;Admin 继续以数据库最终事实展示,不从页面或历史任务猜测订单号。 ## 基线与已确认事实 代码基线:`a3628df`,Agent `0.9.31`、PDD `8.22.0`、CG30/device 5,核验时间 2026-08-31。 - CG-36 为 `live`,状态 `order_result_unknown`;已有 `orderSubmitRequestId`、`irreversibleAt`,但 `pddOrderNo`、`orderSubmittedAt`、`actualUnitPriceCent` 均为空。 - CG-36 的 SYB、虾皮、PDD 关联和地址后缀快照仍存在,说明 Agent→Server 提交及 Admin 查询链路正常;缺失的是动态核单结果和已验证实际单价。 - Android `order_result_unknown` outcome 未携带先前 `verifyUnitPrice` 得到的 `observedPrice`;结果序列化只对 `failed` 写错误码/原因。 - Server 的 `order_result_unknown` 分支只迁移状态,不保存 `ActualUnitPriceCent`、`ErrorCode`、`ErrorMessage`。 - Admin 已直接映射上述数据库字段;当前不是前端漏字段。 - 现有核单器以 nullable 结果折叠空窗口超时、微信恢复失败、未知应用、支付页返回失败、订单上下文缺失、订单号/时间缺失或歧义,现场无法区分。 ## 目标 1. `order_result_unknown` 仍携带并持久化创建订单前已经严格验证的实际单价;不得由订单详情推测或补算。 2. Android 对核单失败输出稳定、脱敏的阶段码和可读原因,至少区分恢复/前台、支付页、订单上下文、订单号、下单时间和证据歧义。 3. Agent Outbox、Server ResultRequest、任务/attempt、Admin 详情和 Agent 历史保持同一最终事实;未知结果不能伪装成 `failed` 或 `order_created`。 4. 不保存或记录订单号候选、页面文字、地址、账号、控件树、坐标或截图;只有取得唯一订单号和有效下单时间时才进入 `order_created`。 ## 非目标 - 不修改或人工补写 CG-36。 - 不重试任务、不再次创建订单、不取消订单、不支付。 - 不放宽订单号唯一性、时间解析或未付款证据要求。 - 不修改 Admin 页面布局;现有字段绑定足以显示持久化结果。 - #163 负责微信恢复后的异步等待竞态,本单不重复修改其导航动作次数和安全边界。 ## 实施方案 - Android 核单器保留现有 `PurchaseOrderEvidence?` 成功契约,同时记录一次调用内的稳定失败阶段;每次调用前清空,所有失败出口显式设置。 - 稳定阶段不包含页面原文或数据值,覆盖:空窗口超时、微信恢复失败/超时、未知应用、选择器返回失败、支付页返回失败/重复、订单上下文未出现、订单号缺失/歧义、下单时间缺失/无效、未付款证据缺失。 - `PurchaseExecutionOutcome(order_result_unknown)` 携带阶段码、限长可读原因及 `observedPrice`;中断恢复没有可信价格时保持为空。 - 结果 JSON 对 `order_result_unknown` 写入错误码/原因;Server 校验允许的稳定码、保存实际单价和错误字段,同时保持状态为 `order_result_unknown`、attempt 为 failed。 - Admin/Agent 历史继续读取现有字段,无 UI 结构变化。 ## 验收标准 - [ ] 核单各失败出口都有稳定阶段,不记录页面原文、候选订单号、时间原文或个人数据。 - [ ] `order_result_unknown` payload 包含稳定错误码/原因;存在已验证实际单价时同时携带,不存在时保持空。 - [ ] Server 只在 live + `order_submit_started` 接受未知结果,并持久化实际单价与错误字段;非法状态仍拒绝。 - [ ] `order_created` 仍强制唯一非空订单号和下单时间;未知结果不得写入这两个字段。 - [ ] Admin 详情可通过现有映射读取实际单价和未知原因;无需页面改版。 - [ ] Android、Server 单元/契约测试及构建通过;不执行 live 真机任务。 ## 风险与安全门禁 本单处理订单不可逆边界后的结果契约。实现和自动化测试不触发设备下单;任何 CG-36 操作、live 重试、地址修改、创建订单或支付仍需独立人工授权。永久禁止支付。 ## 设计证据 恢复既有 Admin 字段与核单审计行为,无新页面或交互,不需要 UI 原型。共享 API 和状态语义由代码测试及 `Android-Agent-API-Contract` 作为设计证据。 ## 文档影响 有长期契约影响:`order_result_unknown` 新增稳定错误阶段并允许保留已验证实际单价。须先更新线上 Wiki `Android-Agent-API-Contract`、回读 revision,再执行一次 `harness.py sync` 和一次 `sync --check`。 ## 状态 待验收(实现、自动化验证、构建与 Wiki 同步已完成;未执行 live 真机验收,不自动关闭)。
Author
Owner

实施与验证结果(待验收)

已提交并推送 ff0cf99 fix(goauto): preserve unknown order evidence (#167),最终 Agent 版本 0.9.33(versionCode 46)。

实现:

  • Android 核单失败按白名单稳定阶段返回,不包含页面原文、订单号候选、时间原文、地址、账号、坐标、控件树或截图。
  • order_result_unknown Outbox 现在携带稳定错误码/原因;创建订单前已严格验证的实际单价存在时一并携带,中断恢复无可信价格时仍为空。
  • Server 只在 live + order_submit_started 接受未知结果;拒绝在未知结果中提交订单号或下单时间,拒绝非白名单失败码。
  • Server 不信任 Agent 错误文案,按白名单错误码写入固定脱敏提示,并将同一阶段写入 task 与 attempt;同时保存非负实际单价。
  • 兼容旧 Agent:错误码和原因均为空时归一为 PURCHASE_ORDER_RESULT_UNKNOWN。
  • Admin 和 Agent 历史继续读取现有数据库字段,无页面布局变化。

验证:

  • Android 定向 PurchaseLiveAutomationTest、PurchaseResultPayloadTest 通过。
  • Android 全量 test assembleDebug assembleRelease --rerun-tasks:BUILD SUCCESSFUL(90 tasks)。
  • Server go test ./... 与 go build ./...:通过。
  • python dev_scripts/harness.py check --strict、git diff --check:通过。
  • Wiki Android-Agent-API-Contract 已在线更新并回读 revision 6990b1a92006572069d13bdffba1ffc5bfc0f13d;镜像同步与一致性检查通过。

安全边界:未修改/补写/重试 CG-36,未安装 APK,未启动正式采购,未修改地址、未创建订单、未支付。CG-36 仍保持 order_result_unknown 和不可逆事实,必须人工核对;本次代码不会追溯猜测历史订单号。

结论:实现、自动化、构建和文档闭环完成,工单保持打开并转待验收。

## 实施与验证结果(待验收) 已提交并推送 `ff0cf99 fix(goauto): preserve unknown order evidence (#167)`,最终 Agent 版本 `0.9.33`(versionCode 46)。 实现: - Android 核单失败按白名单稳定阶段返回,不包含页面原文、订单号候选、时间原文、地址、账号、坐标、控件树或截图。 - `order_result_unknown` Outbox 现在携带稳定错误码/原因;创建订单前已严格验证的实际单价存在时一并携带,中断恢复无可信价格时仍为空。 - Server 只在 `live + order_submit_started` 接受未知结果;拒绝在未知结果中提交订单号或下单时间,拒绝非白名单失败码。 - Server 不信任 Agent 错误文案,按白名单错误码写入固定脱敏提示,并将同一阶段写入 task 与 attempt;同时保存非负实际单价。 - 兼容旧 Agent:错误码和原因均为空时归一为 `PURCHASE_ORDER_RESULT_UNKNOWN`。 - Admin 和 Agent 历史继续读取现有数据库字段,无页面布局变化。 验证: - Android 定向 `PurchaseLiveAutomationTest`、`PurchaseResultPayloadTest` 通过。 - Android 全量 `test assembleDebug assembleRelease --rerun-tasks`:BUILD SUCCESSFUL(90 tasks)。 - Server `go test ./...` 与 `go build ./...`:通过。 - `python dev_scripts/harness.py check --strict`、`git diff --check`:通过。 - Wiki `Android-Agent-API-Contract` 已在线更新并回读 revision `6990b1a92006572069d13bdffba1ffc5bfc0f13d`;镜像同步与一致性检查通过。 安全边界:未修改/补写/重试 CG-36,未安装 APK,未启动正式采购,未修改地址、未创建订单、未支付。CG-36 仍保持 `order_result_unknown` 和不可逆事实,必须人工核对;本次代码不会追溯猜测历史订单号。 结论:实现、自动化、构建和文档闭环完成,工单保持打开并转待验收。
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#167