@maxkle1nz/m1nd 0.9.0-beta.0 → 0.9.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,24 +4,26 @@
4
4
  <img src=".github/m1nd-logo.svg" alt="m1nd" width="400" />
5
5
  </p>
6
6
 
7
- <h3 align="center">Operational intelligence for coding agents</h3>
7
+ <h1 align="center">The Agent Memory Layer for Codebases</h1>
8
8
 
9
9
  <p align="center">
10
- <strong>A local intelligence layer for coding agents.</strong><br/>
11
- <em>Local execution. MCP over stdio. Optional HTTP/UI surface in the default build.</em>
10
+ <strong>Your coding agent stops starting blind.</strong><br/>
11
+ <em>Local-first. MCP-native. Graph memory, recovery, and change reasoning for agent hosts.</em>
12
12
  </p>
13
13
 
14
14
  <p align="center">
15
+ <a href="https://www.npmjs.com/package/@maxkle1nz/m1nd"><img src="https://img.shields.io/npm/v/@maxkle1nz/m1nd.svg?color=00f5ff&label=npm" alt="npm" /></a>
15
16
  <a href="https://crates.io/crates/m1nd-core"><img src="https://img.shields.io/crates/v/m1nd-core.svg" alt="crates.io" /></a>
16
17
  <a href="https://github.com/maxkle1nz/m1nd/actions"><img src="https://github.com/maxkle1nz/m1nd/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
17
18
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License" /></a>
18
19
  <a href="https://docs.rs/m1nd-core"><img src="https://img.shields.io/docsrs/m1nd-core" alt="docs.rs" /></a>
19
- <a href="https://github.com/maxkle1nz/m1nd/releases"><img src="https://img.shields.io/badge/release-v0.8.0-00f5ff" alt="Release" /></a>
20
20
  </p>
21
21
 
22
22
  <p align="center">
23
+ <a href="#why-agents-need-it">Why Agents Need It</a> &middot;
23
24
  <a href="#what-m1nd-is">What m1nd Is</a> &middot;
24
25
  <a href="#what-that-intelligence-covers">What That Intelligence Covers</a> &middot;
26
+ <a href="#how-m1nd-thinks">How m1nd Thinks</a> &middot;
25
27
  <a href="#what-m1nd-is-not">What m1nd Is Not</a> &middot;
26
28
  <a href="#capability-map">Capability Map</a> &middot;
27
29
  <a href="#quick-start">Quick Start</a> &middot;
@@ -29,6 +31,7 @@
29
31
  <a href="#try-the-agent-demo">Agent Demo</a> &middot;
30
32
  <a href="#default-agent-workflow">Default Agent Workflow</a> &middot;
31
33
  <a href="#evidence">Evidence</a> &middot;
34
+ <a href="#why-m1nd-over-alternatives">Why m1nd</a> &middot;
32
35
  <a href="#agent-testimonials">Agent Testimonials</a> &middot;
33
36
  <a href="#limits">Limits</a> &middot;
34
37
  <a href="#architecture-at-a-glance">Architecture</a> &middot;
@@ -38,6 +41,7 @@
38
41
  </p>
39
42
 
40
43
  <p align="center">
44
+ <a href="https://github.com/openai/codex"><img src="https://img.shields.io/badge/OpenAI_Codex-412991?logo=openai&logoColor=fff" alt="OpenAI Codex" /></a>
41
45
  <a href="https://claude.ai/download"><img src="https://img.shields.io/badge/Claude_Code-f0ebe3?logo=claude&logoColor=d97706" alt="Claude Code" /></a>
42
46
  <a href="https://cursor.sh"><img src="https://img.shields.io/badge/Cursor-000?logo=cursor&logoColor=fff" alt="Cursor" /></a>
43
47
  <a href="https://codeium.com/windsurf"><img src="https://img.shields.io/badge/Windsurf-0d1117?logo=windsurf&logoColor=3ec9a7" alt="Windsurf" /></a>
@@ -47,6 +51,7 @@
47
51
  <a href="https://roocode.com"><img src="https://img.shields.io/badge/Roo_Code-6d28d9?logoColor=fff" alt="Roo Code" /></a>
48
52
  <a href="https://github.com/continuedev/continue"><img src="https://img.shields.io/badge/Continue-000?logoColor=fff" alt="Continue" /></a>
49
53
  <a href="https://opencode.ai"><img src="https://img.shields.io/badge/OpenCode-18181b?logoColor=fff" alt="OpenCode" /></a>
54
+ <a href="https://aistudio.google.com"><img src="https://img.shields.io/badge/Gemini-4285F4?logo=google&logoColor=fff" alt="Gemini" /></a>
50
55
  <a href="https://aws.amazon.com/q/developer"><img src="https://img.shields.io/badge/Amazon_Q-232f3e?logo=amazonaws&logoColor=f90" alt="Amazon Q" /></a>
51
56
  </p>
52
57
 
@@ -54,16 +59,44 @@
54
59
  <img src=".github/m1nd-agent-first-map-v2.jpeg" alt="Traditional agent loop vs m1nd-grounded loop" width="960" />
55
60
  </p>
56
61
 
57
- > grep finds text. `m1nd` helps agents recover structure, context, and continuity.
62
+ > grep finds text. Vector search finds similar chunks. `m1nd` gives agents a local graph of what connects, what changed, what breaks, what drifted, and where to resume.
63
+
64
+ ## Why Agents Need It
65
+
66
+ Give a coding agent a large repo and it often starts the same way every time:
67
+ search, open likely files, rebuild context, make a plan, then repeat the whole
68
+ orientation loop in the next session.
69
+
70
+ That works for small codebases. It falls apart when the project has generated
71
+ artifacts, specs, docs, hidden co-change history, multiple agents, and long
72
+ handoffs.
73
+
74
+ The problem is not only the agent's reasoning. The agent has no durable model of
75
+ the codebase's structure.
76
+
77
+ `m1nd` gives it one.
58
78
 
59
79
  ## What m1nd Is
60
80
 
61
- `m1nd` is a local MCP runtime that gives coding agents structural retrieval, change reasoning, document grounding, operations, and continuity through a graph they can reason over before, during, and after change.
81
+ `m1nd` is a local MCP runtime that gives coding agents graph-native memory of a
82
+ codebase: structure, docs, decisions, change impact, recovery state, and
83
+ investigation continuity.
62
84
 
63
- It ingests repositories, documentation, history, runtime-adjacent signals, and graph-native knowledge into a local graph. That graph is the operational model the agent works against instead of rebuilding context from scratch on every step.
85
+ It ingests repositories, documentation, history, runtime-adjacent signals, and
86
+ graph-native knowledge into a local graph. That graph becomes the operational
87
+ model the agent works against instead of rebuilding context from scratch on
88
+ every task.
64
89
 
65
90
  It is not only a query surface. It is an operational layer: answers and edit surfaces can carry proof state, next-step guidance, recovery hints, observable execution, verified writes, stateful navigation, and persisted continuity across sessions.
66
91
 
92
+ Agents can ask the graph questions that plain file search cannot answer well:
93
+
94
+ - "What is the authentication flow?" -> `activate` finds the connected chain, not only files named `auth`.
95
+ - "What breaks if I change this?" -> `impact` and `counterfactual` surface blast radius before edits.
96
+ - "Where did this decision live?" -> `boot_memory`, trails, and perspectives recover prior context.
97
+ - "Does this spec still match the code?" -> document bindings and drift checks expose stale claims.
98
+ - "Is this repo binding trustworthy?" -> `trust_selftest`, `session_handshake`, and `recovery_playbook` tell the agent whether to proceed, ingest, rebind, or fall back.
99
+
67
100
  With `m1nd`, an agent can:
68
101
 
69
102
  - build a durable operational model of a codebase from code, docs, history, runtime signals, and graph-native knowledge
