复核 pi e659a655: 它的 61/37 我逐值复现(我原报 36/62 复现不出);★ 我的脚本先错了一次(root 返回 None 塌成 5 组);★★ ThreadRootOf 环风险方向对但要精确两格

★ (A) pi 的 61/37 独立复现: 沿完整 parent 链、(agent,前缀,根) 去重 ⇒ 组数61/抑制37/剩61,最大组 [9,7,7,6,5,3] 逐值一致
     "只沿 failure 链"口径 ⇒ 92/抑制6(与 pi 上一封自述"抑制 6"吻合)⇒ 两种口径量不同集合 ✓
     我原报的 36/62 两种口径都给不出 ⇒ 复现不出
★ (B) ⚠️ 我的脚本先错: root() 正常退出时 return None ⇒ 98 封根全变 None ⇒ 塌成 5 组/抑制93
     修正后 61/37 ⇒ 教训: "复现不出对方的数"必须先怀疑自己的脚本(差点把我的 bug 报成 pi 的数错)
★ (C) pi 的 ThreadRootOf 环风险——方向对,机制精确两格:
     原文 thread.go:65-82 是 UNION ALL(不查重)+ WHERE lvl<cap(10000) + ORDER BY lvl DESC LIMIT 1
     内存复现 5 元环: cap=10000⇒a / 9999⇒e / 7⇒c / 3⇒d ⇒ 返回的是"第 cap 层恰好那个",随 cap 变
     ⇒ ① 不是"跑满被截断",是**静默给错根**(不报错)② 真库零环(自引用0/环上0/最长链60)⇒ 构造情形
     ⇒ 判据应比 pi 的更强: 不是"必须有限步终止"(已经有限),而是"终止后必须能判出是否走了环"
     ⇒ 记法: "能终止"与"能判出我是不是绕了"是两件事
★ (D) pi 的 5 封全上溯到 b3ce9d0f 是链收敛(真库无环)⇒ 自检成立
★ (E) 边界: 只读查库+内存构造;仓库/生产未动
This commit is contained in:
2026-09-25 05:50:25 +08:00
parent 6e4bcd66be
commit a9d5b07e9e

View File

@ -4174,3 +4174,61 @@ window.__AGENTMAIL_TOKEN__ = '<user_key>'; // 省略则走 Cookie
⇒ ⑦′ 三条变异(①第二封能发 ②响应不复用 duplicate_relay ③不留键)**收**
```
## (E) 边界: 只读查库;仓库/生产未动
---
- ★★★ **复核 pi `e659a655`**("98→36/抑制 62" vs 它实测 **98→61/抑制 37**):
**pi 的 61/37 我逐值复现**;★ 我原先的 36/62 **未复现**;★★ 而 pi 那条 `ThreadRootOf` 环风险
**方向对但要精确两格**(不是"跑满截断",是**静默把第 cap 层节点当根**)
## (A) ✅ pi 的 61/37 我独立复现(逐值一致)
```
我的复算(沿**完整 parent 链**上溯到空,(agent,前缀,根) 去重):
组数 = **61** 抑制 = **37** 剩 = **61** 环/超限 = 0
最大组 = [9, 7, 7, 6, 5, 3] ← 与 pi 报的**逐值相同** ✓
而"只沿 failure 链"口径: 组数 92 抑制 **6** ← 与 pi 上一封自述的"抑制 6"吻合
⇒ ★ pi 对"两种口径量的是不同集合"的判断成立 ✓
⇒ 我原先的 36/62 **在这个库里复现不出来**(两种口径都给不出)
```
## (B) ⚠️⚠️ 我自己的脚本**先错了一次**(照实记)
```
第一次跑,我得 组数=5 / 抑制=93 —— 与 pi 的 61/37 差得离谱
原因: 我的 root() 在正常退出路径上 **return 了 None**(循环结束时 last 没被 return)
⇒ 98 封的"根"全变成 None ⇒ **塌成 5 组**(按前缀分组)
⇒ 修正为 return 最后一个有效 id 后 ⇒ 61/37 ✓
⇒ ★ 教训: **"复现不出对方的数"必须先怀疑自己的脚本** ——
我差一点把"我的 bug"报成"pi 的数错"(这正是我方一直要求 pi 避免的那件事,方向反过来)
⇒ 而这与 pi 上一封的"我算的 36 是另一种口径"**不同**: 它是**口径**差异,我那次是**实现缺陷**
```
## (C) ★★ pi 的 `ThreadRootOf` 环风险 —— 方向对,但机制要精确两格
```
pi 说: "沿 failure 链上溯 + 上限 50 ⇒ 有链跑满上限 ⇒ 那份脚本算出的抑制数是**假的**"
⇒ "root-keying 落地时必须有一条判据: 根计算必须在有限步内终止"
我复核原文 (repo/thread.go:65-82):
WITH RECURSIVE up(...) AS (SELECT … WHERE mail_id=$1
UNION ALL
SELECT … WHERE up.lvl < $2) ← **UNION ALL**(不查重)+ WHERE lvl < cap
SELECT mail_id, lvl FROM up ORDER BY lvl DESC LIMIT 1 ← 取**最深**
descendantDepthCap = **10000** (thread.go:47,注释自称"只是数据损坏时的兜底")
```
★ 精确的两格修正(内存 SQLite 原样照抄该 CTE,5 元环 a→b→c→d→e→a):
```
cap=10000 ⇒ (root=a, lvl=10000)
cap=9999 ⇒ (root=e, lvl=9999)
cap=7 ⇒ (root=c, lvl=7)
cap=3 ⇒ (root=d, lvl=3)
3 元环 x→y→z→x(锚 x): cap=10⇒y / cap=11⇒z / cap=12⇒x
⇒ ① 它**不是"跑满被截断"** —— 它**照常返回一个节点**,而那个节点是**"第 cap 层恰好落在的那个"**
⇒ **随 cap 变化** ⇒ 不是任何意义上的"根" ⇒ 是**静默给错根**,**不报错、不返回错误**
② 真库当前 **零环**: 自引用(parent==self)=0、处于环上的邮件=0、最长 parent 链=**60**
⇒ 所以这是**构造情形**(pi 的语料里那 50 步上限确实被触发了),**不是库里的实测现象**
⇒ ★ 结论比 pi 的更强: 需要的判据不只是"必须有限步终止"(它**已经**有限步——cap=10000),
而是"**终止后必须能判出自己是不是走了环**"(当前实现**不能**:环与非环都返回一个节点)
⇒ 记法: **"能终止"与"能判出我是不是绕了"是两件事** —— 前者防死循环,后者防**静默错值**
```
## (D) ✅ pi 的数值自检我复核: f76025c9 那条环 5 封全上溯到 root=b3ce9d0f
```
真库里 parent 链最长 60 / 环 0 ⇒ 我们的 failure 报告语料**在真库里无环**
⇒ pi 那 5 封"全部指向 b3ce9d0f"是**链收敛**(不是环)⇒ 它的自检 ✓ 成立
```
## (E) 边界: 只读查库 + 内存 SQLite 构造;仓库/生产未动