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>
34 KiB
Context Runtime + Agent Harness 融合实施方案
状态:方案已定稿;Context Runtime Phase 1–6 尚未授权产品代码改动。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 约 808–877 行):
tkmind-search→tkmind-search-mcp.mjs(tkmind_search/tkmind_read/tkmind_research)tkmind-excel→tkmind-excel-mcp.mjs(excel_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.mjs、server.mjs、wechat-mp.mjs、session-reconcile.mjs 等。改动这些会触发 Core + Impact Gate 的影响域展开。
tkmind-search-mcp.mjs / tkmind-excel-mcp.mjs 不在保护清单内,验证成本低一个量级。这是 B 路优先的第二个理由。
1.3 现有技术栈约束
- MCP 协议为手写 stdio JSON-RPC(
tkmind-search-mcp.mjs用node: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-canary,4 个 commit 未进origin/main docs/goose-v149-phase3-closeout.md:Phase 3 收口,本阶段不授权 103/105 操作- 生产仍是 1.41 stable(
:18006–:18014),1.49 仅本地 loopback:18049 goose-canary-memory-policy.mjs硬锁 canary 期 memory 为 legacy,vector / 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 已在本仓库验证过的形状,不另创范式:
- 旁挂不改主干 —— 新增独立模块,主干只加薄调用点
- 默认全关 —— 所有开关默认
off,env +memind_adm双控 - fail-open —— 新层任何异常退回现有行为,绝不阻塞
- shadow 先行 —— 先只观测记录不改行为,拿到证据再 canary → active
- 版本无关 —— A / B 面不引用任何 v149-only 接口
- 不新增原生依赖 —— 存储复用 Redis / PG
3. 目标架构
User → agent-run-routes
│
┌─────┴───────────────────────────────────┐
│ Context Runtime(新增,A 面) │
│ · Injection Budget 统一 token 预算 │
│ · Recall Fusion 三路召回合并去重 │
│ · Trace 单一可观测事件 │
└─────┬───────────────────────────────────┘
│
Agent Harness(重构 agent-run-gateway,A 面)
│
tkmind-proxy → goosed
│
┌─────┴──────────────────────┐
│ MeMind 自有 MCP(B 面) │
│ · Result Compaction │
│ · handle + ctx_fetch │
└────────────────────────────┘
│
Compute Fabric(PAIR,Phase 6)
落点对照
| 新能力 | 新增模块 | 薄调用点(现有文件) | 受保护路径 |
|---|---|---|---|
| Tool Result 压缩 | mcp-result-compactor.mjs |
tkmind-search-mcp.mjs、tkmind-excel-mcp.mjs、capabilities.mjs |
否 |
| Injection Budget | context-budget.mjs |
chat-intent-router.mjs、session-reconcile.mjs、agent-run-gateway.mjs |
部分 |
| Recall Fusion | recall-fusion.mjs |
chat-intent-router.mjs、temporal-recall-service/context-planner.mjs |
否 |
| Harness plugin 化 | harness/ 目录 |
agent-run-gateway.mjs(3235 行拆分) |
否 |
| 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约 310–337 行 →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_FAIL(multiturn / page-e2e 超时;Phase 3 段 portal-resume 已通过) |
| health-p0 dirty | 95(36 M + 59 ??) |
| health-p0 | 领先 2 commit,落后 origin/main 20 commit |
详见第 5 节分类处置清单。
产出:干净 worktree、单一分支、origin/main 已同步。
闸门:node scripts/run-goosed-v149-phase3.mjs → GOOSE_V149_PHASE3_OK;push / 合 main 须取得明确批准。
Phase 1 · Tool Result 压缩(B 面 · 版本无关 · 优先级最高)
目标:降低 goosed context 与 token 成本。
已决策路线:headroom 独立 proxy 模式(Apache 2.0)。决策依据见 6.4。
1-A · headroom provider proxy(选定方案)
为什么是 proxy 而非 MCP:headroom 的 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+)或 Docker(ghcr.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 effort(reasoning_effort / thinking.budget_tokens),直接冲突 check-goosed-v149-thinking-preservation.mjs 与 deepseek-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 前置):
- 多租户 —— 一个 proxy 服务多用户并发,CCR store 是 local-first,需实测请求级隔离无串档
- 保真度 —— 在 MeMind 真实轮次上复现 BFCL 级别准确率,特别是
edit_file/ Page Data 工具链 - Python 3.10+ on 103 —— Mac Studio 环境确认;native wheel 覆盖 macOS Apple Silicon
- 失败降级 —— proxy 不可用时必须直连 provider,不得阻塞(对齐 fail-open 原则)
观测:headroom doctor / headroom dashboard / headroom output-savings
回滚:goosed provider base URL 指回原 provider,proxy 进程独立停止,零代码残留。
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 置 off,MCP 返回原始 payload,零残留。
不碰:tkmind-proxy.mjs、server.mjs、session-reconcile.mjs。
Phase 2 · Injection Budget(A 面 · 稳定性收益最大)
目标:在打开 memory injection 之前,先建立单一预算裁决与去重。
新增 context-budget.mjs:
plan({ memories, temporal, goal, harness, skillPrompt, policy })→{ blocks, droppedItems, totalChars, fingerprints }- 内容指纹去重,跨 Portal 编排块与 harness 条目
- 硬上限 + 优先级降级:超预算时先丢什么有明确规则
薄调用点:
chat-intent-router.mjs——buildAgentOrchestrationAgentText前置调用 budgetsession-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 + Hybrid(A 面)
目标:memory / temporal / episodic 三路召回合并排序,激活语义检索。
新增 recall-fusion.mjs:query 解析(时间 / 实体 / 关键词)→ 三路并行取候选 → 融合排序(借 zvec-grep 的 fuse 思路)→ 按预算截断 → 单一格式化。
薄调用点:chat-intent-router.mjs、temporal-recall-service/context-planner.mjs
可选:激活 memory-v2-pgvector.mjs 的 resolve()(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.mjs(3235 行)拆成 core + plugin slots,借 Cordis 的 service / event / reversible-effect 模型。
新增 harness/:
core.mjs—— context + service registry + lifecycleplugins/memory.mjs、plugins/context-budget.mjs、plugins/skill-router.mjs、plugins/goose-execution.mjs、plugins/tool-gateway.mjs、plugins/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 cluster,Goose provider 与 Direct Chat 指向 PAIR 的 OpenAI-compatible endpoint。
关键约束(PAIR 官方明确):PAIR 按请求路由到单节点,不做显存池化、不跨机分片模型。大模型仍须单节点放得下。它解决的是并发请求分发。
与 Phase 1–4 无代码耦合,可独立试点。但涉及 provider 配置(受保护路径),需单独 Gate。
5. Phase 0 分类处置清单
5.1 Memind 主 worktree(163 项)
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 个未跟踪。
建议处置:
.gitignore增加docs/baselines/*-evidence-*.json- 保留
-latest/-current/runtime-baseline作为可追溯语义基线 - 已误入库的 18 个时间戳 evidence 文件评估是否
git rm --cached 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 worktree(95 项)
worktree: /Users/john/Project/Memind-health-p0
branch: feature/memind-health-p0
dirty: 95(36 M + 59 ??)
领先: 2 commit(health 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 约 808–850 行):
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_ID、MINDSPACE_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 proxy,goosed → 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,无生产可信度。
替代方案:headroom(Apache 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/developer、platform/web 等 MeMind 不拥有的工具输出。这正是 1.1 节标记为「C 路需 fork Goose」的部分,headroom 用 proxy 位置直接解决。
风险与硬约束见第 4 节 Phase 1-A。
6.5 仍需自研的范围
只剩 Injection Budget + Recall Fusion(Phase 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 4(Harness plugin 化)仍是自研重构,但优先级可下调——若 dsh 作为 executor 验证顺利,其 Cordis 模型的价值可先在小范围观察。
6.6 开发工具安装(Phase 0 之后)
装在本机、不触碰 MeMind 运行时,不受发布闸门约束,但建议 Phase 0 清理完成后再装,避免在脏工作区引入配置变更。
# zvec-grep(Apache 2.0,Node ≥22,本机 v26 满足)
npm install -g @zvec/zvec-grep
cd /Users/john/Project/Memind
zg index --embedding local/potion-retrieval-32m # 索引落在 .zvec-grep/
# codebase-memory-mcp(MIT,原生二进制)
curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash
# 重启 Cursor 后对 agent 说 "Index this project"
必须同时处理:
- 两者都在项目根写索引目录(
.zvec-grep/等),需加.gitignore codebase-memory-mcp的install会改写~/.cursor下的 MCP 配置,这是其设计意图,安装前应知情
6.7 明确不做的事
- ❌ 用
dsh替换 goosed —— 生产路径是 Goose +tkmind-proxy;作为并列 executor 可以,替换不行 - ❌ 把
codebase-memory-mcp用于个人生活流 —— 它是 162 语言 tree-sitter parser,只适用于代码库;个人 KG(Phase 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. 待决策项
- health-p0 worktree 处置 —— 闭环入 main 还是登记禁用后删除(阻断所有后续工作)
- B 组 7 个非 v149 文件 —— 是否单独成 commit
- E 组 evidence 文件策略 ——
.gitignore+ 已入库 18 个是否git rm --cached(须先确认 Gate 不依赖) - 是否接受 A / B 面不等 1.49 —— Phase 1–3 在 stable 1.41 上做完并可独立上生产
—— 已决策 2026-09-09:属产品功能,排除;Phase 1 改用context-mode的 ELv2 许可证headroom(Apache 2.0)dsh是否作为第 4 个 code executor 引入 —— developer preview 风险 vs 快速验证 Cordis 模型- 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-*.json;multiturn smoke 默认超时 90s→300s |