AM
dsh-auto-memory · Meta Code
28 模块 · 类型契约 + 关键逻辑伪代码 · 装配预览
Meta Code Atlas / Implementation Sketch / 2026-08-19

每个模块一段 Meta Code:先看装配,再看实现。

Meta code = 类型契约 + 关键逻辑骨架(伪代码,不编译),只表达职责与数据流。第 ⓪ 章是全局装配:一条主动链把各模块串起来,与系统地图的 30 条边一一对应;随后按四个泳道逐模块给出契约、啮合边与实现要点。当前维护通道使用原生 systemPrompt.section() / systemPrompt.context();未来主动 MemoryPacket 才进入 durable Agent Inbox。状态标注沿用地图:原生 / 设计 / 研究 / 安全门。

native: 原生机制(只接不改) planned: 本项目计划实现 research: 论文 / 开源启发 guard: 必须守住的边
模块索引 · 28 个

主环 · 未来主动 packet 的下一请求链

14 个节点构成闭合回路;除标注外,每一步都只影响「下一请求边界」。

N-01 运行时事件SESSION 事实源C-01 ContextObserverC-02 SessionRuntimeM-01 Working MemoryC-03 Retrieval GateC-04 Association EngineC-05 Rank / Dedupe / BudgetC-06 Injection BrokerN-03 Agent InboxN-04 Claim / AssembleN-05 agent/pre-stepN-06 Build RequestN-07 模型 / ProviderN-08 工具结果 / 反馈
未来 packet 回环:toolResult → events → retrieve → Inbox;当前维护快照走 systemPrompt.context() → RuntimeContextProjection

支线 · 召回源 / 证据升格 / 门与降级(15 条)

M-02 Episodic Memory → C-04 Association Engine · recallM-03 Semantic / Profile → C-04 Association Engine · recallM-04 Procedural Memory → C-04 Association Engine · checklistM-05 Lexical / Entity → C-04 Association Engine · entityM-06 Readable Projection → M-03 Semantic / Profile · promoteM-07 Python Memory Engine → C-04 Association Engine · sidecarG-01 Evidence Updater → M-03 Semantic / Profile · updateG-01 Evidence Updater → M-04 Procedural Memory · promoteG-02 Injection Audit → C-06 Injection Broker · auditG-03 Safety Gate → C-06 Injection Broker · gateC-07 Provider Adapter → C-06 Injection Broker · adapterG-04 Evaluation / Metrics → G-02 Injection Audit · measureG-05 Fallback / Degrade → C-04 Association Engine · degradeR-01 Research Signals → C-03 Retrieval Gate · triggerR-02 Cognitive Model → C-04 Association Engine · model
GLOBAL WIRING · 全局装配契约类型 + Host 装配 + 主动链 + 反馈回环
/* ============================================================
 * 全局装配 — 各模块的啮合方式(与地图 30 条边一一对应)
 *
 * 未来主动 packet 主环(每步请求边界前最多走一次):
 *   events → session → observer → runtime → working
 *   → gate → association → rank → safety → broker → inbox
 *   → claim → pre-step → buildRequest → model
 *   → toolResult → events(回环)
 *
 * 当前已落地维护通道:
 *   systemPrompt.section(稳定规则) + systemPrompt.context(易变快照)
 *   → systemPrompt.assemble → RuntimeContextProjection → agent/pre-step
 *
 * 支线:
 *   M-02/03/04/05 + M-07 → association     (召回源)
 *   G-01 → M-02/M-03/M-04                  (证据升格)
 *   G-02/G-03/C-07 → broker                (审计/安全门/能力)
 *   G-04 → G-02 · G-05 → association       (度量/降级)
 *   R-01 → C-03 · R-02 → C-04              (启发)
 * ============================================================ */

/* ---- 契约类型(各模块共享) ---- */
type SourceKind = 'user' | 'tool' | 'agent' | 'lifecycle'
type Scope      = 'Turn' | 'Session' | 'Workspace' | 'User' | 'External'
type Strength   = 'soft' | 'direct' | 'checklist'

interface ContextCursor { sessionId: string; eventSeq: number; contextVersion: number }
interface Segment {
  id: string;  sessionId: string;  kind: SourceKind;  eventSeq: number
  text: string;  entities: string[];  digest: string;  ts: number
}
interface Candidate {
  id: string;  source: 'episodic'|'semantic'|'procedural'|'lexical'
  scope: Scope;  score: number;  confidence: number
  provenance: string;  expiresAt: number;  payload: string
}
interface MemoryPacket {
  packetSchemaVersion: 1
  contextCursor: ContextCursor;  retrievalVersion: string
  triggerReason: string;  strength: Strength;  items: Candidate[]
  exactDigest: string;  semanticDigest: string
  budgetBytes: number;  expiry: number
}

