用户否掉了我上一步的方向:「?拒收那个目录干啥?明明是你的网关投递逻辑造成的错误」。 他是对的。/home 是**合法目录**,平台不该替用户裁定"哪个目录算工作目录": 网关地址受理处的 400、建议接口的过滤、桥侧的同类闸(revert 141003d)全部撤回。 判据随之删除 —— 判据不该给错误的实现护航(那会让错的东西看起来有保障)。 保留的是**真修复**(ad1f3f1,已在线): - 会话解析按 (path, 别名):错投的根因是解析只看别名、path 被当提示; - 唯一索引 (path, 别名);无 path 时"唯一才认,否则报歧义"; - 毒数据清理(/home 污染值 0|0|0)。 核心回归判据 TestFindNamedSessionForRequiresPath 保留。 仍未修(用户指的那一处):SSE 投递只按 name 广播 —— 同名不同 path 的客户端谁接到谁处理。 下一 commit:投递也带会话身份,只投给声明了该会话的客户端。
85 lines
3.4 KiB
Go
85 lines
3.4 KiB
Go
package repo
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"testing"
|
||
)
|
||
|
||
/*
|
||
会话身份 = **path + 别名**(用户 2026-09-15 订正)。
|
||
|
||
原话:「agent 平台的 session 是和 path 绑定的,path+session 才能指定到准确的 agent,
|
||
而授权也是对 session 授权,而不是整个 agent」。
|
||
|
||
这条判据直接对着当天那个**严重错投**:工作区在 TrueAgent 的 pi 给 dsh 发信,信却进了
|
||
workspace=/home 的会话/客户端。根因是解析只按别名(`WHERE session_alias = $1`),
|
||
path 被当成了可选提示 —— 于是两条不相干的线索能落进同一条会话。
|
||
|
||
判据两侧都写(只验一侧会挡住"退回按别名找"这种假修复):
|
||
- 给了 **正确** path → 命中;
|
||
- 给了 **另一个** path(而别名确实存在于别处)→ 必须 ErrSessionNotFound,
|
||
**绝不能**命中共名的那一条(这一条是本次 bug 的回归判据);
|
||
- 不给 path 且别名唯一 → 命中(兼容 `name@.别名` 的旧地址);
|
||
- 不给 path 且同名两条 → ErrSessionAmbiguous(不许掷骰子)。
|
||
*/
|
||
func TestFindNamedSessionForRequiresPath(t *testing.T) {
|
||
setupTestDB(t)
|
||
ctx := context.Background()
|
||
seedAgent(t, "dsh", 20)
|
||
|
||
alias := "鸿蒙客户端与-WebUI-界面对齐"
|
||
a := alias
|
||
idA, err := CreateSession(ctx, &a, "pi", "在 repo 里干活", "/home/program/agentmail")
|
||
if err != nil {
|
||
t.Fatalf("建会话 A: %v", err)
|
||
}
|
||
seedMailForSession(t, idA, "pi", "dsh", "/home/program/agentmail")
|
||
|
||
b := alias
|
||
idB, err := CreateSession(ctx, &b, "pi", "在 /home 里那一条(污染值)", "/home")
|
||
if err != nil {
|
||
t.Fatalf("建会话 B(同名不同 path): %v", err)
|
||
}
|
||
seedMailForSession(t, idB, "pi", "dsh", "/home")
|
||
|
||
// ① 正确 path → 命中 A
|
||
got, err := FindNamedSessionFor(ctx, "dsh", "/home/program/agentmail", alias)
|
||
if err != nil || got != idA {
|
||
t.Fatalf("正确 path 应命中 A:got=%v err=%v", got, err)
|
||
}
|
||
|
||
// ② ★ 错 path(/home)但别名相同 → 必须命中 B,**不是** A;
|
||
// 而如果那个 path 根本没有会话 → NotFound,绝不退回命中 A。
|
||
got, err = FindNamedSessionFor(ctx, "dsh", "/tmp/别的地方", alias)
|
||
if !errors.Is(err, ErrSessionNotFound) {
|
||
t.Fatalf("错 path 必须 ErrSessionNotFound(不许退回按别名找),实际 got=%v err=%v", got, err)
|
||
}
|
||
got, err = FindNamedSessionFor(ctx, "dsh", "/home", alias)
|
||
if err != nil || got != idB {
|
||
t.Fatalf("path=/home 应命中 B(同名但不同身份):got=%v err=%v", got, err)
|
||
}
|
||
|
||
// ③ 不给 path:别名不唯一 → 歧义,不许猜
|
||
if _, err := FindNamedSessionFor(ctx, "dsh", "", alias); !errors.Is(err, ErrSessionAmbiguous) {
|
||
t.Fatalf("同名两条 + 无 path 必须 ErrSessionAmbiguous,实际 %v", err)
|
||
}
|
||
|
||
// ④ 不给 path 且唯一 → 命中(兼容旧地址 `name@.别名`)
|
||
uniq := "只有一条的别名"
|
||
u := uniq
|
||
idU, err := CreateSession(ctx, &u, "pi", "独一份", "/home/program/agentmail")
|
||
if err != nil {
|
||
t.Fatal(err)
|
||
}
|
||
seedMailForSession(t, idU, "pi", "dsh", "/home/program/agentmail")
|
||
if got, err := FindNamedSessionFor(ctx, "dsh", "", uniq); err != nil || got != idU {
|
||
t.Fatalf("唯一别名 + 无 path 应命中:got=%v err=%v", got, err)
|
||
}
|
||
|
||
// ⑤ 没参与过的名字不该命中(地址解析的另一半判据)
|
||
if _, err := FindNamedSessionFor(ctx, "zcode", "/home/program/agentmail", alias); !errors.Is(err, ErrSessionNotFound) {
|
||
t.Fatalf("没参与过这条线索的名字不该命中,实际 %v", err)
|
||
}
|
||
}
|