记忆 Actor 边界(INV-MEM-38~47)
wesgine 记忆系统中 Actor 边界的收敛设计——确保多用户 Cell 中每位员工只看到自己的记忆。
核心问题
Cell 边界落在文件路径上,不需要任何代码记得检查。Actor 边界当时落在 Metadata["actor"] 一个字符串键上,于是它必须被收敛——否则每条读/写/删路径各自把关,漏一处就泄漏。
两个执行点
判据收敛到两个执行点:
读:memory.ActorVisible
func ActorVisible(entry MemoryEntry, actor string) bool {
// 平台分区(ScopeSystem/ScopeGlobal 无主)→ 共享 → true
// 私有域(ScopeAgent)→ 必须 entry.Actor == actor
}
写:RequireActor
在 saveCore 内部——覆盖构造上的每一条写入路径。
func (s *storeImpl) saveCore(entry MemoryEntry) error {
// RequireActor:私有域 entry 必须有 actor
if isPrivateScope(entry.Scope) && entry.Actor == "" {
return ErrActorRequired
}
// ...
}
具体收敛规则
INV-MEM-38:写入单点
RequireActor 只在 saveCore 一处。它曾只被两个进程内调用方显式调用,三条 HTTP 写入路径全在外面。
INV-MEM-39:读取预筛 → 判定
actor 列化后 SQL 从"预算"升格为"判定"——不再是"先拿一页回来再 Go 里筛"。
INV-MEM-40:删除即可见
删除侧判据与读侧相同:ActorVisible。
DeleteAs(id, actor) 单点判 ActorVisible,不属于你回 403(不存在幂等成功)。
INV-MEM-41:无前缀约定
actor 是独立列,namespace 只表示话题/角色。不再用 u:<actor> 前缀编码归属。
INV-MEM-42:Digest 按认知主体分区
Digest 的跨条目认知判断按 (Namespace, CognitiveOwner) 分区,取全量用 DrainList。
INV-MEM-43:行身份带 actor 段
UNIQUE(scope, namespace, actor, key_)
两个员工的同名 key 不再是同一行。
INV-MEM-44:定时 flush 带 actor
去重键含 actor、丢弃非本 actor 的行、落读侧真正查询的命名空间。
INV-MEM-45:HTTP 非 GET 走 admin
/memory 非 GET 一律 cell:admin。
INV-MEM-46:scope 白名单
HTTP 写入端点的 scope 过白名单,system 需 admin。
INV-MEM-47:Session 态行不写死 ID
留空 ID 让 store 铸 UUID;命名空间只用 SessionNS(sessionID)。
读与删的答法差异
| 操作 | 不是你的 | 不存在 |
|---|---|---|
GetAs(id, actor) | 404(与不存在合并) | 404 |
DeleteAs(id, actor) | 403 | nil(幂等成功) |
理由:记忆 id 会随导出与分享链接流出去,一次读不配得到"它确实存在"这个确认。删除点名要删一行,配得上一句拒绝。
无主条目的处理
按 scope 分流:
| 分区 | 无主含义 | 处理 |
|---|---|---|
平台(ScopeSystem/ScopeGlobal) | 正常(L1/L2 共享资产) | 允许 |
私有域(ScopeAgent) | 异常(缺主) | 写入拒绝 |
与 Session 边界的关系
Session 是同一条 Actor 边界的第二个面。
- 记忆面:
memory.ActorVisible+saveCore.RequireActor - 会话面:
SessionHandle.AssertActor(漏斗dispatchCellSessionByID) - 观测面:
actorClause+actorFromRequestOrContext - Cron面:
jobVisible+ownedJob
四个面共用闸门 60-actor-single-judgement.sh。
各产品场景
| 产品 | Actor 边界影响 |
|---|---|
| wescode | actor 恒为 "local",单人无边界问题 |
| wesclaw 桌面 | N=1,单人无边界问题 |
| wesclaw SaaS | 多用户,Actor 边界生效 |
| wescraft 团队 | 多 actor 共享 Cell,四个面都生效 |
| 企业版 | 唯一真正暴露面:部门多员工共享 Cell |