/* ---- Host 装配: 事件入口 ---- */
class ProactiveMemoryHost {
  observer   = new ContextObserver()      // C-01
  runtime    = new SessionRuntime()       // C-02
  gate       = new RetrievalGate()        // C-03
  assoc      = new AssociationEngine()    // C-04(注入 M-02/03/04/05/07 召回源)
  rank       = new RankDedupeBudget()     // C-05
  safety     = new SafetyGate()           // G-03
  broker     = new InjectionBroker()      // C-06
  capability = new ProviderAdapter()      // C-07
  audit      = new InjectionAudit()       // G-02
  evidence   = new EvidenceUpdater()      // G-01
  metrics    = new MetricsCollector()     // G-04
  fallback   = new FallbackController()   // G-05

  /* N-01: 运行时事件入口 */
  onSessionEvent(env: EventEnvelope) {
    const seg = this.observer.observe(env)     // C-01
    if (!seg) return
    this.runtime.push(seg)                     // C-02 → M-01
    this.proactiveTick(seg)                    // 主动链: 异步, 绝不阻塞原生链
  }

  /* 未来主动 packet 链: 下一步请求边界前最多生效一次; 当前 M0/M1 维护快照不经过此检索链 */
  async proactiveTick(seg: Segment) {
    const cur = this.runtime.cursor(seg.sessionId)

    // C-03 门: 现在值不值得检索
    const decision = this.gate.decide(this.runtime.window(seg.sessionId), seg, cur)
    if (decision.action === 'suppress')
      return this.audit.suppressed(cur, decision.reason)

    // C-04 召回(引擎级失败 → G-05 词法回退)
    const cands = await this.assoc.recall(seg, cur)
        .catch(() => this.fallback.keywordRecall(seg, cur))

    // C-05 排序/去重/预算 → G-03 安全门 → C-06 成包
    const ranked  = this.rank.run(cands, cur)
    const verdict = this.safety.check(ranked, this.runtime.scopeOf(seg.sessionId))
    const packet  = this.broker.build(ranked, verdict, this.capability.snapshot())

    // G-02 审计 + G-04 度量(无论注入与否)
    this.audit.injection(packet, verdict)
    this.metrics.observe(packet, verdict)

    // 当前维护快照走 systemPrompt.context(), 由 native RuntimeContextProjection 去重/替换
    // C-06 → N-03(未来 active path): MemoryPacket 只写 next-step inbox, 不改当前请求
    if (packet && verdict.action === 'allow') this.broker.syncInbox(packet)
  }

  /* G-01 反馈回环: 工具结果 / 用户纠正 → 证据更新 → M-02/M-03/M-04 */
  onToolResult(ev)     { this.evidence.record(ev) }
  onUserCorrection(ev) { this.evidence.record(ev) }
}
架构不变量(所有 Meta code 共同遵守)
  • 跨 session 泄漏为零
  • 已发出的请求不原地改写;主动记忆只在下一请求边界生效
  • 过期 / contextVersion 不匹配的 packet 必丢弃,且不标记 delivered
  • 记忆是参考资料不是指令;不覆盖 system / developer / 当前用户指令
  • Procedure 未经验证不自动执行;高风险副作用默认需要用户确认
  • 检索中间态不写主 Session;session/event 是 append-only 事实源

NATIVE DSH REQUEST PLANE

① 原生请求面 — 已发出的请求不可改写;当前维护快照走 runtime-context,未来 packet 才走 next-step

N-01 · DSH 原生链路 NATIVE · 原生 主环 #1

运行时事件

用户、工具、助手可见输出和 Agent 生命周期进入 Host 的可观测入口。

← N-08 工具结果 / 反馈 · replay→ session 事实源 · append
/* N-01 运行时事件 — 原生链路的可观测入口(append-only 事实源) */
interface EventEnvelope {                // 观察信封: 只取最小标量快照
  schemaVersion: 1
  sessionId: string;  agentId: string
  eventSeq: number;   turn: number;   step: number
  sourceKind: 'user' | 'tool' | 'agent' | 'lifecycle'
  callId?: string;    rootCallId?: string
  payloadDigest: string                  // 只存摘要, 不复制整个 payload
}

// 消费结构化事件, 而不是解析模型文本:
on('session/event',  e => observe(envelope(e, 'lifecycle')))   // 用户消息 / 生命周期
on('tools/result',   r => observe(envelope(r, 'tool')))        // 成功 / 失败 / 重试 / 取消 / 纠正
on('agent/step',     s => observe(envelope(s, 'agent')))       // 步边界

// 硬约束: 检索中间态绝不写入 Session;
// Session 回放必须与观察结果一致, 检索失败不得伪造 session 事件
N-03 · DSH 原生链路 NATIVE · 原生 主环 #10

Agent Inbox

未来 MemoryPacket 的持久 next-turn / next-step projection,通过 durable splice 事件维护;当前动态维护快照走 systemPrompt.context()。

← C-06 Injection Broker · future packet→ N-04 Claim / Assemble · claim
/* N-03 Agent Inbox — durable next-turn / next-step projection(未来 MemoryPacket 通道, 不是唯一注入面) */
// 当前维护路径: systemPrompt.context() → native RuntimeContextProjection
//   相同完整快照不重复创建 user-context, 变化快照替换之前的 projection
// Inbox 三原语(未来 packet / 用户消息):
//   claim   步边界原子领取全部 next-step 输入 → 交给 assemble
//   inject  写 next-step 但不唤醒(未来主动 packet 默认走这里)
//   steer   写 next-step 并唤醒(仅用户 / 系统授权场景)

