M3a:息壤三级记忆域——归真触发提取管线/白名单明忆/重忆确认/正影版本链/删除墓碑/双通道召回注入,退役旧记忆-抽取-反思-大周天-演化管线(迁移 004,验收 7 用例)

This commit is contained in:
chenxin committed 2026-08-27 09:16:32 +08:00
1 parent 2a640a901b
commit 9c98c2f85e
69 files changed
+1193 -6033

No files matched your search

+1 -3
View File
@@ -25,10 +25,10 @@ from app.models.mirror_tree import (
TreeNode,
TreeTransplant,
)
from app.models.memory import Memory, MemoryLink
from app.models.personality import PersonalityProposal, PersonalityVersion
from app.models.rbac import Permission, Role, RolePermission, UserRole
from app.models.runtime import Event, Run
from app.models.xirang import FactualRecord, Memory as XirangMemory, MemoryTrigger
from app.models.safety import AuditEvent, PendingConfirmationRecord
from app.models.skills import Skill
from app.models.user import User
@@ -52,9 +52,7 @@ __all__ = [
"Lorebook",
"LorebookEntry",
"McpServer",
"Memory",
"MemoryCandidate",
"MemoryLink",
"PendingConfirmationRecord",
"PerceptionChannel",
"Permission",
-46
View File
@@ -1,46 +0,0 @@
"""记忆模型。"""
from datetime import datetime
from sqlalchemy import DateTime, Float, ForeignKey, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.core.ids import new_memory_id, new_memory_link_id
from app.core.time import utc_now
from app.db.base import Base
class Memory(Base):
__tablename__ = "memories"
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_memory_id)
character_id: Mapped[str] = mapped_column(String(80), ForeignKey("characters.id"), index=True)
type: Mapped[str] = mapped_column(String(60), nullable=False)
title: Mapped[str] = mapped_column(String(200), nullable=False)
content: Mapped[str] = mapped_column(Text, nullable=False)
source: Mapped[str] = mapped_column(String(80), nullable=False, default="user_explicit")
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=1.0)
importance: Mapped[float] = mapped_column(Float, nullable=False, default=0.5)
sensitivity: Mapped[str] = mapped_column(String(40), nullable=False, default="low")
evidence_ids_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
status: Mapped[str] = mapped_column(String(40), nullable=False, default="active", index=True)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
deleted_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
temporal_context_json: Mapped[str] = mapped_column(
Text, nullable=False, default="{}", server_default="{}"
)
class MemoryLink(Base):
__tablename__ = "memory_links"
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_memory_link_id)
character_id: Mapped[str] = mapped_column(String(80), ForeignKey("characters.id"), index=True)
source_memory_id: Mapped[str] = mapped_column(String(80), ForeignKey("memories.id"), index=True)
target_memory_id: Mapped[str] = mapped_column(String(80), ForeignKey("memories.id"), index=True)
relation: Mapped[str] = mapped_column(String(80), nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
+80
View File
@@ -0,0 +1,80 @@
"""息壤(记忆域)模型(data-model.md §3)。
- 三级:微痕 trace(短期)/ 明忆 explicit(低敏长期)/ 重忆 sensitive(须确认);
- 双源:user_explicit / self_inferred;
- 版本链:正影=新行 prev_version_id 指旧行,旧行 superseded 停止普通召回,内容不改写;
- 删除:tombstoned 墓碑不承载原文,主存储/检索/上下文全链路停用。
"""
from datetime import datetime
from sqlalchemy import DateTime, Float, ForeignKey, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.core.ids import new_factual_record_id, new_memory_id, new_memory_trigger_id
from app.core.time import utc_now
from app.db.base import Base
class Memory(Base):
"""统一记忆表:三级 × 类型 × 状态 × 双源(契约词典 §10)。"""
__tablename__ = "memories"
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_memory_id)
character_id: Mapped[str] = mapped_column(String(80), index=True, nullable=False)
# trace / explicit / sensitive(§10.1)
tier: Mapped[str] = mapped_column(String(20), nullable=False, index=True)
# persona / episodic / instruction / relationship_view / fact_candidate(§10.2)
type: Mapped[str] = mapped_column(String(40), nullable=False, index=True)
# candidate / pending / active / superseded / tombstoned(§10.3)
status: Mapped[str] = mapped_column(String(20), nullable=False, default="candidate", index=True)
# user_explicit / self_inferred(§10.4)
source: Mapped[str] = mapped_column(String(20), nullable=False, default="self_inferred")
content: Mapped[str] = mapped_column(Text, nullable=False)
# 可解释性:指向镜树节点/事件(撤销与来源展开的依据)
source_refs_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
sensitivity: Mapped[str] = mapped_column(String(20), nullable=False, default="none")
priority: Mapped[int] = mapped_column(Integer, nullable=False, default=50)
confidence: Mapped[float] = mapped_column(Float, nullable=False, default=0.5)
# 活力值:2^(-Δdays/半衰期) 衰减、命中强化(§6.2)
vitality: Mapped[float] = mapped_column(Float, nullable=False, default=1.0)
# 微痕有效期;空表示不过期
valid_until: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
# 记忆界域:境界记忆不进真界上下文(§5)
realm: Mapped[str] = mapped_column(String(40), nullable=False, default="reality")
prev_version_id: Mapped[str | None] = mapped_column(String(80), index=True)
# 召回统计(召回透明)
recall_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
last_recalled_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
updated_at: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=utc_now, onupdate=utc_now
)
class MemoryTrigger(Base):
"""记忆触发条件:keyword(微痕激活管线共用)与 disclosure(单一触发)。"""
__tablename__ = "memory_triggers"
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_memory_trigger_id)
memory_id: Mapped[str] = mapped_column(String(80), ForeignKey("memories.id"), index=True)
# keyword / disclosure / vector(§10.5)
kind: Mapped[str] = mapped_column(String(20), nullable=False)
pattern: Mapped[str] = mapped_column(String(200), nullable=False)
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
class FactualRecord(Base):
"""实录(不可变):发生了什么 + 证据引用;与心痕(relationship_view)分离。"""
__tablename__ = "factual_records"
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_factual_record_id)
character_id: Mapped[str] = mapped_column(String(80), index=True, nullable=False)
canonization_id: Mapped[str] = mapped_column(String(80), index=True)
# 证据:路径节点引用 + 摘要
evidence_json: Mapped[str] = mapped_column(Text, nullable=False, default="{}")
summary: Mapped[str] = mapped_column(Text, nullable=False, default="")
occurred_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)