Files
memind/docs/context-runtime-harness-fusion-plan.md
T
john 1d165bc6e3 feat(goose): complete v1.49 phase3 closeout gates and context fusion plan
Expand Goose v1.49 smoke coverage (memory chat, portal resume, page e2e,
multiturn provider), add canary memory policy lock, refresh baselines, and
ignore one-off evidence artifacts. Document headroom-based context runtime
fusion plan; include auth, scheduled-task, and wechat intent fixes on branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-09 18:11:39 +08:00

34 KiB
Raw Blame History

Context Runtime + Agent Harness 融合实施方案

状态:方案已定稿;Context Runtime Phase 16 尚未授权产品代码改动。v1.49 收口与 Phase 0 清理可并行推进(2026-09-09)。 生成日期:2026-09-09 关联规范:AGENTS.md · ENGINEERING_WORKFLOW_RULES.md · PRODUCTION_RELEASE_RULES.md · docs/production-release-guardian.md 关联现状:docs/memory-v2/README.md · docs/goose-v149-phase3-closeout.md · docs/goose-v149-canary-runbook.md

0. 本方案要解决的问题

MeMind 当前不缺 Agent 执行能力,缺的是一层统一的 Context Runtime(这一刻 Agent 该知道什么)与可插拔的 Agent Harness(谁来组装、谁来裁决)。

Memory V2 在设计上明确不是 context runtime

Memory V2 is a facade and policy abstraction layer over existing Memind memory systems. It is not a new memory system. —— docs/memory-v2/README.md

因此 Memory ≠ Context 的分层是成立的:Memory 回答「过去有什么值得记住」,Context Runtime 回答「这一刻这个 Agent 为完成任务应该知道什么」。

现存的四套并行上下文注入

管道 位置 现状问题
Portal 编排注入 chat-intent-router.mjs【Memind 任务编排】 与 Goose harness 内容可能重复
Goose harness session-reconcile.mjs/agent/harness_remember 只覆盖 workspace 记忆,不管 tool output
Direct Chat system prompt direct-chat-service.mjs 第三套独立 memory 解析
Session compaction goosed 内部 Portal 侧无 tool result index,压缩后状态丢失

四套互不知情,没有统一预算、没有去重、没有单一 trace。


1. 关键可行性约束(必须先理解)

1.1 工具结果拦截边界

context-mode 的 98% 压缩来自 hook 在工具结果进入模型上下文之前拦截替换,前提是它与 agent 同进程并握有 PreToolUse / PostToolUse 钩子。

MeMind 的拓扑不同:

tkmind-proxy ──HTTP──> goosed ──> MCP tool 执行
                         │              │
                         │         结果回 goosed
                         │              ↓
                         │      goosed 内部拼 LLM 请求  ← 上下文在此已膨胀
                         ↓
                    SSE 事件流 ──> tkmind-proxy  ← Portal 只在此看到,已是事后

推论:在 Portal 侧(agent-run-gateway.mjs / tkmind-proxy.mjs)建 tool result index,只能得到可观测性、replay、审计,拿不到任何 token 节省。

真正能省 token 的只有两条路:

路径 落点 版本依赖 可行性
B 路 MeMind 自有 MCP 在 return 前自压缩 今天即可做
C 路 改 goosed 加通用 hook 绑 1.49 tkmind_go-v149,成本高

MeMind 自有三个 stdio MCP server,由 goosed spawn 但代码在本仓库(见 capabilities.mjs 约 808877 行):

  • tkmind-searchtkmind-search-mcp.mjstkmind_search / tkmind_read / tkmind_research
  • tkmind-exceltkmind-excel-mcp.mjsexcel_inspect / excel_analyze / excel_chart / excel_report
  • mindspace sandbox → mindspace-sandbox-mcp.mjs

tkmind_read 单次可返回 TKMIND_SEARCH_READER_MAX_CHARS(默认 12000)字符,tkmind_research 报告更大。这些结果在 MeMind 自己的进程内生成,可在 return 前压缩为「摘要 + handle」,goosed 拿到的就已经是小结果。

1.2 受保护路径与 Gate 成本

AGENTS.md 受保护关键路径包含 tkmind-proxy.mjsserver.mjswechat-mp.mjssession-reconcile.mjs 等。改动这些会触发 Core + Impact Gate 的影响域展开。

tkmind-search-mcp.mjs / tkmind-excel-mcp.mjs 不在保护清单内,验证成本低一个量级。这是 B 路优先的第二个理由。

