门禁与校验分级:区分只读识别文案与可执行动作(不实现支付) #116

Closed
opened 2026-08-27 17:52:39 +08:00 by ila · 2 comments
Owner

所属与来源

  • 关联工单:#112 面板打开证据与规格值状态分离、#113 订单确认面板回顶、#115 识别文案迁入规则下发。
  • 来源:用户于 2026-08-27 提出「尽量把这些配置在采集采购规则里,修改采购门禁和『不执行付款』这条永久规则,因为是内部使用的项目,不需要很严格」,并在确认范围时明确:只改门禁与校验,不实现支付;建单目的是「尽量少改动、少发布 Agent,为了在 PDD App 兼容不同的商品详情页和不同的规格面板,改动 Admin 的采集规则就能解决问题」。
  • 类型:项目门禁与规则校验调整 / 仓库规则文档 + Server 校验(不含 Agent 行为变更)。
  • 工具回退说明:本工单通过 Gitea API 创建。当前会话未提供 Gitea MCP 工具,按 AGENTS.md「Gitea 交互与工单最小读取」记录回退原因。

问题陈述

目标是让「兼容 PDD 不同商品详情页与规格面板形态」这件事能靠改 Admin 规则完成,而不是每次发 APK。当前有一个结构性障碍:项目把「识别用的文字」和「要点击的文字」当成同一类东西一起禁止了。

具体表现:

  1. server/app/goauto/purchasecontract/contract.go:52-54 的 forbiddenTextFragments(含 支付、付款、免密、创建订单、提交订单、订单号、修改地址、收货地址)在 :160 处对动作的 textAliases 生效。这个设计对要点击的文字是正确的。
  2. 但项目里没有任何地方允许配置只读识别文案。#113 已证实的真机事实是:PDD 的订单确认面板必须靠「提交订单 ¥9.82」「支付方式」「已选」「关闭」「数量增减」这组信号才能识别;这些词是判断页面形态的依据,不是点击目标。
  3. 结果是这类形态识别只能写死在 Agent(PddProductDetailCollector.kt),PDD 一改版就得发版——正是本工单要消除的成本。
  4. AGENTS.md:28「不执行付款;任何自动支付实现、入口或测试都禁止进入本项目」与 CLAUDE.md:35「也不得实现支付」是绝对句式,任何模型读到都会把「在规则里写『支付方式』作为识别信号」一并拒绝。

目标

  1. 在仓库规则与服务端校验中,明确区分只读识别文案(允许由规则配置)与可执行动作文案(继续受禁止清单约束)。
  2. 改写 AGENTS.md / CLAUDE.md 中会误伤只读识别文案的绝对句式,改为按动作分级的表述。
  3. 保持「本项目当前不实现支付」这一事实结论不变,但把它的理由从「永久禁令」改为「尚未实现、需显式开关与能力位」,为后续单独评估留出口径。
  4. 不改变任何 Agent 运行时行为;本工单只动规则文档与服务端校验框架。

非目标

  • 不实现支付:不新增 pay 动作、不新增支付能力位的执行路径、不接入任何支付界面或测试。
  • 不放开地址类禁令(修改地址 / 收货地址 保持永久禁止点击,改错收货地址的破坏力高于其他项)。
  • 不修改 Agent 代码、不修改采集/采购执行逻辑、不修改数据库与共享 API 字段。
  • 不修改 #112 / #113 的面板识别实现(本工单为其提供可配置化的口径,不代其实施)。
  • 不修改 Admin 界面。

实施方案

一、仓库规则改写

  1. AGENTS.md:28 改为按动作分级的表述,建议文本:

    • 不执行付款。当前项目不实现任何自动支付动作、入口或测试;后续如需实现,必须先单独建单评估,并至少具备显式能力位、服务端开关、单笔金额上限与人工授权四项控制。支付、下单、订单相关文字允许作为只读识别信号出现在采集与采购规则中,用于判断页面形态;但任何规则都不得把它们配置为点击目标。
  2. AGENTS.md:29 的采购门禁保持不变(采集与采购仍分离),仅补一句说明:采集规则可以描述订单确认面板的只读特征,这不构成「采购代码混入采集」。

  3. CLAUDE.md:35 的「也不得实现支付」改为与上述一致的表述,避免模型将只读识别文案一并拒绝。

