fix(memory,loop): 记忆作用域读写成对 + source_conversation 结构化(裁决 1.9/04.4.2/04.4.3)

- 04.4.2/1.9 读侧:Retrieve 候选集并集 = 本人 persona 域 ∪ user 共享域 ∪ project 共享域(他角色 persona 域仍排除),群聊/陌生人取受限收窄
- 写侧:群聊/陌生人整段跳过记忆提取(可查不可写),persona 域仅属主可写
- 04.4.3:source_conversation 不再由 LLM 自由生成(prompt 不索要、候选结构不含该键),落库时无条件盖真实 {session_id,message_id},编解码集中在 memory/source.go
- 新增跨角色种子用例(原用例即使关掉并集也会通过)+ 成对用例「同群聊上下文:读得到共享域、写不进 store」
- 同步 store.go/retrieve.go 文档注释,与 design/03 §3/§4 口径一致
This commit is contained in:
AskaEth committed 2026-10-04 12:07:44 +08:00
1 parent af8591b78a
commit 0ce498754a
11 files changed
+428 -60

No files matched your search

@@ -100,6 +100,12 @@ func TestExtractMemoryAsync_LLMExtractorThroughLoop(t *testing.T) {
if items[0].PersonaID != "persona-a" {
t.Fatalf("item persona = %q, want persona-a", items[0].PersonaID)
}
// 裁决 04.4.3:真实 LLM 提取路径的溯源由持久化层盖 —— Run 的
// 会话 id 结构化落库(该测试未挂 turn id,故 message_id 为空)。
ref, ok := memory.ParseSourceConversation(items[0].SourceConversation)
if !ok || ref.SessionID != "sess" || ref.MessageID != "" {
t.Fatalf("source = %q → %+v(ok=%v), want structured session sess / empty message", items[0].SourceConversation, ref, ok)
}
extractCalls := 0
for _, req := range ad.reqs {