1.3 现有技术栈约束

  • MCP 协议为手写 stdio JSON-RPCtkmind-search-mcp.mjsnode:readline),无 MCP SDK 依赖
  • package.json 依赖中没有 SQLite,但有 redis / pg / mysql2
  • 本机 Node v26

推论

  • 自研压缩器,全量存储用 Redis 或 PG,不引入 better-sqlite3 等原生依赖,避免污染 release-portal-runtime-prod.sh 的整包构建与跨平台交付
  • 直接挂载外部 MCP(见第 6 节),它作为独立 stdio 进程自带存储,不进 Portal 依赖树;Node ≥ 22.5 的项目会走内置 node:sqlite,同样无原生编译

1.4 v1.49 定位澄清

v1.49 当前状态:

  • 分支 feature/goose-v149-local-canary4 个 commit 未进 origin/main
  • docs/goose-v149-phase3-closeout.mdPhase 3 收口,本阶段不授权 103/105 操作
  • 生产仍是 1.41 stable:18006:18014),1.49 仅本地 loopback :18049
  • goose-canary-memory-policy.mjs 硬锁 canary 期 memory 为 legacyvector / injection / lifecycle 全关

本方案的工作落在三个互相独立的变更面:

仓库 版本依赖 内容
A. Portal 编排 Memind 版本无关 Injection Budget、Recall Fusion、Harness plugin 化
B. MeMind 自有 MCP Memind 版本无关 Tool result 压缩
C. Goose 运行时 tkmind_go-v149 绑 1.49 通用 PreToolUse hook

设计原则 #0:A / B 面强制版本无关,必须能在 stable 1.41 上独立验证与独立上线,不等 1.49。 理由:1.49 本身未闭环,Context Runtime 又要动 memory 注入。两个未闭环大改动叠加会让故障归因不可能,且 switch-goose-v149-canary.sh rollback 回落 stable 时新层是否成立说不清。


2. 设计原则

沿用 Memory V2 已在本仓库验证过的形状,不另创范式

  1. 旁挂不改主干 —— 新增独立模块,主干只加薄调用点
  2. 默认全关 —— 所有开关默认 offenv + memind_adm 双控
  3. fail-open —— 新层任何异常退回现有行为,绝不阻塞
  4. shadow 先行 —— 先只观测记录不改行为,拿到证据再 canary → active
  5. 版本无关 —— A / B 面不引用任何 v149-only 接口
  6. 不新增原生依赖 —— 存储复用 Redis / PG

3. 目标架构

User → agent-run-routes
         │
   ┌─────┴───────────────────────────────────┐
   │  Context Runtime(新增,A 面)          │
   │  · Injection Budget   统一 token 预算   │
   │  · Recall Fusion      三路召回合并去重  │
   │  · Trace              单一可观测事件    │
   └─────┬───────────────────────────────────┘
         │
   Agent Harness(重构 agent-run-gatewayA 面)
         │
   tkmind-proxy → goosed
                    │
              ┌─────┴──────────────────────┐
              │ MeMind 自有 MCPB 面)    │
              │ · Result Compaction        │
              │ · handle + ctx_fetch       │
              └────────────────────────────┘
                    │
              Compute FabricPAIRPhase 6

落点对照

新能力 新增模块 薄调用点(现有文件) 受保护路径
Tool Result 压缩 mcp-result-compactor.mjs tkmind-search-mcp.mjstkmind-excel-mcp.mjscapabilities.mjs
Injection Budget context-budget.mjs chat-intent-router.mjssession-reconcile.mjsagent-run-gateway.mjs 部分
Recall Fusion recall-fusion.mjs chat-intent-router.mjstemporal-recall-service/context-planner.mjs
Harness plugin 化 harness/ 目录 agent-run-gateway.mjs3235 行拆分)
Personal KG user-model-service/graph.mjs 复用 dormant memory-v2-neo4j.mjs
Compute Router 配置层 provider 配置

融合点:注入预算去重

当前两条独立注入路互不知情:

  • agent-run-gateway.mjs 约 1889 行 → chatIntentRouter.resolveAgentMemoryContext() → Portal 编排文本
  • session-reconcile.mjs 约 310337 行 → buildSessionMemoryEntries()/agent/harness_remember

两者都从 memory 取数据(一条经 resolveAgentMemoryContext,一条经 resolveUserMemories),可能写入同类信息两遍。

