记忆层查询谓词

wesgine 记忆系统中 LayerOf 与 LayerClauses 的双向生成设计。


判层与筛层是同一张表的两个方向

方向函数问题
判层LayerOf(entry)这一行是哪层?
筛层LayerClauses(layer)哪些行是这层?

两者必须由同一份定义生成——分别手写的两份表必然漂移。


为什么两个方向不能独立实现

Scope + Actor 是层的超集:

两者共用 ScopeGlobal,所以没有任何 scope 值能单独命名"关于我"。

拿超集查 L3 会把 L2 的部门共识一起装进 LIMIT 窗口。


筛层必须精确

-- 错误:超集查询
WHERE scope = 'global' AND actor = ?
-- 这会把 consensus(无 actor)也装进来

-- 正确:精确谓词
WHERE scope = 'global' AND actor = ? AND actor != ''

且必须在 LIMIT 之内——页外过滤在两行数据的测试里看不出差别,共享分区一大,用户自己的行就掉出窗口底部。


Layer 与 Scope 互斥

同时给出 ?layer= 和 ?scope= 时返回 ErrMemoryLayerScopeConflict(400),不做交集。

两者只在调用方糊涂时才分歧,返回交集是在回答没人问过的问题。


七值闭域

AllMemoryLayers() = [
    "environment",   // L1
    "consensus",     // L2
    "about_me",      // L3
    "agent_memory",  // L4
    "session",
    "working",
    "unknown",
]

unknown 是兜底出口,新增 scope 落到 unknown 而不是塞进某个真实层。


ListOptions.Layer 下推

type ListOptions struct {
    Layer     string  // 直接下推到 SQL
    Scope     string  // 不可与 Layer 同时给出
    // ...
}

backend.layerPredicate(layer) 生成 SQL WHERE 子句,不是 Go 侧后过滤。


CountByLayer

func CountByLayer(actor, namespace string) map[string]int

返回键覆盖 AllMemoryLayers() 全部层含 0。

缺键会让消费方渲染成"什么都没有"——没有 tab、没有 0、没有报错。


属性测试

LayerOf 与 ActorVisible 由属性测试锁死同向:


相关不变量


相关文档