修复 Agent 当前页面采集过早读取 PDD 剪贴板 #105

Closed
opened 2026-08-27 11:23:04 +08:00 by ila · 3 comments
Owner

所属与来源

  • 关联工单:#101 Agent 当前 PDD 商品页临时采集;前置缺陷 #104 已恢复 PDD 商品任务栈。
  • 来源:用户于 2026-08-27 反馈最新采集任务失败:PDD_CLIPBOARD_UNAVAILABLE:无法读取刚复制的商品链接,并要求建立独立缺陷工单修复。
  • 类型:Android Agent / 当前页面采集 / 剪贴板时序缺陷。
  • 设计证据:复用已审核的 #101 原型和现有错误提示;本缺陷只恢复既定“复制后等待本次新链接”行为,不新增页面、组件、流程或业务语义,因此不另做原型。

当前事实与根因

一加 PKG110、Agent 0.9.1、采集任务 #68 的真机日志:

  • 11:17:09.239:Agent 任务移到后台,PDD NewPageActivity 恢复前台,说明 #104 页面恢复已生效。
  • 11:17:10.622:Android 允许 Agent 读取剪贴板。
  • 11:17:10.719:PDD 才完成本次商品链接写入剪贴板,比 Agent 首次读取晚约 97ms。
  • ClipboardRelayActivity 当前仅在恢复后延迟 120ms 读取一次;首次未读到符合新鲜度条件的链接便结束。外层等待超时因此不能覆盖 PDD 异步写入延迟。
  • 任务 #68 在商品身份确认前以 PDD_CLIPBOARD_UNAVAILABLE 失败,未绑定 goods_id,未写入 PDD 商品或采集结果。

根因是剪贴板中转 Activity 的单次读取与 PDD 异步写入存在时序竞争,不是系统剪贴板权限被拒绝。

目标

在现有有限超时内等待 PDD 本次复制产生的新鲜链接,消除“Agent 先读、PDD 后写”的偶发失败;保持现有来源、新鲜度、类型、数量、长度和 URL 白名单边界。

非目标

  • 不放宽链接白名单或商品身份校验。
  • 不读取历史剪贴板作为兜底,不猜测 goods_id。
  • 不修改 Server、数据库、规则、采集字段、采购能力或页面设计。
  • 不记录、持久化或上传原始剪贴板和分享文案。

实施方案

  1. 将剪贴板中转 Activity 从“延迟后单次读取”改为有限轮询:
    • Activity 获得前台读取资格后立即尝试;
    • 未得到本次新鲜合法文本时,每约 100ms 再试;
    • 在调用方传入的有限 deadline 内成功即立即返回,超时才返回空。
  2. 使用单调时钟计算等待截止时间,避免系统时间调整造成无限等待;系统剪贴板时间戳只用于与本次复制墙钟时间比较。
  3. 保持既有校验:本次复制后产生、text/plain、单条、长度不超过 4096;URL 提取和白名单仍由现有流程完成。
  4. Activity 销毁、请求替换或达到 deadline 时清理回调,只返回一次,避免泄漏和重复完成。
  5. 对调用超时做明确边界,轮询不得超过现有 clipboardTimeoutMs。
  6. 增加可脱离 Android UI 的轮询状态/策略单元测试,覆盖:
    • 第一次旧内容、后续新内容时成功;
    • 一直无内容或旧内容直到超时;
    • 多条、错误 MIME、超长内容继续等待后超时;
    • 成功或销毁后不会重复回调。

安全边界

  • 不保存或记录剪贴板正文、分享文案、控件树和截图。
  • 不打开浏览器、不重开商品、不选择相似商品。
  • 不采购、不修改地址、不创建订单、不支付。
  • 仅修复当前页面采集已经允许的分享与复制链接步骤。

验收标准

  • PDD 在 Agent 首次读取之后异步写入链接时,Agent 能在有限超时内读取本次新链接并继续 goods_id 确认。
  • 未得到本次新鲜合法链接时,超时后仍返回 PDD_CLIPBOARD_UNAVAILABLE,不使用旧剪贴板。
  • MIME、单条、长度、新鲜度和 URL 白名单校验没有放宽。
  • Activity 成功、超时或销毁后只完成一次且清理轮询回调。
  • 不记录或持久化剪贴板内容。
  • Android 单元测试与 APK 构建通过;真机回归需在 PDD 商品详情页执行一次当前页面采集,不涉及采购和支付。

验证计划

  • 单元测试:有限轮询的成功、超时、非法内容、单次完成和清理。
  • 构建:.\gradlew.bat testDebugUnitTest assembleDebug。
  • 静态检查:git diff --check、python dev_scripts/harness.py check --strict。
  • 真机:安装新 APK 后,在一加 PDD 商品详情页复测“采集”,核对前台页面、任务状态和 goods_id 绑定。
  • 文档影响:无长期契约变化,只恢复 #101 已记录的有限等待与安全校验;在工单记录原因并跳过 Wiki。
