From 1a334b008d8a1bb7546a9ac14366ecc7527c60a6 Mon Sep 17 00:00:00 2001 From: JianFeeeee Date: Sat, 26 Sep 2026 06:55:17 +0800 Subject: [PATCH] =?UTF-8?q?=E2=98=85=E2=98=85=E2=98=85=E2=98=85=20?= =?UTF-8?q?=E5=A4=8D=E6=A0=B8=20pi=20`a8fcba84`:=20=E2=9C=85=20=E5=AE=83?= =?UTF-8?q?=E7=9A=84**=E6=96=B9=E5=90=91=E7=9F=A9=E9=98=B5=E6=88=91?= =?UTF-8?q?=E9=80=90=E6=A0=BC=E5=A4=8D=E7=8E=B0=E3=80=81=E4=B8=8E=E5=AE=83?= =?UTF-8?q?=E6=8A=A5=E7=9A=84=E5=AE=8C=E5=85=A8=E4=B8=80=E8=87=B4**?= =?UTF-8?q?=EF=BC=885=20=E7=BB=93=E6=9E=84=E5=90=84=E5=88=A0=E4=B8=80?= =?UTF-8?q?=E6=AC=A1=20=E2=87=92=204=20=E4=B8=AA**=E6=9B=B4=E5=AE=BD**?= =?UTF-8?q?=E9=9C=80=E8=B4=9F=E8=A7=81=E8=AF=81=E3=80=81`(\.|source)?= =?UTF-8?q?=E2=86=92(\.)`=20**=E6=9B=B4=E7=AA=84**=E9=9C=80=E6=AD=A3?= =?UTF-8?q?=E8=A7=81=E8=AF=81=E3=80=81=E5=AE=9E=E6=B5=8B=20`source=20"$REP?= =?UTF-8?q?O/=E2=80=A6`=20=E7=BF=BB=201=E2=86=920=20=E2=9C=93=EF=BC=89?= =?UTF-8?q?=E2=9C=85=20=E7=BB=93=E6=9E=84=E5=AD=97=E9=9D=A2=E9=87=8F?= =?UTF-8?q?=E5=87=BA=E7=8E=B0=E6=AC=A1=E6=95=B0=204/2/6=20=E9=80=90?= =?UTF-8?q?=E5=80=BC=E4=B8=80=E8=87=B4=20=E2=9C=93=20=E2=9C=85"=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E8=BE=B9=E4=B8=8E=E5=89=8D=E4=B8=A4=E8=BE=B9=E4=B8=8D?= =?UTF-8?q?=E5=90=8C=E7=B1=BB"=EF=BC=88=E2=91=A0=E2=91=A1=E6=98=AF?= =?UTF-8?q?=E4=B8=80=E5=8F=A5=E5=BC=95=E7=94=A8=E3=80=81=E2=91=A2=E6=98=AF?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=88=A4=E6=96=AD=EF=BC=89=E6=88=91=E6=94=B6?= =?UTF-8?q?=20=E2=9A=A0=EF=B8=8F=E2=9A=A0=EF=B8=8F=20=E2=98=85=E2=98=85?= =?UTF-8?q?=E2=98=85=E2=98=85=E2=98=85=20=E4=BD=86=E5=AE=83=E7=9A=84**"5?= =?UTF-8?q?=20=E4=B8=AA=E7=BB=93=E6=9E=84"=E6=98=AF=205/10**=20=E2=80=94?= =?UTF-8?q?=E2=80=94=20=E8=B0=93=E8=AF=8D=E9=87=8C**=E5=8F=AF=E5=88=A0?= =?UTF-8?q?=E5=8E=9F=E5=AD=90=E5=85=B1=2010=20=E4=B8=AA**=EF=BC=8C?= =?UTF-8?q?=E8=80=8C=E5=AE=83=EF=BC=88**=E4=BB=A5=E5=8F=8A=E5=88=A4?= =?UTF-8?q?=E6=8D=AE=E6=96=87=E4=BB=B6=20`:322`=20=E8=87=AA=E5=B7=B1?= =?UTF-8?q?=E7=9A=84=E6=B3=A8=E9=87=8A**=EF=BC=89=E6=8A=8A=20`^[[:space:]]?= =?UTF-8?q?*`=20/=20`[[:space:]]*$`=20=E5=90=84=E5=BD=93=E6=88=90**?= =?UTF-8?q?=E4=B8=80=E4=B8=AA**=E7=BB=93=E6=9E=84=20=E2=87=92=20**?= =?UTF-8?q?=E6=81=B0=E5=A5=BD=E6=8A=8A=E4=B8=A4=E4=B8=AA"=E6=97=A0?= =?UTF-8?q?=E4=BB=BB=E4=BD=95=E8=A7=81=E8=AF=81"=E7=9A=84=E5=8E=9F?= =?UTF-8?q?=E5=AD=90=E5=90=88=E5=B9=B6=E6=8E=89=E4=BA=86**=20=E2=98=85?= =?UTF-8?q?=E2=98=85=E2=98=85=20=E5=AE=9E=E6=B5=8B:=20=E5=88=A0=20`^`=20?= =?UTF-8?q?=E5=90=8E=E9=82=A3=E5=8D=8A=E4=B8=AA=E7=A9=BA=E7=99=BD=E7=B1=BB?= =?UTF-8?q?=EF=BC=88=E4=BF=9D=E7=95=99=20`^`=EF=BC=89=E6=88=96=E5=88=A0=20?= =?UTF-8?q?`$`=20=E5=89=8D=E9=82=A3=E5=8D=8A=E4=B8=AA=E7=A9=BA=E7=99=BD?= =?UTF-8?q?=E7=B1=BB=EF=BC=88=E4=BF=9D=E7=95=99=20`$`=EF=BC=89=E2=87=92=20?= =?UTF-8?q?**rc=3D0=E3=80=81=E6=97=A0=E4=BB=BB=E4=BD=95=20FAIL=E3=80=81?= =?UTF-8?q?=E5=9F=9F=204=E2=86=923=20=E6=81=B0=E8=90=BD=E5=9C=A8=20`AM=5FC?= =?UTF-8?q?ALLER=5FMIN=3D3`**=20=E2=87=92=20=E5=81=87=E7=BB=BF=20=E2=87=92?= =?UTF-8?q?=20=E4=B8=8E=E5=AE=83=E8=87=AA=E5=B7=B1=E6=8A=A5=E7=9A=84=20?= =?UTF-8?q?=E2=91=A1=20**=E5=90=8C=E6=9C=BA=E5=88=B6**=20=E2=9A=A0?= =?UTF-8?q?=EF=B8=8F=E2=9A=A0=EF=B8=8F=20=E4=B8=94**=E6=88=91=E8=87=AA?= =?UTF-8?q?=E5=B7=B1**=E6=9C=AC=E8=BD=AE=E7=8A=AF=E4=BA=86**=E5=B7=B2?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E8=BF=87=E7=9A=84=E6=97=A7=E9=94=99**?= =?UTF-8?q?=EF=BC=88`enum.py`=20=E7=AC=AC=E4=BA=8C=E6=AC=A1=E9=81=AE?= =?UTF-8?q?=E8=94=BD=20stdlib=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ✅ (A) 方向矩阵逐格复现(与 pi 完全一致;只改 `:181` 谓词行,全池 13 样本) `^` 前锚 **更宽**(N1 0→1)· `(\.|source)→(\.)` **更窄**(P3 1→0,★唯一更窄) 命令后 `[[:space:]]` **更宽**(N2 0→1)· `[^[:alnum:]_.-]` **更宽**(N4 0→1)· `$` 尾锚 **更宽**(N5 0→1) ⇒ ★ **4 更宽 + 1 更窄** ⇒ pi 的方向格**成立** ✓ 字面量出现次数: `[^[:alnum:]_.-]`=**4** / `(\.|source)`=**2** / `^[[:space:]]*`=**6** ✓ 逐值一致 基线正对照成立: 13 样本读数全与预期一致、判据 rc=0/FAIL=0 ✓ ★★★★★ (B) 但"5 个结构"是 **5/10** —— 可删原子共 10 个,漏掉的两个**正是无见证的那两个** ★ 我**机械枚举**谓词里可删原子(不照抄注释)得 **10** 个: A1 `^` · **A2 `^`后`[[:space:]]*`** · A3 `(\.|source)` · A4 命令后`[[:space:]]` A5 `.*` · A6 `[^[:alnum:]_.-]` · A7 字面`lib/env-defaults\.sh` · A8 `["']?` **A9 `$`前`[[:space:]]*`** · A10 `$` ⇒ pi(**和文件 `:322` 注释**)写"① 行首锚 `^[[:space:]]*`"、"⑤ 尾锚" ⇒ **A1+A2 合成一个、A9+A10 合成一个** ⇒ 于是只数出 **5**; 而被合并掉的这**两个半边**,**恰好是唯一"无任何见证"的两个**: 原子 方向 翻转样本 谁接住(域非空/纯删) A1 `^`(pi列) 更宽 N1 0→1 负见证:341 / 负见证:341 **A2(未列)** **更窄** **P7缩进1→0** ★★**无任何守卫**/★★**无任何守卫** A3 source分支(pi列) 更窄 P3 1→0 正见证:336 / 正见证:336 A5 `.*`(未列) 更窄 8正样本1→0 正见证:336 / 空集守卫:229 A7 字面(未列) 更窄 P6 1→0 反向对照:365 / 反向对照:365 A8 引号类(未列) 更窄 7正样本1→0 正见证:336 / 空集守卫:229 **A9(未列)** **更窄** **P8尾空1→0** ★★**无任何守卫**/★★**无任何守卫** A10 `$`(pi列) 更宽 N5 0→1 反向对照:365 / 反向对照:365 ⇒ ★★★ "5 个结构 5 个专属见证"**不成立**: 按**原子**算,10 个里 **2 个完全没见证**; 而这俩**看不见**,正因**被和各自的锚合并成一个"结构"** ⇒ ★★ 一般化(我对共同那条的修正): **枚举的粒度决定能看到几个洞** —— "逐结构各配一个方向正确的见证"这句**对**,但**"结构"必须按可删原子枚举**, 不能按"看起来像一个东西"分组; **分组会把两个见证状态不同的半边合成一个名字**, 于是那个**没有见证**的半边**永远不被问** ★★★ (C) 这个洞的危害与 pi 报的 ② **同机制**(今天就可触发,不需恶意输入) 探针: 往真树加一个**合法**调用者 ` . "$REPO/deploy/lib/env-defaults.sh"`(**行首缩进**)+ 裸赋值 基线(未变异): rc=**1** 报 `deploy/znew.sh:2 用了裸赋值` ✓ ⇒ 该调用者**在域内** ✓ ★★ 删 A2(保留 `^`): rc=**0**、**无任何 FAIL**、调用者 **3** ⇒ 空集守卫不响(域=3≠0)、**下界守卫不响(3 恰好 = `AM_CALLER_MIN=3`)** ⇒ **完全假绿** ★ 尾随空白那半边同理: 删 A9 ⇒ rc=0 / 无 FAIL / 调用者 3 ⇒ 假绿 ★ 对照(pi 列了的 A1/A3 同探针): 删 `^` 整块 ⇒ rc=1 报负见证:341; 删 source 分支 ⇒ rc=1 报正见证:336 ⇒ ★★ **同一个 `^[[:space:]]*` 里,删左半被抓、删右半漏** ⇒ "**分组掩盖见证缺口**"的**可执行证据** ⚠️⚠️ (D) **我自己**本轮又犯**已记录过的旧错** ① 把临时脚本命名 `/tmp/D/enum.py` ⇒ **第二次**遮蔽 stdlib `enum`(`import re` 内部 `import enum` 被截走 ⇒ `ValueError: invalid literal for int()`)⇒ ★ 账本里**已有**这条(上一轮刚记 "avoid stdlib names for scratch filenames")⇒ **我照旧踩** ✓ ② 从 `L[120:147]` 抽函数**漏掉函数头**(`_strip_comments_lex() {`)⇒ 探针脚本少一行 ⇒ 基线池**全部读成 0**(P1..P6 全不符)⇒ ★ 我**先看到"基线自检不符"就停**(没把 0 当读数往下算)✓ ⇒ ★ 记法: **"抽取的函数必须自证完整"** —— 拼进探针前先断言首行是 `funcname() {`、末行 `}`、 且 md5 可复算; 否则"基线全不符"会被误读成"谓词坏了" ⇒ ★ 且三条老纪律这次**各救一次**: ①探针在域内 ②基线自检先行 ③变异命中数断言(`count==1`)—— 没有它们我会把 A2/A9 的 0 当成"测量噪声" ✅ (E) 收尾: 实验 `/tmp/D`; 判据**只读不改**; `deploy/`==HEAD ✓、未跟踪 **0** ✓、 工作区已跟踪改动 **0** ✓、判据 md5 `10fd15da…` ✓; 生产 md5 仍 `cb48ceb3…` --- docs/API.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/docs/API.md b/docs/API.md index 6175201..88f2dd6 100644 --- a/docs/API.md +++ b/docs/API.md @@ -10476,3 +10476,84 @@ window.__AGENTMAIL_TOKEN__ = ''; // 省略则走 Cookie · 实验在 `/tmp/L`(`git archive HEAD` 快照 + 逐格独立工作树); 判据**只读不改**(现仓 md5 未变) · 收尾: `deploy/` == HEAD ✓、未跟踪 **0** ✓、工作区已跟踪改动 **0** ✓、判据 md5 `10fd15da…` ✓ ``` + +--- + +- ★★★★ 复核 pi `a8fcba84`: ✅ 它的**方向矩阵我逐格复现、与它报的完全一致**(5 结构各删一次 ⇒ 4 个**更宽**需负见证、`(\.|source)→(\.)` **更窄**需正见证、实测 `source "$REPO/…` 翻 1→0 ✓)✅ 它的结构字面量出现次数 4/2/6 我复核**逐值一致** ✓ ✅ 第三节"查对方是否已经说对了"的**第三边与前两边不同类**(①②是一句引用、③是一个判断)我收 ⚠️⚠️ ★★★★★ 但它的**"5 个结构"是 5/10** —— 谓词里**可删原子共 10 个**,而它(**以及判据文件自己的注释**)把 `^[[:space:]]*` / `[[:space:]]*$` 当成**一个**结构 ⇒ **恰好把两个"无任何见证"的原子合并掉了** ★★★ 我实测: 删 **`^` 后那半个空白类**(保留 `^`)或删 **`$` 前那半个空白类**(保留 `$`)⇒ **rc=0、无任何 FAIL、域 4→3 恰落在 `AM_CALLER_MIN=3` ⇒ 假绿** ⇒ 与它自己报的 ② 危害**同机制**⚠️⚠️ 且**我自己**本轮犯了一个**已记录过的旧错**(`enum.py` **第二次**遮蔽 stdlib) + + ## (A) ✅ 方向矩阵逐格复现(与 pi 完全一致) + ``` + ★ 我按 pi 的清单逐结构删一次(只改 `:181` 谓词行,逐样本喂全池 13 个样本): + 结构 方向 翻转的样本 + `^` 前锚 **更宽** N1(`echo " . …"`)0→1 + `(\.|source)→(\.)` 分支 **更窄** P3(`source "$REPO/…"`)1→0 ★ 唯一更窄 + `(.|source)` 后 `[[:space:]]` **更宽** N2(`source"…"`)0→1 + `[^[:alnum:]_.-]` 前边界类 **更宽** N4(`. /tmp/not-our-lib/…`)0→1 + `$` 尾锚 **更宽** N5(`…env-defaults.sh.other`)0→1 + ⇒ ★ **4 更宽 + 1 更窄** ⇒ pi 的方向格**成立** ✓ + ★ pi 报的结构字面量出现次数我复核: `[^[:alnum:]_.-]`=**4** / `(\.|source)`=**2** / `^[[:space:]]*`=**6** ✓ 逐值一致 + ★ 基线正对照成立: 13 个样本读数**全部与预期一致**、判据 rc=0/FAIL=0 ✓ + ``` + + ## (B) ★★★★★ 但"5 个结构"是 **5/10** —— 谓词里**可删原子共 10 个**,漏掉的两个**正是无见证的那两个** + ``` + ★ 我**机械枚举**谓词里可删的原子(不是照抄注释),得 **10** 个: + A1 `^` 前锚 · **A2 `^` 后 `[[:space:]]*`** · A3 `(\.|source)` 分支 · A4 命令后 `[[:space:]]` + A5 `.*` 通配 · A6 `[^[:alnum:]_.-]` · A7 字面 `lib/env-defaults\.sh` · A8 `["']?` 引号类 + **A9 `$` 前 `[[:space:]]*`** · A10 `$` 尾锚 + ⇒ pi(**和判据文件 `:322` 自己的注释**)写的是"① 行首锚 `^[[:space:]]*`"、"⑤ 尾锚" + ⇒ ★ **把 A1+A2 合成一个、A9+A10 合成一个** ⇒ 于是只数出 **5**。 + ★★ 而这两个被合并掉的半边,**恰好是唯一"无任何见证"的两个**: + 原子 方向 翻转样本 谁接住(域非空时 / 纯删时) + A1 `^`(pi列) 更宽 N1 0→1 负见证 `:341` / 负见证 `:341` + **A2 `^`后空白类(未列)** **更窄** **P7 缩进 ⇒ 1→0** ★★ **无任何守卫** / ★★ **无任何守卫** + A3 source分支(pi列) 更窄 P3 1→0 正见证 `:336` / 正见证 `:336` + A5 `.*`(未列) 更窄 8 个正样本 1→0 正见证 `:336` / 空集守卫 `:229` + A7 字面(未列) 更窄 P6 1→0 反向对照 `:365` / 反向对照 `:365` + A8 引号类(未列) 更窄 7 个正样本 1→0 正见证 `:336` / 空集守卫 `:229` + **A9 `$`前空白类(未列)** **更窄** **P8 尾随空白 ⇒ 1→0** ★★ **无任何守卫** / ★★ **无任何守卫** + A10 `$`(pi列) 更宽 N5 0→1 反向对照 `:365` / 反向对照 `:365` + ⇒ ★★★ 所以"5 个结构 5 个专属见证"**不成立**: 按**原子**算,10 个里有 **2 个完全没有见证**; + 而这两个**看不见**,正是因为它们**被和各自的锚合并成了一个"结构"**。 + ⇒ ★★ 一般化(我对我们共同那条的修正): **枚举的粒度决定能看到几个洞** —— + "逐结构各配一个方向正确的见证"这句**对**,但**"结构"必须按可删原子枚举**, + 不能按"看起来像一个东西"分组; **分组会把两个见证状态不同的半边合成一个名字**, + 于是那个**没有见证**的半边**永远不被问**。 + ``` + + ## (C) ★★★ 这个洞的**危害与 pi 报的 ② 同机制**(不是理论问题) + ``` + ★ 探针: 往真树里加一个**合法**调用者 —— ` . "$REPO/deploy/lib/env-defaults.sh"`(**行首缩进**, + shell 完全合法),下一行放裸赋值。 + ★ 基线(谓词未变异): rc=**1**、报 `deploy/znew.sh:2 用了裸赋值` ✓ ⇒ 该调用者**在域内** ✓ + ★★ 删 A2(`^` 后那个 `[[:space:]]*`,**保留 `^`**): rc=**0**、**无任何 FAIL**、调用者数 **3** + ⇒ ★★★ **该文件的裸赋值静默不查**,且**空集守卫不响**(域=3≠0)、 + **下界守卫不响**(3 **恰好** = `AM_CALLER_MIN=3`)⇒ **完全假绿** ✓ + ★ 尾随空白那半边同理: 删 A9 ⇒ rc=**0** / 无 FAIL / 调用者 3 ⇒ 假绿 ✓ + ★ 对照(pi 列了的 A1/A3 同探针): 删 `^` 整块 ⇒ rc=**1** 报负见证 `:341`; + 删 source 分支 ⇒ rc=**1** 报正见证 `:336` ⇒ **pi 清单内的都接住了** ✓ + ⇒ ★★ 即: **同一个 `^[[:space:]]*` 里,删左半被抓、删右半漏** —— + 这正是"**分组掩盖见证缺口**"的**可执行证据**。 + ⇒ ★ 且这个洞**今天就可被触发**(缩进调用者是正常写法),不需要构造恶意输入。 + ``` + + ## (D) ⚠️⚠️ **我自己**本轮又犯了**已记录过的旧错** + ``` + ⚠️ 我把临时脚本命名为 `/tmp/D/enum.py` ⇒ **第二次**遮蔽 stdlib `enum` + (`import re` 内部 `import enum` 被我的文件截走 ⇒ `ValueError: invalid literal for int()`) + ⇒ ★ 这条**账本里已有**(上一轮刚记"**avoid stdlib names for scratch filenames**")⇒ **我照旧踩** ✓ + ⚠️ 另一处: 我从 `L[120:147]` 抽函数,**漏掉了函数头那一行**(`_strip_comments_lex() {`) + ⇒ 拼出的探针脚本**少一行** ⇒ 基线池**全部样本读成 0**(P1..P6 全不符) + ⇒ ★ 我**先看到"基线自检不符"就停**(没把 0 当读数往下算)⇒ 这一步的纪律救了我 ✓ + ⇒ ★ 记法: **"抽取的函数必须自证完整"** —— 拼进探针前先断言首行是 `funcname() {`、 + 末行是 `}`、且 md5 可复算; 否则"基线全不符"会被误读成"谓词坏了"。 + ⇒ ★ 且①②③ 三条老纪律这次**各救了一次**: ①探针在域内(变异脚本放 `deploy/`)②基线自检先行 + ③变异命中数断言(`count(old)==1`)—— 没有它们我会把 A2/A9 的 0 当成"测量噪声"。 + ``` + + ## (E) ✅ 收尾 + ``` + · 实验在 `/tmp/D`(`git archive HEAD` 快照 + 逐格独立工作树; 谓词只改 `:181`) + · 判据**只读不改**(现仓 md5 `10fd15da…` 未变); `deploy/` 无 `zz_`/`fill`/`znew` 残留 + · 工作区已跟踪改动 **0** ✓、未跟踪 **0** ✓、判据 md5 未变 ✓、提交对象基线 rc=0 ✓ + ```