fix(session): 会话身份 = (path, 别名) —— 修用户报的错投,并堵住 /home 这类毒 path
用户 2026-09-15 的订正:「agent 平台的 session 是和 path 绑定的,path+session 才能
指定到准确的 agent,而授权也是对 session 授权,而不是整个 agent」;随后报了一个
严重错投:「工作区在 TrueAgent 的 pi 客户端,发送邮件给 dsh 被投递给了工作区在 home
的客户端」。
根因是四处叠加(都有实测证据):
1. 解析只按别名:`WHERE session_alias = $1`,path 被当可选提示 ⇒ 两条不相干的
线索能落进同一会话;
2. 别名全局唯一 ⇒ path 在解析时冗余,进一步被忽略;
3. 桥按来信的 to_workspace 起 worker(实测日志 `新建 pi 会话 …(cwd=/home)`);
4. 投递(SSE)只按 name 广播。
本提交改 1/2 + 堵源头:
- 解析按 (path, 别名):给了 path 必须两者同时命中,对不上就是 ErrSessionNotFound
(**绝不**退回按别名找);没给 path 则要求该别名唯一,多条时 ErrSessionAmbiguous
(不许掷骰子);
- 唯一索引从 `(session_alias)` 改成 `(COALESCE(workspace,''), session_alias)`
(两方言 + 显式 DROP 旧索引;EnsureSessionAlias 靠唯一索引判撞名,自动变成按 path);
- 新 IsPlausibleWorkspace(与目录建议**同源**一条规则):地址受理处拒收不像工作目录的
path(`/home`、`/root`、`~/.pi/mail-sessions/…`、顶层挂载点),并给出可执行文案;
- 建议接口的候选过滤改用同一条规则(只留具体目录;祖先容器让位给更具体的候选)。
判据:新增/改写 4 组,全部做变异验证 —— 三条核心变异(解析退回按别名找 / 歧义时
掷骰子 / 去掉「深度≥2」)全部变红。过程中判据还抓到自己一个漏洞:
IsPlausibleWorkspace("/home") 在旧规则下是 true(/home 不是 root 的家目录)。
★ 语义变化(会让旧测试红):不同 path 下的同名别名现在是两条独立会话,不再"撞名"。
TestAdoptHandlesAliasCollision 已按新模型重写为两侧(同 path 才加后缀)。
未做:桥侧仍按来信 to_workspace 起 cwd(下一步);线上的库要等下一次启动才跑迁移。
This commit is contained in:
@ -66,10 +66,20 @@ CREATE TABLE IF NOT EXISTS sessions (
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_alias ON sessions(session_alias);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
|
||||
|
||||
-- 会话别名负责寻址(name@path.<alias>),必须全局唯一。
|
||||
-- 部分唯一索引:未命名会话(NULL)不受约束,可以有任意多个。
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_alias_uniq
|
||||
ON sessions(session_alias) WHERE session_alias IS NOT NULL;
|
||||
-- 会话身份 = (path, session) —— 用户 2026-09-15 订正:
|
||||
-- 「agent 平台的 session 是和 path 绑定的,path+session 才能指定到准确的 agent,
|
||||
-- 而授权也是对 session 授权,而不是整个 agent」。
|
||||
-- 所以寻址名的唯一性也是**按 path** 的:不同工作目录下的同名会话是两条不同的会话
|
||||
-- (各自的身份、各自的授权),而不是"同名冲突"。
|
||||
--
|
||||
-- 历史:这里原先是 ON sessions(session_alias) 的全局唯一索引。全局唯一让 path 在解析时
|
||||
-- 成为冗余(于是被忽略),一条 /home 之类的错 path 就能让两条不相干的线索落进同一个
|
||||
-- 会话、同一个 pi 会话文件(2026-09-15 实测:zcode 的"介绍请求"与 agentmail 的部署
|
||||
-- 往来混在 --home-- 的一个 jsonl 里)。
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_path_alias_uniq
|
||||
ON sessions(COALESCE(workspace,''), session_alias) WHERE session_alias IS NOT NULL;
|
||||
-- 老索引必须显式丢弃:CREATE ... IF NOT EXISTS 不会删掉它,而它会继续把别名限制成全局唯一。
|
||||
DROP INDEX IF EXISTS idx_sessions_alias_uniq;
|
||||
|
||||
-- 已存在的库补列(必须先于依赖该列的索引)
|
||||
ALTER TABLE sessions ADD COLUMN IF NOT EXISTS owner_user_id UUID REFERENCES users(user_id);
|
||||
|
||||
Reference in New Issue
Block a user