## 所属与来源 - 关联工单:#101 Agent 当前 PDD 商品页临时采集;前置缺陷 #104 已恢复 PDD 商品任务栈。 - 来源:用户于 2026-08-27 反馈最新采集任务失败:`PDD_CLIPBOARD_UNAVAILABLE:无法读取刚复制的商品链接`,并要求建立独立缺陷工单修复。 - 类型:Android Agent / 当前页面采集 / 剪贴板时序缺陷。 - 设计证据:复用已审核的 #101 原型和现有错误提示;本缺陷只恢复既定“复制后等待本次新链接”行为,不新增页面、组件、流程或业务语义,因此不另做原型。 ## 当前事实与根因 一加 PKG110、Agent 0.9.1、采集任务 #68 的真机日志: - 11:17:09.239:Agent 任务移到后台,PDD `NewPageActivity` 恢复前台,说明 #104 页面恢复已生效。 - 11:17:10.622:Android 允许 Agent 读取剪贴板。 - 11:17:10.719:PDD 才完成本次商品链接写入剪贴板,比 Agent 首次读取晚约 97ms。 - `ClipboardRelayActivity` 当前仅在恢复后延迟 120ms 读取一次;首次未读到符合新鲜度条件的链接便结束。外层等待超时因此不能覆盖 PDD 异步写入延迟。 - 任务 #68 在商品身份确认前以 `PDD_CLIPBOARD_UNAVAILABLE` 失败,未绑定 goods_id,未写入 PDD 商品或采集结果。 根因是剪贴板中转 Activity 的单次读取与 PDD 异步写入存在时序竞争,不是系统剪贴板权限被拒绝。 ## 目标 在现有有限超时内等待 PDD 本次复制产生的新鲜链接,消除“Agent 先读、PDD 后写”的偶发失败;保持现有来源、新鲜度、类型、数量、长度和 URL 白名单边界。 ## 非目标 - 不放宽链接白名单或商品身份校验。 - 不读取历史剪贴板作为兜底,不猜测 goods_id。 - 不修改 Server、数据库、规则、采集字段、采购能力或页面设计。 - 不记录、持久化或上传原始剪贴板和分享文案。 ## 实施方案 1. 将剪贴板中转 Activity 从“延迟后单次读取”改为有限轮询: - Activity 获得前台读取资格后立即尝试; - 未得到本次新鲜合法文本时,每约 100ms 再试; - 在调用方传入的有限 deadline 内成功即立即返回,超时才返回空。 2. 使用单调时钟计算等待截止时间,避免系统时间调整造成无限等待;系统剪贴板时间戳只用于与本次复制墙钟时间比较。 3. 保持既有校验:本次复制后产生、`text/plain`、单条、长度不超过 4096;URL 提取和白名单仍由现有流程完成。 4. Activity 销毁、请求替换或达到 deadline 时清理回调,只返回一次,避免泄漏和重复完成。 5. 对调用超时做明确边界,轮询不得超过现有 `clipboardTimeoutMs`。 6. 增加可脱离 Android UI 的轮询状态/策略单元测试,覆盖: - 第一次旧内容、后续新内容时成功; - 一直无内容或旧内容直到超时; - 多条、错误 MIME、超长内容继续等待后超时; - 成功或销毁后不会重复回调。 ## 安全边界 - 不保存或记录剪贴板正文、分享文案、控件树和截图。 - 不打开浏览器、不重开商品、不选择相似商品。 - 不采购、不修改地址、不创建订单、不支付。 - 仅修复当前页面采集已经允许的分享与复制链接步骤。 ## 验收标准 - [ ] PDD 在 Agent 首次读取之后异步写入链接时,Agent 能在有限超时内读取本次新链接并继续 goods_id 确认。 - [ ] 未得到本次新鲜合法链接时,超时后仍返回 `PDD_CLIPBOARD_UNAVAILABLE`,不使用旧剪贴板。 - [ ] MIME、单条、长度、新鲜度和 URL 白名单校验没有放宽。 - [ ] Activity 成功、超时或销毁后只完成一次且清理轮询回调。 - [ ] 不记录或持久化剪贴板内容。 - [ ] Android 单元测试与 APK 构建通过;真机回归需在 PDD 商品详情页执行一次当前页面采集,不涉及采购和支付。 ## 验证计划 - 单元测试:有限轮询的成功、超时、非法内容、单次完成和清理。 - 构建:`.\gradlew.bat testDebugUnitTest assembleDebug`。 - 静态检查:`git diff --check`、`python dev_scripts/harness.py check --strict`。 - 真机:安装新 APK 后,在一加 PDD 商品详情页复测“采集”,核对前台页面、任务状态和 goods_id 绑定。 - 文档影响:无长期契约变化,只恢复 #101 已记录的有限等待与安全校验;在工单记录原因并跳过 Wiki。
Author
Owner

开始实施(2026-08-27)