@@ -89,6 +122,21 @@ With `m1nd`, an agent can:
89
122
  - Operations: audits, graph-vs-disk verification, daemon monitoring, alerts, metrics, diagrams, runtime overlays, panoramas, savings, reporting, built-in help, and recovery-oriented workflow routing.
90
123
  - Continuity: perspectives, trails, session coverage, boot memory, persisted state, feedback-driven reinforcement, multi-agent isolation, and cross-repo or cross-session investigative state.
91
124
 
125
+ ## How m1nd Thinks
126
+
127
+ Most code intelligence tools treat a repo as a flat index. `m1nd` treats it as a
128
+ system of relationships.
129
+
130
+ - **Spreading activation** moves signal through topology, semantics, recency, and directed flow so the agent can find connected neighborhoods rather than isolated keyword hits.
131
+ - **Ghost edges** lift hidden coupling from git history, including files that often change together without an explicit import.
132
+ - **Impact and counterfactuals** turn "what if I touch this?" into a graph question before the edit happens.
133
+ - **Hebbian plasticity** reinforces useful paths from repeated feedback, so the graph can preserve local project memory over time.
134
+ - **L1GHT and universal document ingest** let specs, claims, citations, and implementation bindings live in the same graph as code.
135
+ - **Context Guard and recovery tools** keep agents honest when a host is stale, bound to the wrong repo, missing recovery tools, or operating through a dead MCP transport.
136
+
137
+ The result is not just retrieval. It is structured orientation, change
138
+ reasoning, and recovery behavior that an agent can call before acting.
139
+
92
140
  ## What m1nd Is Not
93
141
 
94
142
  `m1nd` is not just:
@@ -155,6 +203,10 @@ Then start with this trust loop:
155
203
  // 0b. If you need the cheaper sub-check only
156
204
  {"method":"tools/call","params":{"name":"session_handshake","arguments":{"agent_id":"dev"}}}
157
205
 
206
+ // 0c. If the task names an absolute repo/scope, pass it so Context Guard can
207
+ // detect "active repo A graph, asked about repo B" before retrieval lies by silence.
208
+ {"method":"tools/call","params":{"name":"session_handshake","arguments":{"agent_id":"dev","scope":"/your/project"}}}
209
+
158
210
  // If your host only exposes health, read its tool_surface_contract first
159
211
  {"method":"tools/call","params":{"name":"health","arguments":{"agent_id":"dev"}}}
160
212
 
@@ -214,14 +266,43 @@ from source or point your host at an installed binary.
214
266
  ```bash
215
267
  m1nd mcp-config codex
216
268
  m1nd mcp-config generic
269
+ m1nd restart --source /path/to/m1nd --yes
217
270
  m1nd pack-check
218
271
  ```
219
272
 
273
+ `m1nd restart` is the external repair button for agents. It is useful when a
274
+ host is still launching an old `m1nd-mcp`, reports `Transport closed`, or keeps
275
+ a stale MCP process alive. With `--yes`, it builds from the source checkout,
276
+ installs the native runtime to the default m1nd binary path, and stops visible
277
+ `m1nd-mcp` processes. The host still needs to restart or rebind afterward so it
278
+ can launch the updated binary.
279
+
280
+ In live multi-agent work, use `--no-kill` when you want to update the managed
281
+ binary without interrupting active hosts:
282
+
283
+ ```bash
284
+ m1nd restart --source /path/to/m1nd --yes --no-kill
285
+ ```
286
+
287
+ For every host that supports environment variables, prefer setting
288
+ `M1ND_WORKSPACE_ROOT` to the real repository/workspace. It is the portable
289
+ signal used across Codex, Claude Code, Antigravity, Gemini, Cursor, Windsurf,
290
+ VS Code, and generic MCP clients.
291
+
292
+ When an agent is working across repos, pass the intended absolute repo or
293
+ subtree as `scope` to `session_handshake`, `trust_selftest`,
294
+ `recovery_playbook`, `doctor`, or `validate_plan`. Context Guard returns
295
+ `wrong_workspace_binding` when the host is bound to one workspace but the tool
296
+ call targets another. That is not graph staleness. Rebind the host with
297
+ `M1ND_WORKSPACE_ROOT` set to the requested workspace, ingest that workspace on
298
+ the same binding, or use explicit federation if the task truly spans repos.
299
+
220
300
  See [docs/AGENT-PACKS.md](docs/AGENT-PACKS.md) for the full install map.
221
301
 
222
302
  Windows is part of the universal target. The installer emits Windows-safe MCP
223
- paths and looks for `m1nd-mcp.exe` on `PATH`, through `M1ND_MCP_BINARY`, or at
224
- `%USERPROFILE%\.m1nd\bin\m1nd-mcp.exe`.
303
+ paths and resolves the runtime in this order: `M1ND_MCP_BINARY`,
304
+ `M1ND_MCP_BIN`, the managed `~/.m1nd/bin` path, then `PATH`. On Windows the
305
+ managed path is `%USERPROFILE%\.m1nd\bin\m1nd-mcp.exe`.
225
306
 
226
307
  The Windows support boundary is the universal MCP lane: `m1nd-core`,
227
308
  `m1nd-ingest`, and `m1nd-mcp`. The `m1nd-openclaw` fast path remains a Unix
@@ -251,6 +332,15 @@ If your local demo sees `trust_selftest` but your editor or agent host does not,
251
332
  use the [MCP host refresh guide](docs/MCP-HOST-REFRESH.md) to compare the host
252
333
  tool surface against the local runtime.
253
334
 
335
+ If a host returns `Transport closed`, treat it as a dead MCP transport, not a
336
+ stale graph. Restart/rebind the host MCP client or open a fresh session, then
337
+ run `trust_selftest` or `session_handshake` before relying on retrieval.
338
+
339
+ If a response includes
340
+ `context_guard.wrong_workspace_binding=true`, stop before shell fallback. The
341
+ current graph may be healthy but bound to the wrong repo. Follow the embedded
342
+ `recovery_playbook` payload and rebind or federate intentionally.
343
+
254
344
  ## Default Agent Workflow
255
345
 
256
346
  Make `m1nd` the default investigative layer before `rg`, filesystem globbing, or manual file reads when the task depends on structure, docs, impact, or change.
