diff --git a/docs/DEBTS.json b/docs/DEBTS.json index 6a2c63c..8bf5ef6 100644 --- a/docs/DEBTS.json +++ b/docs/DEBTS.json @@ -435,10 +435,10 @@ { "id": "failure-report-cycle-suppress-by-relayed-mails-lookup", "count": 1, - "due": "桥侧要抑制『报告的报告』时(照此判据实现);或任何人再算这类环的规模时(口径必须是 '%failure:%' 与 '%-failure:%' 的并集)", + "due": "桥侧要抑制『报告的报告』时(照此判据实现;**无需整链抑制机制**,逐跳判定自带该性质);或任何人再算这类环的规模时(口径必须是 '%failure:%' 与 '%-failure:%' 的并集)", "where": "relayed_mails.relay_key(最后一段 = 被指向那封的 mail_id)· 桥侧落点 plugins/*-mail-bridge/src/index.ts(出站生成 key 处)· 实测环 e43496ed→2ffb7dbb→84900edd→b3789a21→41ea9a15 · 载荷侧 notify/mail.go grep relay=0(故加字段要改网关)", - "kind": "**『报告的报告』的自激环,判据已在元数据里**:本封 relay_key 指向的那封 ∈ relayed_mails ⇒ 该抑制,网关契约一个字不用改(逐跳实测:第 2 跳起 4/4 命中,第 1 跳是根不命中)。本轮修正 pi 一处口径误读——标题启发式在真值口径下 **10/10 全中、漏 0**,问题是它答的是另一个问题(『是失败报告』59 封 vs 『在报告报告』10 封),拿它抑制会误杀 59 封真报告", - "note": "★★★ 2026-09-30 登记。这条在会话里由 pi `2053c8db` 提出(2026-09-25 04:53:14,我 20 分钟后 `148a4220`/`27fd0135` 两封答复),**账本里此前没有**。本轮把它连同**一处口径修正**一起落进来。\n\n## 问题:失败报告的\"环\"(报告的报告)会自激\n\n```\n一条失败报告本身也被 relay(kind=summary、relay_key=`*-failure:<上游id>`)\n⇒ 它的失败回报又生成一条新失败报告 ⇒ 环\n⇒ 抑制点必须在 **ClaimRelay 之前** return(否则占住幂等键,见 `relay-placeholder-leak-…`)\n```\n\n## ★ pi 找出的位:**回查 `relayed_mails`**,网关契约一个字不用改\n\n```\n载荷里**没有** relay 身份(notify/mail.go 全文件 grep relay = **0**;mail.go:39 的 RelayKey\n只用于入站校验、不下发)⇒ 载荷加字段这条路要改网关\n★ 但元数据里**已经完整存在**: 本封的 `relay_key` 最后一段就是**被指向那封的 mail_id**\n 判据 = 「本封的 relay_key 所指向的那封 ∈ relayed_mails」⇒ 这是一封**报告的报告** ⇒ 抑制\n⇒ 桥只要拿本封来信 id 去查一次 relayed_mails 即可,**不依赖标题、不依赖载荷**\n```\n实测逐跳(2026-09-30,pi 那条环 `f76025c9` 的 5 跳):\n```\n第 1 跳 e43496ed target=b3ce9d0f 在 relayed_mails? **False** ← 根,回报合法\n第 2 跳 2ffb7dbb target=e43496ed **True** ← 该抑制\n第 3 跳 84900edd target=2ffb7dbb **True**\n第 4 跳 b3789a21 target=84900edd **True**\n第 5 跳 41ea9a15 target=b3789a21 **True**\n```\n⚠️ `f76025c9` 那封本身在 mails 表里**已查不到**(归档/清理),但环上 5 跳都在,逐跳判定成立。\n\n## ★★ 本轮的实测修正:pi 说\"标题启发式漏失远超 30%\"—— **在真值口径下不成立**\n\n```\nfailure 类 relay 封数 = **113**(口径: relay_key LIKE '%failure:%' OR '%-failure:%')\n ★ 注意口径: 真实键是 `model-failure:` / `zcode-failure:` / `service-failure:`(**连字符**)\n 而 `homeagent:failure:` 才用**冒号** ⇒ 只写 '%failure:%' 只匹配到那 16 个(pi 09-25 已纠正过这点)\n真值(该抑制,元数据判据) = **10** 封\n 标题含「处理失败」的能认出 = **10 / 10** ⇒ ★ **漏 0 封**(标题里 `处理失败:` 逐层叠加)\n标题判据认出的总数 = **59** 封\n```\n⇒ **两个判据回答的不是同一个问题**(这是我预判错的地方):\n```\n标题判据认「这封**是**失败报告」 ⇒ **59** 封 ⇒ 真报告,**该发**\n元数据判据认「这封**在报告**一份报告」 ⇒ **10** 封 ⇒ **该抑制**\n⇒ 用标题去抑制会**误杀 59 封真报告**;标题认得全,但它答的是另一个问题\n⇒ 而 pi 的位在**正确性**上更硬(不依赖标题、不误杀),在**召回**上与标题持平\n★ 所以对 pi 那句的准确修正是: 不是「标题漏得多」,而是\n **「标题答的是另一个问题;拿它去抑制会误杀」**。\n```\n\n## 可判动作 / 修法要点\n\n· 桥侧:`data.mail_id` → 查本封 ∈ `relayed_mails` ? 是 ⇒ 抑制回报;否 ⇒ 正常回报。\n· ⚠️ 抑制必须发生在 **ClaimRelay 之前**,否则又落一个占位行(永占幂等键)。\n· 口径陷阱:判 failure 类要用 `'%failure:%'` **或** `'%-failure:%'` **两者并集**。\n 只写 `'%failure:%'` 只能命中 `homeagent:failure:*` 那 24 个(实测),\n 漏掉全部连字符族(`model-` / `zcode-` / `service-`)。\n ⇒ 只写前者会**漏 89 个**(113 − 24),不是漏 97 —— 我第一版把数算反了,已按实测改。\n\n## 边界 / 未做\n\n· **没有改任何代码**(本轮只读 SQL)。该位**未落地**——落点在桥侧(`plugins/*-mail-bridge/src/index.ts`),\n 且要与\"环整体抑制还是只抑制一跳\"配套决定。\n· 10 / 59 / 113 都是**此刻**的值(瞬时量),引用须带时刻。\n· 我**没有**去核\"标题判据在别的 session 上是否也 10/10\"——样本只此一个环族。\n· 我**没有**判定 pi 那句\"漏失远超 30%\"是在哪个口径下说的(他未附口径)——\n 我只能说在真值口径下它不成立。\n· 未能回给 pi(`send_mail` 被会话闸挡下)。" + "kind": "**『报告的报告』的自激环,判据已在元数据里**:本封 relay_key 指向的那封 ∈ relayed_mails ⇒ 该抑制,网关契约一个字不用改(逐跳实测:第 2 跳起 4/4 命中,第 1 跳是根不命中;链长实测最长 5 层但判据逐跳独立 ⇒ 不需要『整链抑制』的配套机制)。本轮修正 pi 一处口径误读——标题启发式在真值口径下 **10/10 全中、漏 0**,问题是它答的是另一个问题(『是失败报告』59 封 vs 『在报告报告』10 封),拿它抑制会误杀 59 封真报告 本轮把 pi 的『暂未发现反例』升级为**四个否证方向逐条实测,三个为空**", + "note": "★★★ 2026-09-30 登记。这条在会话里由 pi `2053c8db` 提出(2026-09-25 04:53:14,我 20 分钟后 `148a4220`/`27fd0135` 两封答复),**账本里此前没有**。本轮把它连同**一处口径修正**一起落进来。\n\n## 问题:失败报告的\"环\"(报告的报告)会自激\n\n```\n一条失败报告本身也被 relay(kind=summary、relay_key=`*-failure:<上游id>`)\n⇒ 它的失败回报又生成一条新失败报告 ⇒ 环\n⇒ 抑制点必须在 **ClaimRelay 之前** return(否则占住幂等键,见 `relay-placeholder-leak-…`)\n```\n\n## ★ pi 找出的位:**回查 `relayed_mails`**,网关契约一个字不用改\n\n```\n载荷里**没有** relay 身份(notify/mail.go 全文件 grep relay = **0**;mail.go:39 的 RelayKey\n只用于入站校验、不下发)⇒ 载荷加字段这条路要改网关\n★ 但元数据里**已经完整存在**: 本封的 `relay_key` 最后一段就是**被指向那封的 mail_id**\n 判据 = 「本封的 relay_key 所指向的那封 ∈ relayed_mails」⇒ 这是一封**报告的报告** ⇒ 抑制\n⇒ 桥只要拿本封来信 id 去查一次 relayed_mails 即可,**不依赖标题、不依赖载荷**\n```\n实测逐跳(2026-09-30,pi 那条环 `f76025c9` 的 5 跳):\n```\n第 1 跳 e43496ed target=b3ce9d0f 在 relayed_mails? **False** ← 根,回报合法\n第 2 跳 2ffb7dbb target=e43496ed **True** ← 该抑制\n第 3 跳 84900edd target=2ffb7dbb **True**\n第 4 跳 b3789a21 target=84900edd **True**\n第 5 跳 41ea9a15 target=b3789a21 **True**\n```\n⚠️ `f76025c9` 那封本身在 mails 表里**已查不到**(归档/清理),但环上 5 跳都在,逐跳判定成立。\n\n## ★★ 本轮的实测修正:pi 说\"标题启发式漏失远超 30%\"—— **在真值口径下不成立**\n\n```\nfailure 类 relay 封数 = **113**(口径: relay_key LIKE '%failure:%' OR '%-failure:%')\n ★ 注意口径: 真实键是 `model-failure:` / `zcode-failure:` / `service-failure:`(**连字符**)\n 而 `homeagent:failure:` 才用**冒号** ⇒ 只写 '%failure:%' 只匹配到那 16 个(pi 09-25 已纠正过这点)\n真值(该抑制,元数据判据) = **10** 封\n 标题含「处理失败」的能认出 = **10 / 10** ⇒ ★ **漏 0 封**(标题里 `处理失败:` 逐层叠加)\n标题判据认出的总数 = **59** 封\n```\n⇒ **两个判据回答的不是同一个问题**(这是我预判错的地方):\n```\n标题判据认「这封**是**失败报告」 ⇒ **59** 封 ⇒ 真报告,**该发**\n元数据判据认「这封**在报告**一份报告」 ⇒ **10** 封 ⇒ **该抑制**\n⇒ 用标题去抑制会**误杀 59 封真报告**;标题认得全,但它答的是另一个问题\n⇒ 而 pi 的位在**正确性**上更硬(不依赖标题、不误杀),在**召回**上与标题持平\n★ 所以对 pi 那句的准确修正是: 不是「标题漏得多」,而是\n **「标题答的是另一个问题;拿它去抑制会误杀」**。\n```\n\n## 可判动作 / 修法要点\n\n· 桥侧:`data.mail_id` → 查本封 ∈ `relayed_mails` ? 是 ⇒ 抑制回报;否 ⇒ 正常回报。\n· ⚠️ 抑制必须发生在 **ClaimRelay 之前**,否则又落一个占位行(永占幂等键)。\n· 口径陷阱:判 failure 类要用 `'%failure:%'` **或** `'%-failure:%'` **两者并集**。\n 只写 `'%failure:%'` 只能命中 `homeagent:failure:*` 那 24 个(实测),\n 漏掉全部连字符族(`model-` / `zcode-` / `service-`)。\n ⇒ 只写前者会**漏 89 个**(113 − 24),不是漏 97 —— 我第一版把数算反了,已按实测改。\n\n## 边界 / 未做\n\n· **没有改任何代码**(本轮只读 SQL)。该位**未落地**——落点在桥侧(`plugins/*-mail-bridge/src/index.ts`),\n 且要与\"环整体抑制还是只抑制一跳\"配套决定。\n· 10 / 59 / 113 都是**此刻**的值(瞬时量),引用须带时刻。\n· 我**没有**去核\"标题判据在别的 session 上是否也 10/10\"——样本只此一个环族。\n· 我**没有**判定 pi 那句\"漏失远超 30%\"是在哪个口径下说的(他未附口径)——\n 我只能说在真值口径下它不成立。\n· 未能回给 pi(`send_mail` 被会话闸挡下)。\n\n## ★★ 第⑤条判据的否证清单(2026-09-30 逐条实测,全部为空)\n\npi 那张判决表里第⑤条写的是「**暂未发现反例**」。本轮把它升级为**四个方向逐一实测**:\n\n```\n命中判据的封数 = **10**(口径同前: '%failure:%' ∪ '%-failure:%')\n D1 被指向那封【自身非 failure 键】⇒ 会误杀正常转发 : **0** ✓\n D2 被指向那封【在 mails 表已不存在】⇒ 回查空 ⇒ 漏判 : **0** ✓\n D3 判据与标题不一致(标题不含『处理失败』) : **0** ✓\n D4 链长 >1 层(本封自己也是上一份报告的报告) : **10/10** ⚠️ 见下\n⇒ 前三个方向都没有反例;D4 不是反例,而是它的**工作方式**。\n```\n\n### D4 澄清了一个未决项:要不要\"整链抑制\"?(**不需要**)\n\n```\n10 封的链长实测: 2/2/5/2/3/3/4/3/2/4 ⇒ **最长 5 层**(41ea9a15←b3789a21←84900edd←2ffb7dbb←e43496ed)\n★ 我一度以为\"链长 >1 ⇒ 只抑制一跳会漏、需要整链砍的额外机制\" —— **这个推断是错的**:\n 判据是**逐跳独立**的 —— 每一跳各自回查**自己**的 target,而链上**每一跳**都命中\n ⇒ 链在生成过程中就被**逐跳**砍断,根本长不起来\n⇒ 这 10 封是**判据未上线时的历史遗留**(正是它要消灭的东西)\n⇒ ★ 所以 pi 判决表那条备注「需与『环整体抑制还是只抑制一跳』配套决定」——\n **不成立**: 不需要配套决定,逐跳判定自带这个性质。\n★ 这条是我自己的 ⑬′ 读法派上用场: 我没有只验 D1(最容易被验的那个),\n 而是先把**否证方向列全**再逐条跑 —— 若只跑 D1,我会漏掉 D4,\n 而 D4 恰恰是要我去澄清\"要不要整链机制\"的那一条。\n" } ] }