context-budget.mjs 在两者之上做单一预算裁决 + 内容指纹去重,输出「本次注入什么、各占多少 token」,并产出统一 trace 事件。

注意:MEMORY_AGENT_INJECTION_MODE 默认 off,所以这条重复今天大概率还未真正发生。这是好消息——在打开 injection 之前先把预算层建好,比打开后救火便宜得多。


4. 分期实施

Phase 0 · 前置清理(硬阻断)

AGENTS.md 单一开发分支硬闸门要求:同时只允许一个未闭环开发分支 + 一个开发 worktree。当前状态违反:

实测
worktree 1 /Users/john/Project/Memind @ feature/goose-v149-local-canary
worktree 2 /Users/john/Project/Memind-health-p0 @ feature/memind-health-p0
Memind dirty ~192(34+ 已跟踪修改 + 大量未跟踪 evidence)
Memind 未推送 4 commit
Phase 3 聚合 最近一次 GOOSE_V149_PHASE3_FAILmultiturn / page-e2e 超时;Phase 3 段 portal-resume 已通过)
health-p0 dirty 9536 M + 59 ??
health-p0 领先 2 commit,落后 origin/main 20 commit

详见第 5 节分类处置清单。

产出:干净 worktree、单一分支、origin/main 已同步。 闸门node scripts/run-goosed-v149-phase3.mjsGOOSE_V149_PHASE3_OKpush / 合 main 须取得明确批准。


Phase 1 · Tool Result 压缩(B 面 · 版本无关 · 优先级最高)

目标:降低 goosed context 与 token 成本。

已决策路线:headroom 独立 proxy 模式Apache 2.0)。决策依据见 6.4。

1-A · headroom provider proxy(选定方案)

为什么是 proxy 而非 MCPheadroom 的 proxy 拦截的是发往 LLM 的请求本身,而工具输出正是在 goosed 内部累积进该请求。这绕过了 1.1 节标记的「必须 fork Goose」约束,不改 Goose 也能压到真实上下文

goosed ──> headroom proxy ──> LLM provider
              ↑
        在此压缩 LLM 请求

MeMind 已有同形插槽:deepseek-no-think-proxy.mjs:18036)就是 provider 层代理,headroom 并列接入。

必须用 standalone proxy,不要用 headroom wrap goose 尽管官方兼容矩阵中 Goose 标记为 starts proxy + launches),但 wrap 会:启动 agent 会话、自动安装 Serena、注入 agent 配置。这些对服务端部署全是错的。正确做法是 headroom proxy --port <port> 独立常驻,goosed 的 provider base URL 指向它。

部署形态:独立 Python 进程(Python 3.10+)或 Dockerghcr.io/headroomlabs-ai/headroom:latest)。 不进 Portal 依赖树,不影响 release-portal-runtime-prod.sh 整包。

官方基准(工具调用相关)

Benchmark 类别 准确率 压缩率
BFCL Tools 97% 32%
SQuAD v2 QA 97% 19%
GSM8K Math ±0.000

BFCL 是唯一与 tool-call 保真度直接相关的项:32% 压缩下 97% 准确。即约 3% 的工具调用退化率——对 MeMind 的交付契约(Page Data、MindSpace publish)而言这不是可忽略的数字,必须按轮次类型分级启用。

硬约束(与现有回归守卫冲突,必须遵守)

要求 原因
HEADROOM_OUTPUT_SHAPER 必须保持 0(默认) 它会下调 thinking effortreasoning_effort / thinking.budget_tokens),直接冲突 check-goosed-v149-thinking-preservation.mjsdeepseek-no-think-proxy.mjs 的 reasoning 保留策略
headroom learn 禁止运行 会改写 CLAUDE.md / AGENTS.md,违反本仓库规则文件管理
headroom wrap 禁止使用 会安装 Serena、注入 agent 配置、启动交互会话
POST /admin/runtime-env 须限制为 loopback headroom 的运行时配置热更新端点,103 上不得暴露
页面生成 / code 任务轮次 首期排除 交付契约对 tool-call 保真度零容忍

开关MEMIND_HEADROOM_MODE = off | shadow | active,默认 off。 shadow 期用 HEADROOM_OUTPUT_HOLDOUT 留对照组,取 measured 而非 estimated 数据。

