Files

112 lines
13 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-401
title: 首次真实提交与生产接线
phase: 4
deps: [T-400, T-402]
status: TODO
created: 2026-08-04
vikunja_task_id: 52
context_ref: 8600c33
work_branch: task/t-401-first-real-submission
needs_device: true
needs_human_review: true
write_paths:
- docs/tasks/T-401.md
- client/src/cmbuyer_client/pdd/order_submission.py
- client/src/cmbuyer_client/execution/**
- client/src/cmbuyer_client/ui/**
- client/src/cmbuyer_client/app.py
- client/tests/pdd/test_order_submission.py
- client/tests/execution/**
- client/tests/ui/**
- client/tests/test_app.py
---
<!-- BEGIN VIKUNJA EXPORT id=52 synced=2026-08-06T02:59:12Z sha256=e388ed4e91052ce9d8a0a7b5ac0aa55f7721a3133c17cc5eff948dae4167ce21 -->
## 问题 / 背景
T-107 已把订单确认页、闸门三与精确唯一“提交订单”控件限制为证据/App 版本绑定的只读能力,T-308 将只在当前进程首次明确围栏许可后产生不可恢复 permit,T-400 只用测试 fixture 证明四条件与一次性编排。T-305 的真实 dry-run 已安全 Back 并以 DRY_RUN_COMPLETED_BEFORE_FENCE 终止 attempt,只能提供已验收代码/判据契约,任何运行对象、截图、缓存或 proof 都不能提交。T-401 必须领取一条新的已授权真实任务,在全新 attempt 的同一设备会话中从打开商品开始实时重跑 Gate1、数量/Gate2、确认页/Gate3,并在仍停留于当前确认页时即时构造生产 ReadyForSubmission,随后才可申请围栏和精确点击一次。系统只创建可能的待付款订单,绝不付款;首次提交后页面无本项目证据,因此点击后无条件上报 UNKNOWN 并由 T-403 调和。
## 关联需求与交互
- 功能:F-005、F-006、F-007、F-011、F-017。
- 用户故事:US-003、US-004、US-005、US-008。
- 交互:IX-008、IX-011;执行员没有人工“提交订单”按钮。
- 依赖:T-400、T-402;T-400 传递 T-305/T-308 的已验收契约但不传递任何运行时 ReadyForSubmission,T-402 传递 T-403 并保证点击后已有安全调和与待付款收口。
- 需要真机和人工安全验收;agent 只能实现、离线验证和准备命令,不得自行触发真实提交或标 DONE。
## 方案
1. 生产执行只接受本次新领取的 PENDING + ACTIVE 授权任务,由服务端创建新的 active attempt/generation。已有 DRY_RUN_COMPLETED_BEFORE_FENCE、FAILED、FENCED、ABANDONED 或其它结束 attempt,以及 T-305 的 task/attempt id 都必须在任何页面动作和 fence 前拒绝。
2. 在一个不中断的全新设备会话中按固定顺序执行:打开本次任务 canonical 商品 → 受控入口/精确选规格 → Gate1 当前 SKU 单价 → 设置并读回数量 → 重读规格与 Gate2 单价 → 进入订单确认页 → Gate3 规格/数量/总额 → 只读确认精确唯一最终控件。每一步都使用当前 attempt 的实时事实和新证据,不能跳步或使用历史值。
3. 生产 ReadyForSubmission 构造入口首次且仅在 T-401 composition 内出现:只有上述当前步骤全部成功、当前 claim/authorization/attempt/generation/App 版本仍一致、三个 AssetRef 均属于本次 attempt,并且仍停留在刚验证的确认页时,才即时构造不可持久化的临时对象交 T-400 编排。
4. ReadyForSubmission 不写入 SQLite、文件、缓存、日志或恢复快照,不提供 from_dry_run/from_snapshot/from_evidence/from_localstate。构造后页面 Back/导航、claim/lease/授权变化、App 版本/前台包变化、证据或任务版本漂移都立即使其失效并零 fence/零点击;不能重新加载或跨重启恢复。
5. 静态和运行边界显式拒绝 T-305 PreFenceDryRunResult、DRY_RUN_COMPLETED_BEFORE_FENCE attempt、dry-run screenshot/AssetRef、action journal、缓存页面对象和旧 proof。T-305 已 Back 的页面不能“返回去继续”,必须领取新任务从商品打开开始。
6. 在生产 composition root 接入 T-400 SinglePassSubmissionOrchestrator、T-308 SubmissionSink 与极窄 PDD SubmitOrderPort。UI 只显示自动阶段和安全状态,不提供执行员可点击的提交、重试、释放围栏或继续按钮。
7. 具体 SubmitOrderPort 只接受当前进程一次性 ArmedSubmission 和本次 T-107 判据生成的 VerifiedSubmitObservationBoundary。点击前在当前确认页再次执行精确文本、唯一可点击祖先、前台包与 App 版本检查;不得接受任务下发 selector/坐标、通用 click、相似文案、OCR 或旧项目常量。
8. T-308 必须已 durable 写入“即将发出唯一点击”且本地状态进入 RECONCILE_ONLY,才允许调用底层真机点击。低层点击语句在生产调用图中恰好一个调用点、执行恰好一次;不能放在循环、重试器、finally、恢复回调或可重复 signal handler 中。
9. 四条件任一缺失、页面实时复核漂移、围栏响应不明、许可不是首次、持久化失败、App/设备/claim 状态变化均零点击并停止。停止轮询、Esc、查看历史、关闭窗口、超时、异常和进程重启都不得重构 ReadyForSubmission、重新 arm、重做页面动作或再次点击。
10. 点击调用返回、抛错或超时后不再与页面交互。首次真实运行没有提交后页面判据,客户端必须无条件以固定 UNKNOWN 上报同一 submission,任务进入 RECONCILIATION_REQUIRED;即使人看到待付款页,也不得由客户端推断或改报 SUBMITTED。
11. T-401 不采集、持久化或上传点击后的截图/XML,不新增 SUBMISSION_RESULT evidence kind,不把 Gate3 图冒充结果图。尤其不得截取或上传外部支付页、支付凭据、安全校验页面;点击后结果只由管理员在 T-403 调和同一 submission。
12. UNKNOWN result HTTP 不明时只由 T-308 用原 result_key、原载荷调和;不得重复观察页面、生成新 key、重新提交、释放围栏、重新授权、重新领取或推进下一任务。
13. 首次真实运行必须使用项目所有者专门创建并授权的低风险新任务,在 T-305 dry-run 和全部离线门禁通过后,由项目所有者在执行记录中给出针对本次运行的一次性明确批准。额外批准只是首次发布验收,不新增产品内第二授权按钮。
14. 真实点击后由人检查手机和采购服务,只通过 T-403 选择 CONFIRMED_CREATED、CONFIRMED_NOT_CREATED_OR_CANNOT_COMPLETE 或 STILL_UNKNOWN。系统不支付、不自动取消外部订单;人负责说明订单是否产生及如何处置。
## 验收要点
- 测试证明只有新领取、未结束且当前归属一致的 attempt 能开始;T-305/DRY_RUN_COMPLETED_BEFORE_FENCE、FAILED、FENCED、ABANDONED、旧 generation 和跨 task/authorization 均零页面动作、零 fence、零点击。
- 动作/事件序列严格证明本次新 attempt 在同一会话执行商品打开→Gate1→数量/Gate2→确认页/Gate3→即时 ReadyForSubmission→fence→点击;不得出现引用 T-305 截图、缓存、AssetRef、journal 或 proof。
- ReadyForSubmission factory 仅 T-401 production composition 可达,输入只来自本次内存实时结果;AST/数据流测试证明无 dry-run/storage/cache/restart factory,Back/导航/版本/claim 漂移后对象失效。
- 离线 fake-device/port 测试覆盖四条件缺一、控件 0/2 个、文本/版本/前台包漂移、非首次 permit、点击意图落盘失败、并发进入、停止/关闭/重启,所有负例底层点击数为 0。
- 唯一成功调用测试证明点击意图已先落盘、底层点击调用数恰好为 1;底层返回、异常和超时后再次进入/重启的累计点击数仍为 1,没有 retry/fallback。
- 点击后的所有离线分支都只生成 UNKNOWN;静态测试禁止 SUBMITTED 推断、提交后截图/XML/evidence 上传,以及页面观察或第二次点击。
- AST/import/call graph 证明只有一个生产低层提交点击点,且支付、免密支付、先用后付、扣款控件、人工提交按钮和通用 click 不可达。
- 运行 client 全量 unittest、compileall、wheel metadata、完整 init、上下文、Vikunja export 与 diff-check;人工放行前不得运行真机提交命令。
- 真机记录必须包含“全新任务/授权/attempt”证明、设备型号、Android、连接方式、拼多多版本、goods_id、task/authorization/attempt/submission id、本次三闸门值/AssetRef、唯一控件计数、fence 首次许可、点击意图先落盘、低层点击恰好一次、UNKNOWN/RECONCILIATION_REQUIRED、T-403 人工结论、订单是否产生/如何处置和“未付款”。不得记录 token、地址/手机号字段、支付凭据或点击后截图/XML。
- 真机运行与最终结论只能由项目所有者明确批准并人工确认;确认前保持 DOING,agent 不得自行执行、推断成功或标 DONE。
## 执行记录
### 2026-08-06T02:58:55Z · ila
2026-08-06T02:58:54.857Z · Codex
2026-08-06 生产单趟删除“进入确认页”步骤:数量/Gate2 后保持同一最终面板,实时读取结构化最终控件金额作为 Gate3,再申请围栏。真实点击仍必须四条件全过且只一次;点击会直接创建待付款订单并进入付款界面,随后立即停止、绝不付款。
<!-- END VIKUNJA EXPORT -->
## 边界
- 2026-08-06 起生产单趟在数量/Gate2 后保持同一合并式最终提交面板,读取结构化最终控件金额作为
Gate3;不存在确认页导航。最终点击会直接创建待付款订单并进入付款界面,仍须四条件全过、只点
一次,点击后立即停止并调和,绝不执行付款。
- 本任务只把 T-107 已取证且绑定拼多多 App 版本的精确唯一最终控件、T-308 当前进程首次明确
`SubmissionPermit` / 一次性 `ArmedSubmission` 和 T-400 离线编排接入生产。不得接收服务端
selector/坐标/动作脚本,不得使用相似文案、OCR、通用 click、旧项目常量或未取证页面能力。
- 每次生产执行必须领取一条新的 `PENDING` + `ACTIVE` 授权真实任务,并由服务端创建新的 active
attempt/generation。在一个全新且不中断的同一设备会话内,严格重新执行商品打开 → Gate1 → 数量
设置/读回与 Gate2 → 确认页/Gate3 → 当前最终控件只读复核;不能从中间页面或旧 attempt 续跑。
- T-305 正常 dry-run 已安全 Back,并以 `DRY_RUN_COMPLETED_BEFORE_FENCE` 终止 attempt。其任何
结果对象、task/attempt id、screenshot/AssetRef、action journal、缓存页面对象、本地快照或旧 proof
永远不得用于生产 `ReadyForSubmission`、申请 fence 或提交;结束/失败/围栏后的其它 attempt 同样拒绝。
- 生产 `ReadyForSubmission` 只能在本次新 attempt 的 Gate3 与唯一控件刚刚实时通过、仍停留当前
确认页且 claim/lease/authorization/generation/App 版本全部一致时即时构造。对象不得持久化、缓存、
序列化或跨导航/Back/重启恢复;任一事实漂移立即失效并零 fence、零点击。
- 只有一次性授权与服务端首次围栏许可、Gate2、Gate3、精确唯一提交控件四条件同时成立,并且
T-308 已 durable 写入点击意图和 `RECONCILE_ONLY`,才可调用低层提交点击。生产调用图中低层
点击恰好一个调用点、运行恰好一次;不得位于循环、retry、fallback、`finally` 或恢复回调。
- 围栏/许可/持久化/页面复核任一失败均零点击。点击调用返回、抛错、超时、停止轮询、Esc、查看
历史、关闭窗口或重启都不得重新 arm、重复页面动作或再次点击,也不得释放围栏、重新授权、
重新领取或推进下一任务。
- 首次真实提交后的页面尚无本项目真机证据。点击后客户端必须无条件上报固定 `UNKNOWN` 并进入
`RECONCILIATION_REQUIRED`;不得解析页面、根据人眼结论推断 `SUBMITTED`,也不得把结果改报为
其他 observation。订单是否产生只由管理员通过 T-403 调和同一 submission。
- 本任务不得采集、持久化或上传点击后的截图/XML,不新增结果 evidence kind,不把 Gate3 图冒充
结果图。尤其不得保存或上传外部支付页、支付凭据或安全校验页面。
- 采购工具不得提供人工“提交订单”、重试提交、释放围栏或继续执行按钮。UI 只能显示后台自动阶段、
submission id 和“可能已创建订单,禁止再次提交,只能人工调和”的安全状态。
- 系统不点击支付、免密支付、先用后付或任何扣款控件,不自动取消外部订单。真实订单是否产生、
是否付款和如何处置均由人负责;`WAITING_PAYMENT` 不等于成功。
- 真实运行除管理员“开始采购”的业务授权外,还必须由项目所有者在任务执行记录中针对本次首次
发布验收给出明确一次性批准。agent 不得自行运行真实提交命令、确认真机结论或标 `DONE`;
`needs_device` 与 `needs_human_review` 未同时由人确认前必须保持 `DOING`。