补漏:句柄归属跨 chat 未校验(可撤别群消息)+ 习得贴纸开关无命令(整个子系统恒不执行) #102

Closed
opened 2026-07-30 05:56:52 +00:00 by KumaAgent · 0 comments
Member

补漏票。 这两条是 2026-07-29 全 ADR 查漏产出的 8 条「高紧迫」里的 2 条,写第一批票(#93/#94/#95)时从分类里掉出去了——既没进任何票,也没进任何待办清单。两条都是 实现/小/高紧迫,属批次一

掉出去的机制:#93 是「真 bug 合集」、#96/#101 是文档、#97 是结构,而"第四批 = 剩余实现类"从未落成清单。① 因为 #93 里已有一条 _handle_edit 的 bug,被误当成"self_recall/edit 领域已覆盖"(实为同两个函数里的两个不同 bug);② 因为它是"缺一条命令",三个桶都不属于。全 77 条的完整去处对账见 #103。

1. self_recall/edit 不校验句柄归属 → 可用 A 群的句柄撤 B 群的消息

ADR-0012「决策 → 2. 触发」+「6. 治理」:

撤/改限当前会话 + 平台撤回窗口;硬约束只针对自己的、窗口内消息

实际runtime_loop.py_handle_self_recall / _handle_edit 拿到 entry从不比较 entry.chat_id 与本轮 chat_id。查漏复核方已实测:在 gB 群用 gA 群的句柄撤回成功。

ADR 把这条称作结构不变量,理由是「误撤比不撤更糟」。

风险有多真:句柄是 uuid4 前 12 位,跨会话猜不到——但模型记错句柄归属比猜句柄现实得多(同一模型在多个 chat 间轮转,句柄形如 m7 的短标识极易串)。

为什么测试没抓到tests/test_self_message_control.py 全部用例都在单会话内——典型的「测试与被测守卫同构,守卫不存在也全绿」。

  • _handle_self_recall / _handle_edit 解析出 entry 后校验 entry.chat_id == chat_id,不等即 fail-closed 不产生任何平台调用(同这两个函数里既有的「句柄不解析即不动」风格)。
  • 补跨 chat 回归测试:在 chat B 用 chat A 的句柄调 self_recall/edit,断言 egress 零调用
  • 注意范围:ADR 那句里的「平台撤回窗口」那一半不在本票——它依赖 Sent Log 增加时间字段(查漏清单里的另一条,属第四批)。本票只做 chat_id 归属校验这一半,并在实现时注明另一半的依赖,别让下一个人以为整条 AC 已兑现。

2. 习得贴纸的 opt-in 开关没有任何命令可以打开 → 整个子系统恒不执行

ADR-0024「决策」节第 4 条:

默认关闭(opt-in),per-chat 开关,心智模型同 /settool

实际get_sticker_learning_enabled 无行时返回 False,而 set_sticker_learning_enabledsrc/ 零调用点、也没有对应的管理命令

后果:识别 → 去重 → 人设漂移守护 → 落库整条链永不触发search_stickers 恒查空库。也就是 249 行 learned_sticker.py + 一张存储表 + 一个 Qdrant collection + 工具 schema + 一整套测试,产出为零

learned_sticker.py:12 把这条跟进挂在「ADR-0010 运营面建好后」,而运营面已在 issue #83 宣布全部落地——前置早就满足了,只是没人回来接这根线。

  • 仿 /settool 加一条 per-chat 开关命令(走 ports.is_admin 校验,与其余管理命令同形)。
  • 命令覆盖网按 #92 建立的穷举守卫同步扩(tests/test_admin_commands_dispatch.py 的「已覆盖集合 == 管理命令集合」断言会因为新增命令而红,那正是它该做的)。
  • 端到端断言:开关打开后,收到贴纸能真的走完识别→落库;search_stickers 能查到。别只断言"开关能写进去"——那不能区分"开关生效了"和"开关写了但链路仍不通"。

Not in scope

  • ADR-0012 那句里的「平台撤回窗口」半(依赖 Sent Log 时间字段,属第四批,见 #103)。
  • 习得贴纸的其余部分(识别流水线/去重/检索本身在 issue #70 已实现,本票只补开关这一环)。
  • 其余 29 条中低紧迫实现类落差 → 第四批,清单见 #103。
> **补漏票。** 这两条是 2026-07-29 全 ADR 查漏产出的 8 条「高紧迫」里的 2 条,写第一批票(#93/#94/#95)时**从分类里掉出去了**——既没进任何票,也没进任何待办清单。两条都是 `实现/小/高紧迫`,属**批次一**。 > > 掉出去的机制:#93 是「真 bug 合集」、#96/#101 是文档、#97 是结构,而"第四批 = 剩余实现类"从未落成清单。① 因为 #93 里已有一条 `_handle_edit` 的 bug,被误当成"self_recall/edit 领域已覆盖"(实为同两个函数里的两个不同 bug);② 因为它是"缺一条命令",三个桶都不属于。全 77 条的完整去处对账见 #103。 ## 1. `self_recall`/`edit` 不校验句柄归属 → 可用 A 群的句柄撤 B 群的消息 ADR-0012「决策 → 2. 触发」+「6. 治理」: > 撤/改限当前会话 + 平台撤回窗口;硬约束只针对**自己的、窗口内**消息 **实际**:`runtime_loop.py` 的 `_handle_self_recall` / `_handle_edit` 拿到 `entry` 后**从不比较 `entry.chat_id` 与本轮 `chat_id`**。查漏复核方**已实测**:在 gB 群用 gA 群的句柄撤回成功。 ADR 把这条称作**结构不变量**,理由是「**误撤比不撤更糟**」。 风险有多真:句柄是 uuid4 前 12 位,跨会话猜不到——但**模型记错句柄归属比猜句柄现实得多**(同一模型在多个 chat 间轮转,句柄形如 `m7` 的短标识极易串)。 **为什么测试没抓到**:`tests/test_self_message_control.py` **全部用例都在单会话内**——典型的「测试与被测守卫同构,守卫不存在也全绿」。 - [ ] `_handle_self_recall` / `_handle_edit` 解析出 `entry` 后校验 `entry.chat_id == chat_id`,不等即 fail-closed **不产生任何平台调用**(同这两个函数里既有的「句柄不解析即不动」风格)。 - [ ] 补跨 chat 回归测试:在 chat B 用 chat A 的句柄调 `self_recall`/`edit`,断言 egress **零调用**。 - [ ] **注意范围**:ADR 那句里的「**平台撤回窗口**」那一半**不在本票**——它依赖 Sent Log 增加时间字段(查漏清单里的另一条,属第四批)。本票只做 chat_id 归属校验这一半,并在实现时注明另一半的依赖,别让下一个人以为整条 AC 已兑现。 ## 2. 习得贴纸的 opt-in 开关没有任何命令可以打开 → 整个子系统恒不执行 ADR-0024「决策」节第 4 条: > 默认关闭(opt-in),per-chat 开关,心智模型同 `/settool` **实际**:`get_sticker_learning_enabled` 无行时返回 `False`,而 `set_sticker_learning_enabled` 在 `src/` **零调用点、也没有对应的管理命令**。 **后果**:识别 → 去重 → 人设漂移守护 → 落库整条链**永不触发**,`search_stickers` 恒查空库。也就是 **249 行 `learned_sticker.py` + 一张存储表 + 一个 Qdrant collection + 工具 schema + 一整套测试,产出为零**。 `learned_sticker.py:12` 把这条跟进挂在「ADR-0010 运营面建好后」,而运营面已在 issue #83 宣布全部落地——**前置早就满足了**,只是没人回来接这根线。 - [ ] 仿 `/settool` 加一条 per-chat 开关命令(走 `ports.is_admin` 校验,与其余管理命令同形)。 - [ ] 命令覆盖网按 #92 建立的**穷举守卫**同步扩(`tests/test_admin_commands_dispatch.py` 的「已覆盖集合 == 管理命令集合」断言会因为新增命令而红,那正是它该做的)。 - [ ] 端到端断言:开关打开后,收到贴纸能真的走完识别→落库;`search_stickers` 能查到。**别只断言"开关能写进去"**——那不能区分"开关生效了"和"开关写了但链路仍不通"。 ## Not in scope - ADR-0012 那句里的「平台撤回窗口」半(依赖 Sent Log 时间字段,属第四批,见 #103)。 - 习得贴纸的其余部分(识别流水线/去重/检索本身在 issue #70 已实现,本票只补开关这一环)。 - 其余 29 条中低紧迫实现类落差 → 第四批,清单见 #103。
Yushu closed this issue 2026-07-30 12:53:41 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ProjectKuma/arise#102
No description provided.