待验证项(Phase 1 前置)

  1. 多租户 —— 一个 proxy 服务多用户并发,CCR store 是 local-first,需实测请求级隔离无串档
  2. 保真度 —— 在 MeMind 真实轮次上复现 BFCL 级别准确率,特别是 edit_file / Page Data 工具链
  3. Python 3.10+ on 103 —— Mac Studio 环境确认;native wheel 覆盖 macOS Apple Silicon
  4. 失败降级 —— proxy 不可用时必须直连 provider,不得阻塞(对齐 fail-open 原则)

观测headroom doctor / headroom dashboard / headroom output-savings

回滚goosed provider base URL 指回原 providerproxy 进程独立停止,零代码残留。

1-B · 自研 mcp-result-compactor.mjs(备选,仅在 1-A 验证失败时启用)

  • compact(payload, { budget, kind }){ summary, handle, stats }
  • 全量存 Redis(复用现有 redis 依赖)+ TTL;无 Redis 时 fail-open 返回原始 payload
  • 新增 ctx_fetch(handle) 工具按需取回全量
  • 记录 rawBytes / sentBytes / savedRatio,对齐 context-mode 的 savings 计量口径

薄调用点

  • tkmind-search-mcp.mjs —— tkmind_read / tkmind_research / tkmind_research_status 结果过压缩器
  • tkmind-excel-mcp.mjs —— excel_report / excel_analyze 同理
  • capabilities.mjs —— available_tools 在开关开启时追加 ctx_fetch

开关MEMIND_MCP_COMPACT_MODE = off | shadow | active,默认 off。 shadow 只记录「本来会省多少」,不改返回值。

验证

node --test mcp-result-compactor.test.mjs          # 新增单测
node scripts/check-goosed-v149-web-smoke.mjs        # tkmind_search / read 路径
node scripts/check-goosed-v149-skills-smoke.mjs
node scripts/check-goosed-v149-memory-policy.mjs    # 守住 canary memory 硬锁
# 并在 stable 1.41 :18006 上重跑一遍,证明版本无关

回滚:单一 env 置 offMCP 返回原始 payload,零残留。

不碰tkmind-proxy.mjsserver.mjssession-reconcile.mjs


Phase 2 · Injection BudgetA 面 · 稳定性收益最大)

目标:在打开 memory injection 之前,先建立单一预算裁决与去重。

新增 context-budget.mjs

  • plan({ memories, temporal, goal, harness, skillPrompt, policy }){ blocks, droppedItems, totalChars, fingerprints }
  • 内容指纹去重,跨 Portal 编排块与 harness 条目
  • 硬上限 + 优先级降级:超预算时先丢什么有明确规则

薄调用点

  • chat-intent-router.mjs —— buildAgentOrchestrationAgentText 前置调用 budget
  • session-reconcile.mjs —— buildSessionMemoryEntries 输出经同一 budget 过滤
  • agent-run-gateway.mjs —— 新增 context_budget_resolved 事件,替代分散的 agent_memory_resolved / runtime_context_resolved 拼图

开关MEMIND_CONTEXT_BUDGET_MODE = off | shadow | active,默认 off

验证

node --test chat-intent-router.test.mjs             # 补预算/去重用例
node --test session-reconcile.test.mjs
node scripts/check-goosed-v149-session-reconcile.mjs
node scripts/check-goosed-v149-harness.mjs
node scripts/check-goosed-v149-memory-loop.mjs
node scripts/check-goosed-v149-memory-chat.mjs
node scripts/check-goosed-v149-memory-policy.mjs    # 必须仍然通过
node scripts/compare-goose-v149-memory-manifest.mjs # manifest 无 drift

硬约束Phase 2 不得打开 MEMORY_AGENT_INJECTION_MODE。预算层先建好、先 shadow 观测;打开 injection 是独立决策、独立审批。


Phase 3 · Recall Fusion + HybridA 面)

目标memory / temporal / episodic 三路召回合并排序,激活语义检索。

新增 recall-fusion.mjs:query 解析(时间 / 实体 / 关键词)→ 三路并行取候选 → 融合排序(借 zvec-grep 的 fuse 思路)→ 按预算截断 → 单一格式化。

薄调用点chat-intent-router.mjstemporal-recall-service/context-planner.mjs

可选:激活 memory-v2-pgvector.mjsresolve()write / compact 仍走 legacy,与现有设计一致)

验证

node --test memory-v2-runtime.test.mjs
npm run check:memory-v2-contracts -- --include-pgvector-adapter
node scripts/check-goosed-v149-memory-verbal-recall.mjs