二、服务端校验分级

  1. purchasecontract/contract.go 将 forbiddenTextFragments 拆为两组,并明确各自的适用面:
    • forbiddenClickFragments(作用于动作 textAliases,即点击目标):保留现有全部词条,行为不变。
    • forbiddenAlwaysFragments(无论何种用途都禁止):修改地址、收货地址。
  2. 新增只读识别文案的校验入口(供 #115 的 collector.textAliases 与后续采购规则识别字段共用):允许 支付、付款、提交订单、订单号 等词,拒绝 forbiddenAlwaysFragments,并沿用既有长度与数量上限。
  3. contract.go:112 对 pay / payment 动作类型保持拒绝,但把错误信息从「包含永远禁止的支付动作」改为「支付动作尚未实现」,与新的规则口径一致,不产生「已放开」的误解。
  4. purchasecontract/default_test.go 中「默认规则不得包含 pay / 支付」的断言需相应调整:默认规则仍不得包含支付动作,但不应因出现只读识别文案而失败。调整时保留对动作类型的断言强度。

三、与 #115 的口径统一

  1. #115 正文写有「服务端拒绝在 B 类字段中写入 提交订单/确认订单/支付/付款」。该条与 #113 已证实的订单确认面板识别需求直接冲突,须按本工单口径修正为:B 类只读识别字段允许这些词;禁止的是把它们用作点击目标(该禁令由 Agent 侧不可配置的拒绝清单保证)。本工单落地后需在 #115 同步该修正。

安全边界

  • Agent 侧的点击拒绝清单(PddProductDetailCollector.kt:374 的 dangerousWords)保持在代码内且不接受规则覆盖;本工单不改动它。
  • 采购规则的动作 textAliases 校验强度不降低。
  • 地址类文字保持永久禁止。
  • 本工单不产生任何可执行支付路径;pay 动作在校验层仍被拒绝。
  • 不涉及创建订单、权限、并发、迁移与删除数据。

验收标准

  • AGENTS.md 与 CLAUDE.md 的表述一致,且明确「只读识别文案允许配置、点击目标不允许」。
  • 采购规则把 支付 / 提交订单 写进动作 textAliases 时仍被拒绝,错误信息不变。
  • 把 修改地址 / 收货地址 写进任何字段(动作或只读识别)都被拒绝。
  • 只读识别字段接受 提交订单、支付方式、订单号 等词,并受长度与数量上限约束。
  • pay / payment 动作类型仍被拒绝,错误信息改为「尚未实现」。
  • default_test.go 调整后仍能拦住「默认规则包含支付动作」这一真实风险。
  • 仓库内不存在任何可执行支付代码路径(以搜索与测试共同确认)。

验证方式

  • go test ./app/goauto/purchasecontract/... ./app/goauto/rulecontract/...
  • 全量检索确认无支付执行路径新增。
  • python dev_scripts/harness.py check --strict(规则文档结构)。
  • 本工单不改 Agent,不需要真机验证;如实记录该结论。

依赖、并行与风险

  • 与 #115 存在口径耦合:本工单先行落地,#115 按第 8 条实施;两者不并行。
  • 与 #112 / #113 无代码冲突,可并行。
  • 风险:放宽只读识别文案后,若后续有人把这些词误用于点击目标,防线只剩「动作 textAliases 校验」与「Agent 侧拒绝清单」。缓解:两道防线均不在本工单中削弱,且验收含针对性用例。
  • 回退:还原本工单提交即可恢复原门禁表述与校验,不涉及数据与接口。

文档影响

  • AGENTS.md、CLAUDE.md 属仓库规则文件,直接修改并提交。
  • 需更新 Wiki Business-Rules-and-Glossary(docs/03-business-rules-and-glossary.md):安全边界中关于付款与规则可配置范围的描述。
  • 需更新 Wiki Android-Agent-API-Contract(docs/08-agent-api-contract.md):现有「任何规则都不能执行付款」一句需按新口径改写,明确只读识别与点击目标的区别。
  • 按 Wiki-first 门禁:先改线上页面并回读 revision,再执行一轮 sync 与一轮 sync --check,把页面与 revision 写回本工单。

状态

待实施。

## 所属与来源 - 关联工单:#112 面板打开证据与规格值状态分离、#113 订单确认面板回顶、#115 识别文案迁入规则下发。 - 来源:用户于 2026-08-27 提出「尽量把这些配置在采集采购规则里,修改采购门禁和『不执行付款』这条永久规则,因为是内部使用的项目,不需要很严格」,并在确认范围时明确:**只改门禁与校验,不实现支付**;建单目的是「尽量少改动、少发布 Agent,为了在 PDD App 兼容不同的商品详情页和不同的规格面板,改动 Admin 的采集规则就能解决问题」。 - 类型:项目门禁与规则校验调整 / 仓库规则文档 + Server 校验(不含 Agent 行为变更)。 - 工具回退说明:本工单通过 Gitea API 创建。当前会话未提供 Gitea MCP 工具,按 `AGENTS.md`「Gitea 交互与工单最小读取」记录回退原因。 ## 问题陈述 目标是让「兼容 PDD 不同商品详情页与规格面板形态」这件事能靠改 Admin 规则完成,而不是每次发 APK。当前有一个结构性障碍:**项目把「识别用的文字」和「要点击的文字」当成同一类东西一起禁止了。** 具体表现: 1. `server/app/goauto/purchasecontract/contract.go:52-54` 的 `forbiddenTextFragments`(含 `支付`、`付款`、`免密`、`创建订单`、`提交订单`、`订单号`、`修改地址`、`收货地址`)在 `:160` 处对动作的 `textAliases` 生效。这个设计对**要点击的文字**是正确的。 2. 但项目里**没有任何地方允许配置只读识别文案**。#113 已证实的真机事实是:PDD 的订单确认面板必须靠「提交订单 ¥9.82」「支付方式」「已选」「关闭」「数量增减」这组信号才能识别;这些词是**判断页面形态的依据,不是点击目标**。 3. 结果是这类形态识别只能写死在 Agent(`PddProductDetailCollector.kt`),PDD 一改版就得发版——正是本工单要消除的成本。 4. `AGENTS.md:28`「不执行付款;任何自动支付实现、入口或测试都禁止进入本项目」与 `CLAUDE.md:35`「也不得实现支付」是绝对句式,任何模型读到都会把「在规则里写『支付方式』作为识别信号」一并拒绝。 ## 目标 1. 在仓库规则与服务端校验中,明确区分**只读识别文案**(允许由规则配置)与**可执行动作文案**(继续受禁止清单约束)。 2. 改写 `AGENTS.md` / `CLAUDE.md` 中会误伤只读识别文案的绝对句式,改为按动作分级的表述。 3. 保持「本项目当前不实现支付」这一事实结论不变,但把它的理由从「永久禁令」改为「尚未实现、需显式开关与能力位」,为后续单独评估留出口径。 4. 不改变任何 Agent 运行时行为;本工单只动规则文档与服务端校验框架。 ## 非目标 - **不实现支付**:不新增 `pay` 动作、不新增支付能力位的执行路径、不接入任何支付界面或测试。 - 不放开地址类禁令(`修改地址` / `收货地址` 保持永久禁止点击,改错收货地址的破坏力高于其他项)。 - 不修改 Agent 代码、不修改采集/采购执行逻辑、不修改数据库与共享 API 字段。 - 不修改 #112 / #113 的面板识别实现(本工单为其提供可配置化的口径,不代其实施)。 - 不修改 Admin 界面。 ## 实施方案 ### 一、仓库规则改写 1. `AGENTS.md:28` 改为按动作分级的表述,建议文本: > - 不执行付款。当前项目不实现任何自动支付动作、入口或测试;后续如需实现,必须先单独建单评估,并至少具备显式能力位、服务端开关、单笔金额上限与人工授权四项控制。**支付、下单、订单相关文字允许作为只读识别信号出现在采集与采购规则中,用于判断页面形态;但任何规则都不得把它们配置为点击目标。** 2. `AGENTS.md:29` 的采购门禁保持不变(采集与采购仍分离),仅补一句说明:采集规则可以描述订单确认面板的只读特征,这不构成「采购代码混入采集」。 3. `CLAUDE.md:35` 的「也不得实现支付」改为与上述一致的表述,避免模型将只读识别文案一并拒绝。 ### 二、服务端校验分级 4. `purchasecontract/contract.go` 将 `forbiddenTextFragments` 拆为两组,并明确各自的适用面: - `forbiddenClickFragments`(作用于动作 `textAliases`,即点击目标):保留现有全部词条,行为不变。 - `forbiddenAlwaysFragments`(无论何种用途都禁止):`修改地址`、`收货地址`。 5. 新增只读识别文案的校验入口(供 #115 的 `collector.textAliases` 与后续采购规则识别字段共用):允许 `支付`、`付款`、`提交订单`、`订单号` 等词,拒绝 `forbiddenAlwaysFragments`,并沿用既有长度与数量上限。 6. `contract.go:112` 对 `pay` / `payment` 动作类型保持拒绝,但把错误信息从「包含永远禁止的支付动作」改为「支付动作尚未实现」,与新的规则口径一致,不产生「已放开」的误解。 7. `purchasecontract/default_test.go` 中「默认规则不得包含 `pay` / `支付`」的断言需相应调整:默认规则仍不得包含支付**动作**,但不应因出现只读识别文案而失败。调整时保留对动作类型的断言强度。 ### 三、与 #115 的口径统一 8. #115 正文写有「服务端拒绝在 B 类字段中写入 `提交订单/确认订单/支付/付款`」。该条与 #113 已证实的订单确认面板识别需求直接冲突,**须按本工单口径修正为**:B 类只读识别字段允许这些词;禁止的是把它们用作点击目标(该禁令由 Agent 侧不可配置的拒绝清单保证)。本工单落地后需在 #115 同步该修正。 ## 安全边界 - Agent 侧的点击拒绝清单(`PddProductDetailCollector.kt:374` 的 `dangerousWords`)保持在代码内且不接受规则覆盖;本工单不改动它。 - 采购规则的动作 `textAliases` 校验强度不降低。 - 地址类文字保持永久禁止。 - 本工单不产生任何可执行支付路径;`pay` 动作在校验层仍被拒绝。 - 不涉及创建订单、权限、并发、迁移与删除数据。 ## 验收标准 - [ ] `AGENTS.md` 与 `CLAUDE.md` 的表述一致,且明确「只读识别文案允许配置、点击目标不允许」。 - [ ] 采购规则把 `支付` / `提交订单` 写进动作 `textAliases` 时仍被拒绝,错误信息不变。 - [ ] 把 `修改地址` / `收货地址` 写进任何字段(动作或只读识别)都被拒绝。 - [ ] 只读识别字段接受 `提交订单`、`支付方式`、`订单号` 等词,并受长度与数量上限约束。 - [ ] `pay` / `payment` 动作类型仍被拒绝,错误信息改为「尚未实现」。 - [ ] `default_test.go` 调整后仍能拦住「默认规则包含支付动作」这一真实风险。 - [ ] 仓库内不存在任何可执行支付代码路径(以搜索与测试共同确认)。 ## 验证方式 - `go test ./app/goauto/purchasecontract/... ./app/goauto/rulecontract/...` - 全量检索确认无支付执行路径新增。 - `python dev_scripts/harness.py check --strict`(规则文档结构)。 - 本工单不改 Agent,不需要真机验证;如实记录该结论。 ## 依赖、并行与风险 - 与 #115 存在口径耦合:本工单先行落地,#115 按第 8 条实施;两者不并行。 - 与 #112 / #113 无代码冲突,可并行。 - 风险:放宽只读识别文案后,若后续有人把这些词误用于点击目标,防线只剩「动作 textAliases 校验」与「Agent 侧拒绝清单」。缓解:两道防线均不在本工单中削弱,且验收含针对性用例。 - 回退:还原本工单提交即可恢复原门禁表述与校验,不涉及数据与接口。 ## 文档影响 - `AGENTS.md`、`CLAUDE.md` 属仓库规则文件,直接修改并提交。 - 需更新 Wiki `Business-Rules-and-Glossary`(`docs/03-business-rules-and-glossary.md`):安全边界中关于付款与规则可配置范围的描述。 - 需更新 Wiki `Android-Agent-API-Contract`(`docs/08-agent-api-contract.md`):现有「任何规则都不能执行付款」一句需按新口径改写,明确只读识别与点击目标的区别。 - 按 Wiki-first 门禁:先改线上页面并回读 revision,再执行一轮 `sync` 与一轮 `sync --check`,把页面与 revision 写回本工单。 ## 状态 待实施。
Author
Owner

实施完成,待验收

实现

  • AGENTS.md 与 CLAUDE.md 已按用途区分只读识别文字和可执行点击目标。
  • 当前仍不实现任何支付动作、入口或测试;pay / payment 动作继续在服务端拒绝,错误口径改为“尚未实现”。
  • 采购动作 textAliases 的禁止清单强度不变:支付、付款、免密、创建/提交订单、订单号和地址文字仍不能成为点击目标,既有错误信息保持不变。
  • 新增服务端只读文字校验入口 ValidateReadOnlyTextAliases:允许“提交订单”“支付方式”“订单号”“付款说明”等页面证据;“修改地址”“收货地址”在任何可配置用途仍拒绝;数量、长度、空白和重复限制由调用契约明确传入。
  • 默认采购规则测试改为检查动作类型,不再因为未来只读字段出现“支付”文字而误报。
  • 未修改 Android Agent、数据库、共享 API 字段、Admin 或任何运行时支付路径。

验证

  • go test ./app/goauto/purchasecontract/... ./app/goauto/rulecontract/...:通过。
  • .\scripts\verify.ps1 -Component server:通过(go test ./...、go build)。
  • python dev_scripts/harness.py check --strict:通过。
  • git diff --check:通过。
  • 仓库差异审查确认没有新增支付 action、能力位或执行调用。
  • 本工单不改 Agent,无需真机验证。

Wiki

  • Business-Rules-and-Glossary:26618d4312a1e7091f6b483111c31e67f70f26eb
  • Android-Agent-API-Contract:3d6a43359e015d4d6eaeb896f63dc1920ca601f6
  • 两页已在线回读;一轮 sync 与一轮 sync --check 均通过。

提交

3619435 — refactor(#116): separate read-only aliases from actions,已推送到 origin/main。

工单保持打开,等待用户验收。

## 实施完成,待验收 ### 实现 - `AGENTS.md` 与 `CLAUDE.md` 已按用途区分只读识别文字和可执行点击目标。 - 当前仍不实现任何支付动作、入口或测试;`pay` / `payment` 动作继续在服务端拒绝,错误口径改为“尚未实现”。 - 采购动作 `textAliases` 的禁止清单强度不变:支付、付款、免密、创建/提交订单、订单号和地址文字仍不能成为点击目标,既有错误信息保持不变。 - 新增服务端只读文字校验入口 `ValidateReadOnlyTextAliases`:允许“提交订单”“支付方式”“订单号”“付款说明”等页面证据;“修改地址”“收货地址”在任何可配置用途仍拒绝;数量、长度、空白和重复限制由调用契约明确传入。 - 默认采购规则测试改为检查动作类型,不再因为未来只读字段出现“支付”文字而误报。 - 未修改 Android Agent、数据库、共享 API 字段、Admin 或任何运行时支付路径。 ### 验证 - `go test ./app/goauto/purchasecontract/... ./app/goauto/rulecontract/...`:通过。 - `.\scripts\verify.ps1 -Component server`:通过(`go test ./...`、`go build`)。 - `python dev_scripts/harness.py check --strict`:通过。 - `git diff --check`:通过。 - 仓库差异审查确认没有新增支付 action、能力位或执行调用。 - 本工单不改 Agent,无需真机验证。 ### Wiki - Business-Rules-and-Glossary:`26618d4312a1e7091f6b483111c31e67f70f26eb` - Android-Agent-API-Contract:`3d6a43359e015d4d6eaeb896f63dc1920ca601f6` - 两页已在线回读;一轮 `sync` 与一轮 `sync --check` 均通过。 ### 提交 `3619435` — `refactor(#116): separate read-only aliases from actions`,已推送到 `origin/main`。 工单保持打开,等待用户验收。
Author
Owner

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

用户于 2026-08-28 明确确认本工单验收通过。按项目流程记录验收结论并关闭工单;本次仅更新工单状态,无新增长期文档事实,不重复同步 Wiki。
ila closed this issue 2026-08-28 15:07:11 +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#116