function syncInbox(packet: MemoryPacket) {
  // 先在 claimed 或可见 surface 找重复, 有则删除 pending 副本
  if (alreadyClaimed(packet.exactDigest) || alreadyVisible(packet.exactDigest))
    return dropPending(packet.id)
  // durable splice: 先写 durable event, 再改 live projection
  inbox.splice({ op: 'inject',
                 message: nextStepUserMessage(packet) })
}

// 约束: next-step 不是临时内存, future packet 持久存在直到被 claim 或显式移除;
// 取消 / 重启 / 恢复后 pending 状态必须可重建
N-04 · DSH 原生链路 NATIVE · 原生 主环 #11

Claim / Assemble

请求前先领取待处理消息,再组装 system prompt、runtime context 和工具。

← N-03 Agent Inbox · claim→ N-05 agent/pre-step · assemble + waterfall
/* N-04 Claim / Assemble — 请求前的原子领取与组装(真实顺序的锚点) */
// 真实顺序:  claim → systemPrompt.assemble(section + context) → runtime projection
//            → agent/pre-step waterfall → step/start → buildRequest

async function stepBoundary(session) {
  const claimed  = inbox.claimAll(session)       // 原子领取 next-step + next-turn FIFO
  const assembly = await systemPrompt.assemble({ session })
  const sections = renderContextSections(assembly)
  const context  = runtimeContext.project(joinContextSections(sections), sections)
  return { claimed, assembly, context }
}

// 约束: section/context provider 都是同步求值, 不能在其中 await 异步检索;
// 稳定规则留在 section, 易变维护快照留在 context;
// 未来异步 MemoryPacket 先进入 Inbox 或 projection queue, 再交给 pre-step waterfall
N-05 · DSH 原生链路 NATIVE · 原生 主环 #12

agent/pre-step

原生 runtime-context snapshot 与未来 packet 在下一步请求前汇合的 waterfall 边界。

← N-04 Claim / Assemble · assemble + waterfall→ N-06 Build Request · request
/* N-05 agent/pre-step — DSH 核心先组装, 再把 runtime context 交给 waterfall */
async function nativePreStep(agent, target, position, signal) {
  const claimed = agent.inbox.claim(target, position.turn)
  const assembly = await agent.loopCtx.systemPrompt.assemble(assembleContextFor(agent, signal))
  signal.throwIfAborted()
  const sections = renderContextSections(assembly)
  const context = agent.runtimeContext.project(joinContextSections(sections), sections)
  const decision = await agent.dispatch.waterfall('agent/pre-step',
    { messages: claimed, ...position, signal },
    () => Promise.resolve({
      kind: 'enter',
      messages: context === undefined ? claimed : [...claimed, context]
    }))
  signal.throwIfAborted()
  return decision.kind === 'reject' ? decision : { ...decision, assembly }
}

// 当前 native context 在这里按完整文本去重; 变化时替换旧 projection
// 未来 packet listener 只在 waterfall 中校验/保留/消费自己的 Inbox pending
N-06 · DSH 原生链路 NATIVE · 原生 主环 #13

Build Request

把 assembled context、可见历史、工具 schema 和当前路由形成精确请求。

← N-05 agent/pre-step · request→ N-07 模型 / Provider · dispatch
/* N-06 Build Request — 精确成形; 此后任何事件只影响下一 step/turn */
interface RequestAudit {
  provider: string;  model: string
  reasoning: 'none' | 'summary' | 'full' | 'unknown'
  packetBytes: number;  packetDigest?: string
  contextVersion: number
}

function buildRequest({ assembly, messages, tools, history }) {
  return {
    system: renderPrompt(assembly),              // section 稳定前缀 → KV cache 复用
    messages: [...history.visible, ...messages], // context 是原生 user-role snapshot
    tools,
    _audit: new RequestAudit(),                 // 生效 provider/model/reasoning 可追踪
  }
}

// 未来 MemoryPacket 也只能追加到下一请求 messages, 不能改写已发请求
// 约束: 动态段每步变化会击穿前缀缓存, 与稳定段分开预算;
// 字符预算 ≠ 模型 token 预算; packet 成本单独核算
N-07 · DSH 原生链路 NATIVE · 原生 主环 #14

模型 / Provider

异构模型实际生成、调用工具并返回可观测结果。

← N-06 Build Request · dispatch→ N-08 工具结果 / 反馈 · feedback
/* N-07 模型 / Provider — 异构模型执行; 能力由 adapter 声明, 不按名字硬编码 */
function dispatch(req: BuiltRequest) {
  const cap = capability.snapshot(route(req))   // C-07 协商: reasoning / runtimeContext / packetPatch
  return llm.complete(req)                       // → assistant output / tool calls / reasoning?
}

// 约束: 公开 reasoning ≠ 完整、忠实的内部状态(CoT faithfulness);
// 闭源模型只依赖用户 / 工具 / 可见输出 / 运行时事件;
// reasoning trace 不单独写入事实、授权副作用或晋升技能
N-08 · DSH 原生链路 NATIVE · 原生 主环 #15

