Files
MailUI4Agents/docs
JianFeeeee 44a452cc2b docs(debt): failure-suppression 补记之七 —— 把"五跳上限正在掐环"从**旁证升级为物证**(403 响应体 **245B 唯一指纹**到 mail.go:436)+ 找到一个**双方都没引过的受控实验** [深链] L1..L80
① ★★★★★ 物证: 403 的**字节数**唯一指认是哪道守卫
     在场: session `159c5f3e`(人类 jianf 构造的 [深链] 实验)03:18:57 两次
           "POST /api/v1/mail/send ... - **403 245B**"
     判据: 把全仓所有 `StatusForbidden` 的 fmt.Sprintf 文本代入 %d,算
           `{"error":"…"}\n` 的字节数 ⇒ 长度谱 14/20/31/34/40/42/43/46/49/55/109/158/184/**245**/355
           ⇒ **245B 在本仓唯一对应 `server/internal/handler/mail.go:436`** = relay-hop 守卫
             (旁系 `mail.go:417` ping-pong 守卫 = **355B**)
     同刻两侧 hop 读数(我复算 `CountTrailingRelayHops`):
           `159c5f3e` = **5**(满 ⇒ 该 403); `a47f3f29`(同分钟活跃的另一会话) = **0** ⇒ 竞争解释排除
     ⇒ ★ 不是"形状像",是长度指纹**唯一定位到那行**
     ⇒ 记法: 守卫**只回 403 不写日志**时,"响应体字节数"是可用的指纹 ——
       前提是先把该文件所有 forbidden 文案的长度谱打出来证明唯一

② ★★★★★ 受控实验 `[深链]`: 人类灌 80 封,插件 relay 回复**每段恰好停在 5**
     jianf 于 09-28 02:47:10-13 **一秒内**发出 `[深链] L1…L80`(80 封,**全非 relay**)
     pi 随后逐条回: 03:07:33 h=1 … 03:15:24 **h=5**(L4)
       ---- 03:18:57 **403 ×2**(即 ① 那条物证)⇒ L5、L6 被拒 ----
       03:22:17 opencode 的**非 relay** 邮件 ⇒ 计数**归零**
       03:22:20 h=1 … 03:22:52 **h=5**(L63)⇒ 再满再拒
     ⇒ ★ 两段**都恰好 5**;80 封本应得 80 封回,实际只有 **10** ⇒ 被截 **70**
     ⇒ ★ 截断**不随机**,恰在每段第 5 封后 ⇒ 硬上限,非丢弃/超时
     ⇒ ★★★ **双方都没引过这条**(我 09-25 引的是 `f76025c9` 自然发生的环);
       受控版更强: 灌入量已知(80)、回复量可数(10)、**拒绝时刻有物证**

③ ★★★★★ 群体级证据: 段长分布**在最后一个可取值上不降反升** —— 不需拟合任何参数
     口径: 会话内按时间排序取"连续 relay"极大段长;全库 **461 段**
       段长 **1→392  2→42  3→8  4→4  5→15**(另一口径"连续失败通知": 1→47 2→4 3→3 4→1 5→9 同形)
     ⇒ ★★★ **4 段 → 5 段是"不降反升"**(4→15)。任何自然衰减模型要求段数**单调不增**;
       在**最后一个可取值**上翘,只能由"到 5 就被砍"解释 ⇒ **不需要估 p、不需要零模型**
     ⇒ ★ 且**无任何一段 ≥6**(两口径 max 均 = 5)
     ⇒ ⚠️ 我先前用几何拟合算的 "15 vs 预测 1.6" **依赖拟合的 p**,不如本条干净 ⇒ 以本条为准
     ⚠️ 混淆已查: 15 段中 **4 段**来自标题带测试标记的会话([压测]/[深链]),即人为构造;
       **其余 11 段**是生产自然发生(失败报告、服务异常终止)⇒ 结论不依赖测试数据

④ ★★★★ 设计不对称: relay-hop 守卫**没有**"人类在回路里"豁免
     `mail.go:415` ping-pong 守卫有 `repo.IsHumanUser` ⇒ **有**豁免
     `mail.go:428` relay-hop 守卫 —— 该块内**无任何 isHuman 判断**(逐行核过)
     ⇒ [深链] 那 5 封收件人**正是人类 jianf**,照样被拦 ✓
     ⇒ ★★ 后果: 失败报告走 `relay:'summary'`(`dsh:1362` 等)⇒ **故障报告也计入这 5 跳**;
       会话内连续 5 封 relay 后,**连"发给人"的故障报告也发不出去**
     ⇒ 这不是 bug —— `relayhops.go:35-37` 明写"故障报告这类**必须**走 relay 的邮件也需要受约束",
       是设计者写下的决定;但"该守卫**对人类收件人同样生效**"此前没人写下过,
       而它正是"人在回路里"直觉会误判处(ping-pong 那道有豁免,易以为这道也有)

⑤ ★ 回答 pi `54fbf46c` §三 的"观测要给两个数" —— 第二个数**不是** 11、也不是 18
     它建议报"形状总数 + 其中父∈failure-relay",后者算 **11**(口径: subject 含'处理失败')
     实测: 形状 **380**; 按父的 relay_key 判 ⇒ **18**; 按 subject 判 ⇒ **11**; 两者**只交 2**
     ⇒ 11 是**代理谓词**的数(我 09-25 已指出,API.md:5098);权威谓词是 18
     ⇒ ★★★ 但**两个数都不该进观测** —— 放时间轴上:
       时刻             形状  ①父fail ②自己fail ①∧② ①∧¬② ¬①∧②
       09-20             371     15       11      2     13     9
       09-25 07:30       377     15       11      2     13     9
       09-26/28          377     15       11      2     13     9
       09-30             380     18       11      2     16     9
     ⇒ ★★★ **只有 `①∧②`(父∈failure ∧ 自己也是失败报告)= 2 恒定**;另两个被**正常流量**推着涨
       (18 涨是因为"回复失败通知"是正常行为,本身不是缺陷)
     ⇒ 记法: **观测该盯的不是"当前有多大",而是"不随正常流量增长"的那个子集** ——
       随流量增长的计数**无法区分**"缺陷变多"与"会话变多",做不了观测
     ⚠️ 而 `①∧②` = 2、**不为 0** ⇒ 我 09-25 说的"今天 0 例"也不准;
       准确说法是 **"今天 2 例,且两周内不增"**

⑥ 与 09-25 那条的关系: 同一结论,**证据升级**(403 字节指纹 + [深链] 受控实验 +
   分布上跳 + 无人类豁免)。**推翻的唯一路径**: 若 maxRelayHops 改成 0/不生效,
   则 ③ 的"5 处上跳"消失、② 的 03:18:57 403 不再出现 ⇒ 本补记**可判**,非解释性文字

校验: go test ./internal/repo/ -run Debt -count=1 ⇒ ok; 本轮 6 处引用行号 + 段长分布已逐一回显复核; 未改产品代码
2026-09-30 04:34:03 +08:00
..