Merge branch 'feature/goose-v149-local-canary'
Memind CI / Test, build, and release guards (push) Has been cancelled
Memind CI / Test, build, and release guards (push) Has been cancelled
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,16 @@
|
||||
# Goose v1.49 Phase 0 本地基线
|
||||
|
||||
本目录存放 loopback 升级对照用的 JSON 基线,**不含生产密钥**。
|
||||
|
||||
| 文件 | 生成命令 |
|
||||
|---|---|
|
||||
| `goose-v149-memory-latest.json` | `node scripts/export-goose-v149-memory-manifest.mjs --output docs/baselines/goose-v149-memory-latest.json` |
|
||||
| `goose-v149-runtime-baseline-*.json` | `node scripts/capture-goose-v149-baseline.mjs` |
|
||||
| `goose-v149-cost-evidence-*.json` | `node scripts/check-goosed-v149-cost-smoke.mjs` |
|
||||
| `goose-v149-deepseek-tools-evidence-*.json` | `node scripts/check-goosed-v149-deepseek-tools.mjs` |
|
||||
| `goose-v149-thinking-preservation-latest.json` | `node scripts/check-goosed-v149-thinking-preservation.mjs` |
|
||||
| `goose-v149-message-sanitize-latest.json` | `node scripts/compare-goose-v149-message-sanitize.mjs` |
|
||||
|
||||
Phase 3 收口:[goose-v149-phase3-closeout.md](../goose-v149-phase3-closeout.md) · 聚合:`node scripts/run-goosed-v149-phase3.mjs`
|
||||
|
||||
**Git 策略**:只跟踪语义基线(`*-latest.json`、`*-current.json`、`runtime-baseline-*.json`)。每次 smoke 生成的时间戳 `*-evidence-*.json` 已写入根目录 `.gitignore`,勿提交。
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T10:06:59.003Z",
|
||||
"sessionId": "20260908_30",
|
||||
"requestId": "b0ee6f3f-cedc-470c-84cd-925b83c3c131",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8339,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8341,
|
||||
"accumulatedInputTokens": 8339,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8341,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8339,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.0022537300000000002
|
||||
},
|
||||
"enrichedCost": 0.0022537300000000002
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T10:07:14.546Z",
|
||||
"sessionId": "20260908_37",
|
||||
"requestId": "4c558b69-64e3-4909-9e33-1cb598a00cc2",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8339,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8341,
|
||||
"accumulatedInputTokens": 8339,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8341,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8339,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.0022537300000000002
|
||||
},
|
||||
"enrichedCost": 0.0022537300000000002
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T10:30:13.352Z",
|
||||
"sessionId": "20260908_50",
|
||||
"requestId": "752da410-df43-44c6-9958-2c23f3d948ae",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8339,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8341,
|
||||
"accumulatedInputTokens": 8339,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8341,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8339,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.0022537300000000002
|
||||
},
|
||||
"enrichedCost": 0.0022537300000000002
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T11:12:36.359Z",
|
||||
"sessionId": "20260908_66",
|
||||
"requestId": "ba50d32c-5024-4b77-8372-cf6ea1c5eaf0",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8339,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8341,
|
||||
"accumulatedInputTokens": 8339,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8341,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8339,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.0022537300000000002
|
||||
},
|
||||
"enrichedCost": 0.0022537300000000002
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T11:19:29.723Z",
|
||||
"sessionId": "20260908_79",
|
||||
"requestId": "388a1d9e-6edb-413a-bd49-9d602e3132d0",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8586,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8588,
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8588,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.00232042
|
||||
},
|
||||
"enrichedCost": 0.00232042
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T12:07:15.664Z",
|
||||
"sessionId": "20260908_94",
|
||||
"requestId": "f72ff3fd-413f-4c80-b671-1d4f15d1ecf1",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8586,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8588,
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8588,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.00232042
|
||||
},
|
||||
"enrichedCost": 0.00232042
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T12:23:16.640Z",
|
||||
"sessionId": "20260908_109",
|
||||
"requestId": "a9365f33-add9-45f3-8512-6a5554e85194",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8586,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8588,
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8588,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.00232042
|
||||
},
|
||||
"enrichedCost": 0.00232042
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T12:32:49.137Z",
|
||||
"sessionId": "20260908_124",
|
||||
"requestId": "b31d65ea-e68a-4a7b-a47b-89b3d365afa2",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8586,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8588,
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8588,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.00232042
|
||||
},
|
||||
"enrichedCost": 0.00232042
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-cost-evidence-v1",
|
||||
"capturedAt": "2026-09-08T13:06:15.865Z",
|
||||
"sessionId": "20260908_141",
|
||||
"requestId": "d85df70e-9d1d-45d1-9408-96dbff9d5c96",
|
||||
"finishReason": "stop",
|
||||
"tokenState": {
|
||||
"inputTokens": 8586,
|
||||
"outputTokens": 2,
|
||||
"totalTokens": 8588,
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedTotalTokens": 8588,
|
||||
"accumulatedCost": null
|
||||
},
|
||||
"billingState": {
|
||||
"accumulatedInputTokens": 8586,
|
||||
"accumulatedOutputTokens": 2,
|
||||
"accumulatedCost": 0.00232042
|
||||
},
|
||||
"enrichedCost": 0.00232042
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T12:07:03.092Z",
|
||||
"sessionId": "20260908_84",
|
||||
"requestId": "24118cbb-ebe9-4f0f-9b8c-59a71cbbad28",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T12:07:06.888Z",
|
||||
"sessionId": "20260908_89",
|
||||
"requestId": "cbdfc7d5-48ee-4fe9-acf1-dd08bbba27b2",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T12:07:18.952Z",
|
||||
"sessionId": "20260908_96",
|
||||
"requestId": "23c5fcf6-e15a-4880-b0d1-c9fd0073c419",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T12:23:05.066Z",
|
||||
"sessionId": "20260908_104",
|
||||
"requestId": "c5f423b5-9dc0-474e-898c-a472a935386e",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T12:23:19.758Z",
|
||||
"sessionId": "20260908_112",
|
||||
"requestId": "0f40ec62-b124-4288-9518-040c4550e329",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T12:32:37.309Z",
|
||||
"sessionId": "20260908_119",
|
||||
"requestId": "3e3c39f4-6165-4e40-9b0a-d4785c969851",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T12:32:51.717Z",
|
||||
"sessionId": "20260908_127",
|
||||
"requestId": "8c1f27ac-e8c1-47c8-8835-9ae27d217adb",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T13:04:37.865Z",
|
||||
"sessionId": "20260908_135",
|
||||
"requestId": "c1360188-7f59-41e3-ba43-689fa8f7be1d",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-deepseek-tools-v1",
|
||||
"capturedAt": "2026-09-08T13:06:18.709Z",
|
||||
"sessionId": "20260908_144",
|
||||
"requestId": "328356c3-25b6-4d15-bd18-206dd7c803aa",
|
||||
"providerId": "custom_tkmind_relay_deepseek",
|
||||
"model": "deepseek-chat",
|
||||
"toolNames": [
|
||||
"todo__todo_write"
|
||||
],
|
||||
"finishReason": "stop",
|
||||
"eventTypes": [
|
||||
"Message",
|
||||
"Message",
|
||||
"Message",
|
||||
"Finish"
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-message-sanitize-v2",
|
||||
"capturedAt": "2026-09-09T13:35:24.843Z",
|
||||
"v149": {
|
||||
"root": "/Users/john/Project/tkmind_go-v149",
|
||||
"version": "1.49.0",
|
||||
"commit": "30dd3a4d2b2ef490a1b2d5cdf925d973eea3da75",
|
||||
"dirty": true,
|
||||
"passed": 11,
|
||||
"tests": [
|
||||
"openai::tests::sanitize_meta_applies_reasoning_effort_from_thinking_effort",
|
||||
"openai::tests::sanitize_meta_clamps_off_thinking_effort_to_low",
|
||||
"openai::tests::sanitize_meta_maps_max_thinking_effort_to_xhigh",
|
||||
"openai::tests::sanitize_meta_omits_reasoning_effort_when_unset",
|
||||
"openai::tests::sanitize_nearai_preserves_openai_reasoning_effort",
|
||||
"openai::tests::sanitize_nearai_reasoning_chat_params",
|
||||
"openai::tests::sanitize_no_token_params",
|
||||
"openai::tests::sanitize_noop_for_native_openai_provider",
|
||||
"openai::tests::sanitize_noop_for_unknown_provider",
|
||||
"openai::tests::sanitize_preserves_existing_max_tokens_for_compat_provider",
|
||||
"openai::tests::sanitize_remaps_max_completion_tokens_for_compat_provider"
|
||||
]
|
||||
},
|
||||
"v141": {
|
||||
"passed": 11,
|
||||
"ok": true,
|
||||
"root": "/Users/john/Project/tkmind_go-v141-prod-prep",
|
||||
"reused": true,
|
||||
"reuseReason": "v1.41 worktree sanitize compile failed; prior evidence retained"
|
||||
},
|
||||
"regressionSuitesPassed": true,
|
||||
"equivalent": null,
|
||||
"limitation": "Independent regression suites do not prove cross-version behavior equivalence. Keep Portal sanitize until shared-fixture parity is verified."
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-baseline-v1",
|
||||
"capturedAt": "2026-09-08T10:02:06.825Z",
|
||||
"target": "https://127.0.0.1:18049",
|
||||
"status": {
|
||||
"status": "ok"
|
||||
},
|
||||
"sessionsSummary": {
|
||||
"count": 20,
|
||||
"sample": [
|
||||
{
|
||||
"id": "20260908_20",
|
||||
"working_dir": "/Users/john/Project/Memind",
|
||||
"name": "pong",
|
||||
"user_set_name": false,
|
||||
"session_type": "user",
|
||||
"created_at": "2026-09-08T10:02:00.279689Z",
|
||||
"updated_at": "2026-09-08T10:02:02.146310Z",
|
||||
"extension_data": {
|
||||
"enabled_extensions.v0": {
|
||||
"extensions": [
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "tom",
|
||||
"description": "Inject custom context into every turn via GOOSE_MOIM_MESSAGE_TEXT and GOOSE_MOIM_MESSAGE_FILE environment variables",
|
||||
"display_name": "Top Of Mind",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "skills",
|
||||
"description": "Discover and provide skill instructions from filesystem and builtins",
|
||||
"display_name": "Skills",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "aider",
|
||||
"description": "Delegate multi-file coding tasks to Aider instead of developer write/edit",
|
||||
"display_name": "Aider",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "Extension Manager",
|
||||
"description": "Enable extension management tools for discovering, enabling, and disabling extensions",
|
||||
"display_name": "Extension Manager",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "developer",
|
||||
"description": "Write and edit files, and execute shell commands",
|
||||
"display_name": "Developer",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "summon",
|
||||
"description": "Load knowledge and delegate tasks to subagents",
|
||||
"display_name": "Summon",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "openhands",
|
||||
"description": "Delegate multi-file coding tasks to OpenHands instead of developer write/edit",
|
||||
"display_name": "OpenHands",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "apps",
|
||||
"description": "Create and manage custom Goose apps through chat. Apps are HTML/CSS/JavaScript and run in sandboxed windows.",
|
||||
"display_name": "Apps",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "analyze",
|
||||
"description": "Analyze code structure with tree-sitter: directory overviews, file details, symbol call graphs",
|
||||
"display_name": "Analyze",
|
||||
"bundled": true
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "todo",
|
||||
"description": "Enable a todo list for goose so it can keep track of what it is doing",
|
||||
"display_name": "Todo",
|
||||
"bundled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"usage": {
|
||||
"input_tokens": 8339,
|
||||
"output_tokens": 2,
|
||||
"total_tokens": 8341,
|
||||
"cache_read_input_tokens": 0,
|
||||
"cache_write_input_tokens": null
|
||||
},
|
||||
"accumulated_usage": {
|
||||
"input_tokens": 8339,
|
||||
"output_tokens": 2,
|
||||
"total_tokens": 8341,
|
||||
"cache_read_input_tokens": 0,
|
||||
"cache_write_input_tokens": 0
|
||||
},
|
||||
"accumulated_cost": null,
|
||||
"schedule_id": null,
|
||||
"recipe": null,
|
||||
"user_recipe_values": null,
|
||||
"conversation": null,
|
||||
"message_count": 3,
|
||||
"last_message_at": "2026-09-08T10:02:01Z",
|
||||
"provider_name": "custom_tkmind_relay_deepseek",
|
||||
"model_config": {
|
||||
"model_name": "deepseek-chat",
|
||||
"temperature": null,
|
||||
"max_tokens": null,
|
||||
"toolshim": false,
|
||||
"toolshim_model": null
|
||||
},
|
||||
"goose_mode": "auto",
|
||||
"archived_at": null,
|
||||
"project_id": null,
|
||||
"parent_session_id": null,
|
||||
"last_message_snippet": null
|
||||
},
|
||||
{
|
||||
"id": "20260908_19",
|
||||
"working_dir": "/Users/john/Project/Memind",
|
||||
"name": "New Chat",
|
||||
"user_set_name": false,
|
||||
"session_type": "user",
|
||||
"created_at": "2026-09-08T10:02:00.057531Z",
|
||||
"updated_at": "2026-09-08T10:02:00.064842Z",
|
||||
"extension_data": {
|
||||
"enabled_extensions.v0": {
|
||||
"extensions": [
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "openhands",
|
||||
"description": "OpenHands coding delegate",
|
||||
"display_name": null,
|
||||
"bundled": null,
|
||||
"available_tools": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "aider",
|
||||
"description": "Aider coding delegate",
|
||||
"display_name": null,
|
||||
"bundled": null,
|
||||
"available_tools": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"usage": {
|
||||
"input_tokens": null,
|
||||
"output_tokens": null,
|
||||
"total_tokens": null,
|
||||
"cache_read_input_tokens": null,
|
||||
"cache_write_input_tokens": null
|
||||
},
|
||||
"accumulated_usage": {
|
||||
"input_tokens": null,
|
||||
"output_tokens": null,
|
||||
"total_tokens": null,
|
||||
"cache_read_input_tokens": null,
|
||||
"cache_write_input_tokens": null
|
||||
},
|
||||
"accumulated_cost": null,
|
||||
"schedule_id": null,
|
||||
"recipe": null,
|
||||
"user_recipe_values": null,
|
||||
"conversation": null,
|
||||
"message_count": 0,
|
||||
"last_message_at": null,
|
||||
"provider_name": null,
|
||||
"model_config": null,
|
||||
"goose_mode": "auto",
|
||||
"archived_at": null,
|
||||
"project_id": null,
|
||||
"parent_session_id": null,
|
||||
"last_message_snippet": null
|
||||
},
|
||||
{
|
||||
"id": "20260908_18",
|
||||
"working_dir": "/Users/john/Project/Memind",
|
||||
"name": "New Chat",
|
||||
"user_set_name": false,
|
||||
"session_type": "user",
|
||||
"created_at": "2026-09-08T10:01:59.691171Z",
|
||||
"updated_at": "2026-09-08T10:01:59.885622Z",
|
||||
"extension_data": {
|
||||
"enabled_extensions.v0": {
|
||||
"extensions": [
|
||||
{
|
||||
"type": "stdio",
|
||||
"name": "sandbox-fs",
|
||||
"description": "MindSpace sandbox filesystem MCP (local v1.49 smoke)",
|
||||
"cmd": "/opt/homebrew/Cellar/node/26.0.0/bin/node",
|
||||
"args": [
|
||||
"/Users/john/Project/Memind/mindspace-sandbox-mcp.mjs",
|
||||
"/var/folders/wv/y43yzlmn7gd1bcsq1fcwx3b00000gn/T/goose-v149-sandbox-3ADPMS"
|
||||
],
|
||||
"envs": {
|
||||
"ALLOWED_TOOLS": "write_file,read_file,edit_file,create_dir,list_dir",
|
||||
"SANDBOX_ROOT": "/var/folders/wv/y43yzlmn7gd1bcsq1fcwx3b00000gn/T/goose-v149-sandbox-3ADPMS"
|
||||
},
|
||||
"env_keys": [],
|
||||
"timeout": null,
|
||||
"cwd": null,
|
||||
"bundled": null,
|
||||
"available_tools": [
|
||||
"write_file",
|
||||
"read_file",
|
||||
"edit_file",
|
||||
"create_dir",
|
||||
"list_dir"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "platform",
|
||||
"name": "skills",
|
||||
"description": "skills",
|
||||
"display_name": null,
|
||||
"bundled": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"usage": {
|
||||
"input_tokens": null,
|
||||
"output_tokens": null,
|
||||
"total_tokens": null,
|
||||
"cache_read_input_tokens": null,
|
||||
"cache_write_input_tokens": null
|
||||
},
|
||||
"accumulated_usage": {
|
||||
"input_tokens": null,
|
||||
"output_tokens": null,
|
||||
"total_tokens": null,
|
||||
"cache_read_input_tokens": null,
|
||||
"cache_write_input_tokens": null
|
||||
},
|
||||
"accumulated_cost": null,
|
||||
"schedule_id": null,
|
||||
"recipe": null,
|
||||
"user_recipe_values": null,
|
||||
"conversation": null,
|
||||
"message_count": 0,
|
||||
"last_message_at": null,
|
||||
"provider_name": null,
|
||||
"model_config": null,
|
||||
"goose_mode": "auto",
|
||||
"archived_at": null,
|
||||
"project_id": null,
|
||||
"parent_session_id": null,
|
||||
"last_message_snippet": null
|
||||
}
|
||||
]
|
||||
},
|
||||
"reply": {
|
||||
"requestId": "a53113c2-8462-4b6d-94f6-0303f6eebea5",
|
||||
"outcome": "error",
|
||||
"events": [
|
||||
{
|
||||
"type": "Error",
|
||||
"error": "Provider not set",
|
||||
"chat_request_id": "a53113c2-8462-4b6d-94f6-0303f6eebea5",
|
||||
"request_id": "a53113c2-8462-4b6d-94f6-0303f6eebea5"
|
||||
}
|
||||
],
|
||||
"sessionId": "20260908_21"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"schemaVersion": "goose-v149-thinking-preservation-v1",
|
||||
"capturedAt": "2026-09-09T13:47:20.080Z",
|
||||
"worktree": "/Users/john/Project/tkmind_go-v149",
|
||||
"tests": [
|
||||
"test_deepseek_thinking_preserved_in_tool_call_message",
|
||||
"test_kimi_thinking_preserved_in_tool_call_message",
|
||||
"test_reasoning_preserved_when_combined_with_tool_call",
|
||||
"test_multi_tool_response_preserves_reasoning_and_message_id_correlation"
|
||||
],
|
||||
"passed": 4
|
||||
}
|
||||
@@ -0,0 +1,688 @@
|
||||
# Context Runtime + Agent Harness 融合实施方案
|
||||
|
||||
> 状态:**方案已定稿;Context Runtime Phase 1–6 尚未授权产品代码改动**。v1.49 收口与 Phase 0 清理可并行推进(2026-09-09)。
|
||||
> 生成日期:2026-09-09
|
||||
> 关联规范:[AGENTS.md](../AGENTS.md) · [ENGINEERING_WORKFLOW_RULES.md](../ENGINEERING_WORKFLOW_RULES.md) · [PRODUCTION_RELEASE_RULES.md](../PRODUCTION_RELEASE_RULES.md) · [docs/production-release-guardian.md](./production-release-guardian.md)
|
||||
> 关联现状:[docs/memory-v2/README.md](./memory-v2/README.md) · [docs/goose-v149-phase3-closeout.md](./goose-v149-phase3-closeout.md) · [docs/goose-v149-canary-runbook.md](./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 已在本仓库验证过的形状,**不另创范式**:
|
||||
|
||||
1. **旁挂不改主干** —— 新增独立模块,主干只加薄调用点
|
||||
2. **默认全关** —— 所有开关默认 `off`,env + `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-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 前置)**:
|
||||
|
||||
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 指回原 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 只记录「本来会省多少」,不改返回值。
|
||||
|
||||
**验证**:
|
||||
|
||||
```bash
|
||||
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` 前置调用 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`。
|
||||
|
||||
**验证**:
|
||||
|
||||
```bash
|
||||
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,与现有设计一致)
|
||||
|
||||
**验证**:
|
||||
|
||||
```bash
|
||||
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 + lifecycle
|
||||
- `plugins/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 个未跟踪。
|
||||
|
||||
**建议处置**:
|
||||
|
||||
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 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 行):
|
||||
|
||||
```js
|
||||
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 架构:
|
||||
|
||||
```js
|
||||
// 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 清理完成后再装,避免在脏工作区引入配置变更。
|
||||
|
||||
```bash
|
||||
# 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. 待决策项
|
||||
|
||||
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 1–3 在 stable 1.41 上做完并可独立上生产
|
||||
5. ~~`context-mode` 的 ELv2 许可证~~ —— **已决策 2026-09-09**:属产品功能,排除;Phase 1 改用 `headroom`(Apache 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-*.json`;multiturn smoke 默认超时 90s→300s |
|
||||
@@ -0,0 +1,109 @@
|
||||
# Goose v1.49 本地 Canary 运行手册
|
||||
|
||||
> 范围:仅本机 loopback(`:18049` vs `:18006`),**禁止**连接 103/105 或修改生产 launchd。
|
||||
> 决策表:[TKMIND_V1_49_MIGRATION.md](../TKMIND_V1_49_MIGRATION.md)
|
||||
|
||||
## 架构
|
||||
|
||||
```text
|
||||
Portal (pnpm dev :8081)
|
||||
│
|
||||
├─ TKMIND_GOOSE_CANARY=off → TKMIND_API_TARGET=https://127.0.0.1:18006 (stable 1.41)
|
||||
├─ TKMIND_GOOSE_CANARY=all → TKMIND_API_TARGET=https://127.0.0.1:18049 (v1.49 候选)
|
||||
└─ TKMIND_GOOSE_CANARY=users → 双 target;canary 用户路由到 v1.49(需 USER_IDS)
|
||||
```
|
||||
|
||||
Memory 在 canary 期间保持 legacy owner(MySQL `h5_user_memory_items`),upstream goosed **不得**写入业务记忆。
|
||||
|
||||
## 前置条件
|
||||
|
||||
```bash
|
||||
bash scripts/build-goosed-v149-local.sh
|
||||
bash scripts/ensure-goose-v149-local-db.sh
|
||||
bash scripts/run-goosed-v149-local.sh # 另开终端,监听 :18049
|
||||
curl -sk https://127.0.0.1:18049/status # → ok
|
||||
```
|
||||
|
||||
## 一键开启 Canary(全量切到 v1.49)
|
||||
|
||||
```bash
|
||||
bash scripts/switch-goose-v149-canary.sh on all
|
||||
pnpm dev # 重启 Portal 以加载 .env.local
|
||||
node scripts/check-goosed-v149-canary-portal.mjs # 隔离 :8083 验证(不干扰主 Portal)
|
||||
```
|
||||
|
||||
> 已写入 `.env.local` canary 块。主 Portal `:8081` 须重启后才路由到 `:18049`。
|
||||
> v1.49 已移植 `platform/web`(`web_search` / `fetch_url`);验证:`node scripts/check-goosed-v149-web-smoke.mjs`。
|
||||
|
||||
脚本会在 `.env.local` 写入 `# GOOSE_V149_CANARY_BEGIN … END` 块,设置:
|
||||
|
||||
- `TKMIND_GOOSE_CANARY=all`
|
||||
- `TKMIND_API_TARGET=https://127.0.0.1:18049`
|
||||
- Memory 安全开关(legacy / vector off)
|
||||
- `H5_PUBLIC_BASE_URL=http://127.0.0.1:8081`(避免 Vite `:5173` 未起时页面链接失效)
|
||||
|
||||
## 按用户 Canary(双 target)
|
||||
|
||||
```bash
|
||||
export TKMIND_GOOSE_CANARY_USER_IDS="<your-user-uuid>"
|
||||
bash scripts/switch-goose-v149-canary.sh on users
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Portal 会注册 `[18006, 18049]` 双 target;canary 用户的新 session 应 pin 到 v1.49(见 `scripts/goose-v149-canary.mjs` + `release-gate/canary-routing.mjs`)。
|
||||
|
||||
## 一键回滚(回落 stable)
|
||||
|
||||
```bash
|
||||
bash scripts/switch-goose-v149-canary.sh rollback
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
回滚仅移除 canary 块,不删 v1.49 进程或 PG 库;stable `:18006` 保持可用。
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
# Phase 2 聚合(推荐日常)
|
||||
node scripts/run-goosed-v149-phase2.mjs
|
||||
|
||||
# Phase 3 收口(合并前)
|
||||
node scripts/run-goosed-v149-phase3.mjs
|
||||
|
||||
# 单项 / 全量 smoke
|
||||
node scripts/check-goosed-v149-all.mjs
|
||||
node scripts/check-goosed-v149-memory-loop.mjs
|
||||
node scripts/check-goosed-v149-portal-smoke.mjs # 主 Portal 重启后
|
||||
node scripts/check-goosed-v149-canary-portal.mjs # 隔离 :8083
|
||||
```
|
||||
|
||||
## Phase 0 基线采集
|
||||
|
||||
```bash
|
||||
# Runtime 样本(status / sessions / 可选 SSE reply)
|
||||
node scripts/capture-goose-v149-baseline.mjs
|
||||
|
||||
# Memory manifest(每用户 ID/hash/evidence/source session)
|
||||
node scripts/export-goose-v149-memory-manifest.mjs --output docs/baselines/goose-v149-memory-latest.json
|
||||
```
|
||||
|
||||
输出目录:`docs/baselines/`(git 可跟踪的本地基线 JSON)。
|
||||
|
||||
## 环境变量参考
|
||||
|
||||
见 [goose-v149-canary.env.example](./goose-v149-canary.env.example)。
|
||||
|
||||
| 变量 | 说明 |
|
||||
|---|---|
|
||||
| `TKMIND_GOOSE_CANARY` | `off` / `all` / `users` |
|
||||
| `TKMIND_API_TARGET_STABLE` | 默认 `https://127.0.0.1:18006` |
|
||||
| `TKMIND_API_TARGET_V149` | 默认 `https://127.0.0.1:18049` |
|
||||
| `TKMIND_GOOSE_CANARY_USER_IDS` | 逗号分隔 user UUID(users 模式) |
|
||||
| `GOOSE_V149_CANARY_ENV_FILE` | 默认 `.env.local` |
|
||||
|
||||
## 禁止项
|
||||
|
||||
- 不得把 `TKMIND_API_TARGET` 指向 103/105 公网或生产端口
|
||||
- 不得在本阶段修改 103 launchd、105 nginx
|
||||
- 不得启用 upstream Memory backend 写入 MySQL 业务表
|
||||
- 生产发布仍须走 `main` + `check-release-ready.sh` + Gate report
|
||||
@@ -0,0 +1,52 @@
|
||||
# Goose v1.49 local canary example.
|
||||
# Copy into .env.local via: bash scripts/switch-goose-v149-canary.sh on all
|
||||
# Rollback: bash scripts/switch-goose-v149-canary.sh rollback
|
||||
|
||||
# --- Full canary (all Portal traffic → v1.49) ---
|
||||
# TKMIND_GOOSE_CANARY=all
|
||||
# TKMIND_API_TARGET=https://127.0.0.1:18049
|
||||
# TKMIND_API_TARGET_STABLE=https://127.0.0.1:18006
|
||||
# TKMIND_API_TARGET_V149=https://127.0.0.1:18049
|
||||
|
||||
# --- Per-user canary ---
|
||||
# TKMIND_GOOSE_CANARY=users
|
||||
# TKMIND_API_TARGET=https://127.0.0.1:18006
|
||||
# TKMIND_API_TARGETS=https://127.0.0.1:18006,https://127.0.0.1:18049
|
||||
# TKMIND_GOOSE_CANARY_USER_IDS=replace-with-user-uuid
|
||||
|
||||
# Memory safety (Phase 0–1)
|
||||
MEMORY_BACKEND=legacy
|
||||
MEMORY_VECTOR_ENABLED=0
|
||||
MEMORY_AGENT_INJECTION_MODE=off
|
||||
MEMORY_LIFECYCLE_ENABLED=0
|
||||
MEMORY_CANDIDATE_ENABLED=0
|
||||
|
||||
# Goose v1.49 local session DB (isolated from production memind_sessions)
|
||||
# GOOSE_SESSION_DB_URL=postgresql://john@127.0.0.1:5432/goose_sessions_v149_dev
|
||||
|
||||
# Headroom context compression (Phase 1, local loopback only)
|
||||
# MEMIND_HEADROOM_MODE=off
|
||||
# MEMIND_HEADROOM_PROXY_BASE_URL=http://127.0.0.1:8787/v1
|
||||
# MEMIND_HEADROOM_UPSTREAM_BASE_URL=http://127.0.0.1:18036/v1
|
||||
# OPENAI_TARGET_API_URL=http://127.0.0.1:18036/v1
|
||||
# HEADROOM_OUTPUT_SHAPER=0
|
||||
# MEMIND_HEADROOM_OBS_MODEL=deepseek-chat
|
||||
|
||||
# DeepSeek Harness code executor (developer preview, default off)
|
||||
# MEMIND_TOOL_GATEWAY_DSH_ENABLED=0
|
||||
# MEMIND_TOOL_GATEWAY_DSH_TASK_TYPES=repo_refactor,multi_file
|
||||
# MEMIND_DSH_BIN=dsh
|
||||
|
||||
# Context injection budget (Phase 2, default off — does not open memory injection)
|
||||
# MEMIND_CONTEXT_BUDGET_MODE=off
|
||||
# MEMIND_CONTEXT_BUDGET_MAX_CHARS=12000
|
||||
|
||||
# Recall fusion (Phase 3, default off)
|
||||
# MEMIND_RECALL_FUSION_MODE=off
|
||||
# MEMIND_RECALL_FUSION_RRF_K=60
|
||||
# MEMIND_RECALL_FUSION_LIMIT=3
|
||||
|
||||
# zvec-grep workspace search for code tasks (dev/local, default off)
|
||||
# MEMIND_ZVEC_WORKSPACE_MODE=off
|
||||
# MEMIND_ZVEC_BINARY=zg
|
||||
# MEMIND_ZVEC_WORKSPACE_TASK_TYPES=page_data_dev_complex,repo_refactor,multi_file
|
||||
@@ -0,0 +1,77 @@
|
||||
# Goose v1.49 本地升级 Phase 0 基线
|
||||
|
||||
> 范围:仅本机 loopback,禁止连接 103/105 或生产库。
|
||||
> 决策表:[TKMIND_V1_49_MIGRATION.md](../TKMIND_V1_49_MIGRATION.md)
|
||||
|
||||
## Stable 基线(103 生产,只读对照)
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| goosed 版本 | `goose-server 1.41.0` |
|
||||
| 二进制 | `tkmind_go-native/releases/goosed-20260729-v141-m1` |
|
||||
| 源码分支 | `upgrade/goose-1.47`(TKMind 补丁) |
|
||||
| 端口 | `18006`–`18014`(native launchd × 9) |
|
||||
| Session PG | `memind_sessions` @ `127.0.0.1:5432`(103) |
|
||||
| 记录时间 | 2026-09-08 |
|
||||
|
||||
## v1.49 候选(本地隔离)
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| worktree | `/Users/john/Project/tkmind_go-v149` |
|
||||
| 分支 | `upgrade/v1.49-tkmind` |
|
||||
| upstream tag | `v1.49.0` |
|
||||
| 端口 | `18049` |
|
||||
| 启动命令 | `goose serve --tls`(**v1.49 已移除 `goosed`/`goose-server`**,改为 ACP HTTP/WS) |
|
||||
| Session PG | `goose_sessions_v149_dev` @ `127.0.0.1:5432` |
|
||||
| XDG 隔离 | `/tmp/goose-v149-runtime/{config,data,state,cache}` |
|
||||
| Portal 目标 | `TKMIND_API_TARGET_V149=https://127.0.0.1:18049`(独立 H5 进程时使用) |
|
||||
|
||||
## Memory 本地策略(Phase 1 初始)
|
||||
|
||||
```bash
|
||||
MEMORY_BACKEND=legacy
|
||||
MEMORY_VECTOR_ENABLED=0
|
||||
MEMORY_AGENT_INJECTION_MODE=off
|
||||
MEMORY_LIFECYCLE_ENABLED=0
|
||||
MEMORY_CANDIDATE_ENABLED=0
|
||||
```
|
||||
|
||||
upstream / v1.49 goosed 不得写入 MySQL 业务记忆;只走现有 Portal `conversation-memory` owner。
|
||||
|
||||
## Phase 0 检查项
|
||||
|
||||
- [x] 记录 stable 1.41 基线
|
||||
- [x] 拉取 upstream `v1.49.0` tag
|
||||
- [x] 创建 `upgrade/v1.49-tkmind` worktree
|
||||
- [x] 创建隔离 PG 库 `goose_sessions_v149_dev`
|
||||
- [x] 编译 v1.49 goosed 并通过 `GET /status`(`goose 1.49.0` @ `:18049` → `ok`)
|
||||
- [x] 移植 legacy REST(`/agent/start`、`/sessions`、`/sessions/{id}/events|reply|cancel` 等,见 `tkmind_compat`)
|
||||
- [x] 导出 Memory manifest(`node scripts/export-goose-v149-memory-manifest.mjs` → `docs/baselines/goose-v149-memory-latest.json`)
|
||||
- [x] 保存 runtime 基线样本(`node scripts/capture-goose-v149-baseline.mjs` → `docs/baselines/`)
|
||||
- [x] Canary 开关与一键回滚(`scripts/switch-goose-v149-canary.sh`,见 [goose-v149-canary-runbook.md](./goose-v149-canary-runbook.md))
|
||||
|
||||
## Phase 1 验证
|
||||
|
||||
```bash
|
||||
node scripts/run-goosed-v149-phase2.mjs # Phase 2 聚合(cost + drift + phase1)
|
||||
node scripts/check-goosed-v149-cost-smoke.mjs # Finish token_state / billing
|
||||
node scripts/compare-goose-v149-memory-manifest.mjs
|
||||
bash scripts/switch-goose-v149-canary.sh on all # 全量 canary 后重启 pnpm dev
|
||||
```
|
||||
|
||||
```bash
|
||||
bash scripts/ensure-goose-v149-vendor.sh # 离线 vendor(GitHub 不可用时)
|
||||
bash scripts/build-goosed-v149-local.sh # 编译 goose CLI(首次较久)
|
||||
bash scripts/ensure-goose-v149-local-db.sh
|
||||
bash scripts/run-goosed-v149-local.sh # goose serve @ 18049
|
||||
curl -sk https://127.0.0.1:18049/status
|
||||
```
|
||||
|
||||
> v1.49 已通过 `crates/goose/src/acp/tkmind/` 重移植 legacy REST;聚合验证:`node scripts/check-goosed-v149-all.mjs`。
|
||||
|
||||
## 禁止项
|
||||
|
||||
- 不得使用生产 `DATABASE_URL`、`GOOSE_SESSION_DB_URL`(含 RDS / 103 / 105 地址)
|
||||
- 不得修改 103 launchd、105 nginx、Portal `:8081`
|
||||
- 不得在本阶段删除 1.41 定制或 `:18036` DeepSeek 代理
|
||||
@@ -0,0 +1,87 @@
|
||||
# Goose v1.49 本地编译所需下载链接
|
||||
|
||||
> TKMind 需要 **code-mode**(含 v8)。本机 GitHub SSL 不稳定时,可手动下载后放入 cargo 缓存。
|
||||
|
||||
## 默认编译(含 code-mode,推荐)
|
||||
|
||||
```bash
|
||||
bash scripts/build-goosed-v149-local.sh
|
||||
# 等价 GOOSE_V149_BUILD_MODE=codemode
|
||||
```
|
||||
|
||||
会先执行 `scripts/ensure-goose-v149-v8.sh` 确保 v8 缓存就绪。
|
||||
|
||||
## 方案 A:仅跳过 local-inference 的 code-mode 编译
|
||||
|
||||
```bash
|
||||
cd /Users/john/Project/tkmind_go-v149
|
||||
bash ../Memind/scripts/ensure-goose-v149-v8.sh
|
||||
rustup run 1.96.1 cargo build --release --package goose-cli --bin goose \
|
||||
--no-default-features --features rustls-tls,aws-providers,system-keyring,code-mode,telemetry
|
||||
```
|
||||
|
||||
## 方案 B:完整 default features(含 v8 + local-inference)
|
||||
|
||||
```bash
|
||||
GOOSE_V149_BUILD_MODE=full bash scripts/build-goosed-v149-local.sh
|
||||
```
|
||||
|
||||
### rusty_v8 静态库(code-mode 必需)
|
||||
|
||||
| 项 | 值 |
|
||||
|---|---|
|
||||
| 文件 | `librusty_v8_release_aarch64-apple-darwin.a.gz` |
|
||||
| 直链 | https://github.com/denoland/rusty_v8/releases/download/v145.0.0/librusty_v8_release_aarch64-apple-darwin.a.gz |
|
||||
| Release 页 | https://github.com/denoland/rusty_v8/releases/tag/v145.0.0 |
|
||||
|
||||
**重要**:cargo/rusty_v8 要求缓存路径是**单个 gzip 文件**,不是目录:
|
||||
|
||||
```text
|
||||
~/.cargo/.rusty_v8/https___github_com_denoland_rusty_v8_releases_download_v145_0_0_librusty_v8_release_aarch64_apple_darwin_a_gz
|
||||
```
|
||||
|
||||
(该路径本身就是文件,不要再套一层子目录。)
|
||||
|
||||
手动下载命令:
|
||||
|
||||
```bash
|
||||
bash scripts/ensure-goose-v149-v8.sh
|
||||
```
|
||||
|
||||
或:
|
||||
|
||||
```bash
|
||||
CACHE_FILE="$HOME/.cargo/.rusty_v8/https___github_com_denoland_rusty_v8_releases_download_v145_0_0_librusty_v8_release_aarch64_apple_darwin_a_gz"
|
||||
mkdir -p "$(dirname "$CACHE_FILE")"
|
||||
curl -fL --retry 5 -o "$CACHE_FILE" \
|
||||
"https://github.com/denoland/rusty_v8/releases/download/v145.0.0/librusty_v8_release_aarch64-apple-darwin.a.gz"
|
||||
```
|
||||
|
||||
## 方案 C:minimal(无 code-mode,仅调试 serve 路由)
|
||||
|
||||
```bash
|
||||
GOOSE_V149_BUILD_MODE=minimal bash scripts/build-goosed-v149-local.sh
|
||||
```
|
||||
|
||||
### 2. Git 依赖(已用 file:// 本地 hermit 缓存,一般不需再下)
|
||||
|
||||
| 依赖 | 本地路径 |
|
||||
|---|---|
|
||||
| agent-client-protocol rust-sdk | `tkmind_go-v141-prod-prep/.hermit/rust/git/checkouts/rust-sdk-.../c97a520` |
|
||||
| cudaforge | `tkmind_go-v141-prod-prep/.hermit/rust/git/checkouts/cudaforge-.../e7c1967` |
|
||||
|
||||
已在 `tkmind_go-v149/Cargo.toml` 的 `[patch.crates-io]` 指向 `file://`。
|
||||
|
||||
### 3. upstream Goose 源码
|
||||
|
||||
| 项 | 链接 |
|
||||
|---|---|
|
||||
| Tag v1.49.0 | https://github.com/aaif-goose/goose/releases/tag/v1.49.0 |
|
||||
|
||||
## 验证
|
||||
|
||||
```bash
|
||||
bash scripts/build-goosed-v149-local.sh # 或方案 A 命令
|
||||
bash scripts/run-goosed-v149-local.sh
|
||||
curl -sk https://127.0.0.1:18049/status
|
||||
```
|
||||
@@ -0,0 +1,45 @@
|
||||
# Goose v1.49 Phase 2 证据台账
|
||||
|
||||
> 本地 loopback only。每项记录 **通过 / 保留 / 回滚**,禁止批量删除定制。
|
||||
|
||||
## 执行入口
|
||||
|
||||
```bash
|
||||
node scripts/run-goosed-v149-phase2.mjs
|
||||
node scripts/check-goosed-v149-cost-smoke.mjs # 需 DEEPSEEK_API_KEY
|
||||
node scripts/compare-goose-v149-memory-manifest.mjs # 对比 baseline drift
|
||||
node scripts/check-goosed-v149-deepseek-tools.mjs # 需 DEEPSEEK_API_KEY
|
||||
node scripts/compare-goose-v149-message-sanitize.mjs # provider sanitize 单测对照
|
||||
node scripts/check-goosed-v149-thinking-preservation.mjs
|
||||
node scripts/check-goosed-v149-skills-smoke.mjs
|
||||
```
|
||||
|
||||
## 证据项
|
||||
|
||||
| 项 | 脚本/产物 | 状态 | 备注 |
|
||||
|---|---|---|---|
|
||||
| Phase 1 聚合 smoke | `check-goosed-v149-all.mjs` | 通过 | 2026-09-08 |
|
||||
| Finish token_state + cost | `check-goosed-v149-cost-smoke.mjs` | 通过 | in=8339 out=2 cost≈0.00225 USD |
|
||||
| Memory manifest 无 drift | `compare-goose-v149-memory-manifest.mjs` | 通过 | digest=69b48723… |
|
||||
| Memory fail-open (legacy) | `check-goosed-v149-memory-failopen.mjs` | 通过 | 超时 degrade 不抛错 |
|
||||
| Portal canary 联调 | `check-goosed-v149-canary-portal.mjs` | 通过 | 隔离 Portal :8083 → v149 :18049 |
|
||||
| Session reconcile 路由 | `check-goosed-v149-session-reconcile.mjs` | 通过 | GET /sessions/{id}, add/remove/restart |
|
||||
| platform/web 扩展 | `check-goosed-v149-web-smoke.mjs` | 通过 | web_search + fetch_url 工具挂载 |
|
||||
| DeepSeek 工具轮次 | `check-goosed-v149-deepseek-tools.mjs` | 通过/可选 | 需 DEEPSEEK_API_KEY;todo_write Finish |
|
||||
| DeepSeek reasoning 保留 | `check-goosed-v149-thinking-preservation.mjs` | 通过 | agent 集成测试 4 项 |
|
||||
| upstream web-search 路径 | `check-goosed-v149-skills-smoke.mjs` | 通过 | skills/load_skill(与 platform/web 并存) |
|
||||
| message sanitize 对照 | `compare-goose-v149-message-sanitize.mjs` | 通过 | goose-providers sanitize 单测 v1.41≈v1.49 |
|
||||
| DeepSeek no-think 代理 `:18036` | — | 保留 | 生产 parity;Portal session-reply-wait 仍启用 |
|
||||
|
||||
## 回滚
|
||||
|
||||
```bash
|
||||
bash scripts/switch-goose-v149-canary.sh rollback
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
## 判定规则
|
||||
|
||||
- **通过**:脚本 OK + 证据 JSON 已写入 `docs/baselines/`
|
||||
- **保留**:行为不等价或缺证据,维持 1.41 / 定制实现
|
||||
- **回滚**:canary 一切换即异常,执行 rollback 脚本
|
||||
@@ -0,0 +1,62 @@
|
||||
# Goose v1.49 Phase 3 收口清单
|
||||
|
||||
> **本阶段不授权 103/105 操作。** 仅整理证据、回滚路径与合并前闸门。
|
||||
> 决策表:[TKMIND_V1_49_MIGRATION.md](../TKMIND_V1_49_MIGRATION.md) · Phase 2 台账:[goose-v149-phase2-evidence.md](./goose-v149-phase2-evidence.md)
|
||||
|
||||
## 聚合验证入口
|
||||
|
||||
```bash
|
||||
bash scripts/run-goosed-v149-local.sh # :18049 另开终端
|
||||
node scripts/run-goosed-v149-phase3.mjs # Phase 2 + parity + drift
|
||||
```
|
||||
|
||||
通过时应输出 **`GOOSE_V149_PHASE3_OK`**。
|
||||
|
||||
## 已取得证据(可进入合并讨论,不可直接删代码)
|
||||
|
||||
| 能力 | 证据 | Phase 3 结论 |
|
||||
|---|---|---|
|
||||
| tkmind_compat / PG Session | `check-goosed-v149-all.mjs` | **Keep** — 已适配 v1.49 |
|
||||
| sandbox-fs / harness | harness + sandbox-fs smoke | **Keep** |
|
||||
| platform/web | `check-goosed-v149-web-smoke.mjs` | **Keep** — 已移植;upstream skill 并存 |
|
||||
| skills / web-search | `check-goosed-v149-skills-smoke.mjs` | **Wrapper** — 不替换 platform/web |
|
||||
| DeepSeek Finish + 工具轮次 | provider + deepseek-tools smoke | **Keep** relay + v1.49 runtime |
|
||||
| reasoning 保留 | `check-goosed-v149-thinking-preservation.mjs` | **保留** `:18036` 直至生产 parity |
|
||||
| message sanitize | `compare-goose-v149-message-sanitize.mjs` | provider 层等价;Portal 展示仍 Keep |
|
||||
| Memory legacy owner | memory-loop + drift + failopen | **Keep** — 禁止 upstream 写 MySQL |
|
||||
| 计费 token_state | cost-smoke JSON | **Wrapper** — 观察 v1.49 原生 cost |
|
||||
|
||||
## 明确禁止在本阶段删除
|
||||
|
||||
- `session-reply-wait.mjs`、H5 SSE 游标映射、Finish merge
|
||||
- `deepseek-no-think-proxy.mjs` / `:18036`(生产 parity 未退役)
|
||||
- MindSpace / Page Data / 微信 / 计费 / capabilities 策略
|
||||
- 1.41 stable 端口池 `:18006`–`:18014` 与 launchd 配置
|
||||
|
||||
## 合并前闸门(Memind 仓库)
|
||||
|
||||
1. [ ] `upgrade/v1.49-tkmind` worktree 变更已 review(`tkmind_go-v149` 独立仓库/worktree)
|
||||
2. [ ] Memind 侧脚本/文档/canary 开关 PR 就绪
|
||||
3. [ ] `node scripts/run-goosed-v149-phase3.mjs` 连续通过(2026-09-09:失败项 `phase2`/`page-e2e`/`multiturn-provider` 超时;非 goose 不可用)
|
||||
4. [ ] Memory manifest 无 drift(`compare-goose-v149-memory-manifest.mjs`)
|
||||
5. [x] 主 Portal 重启后 canary 联调:`check-goosed-v149-portal-smoke.mjs`(targets 含 `:18049`);canary 块强制 `H5_PUBLIC_BASE_URL=http://127.0.0.1:8081` 避免 5173 未起时链接失效
|
||||
6. [ ] **用户明确批准** 后才:`git push`、合并 `main`、任何 103 构建
|
||||
|
||||
## 合并后 / 生产前(仍须单独审批)
|
||||
|
||||
- `bash scripts/check-release-ready.sh`
|
||||
- 生产 Gate report(Core + Impact)
|
||||
- `npm run verify:mindspace-publish-guards:full` 等受保护路径 verify
|
||||
- Memory owner 切换:**不在** v1.49 运行时升级包内默认开启
|
||||
|
||||
## 回滚(任意时刻)
|
||||
|
||||
```bash
|
||||
bash scripts/switch-goose-v149-canary.sh rollback
|
||||
pnpm dev
|
||||
# stable :18006 继续服务;v1.49 :18049 可单独停进程
|
||||
```
|
||||
|
||||
## 基线产物索引
|
||||
|
||||
见 [docs/baselines/README.md](./baselines/README.md)。
|
||||
Reference in New Issue
Block a user