工具结果 / 反馈

工具成功、失败、重试、取消和用户纠正是最可靠的运行时反馈。

← N-07 模型 / Provider · feedback→ N-01 运行时事件 · replay
/* N-08 工具结果 / 反馈 — 最可靠的运行时反馈(emit-only 冻结观测) */
on('tools/result', r => {
  // freeze: 冻结结果只读, 绝不当作可原地修改的对象
  const obs = { kind: 'tool', callId: r.callId, rootCallId: r.rootCallId,
                ok: r.ok, digest: digest(r.payload) }
  observer.observe(obs)      // → C-01
  evidence.record(obs)       // → G-01(强化 / 削弱)
})

// touch 延迟到 step/end 结算, 避免开放步骤抢跑;
// 只有工具明确产生下一步说明时才使用 deferContext;
// 成功 / 失败 / abort / 嵌套调用都能生成稳定 observation

PROACTIVE MEMORY CONTROL PLANE

② 主动控制面 — observe → retrieve → packet

C-01 · 主动控制面 PLANNED · 设计 主环 #3

ContextObserver

把原生事件转换为按 session 隔离的语义上下文片段。

← session 事实源 · observe→ C-02 SessionRuntime · scope
/* C-01 ContextObserver — 原生事件 → 按 session 隔离的语义上下文片段 */
function observe(env: EventEnvelope): Segment | null {
  if (env.schemaVersion !== 1) return null        // 版本不符直接丢
  const text = sliceByKind(env)                   // 按事件类型切片, 不粗暴取最后 N token
  return {
    id: uid(), sessionId: env.sessionId, kind: env.sourceKind,
    eventSeq: env.eventSeq, text,
    entities: extract(text), digest: digest(text), ts: now(),
  }
}

// 约束: 跨 session 合并事件 = 污染后续所有检索;
// contextVersion 单调递增; 过期异步结果可丢弃;
// reasoning chunk 可作可选 reasoning segment, 默认不持久化
C-02 · 主动控制面 PLANNED · 设计 主环 #4

SessionRuntime

每个 agent/session 的工作状态、上下文环、pending packet 和冷却。

← C-01 ContextObserver · scope→ M-01 Working Memory · window
/* C-02 SessionRuntime — per-agent/session 运行态(消灭全局状态) */
const states = new WeakMap<Agent, AgentMemoryState>()   // 执行 token 用 Map 关联嵌套观测

interface AgentMemoryState {
  working: RingBuffer<Segment>        // → M-01 工作记忆
  cursor: ContextCursor               // 单调递增
  pending: MemoryPacket[]             // 待注入队列
  cooldown: Map<string, number>       // 触发冷却
  sidecarJob?: AbortController
}

function teardown(agent) {
  states.get(agent)?.sidecarJob?.abort()   // abort 检索 → sidecar quiescence → 清理 map
  states.delete(agent)
}

// 验收: 并发 A/B session 隔离为零泄漏;
// 不再依赖进程级 _lastAgent / 全局 _consolidating / 全局 pending queue
C-03 · 主动控制面 PLANNED · 设计 主环 #6

Retrieval Gate

动态判断现在是否值得检索,而不是每一步固定召回。

← M-01 Working Memory · signal← R-01 Research Signals · trigger→ C-04 Association Engine · retrieve
/* C-03 Retrieval Gate — 动态判断"现在值不值得检索"(无 CoT 也成立) */
interface GateDecision { action: 'retrieve' | 'prefetch' | 'suppress'; reason: string }

function decide(win: Segment[], seg: Segment, cur: ContextCursor): GateDecision {
  const signals = {
    novelty:     !win.some(s => s.digest === seg.digest),         // 新颖度
    unresolved:  unresolvedEntities(win).length > 0,              // 未决实体
    phaseShift:  taskPhase(win) !== taskPhase(win.slice(0, -1)),  // 任务阶段变化
    toolFailure: seg.kind === 'tool' && !seg.ok,                  // 工具失败
    conflict:    conflictCount(cur.sessionId) > 0,                // 冲突
    historical:  hitRecent(cur.sessionId) !== null,               // 相似历史命中
  }
  if (cooldownActive(cur))            return { action: 'suppress', reason: 'cooldown' }
  if (ignoredMemory(cur, seg.digest)) return { action: 'suppress', reason: 'user-ignored' }
  const s = weighted(signals)   // 权重来自 R-02 认知模型 + R-01 论文启发
  return s >= HOT  ? { action: 'retrieve', reason: 'above-threshold' }
       : s >= WARM ? { action: 'prefetch', reason: 'warm' }
       :             { action: 'suppress', reason: 'below-threshold' }
}

// 公开模型可增加 uncertainty / reasoning 信号, 但不是硬依赖;
// cognitive load 不是"记忆只在困难时出现"的硬门;
// 滞回 + 冷却 + "已忽略记忆"抑制避免反复打扰
C-04 · 主动控制面 PLANNED · 设计 主环 #7

Association Engine

从预索引记忆中找出当前情境可能自动唤回的候选。

