docs(tasks): define T-305 prefence dry run

This commit is contained in:
QiuSW
2026-08-04 22:14:55 +08:00
parent c1cee49fb1
commit 19f81a5e58
2 changed files with 103 additions and 9 deletions
+11 -9
View File
@@ -19,7 +19,7 @@ Phase 是里程碑分组,不是整段串行栅栏。推荐波次:
| --- | --- | --- | --- |
| 1 | T-001 → T-004 → T-201 → T-202 | T-002 → T-101 → T-102 | T-003、原型与契约 |
| 2 | T-209 → T-203 → T-204 | T-103 → T-104 → T-105 → T-107 | T-111 单趟重构;逐任务主审 |
| 3 | T-205 → T-207 → T-208 | T-301 → T-304 → T-306 | 双端契约完整门禁 |
| 3 | T-205 →(T-206 → T-207)/ T-210 → T-208 | T-301 → T-302 → T-303,再并行 T-304 / T-306 / T-307 | 双端契约完整门禁 |
| 4 | - | T-305 | 围栏前端到端 dry-run 主审 |
| 5 | T-402 / T-403 | T-401 | 真机人工授权、提交与调和验收 |
| 6 | - | T-405 | T-404 完整验收 |
@@ -59,9 +59,9 @@ Phase 是里程碑分组,不是整段串行栅栏。推荐波次:
| T-102 | 验证按链接打开商品详情页 | T-101 | canonical goods 链接进入对应商品;前台包与 goods_id 有证据 |
| T-103 | 验证受控规格面板、精确选择与 SKU 单价 | T-102, T-110, T-111 | 精确唯一入口、维度内等值选择/读回、防前缀碰撞、当前价唯一读取;隔离 capability 不含数量/确认/提交 |
| T-104 | 验证规格选择能力安全退出 | T-103 | 完成选择/读价/截图后可关闭面板或退出;不进入确认页、不提交 |
| T-105 | 验证数量设置、读回与闸门二 | T-103 | 设置数量并精确读回;再次读规格/单价等于闸门一;不一致即停 |
| T-106 | dry-run:确认页与闸门三取证 | T-105 | 进入确认页读规格、数量、应付总额并验证提交控件唯一;绝不点击 |
| T-107 | 固化确认页与提交控件安全判据 | T-106 | 只使用本项目证据;dry-run 静态不可达提交;版本失配 fail closed |
| T-105 | 验证数量设置、读回与闸门二 | T-104 | 先只读取证并由人确认,再设置数量、精确读回并复核规格/单价;不一致即停 |
| T-106 | dry-run:确认页与闸门三取证 | T-105 | 只读采集导航前、确认页、最终控件及一次人工 Back 状态;agent 不执行页面动作 |
| T-107 | 固化确认页与提交控件安全判据 | T-106 | 只点已取证导航控件一次;最终控件只读观察;一次 Back;静态不可达提交 |
| T-110 | 批准证据绑定的受控规格入口 | T-103 no-go 决策 | 仅批准拼多多 8.17.0 已取证的精确唯一“快要抢光”,不泛化 |
| T-111 | 调整为开始采购授权的单趟流程 | T-004, T-010, T-110 | 状态/API/原型/任务依赖一致;删除试选后确认但不放宽三闸门和围栏 |
@@ -77,10 +77,11 @@ T-106 / T-107 是发布前只读验证,不是业务任务的第一趟。首次
| T-209 | 把核心 schema / 状态机迁移为单趟模型 | T-004, T-111 | 新 migration 安全替换旧 `spec_trials` / 授权锁价结构;新增 `purchase_attempts`;删除旧 MVP 状态;无业务数据事实写入迁移前置,遇未知旧数据 fail closed;领域/迁移测试同步 |
| T-203 | 表格查询与批量开始采购(F-004、F-008、F-018) | T-202, T-209 | 只选 DRAFT;按钮明确“不付款”;事务内创建锁定任务字段的一次性授权并全批 `DRAFT → PENDING`;重放/冲突测试 |
| T-204 | 路由化任务详情与内部截图资产(F-007、F-011) | T-203 | 抽屉/完整页共享 URL;状态详情;受保护 `INTERNAL_RAW` screenshot 上传/读取、SHA-256 与 no-store;不接收 XML |
| T-205 | purchase attempt、事件与执行摘要 API | T-204, T-103 | 记录实际规格、两次单价、数量、确认页金额、固定 reason;不再创建 `spec_trials` 审批记录 |
| T-205 | purchase attempt、事件与执行摘要 API | T-103, T-204, T-301, T-302 | 记录实际规格、两次单价、数量、确认页金额、固定 reason;不再创建 `spec_trials` 审批记录 |
| T-210 | 扩展闸门二与闸门三证据类型 | T-107, T-205 | 精确扩展 Gate2/Gate3 kind;保留 Gate1、归属/FK/trigger/幂等;有新事实时拒绝降级 |
| T-206 | 单趟状态视图与安全主动作 | T-205 | PENDING/CLAIMED/ORDERING/NEEDS_MANUAL/WAITING_PAYMENT/RECONCILIATION_REQUIRED 显示和允许动作一致;无中途确认 |
| T-207 | 授权有效期与围栏前重置(F-010) | T-206 | 围栏前过期/关闭旧授权后回 DRAFT;围栏后拒绝释放、取消、重新授权 |
| T-208 | 提交围栏与结果调和 API(F-017) | T-207, T-107 | 原子复核授权/attempt/三闸门/唯一控件;首次许可一次;重放不许可点击;结果不明永久围栏且只调和 |
| T-208 | 提交围栏与结果调和 API(F-017) | T-207, T-107, T-210 | 原子复核授权/attempt/三闸门/唯一控件;首次许可一次;重放不许可点击;结果不明永久围栏且只调和 |
### Phase 3 · 双端打通(单趟围栏前)
@@ -88,10 +89,11 @@ T-106 / T-107 是发布前只读验证,不是业务任务的第一趟。首次
| --- | --- | --- | --- |
| T-301 | 设备凭据与身份隔离(F-013) | T-201 | Bearer 不能建单/授权;管理会话不能领任务;凭据可撤销 |
| T-302 | 已授权任务原子领取与租约(F-005) | T-301, T-203 | 只领 PENDING+有效授权;并发唯一;重放同一 attempt;claim token/generation 有效 |
| T-303 | `HttpTaskSource` / `HttpResultSink` | T-302, T-002 | 执行器依赖抽象;幂等重放;线协议严格校验;不扩大 Excel 范围 |
| T-303 | HTTP 任务源、证据 sink 与可恢复本地状态 | T-002, T-204, T-302 | 严格 claim/renew/evidence HTTP、DPAPI/SQLite、单实例和原子恢复槽;不伪造完整 ResultSink |
| T-304 | 定时轮询与会话边界 | T-303, T-006 | 人启动后轮询;停止只阻止下次领取;连续失败停;当前任务/记录详情双视图 |
| T-306 | 单趟截图与证据上传 | T-304, T-204 | 显式上传原始 screenshot;可含页面地址/手机号;完整 XML、本机路径、外部支付页不上传 |
| T-305 | **单趟围栏前端到端 dry-run** | T-306, T-107, T-205 | 从领取连续跑到闸门三与提交控件验证,随后安全停止;全程事件/证据齐全,不申请真实许可、不点击提交 |
| T-306 | 规格面板原始截图与可靠证据上传 | T-104, T-303 | 只发布 Gate1 的显式原始 PNG;唯一恢复槽;可含页面地址/手机号;不上传 XML/路径或扩 kind |
| T-307 | 客户端 attempt 事件与失败 sink | T-205, T-303 | 窄 events/fail HTTP 与同键恢复;不实现 ResultSink、围栏、结果、PDD 或 UI |
| T-305 | **单趟围栏前端到端 dry-run** | T-107, T-304, T-306, T-307, T-210 | 连续跑到三闸门及最终控件只读观察,随后一次安全 Back 并以固定 reason 停在围栏前;不申请许可、不点击提交 |
### Phase 4 · 真实提交与收尾
+92
View File
@@ -0,0 +1,92 @@
---
id: T-305
title: 围栏前单趟 dry-run 编排
phase: 3
deps: [T-107, T-304, T-306, T-307, T-210]
status: TODO
created: 2026-08-04
vikunja_task_id: 44
context_ref: c1cee49
work_branch: task/t-305-prefence-dry-run
needs_device: true
needs_human_review: true
write_paths:
- docs/tasks/T-305.md
- client/src/cmbuyer_client/execution/**
- client/src/cmbuyer_client/core/**
- client/src/cmbuyer_client/remote/**
- client/src/cmbuyer_client/localstate/**
- client/src/cmbuyer_client/polling/**
- client/src/cmbuyer_client/ui/**
- client/src/cmbuyer_client/app.py
- client/tests/execution/**
- client/tests/core/**
- client/tests/remote/**
- client/tests/localstate/**
- client/tests/polling/**
- client/tests/ui/**
- client/tests/test_app.py
- docs/api.md
- docs/04-architecture.md
- docs/06-tasks.md
- docs/current-state.md
---
<!-- BEGIN VIKUNJA EXPORT id=44 synced=2026-08-04T14:13:33Z sha256=01cdc47330b88791356618a90caed5e884666ad1b153ed136e6d3aacf51d8faf -->
## 问题 / 背景
T-103~T-107 分段固化真机页面能力,T-303/T-304 提供本地恢复与桌面执行壳,T-306/T-307 提供三闸门证据上传和 attempt 事件/失败 sink,T-210 扩展完整三闸门证据类型。T-305 只把这些已完成能力组合为围栏前 dry-run,验证领取后同一趟执行可以安全到达最终提交控件观察点,并在任何不可逆动作前停止。
## 关联需求与交互
- 功能:F-005、F-006、F-007、F-013、F-017 的围栏前部分。
- 用户故事:US-003、US-004、US-005。
- 依赖:T-107、T-304、T-306、T-307、T-210。
- 后续消费者:T-208 提交围栏与真实单次提交。
- 本任务不得调用 submission fence、result 或订单提交能力。
## 方案
1. 实现窄 PreFenceDryRunOrchestrator,只依赖已冻结的 claim/renew、attempt event/fail、三闸门 EvidenceSink、T-103/T-105/T-107 页面能力和 T-304 UI 执行外壳;不直接实现 HTTP、PDD selector 或新页面判据。
2. 首次领取后把 authorization/task/attempt/generation/claim/版本快照和执行载荷原子写入 T-303 localstate;页面动作前写 action journal。重启只调和 HTTP 与展示人工恢复状态,不自动续跑任何手机点击。
3. 同一趟严格执行:规格面板闸门一 → 数量设置与闸门二 → 唯一证据绑定的确认页导航 → 闸门三与最终提交控件只读观察 → 一次安全 Back。任一前置条件、读回、价格或证据失败立即 fail closed。
4. 三闸门每次都先把原始 PNG 交 T-306 持久化固定 upload_key/metadata/hash,再用 T-307 追加对应成功事件;事件只能引用服务端确认的 AssetRef。未知上传结果只重放同键同文件,不重做页面动作或替换证据。
5. 动作日志使用固定动作类型、attempt/generation/阶段、开始时间与明确后置状态;不保存 selector、坐标、自由页面文本、XML、地址、手机号或 token。点击结果不明时停止并转人工,不以重启或超时自动重试。
6. 完成闸门三观察且一次 Back 验证安全返回后,写固定失败终止 reason DRY_RUN_COMPLETED_BEFORE_FENCE,使 attempt/task 进入围栏前人工状态。不得请求或模拟围栏,不得创建 order_submission。
7. HTTP 出站仅允许 T-303 transport 固定 loopback API;import 闭包和静态测试禁止 SubmissionPermit、fence/result client、click_permitted、submitter、submit_order_once、支付模块。
8. UI 显示当前执行阶段、已确认的最小任务摘要和滚动日志;Esc 只处理详情/当前任务切换,不取消在途请求、不清本地 journal、不释放 claim、不触发真机动作。
## 验收要点
- 离线组合测试覆盖正常三闸门、每一步失败、价格/规格/数量漂移、证据未知结果、事件未知结果、租约/授权到期、重启和 active claim 漂移。
- 证明每个页面动作前已有 journal;不明结果和重启均零自动页面动作,只有同键 HTTP 调和。
- 证明 Gate1/Gate2/Gate3 的 PNG、captured_at 与 AssetRef 顺序正确,事件不能先于证据成功,也不能串 attempt/generation。
- 正常 dry-run 最终只产生 DRY_RUN_COMPLETED_BEFORE_FENCE,不存在 fence、order_submission、result 或提交点击。
- 静态调用图/import 闭包证明不可达 submission fence、SubmissionPermit、click_permitted、submit_order_once 与任何付款能力。
- 真机验收必须由人完成,记录设备/Android/拼多多版本、三个证据路径、三闸门读回、最终控件只读观察和一次 Back 后置状态;确认前保持 DOING。
- client 全量 unittest、compileall、wheel metadata、完整 init、上下文、Vikunja export 与 diff-check 通过。
## 执行记录
### 2026-08-04T14:11:20Z · ila
2026-08-04 任务定值:T-305 只做围栏前单趟 dry-run,总装已验收的 T-107/T-304/T-306/T-307/T-210 能力;正常路径最终写 DRY_RUN_COMPLETED_BEFORE_FENCE 并安全返回,不请求围栏、不创建 order_submission、不点击提交订单、不涉及付款。
<!-- END VIKUNJA EXPORT -->
## 边界
- 只实现 `PreFenceDryRunOrchestrator` 与围栏前 UI 组合;不得在本任务的构造、import 闭包或运行时
引入 submission fence/result client、`SubmissionPermit`、`click_permitted`、submitter、
`submit_order_once()`、`order_submission` 或任何付款能力。
- 本任务不得修改 `client/src/cmbuyer_client/pdd/**` 或新增页面 selector/坐标/判据;只调用依赖任务
已完成人工验收且版本绑定的窄能力。未完成验收、版本不匹配或观察不唯一时必须停止,不能猜测。
- 同一趟动作顺序固定为闸门一、数量与闸门二、证据绑定的唯一确认页导航、闸门三/最终控件只读观察、
一次安全 Back。最终控件不得暴露节点/selector/坐标/句柄,也不得发生点击。
- 每个真机动作前必须先写固定 action journal。结果不明、超时、停止、Esc、关闭窗口或重启均不得
自动重试页面动作、续跑下一步、清 journal、释放 claim 或转领;重启只允许同键同载荷 HTTP 调和。
- 三闸门截图必须先经 T-306 取得服务端确认的 `AssetRef`,再由 T-307 写对应固定事件;不得先写成功
事件、替换不明证据、串 attempt/generation,或上传 XML/manifest/目录。
- 正常 dry-run 必须以固定 reason `DRY_RUN_COMPLETED_BEFORE_FENCE` 在围栏前安全终止;不得请求、
模拟或伪造围栏,不得创建待付款订单。本任务不编写支付、免密支付、先用后付或任何扣款代码。
- `needs_device: true` 的最终验收只能由人完成。离线验证通过后仍保持 `DOING`,直到人确认三闸门
证据、最终提交控件仅被观察、一次 Back 安全返回且没有创建订单。