@@ -279,6 +369,22 @@ Detailed client-by-client setup lives in the [canonical wiki](https://m1nd.world
279
369
  | `impact` depth=3 | **543 ns** ([benchmarks](https://m1nd.world/wiki/benchmarks.html)) |
280
370
  | Post-write validation sample | **12/12** classified correctly |
281
371
 
372
+ ## Why m1nd Over Alternatives
373
+
374
+ | What an agent needs | grep / rg | vector RAG | `m1nd` |
375
+ |---|---:|---:|---:|
376
+ | Find exact text | yes | yes | yes, through `search` |
377
+ | Find similar concepts | no | yes | yes, with graph context |
378
+ | Understand structural relationships | no | limited | yes |
379
+ | Ask "what breaks if I change this?" | no | no | yes, through `impact` and `counterfactual` |
380
+ | Resume investigation state | no | no | yes, through trails, perspectives, and boot memory |
381
+ | Bind docs/specs to code | no | partial | yes, through document bindings and drift checks |
382
+ | Detect hidden co-change coupling | no | no | yes, through ghost edges |
383
+ | Recover from stale host bindings | no | no | yes, through trust and recovery surfaces |
384
+
385
+ `m1nd` does not replace grep, embeddings, tests, or compilers. It gives agents
386
+ the structural layer those tools do not provide by themselves.
387
+
282
388
  ## Agent Testimonials
283
389
 
284
390
  ### Jimi - build agent on SAMBA/DOOB
@@ -324,9 +430,9 @@ The workspace is split into three core crates plus one auxiliary bridge crate:
324
430
 
325
431
  Current crate versions:
326
432
 
327
- - `m1nd-core` `0.8.0`
328
- - `m1nd-ingest` `0.8.0`
329
- - `m1nd-mcp` `0.8.0`
433
+ - `m1nd-core` `0.9.0-beta.1`
434
+ - `m1nd-ingest` `0.9.0-beta.1`
435
+ - `m1nd-mcp` `0.9.0-beta.1`
330
436
 
331
437
  <p align="center">
332
438
  <img src=".github/m1nd-architecture-overview-v2.jpeg" alt="m1nd architecture overview" width="960" />
@@ -47,6 +47,10 @@ The demo proves the practical agent loop:
47
47
  The point is not just search. The point is that the agent knows whether it can
48
48
  trust the current session before it acts.
49
49
 
50
+ When a task points at a different repo than the active binding, the same trust
51
+ loop should return `wrong_workspace_binding` through `context_guard` rather than
52
+ letting the agent confuse workspace mismatch with a stale or empty graph.
53
+
50
54
  ## How To Read The Output
51
55
 
52
56
  The Markdown output is shaped like a handoff:
@@ -47,6 +47,30 @@ Those commands write into `/path/to/project/.m1nd/agent-pack/`. Point the host
47
47
  at the generated rule file or paste it into the host custom-instructions
48
48
  surface.
49
49
 
50
+ The portable pack includes recovery language for dead MCP transports. If a host
51
+ reports `Transport closed`, treat it as a host binding death, not as stale graph
52
+ state. Relaunch/rebind the MCP client or open a fresh session before calling
53
+ `doctor`, `recovery_playbook`, or `ingest`.
54
+
55
+ If the host is stale because it is still launching an older native binary, use
56
+ the external restart helper from a m1nd source checkout:
57
+
58
+ ```bash
59
+ m1nd restart --source /path/to/m1nd --yes
60
+ ```
61
+
62
+ This builds the latest `m1nd-mcp`, installs it to the default m1nd binary path,
63
+ and stops visible `m1nd-mcp` processes so the host can relaunch. It still cannot
64
+ refresh a client's cached MCP tool list by itself; restart or rebind the host
65
+ session afterward.
66
+
67
+ During live multi-agent work, add `--no-kill` if the goal is only to update the
68
+ managed binary while keeping current host sessions alive:
69
+
70
+ ```bash
71
+ m1nd restart --source /path/to/m1nd --yes --no-kill
72
+ ```
73
+
50
74
  ## MCP Config Snippets
51
75
 
52
76
  Codex:
@@ -77,8 +101,19 @@ Then point your host at:
77
101
  target/release/m1nd-mcp
78
102
  ```
79
103
 
80
- On Windows, the native binary is `m1nd-mcp.exe`. The npm installer looks for it
81
- on `PATH`, through `M1ND_MCP_BINARY`, or at:
104
+ When the host supports environment variables, set:
105
+
106
+ ```text
107
+ M1ND_WORKSPACE_ROOT=/path/to/project
108
+ ```
109
+
110
+ That is the host-neutral workspace contract. Host-specific variables from
111
+ Claude Code, Antigravity, Gemini, Cursor, Windsurf, VS Code, and shells are
112
+ recognized as aliases, but `M1ND_WORKSPACE_ROOT` is the preferred signal.
113
+
114
+ On Windows, the native binary is `m1nd-mcp.exe`. The npm installer resolves it
115
+ in this order: `M1ND_MCP_BINARY`, `M1ND_MCP_BIN`, the managed m1nd binary path,
116
+ then `PATH`. The managed Windows path is:
82
117
 
83
118
  ```text
84
119
  %USERPROFILE%\.m1nd\bin\m1nd-mcp.exe
@@ -96,6 +131,8 @@ should use plain MCP until a Windows-native fast lane is introduced.
96
131
 
97
132
  ## Trust Loop For Every Host
98
133
 
134
+ 0. If the host returns `Transport closed`, restart/rebind the host MCP client
135
+ first. The transport died before m1nd could run a recovery tool.
99
136
  1. Call `trust_selftest`.
100
137
  2. If unavailable, call `session_handshake`.
101
138
  3. If only `health` is visible, inspect `tool_surface_contract`.
@@ -33,7 +33,8 @@ Most hosts are perfectly fine with:
33
33
  "command": "/path/to/m1nd-mcp",
34
34
  "env": {
35
35
  "M1ND_GRAPH_SOURCE": "/tmp/m1nd-graph.json",
36
- "M1ND_PLASTICITY_STATE": "/tmp/m1nd-plasticity.json"
36
+ "M1ND_PLASTICITY_STATE": "/tmp/m1nd-plasticity.json",
37
+ "M1ND_WORKSPACE_ROOT": "/path/to/your/project"
37
38
  }
38
39
  }
39
40
  }
@@ -63,6 +64,7 @@ args = ["--stdio", "--no-gui"]
63
64
  [mcp_servers.m1nd.env]
64
65
  M1ND_GRAPH_SOURCE = "/tmp/m1nd-graph.json"
65
66
  M1ND_PLASTICITY_STATE = "/tmp/m1nd-plasticity.json"
67
+ M1ND_WORKSPACE_ROOT = "/path/to/your/project"
66
68
  ```
67
69
 
68
70
  But some editor hosts still pay too much overhead if they cold-start a stdio MCP
@@ -108,6 +110,31 @@ Examples:
108
110
 
109
111
  ## Practical recommendations
110
112
 
113
+ ### Set the workspace root when possible
114
+
115
+ Use `M1ND_WORKSPACE_ROOT` as the portable contract for Codex, Claude Code,
116
+ Antigravity, Gemini, Cursor, Windsurf, VS Code, and generic MCP clients. Point
117
+ it at the real repository or workspace, not at a host-managed runtime folder.
118
+
119
+ Host-specific hints such as `CLAUDE_PROJECT_DIR` or
120
+ `ANTIGRAVITY_WORKSPACE_ROOT` are recognized as compatibility aliases, but
121
+ `M1ND_WORKSPACE_ROOT` is the clearest cross-host signal.
122
+
123
+ If a tool call fails with `Transport closed`, the MCP pipe died before m1nd
124
+ could run. Restart/rebind the host MCP client or open a fresh session, then
125
+ call `trust_selftest` or `session_handshake` before retrieval.
126
+
127
+ If the host is launching an old native runtime, use the external repair helper
128
+ from a m1nd source checkout:
129
+
130
+ ```bash
131
+ m1nd restart --source /path/to/m1nd --yes
132
+ ```
133
+
134
+ For live multi-agent sessions, add `--no-kill` to install the updated managed
135
+ binary without stopping current host processes, then restart/rebind only the
136
+ target host.
137
+
111
138
  ### Use plain MCP when:
112
139
 
113
140
  - the host already keeps the MCP server alive
@@ -10,6 +10,27 @@ The most common symptom is simple:
10
10
  - the host session only sees some of those tools
11
11
  - retrieval looks blocked or stale even after ingest
12
12
 
13
+ Another common symptom is more abrupt:
14
+
15
+ - a tool call fails with `Transport closed`
16
+
17
+ That is not graph staleness. It means the MCP transport died before m1nd could
18
+ execute a tool. Recovery tools such as `doctor`, `recovery_playbook`, and
19
+ `ingest` cannot run through that closed transport. Prove the binary locally,
20
+ restart/rebind the host MCP client or open a fresh session, then call
21
+ `trust_selftest` or `session_handshake` on the newly launched binding.
22
+
23
+ A third symptom is a cross-repo binding mismatch:
24
+
25
+ - the active graph is populated for repo A
26
+ - a tool call passes a scope/path from repo B
27
+ - retrieval returns blocked or zero candidates even though repo B has content
28
+
29
+ Current builds surface this as `wrong_workspace_binding` in `trust_selftest`,
30
+ `session_handshake`, `recovery_playbook`, `doctor`, and `validate_plan`. That
31
+ means the graph may be fine; the host is just bound to the wrong workspace for
32
+ this task.
33
+
13
34
  ## 1. Prove The Local Binary First
14
35
 
15
36
  From the repo root:
@@ -53,6 +74,12 @@ If `trust_selftest` is visible, call it first:
53
74
  {"agent_id":"dev"}
54
75
  ```
55
76
 
77
+ If the task names a target repo or absolute path, pass it as `scope`:
78
+
79
+ ```json
80
+ {"agent_id":"dev","scope":"/path/to/intended/repo"}
81
+ ```
82
+
56
83
  If it returns `full_trust`, continue with m1nd-first work. If it returns any
57
84
  other verdict, follow the embedded `recovery_playbook` or call
58
85
  `recovery_playbook` with the same evidence.
@@ -76,10 +103,34 @@ Recommended order:
76
103
 
77
104
  1. Rebuild `m1nd-mcp`.
78
105
  2. Confirm the MCP config points at the rebuilt binary.
79
- 3. Restart the MCP server process if the host manages it separately.
80
- 4. Reload or restart the client window/session.
81
- 5. Re-run `tools/list`.
82
- 6. Call `trust_selftest`.
106
+ 3. Set `M1ND_WORKSPACE_ROOT` to the intended repo/workspace when the host lets
107
+ you configure environment variables.
108
+ 4. Restart the MCP server process if the host manages it separately.
109
+ 5. Reload or restart the client window/session.
110
+ 6. Re-run `tools/list`.
111
+ 7. Call `trust_selftest`.
112
+
113
+ If the error is `Transport closed`, the old binding is already gone. Skip graph
114
+ recovery calls in that session and relaunch the host binding first.
115
+
116
+ For agent-driven repair from a source checkout, the shortest external helper is:
117
+
118
+ ```bash
119
+ m1nd restart --source /path/to/m1nd --yes
120
+ ```
121
+
122
+ `m1nd restart` is deliberately outside MCP, so it can still help when the MCP
123
+ transport is stale or closed. With `--yes`, it builds the release binary,
124
+ installs it to the default m1nd binary path, and stops visible `m1nd-mcp`
125
+ processes. Then the agent or human must restart/rebind the host so it launches
126
+ the updated binary. Without `--yes`, it prints the repair plan only.
127
+
128
+ For a live multi-agent session, use `--no-kill` when you need to update the
129
+ managed binary without stopping current hosts:
130
+
131
+ ```bash
132
+ m1nd restart --source /path/to/m1nd --yes --no-kill
133
+ ```
83
134
 
84
135
  For hosts that cache tool schemas per conversation or workspace, start a new
85
136
  conversation/session after rebuilding the binary. The old conversation may keep
@@ -116,6 +167,23 @@ The important rule is to compare binding fingerprints before falling back to
116
167
  manual search. If the local stdio/HTTP demo and the host session disagree, the
117
168
  problem is likely host binding freshness, not the graph model itself.
118
169
 
170
+ For a wrong workspace binding, include the suspicious target scope:
171
+
172
+ ```json
173
+ {
174
+ "agent_id": "dev",
175
+ "observed_tool": "seek",
176
+ "observed_proof_state": "blocked",
177
+ "observed_candidates": 0,
178
+ "scope": "/path/to/intended/repo"
179
+ }
180
+ ```
181
+
182
+ If the result includes `context_guard.wrong_workspace_binding=true`, rebind the
183
+ host with `M1ND_WORKSPACE_ROOT=/path/to/intended/repo`, ingest that workspace on
184
+ the same binding, or choose `federate_auto`/`federate` for intentional cross-repo
185
+ reasoning. Do not keep retrying retrieval against the old workspace.
186
+
119
187
  ## Limits
120
188
 
121
189
  This guide does not force any client to reload its MCP registry. It gives the
package/npm/lib/cli.js CHANGED
@@ -19,12 +19,18 @@ Usage:
19
19
  m1nd install-skills <host> [--project <dir>]
20
20
  m1nd mcp-config <host> [--binary <path>]
21
21
  m1nd doctor [--json]
22
+ m1nd restart [--source <dir>] [--binary <path>] [--yes] [--json]
22
23
  m1nd demo [--repo <dir>] [--transport stdio|http] [--json]
23
24
  m1nd smoke [--repo <dir>] [--transport stdio|http] [--json]
24
25
  m1nd pack-check [--json]
25
26
 
26
27
  This npm package installs the universal agent doctrine and host adapters. The
27
- native runtime is still m1nd-mcp; doctor tells you whether it is visible.`;
28
+ native runtime is still m1nd-mcp; doctor tells you whether it is visible.
29
+
30
+ restart is an external repair helper for stale host bindings. Without --yes it
31
+ prints the plan. With --yes it builds from source when available, installs the
32
+ native binary to the m1nd default path, and stops visible m1nd-mcp processes so
33
+ the host can relaunch/rebind.`;
28
34
  }