← C-03 Retrieval Gate · retrieve← M-02 Episodic Memory · recall← M-03 Semantic / Profile · recall← M-04 Procedural Memory · checklist← M-05 Lexical / Entity · entity← M-07 Python Memory Engine · sidecar← G-05 Fallback / Degrade · degrade← R-02 Cognitive Model · model→ C-05 Rank / Dedupe / Budget · candidates
/* C-04 Association Engine — 三级检索: 词法初筛 → 向量/时间过滤 → 图扩散 */
async function recall(seg: Segment, cur: ContextCursor): Promise<Candidate[]> {
  const hits: Candidate[] = []

  // ① 关键词 / 实体快速初筛(永远可用)
  hits.push(...lexical.hits(seg.entities, seg.text))            // M-05

  // ② 向量 + 时间过滤(sidecar, 可降级)
  const emb = await sidecar.embed(seg.text, cur)                // M-07
  if (emb.ok) hits.push(...await sidecar.vsearch(emb.vec, cur.scope))
  else hits.push(...fallbackKeyword(seg.text))                  // G-05 词法回退

  // ③ 必要时图扩散(HippoRAG PPR / A-MEM 链接)
  if (graphEnabled && hits.length < k)
    hits.push(...await sidecar.graphExpand(seg.entities))

  // embedding 元数据(model / dimension / version)随索引持久化, 版本不一致不得混用
  // 图链接追加证据且可撤销, 避免一次错误扩散污染整个图
  return hits
}
C-05 · 主动控制面 PLANNED · 设计 主环 #8

Rank / Dedupe / Budget

把"相关"变成有限、可解释、不会重复的候选集合。

← C-04 Association Engine · candidates→ C-06 Injection Broker · policy
/* C-05 Rank / Dedupe / Budget — 把"相关"变成有限、可解释、不重复的候选集 */
function run(cands: Candidate[], cur: ContextCursor): RankedResult {
  const scored = cands
    .filter(c => c.scope === cur.scope && c.expiresAt > now())    // scope + TTL
    .map(c => ({ c, s: wSim * c.similarity + wSal * c.salience
                   + wNov * novelty(c, cur) + wRec * recency(c, cur) }))
    .sort((a, b) => b.s - a.s)

  const kept = [], dropped = []
  const seen = new Set()
  for (const x of scored) {
    const key = dedupeKey(x.c, cur)   // session/agent + context cursor
                                      // + exact/semantic digest + schema/index 版本
    if (seen.has(key)) { dropped.push({ id: x.c.id, reason: 'duplicate' }); continue }
    if (bytes + x.c.payload.length > budget.candidateBytes)
      { dropped.push({ id: x.c.id, reason: 'budget' }); continue }
    seen.add(key); kept.push(x)
  }
  return { ranked: kept, dropped }    // 每个 drop 都有理由

// 预算分层: 摄取上限 → 候选延迟上限 → packet UTF-8 bytes → token/context window
// 超预算候选不得标记 delivered; TTL 只触发重检索, 不充当内容 identity
}
C-06 · 主动控制面 PLANNED · 设计 主环 #9

Injection Broker

决定未来候选记忆是否在下一请求边界变成 MemoryPacket;不负责当前 native runtime-context snapshot。

← C-05 Rank / Dedupe / Budget · policy← G-02 Injection Audit · audit← G-03 Safety Gate · gate← C-07 Provider Adapter · adapter→ N-03 Agent Inbox · future packet
/* C-06 Injection Broker — 候选 → 下一请求边界的 MemoryPacket(或放弃) */
function build(ranked, verdict: SafetyVerdict, cap): MemoryPacket | null {
  if (!cap.packetPatch || cap.packetPatch === 'none') return null  // runtime-context 不是未来 packet 通道
  if (verdict.action !== 'allow') return null                        // G-03 拦截
  return {
    packetSchemaVersion: 1,
    contextCursor: cur,                     // 与 retrievalVersion 一起校验新鲜度
    retrievalVersion: indexVersion(),
    triggerReason: verdict.trigger,
    strength: pickStrength(ranked, cap),    // soft hint / direct context / checklist
    items: ranked,
    exactDigest: exactDigest(ranked),  semanticDigest: semanticDigest(ranked),
    sourceSeqs: ranked.map(c => c.sourceSeq),
    budgetBytes: totalBytes(ranked),  expiry: now() + ttl,
  }
}

// 约束: packet 不是高优先级新指令; 请求发出后不回写隐藏状态;
// 任何注入都能回答 why / what / source / cost / expiry
C-07 · 主动控制面 PLANNED · 设计 支线模块

Provider Adapter

按 Provider、model、version 分开协商 reasoning、native runtime context 与未来 packet surface。

→ C-06 Injection Broker · adapter
/* C-07 Provider Adapter — 分开声明 native runtime context 与 future packet surface */
function snapshot(route): CapabilitySnapshot {
  const m = manifest(route.provider, route.model, route.modelVersion)
  return {
    reasoningVisibility: m.reasoning ?? 'unknown',   // none / summary / full / unknown
    runtimeContext: m.includeRuntimeContext !== false ? 'native' : 'none',
    packetPatch: m.supportsPreStep ? 'pre-step'
                : m.supportsUserMessage ? 'user-message'
                : 'none',
    abortAndResume: !!m.abortAndResume,
  }
}