已核对 #101/#104、业务规则、任务 #68 真机日志与当前代码基线。按工单最小范围修改 Android:

  • 剪贴板中转 Activity 在现有有限超时内轮询本次新内容;
  • 使用单调时钟限制等待,成功、超时或销毁后只完成一次;
  • 保留新鲜度、MIME、单条、长度及 URL 白名单校验;
  • 增加纯策略单元测试并构建 APK。

不修改 Server、数据库、规则、UI 或采购能力;不记录剪贴板内容。

## 开始实施(2026-08-27) 已核对 #101/#104、业务规则、任务 #68 真机日志与当前代码基线。按工单最小范围修改 Android: - 剪贴板中转 Activity 在现有有限超时内轮询本次新内容; - 使用单调时钟限制等待,成功、超时或销毁后只完成一次; - 保留新鲜度、MIME、单条、长度及 URL 白名单校验; - 增加纯策略单元测试并构建 APK。 不修改 Server、数据库、规则、UI 或采购能力;不记录剪贴板内容。
Author
Owner

实现与自动化验证完成,待真机业务回归

实现

  • ClipboardRelayActivity 由固定延迟后的单次读取改为每 100ms 有限轮询。
  • 调用方使用既有 clipboardTimeoutMs(500~10000ms)计算单调时钟 deadline;到期立即失败,不会无限等待。
  • 成功、超时、请求消失或 Activity 销毁后均停止回调并只交付一次。
  • 保留本次复制新鲜度、text/plain、单条、4096 字符上限以及后续 PDD HTTPS 域名白名单校验。
  • Agent 版本更新为 0.9.2(versionCode 15)。
  • 未修改 Server、数据库、规则、UI 或采购能力;未记录或保存剪贴板内容。
  • 无长期契约变化,只恢复 #101 已记录的有限等待行为,按工单约定跳过 Wiki。

验证

  • cd android && .\gradlew.bat testDebugUnitTest assembleDebug:通过。
  • 新增单元测试:旧内容后出现新内容成功、持续无效直到超时、错误 MIME、多条、超长、缺失描述拒绝,以及成功/超时后不重复完成。
  • python dev_scripts/harness.py check --strict:通过。
  • git diff --check:通过。
  • 本地提交:f0d0166 fix(agent): wait for fresh PDD clipboard link (#105)。
  • APK 已覆盖安装到一加 PKG110:0.9.2 / versionCode 15;无障碍服务仍为启用状态。

待人工业务回归

请在一加手机 PDD 商品详情页切回 Agent,点击采集并确认。预期 PDD 异步写入链接后 Agent 能在有限超时内继续识别 goods_id;若始终没有合法新链接,仍明确返回 PDD_CLIPBOARD_UNAVAILABLE。不涉及采购、创建订单或支付。工单保持待验收。

## 实现与自动化验证完成,待真机业务回归 ### 实现 - `ClipboardRelayActivity` 由固定延迟后的单次读取改为每 100ms 有限轮询。 - 调用方使用既有 `clipboardTimeoutMs`(500~10000ms)计算单调时钟 deadline;到期立即失败,不会无限等待。 - 成功、超时、请求消失或 Activity 销毁后均停止回调并只交付一次。 - 保留本次复制新鲜度、`text/plain`、单条、4096 字符上限以及后续 PDD HTTPS 域名白名单校验。 - Agent 版本更新为 0.9.2(versionCode 15)。 - 未修改 Server、数据库、规则、UI 或采购能力;未记录或保存剪贴板内容。 - 无长期契约变化,只恢复 #101 已记录的有限等待行为,按工单约定跳过 Wiki。 ### 验证 - `cd android && .\gradlew.bat testDebugUnitTest assembleDebug`:通过。 - 新增单元测试:旧内容后出现新内容成功、持续无效直到超时、错误 MIME、多条、超长、缺失描述拒绝,以及成功/超时后不重复完成。 - `python dev_scripts/harness.py check --strict`:通过。 - `git diff --check`:通过。 - 本地提交:`f0d0166 fix(agent): wait for fresh PDD clipboard link (#105)`。 - APK 已覆盖安装到一加 PKG110:0.9.2 / versionCode 15;无障碍服务仍为启用状态。 ### 待人工业务回归 请在一加手机 PDD 商品详情页切回 Agent,点击采集并确认。预期 PDD 异步写入链接后 Agent 能在有限超时内继续识别 goods_id;若始终没有合法新链接,仍明确返回 `PDD_CLIPBOARD_UNAVAILABLE`。不涉及采购、创建订单或支付。工单保持待验收。
Author
Owner

用户于 2026-08-28 明确确认本工单验收通过。按项目流程记录验收结论并关闭工单;本次仅更新工单状态,无新增长期文档事实,不重复同步 Wiki。

用户于 2026-08-28 明确确认本工单验收通过。按项目流程记录验收结论并关闭工单;本次仅更新工单状态,无新增长期文档事实,不重复同步 Wiki。
ila closed this issue 2026-08-28 15:07:12 +08:00
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: OPC/goauto#105