29
35
 
30
36
  function parseArgs(args) {
@@ -36,7 +42,7 @@ function parseArgs(args) {
36
42
  continue;
37
43
  }
38
44
  const key = arg.slice(2);
39
- if (["help", "json", "yes"].includes(key)) {
45
+ if (["build", "help", "install", "json", "kill", "no-build", "no-install", "no-kill", "yes"].includes(key)) {
40
46
  parsed[key] = true;
41
47
  continue;
42
48
  }
@@ -96,7 +102,13 @@ function defaultRuntimePath(platform = process.platform, homeDir = os.homedir())
96
102
  }
97
103
 
98
104
  function findRuntimeBinary() {
99
- return process.env.M1ND_MCP_BINARY || which("m1nd-mcp") || (fs.existsSync(defaultRuntimePath()) ? defaultRuntimePath() : null);
105
+ const managedRuntime = defaultRuntimePath();
106
+ return (
107
+ process.env.M1ND_MCP_BINARY ||
108
+ process.env.M1ND_MCP_BIN ||
109
+ (fs.existsSync(managedRuntime) ? managedRuntime : null) ||
110
+ which("m1nd-mcp")
111
+ );
100
112
  }
101
113
 
102
114
  function readPackageVersion() {
@@ -202,6 +214,8 @@ args = ["--stdio", "--no-gui"]
202
214
  function doctor() {
203
215
  const pack = assertPackShape();
204
216
  const binary = findRuntimeBinary();
217
+ const binaryVersion = runtimeVersion(binary);
218
+ const packageVersion = readPackageVersion();
205
219
  const codexSkillRoot = path.join(os.homedir(), ".codex", "skills");
206
220
  const codexSkillsInstalled =
207
221
  fs.existsSync(path.join(codexSkillRoot, "m1nd-first", "SKILL.md")) &&
@@ -209,7 +223,7 @@ function doctor() {
209
223
 
210
224
  const result = {
211
225
  schema: "m1nd-npm-doctor-v0",
212
- package_version: readPackageVersion(),
226
+ package_version: packageVersion,
213
227
  package_root: PACKAGE_ROOT,
214
228
  pack_ok: pack.ok,
215
229
  missing_pack_files: pack.missing,
@@ -217,6 +231,7 @@ function doctor() {
217
231
  platform: process.platform,
218
232
  arch: process.arch,
219
233
  binary: binary || null,
234
+ version: binaryVersion,
220
235
  default_install_path: defaultRuntimePath(),
221
236
  visible_on_path_or_env: Boolean(binary),
222
237
  hint: binary
@@ -236,6 +251,9 @@ function doctor() {
236
251
  if (!binary) {
237
252
  result.next_actions.push(`From a source checkout: cargo build --release -p m1nd-mcp, then copy ${runtimeBinaryName()} to ${defaultRuntimePath()}`);
238
253
  }
254
+ if (binary && (!binaryVersion || !binaryVersion.includes(packageVersion))) {
255
+ result.next_actions.push(`Runtime version ${binaryVersion || "unknown"} does not match package ${packageVersion}; run m1nd restart --source /path/to/m1nd --yes, then rebind the host.`);
256
+ }
239
257
  if (!codexSkillsInstalled) {
240
258
  result.next_actions.push("For Codex: m1nd install-skills codex");
241
259
  }
@@ -245,6 +263,209 @@ function doctor() {
245
263
  return result;
246
264
  }
247
265
 
266
+ function runCommand(command, args, options = {}) {
267
+ const result = spawnSync(command, args, {
268
+ cwd: options.cwd,
269
+ encoding: "utf8",
270
+ stdio: options.stdio || "pipe",
271
+ timeout: options.timeout,
272
+ killSignal: options.killSignal || "SIGKILL",
273
+ });
274
+ return {
275
+ command,
276
+ args,
277
+ cwd: options.cwd || process.cwd(),
278
+ status: result.status,
279
+ ok: !result.error && result.status === 0,
280
+ error: result.error ? result.error.message : null,
281
+ stdout: result.stdout || "",
282
+ stderr: result.stderr || "",
283
+ };
284
+ }
285
+
286
+ function runtimeVersion(binary) {
287
+ if (!binary || !fs.existsSync(binary)) return null;
288
+ const result = runCommand(binary, ["--version"], { timeout: 1500 });
289
+ if (result.error && result.error.includes("ETIMEDOUT")) return "version-check-timeout";
290
+ if (!result.ok) return null;
291
+ return result.stdout.trim() || null;
292
+ }
293
+
294
+ function sourceReleaseBinary(sourceDir) {
295
+ return path.join(sourceDir, "target", "release", runtimeBinaryName());
296
+ }
297
+
298
+ function sourceLooksBuildable(sourceDir) {
299
+ return (
300
+ fs.existsSync(path.join(sourceDir, "Cargo.toml")) &&
301
+ fs.existsSync(path.join(sourceDir, "m1nd-mcp", "Cargo.toml"))
302
+ );
303
+ }
304
+
305
+ function listRuntimeProcesses() {
306
+ if (process.platform === "win32") {
307
+ const result = runCommand("tasklist", ["/FI", `IMAGENAME eq ${runtimeBinaryName()}`, "/FO", "CSV", "/NH"]);
308
+ if (!result.ok) return [];
309
+ return result.stdout
310
+ .split(/\r?\n/)
311
+ .map((line) => line.trim())
312
+ .filter(Boolean)
313
+ .map((line) => {
314
+ const columns = line
315
+ .split(/","/)
316
+ .map((part) => part.replace(/^"|"$/g, ""));
317
+ return { pid: Number(columns[1]), ppid: null, state: null, command: columns[0] };
318
+ })
319
+ .filter((processInfo) => Number.isFinite(processInfo.pid));
320
+ }
321
+ const result = runCommand("ps", ["-ax", "-o", "pid=,ppid=,state=,command="]);
322
+ if (!result.ok) return [];
323
+ return result.stdout
324
+ .split(/\r?\n/)
325
+ .map((line) => line.trim())
326
+ .map((line) => {
327
+ const match = line.match(/^(\d+)\s+(\d+)\s+(\S+)\s+(.+)$/);
328
+ if (!match) return null;
329
+ return { pid: Number(match[1]), ppid: Number(match[2]), state: match[3], command: match[4] };
330
+ })
331
+ .filter(Boolean)
332
+ .filter((processInfo) => commandLooksLikeRuntime(processInfo.command));
333
+ }
334
+
335
+ function commandLooksLikeRuntime(command) {
336
+ const firstToken = String(command || "").trim().split(/\s+/)[0] || "";
337
+ const base = path.basename(firstToken).replace(/^\(|\)$/g, "");
338
+ return base === runtimeBinaryName();
339
+ }
340
+
341
+ function stopRuntimeProcesses(processes) {
342
+ const stopped = [];
343
+ for (const processInfo of processes) {
344
+ if (!processInfo.pid || processInfo.pid === process.pid) continue;
345
+ const result =
346
+ process.platform === "win32"
347
+ ? runCommand("taskkill", ["/PID", String(processInfo.pid), "/T", "/F"])
348
+ : runCommand("kill", ["-TERM", String(processInfo.pid)]);
349
+ stopped.push({
350
+ pid: processInfo.pid,
351
+ ppid: processInfo.ppid || null,
352
+ state: processInfo.state || null,
353
+ command: processInfo.command,
354
+ ok: result.ok,
355
+ status: result.status,
356
+ stderr: result.stderr.trim(),
357
+ });
358
+ }
359
+ return stopped;
360
+ }
361
+
362
+ function installRuntimeBinary(sourceBinary, targetBinary) {
363
+ ensureDir(path.dirname(targetBinary));
364
+ const tempTarget = path.join(
365
+ path.dirname(targetBinary),
366
+ `.${path.basename(targetBinary)}.${process.pid}.tmp`
367
+ );
368
+ fs.copyFileSync(sourceBinary, tempTarget);
369
+ if (process.platform !== "win32") fs.chmodSync(tempTarget, 0o755);
370
+ fs.renameSync(tempTarget, targetBinary);
371
+ }
372
+
373
+ function restart(args) {
374
+ const sourceDir = path.resolve(args.source || args["build-from"] || process.cwd());
375
+ const targetBinary = path.resolve(args.binary || defaultRuntimePath());
376
+ const yes = Boolean(args.yes);
377
+ const buildRequested = !args["no-build"] && (args.build || args.install || yes);
378
+ const installRequested = !args["no-install"] && (args.install || yes);
379
+ const killRequested = !args["no-kill"] && (args.kill || yes);
380
+ const buildable = sourceLooksBuildable(sourceDir);
381
+ const beforeVersion = runtimeVersion(targetBinary);
382
+ const processes = listRuntimeProcesses();
383
+ const result = {
384
+ schema: "m1nd-npm-restart-v0",
385
+ package_version: readPackageVersion(),
386
+ source_dir: sourceDir,
387
+ source_buildable: buildable,
388
+ target_binary: targetBinary,
389
+ before_version: beforeVersion,
390
+ after_version: null,
391
+ dry_run: !yes,
392
+ actions: {
393
+ build_requested: buildRequested,
394
+ install_requested: installRequested,
395
+ kill_requested: killRequested,
396
+ built: false,
397
+ installed: false,
398
+ stopped_processes: [],
399
+ },
400
+ visible_runtime_processes: processes,
401
+ next_actions: [],
402
+ non_claims: [
403
+ "m1nd restart does not refresh a host's cached MCP tool list by itself.",
404
+ "m1nd restart does not repair graph contents, ingest roots, or semantic retrieval.",
405
+ "m1nd restart does not select the correct workspace for the agent.",
406
+ ],
407
+ };
408
+
409
+ if (buildRequested && !buildable) {
410
+ result.next_actions.push("Run from a m1nd source checkout or pass --source /path/to/m1nd before building.");
411
+ }
412
+
413
+ if (yes && buildRequested && buildable) {
414
+ const build = runCommand("cargo", ["build", "--release", "-p", "m1nd-mcp"], { cwd: sourceDir });
415
+ result.actions.build = {
416
+ ok: build.ok,
417
+ status: build.status,
418
+ stderr: build.stderr.trim(),
419
+ };
420
+ result.actions.built = build.ok;
421
+ if (!build.ok) {
422
+ result.next_actions.push("Fix the cargo build failure before installing or rebinding hosts.");
423
+ result.after_version = runtimeVersion(targetBinary);
424
+ return result;
425
+ }
426
+ }
427
+
428
+ if (yes && installRequested) {
429
+ const builtBinary = sourceReleaseBinary(sourceDir);
430
+ if (!fs.existsSync(builtBinary)) {
431
+ result.next_actions.push(`Built binary not found at ${builtBinary}; run cargo build --release -p m1nd-mcp first.`);
432
+ } else {
433
+ try {
434
+ installRuntimeBinary(builtBinary, targetBinary);
435
+ result.actions.install = { ok: true, source: builtBinary, target: targetBinary };
436
+ result.actions.installed = true;
437
+ } catch (error) {
438
+ result.actions.install = {
439
+ ok: false,
440
+ source: builtBinary,
441
+ target: targetBinary,
442
+ error: error instanceof Error ? error.message : String(error),
443
+ };
444
+ result.next_actions.push("Install failed; close live runtimes or use --binary to install to an isolated target, then retry.");
445
+ result.after_version = runtimeVersion(targetBinary);
446
+ return result;
447
+ }
448
+ }
449
+ }
450
+
451
+ if (yes && killRequested) {
452
+ result.actions.stopped_processes = stopRuntimeProcesses(processes);
453
+ const failedStops = result.actions.stopped_processes.filter((processInfo) => !processInfo.ok);
454
+ if (failedStops.length > 0) {
455
+ result.next_actions.push("Some visible m1nd-mcp processes did not stop; restart the host session or OS if the process state is uninterruptible.");
456
+ }
457
+ }
458
+
459
+ result.after_version = runtimeVersion(targetBinary);
460
+
461
+ if (!yes) {
462
+ result.next_actions.push("Re-run with --yes to build/install/stop processes, or add --no-build/--no-install/--no-kill to narrow the repair.");
463
+ }
464
+ result.next_actions.push("Restart or rebind the MCP host/client so it launches the installed binary.");
465
+ result.next_actions.push("Then run trust_selftest or session_handshake with the intended workspace scope.");
466
+ return result;
467
+ }
468
+
248
469
  function runDemo(args) {
249
470
  const repo = path.resolve(args.repo || process.cwd());
250
471
  const script = path.join(repo, "scripts", "m1nd_agent_demo.py");
@@ -279,18 +500,31 @@ function print(value, asJson) {
279
500
  if (value.schema === "m1nd-npm-doctor-v0") {
280
501
  console.log(`m1nd npm package ${value.package_version}`);
281
502
  console.log(`pack: ${value.pack_ok ? "ok" : "missing files"}`);
282
- console.log(`runtime: ${value.runtime.binary || "not found"}`);
503
+ console.log(`runtime: ${value.runtime.binary || "not found"}${value.runtime.version ? ` (${value.runtime.version})` : ""}`);
283
504
  console.log(`codex skills: ${value.codex.skills_installed ? "installed" : "not installed"}`);
284
505
  console.log("next:");
285
506
  for (const action of value.next_actions) console.log(` - ${action}`);
286
507
  return;
287
508
  }
509
+ if (value.schema === "m1nd-npm-restart-v0") {
510
+ console.log(`m1nd restart ${value.dry_run ? "plan" : "result"}`);
511
+ console.log(`source: ${value.source_dir}${value.source_buildable ? "" : " (not buildable)"}`);
512
+ console.log(`target: ${value.target_binary}`);
513
+ console.log(`version: ${value.before_version || "unknown"} -> ${value.after_version || "unknown"}`);
514
+ console.log(`visible m1nd-mcp processes: ${value.visible_runtime_processes.length}`);
515
+ console.log(`built: ${value.actions.built ? "yes" : "no"}`);
516
+ console.log(`installed: ${value.actions.installed ? "yes" : "no"}`);
517
+ console.log(`stopped: ${value.actions.stopped_processes.length}`);
518
+ console.log("next:");
519
+ for (const action of value.next_actions) console.log(` - ${action}`);
520
+ return;
521
+ }
288
522
  console.log(String(value));
289
523
  }
290
524
 
291
525
  async function main(rawArgs) {
292
526
  const args = parseArgs(rawArgs);
293
- const command = args._[0] || "help";
527
+ const command = args._[0] === "/restart" ? "restart" : args._[0] || "help";
294
528
 
295
529
  if (args.help || ["help", "-h", "--help"].includes(command)) {
296
530
  console.log(usage());
@@ -315,6 +549,11 @@ async function main(rawArgs) {
315
549
  return;
316
550
  }
317
551
 
552
+ if (command === "restart") {
553
+ print(restart(args), args.json);
554
+ return;
555
+ }
556
+
318
557
  if (command === "pack-check") {
319
558
  const result = assertPackShape();
320
559
  if (args.json) {
@@ -341,6 +580,8 @@ module.exports = {
341
580
  doctor,
342
581
  findRuntimeBinary,
343
582
  installSkills,
583
+ restart,
344
584
  mcpConfig,
345
585
  runtimeBinaryName,
586
+ commandLooksLikeRuntime,
346
587
  };
@@ -5,8 +5,10 @@ const path = require("path");
5
5
  const { spawnSync } = require("child_process");
6
6
 
7
7
  const {
8
+ commandLooksLikeRuntime,
8
9
  defaultRuntimePath,
9
10
  mcpConfig,
11
+ restart,
10
12
  runtimeBinaryName,
11
13
  } = require("../lib/cli");
12
14
 
@@ -15,6 +17,9 @@ const cli = path.resolve(__dirname, "../bin/m1nd.js");
15
17
  assert.strictEqual(runtimeBinaryName("win32"), "m1nd-mcp.exe");
16
18
  assert.strictEqual(runtimeBinaryName("darwin"), "m1nd-mcp");
17
19
  assert.strictEqual(runtimeBinaryName("linux"), "m1nd-mcp");
20
+ assert.strictEqual(commandLooksLikeRuntime("/Users/you/.m1nd/bin/m1nd-mcp --stdio"), true);
21
+ assert.strictEqual(commandLooksLikeRuntime("(m1nd-mcp)"), true);
22
+ assert.strictEqual(commandLooksLikeRuntime("node codex prompt mentions m1nd-mcp"), false);
18
23
 
19
24
  assert.strictEqual(
20
25
  defaultRuntimePath("win32", "C:\\Users\\you"),
@@ -41,9 +46,23 @@ const help = spawnSync(process.execPath, [cli, "--help"], { encoding: "utf8" });
41
46
  assert.strictEqual(help.status, 0, help.stderr);
42
47
  assert(help.stdout.includes("m1nd installer"));
43
48
  assert(help.stdout.includes("m1nd smoke"));
49
+ assert(help.stdout.includes("m1nd restart"));
44
50
 
45
51
  const packCheck = spawnSync(process.execPath, [cli, "pack-check", "--json"], { encoding: "utf8" });
46
52
  assert.strictEqual(packCheck.status, 0, packCheck.stderr);
47
53
  assert.strictEqual(JSON.parse(packCheck.stdout).schema, "m1nd-agent-pack-check-v0");
48
54
 
55
+ const restartPlan = restart({
56
+ source: path.resolve(__dirname, "..", ".."),
57
+ binary: path.resolve(__dirname, "missing-m1nd-mcp"),
58
+ "no-build": true,
59
+ "no-install": true,
60
+ "no-kill": true,
61
+ });
62
+ assert.strictEqual(restartPlan.schema, "m1nd-npm-restart-v0");
63
+ assert.strictEqual(restartPlan.dry_run, true);
64
+ assert.strictEqual(restartPlan.actions.built, false);
65
+ assert.strictEqual(restartPlan.actions.installed, false);
66
+ assert(restartPlan.next_actions.some((action) => action.includes("Restart or rebind")));
67
+
49
68
  console.log("npm cli tests ok");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maxkle1nz/m1nd",
3
- "version": "0.9.0-beta.0",
3
+ "version": "0.9.0-beta.1",
4
4
  "description": "Universal installer and agent pack for the m1nd MCP runtime.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -36,6 +36,26 @@ Skip the `m1nd` first pass only when:
36
36
 
37
37
  If `m1nd` does not answer enough, then fall back to shell search, direct file reads, compiler output, tests, logs, and debugger data.
38
38
 
39
+ If a tool call fails with `Transport closed`, classify it as a host MCP binding
40
+ failure before m1nd can run. Do not call `doctor`, `recovery_playbook`, or
41
+ `ingest` through that dead binding. Verify the binary with a local smoke, kill
42
+ stale `m1nd-mcp --stdio` processes if you own the host, and restart/rebind the
43
+ agent host or open a fresh thread so the MCP client launches a new transport.
44
+ After rebind, run `trust_selftest` or `session_handshake` before trusting
45
+ retrieval.
46
+
47
+ If the host appears to be launching an old native runtime, use the external CLI
48
+ repair path from a m1nd source checkout:
49
+
50
+ ```bash
51
+ m1nd restart --source /path/to/m1nd --yes
52
+ ```
53
+
54
+ Use `--no-kill` in live multi-agent sessions when you only want to install the
55
+ updated managed binary and rebind one selected host. `m1nd restart` does not
56
+ ingest, repair graph contents, choose a workspace, or refresh an already-open
57
+ client's cached MCP tool list.
58
+
39
59
  For local m1nd repo work, prefer the cheap trust selftest path before a full smoke:
40
60
 
41
61
  ```bash
@@ -54,6 +74,28 @@ retrieval. If the verdict is not `full_trust`, follow the embedded
54
74
  guessing the next move. The selftest is diagnostic-only: no ingest, repair,
55
75
  host refresh, graph mutation, or retrieval probe happens automatically.
56
76
 
77
+ If the verdict is `needs_ingest`, or `graph_state.node_count` is `0` while
78
+ `ingest` is available, treat it as a recoverable cold graph, not as a reason to
79
+ abandon m1nd. Call `ingest` on the same MCP binding with the absolute path of
80
+ the intended repo/workspace, never a managed runtime/session path such as
81
+ `~/.codex/m1nd-runtimes/...`, `~/.claude/m1nd-runtimes/...`, an Antigravity
82
+ agent runtime, or a generic `mcp-runtimes`/`agent-runtimes` folder. Host
83
+ integrations should prefer `M1ND_WORKSPACE_ROOT`; m1nd also recognizes common
84
+ workspace hints from Claude Code, Antigravity, Gemini, Cursor, Windsurf, VS
85
+ Code, and shell/package-manager env vars. Then rerun `session_handshake` and
86
+ one cheap retrieval. Fall back to direct files only when ingest is unavailable,
87
+ ingest fails, or a post-ingest retrieval still reports `blocked` and
88
+ `recovery_playbook`/`doctor` confirms stale binding or degraded host surface.
89
+
90
+ If `trust_selftest`, `session_handshake`, `recovery_playbook`, `doctor`,
91
+ `validate_plan`, or a retrieval response includes
92
+ `context_guard.wrong_workspace_binding=true`, do not classify the repo graph as
93
+ stale. The active binding is pointed at one workspace while the call asked about
94
+ another. Follow the embedded `recovery_playbook` payload, rebind the host with
95
+ `M1ND_WORKSPACE_ROOT` set to `requested_workspace_hint`, or explicitly ingest
96
+ that workspace on the same binding if the switch is intentional. Use
97
+ `federate_auto`/`federate` only when the task is genuinely cross-repo.
98
+
57
99
  If `trust_selftest` is not exposed but `session_handshake` is, call the cheaper
58
100
  sub-check:
59
101
 
@@ -61,6 +103,12 @@ sub-check:
61
103
  {"agent_id":"codex-m1nd"}
62
104
  ```
63
105
 
106
+ When the task names a target repo or absolute path, include it as `scope`:
107
+
108
+ ```json
109
+ {"agent_id":"codex-m1nd","scope":"/path/to/intended/repo"}
110
+ ```
111
+
64
112
  Treat its `trust_mode` as the session routing decision before relying on
65
113
  retrieval. If the mode is not `full_trust`, call `recovery_playbook` before
66
114
  guessing the next move. The playbook returns ordered recovery steps and a
@@ -28,20 +28,54 @@ Only skip the `m1nd` first pass when:
28
28
  - Prefer the live MCP surface over stale prose. If tool names, counts, or parameters matter, run the bundled helper from this skill directory: `python3 scripts/probe_m1nd.py tools`.
29
29
  - Keep `agent_id` stable within one investigation. Change it only when intentionally starting another role or another concurrent investigation.
30
30
  - Ingest first. Re-ingest after code changes, or use incremental ingest for code repos when appropriate.
31
+ - If a m1nd tool call fails with `Transport closed`, treat it as a host MCP
32
+ transport death, not as a graph, retrieval, or proof-state failure. Recovery
33
+ tools cannot run through a closed transport. Verify the local binary with the
34
+ repo smoke harness, kill stale `m1nd-mcp --stdio` processes if you own that
35
+ host, then restart/rebind the MCP client or open a fresh thread. After the
36
+ host relaunches the transport, run `trust_selftest` or `session_handshake`
37
+ before relying on retrieval.
38
+ - If the host is launching an old native runtime, use the external repair
39
+ helper from a m1nd source checkout: `m1nd restart --source /path/to/m1nd
40
+ --yes`. In live multi-agent sessions, add `--no-kill` and rebind only the
41
+ selected host. This helper does not ingest, choose a workspace, or refresh an
42
+ already-open client's cached MCP tool list.
31
43
  - If the live MCP surface exposes `trust_selftest`, call it first and route by
32
44
  `verdict` before relying on retrieval. `full_trust` means proceed with
33
45
  m1nd-first; `needs_ingest` means ingest the intended repo; `orientation_only`
34
46
  or `degraded_host_tool_surface` means use m1nd only for orientation and
35
47
  verify final truth with local files until the binding is refreshed;
36
- `stale_binding_suspected` means compare binding fingerprints and follow the
37
- recovery playbook before trusting retrieval.
48
+ `wrong_workspace_binding` means the active graph is healthy but bound to the
49
+ wrong repo for the requested scope; `stale_binding_suspected` means compare
50
+ binding fingerprints and follow the recovery playbook before trusting
51
+ retrieval.
38
52
  - If `trust_selftest` is not exposed but `session_handshake` is, call the
39
- handshake and route by `trust_mode` as the cheaper sub-check.
53
+ handshake and route by `trust_mode` as the cheaper sub-check. When the task
54
+ names a target repo or absolute path, pass it as `scope` so Context Guard can
55
+ detect cross-repo binding mistakes before retrieval.
40
56
  - If the selftest verdict or handshake trust mode is not `full_trust`, or
41
57
  retrieval returns `blocked`/zero candidates unexpectedly, call
42
58
  `recovery_playbook` before inventing the next step. Use its ordered steps and
43
59
  `binding_fingerprint` to compare host, stdio, HTTP, runtime root, graph paths,
44
60
  generation counters, and ingest roots.
61
+ - If a response includes `context_guard.wrong_workspace_binding=true`, stop the
62
+ normal stale-graph path. Rebind the MCP host with `M1ND_WORKSPACE_ROOT` set to
63
+ `requested_workspace_hint`, intentionally ingest that workspace on the same
64
+ binding, or use `federate_auto`/`federate` only when the investigation truly
65
+ spans repos. Do not treat this as proof that m1nd retrieval is broken.
66
+ - If `trust_selftest` or `session_handshake` reports `needs_ingest`, or the
67
+ mini `graph_state.node_count` is `0` while `ingest` is available, treat the
68
+ session as a recoverable cold graph. Do not jump straight to shell fallback.
69
+ Call `ingest` on the same MCP binding with the absolute intended
70
+ repo/workspace path, never a managed runtime/session path such as
71
+ `~/.codex/m1nd-runtimes/...`, `~/.claude/m1nd-runtimes/...`, an Antigravity
72
+ agent runtime, or a generic `mcp-runtimes`/`agent-runtimes` folder. Host
73
+ integrations should prefer `M1ND_WORKSPACE_ROOT`; m1nd also recognizes common
74
+ workspace hints from Claude Code, Antigravity, Gemini, Cursor, Windsurf, VS
75
+ Code, and shell/package-manager env vars. Then rerun `session_handshake` and
76
+ one cheap retrieval. Fall back only if ingest is unavailable, ingest fails,
77
+ or post-ingest retrieval is still blocked and `recovery_playbook`/`doctor`
78
+ confirms stale binding or degraded host surface.
45
79
  - If the host exposes `health` but not `trust_selftest`, `session_handshake`, or
46
80
  `recovery_playbook`, read `health.tool_surface_contract` and
47
81
  `health.host_binding_alignment`. Treat missing required host-visible tools as
@@ -116,6 +150,7 @@ Use the bundled probe script from this skill directory whenever the live runtime
116
150
  python3 scripts/probe_m1nd.py tools
117
151
  python3 scripts/probe_m1nd.py call health '{"agent_id":"codex-m1nd"}'
118
152
  python3 scripts/probe_m1nd.py call trust_selftest '{"agent_id":"codex-m1nd"}'
153
+ python3 scripts/probe_m1nd.py call session_handshake '{"agent_id":"codex-m1nd","scope":"/path/to/intended/repo"}'
119
154
  python3 scripts/probe_m1nd.py call recovery_playbook '{"agent_id":"codex-m1nd","observed_tool":"seek","observed_proof_state":"blocked","observed_candidates":0}'
120
155
  python3 scripts/probe_m1nd.py call help '{"agent_id":"codex-m1nd","tool_name":"validate_plan"}'
121
156
  python3 scripts/probe_m1nd.py run '[{"name":"ingest","arguments":{"agent_id":"codex-m1nd","path":"/path/to/repo"}},{"name":"seek","arguments":{"agent_id":"codex-m1nd","query":"where retry backoff is decided","top_k":5}}]'
@@ -10,6 +10,8 @@ Most hosts should point their MCP config at the same native binary:
10
10
  - Binary name: `m1nd-mcp`
11
11
  - Default launch args: `--stdio --no-gui`
12
12
  - Optional env override: `M1ND_MCP_BINARY=/absolute/path/to/m1nd-mcp`
13
+ - Compatibility alias accepted by the probe helper:
14
+ `M1ND_MCP_BIN=/absolute/path/to/m1nd-mcp`
13
15
 
14
16
  Use the bundled helper script to verify the current runtime instead of trusting memory:
15
17
 
@@ -128,6 +130,30 @@ When this skill starts feeling stale:
128
130
  3. Run `python3 scripts/probe_m1nd.py tools` against the local installed binary.
129
131
  4. Update this skill only where the live runtime or official docs actually changed.
130
132
 
133
+ ## External Restart Helper
134
+
135
+ When an agent sees `Transport closed`, an old binary version, stale host tools,
136
+ or repeated blocked retrieval after a good local graph, use an external restart
137
+ instead of trying to repair through the dead MCP binding:
138
+
139
+ ```bash
140
+ m1nd restart --source /path/to/m1nd --yes
141
+ ```
142
+
143
+ This command builds the latest source checkout, installs the native runtime to
144
+ the default m1nd binary path, and stops visible `m1nd-mcp` processes. It does
145
+ not refresh the host's cached tool list, choose a workspace, or ingest a graph.
146
+ After it runs, restart/rebind the host client and call `trust_selftest` or
147
+ `session_handshake` with the intended `scope`.
148
+
149
+ For live multi-agent sessions, prefer:
150
+
151
+ ```bash
152
+ m1nd restart --source /path/to/m1nd --yes --no-kill
153
+ ```
154
+
155
+ Then restart/rebind only the host that needs the new binary.
156
+
131
157
  ## Host-Specific Note For Codex
132
158
 
133
159
  At the protocol level, `m1nd`'s canonical tool names are bare names like `activate` and `validate_plan`.
@@ -10,7 +10,12 @@ import shutil
10
10
  from typing import Any
11
11
 
12
12
 
13
- DEFAULT_BINARY = os.environ.get("M1ND_MCP_BINARY") or shutil.which("m1nd-mcp") or "m1nd-mcp"
13
+ DEFAULT_BINARY = (
14
+ os.environ.get("M1ND_MCP_BINARY")
15
+ or os.environ.get("M1ND_MCP_BIN")
16
+ or shutil.which("m1nd-mcp")
17
+ or "m1nd-mcp"
18
+ )
14
19
  DEFAULT_ARGS = shlex.split(os.environ.get("M1ND_MCP_ARGS", "--stdio --no-gui"))
15
20
 
16
21
 
@@ -15,6 +15,10 @@ local file action.
15
15
 
16
16
  ## Startup Trust Loop
17
17
 
18
+ 0. If a tool call fails with `Transport closed`, stop treating it as graph
19
+ staleness. The MCP transport died before m1nd could run. Verify the binary
20
+ with a local smoke, restart/rebind the host MCP client or open a fresh
21
+ thread, then continue with this loop.
18
22
  1. Call `trust_selftest` if the host exposes it.
19
23
  2. If unavailable, call `session_handshake`.
20
24
  3. If only `health` is exposed, inspect `tool_surface_contract` and
@@ -22,6 +26,15 @@ local file action.
22
26
  4. If trust is not full, call or follow `recovery_playbook`.
23
27
  5. Only then rely on retrieval surfaces such as `search`, `seek`, or `activate`.
24
28
 
29
+ When the task names a concrete repo, worktree, or absolute path, pass it as
30
+ `scope` to `session_handshake`, `trust_selftest`, `recovery_playbook`, `doctor`,
31
+ or `validate_plan`. If the response reports
32
+ `context_guard.wrong_workspace_binding=true` or trust mode
33
+ `wrong_workspace_binding`, the host is bound to a different workspace than the
34
+ one you asked about. Rebind with `M1ND_WORKSPACE_ROOT`, intentionally ingest the
35
+ requested workspace on the same binding, or use explicit federation for real
36
+ cross-repo work. Do not call this graph staleness.
37
+
25
38
  `trust_selftest` and `recovery_playbook` are diagnostic. They do not ingest,
26
39
  repair, refresh the host, or mutate the graph.
27
40
 
@@ -40,6 +53,24 @@ repair, refresh the host, or mutate the graph.
40
53
 
41
54
  ## Recovery Rules
42
55
 
56
+ `Transport closed` is a host transport failure, not a m1nd proof-state. Do not
57
+ call `doctor`, `recovery_playbook`, or `ingest` through that dead binding. A
58
+ fresh MCP transport must be launched first.
59
+
60
+ If the host appears to be launching an old or stale native runtime, and a local
61
+ `m1nd` CLI is available outside the MCP transport, run:
62
+
63
+ ```bash
64
+ m1nd restart --source /path/to/m1nd --yes
65
+ ```
66
+
67
+ Then restart or rebind the host MCP client. `m1nd restart` is external repair:
68
+ it does not ingest, pick the workspace, or refresh a client's cached tool list
69
+ inside an already-open conversation.
70
+
71
+ In live multi-agent sessions, use `--no-kill` to install the updated managed
72
+ binary without stopping every active `m1nd-mcp` host.
73
+
43
74
  If `seek`, `search`, or `activate` returns `blocked`, zero candidates, or an
44
75
  unexpectedly empty graph after ingest, treat it as possible stale binding or
45
76
  session split-brain before blaming the repo.
@@ -74,6 +105,11 @@ and local file truth. It does not replace them.
74
105
  Keep `agent_id` stable within one investigation. Use trails, perspectives, and
75
106
  coverage sessions when work spans agents, branches, or sessions.
76
107
 
108
+ For host setup, prefer exporting `M1ND_WORKSPACE_ROOT` to the actual repository
109
+ or project root. Claude Code, Antigravity, Gemini, Cursor, Windsurf, VS Code,
110
+ and generic shells can expose their own workspace hints too, but
111
+ `M1ND_WORKSPACE_ROOT` is the portable contract.
112
+
77
113
  ## L1GHT
78
114
 
79
115
  Use `adapter="light"` for graph-native semantic markdown. Use