// runtimeContext = native systemPrompt.context() + RuntimeContextProjection
// packetPatch = future Agent Inbox / next-step MemoryPacket path
// includeRuntimeContext:false suppresses the first channel; it does not create the second
// Minimal complete persona: complete:true + includeRuntimeContext:false
//   → native runtime-context 被抑制, 不能假设已挂载 dsh-agent-instructions
//   → 未来需自建 packetPatch user/message 路径, 否则安全降级 shadow retrieval
// 约束: 不能按"模型名称"硬编码能力; preset 不支持 patch 时不强行改请求

COGNITIVE MEMORY PLANE

③ 认知记忆面 — working / episodic / semantic / procedural / lexical / projection / sidecar

M-01 · 认知记忆面 PLANNED · 设计 主环 #5

Working Memory

当前 session 的短期注意力缓冲:目标、窗口、未决事项、最近结果和 pending packet。

← C-02 SessionRuntime · window→ C-03 Retrieval Gate · signal
/* M-01 Working Memory — session 内短期注意力缓冲(ring + TTL, 不跨 session) */
class WorkingMemory {
  ring: Segment[] = []
  cap = 32;  ttl = 15 * 60_000

  push(seg) { this.ring.push(seg); this.evict() }   // 按最旧/TTL/重复淘汰, 可解释
  window()  { return this.ring.filter(s => now() - s.ts < this.ttl) }
  signals() {                                        // → C-03 gate
    return { unresolved: this.unresolved(), phase: this.phase(),
             last: this.ring.at(-1) }
  }
}

// 按语义片段而非粗暴最后 N token;
// 高相关候选可静默预取(pending), 不必立即注入;
// 容量无限增长会让"联想"退化成全量 RAG
M-02 · 认知记忆面 PLANNED · 设计 支线模块

Episodic Memory

带时间、动作、工具结果和失败证据的事件经验。

→ C-04 Association Engine · recall
/* M-02 Episodic Memory — 带时间/动作/结果/失败证据的事件经验 */
interface Episode {
  intent: string;  actions: string[];  entities: string[]
  unresolved: string[];  outcome: 'success' | 'failure'
  provenance: string          // sessionId + '#' + turn + '.' + step
}

function record(ev) {
  const ep = { intent: infer(ev), actions: ev.actions, entities: ev.entities,
               unresolved: ev.unresolved, outcome: ev.ok ? 'success' : 'failure',
               provenance: sessionId + '#' + turn + '.' + step }
  sidecar.append('episodes.jsonl', ep)      // 轻量事件先落 sidecar
  scheduleIdle(() => consolidate(ep))       // 空闲期摘要 + 巩固 → 候选进 M-03
}

// 失败经验默认是 candidate, 不直接是事实;
// 错误自我解释被持久化 = 污染长期层
M-03 · 认知记忆面 PLANNED · 设计 支线模块

Semantic / Profile

去重后的项目事实、环境约束、用户偏好和稳定决策。

← M-06 Readable Projection · promote← G-01 Evidence Updater · update→ C-04 Association Engine · recall
/* M-03 Semantic / Profile — 去重后的项目事实 / 环境约束 / 用户偏好 / 稳定决策 */
interface Fact {
  scope: Scope
  subject: string;  predicate: string;  object?: string
  provenance: string[];  confirmedAt: number
  ttl?: number;  revoked?: boolean
}

function upsert(cand: FactCandidate) {
  if (conflicts(cand)) return conflicts.add(cand)          // 冲突集保留双方 provenance
  const existing = find(cand.subject, cand.predicate)
  if (existing && cand.source === 'inference') return      // 自动推断不覆盖硬规则
  store.put(merge(existing, cand))                          // → M-06 投影 + sidecar 索引
}

// 用户明确声明 > 模型推断; 项目事实 / 用户画像 / 术语分开;
// 冲突可见、可确认、可撤销(revoked)
M-04 · 认知记忆面 GUARD · 安全 支线模块

Procedural Memory

经过独立成功验证的步骤、技能、检查清单和回滚流程。

← G-01 Evidence Updater · promote→ C-04 Association Engine · checklist
/* M-04 Procedural Memory — 经验证的步骤/技能/检查清单(guard 级) */
type Stage = 'observed' | 'candidate' | 'validated' | 'active' | 'deprecated'

interface Procedure {
  preconditions: string[];  steps: string[];  checks: string[]
  successCriteria: string[];  rollback: string[]
  riskLevel: 'low' | 'medium' | 'high';  requiresApproval: boolean
  stage: Stage;  evidence: string[]
}

function promote(p: Procedure) {
  if (p.riskLevel === 'high' && p.requiresApproval && !userApproved)
    return { action: 'ask' }                    // 永远先问, G-03
  if (!crossSessionEvidence(p)) return          // 跨独立 session 证据不足则停
  p.stage = 'validated';  store.put(p)
}