依赖:Phase 2 预算层必须已就位,否则融合结果会直接撑爆上下文。


Phase 4 · Harness Plugin 化(A 面 · 重构 · 风险最高)

目标agent-run-gateway.mjs3235 行)拆成 core + plugin slots,借 Cordis 的 service / event / reversible-effect 模型。

新增 harness/

  • core.mjs —— context + service registry + lifecycle
  • plugins/memory.mjsplugins/context-budget.mjsplugins/skill-router.mjsplugins/goose-execution.mjsplugins/tool-gateway.mjsplugins/telemetry.mjs

方式纯行为等价重构,先不加任何新功能。每抽出一个 plugin 就跑全量 v149 smoke 对比,确认零行为变化再抽下一个。

验证node --test agent-run-gateway.test.mjs 全绿 + node scripts/check-goosed-v149-all.mjs 前后输出一致

时机1.49 完全闭环、Phase 1–3 已上生产并稳定运行之后。


Phase 5 · Personal KG(长期)

扩展 user-model-service/ 的 entity 抽取(Person / Project / Intent / Event),借 codebase-memory-mcp 的 node/edge schema 与增量 watcher 模型,复用 dormant 的 memory-v2-neo4j.mjs slot。独立灰度,不进主聊天路径直到有明确收益证据。

类比映射:

codebase-memory-mcp MeMind Personal KG
Repository User Life Stream
Tree-sitter AST Event Parser(聊天 / 输入法 / 日历 / Agent trace
Function / Class 节点 Person / Project / Intent / Event 节点
CALLS 边 RELATES_TO / MENTIONED / SCHEDULED
get_architecture get_user_context_snapshot

Phase 6 · PAIR Compute Fabric(基础设施 · 可并行)

103 / 105 / home lab 试点 PAIR clusterGoose provider 与 Direct Chat 指向 PAIR 的 OpenAI-compatible endpoint。

关键约束(PAIR 官方明确)PAIR 按请求路由到单节点,不做显存池化、不跨机分片模型。大模型仍须单节点放得下。它解决的是并发请求分发。

与 Phase 1–4 无代码耦合,可独立试点。但涉及 provider 配置(受保护路径),需单独 Gate。


5. Phase 0 分类处置清单

5.1 Memind 主 worktree163 项)

A 组 · v1.49 核心交付(应提交)

已跟踪修改,与 4 个未推送 commit 同属 v149 canary 工作:

agent-run-gateway.mjs                          session-reconcile.mjs
chat-intent-router.mjs                         session-reconcile.test.mjs
chat-intent-router-rules.mjs                   tkmind-proxy.mjs
chat-intent-router.test.mjs                    goose-message.mjs
chat-skills.mjs                                memory-v2-runtime.mjs
chat-skills.test.mjs                           memory-v2-runtime.test.mjs
scripts/agent-run-worker.mjs
scripts/check-goosed-v149-all.mjs              scripts/check-goosed-v149-local.mjs
scripts/check-goosed-v149-memory-policy.mjs    scripts/check-goosed-v149-portal-resume.mjs
scripts/check-goosed-v149-portal-smoke.mjs     scripts/check-goosed-v149-session-reconcile.mjs
scripts/compare-goose-v149-message-sanitize.mjs
scripts/goose-v149-canary.mjs
scripts/run-goosed-v149-phase2.mjs             scripts/run-goosed-v149-phase3.mjs

未跟踪新文件,同属 v149 交付:

goose-canary-memory-policy.mjs
scripts/check-goosed-v149-memory-chat.mjs
scripts/check-goosed-v149-memory-verbal-recall.mjs
scripts/check-goosed-v149-multiturn-provider.mjs
scripts/check-goosed-v149-no-think-evidence.mjs
scripts/check-goosed-v149-page-data-evidence.mjs
scripts/check-goosed-v149-page-e2e.mjs
scripts/check-goosed-v149-session-affinity-evidence.mjs
scripts/check-goosed-v149-wechat-evidence.mjs
scripts/goose-v149-check-result.mjs
scripts/goose-v149-check-result.test.mjs
scripts/goose-v149-source-baseline.mjs
scripts/run-goosed-v149-missing-evidence.mjs

处置:与现有 4 commit 一并整理为 v149 收口提交。

B 组 · 与 v1.49 无关,需独立决策

scheduled-task-executor.mjs        scheduled-task-executor.test.mjs
scheduled-task-worker.mjs
user-auth.mjs                      user-auth.test.mjs
wechat-intent-router.test.mjs      wechat/intent/patterns.mjs

