Files
cmbuyer/docs/tasks/T-103.md
T

200 lines
23 KiB
Markdown
Raw 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-103
title: 验证规格面板精确选择与 SKU 单价
phase: 1
deps: [T-102, T-110, T-111]
status: BLOCKED
created: 2026-08-04
vikunja_task_id: 23
context_ref: 1dc8308
work_branch: task/t-103-sku-panel
needs_device: true
needs_human_review: true
write_paths:
- docs/tasks/T-103.md
- client/src/cmbuyer_client/pdd/**
- client/src/cmbuyer_client/device/**
- client/tests/pdd/**
- client/tests/device/**
- client/scripts/capture_sku_panel_spike.py
- client/scripts/sanitize_sku_panel_evidence.py
- docs/02-requirements.md
- docs/03-tech-stack.md
- docs/04-architecture.md
- docs/api.md
- docs/current-state.md
---
<!-- BEGIN VIKUNJA EXPORT id=23 synced=2026-08-04T07:53:12Z sha256=87cad2b00d612381b663ebd94dbd4b6c142439e88935b2d40054599448b8bfda -->
## 问题 / 背景
T-102 已证明 canonical 链接可进入目标商品。T-103 在 PKG110 / Android 16 / 拼多多 8.17.0、goods_id `937122477375` 上确认:规格面板只能由详情页精确唯一的“快要抢光”打开;T-110 已把该入口批准为可逆、能力受限的第一趟导航。面板刚打开时目标颜色“黑色CHA(纯棉)”和尺码“M(建议100-115)”自动选中。
真实 `t103-privacy-v5` 派生曾成功用于安全分析:顶部价格节点为“快卖完 ¥12.88”,并列原价为“¥29.88”;派生截图的整宽遮罩把顶部价格文字遮住一半。项目所有者确认 cmbuyer 是内部系统,要求停止遮罩返工:正式流程可以把包含页面地址/手机号的原始截图上传采购服务供已登录管理员查看。完整 XML 不上传,地址/手机号不解析为业务字段,支付凭据仍禁止处理。
## 关联需求与交互
- 功能:F-006 第一趟试选;覆盖 `open_trial_sku_panel()`、`select_sku_options()`、`read_sku_unit_price()` 和安全退出的真机 spike。
- 用户故事:US-003、US-004、US-008;本任务无生产 GUI。T-103 先验证本机真机能力,T-204 接入原始截图 HTTP 上传与管理员查看。
- 架构 / API:`docs/04-architecture.md` 第三、四、5.4、六节;`docs/api.md` 的 `TrialSkuFlow`;T-104、T-105 与 Phase 2 的前置。
## 方案
1. 停止修改或调用截图遮罩器。T-103 的截图先保存在 `%LOCALAPPDATA%\cmbuyer\artifacts\T-103\...` 完成本机验收;T-204 正式接入原始截图上传,资产标记 `privacy_tier=INTERNAL_RAW`,允许包含页面已显示的地址和手机号。
2. 完整 XML 只留采购工具本机,不上传、不进日志、Vikunja 或 Git。以已确认的 v5 派生 XML 提取只含页面判据节点的最小 fixture;fixture 不含地址、手机号或支付凭据。
3. 实现 `TrialSkuFlow` 窄 capability。`open_trial_sku_panel()` 只允许拼多多 8.17.0、goods_id `937122477375` 上证据绑定、精确唯一的 `快要抢光`;缺失、重复、版本失配或面板判据不唯一时零后续点击。其他购买文案不得复用。
4. 第一趟只含打开商品、受控打开面板、在维度容器内精确选择、读回选中态、读取 SKU 单价、原始截图和退出。不得暴露通用 `click`、数量、确认页、提交订单或支付能力;“提交订单”、微信支付、先用后付和 0 元下单只作为硬拒绝判据。
5. 规格选项按维度容器隔离后文本精确唯一匹配,防 `红`/`粉红`、`1`/`10` 前缀碰撞;缺失、重复、禁用、维度不明或选中态不唯一均停止。
6. 单价只从已取证规格面板结构中的当前价角色读取,严格解析人民币两位小数字符串。促销前缀会变化,不能把“快卖完”作为主判据;必须限定 PDD package、面板结构/相对位置、非点击价格叶节点、唯一当前价,并排除原价及“提交订单/支付/优惠/预估”等语义。任一歧义返回 unreadable,不从详情页或底部提交区补值。
7. 真机运行时在内存中读取当前页面树,只返回规格、选中态、价格和页面状态摘要;地址/手机号不解析为结构化字段。原始截图可由 T-204 显式上传,但截图上传器不得枚举目录或顺带上传 XML/manifest。
8. 离线主审通过后,由人先把颜色和尺码改成明确记录的非目标值,再运行脚本恢复目标规格、读取 `12.88`、保存原始截图并安全退出。`needs_device=true`,agent 保持 DOING,等待人工验收。
## 验收要点
- 最小 fixture 只来自本项目拼多多 8.17.0、goods_id `937122477375` 的已验收 v5 派生 XML,不含地址、手机号或支付凭据。
- `快要抢光` 精确唯一时才打开面板;其他入口、版本失配、面板不唯一、规格碰撞/禁用、选中态或价格不唯一均 fail closed。
- 价格读取不依赖可变促销文案,能区分当前价 `12.88`、原价 `29.88` 和硬拒绝区“提交订单 ¥12.88”;金额只用十进制字符串。
- 静态 API/导入测试证明第一趟无通用点击、数量、确认页、提交订单或支付能力。
- T-103 不再开发遮罩;T-204 原始截图上传必须限制为显式截图文件、设备鉴权、SHA-256 校验和管理员会话读取,不上传完整 XML 或支付凭据。
- client 全部单测、compileall、wheel metadata、上下文校验、完整 `init.ps1` 与 diff-check 通过。
- 只有人完成受控入口、精确规格选择、单价读取、页面对应性、原始截图与安全退出验收后才能 DONE。
## 执行记录
### 2026-08-04T01:58:01Z · ila
2026-08-04:已认领 T-103,工作分支 `task/t-103-sku-panel`,任务定义基线 `27999c8`。先执行人工证据门禁,不立即编写页面判据:T-102 现有详情截图只证明目标商品,且当前视口可见“单独购买 / 免拼购买”“先用后付 / 0元下单”等禁触入口,没有证明独立安全规格入口。下一步由人手工寻找非购买的“规格 / 已选”入口;若不存在就记录 no-go,不点击购买按钮兜底。规格面板三态证据与隐私确认完成前,受托 agent 只允许做证据采集脚手架、纯函数边界和只读审计,T-103 保持 DOING。
### 2026-08-04T02:09:48Z · ila
2026-08-04 离线实现与主审记录:
- 提交 `a92b8f6` 新增 T-103 人工声明三状态的只读取证 CLI、捕获模块与离线测试;脚本不打开链接/面板,不点击、滑动、选择规格或读取价格。
- 失败闭合覆盖:严格 URL/状态/版本/前台包校验、截图/XML 有效性、超时脱敏、原子发布、已有输出目录不覆盖;协议无购买、下单、支付或数量操作。
- 主 agent 独立复跑:client 55 项单测、compileall、wheel metadata、agent-context validator、diff-check 与完整 `init.ps1` 全部通过。
- `needs_device=true`,任务保持 DOING;等待人通过独立安全规格入口分别采集 initial、one-dimension-selected、all-dimensions-selected 三组证据并完成对应性与隐私检查。若只有购买/下单/资金入口可打开面板,则记录 no-go,不放宽边界。
### 2026-08-04T02:36:33Z · ila
2026-08-04 真机证据主审退回:
- goods_id `937122477375` 的三组 manifest、设备/App 元数据与文件 SHA-256 均一致。
- 人工给出隐私确认后,主 agent 只查看三张 screenshot,未读取 XML。
- `initial` 截图实际仍为商品详情页,不是规格面板初始态;`one-dimension-selected` 与 `all-dimensions-selected` 截图顶部含收货区域和掩码手机号,不满足任务的无地址/手机号证据边界。
- 本组证据判定不合格:不提取 fixture、不编写页面判据、不提交原始证据;T-103 保持 DOING。
- 下一步使用全新输出目录重采:人先在规格面板取消全部规格选择,并滚动到收货区域和手机号完全离开可见视口,同时保留规格面板价格与规格区域;三态逐次人工核对后再交主审。
### 2026-08-04T02:41:12Z · ila
2026-08-04 T-103 真机 no-go 结论:
- 人工确认 goods_id `937122477375` 的规格面板是通过商品详情页右下角“快要抢光”进入;通常“免拼购买 / 快要抢光 / 单独购买 / 直接拼成”等购买语义按钮才会打开规格面板。
- 这直接触发任务方案与边界中的 no-go 条件:第一趟不得点击任何购买、下单、提交或资金入口,也不得把购买按钮包装成规格入口。
- 因此不读取本轮 XML、不提取 fixture、不实现选择器;已有截图仅用于判定入口不可行,原始证据不提交 Git。
- 当前 MVP 的自动第一趟试选在现有安全边界下不可实现,T-103 转 BLOCKED。解除阻塞需要项目所有者选择新的架构方向,并先更新架构/任务边界;不得由 agent 擅自放宽。
### 2026-08-04T02:56:36Z · ila
2026-08-04:T-110 已获项目所有者授权并同步架构契约。T-103 方案已重写为“先自动脱敏派生证据,再实现受控 `快要抢光` 入口与精确规格/价格判据”;T-110 完成并转 Done 后,本任务恢复 Doing。
### 2026-08-04T03:20:51Z · ila
2026-08-04 T-103 自动脱敏第一阶段实现与主审:
- 提交 `9b2eb74` 新增离线确定性脱敏 CLI、实现模块和纯合成测试;仅允许 `raw` 到同级全新 `derived`,不连接设备。
- 绑定 PKG110 / Android 16 / 拼多多 8.17.0 / goods_id `937122477375` / 1080×2400 / 人工声明三态;校验源 manifest 与文件哈希。
- 截图整宽遮罩 `[0,0,1080,540)`;XML 递归删除隐私带节点、清空跨界容器并保留下方规格节点,完整/掩码/分隔/跨节点手机号残留均 fail closed。
- 主审首轮发现手机号跨节点绕过、隐私结构未确认和发布竞态风险后退回;第二轮修复并补测,目标目录已存在或竞态出现均不覆盖且不留 staging。
- 主 agent 独立验证:66 项 client 单测、compileall、CLI help、wheel metadata、完整 `init.ps1`、上下文校验与 diff-check 全部通过。
- 实现与审查过程未读取、列举或打开任何真实 raw artifacts,也未实现 PDD 页面判据、点击、规格选择、价格、数量、确认页、提交或付款能力。
- `needs_device=true`,T-103 保持 DOING;等待人重新采集三态 raw、运行脱敏器并只核对 derived 后,才能继续页面判据与真机选择/读价。
### 2026-08-04T03:34:47Z · ila
项目所有者确认:规格面板刚打开时已自动选中目标颜色“黑色CHA(纯棉)”与尺码“M(建议100-115)”。旧的未选择/单维度/全选三态假设失效;T-103 改为记录刚打开目标预选、两个维度改为非目标值、两个维度恢复目标值三态。修改 CLI 状态枚举与测试前不再采集旧状态。
### 2026-08-04T03:40:39Z · ila
T-103 新三态离线实现与主审:提交 dbb69a7 将人工声明状态集中到 sku_panel_state.py,采集器和脱敏器仅接受 panel-opened-target-preselected、alternate-all-dimensions-selected、target-selection-restored;旧 initial / one-dimension-selected / all-dimensions-selected 与未知值均 fail closed。主 agent 独立复跑 67 项 client 单测、compileall、两个 CLI help、静态禁用能力检索与完整 init.ps1,全部通过。过程未连接设备、未读取真实 raw、未新增页面判据或点击/数量/确认/提交/付款能力。T-103 保持 DOING,等待新三态 derived 人工验收。
### 2026-08-04T03:54:21Z · ila
第一组新三态 raw 已由人成功采集;脱敏器 v1 按设计拒绝。人只读取 PNG 头部元数据并确认实际 format=PNG、size=1080x2376,证明 v1 将截图尺寸与 Android XML 坐标空间统一设为 1080x2400 的假设错误。原始证据不重采、不删除、不读取正文;下一步把 screenshot 与 XML coordinate space 分离配置,升级 sanitizer 版本并继续 fail closed。
### 2026-08-04T03:58:54Z · ila
T-103 sanitizer v2 坐标修正与主审:提交 44c027a 将 screenshot space 固定为人确认的 1080x2376,并把 XML coordinate space 独立严格配置为待验证的 1080x2400;sanitizer_version 升为 t103-privacy-v2。XML 会统计所有 bounds 的 max right/bottom,任何小于或大于配置的偏差均 fail closed,错误只含非敏感 observed 尺寸。派生 manifest 记录两个坐标空间和各自遮罩。主 agent 独立复跑 69 项 client 单测、compileall、CLI help 与 diff-check,全部通过;未读取真实 raw 正文、未连接设备。等待人用同一第一态 raw 重跑 v2 脱敏。
### 2026-08-04T06:01:02Z · ila
人使用 sanitizer v2 对同一第一态 raw 重跑,安全诊断返回 XML observed 1080x2376;未发布 derived。由此确认本次 screenshot space 与 XML coordinate space 均为 1080x2376,v2 对 XML=1080x2400 的待验证假设被真机证据否定。原始证据继续保留且不重采;下一步升级 v3,仍分离建模两个空间但分别精确绑定当前相同尺寸。
### 2026-08-04T06:05:53Z · ila
2026-08-04 T-103 sanitizer v3 坐标修正与主审:人用同一第一态 raw 运行 v2,脱敏器安全拒绝并仅报告 observed 1080x2376,证明 XML 实际坐标与截图相同;原始证据仍有效、未重采、未读取正文。提交 acf7e11 将 sanitizer_version 升为 t103-privacy-v3;截图与 XML 仍分别建模并分别严格校验,但当前均精确绑定 1080x2376,隐私带保持 [0,0,1080,540)。合成测试明确拒绝旧截图 1080x2400、旧 v2 XML 1080x2400,以及较小/较大坐标;手机号残留、哈希/状态/版本、确定性、原子发布和不覆盖门禁保持不变。主 agent 独立复跑 69 项 client 单测、compileall、CLI help、静态禁用能力检索与 diff-check,全部通过;未连接设备、未读取真实 raw。T-103 保持 DOING,等待人用同一第一态 raw 重跑 v3 并只核对 derived。
### 2026-08-04T06:17:05Z · ila
2026-08-04 第一态 derived 人工隐私验收与主审:项目所有者确认截图顶部隐私区完全遮黑、派生 XML 不含地址/手机号、目标颜色和尺码仍为预选;顶部价格因隐私带只显示一部分,最底部价格完整。人工确认后主 agent 才读取 derived,未访问 raw。路径 C:\Users\ila20\AppData\Local\cmbuyer\artifacts\T-103\sku-panel-opened-target- 937122477375-v2\derived;manifest 为 privacy_tier=SANITIZED、sanitizer_version=t103-privacy-v3、state=panel-opened-target-preselected,派生 screenshot/XML SHA-256 分别为 f9e370747cbef4facf6ec4a20d5af72b36c7615e7be7038144b1834632cdbf57 / f2024b7bcc69a03b05f5e95610708c0dbd33001698f40a011ddc895cf0410fb1,复算一致。XML 中“黑色 CHA (纯棉)”与“M(建议100-115)”各有明确 selected=true,汇总文本一致。完整金额候选仅见“提交订单 ¥12.88”;该文本只能在不可点击的派生快照中用于离线价格语义验证,第一趟绝不能获得该控件或其可点击父节点。另观察到 com.android.systemui 的“肉包采购辅助”浮层节点,后续最小 fixture/判据必须限定 PDD package,并建议后两态采集前关闭该浮层。第一态隐私与状态证据通过,但价格语义仍需另两态交叉验证,T-103 保持 DOING。
### 2026-08-04T06:20:03Z · ila
主审补充澄清:上一条所述“提交订单 ¥12.88”只能证明面板中存在该禁触文本,不得作为第一趟 SKU 单价证据,也不得驱动任何控件解析或交互。原因是它属于可点击“提交订单”父区域,违反 T-110 硬拒绝区边界。v3 第一态因此只通过隐私与预选状态验收,价格证据仍不通过。下一步不缩小 [0,0,1080,540) 截图遮罩,而由 v4 脱敏器在顶部交界带仅保留严格白名单、PDD package、非点击叶节点的价格文本到派生 XML;任何混杂文本、点击节点、包外节点或非唯一候选均 fail closed。
### 2026-08-04T06:43:53Z · ila
2026-08-04 客户确认加速方案:手机规格面板显示地址/手机号不再作为真机流程阻塞条件;不再扩大或调整截图黑色遮罩。原始证据仍只留本机,agent/Git/服务端仍只消费派生物。提交 1e69d27 实现 t103-privacy-v4:截图遮罩与 1080x2376 双坐标校验完全不变,只把已取证的两个顶部交界价格槽中,PDD package、TextView、非点击、可见启用、叶节点且严格匹配“唯一快卖光当前价 + 至多一个原价”的七属性安全文本投影到派生 XML;结构/文本/候选数漂移均原子拒绝,底部“提交订单 ¥12.88”仍不是价格候选。主 agent 两轮退回测试职责问题后独立复跑 76 项 client 单测、compileall、CLI help、禁用能力检索与 diff-check,全部通过。下一步保留已验收 v3 derived,用同一 raw 生成 v4 derived;T-103 保持 DOING。
### 2026-08-04T06:55:52Z · ila
2026-08-04 项目所有者用同一第一态 raw 运行 v4,脱敏器按设计 fail closed:跨界价格节点文本不匹配,未发布 derived;raw 与已保留的 derived-v3-reviewed 未受损。提交 ef1ac60 增加最小安全诊断:失败只输出两个固定价格槽位和受控 reason 枚举,不回显原文、金额、数字串、字符码点、长度或原始属性,v4 成功白名单与原子不发布语义不变。主 agent 独立复跑 78 项 client 单测、compileall、CLI help 与 diff-check,全部通过。等待项目所有者用同一 raw 重跑并反馈 slot/reason;T-103 保持 DOING。
### 2026-08-04T07:17:10Z · ila
2026-08-04 项目所有者重跑安全诊断,固定当前价槽 [396,503][712,570] 返回 reason=known_prefix_missing,证明 raw 文本以“快”开头但不是 v4 假设的精确“快卖光”;该原因不足以证明具体前缀,成功白名单未放宽。提交 6e001b2 仅细分一个已人工观察过的安全枚举:若该槽精确以“快要抢光”开头则返回 observed_prefix_kuaiyaoqiangguang,其余“快”开头仍为 generic;不回显后缀、金额、长度、码点或 raw 属性。主 agent 独立复跑 79 项 client 单测、compileall 与 diff-check 通过。等待项目所有者用同一 raw 再次重跑;T-103 保持 DOING。
### 2026-08-04T07:19:42Z · ila
2026-08-04 项目所有者在手机 live 规格面板人工确认:固定顶部当前价槽的完整非敏感文字为“快卖完 ¥12.88”;底部购买按钮“快要抢光”是另一控件。主 agent 未读取 raw。该事实解释了 v4 对未经验证“快卖光”假设的两次安全拒绝。下一步升级 v5:删除“快卖光”成功假设,只允许证据绑定的精确“快卖完”当前价;坐标、遮罩、结构、PDD package、非点击叶节点、唯一性与原价限制全部不变。T-103 保持 DOING。
### 2026-08-04T07:42:53Z · ila
2026-08-04 范围调整:`t103-privacy-v5` 已在真实第一态成功生成,人工确认派生 XML 无实际地址/手机号、目标规格保留;顶部当前价为“快卖完 ¥12.88”、原价为“¥29.88”,底部“提交订单 ¥12.88”继续属于第一趟硬拒绝区。派生截图的整宽遮罩把顶部价格遮住一半。项目所有者要求停止遮罩返工并加速 MVP:T-103 不上传规格页截图,以安全最小 XML fixture 继续选择/读价;正式管理员证据截图归 T-204,上传端仍不得接收地址、手机号或支付凭据。未完成真机选择/读价验收,T-103 保持 Doing。
### 2026-08-04T07:45:57Z · ila
2026-08-04 最终范围澄清:上一条“正式截图仍需脱敏/裁剪”的记录已被项目所有者新决定取代。cmbuyer 是内部系统,正式第一趟允许把包含页面已显示地址/手机号的原始截图上传采购服务,不做遮罩或裁剪;T-204 负责设备鉴权上传、SHA-256 校验与管理员会话访问。完整 XML、普通日志、Git、Vikunja 和支付凭据仍不接收。T-103 立即停止遮罩开发,继续受控规格选择与 SKU 读价,任务保持 Doing。
### 2026-08-04T07:52:38Z · ila
2026-08-04:项目所有者确认管理员点击“开始采购”即授权创建待付款订单,MVP 从两趟人工确认改为单趟采购。T-103 暂停,等待 T-111 先重写状态机、授权、价格闸门与任务依赖;暂停期间不得继续实现 TrialSkuFlow 或任何数量/确认页/提交代码。T-103 仍为未完成任务。
<!-- END VIKUNJA EXPORT -->
## 边界
- 任何规格面板入口、维度容器、选项、选中态和价格判据都必须来自本项目拼多多 8.17.0 真机证据;
T-102 详情页证据只能证明已到目标商品,不能证明规格面板结构。T-103 只使用已由人确认无实际地址/
手机号的 v5 派生 XML 提取最小 fixture;派生截图的上传适用性不再是本任务的代码门禁。
- 第一趟只允许 T-110 批准的 `open_trial_sku_panel()` 窄能力点击证据/版本绑定、精确唯一的
`快要抢光`;当前事实仅覆盖 goods_id `937122477375`、拼多多 `8.17.0`。不得把“免拼购买 /
单独购买 / 直接拼成”等其他文案加入包含、前缀、同义或坐标兜底,分别取证前一律拒绝。
- 规格选项只能在已确认的面板及对应维度容器内按文本精确唯一匹配;缺失、重复、禁用、维度不明、
选中态无法唯一读回或页面版本不符均 fail closed。不得前缀、包含、模糊、相似或跨维度匹配,
不得用 OCR / 坐标兜底猜选项。
- 单价只允许从规格面板证据确认的节点读取,并以十进制字符串表达;不得使用浮点,不得从详情页、
搜索卡片或其他页面的数字补值。券后价、原价、区间价、货币符号拆分或多个候选的语义无法唯一
证明时必须返回 unreadable 并转人工。
- T-103 代码路径不得引用或实现 `set_quantity()`、`go_to_order_confirm()`、`submit_order()`、
通用 `click`、创建订单、授权、提交围栏或任何支付能力;不得进入订单确认页,不得创建待付款订单。
规格面板中的“提交订单”、微信支付、先用后付、0 元下单只可作为硬拒绝判据,不能返回可点击对象。
- 不把 `/mnt/d/chengma/cmroubao`、`/mnt/d/chengma/cmpdd` 或任何旧版本的节点、Activity、选择器、
坐标、文本形态和页面结论当作事实;前序项目只可用于理解为什么必须 fail closed。
- 原始完整 XML 只保存在 `%LOCALAPPDATA%\cmbuyer\artifacts\T-103\...\raw`,不得由 HTTP sink、
Vikunja 或 Git 读取/上传。真机流程可在内存中读取当前页面树,但只返回规格、选中态、价格和页面
状态摘要;不得把地址、手机号或支付凭据解析成业务字段或写入日志。
- T-103 不再扩展截图遮罩器;本任务先以本机原始截图完成真机验收。生产第一趟原始截图上传由 T-204
接入,允许截图包含页面已显示的地址和手机号,但只允许已认证设备上传、已登录管理员查看;完整 XML、
外部支付页和支付凭据不得上传。
- `needs_device: true`:agent 只能完成离线实现并保持 `DOING`;只有人完成安全入口、精确规格选择、
SKU 单价语义、页面对应性与安全退出验收后才能标 `DONE`。HTTP 截图上传实现不属于 T-103 验收。