From fe0cfe626c8eb2c85180437bae5681312815e7fa Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sat, 19 Sep 2026 12:04:43 +0800 Subject: [PATCH] =?UTF-8?q?=E9=AA=8C=E6=94=B6=E5=8F=A3=E5=BE=84:=20--prefi?= =?UTF-8?q?x=20=E4=B8=A5=E6=A0=BC=E5=89=8D=E7=BC=80=20=E2=80=94=E2=80=94?= =?UTF-8?q?=20=E4=BF=AE=E6=AD=A3=20--only=20mail-=20=E8=AF=AF=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=20agentmail-=20=E9=80=A0=E6=88=90=E7=9A=84=203=20?= =?UTF-8?q?=E4=B8=AA=E5=81=87=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 第一版验收用 --only mail- 得到「47 可读 / 3 不可读」,但那 3 个根本不是邮件会话: 目录名是普通 UUID,只是父目录 --home-program-agentmail-- 里含子串 mail-。 它们的错因是另一个独立缺陷(subagent/descriptor v2)。 换严格前缀后的真实数字:真 mail-* 会话 43/43 可读,0 不可读。 脚本现在同时提供 --only(子串)与 --prefix(目录名严格前缀)。 --- docs/DSH-0.1.5-MAIL-CHANNEL-ROOTCAUSE.md | 19 ++++++++++++++++++- scripts/verify-mail-sessions-readable.mjs | 8 +++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/docs/DSH-0.1.5-MAIL-CHANNEL-ROOTCAUSE.md b/docs/DSH-0.1.5-MAIL-CHANNEL-ROOTCAUSE.md index 8cc1243..a958f73 100644 --- a/docs/DSH-0.1.5-MAIL-CHANNEL-ROOTCAUSE.md +++ b/docs/DSH-0.1.5-MAIL-CHANNEL-ROOTCAUSE.md @@ -178,7 +178,7 @@ pi 的「其它 34/28」也复现了,且能解释:28 个读不了的里 | 事件数 | 逐文件解压行数比对 | **40/40 一致**,零丢失 | | 大小变化 | 例 `mail-d042cc4c` 25.2MB → 12.5MB | **纯重压缩**(单帧改 500 行/帧),非丢数据 | | v3 修复 | `repair-v3-usermessage-ids.mjs --apply` | **2 个写入成功** | -| 真 mail-* 会话 | 最终验收 | **41/41 可读** | +| 真 mail-* 会话 | 最终验收(`--prefix mail-`) | **43/43 可读** | 反例留档:`~/.dsh/sessions/**` 仍有 3 个非邮件会话读不了,根因是 `subagent/descriptor ... unsupported descriptor version 2`,**与本问题无关**, @@ -265,3 +265,20 @@ dsh 观察到 `readSession()` 成功、`JsonlSessionPersistence.open()` 失败 2. **判定磁盘健康只认 `open()`**:`readSession()` 走 live 内存快照,会掩盖磁盘损坏。 3. **校验与落盘不能共用同一批对象**:验证器会原地改写,dry-run/apply 会因此给出 相反结论。 + +## 16. 度量口径的一个坑:`--only` 是子串匹配 + +第一版验收用 `--only mail-`,得到「47 可读 / 3 不可读」。那 3 个**不是邮件会话**—— +它们的目录名是普通 UUID,只是父目录是 `--home-program-agentmail--`, +而 `agentmail-` 里含子串 `mail-`,被误匹配进来。它们的错因是另一个独立缺陷 +(`subagent/descriptor 0 uses unsupported descriptor version 2`)。 + +换成严格前缀 `--prefix mail-` 后的真实数字: + +``` +候选: 43 可读: 43 不可读: 0 +``` + +⇒ **「真 mail-* 会话 43/43 可读,0 不可读」**。 +度量口径本身也会制造假结论,所以脚本现在两个开关都提供: +`--only`(子串,跑路径片段)与 `--prefix`(目录名严格前缀,点名某类会话时用后者)。 diff --git a/scripts/verify-mail-sessions-readable.mjs b/scripts/verify-mail-sessions-readable.mjs index 1b7d12a..e0265f2 100644 --- a/scripts/verify-mail-sessions-readable.mjs +++ b/scripts/verify-mail-sessions-readable.mjs @@ -27,7 +27,12 @@ const argOf = (flag, dflt) => { return i >= 0 && argv[i + 1] ? argv[i + 1] : dflt; }; const ROOT = argOf("--root", "/root/.dsh/sessions"); -const ONLY = argOf("--only", "mail-"); +// `--only` 是**子串**匹配(保留原语义,便于按路径片段过滤)。 +// 但它会把 `--only mail-` 误匹配到 `--home-program-agentmail--/` 下的普通会话 +// (`agentmail-` 里含 `mail-`),从而把「其他缺陷」报成「邮件会话仍不可读」。 +// 需要「只统计真 mail-* 会话」时用 `--prefix mail-`(目录名严格前缀)。 +const ONLY = argOf("--only", ""); +const PREFIX = argOf("--prefix", ""); const { Context } = await import(join(NM, "cordis/lib/index.js")); @@ -52,6 +57,7 @@ const targets = []; for (const p of walk(ROOT)) { if (ONLY && !p.includes(ONLY)) continue; const id = p.split("/").at(-2); + if (PREFIX && !id.startsWith(PREFIX)) continue; targets.push({ id, path: p }); }