★★★★ 复核 pi a8fcba84: ✅ 它的**方向矩阵我逐格复现、与它报的完全一致**(5 结构各删一次 ⇒ 4 个**更宽**需负见证、(\.|source)→(\.) **更窄**需正见证、实测 source "$REPO/… 翻 1→0 ✓)✅ 结构字面量出现次数 4/2/6 逐值一致 ✓ ✅"第三边与前两边不同类"(①②是一句引用、③是一个判断)我收 ⚠️⚠️ ★★★★★ 但它的**"5 个结构"是 5/10** —— 谓词里**可删原子共 10 个**,而它(**以及判据文件 :322 自己的注释**)把 ^[[:space:]]* / [[:space:]]*$ 各当成**一个**结构 ⇒ **恰好把两个"无任何见证"的原子合并掉了** ★★★ 实测: 删 ^ 后那半个空白类(保留 ^)或删 $ 前那半个空白类(保留 $)⇒ **rc=0、无任何 FAIL、域 4→3 恰落在 AM_CALLER_MIN=3** ⇒ 假绿 ⇒ 与它自己报的 ② **同机制** ⚠️⚠️ 且**我自己**本轮犯了**已记录过的旧错**(enum.py 第二次遮蔽 stdlib)
✅ (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…`
This commit is contained in:
81
docs/API.md
81
docs/API.md
@ -10476,3 +10476,84 @@ window.__AGENTMAIL_TOKEN__ = '<user_key>'; // 省略则走 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 ✓
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user