feat(t213): guard read-only specification verification

This commit is contained in:
QiuSW
2026-07-27 23:06:21 +08:00
parent 1316b9bb32
commit 9a8388fac6
25 changed files with 1540 additions and 207 deletions
+33 -11
View File
@@ -257,22 +257,44 @@ T-102/T-104 在搜索结果后追加一个有界候选步骤:
-> 最多 2 次滚动预算
-> 最多 5 个去重商品卡
-> 验证详情页
-> 无障碍截图
-> App cache/candidate-NN.png + manifest.json
-> 详情页无障碍截图
-> 唯一、安全、非交易规格入口
-> 规格弹层只读语义和截图
-> App cache/candidate-NN-{detail,specification}.png + manifest.json
-> 关闭规格弹层并复核详情页
-> 一次全局返回并复核固定词结果页
```
候选卡只保留语义指纹和计数,详情截图保存在 App 内部 cache。manifest 记录匿名文件名、
截图 SHA-256、字节数和尺寸,不保存商品标题或页面原文。T-104 使用这些证据时必须通过
受控 evidence 边界读取,不能让 VLM adapter 自行遍历 cache。Android 10/API 29 及
以下不能运行当前截图探针,应在预检时明确不支持,不使用媒体投影或 shell 绕过。
候选卡只保留语义指纹和计数,详情/规格截图保存在 App 内部 cache。manifest v2 记录
匿名文件名、截图 SHA-256、字节数、尺寸和有界规格语义,不保存商品标题或完整页面
原文。T-104/T-213 使用这些证据时必须通过受控 evidence 边界读取,不能让 VLM adapter
自行遍历 cache。Android 10/API 29 及以下不能运行当前截图探针,应在预检时明确
不支持,不使用媒体投影或 shell 绕过。
`CandidateEvidenceSource` 只接受当前 workflow 内存中的连续 ordinal 元数据,文件名
固定为 `candidate-01.png` 至 `candidate-05.png`;每张 PNG 最多 8 MiB、全批最多
32 MiB、声明尺寸最长边不超过 10000 px,并复核规范路径、PNG/IHDR、精确字节数、
尺寸和 SHA-256。Android gateway 再解码并把最长边缩至 2048 px。当前需求快照与
搜索词必须同时匹配候选 session,否则拒绝评估;另一个关键词的结果页只允许重新进入
搜索框,不能采集候选。
固定为 `candidate-01-detail.png`/`candidate-01-specification.png` 至第五组;每张
PNG 最多 8 MiB、全批最多 64 MiB、声明尺寸最长边不超过 10000 px,并复核规范路径、
PNG/IHDR、精确字节数、尺寸和 SHA-256。每个候选回传时必须恰好绑定
`DETAIL`/`SPECIFICATION` 两份证据,生成独立 asset ID;先验证全批 ordinal、类型和
哈希再写入加密 outbox,候选的 asset ID 数组固定按 `DETAIL`、`SPECIFICATION`
排序,重试沿用各自 idempotency key。Android gateway 再解码详情图并把最长边缩至
2048 px。当前需求快照与搜索词必须同时匹配候选 session,否则拒绝评估;另一个
关键词的结果页只允许重新进入搜索框,不能采集候选。
T-213 规格核验只允许精确语义为“选择规格/请选择规格/颜色分类/颜色款式/选择颜色/
选择尺码”或“已选/请选择”前缀的唯一节点及其可点击祖先。弹层内不点击任何规格选项,
只读取最多 160 个语义节点、每组最多 30 个选项及 selected/enabled/scrollable 语义。
颜色和尺码各自必须是唯一分组:目标值明确且可用为 `MATCH`,完整分组明确缺失或目标
禁用为 `MISMATCH`,重复、缺组、滚动截断或无障碍语义不足为 `UNKNOWN`。
候选评估 schema/prompt v3 把本地规格结果作为权威输入;模型返回的颜色/尺码状态必须
逐项与本地结果相同,否则整批降级人工检查。详情和规格证据 SHA-256 同时绑定
assessment、重排身份和 outbox 资产,VLM 不能通过主图推断覆盖本地硬约束。
PKG110 上的拼多多 8.17.0 服装详情只暴露不可点击的“颜色/款式”预览;完整颜色/尺码
弹层只能通过“单独购买/免拼购买”控件进入。自动化不得点击这两个交易语义控件,也
不得用坐标降级,因此当前版本在没有独立可点击规格入口时返回安全阻塞。是否把购买
语义控件重新定义为只读弹层入口,必须单独做产品/安全决策后变更本边界。
评估结束后 automation 不再产生动作,UI 进入 `AWAITING_CONFIRMATION`、
`MANUAL_REVIEW` 或 `NO_MATCH`。人员可以把本地建议项标记为可用,或拒绝本次候选;
+20 -15
View File
@@ -5,9 +5,9 @@
## 当前快照
- 日期:2026-07-27
- 阶段:T-212 候选重排身份映射完成;下一步 T-213 只读核验拼多多规格弹窗
- 阶段:T-212 已完成;T-213 只读规格核验已实现但被拼多多 8.17 入口语义阻塞
- Git:当前分支为 `main`;T-001 至 T-004、T-101 至 T-104、T-201 至 T-207、T-209、
T-210、T-211、T-212 均已纳入 Git 历史
T-210、T-211、T-212 均已纳入 Git 历史;T-213 等待安全策略决策
- 生产代码:`android-buyer/` 已接入 Roubao Android 源码
- Android:固定 `main@c8a6d7f03422eb01744b01f3ee77bf7757741f7e`;MIT 许可证已保留
@@ -17,10 +17,10 @@
- 本机 Android 工具:JDK 17.0.13、Command-line Tools 22.0、SDK 34、
Build Tools 34.0.0、Platform Tools/ADB 37.0.0;用户级 SDK 环境变量已设置
- Android Studio:未安装;`winget` 静默安装卡住后已终止,不阻塞命令行构建
- 测试:T-212 运行 `:app:testDebugUnitTest` 和 `:app:assembleDebug` 通过,21 个 suite
共 113 个测试、0 失败;T-211 Debug APK 已安装到 PKG110
- 后端测试:T-211 运行 `GOTOOLCHAIN=local go test -count=1 ./...` 和
`go vet ./...` 通过;T-207 的全包 race 与 migration 验证继续有效
- 测试:T-213 运行 `:app:testDebugUnitTest` 和 `:app:assembleDebug` 通过,24 个 suite
共 128 个测试、0 失败;Debug APK `1.4.3 (8)` 已安装到 PKG110
- 后端测试:T-213 运行 `go test ./...` 通过;T-207 的全包 race 与 migration
验证继续有效
- 原型:4 个管理 Web 页面和 7 个 Android 页面均可离线独立打开;Playwright
以 1440×900、390×844、360×800 验证 36 个页面/视口组合,无页面横向溢出、
脚本错误或外部请求,Android 可见交互控件均不小于 44px
@@ -47,9 +47,13 @@
顺序回传,授权到期补报单独审计,所有终态固定 `order_submitted=false`。管理任务
详情展示模型/候选/人工理由/事件/证据摘要,不保存 VLM Key、完整 endpoint 或原始响应。
- T-211 图片检索:后台任务固定使用经 SHA-256 校验的参考 JPEG,经一次性 MediaStore
图片进入拼多多拍照搜索;App 本地从 SKU 唯一提取颜色和尺码,schema v2 逐项返回
图片进入拼多多拍照搜索;App 本地从 SKU 唯一提取颜色和尺码,schema v3 逐项返回
`MATCH/MISMATCH/UNKNOWN`。只有两项均匹配且分数/置信度不低于 `0.75` 的候选按
分数、置信度和曝光顺序回传 `0..5` 项,弱匹配和未知项不凑数。
- T-213 规格核验:只允许唯一、非交易规格入口;弹层内不点击选项,本地根据有界的
颜色/尺码分组、可用/禁用和完整性语义产生硬约束结果。每个候选绑定详情/规格两张
PNG 及两个 SHA-256/asset ID;模型不能覆盖本地状态。拼多多 8.17 服装详情的完整
规格弹层只挂在“单独购买/免拼购买”后,当前安全边界拒绝该入口,故真机流程阻塞。
- Workflow:纯 Kotlin runner 已支持步骤 timeout、最多 3 次 retry、安全阻塞、
用户停止和单 runner 并发拒绝;T-102 已接入搜索加有界候选采集五步
- TaskSource:严格 CLI 已生成并验证真实私有 ProbeTask;默认 APK 不含私有 fixture
@@ -65,7 +69,7 @@
- 离线执行:默认 30 分钟有限授权和 30 秒 best-effort heartbeat 已实现;PKG110
真机断开临时后端 95 秒后保持同一 execution,重连后滑动续期;到期持久安全停止,
RUNNING 不自动重新分配
- 测试设备:OnePlus PKG110,Android 16/API 36;肉包 `1.4.2 (7)`;拼多多
- 测试设备:OnePlus PKG110,Android 16/API 36;肉包 `1.4.3 (8)`;拼多多
`8.17.0 (81700)`
- 设备就绪:拼多多首页、文字/图片搜索、双列候选卡、详情截图和返回均已通过 8.17.0
真机验证;最终 APK 重装/force-stop 后 ColorOS 已关闭肉包采购无障碍,当前需采购员
@@ -80,8 +84,10 @@
已用 CLI 真实导入并逐字段/图片哈希验证,生成物位于被忽略的 `.local/`
- 标准启动路径:`$env:RUN_START_COMMAND="1"; .\init.ps1`
- 标准验证路径:`.\init.ps1`
- 当前 blocker:真实 VLM 服务地址、模型、设备级测试凭证、成本上限和数据留存尚未确认;
当前只支持单 SKU/JPEG;候选探针截图要求 Android 11/API 30+
- 当前 blocker:T-213 需要确认是否允许点击“单独购买/免拼购买”仅用于打开规格弹层,
或提供独立规格入口/受支持数据源;ColorOS 重装后需采购员手动重新启用肉包无障碍。
真实 VLM 服务地址、模型、设备级测试凭证、成本上限和数据留存也尚未确认;当前只
支持单 SKU/JPEG;候选探针截图要求 Android 11/API 30+
## 当前目录
@@ -108,7 +114,7 @@
| `docs/tasks/T-210.md` | DONE | 兼容拼多多 8.17 搜索结果页与长词省略显示 |
| `docs/tasks/T-211.md` | DONE | 参考图召回、SKU 颜色尺码硬匹配与 0..5 候选回传 |
| `docs/tasks/T-212.md` | DONE | 修复重排候选、推荐、证据与人工接受的身份映射 |
| `docs/tasks/T-213.md` | TODO | 只读采集拼多多规格弹窗中的颜色和尺码证据 |
| `docs/tasks/T-213.md` | BLOCKED | 实现只读规格核验;等待拼多多购买语义入口安全决策 |
| `docs/design/` | 已确认 | T-202 原型索引、4 个管理页和 7 个 Android 页面 |
| `deepseek总结.txt` | 已有 | 历史讨论摘要,不是正式需求权威 |
| `android-buyer/` | 已有 | Roubao `main` 固定 commit 的 Android 基线 |
@@ -121,10 +127,9 @@
- 已完成:T-001 至 T-004、T-101 至 T-104、T-201 至 T-207、T-209、T-210、T-211、
T-212。
- 正在进行:T-213 拼多多规格弹窗只读核验。
- 下一个可领取任务:无;T-208 依赖 T-213 完成。
- 后置任务:T-213 拼多多规格弹窗只读核验;完成后再做 T-208 候选决策数据与人工
理由闭环。
- 阻塞中:T-213 拼多多规格弹窗只读核验,等待购买语义入口的安全策略决策。
- 下一个可领取任务:无;T-208 依赖 T-213 真机验收完成。
- 后置任务:解除 T-213 阻塞后再做 T-208 候选决策数据与人工理由闭环。
## 当前可运行内容
+24 -7
View File
@@ -4,11 +4,12 @@ title: 拼多多规格弹窗只读核验
phase: 2
deps:
- T-212
status: DOING
status: BLOCKED
created: 2026-07-27
context_ref: edfee2c
work_branch: null
write_paths:
- android-buyer/app/build.gradle.kts
- docs/tasks/T-213.md
- docs/04-architecture.md
- docs/current-state.md
@@ -53,12 +54,12 @@ Top 5 为空。仅凭商品主图推断颜色或尺码不满足硬约束要求
## 验收要点
- [ ] 页面分类测试覆盖规格弹窗、普通详情、登录、验证码、风控、购物车、订单和支付。
- [ ] 自动化只点击唯一规格入口,不点击颜色/尺码选项、购买、拼单、购物车或支付控件。
- [ ] 颜色、尺码分组及选项解析有数量/文本长度边界,截断或歧义不会判为 `MATCH`。
- [ ] 单元测试覆盖两个目标均匹配、明确不匹配、禁用、缺失和未知。
- [ ] 每个候选的详情/规格证据哈希和后端 asset ID 对应正确,离线重试不重复或串位。
- [ ] Android 单元测试和 Debug 构建通过。
- [x] 页面分类测试覆盖规格弹窗、普通详情、登录、验证码、风控、购物车、订单和支付。
- [x] 自动化只点击唯一规格入口,不点击颜色/尺码选项、购买、拼单、购物车或支付控件。
- [x] 颜色、尺码分组及选项解析有数量/文本长度边界,截断或歧义不会判为 `MATCH`。
- [x] 单元测试覆盖两个目标均匹配、明确不匹配、禁用、缺失和未知。
- [x] 每个候选的详情/规格证据哈希和后端 asset ID 对应正确,离线重试不重复或串位。
- [x] Android 单元测试和 Debug 构建通过。
- [ ] PKG110、Android 16、拼多多 8.17.0 真机 smoke 完成规格弹窗打开、只读采集、
关闭和返回;记录 App/拼多多版本并确认未进入订单或支付。
@@ -75,3 +76,19 @@ Top 5 为空。仅凭商品主图推断颜色或尺码不满足硬约束要求
关联到错误的重排候选。
- 2026-07-27:T-212 完成提交 `4b795a4` 后领取。先冻结拼多多 8.17 规格弹窗的只读
页面/动作边界和候选多证据模型,再进行真机验证。
- 2026-07-27:实现规格弹层分类、安全入口 allowlist、颜色/尺码有界解析、本地确定性
硬匹配、candidate evaluation schema/prompt v3,以及每个候选详情/规格两份证据的
cache 校验、重排身份绑定和加密 outbox 关联。模型返回状态与本地状态不一致时强制
降级人工检查。
- 2026-07-27:Android `testDebugUnitTest` 24 个 suite、128 个测试全部通过,
`assembleDebug` 通过;后端 `go test ./...` 通过。Debug APK `1.4.3 (8)` 已安装到
PKG110,拼多多版本为 `8.17.0 (81700)`。
- 2026-07-27:真机检查图片结果中的定制商品和文字搜索 `black tshirt L` 的普通服装
商品。服装详情只暴露不可点击的“颜色/款式”预览,完整颜色/尺码弹层只能通过
“单独购买/免拼购买”控件进入;前两个定制商品甚至没有规格预览。全程未点击购买、
拼单、购物车、订单或支付控件。
- 2026-07-27:任务标记 `BLOCKED`。代码在缺少独立可点击规格入口时按
`UNKNOWN_PAGE` 安全停止,符合边界但无法完成“打开/采集/关闭/返回”的真机验收。
外部解除条件是:确认允许把购买语义控件仅用于打开规格弹层,或提供不经过购买控件
的稳定规格入口/受支持数据源。重新安装后 ColorOS 也关闭了肉包无障碍服务,继续
smoke 前需采购员在系统设置手动重新启用。