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 ✓ + ```