// 注入形态: 只作建议 / checklist packet;
// 高风险工具(SSH/部署/删除)永不因相似度自动执行;
// 一次成功或三次重复都不足以证明技能可靠
M-05 · 认知记忆面 RESEARCH · 研究 支线模块

Lexical / Entity

术语、缩写、别名和实体对齐层,帮助关联检索但不等于用户画像。

→ C-04 Association Engine · entity
/* M-05 Lexical / Entity — 术语/缩写/别名/实体对齐(检索增强层) */
function hits(entities: string[], text: string): Candidate[] {
  return entities
    .flatMap(e => aliasIndex[e] ?? [])       // 别名展开
    .map(n => ({ ...n, source: 'lexical', score: LOW_PRIOR }))
}

// 词法别名是低风险检索增强, 不直接提升事实置信度;
// 实体关系可连接 semantic / episodic / procedure 节点;
// 冲突别名保留来源与 scope; 可撤销且不覆盖原文; 共现 ≠ 偏好/事实
M-06 · 认知记忆面 NATIVE · 原生 支线模块

Readable Projection

Markdown 是用户可读、可编辑、可备份的持久投影;sidecar 承担运行时索引。

→ M-03 Semantic / Profile · promote
/* M-06 Readable Projection — Markdown 是事实可见性边界, sidecar 是运行时索引 */
function project(fact: Fact) {
  writeMarkdown(target(fact.scope), render(fact))   // MEMORY.md / 日志 / 反思, 保留现有结构
  sidecar.index(fact)                                // JSONL / SQLite / vector 元数据
}

// sidecar 损坏可从 Markdown 重建; 新增元数据不覆盖 Markdown;
// 写入与索引更新必须原子或可恢复;
// 验收: 关闭新层时现有 Markdown 行为不变
M-07 · 认知记忆面 PLANNED · 设计 支线模块

Python Memory Engine

可选 sidecar:embedding、向量/图检索、reranker、衰减和离线评测。

→ C-04 Association Engine · sidecar
/* M-07 Python Memory Engine — 可选 sidecar(JSONL 协议, 失败回退 JS) */
interface SidecarRequest {
  requestId: string;  contextVersion: number
  op: 'embed' | 'search' | 'graph-expand' | 'consolidate'
  payload: JsonValue
}

// JS Host: 无 shell 的 spawn/execFile 拉起长驻 worker; lazy start
// stdout 只输出 JSONL; stderr 输出日志
async function call(req: SidecarRequest) {
  const res = await timeout(3000, jsonl(request(req)),
                            () => { sidecar.restart(); return FALLBACK })
  if (res.contextVersion !== cur.contextVersion) return DROP   // 版本不匹配必丢弃
  return res.candidates
}

// Python 崩溃/超时/未安装 → 回退 JS 关键词检索;
// sidecar 不接触 ctx / Agent 对象 / 请求; 不修改请求

EVIDENCE · SAFETY · OPERATIONS

④ 证据 · 安全 · 运营 — 升格 / 审计 / 安全门 / 度量 / 降级 / 理论

G-01 · 治理与运营 PLANNED · 设计 支线模块

Evidence Updater

根据成功、失败、纠正、复用和冲突更新记忆证据与状态。

→ M-03 Semantic / Profile · update→ M-04 Procedural Memory · promote
/* G-01 Evidence Updater — 结果证据驱动的置信度与升格决策 */
function record(ev) {
  if (ev.kind === 'tool') {
    ev.ok ? reinforce(ev.provenance)   // 成功复用 → confidence ↑
          : weaken(ev.provenance)      // 失败 → ↓
  }
  if (ev.kind === 'user-correction') conflict.add(ev.fact)     // 纠正 → 冲突集
  if (ev.kind === 'packet-delivered') advanceDeliveredCursor(ev.digest)
      // 只有实际进入 decision.messages 的 packet 才推进 delivered cursor
}

// 空闲期 consolidation, 不阻塞主模型请求;
// 没有结果证据的自动升格 = 放大错误; 每次晋升都有 evidence list + 可逆状态
G-02 · 治理与运营 PLANNED · 设计 支线模块

Injection Audit

记录为什么注入、注入了什么、从哪里来、花费多少以及结果如何。

← G-04 Evaluation / Metrics · measure→ C-06 Injection Broker · audit
/* G-02 Injection Audit — why / what / source / cost / result 全链路可解释 */
function injection(packet: MemoryPacket, verdict: SafetyVerdict) {
  audit.log({
    packetId, sessionId, cursor: packet.contextCursor,
    trigger: verdict.trigger, scores: packet.items.map(i => i.score),
    sourceSeqs: packet.sourceSeqs, bytes: packet.budgetBytes,
    expiry: packet.expiry, action: verdict.action,
  })   // 只存最小必要摘要: 审计本身也可能暴露敏感内容
}

// 检索中间态不写主 Session; 注入决策与结果形成可解释审计;
// UI 提供查看 / 撤销 / 禁用 / 重放入口;
// 任何注入可从审计反查到来源与版本
G-03 · 治理与运营 GUARD · 安全 支线模块

