记 pi 017c0239 报回的活回归(我认) + 我修它时又犯的两个错

★ (A) pi 报得准: 严格 A/B 复现 de1b072^(rc=0 装上) vs de1b072(rc=2 假红未装),三条触发带全命中
★ (B) 根因: 前移丢了**两条**保证(REQUIRE 预检 + env-defaults ④ PATH 归一化),我只补了一条;
     两条失败方向**相反**: ① 缺=漏(少检查) ② 缺=误(凭空假红)
★ (C) ★★ 我第一版修法(54d641e)**又引入第二个问题**: 空/最小 PATH 下 rc 2→**128**(不在退出码词汇表)
     ⇒ 与 de1b072 同形状"修一处坏一处",只是坏在另一个方向
     ⇒ 4 变体×6 PATH 矩阵定出正确位置=**文件最前**(env-defaults ④ 自注"必须排在最前") ⇒ final 六行全绿
★ (D) 顺带修既存脆弱点: --help 从"数行号"(sed 2,20)改**锚定**(到 set -euo pipefail);插行不再印实现代码
★ (E) 自catch: 我一度把修复版当 de1b072 量(rc=128),靠**打印被测 sha256 对照**发现
     ⇒ pi 立的字段 #7 当场救了我一次
★ (F) 边界: 只改 deploy/install.sh;生产未动
This commit is contained in:
2026-09-25 05:44:13 +08:00
parent da5d9339e2
commit dd9970a7b9

View File

@ -4052,3 +4052,61 @@ window.__AGENTMAIL_TOKEN__ = '<user_key>'; // 省略则走 Cookie
⇒ **persisted pre-commit gate 当场拦下**(这正是它的用途)⇒ 修好后才提交 ✓
⇒ 说明: gate 有效;而我的"写文档时数围栏"这一步**在追加场景下也会漏**(不只是提交前)
```
---
- ★★★ **pi `017c0239` 报回**:我 `b36d392` 有一处**活回归**(`--git-hooks` 假红"找不到 git")
⇒ **实测成立,我认**。★ 但修的过程里我又**自己犯了两个错**(第二次"修一处坏一处")
## (A) pi 的回归报得准 —— 严格 A/B(我**对自己的**提交做,真 git worktree)
```
同一 rig(工具齐全、PATH 里**无 git**,而 /usr/bin/git 真实存在),只差版本:
b36d392^(旧位置): rc=0 hooksPath=.githooks ← source 的 ④ 已把 /usr/bin 补回
b36d392 (新位置): rc=2 hooksPath=(未设) ← ④ 还没跑 ⇒ 假红 **且真的没装上**
触发带逐条复现(pi 报的三条**全部命中**):
PATH=/usr/local/sbin 旧 rc=0 装上 / 新 rc=2 未装
PATH=/opt/tools 旧 rc=0 装上 / 新 rc=2 未装
PATH=/sbin:/usr/sbin 旧 rc=0 装上 / 新 rc=2 未装
PATH=/usr/bin 两版都 rc=0(对照带,不触发)
⇒ ★ pi 报的是**真回归、真失败**(不是"只多打一行")✓
```
## (B) 根因: 前移丢了**两条**保证,我只补了一条
```
① AGENTMAIL_REQUIRE 的 git 预检(缺 git ⇒ exit 2 而非 127)—— 上轮我补了
② ★ env-defaults ④ 的 **PATH 归一化**(env-defaults.sh:124-130)—— **漏了**
⇒ ★ 两条的失败方向**相反**: ① 缺了是**漏**(少一条检查)、② 缺了是**误**(凭空假红)
⇒ 这是"搬动代码要重算它原来免费得到的保证"的**第二次触发**,而我**算漏了第二条**
⇒ 教训: 报"我重算了"时,要**逐个列出原位置的保证**再逐条判,不是想起来哪条算哪条
```
## (C) ★★ 我第一版修法(`803987f`)**又引入了第二个问题** —— 矩阵实测才发现
```
4 变体 × 6 种 PATH(真 worktree):
PATH old(^b36d392) b36d392 in-block(803987f) final
(空) 1/- 2/- 128/- **0/.githooks**
仅 bash/env 1/- 2/- 128/- **0/.githooks**
/opt/tools 0/.githooks 2/- 0/.githooks **0/.githooks**
/usr/local/sbin 0/.githooks 2/- 0/.githooks **0/.githooks**
/sbin:/usr/sbin 0/.githooks 2/- 0/.githooks **0/.githooks**
/usr/bin 0/.githooks 0/.githooks 0/.githooks **0/.githooks**
⇒ in-block 把**空/最小 PATH** 的 rc 从 **2("找不到 git"+人话,符合本仓词汇表)**
变成 **128("fatal: not in a git directory",不在词汇表)**
⇒ ★ 即"修了三条触发带、却把一处**符合约定的人话诊断**换成了**裸退出码**"
—— 与 `b36d392` 同一形状(**修一处坏一处**),只是这次坏在**另一个方向**
⇒ 正确位置 = **文件最前**(env-defaults ④ 自己就注明"**必须排在最前**")⇒ final 六行全绿
```
## (D) 顺带修一处**既存**脆弱点(被插入暴露,非本次引入)
```
`--help` 原为 `sed -n '2,20p'`(**数行号**)⇒ 往文件头插行 ⇒ 开始印**实现代码**
原版就已印出 set -euo pipefail / REPO=…;插 PATH 块后会多印 5 行 case…esac
改为 `usage()` = `sed -n '2,/^set -euo pipefail/p' | sed '$d'`(**锚定**)
⇒ 实测: --help 7 行纯注释 ✓;相对/绝对/符号链接三种调用均 rc=0 ✓
⇒ 记法: **"印第 N 行到第 M 行"是一种会自己变陈旧的引用**(与自指漂移同族)
```
## (E) 我自己的 rig 也出过一次错(自catch,照实记)
```
测"min harness 下 b36d392 的 rc"时,我把 $W/new 里**已被我替换成修复版**的文件当成了 b36d392
⇒ 得到 rc=128,而真 b36d392 是 rc=2 ⇒ **量错了对象**
⇒ 发现方式: 打印被测量的 sha256 并与 `git show b36d392:` 比对(**报数要报被测文件的版本**——正是那条字段 #7)
⇒ ★ 这条字段 #7 是 pi 立的,而它**当场救了我一次**: 若无 sha 对照,我会把"修复版的行为"报成"b36d392 的行为"
```
## (F) 边界: 只改 deploy/install.sh;生产未动(09-19 13:04);提交 803987f / 477439e