处置:这 7 项混在 v149 分支里会污染 v149 的可追溯性。建议评估能否单独成 commit,或确认它们确实是 v149 适配的必要副产物。

C 组 · 一次性运维脚本(建议不入库或移出)

scripts/deploy-yaodingdang-teacher-day-103.mjs
scripts/reactivate-icyxu-medication-reminder-103.mjs
scripts/multiturn-ping-custom.mjs
scripts/multiturn-ping-debug.mjs
scripts/multiturn-ping-single.mjs
scripts/assets/hulunbeier-travel-guide-202609.html
scripts/assets/shenmei-teacher-day-tribute-2026.html

处置:一次性投放 / 调试脚本与页面资产。建议移到仓库外或明确归档位置,避免长期堆积在 scripts/

D 组 · 临时探针(应删除)

tmp-probe-run.mjs

E 组 · Baseline 证据文件(109 未跟踪 + 已跟踪 18 个时间戳文件)

实测:

数量
docs/baselines/ 总文件 132
已跟踪 24
未跟踪 109
目录体积 3.7 MB
.gitignore baseline 规则

docs/baselines/README.md 列出的语义基线-latest.json-current.json 系列:

goose-v149-memory-latest.json
goose-v149-memory-current.json
goose-v149-message-sanitize-latest.json
goose-v149-thinking-preservation-latest.json
goose-v149-runtime-baseline-*.json

*-evidence-2026-*.json每次 smoke 的一次性产物。当前已有 9 个 cost-evidence + 9 个 deepseek-tools-evidence 被跟踪(推测是早期误入库),另有 109 个未跟踪。

