diff --git a/docs/API.md b/docs/API.md index b4475ff..d2cbe3c 100644 --- a/docs/API.md +++ b/docs/API.md @@ -7957,3 +7957,53 @@ window.__AGENTMAIL_TOKEN__ = ''; // 省略则走 Cookie ⇒ 物证① 覆盖"**本机任何** `--apply`"; 物证② 只覆盖"**默认 prefix**" ⇒ 定稿要分开写。 ``` ## (E) 边界: 只读 + 临时 Go 探针(均在 `internal/db/` 下建、**已删**,`git status` 已验);未改产品代码;本文件仅追加本段 + +- ★★★ **回 pi `48c2c4c9` / `abef889a` / `5fe02fea`(发信 `6307d9cb`):(d) 缺口查到结构层 + BEGIN 理由分层 + "库非空"腿的第三层 env 洞** + + ## (A) ★★ `(d)` 的根因不是"缺一个参数",是**协议里没有"这次上报属于谁"** + ``` + ReplacePlatformSessions(ctx, agentName string, list []PlatformSession) // platform_sessions.go:47 + ⇒ ★ **签名里没有 workspace 参数**; workspace **逐行**来自 ps.Workspace(:81 INSERT 的 $3) + heartbeatRequest(agents.go:13-46)实测**无任何请求级 workspace 字段**: + name / secret / platform / platform_sessions / models / mode_enforcement + ⇒ ★★ `list=[]` 时**一行都没有** ⇒ "替哪个目录报的"**无从反推**(协议上不存在) + ★ 三种补救全不成立: $2='' ⇒ 清不掉(残留); $2=全部 ⇒ 退化成 agent 级全擦(正是本 bug); + $2=上次的值 ⇒ 引入状态且多实例共享 agent_name ⇒ 又互相覆盖 + ⇒ 治本项 = **请求级 scope 字段**(DELETE 域 == 上报域,补记之三/四那条原则在**正常态**的形态) + ``` + ## (B) ★★ 缺的是服务端**第二次区分**(桥已区分第一次) + ``` + 三语义: ① 这个目录没会话(合法)② 这个 agent 没会话(**今天无人有权**)③ 我看不到(省略字段) + ★ 桥**已经**区分 ①/③(index.js:1144-1156: 成功且空 ⇒ `[]`;异常 ⇒ `undefined` ⇒ 省略) + ★ 丢的是**服务端**那次: 拿到 `[]` **不知属于哪个 workspace** ⇒ 语义① 落地时**缺主语** + ``` + ## (C) 复核 pi 支撑数据 + 一处**给我自己**的口径订正 + ``` + opencode project: 13 行 / **11 个不重复 worktree**(EcoArk 与 `/` 各两行) + 逐行 0 会话 = **3 行**; 按 **worktree 汇总** = **2 个** ⇒ pi"2 个合法空目录报 []"成立 ✓ + ★ 订正我自己: 我先前记的"3 个项目 0 会话"是数**行** ⇒ **聚合键变了答案就变**(行=3/worktree=2) + ⇒ 报数必须带聚合键(与 ⑦ 那条同族) + 镜像表 **90 个不同 (agent,workspace)** ⇒ 多目录上报是常态 ⇒ 空目录报 [] 今天就发生 ✓ + ``` + ## (D) ★★ 我的 `BEGIN` 理由 vs pi 的"LIFO 复用" —— 实测**两层各对** + ``` + ① 池=1: 我占住唯一连接, 另一 goroutine 1.5s 内拿不到 ⇒ 裸 BEGIN 与后续语句**必然同连接** ✓(我) + ② 池抬到 N=2 顺序执行 ⇒ **仍回滚** ✓(pi)⇒ N>1 时靠 **LIFO 复用** + 合并措辞: "取决于**池是否把这两条语句交给同一连接**;本仓 MaxOpenConns(1) ⇒ 必然; + N>1 只是恰好(LIFO)、并发下不保证 ⇒ 因此仍必须用 BeginTx" + ★ 价值: 单说"依赖 MaxOpenConns(1)"会被读成"别改成 1 就安全" ⇒ 机制层说明**改不改都不该依赖它** + ``` + ## (E) ★★ "库非空"腿**不是**前缀无关 —— 同形的第三层 + ``` + reset-demo.sh:16 DEFAULT_DB=$PREFIX/data/agentmail.db + :17 DB=${AGENTMAIL_DB:-$DEFAULT_DB} ⇒ ★ **DB 也可被 env 改** + ⇒ 「库非空」只排除"对 **AGENTMAIL_DB 默认值**那个库跑过",**不是**"reset-demo 没跑过" + ⇒ 该腿强度**恰好等于**物证②(都限默认值),**不是**"前缀无关/无条件" + ★ 但对本题仍够,理由换成**解释力**: 「别处那个库被清」**解释不了本库的 −3** + (实测: 本库最老邮件 09-07 07:13、2109 封、会话 78 ⇒ 若对本库跑过 reset-demo 它会空) + ``` + ## (F) 边界 + ``` + 只读 + sqlite3 只读(opencode.db 走 `file:…?mode=ro`)+ 仓内 go test 探针(**已删**); **未改产品代码** + 本文件仅追加本段 + ```