Safety Gate

记忆是参考资料,不是新指令;冲突、范围、风险和副作用必须在 Broker 前拦截。

→ C-06 Injection Broker · gate
/* G-03 Safety Gate — 在 Broker 之前拦截(记忆是参考资料, 不是新指令) */
function check(ranked: Candidate[], scope: Scope): SafetyVerdict {
  for (const c of ranked) {
    if (c.scope !== scope && c.scope !== 'Workspace') return suppress('scope')
    if (c.kind === 'procedure' && c.riskLevel === 'high') return ask()   // 副作用默认确认
    if (looksLikeInstruction(c.payload)) return suppress('injection')    // 提示注入 / 过期指令
    if (c.revoked) return suppress('revoked')
  }
  return { action: 'allow', trigger: ranked[0]?.triggerReason }
}

// scope: Turn / Session / Workspace / User / External 正交管理;
// 公开 reasoning 不能单独授权动作或证明事实;
// 外部记忆可能含提示注入 / 过期指令 / 恶意文本
G-04 · 治理与运营 PLANNED · 设计 支线模块

Evaluation / Metrics

用离线回放和基准评估主动召回是否真的提高任务结果。

→ G-02 Injection Audit · measure
/* G-04 Evaluation / Metrics — 离线回放 + 基准评估主动召回的真实收益 */
function observe(packet: MemoryPacket | null, verdict: SafetyVerdict) {
  metrics.inc('trigger', { hit: verdict.action === 'allow', reason: verdict.trigger })
  metrics.inc('cost',    { bytes: packet?.budgetBytes ?? 0 })
}

// 基准: LongMemEval(跨 session/时间/知识更新) + LoCoMo(长对话单跳/多跳)
// 指标: trigger precision/recall · helpful gain · harmful injection
//       duplicate · contamination · latency · tokens · leakage
// 路线: 先 Shadow Retrieval(只记录), 再 A/B Soft Injection
// 只测最终答案会忽略触发时机和误注入伤害; cross-session leakage 必须为零
G-05 · 治理与运营 GUARD · 安全 支线模块

Fallback / Degrade

高级算法不可用时,系统仍保持 DSH 基础对话和当前记忆功能。

→ C-04 Association Engine · degrade
/* G-05 Fallback / Degrade — 高级层关闭时, 基础对话与现有记忆功能不变 */
function keywordRecall(seg: Segment, cur: ContextCursor): Candidate[] {
  return lexicalIndex.search([...seg.entities, ...tokens(seg.text)])
}

// Python / embedding / reranker / 图检索: 全部有超时 + 失败回退
// provider unavailable ≠ 删除文件(原生 pattern 回滚临时状态)
// 过期 packet 丢弃且不标记 delivered; 下一事件可重新检索
// 回退路径不悄悄改变现有 Markdown 注入语义
R-01 · 理论研究 RESEARCH · 研究 支线模块

Research Signals

论文提供触发、记忆类型、反思、技能和评测的参考,不是现成 Host 实现。

→ C-03 Retrieval Gate · trigger
/* R-01 Research Signals — 论文启发 → 设计约束(不是现成 Host 实现) */
const constraints = {
  types:    CoALA,                                  // 记忆类型词汇
  stream:   GenerativeAgents,                       // stream + relevance/recency/importance
  paging:   MemGPT,                                 // 受限窗口 + 外部记忆分页
  graph:    [A_MEM, HippoRAG],                      // 链接记忆 / KG + PPR 扩散
  inGen:    [FLARE, IRCoT, DRAGIN, SelfRAG],        // 生成过程检索 → 只作触发启发
  skills:   [Reflexion, Voyager],                   // 经验反馈 / 环境验证技能库
  eval:     [LongMemEval, LoCoMo],                  // 评测
}

// 约束: 不能把生成侧方法描述成已实现的 Host 主动注入;
// 每条设计类比在文档中标注"启发"而非"已实现"
R-02 · 理论研究 RESEARCH · 研究 支线模块

Cognitive Model

人类联想机制的工程抽象:激活、衰减、扩散与抑制。

→ C-04 Association Engine · model
/* R-02 Cognitive Model — 激活 / 衰减 / 扩散 / 抑制的工程化近似 */
function activation(c: Candidate, seg: Segment, cur: ContextCursor): number {
  return base(c.confidence)
       + wRel * relevance(c, seg)     // 关联度
       + wRec * recency(c, cur)       // 近因
       + wFrq * frequency(c, cur)     // 频因
       + wSal * salience(c)           // 显著性
       - wSup * suppression(c, cur)   // 重复 / 已忽略抑制
}

// Activation 只用于排序, ≠ 真实性;
// 认知状态(介入强度)与联想激活(候选)分离;
// 每个权重可通过离线回放校准;
// 不宣称软件分数等同真实脑机制或模型隐藏 attention
边界说明:本页 Meta code 是与 proactive-associative-memory-system-map.html 一一对应的实现草图,不编译、不运行;标注为「设计/研究」的模块不代表当前插件已实现。原生模块(N-*)描述的是插件「如何接入」DSH 既有机制,而非重新实现它们。