建议处置

  1. .gitignore 增加 docs/baselines/*-evidence-*.json
  2. 保留 -latest / -current / runtime-baseline 作为可追溯语义基线
  3. 已误入库的 18 个时间戳 evidence 文件评估是否 git rm --cached
  4. scripts/check-goosed-v149-all.mjs 已有 refreshMemoryBaselineAfterSmoke() 自动刷新 -latest,与上述策略一致

注意:docs/production-release-guardian.md 的 Gate report 需要与 commit / runtime artifact 绑定的证据。移除 evidence 入库前,须确认 Gate 不依赖这些时间戳文件在 Git 中的存在。

5.2 health-p0 worktree95 项)

worktree: /Users/john/Project/Memind-health-p0
branch:   feature/memind-health-p0
dirty:    9536 M + 59 ??
领先:      2 commithealth channel kernel + H5 health page/WeChat/observation API
落后:      origin/main 20 commit

AGENTS.md 规则 3,需要明确处置:完成闭环并入 main,或登记为「禁止再次引用」后删除 worktree。落后 20 commit 意味着不能直接作为合并来源。

这是唯一必须先做决策的项——两个 worktree 并存本身就阻断新分支创建。


6. 外部项目引入方式

核心结论:五个 repo 中四个可以直接安装并挂进 MeMind 运行时。 唯一卡点是 context-mode 的 ELv2 许可证,且那是商务/法务决策而非工程问题。

「借架构自研」只应用在没有现成项目可装的地方,而那个范围比初版方案估计的小得多(见 6.5)。

6.1 为什么直接挂载是可行的

MeMind 的 Goose extension 机制本来就是通用 stdio MCP 挂载点capabilities.mjs 约 808850 行):

extensions.push({
  type: 'stdio',
  name: 'tkmind-search',
  bundled: false,
  cmd: resolveSandboxMcpNodeExecPath(...),
  args: [ ...mcpServerPath ],
  envs: { TKMIND_SEARCH_USER_ID: userId, ... },   // ← per-user env 注入
  available_tools: ['tkmind_search', 'tkmind_read'],  // ← 生效的工具白名单
});

三个关键事实使直接挂载成立:

事实 依据 解决的疑虑
extension 按用户/会话动态构建,可注入 per-user env TKMIND_SEARCH_USER_IDMINDSPACE_WORKSPACE_ROOT 现成先例 多租户隔离
available_tools 是生效白名单 makeExtension('platform','developer',['read_image']);AGENTS.md「带图轮次必须摘掉 read_image 危险工具可摘除
Node ≥ 22.5 自动用内置 node:sqlite context-mode README;本机 Node v26 无原生编译依赖

6.2 逐项决策(修正版)

Repo License 决策 落点
headroomlabs-ai/headroom Apache 2.0 直接装(Phase 1 选定) provider proxygoosed → headroom → LLM
DeusData/codebase-memory-mcp MIT 直接装 ① Cursor 开发工具;② 挂给 code 任务(tool-gateway aider/openhands 路径)
zvec-ai/zvec-grep Apache 2.0 直接装 ① Cursor 开发工具;② 挂给用户 workspace 检索
deepseek-ai/deepseek-harness MIT 直接装(改用法) 作为第 4 个 code executor 并列,不是替换 goosed
NVIDIA/Personal-AI-Router Apache 2.0 直接装 Phase 6 基础设施,103/105/home lab
mksglu/context-mode ELv2 产品集成排除 见 6.4;仅可作个人开发工具
Open330/context-compress 标称 MIT 不采用 见 6.4 许可证风险

6.3 deepseek-harness 用法修正

初版按「替换 goosed」评估,成本极高。但 MeMind 已是多 executor 架构:

// tool-gateway.mjs
const BASE_CODE_EXECUTORS = ['aider', 'openhands'];
// cursor 后加入,走同一套 selectExecutor + launch plan + env 开关

cursor 就是后加进来的。dsh 是同一模式,不是重写 harness

  • codeExecutorsForEnv() 增加 dsh,默认关闭
  • MEMIND_TOOL_GATEWAY_DSH_TASK_TYPES 按 task type 路由
  • 复用现有 assertRequiredCodeExecutorAvailable 与 fallback 机制

风险:dsh 处于 developer preview,官方声明会有 breaking changes。对策:默认关闭 + 按 task type 白名单 + 现有 executor fallback 路径。

6.4 context-mode 排除决策(已定)

ELv2 限制条款原文:

You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software.

已决策(2026-09-09:MeMind 是带计费的托管服务(tkmind.cn / 103 生产 / h5 用户),其 ctx_* 能力经 Agent 提供给付费用户,属于产品功能,因此落入 ELv2 禁止范围。

结论

  • context-mode 排除于 MeMind 产品集成,不得挂进 goosed、不得进入任何 103 部署
  • 个人本机开发工具用途属 ELv2 许可的 use,不受限
  • 不得将其源码或实现逻辑抄进 MeMind。ELv2 允许 derivative works,但要求「anyone who gets a copy of any part of the software from you also gets a copy of these terms」——抄代码会让 MeMind 相关部分继承 ELv2
  • 自研 1-B 时只可参考其 README / 公开 benchmark 层面的概念sandbox、handle、FTS5+BM25 检索),不读实现、不照搬结构

Open330/context-compress 同样排除:其 README 自述「Based on context-mode」,却标称 MIT。ELv2 衍生作品要求传递原条款,将其重新许可为 MIT 的合法性存疑。且该仓库仅 1 star,无生产可信度。

替代方案headroomApache 2.0),见 6.4.1。

6.4.1 为什么 headroom 是更优解

维度 context-mode headroom
License ELv2(与托管服务冲突) Apache 2.0
Goose 支持 官方兼容矩阵
拦截点 MCP 工具层 LLM 请求层
Goose 无 hook 时节省 ~60% 不受 hook 限制
需改 Goose 通用覆盖需 fork 不需要
部署 Node 进程 独立 Python 进程 / Docker
Stars 21.4K 67.5K

关键优势是拦截点更靠后proxy 拦 LLM 请求,覆盖 goosed 内部已累积的全部上下文,包括上游 platform/developerplatform/web 等 MeMind 不拥有的工具输出。这正是 1.1 节标记为「C 路需 fork Goose」的部分,headroom 用 proxy 位置直接解决。

风险与硬约束见第 4 节 Phase 1-A。

6.5 仍需自研的范围

只剩 Injection Budget + Recall FusionPhase 2 + Phase 3)。 Phase 1 已由 headroom 覆盖。

原因:这两项要做的是「把 MySQL h5_user_memory_items 的 legacy memory + temporal-recall-service 时间线 + episodic-memory 三路合并去重、按 token 预算裁决,并同时约束 Portal 编排块与 /agent/harness_remember 两条注入路」。

这是 MeMind 特有的数据形状与特有的双注入拓扑。外部项目不知道 h5_user_memory_items/agent/harness_remember 的存在,无法替代。

Phase 4Harness plugin 化)仍是自研重构,但优先级可下调——若 dsh 作为 executor 验证顺利,其 Cordis 模型的价值可先在小范围观察。

6.6 开发工具安装(Phase 0 之后)

装在本机、不触碰 MeMind 运行时,不受发布闸门约束,但建议 Phase 0 清理完成后再装,避免在脏工作区引入配置变更。

# zvec-grepApache 2.0Node ≥22,本机 v26 满足)
npm install -g @zvec/zvec-grep
cd /Users/john/Project/Memind
zg index --embedding local/potion-retrieval-32m       # 索引落在 .zvec-grep/

# codebase-memory-mcpMIT,原生二进制)
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
# 重启 Cursor 后对 agent 说 "Index this project"

必须同时处理

  • 两者都在项目根写索引目录(.zvec-grep/ 等),需加 .gitignore
  • codebase-memory-mcpinstall改写 ~/.cursor 下的 MCP 配置,这是其设计意图,安装前应知情

6.7 明确不做的事

  • dsh 替换 goosed —— 生产路径是 Goose + tkmind-proxy;作为并列 executor 可以,替换不行
  • codebase-memory-mcp 用于个人生活流 —— 它是 162 语言 tree-sitter parser,只适用于代码库;个人 KGPhase 5)只借其 schema 思想
  • zvec-grep 当个人记忆主检索 —— 它是 workspace/file 导向;「我这周有什么重要事情」必须走 Personal Retrieval
  • 向端用户暴露 ctx_execute 或任何任意代码执行工具 —— 必须经 available_tools 白名单摘除
  • 指望 PAIR 做显存池化 —— 官方明确不支持
  • context-mode 或其衍生实现引入 MeMind 产品(ELv2,已决策排除)
  • 使用 headroom wrap —— 会安装 Serena、注入 agent 配置、启动交互会话
  • 运行 headroom learn —— 会改写 CLAUDE.md / AGENTS.md
  • 开启 HEADROOM_OUTPUT_SHAPER —— 会下调 thinking effort,冲突 reasoning 保留守卫

7. 收益与风险

收益

机制
上下文污染可控 单一预算裁决 + 指纹去重,替代四套并行注入
token 成本下降 B 面 MCP 自压缩,直接减少 goosed 输入
可观测性 单条 context_budget_resolved trace 替代分散事件拼图
回滚粒度 每期一个 env 开关,独立回滚
主干可维护 3235 行 gateway 拆成可测 plugin

风险与对策

风险 对策
重构引入回归 Phase 4 严格行为等价,逐个 plugin 抽取 + 全量 smoke 前后对比
与 1.49 迁移互相干扰 A / B 面强制版本无关,在 stable 1.41 上独立验证
破坏 canary memory 硬锁 每期必跑 check-goosed-v149-memory-policy.mjs
触发大范围 Impact Gate 优先改非保护路径;Phase 1 完全避开保护清单
压缩丢关键信息 shadow 期只观测;ctx_fetch 保留全量取回
新增原生依赖污染整包 存储复用 Redis / PG,禁止引入 SQLite 原生模块

8. 待决策项

  1. health-p0 worktree 处置 —— 闭环入 main 还是登记禁用后删除(阻断所有后续工作)
  2. B 组 7 个非 v149 文件 —— 是否单独成 commit
  3. E 组 evidence 文件策略 —— .gitignore + 已入库 18 个是否 git rm --cached(须先确认 Gate 不依赖)
  4. 是否接受 A / B 面不等 1.49 —— Phase 13 在 stable 1.41 上做完并可独立上生产
  5. context-mode 的 ELv2 许可证 —— 已决策 2026-09-09:属产品功能,排除;Phase 1 改用 headroomApache 2.0
  6. dsh 是否作为第 4 个 code executor 引入 —— developer preview 风险 vs 快速验证 Cordis 模型
  7. headroom 保真度门槛 —— BFCL 显示 32% 压缩下 97% 准确,约 3% 工具调用退化。需定义 MeMind 可接受阈值与分级启用范围(首期建议排除页面生成与 code 任务)

9. 变更记录

日期 变更
2026-09-09 初版:五 repo 评估,结论「零个进产品运行时」
2026-09-09 修正一:四个可直接装。原生依赖、多租户、dsh 用法三处判断错误已纠正
2026-09-09 修正二:context-mode 按 ELv2 排除产品集成;Phase 1 改为 headroom provider proxy
2026-09-09 Phase 0 推进:.gitignore 排除 *-evidence-*.jsonmultiturn smoke 默认超时 90s→300s