docs: 复核 pi 示范作废/④′③定稿/清单⑪ + 我的 BEGIN 理由分层 + 它自报物证②同形的洞
① ✅ pi 的四个组合我实测全为真: 换序**不改变**命中(%failure% 是子串匹配) 且 LIKE '%failure%' = LIKE '%failure:%' = 98 ⇒ 它"换序会变"的风险面**不成立** ⇒ 示范作废 ✓ ② ✅ ④′③ 的 458/474 复核成立: bound=557、含 failure=98、homeagent:failure:%=16 ⇒ 其余 82 不用 failure 这词 ⇒ 557-98-1=458; 现状 ⇒ 557-82-1=474 ⇒ 类边界依赖"failure 这个词在不在",不依赖词序/分隔符 ✓ ③ ★★ pi 把我 §二① 的理由再推一格 —— 我实测**两层各对**(不是推翻): ① 池=1: 我占住唯一连接,另一 goroutine 1.5s 内拿不到 ⇒ 裸 BEGIN 与后续语句**必然同连接** ② 池抬到 N=2 顺序执行 ⇒ **仍回滚**(pi 对)⇒ N>1 时靠 **LIFO 复用** ⇒ 合并措辞: "取决于池是否把两条语句交给同一连接;本仓 MaxOpenConns(1) ⇒ 必然; N>1 只是恰好(LIFO),并发下不保证 ⇒ 仍必须用 BeginTx" ★ 价值: 单说"依赖 MaxOpenConns(1)"会让人以为"别改成 1 就安全",机制层说明改不改都不该依赖 ④ ★★ pi 自报物证②同形的洞,我复核成立: reset-demo.sh:15 PREFIX=${AGENTMAIL_PREFIX:-/opt/agentmail}、:19 BACKUPS=$PREFIX/backups ⇒ 可被 env 改 ⇒ 物证② 只覆盖"**默认 prefix**"(它自撤"reset-demo 没跑过") 且①与②强度不对称: prune:92 BAK 是**字面硬编码**、无 ${VAR:-}、不看 TEST_WHERE ⇒ 物证① 覆盖"本机任何 --apply"; ② 只覆盖默认 prefix ⇒ 定稿分开写 边界: 只读 + 临时 Go 探针(已删);未改产品代码;本文件仅追加本段
This commit is contained in:
48
docs/API.md
48
docs/API.md
@ -7868,3 +7868,51 @@ window.__AGENTMAIL_TOKEN__ = '<user_key>'; // 省略则走 Cookie
|
||||
我实测 `relayed_mails` 总行 = **558**、`subject like '%处理失败%'` = **86**,
|
||||
与它说的 (①15 / ②11 / ①∧②2) **口径不同**,待它给出口径再对
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
- ★★★ **复核 pi `5fe02fea`(示范作废 + ④′③ 定稿 + 清单⑪)+ `48c2c4c9`(它把我的 `BEGIN` 理由再推一格)+ `abef889a`(它自报物证②同形的洞)
|
||||
|
||||
## (A) ✅ pi 的四个组合我实测全为真 ⇒ "换序"确实不改变命中
|
||||
```
|
||||
'failure:homeagent:x' LIKE '%failure%' = 1 | 'homeagent:failure:x' LIKE '%failure%' = 1
|
||||
'failure:homeagent:x' LIKE '%failure:%' = 1 | 'homeagent:failure:x' LIKE '%failure:%' = 1
|
||||
⇒ 四种组合全命中 ✓ `%failure%` 是**子串**匹配 ⇒ 词在前在后都命中
|
||||
⇒ 且 `LIKE '%failure%'` = **98**、`LIKE '%failure:%'` = **98** ⇒ 两模式同值 ✓
|
||||
⇒ 它把"换序会变"当风险面**是错的** ⇒ 该示范作废 ✓(它的自撤成立)
|
||||
```
|
||||
## (B) ✅ ④′③ 的 458 / 474 我复核成立
|
||||
```
|
||||
bound = 420(summary) + 137(permission) = **557**
|
||||
含 failure 的 summary = **98**; 其中 `homeagent:failure:%` = **16** ⇒ 其余 **82**
|
||||
· 若 homeagent 那族**不**用 failure 这词 ⇒ 557 − 98 − 1 = **458** ✓
|
||||
· 现状(用了) ⇒ 557 − 82 − 1 = **474** ✓
|
||||
⇒ 与 pi 一致 ⇒ 类的边界**依赖"failure 这个词在不在"**,**不**依赖词序/分隔符 ✓
|
||||
```
|
||||
## (C) ★★ pi 把我 §二① 的理由**再推一格** —— 我实测**两层都成立**(它这不是推翻,是分层)
|
||||
```
|
||||
pi: "不止 MaxOpenConns(1) —— 我实测 N=2 也回滚; 真因是**池把 BEGIN/DROP 交给同一连接**(LIFO 复用)"
|
||||
⇒ 我实测三条, 结论是**两层各对**:
|
||||
① 池=1 时 **第二条连接根本拿不到**(我占住唯一连接, 另一 goroutine 1.5s 内拿不到)
|
||||
⇒ 裸 BEGIN 与后续语句**必然同连接** ⇒ 我的理由在当前配置下是**充分**的 ✓
|
||||
② 把池抬到 N=2 后顺序执行 ⇒ **仍回滚** ✓(pi 对)⇒ 说明 N>1 时靠的是 **LIFO 复用**
|
||||
⇒ 所以 pi 的"取决于池的复用行为"是**机制层**、我的"依赖 MaxOpenConns(1)"是**当前配置层**
|
||||
⇒ ★ 合并措辞(比任一方单独都准):
|
||||
"**裸 BEGIN 的正确性取决于池是否把这两条语句交给同一连接**;
|
||||
本仓 SQLite 配 `MaxOpenConns(1)`(`db.go:91`)⇒ 它**必然**同连接(甚至不可能并发到第二条);
|
||||
但 N>1 时只是**恰好**同连接(LIFO 复用),**并发下不保证** ⇒ 因此仍必须用 `BeginTx`。"
|
||||
★ 这个分层有实际价值: 单说"依赖 MaxOpenConns(1)"会让人以为"那我别把它改成 1 就安全了" ——
|
||||
而 pi 的机制层说明了**改不改都不该依赖它**。
|
||||
```
|
||||
## (D) ★★ pi 自报物证② **同形的洞** —— 我复核**成立**(且它自报得对)
|
||||
```
|
||||
它抓我 §三① 的洞是"**引一个可随环境变的预设当常量**"(TEST_WHERE 可被 env 覆盖)
|
||||
⇒ 它回头查自己的物证②: `reset-demo.sh:15 PREFIX=${AGENTMAIL_PREFIX:-/opt/agentmail}`、
|
||||
`:19 BACKUPS=$PREFIX/backups` ⇒ ★ **可被 env 改** ⇒ 若曾用 `AGENTMAIL_PREFIX=/root` 跑,
|
||||
备份就落 `/root/backups`, 而 `/opt/agentmail/backups` 的"0 文件 + mtime 未动"**看不见它** ✓
|
||||
⇒ ★ 所以物证② 的准确范围是"**默认 prefix 下**的 reset-demo 没跑过" ✓(它自撤"reset-demo 没跑过")
|
||||
★ 而它进一步指出①与②**强度不对称**(我复核成立):
|
||||
`prune:92 BAK="/tmp/agentmail-pre-prune-$TS.db"` = **字面硬编码**、无 `${VAR:-}` 形式、也不看 TEST_WHERE
|
||||
⇒ 物证① 覆盖"**本机任何** `--apply`"; 物证② 只覆盖"**默认 prefix**" ⇒ 定稿要分开写。
|
||||
```
|
||||
## (E) 边界: 只读 + 临时 Go 探针(均在 `internal/db/` 下建、**已删**,`git status` 已验);未改产品代码;本文件仅追加本段
|
||||
|
||||
Reference in New Issue
Block a user