Shared memory and context tools for agentic work.
Code Rooms
# Lifecycle, Document & Lock Tools
This page covers the in-session front door, graph ingestion, document runtime operations, health monitoring, plan validation, persistence, and subgraph locking with change detection.
---
<a id="m1ndnorth"></a>
## `north`
The in-session front door. Call `north(task)` **before reading or editing
anything**. In one round-trip it composes binding trust, task context (focus
nodes + PageRank anchors), prior cross-session memory (each claim with its real
age and author — absent, never faked, when unknown), a sufficiency signal, one
`next_move`, and `honest_gaps` (what m1nd does not yet know).
The packet also carries **`memory_exists`** — the ground-truth count of durable
L1GHT claims in the on-disk store. It exists so a beat that surfaces no
task-relevant memory (`memory: []`) never lies about an **empty store**: when the
store holds claims that simply did not match this task, `memory_exists` is `> 0`
and `honest_gaps` says the store has memory that did not match — the false
"no durable memory yet" line is emitted **only** when the store is truly empty.
**Packet budget.** The binding serializes the `ingest_roots` array exactly once
(in `binding.fingerprint`); `binding.graph_state` carries only the
`ingest_root_count`, never a duplicate copy of the array. Durable memory sidecars
in the `agent-memory` store collapse into the single store-directory root rather
than minting one ingest root per `.light.md` file, so the packet stays within its
2,000-token MCP budget as the memory store grows.
On first contact the packet may also carry a `reception` field (First-Contact
Reception, degraded mode): `reception.match == "caller_root_mismatch"` means the
bound graph does **not** cover your current repo (its root ≠ your resolved
caller root) — do not trust retrieval for this repo; read `reception.options[]`.
ONE call sets you up: `ingest` with `project_root=<your repo root>` creates a
per-project brain inside the served owner, ingests your repo into it, binds your
session to it, and returns its north packet in the same response — thereafter
every call from your root (this session or a brand-new one) routes to YOUR brain
automatically. It is `null` when your root matches the brain serving you (silent
bind is legal only on a match) or when the caller root is unknown (direct-HTTP
callers).
`north` composes `trust_selftest` + `orient` + `boot_memory` + `focus`. Reach
for those pieces directly only when you need just one.
When a SystemBlock store exists, `north` also carries its coherence vital sign
through `honest_gaps`. A mismatch names both the serving brain's expected slug
and the skeleton's found slug as a **signal only**; it never blocks reads or
writes. No store means no coherence line.
The `trust_selftest` / `session_handshake` / `recovery_playbook` trio is the
degraded/recovery lane — use it when trust looks off, retrieval is blocked, or a
binding is stale — not the default front door.
### Parameters
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `agent_id` | `string` | Yes | -- | Calling agent identifier. |
| `task` | `string` | No | -- | Natural-language description of what you are about to do. Focuses task context and the `next_move`. |
### When to Use
- **Session start** -- the first call before any read or edit, to pre-orient
- **Task switch** -- re-orient when the goal changes
- **After `needs_ingest`** -- `ingest` the repo, then call `north` again;
`needs_ingest` is a real answer for an empty or unbound graph, not a failure
### Related Tools
- [`ingest`](#m1ndingest) -- run after `north` returns `needs_ingest`
- [`trust_selftest`](#m1ndtrust_selftest) -- the degraded/recovery entry when trust looks off
- [`seek`](exploration.md#m1ndseek) -- first retrieval pass after orientation
<a id="m1ndingest"></a>
## `ingest`
Ingest or re-ingest a codebase, descriptor, or memory/document corpus into the graph. This is the primary way to load data into m1nd. It now supports code-first, structured-document, and universal document adapters.
| `path` | `string` | Yes | -- | Filesystem path to the source root or memory corpus. |
| `incremental` | `boolean` | No | `false` | Incremental ingest (code adapter only). Only re-processes files that changed since the last ingest. |
| `adapter` | `string` | No | `"code"` | Adapter to use for parsing. Values include `"code"`, `"json"`, `"memory"`, `"light"`, `"patent"`, `"article"`, `"bibtex"`, `"rfc"`, `"crossref"`, `"universal"`, and `"auto"` / `"document"` for format detection. |
| `mode` | `string` | No | `"replace"` | How to handle the existing graph. Values: `"replace"` (clear and rebuild), `"merge"` (add new nodes/edges into existing graph). |
| `namespace` | `string` | No | -- | Optional namespace tag for non-code nodes. Used by `memory` and `json` adapters to prefix node external_ids. |
### Example Request
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "ingest",
"arguments": {
"agent_id": "agent-1",
"path": "/path/to/project-f/backend",
"adapter": "code",
"mode": "replace",
"incremental": false
}
```
### Example Response
"files_processed": 335,
"nodes_created": 9767,
"edges_created": 26557,
"languages": { "python": 335 },
"elapsed_ms": 910.0
### Adapters
| Adapter | Input | Node Types | Edge Types |
|---------|-------|------------|------------|
| `code` | Source code directory | file, class, function, struct, module | imports, calls, registers, configures, tests, inherits |
| `json` | Graph snapshot JSON | (preserved from snapshot) | (preserved from snapshot) |
| `memory` | Markdown files | document, concept, entity | references, relates_to |
| `light` | L1GHT protocol markdown | document, section, entity, typed semantic nodes | explicit semantic edges from frontmatter and markers |
| `patent` / `article` / `bibtex` / `rfc` / `crossref` | Structured document formats | document, section, citation, entity | citation and cross-domain edges |
| `universal` | Best-effort document canonicalization | document, section, block, table, citation, entity, claim | document containment, references, bindings, supports |
| `auto` / `document` | Format detection wrapper | routes to the strongest detected adapter | adapter-specific |
### Mode Behavior
| Mode | Behavior |
|------|----------|
| `replace` | Clears the existing graph, ingests fresh, finalizes (PageRank + CSR). All perspectives and locks are invalidated. |
| `merge` | Adds new nodes and edges into the existing graph. Existing nodes are updated if they share the same external_id. Graph is re-finalized after merge. |
- **Session start** -- ingest the codebase if the graph is empty or stale
- **After code changes** -- re-ingest incrementally to update the graph
- **Multi-source** -- merge a memory corpus into a code graph for cross-domain queries
- **Federation preparation** -- use `federate` instead for multi-repo ingestion
### Side Effects
- **replace mode**: clears all graph state, invalidates all perspectives and locks, marks lock baselines as stale
- **merge mode**: adds to graph, increments graph generation, triggers watcher events on affected locks
- [`health`](#m1ndhealth) -- check graph status before deciding to ingest
- [`doctor`](#m1nddoctor) -- diagnose graph/session continuity when retrieval looks stale
- [`drift`](memory.md#m1nddrift) -- see what changed since last session
- [`federate`](exploration.md#m1ndfederate) -- multi-repo ingestion
- [`document_resolve`](#m1nddocument_resolve) -- resolve canonical artifacts for a universal document
- [`auto_ingest_start`](#m1ndauto_ingest_start) -- keep document roots synchronized after ingest
<a id="m1nddocument_resolve"></a>
## `document_resolve`
Resolve the canonical local artifact set for a universally ingested document by source path or universal node id.
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `agent_id` | `string` | Yes | Calling agent identifier. |
| `path` | `string` | No | Original source path or canonical markdown path. |
| `node_id` | `string` | No | Universal graph node id for the document. |
"id": 2,
"name": "document_resolve",
"path": "docs/specs/auth.md"
"source_path": "docs/specs/auth.md",
"canonical_markdown_path": "/tmp/m1nd-runtime/l1ght-cache/sources/abcd/canonical.md",
"canonical_json_path": "/tmp/m1nd-runtime/l1ght-cache/sources/abcd/canonical.json",
"claims_path": "/tmp/m1nd-runtime/l1ght-cache/sources/abcd/claims.json",
"producer": "universal:internal",
"section_count": 4,
"claim_count": 3,
"binding_count": 2
- when an agent needs the durable local artifact path
- when a doc has already been ingested and you want its canonical projection
- before opening `canonical.md` or `claims.json` directly
- [`document_bindings`](#m1nddocument_bindings)
- [`document_drift`](#m1nddocument_drift)
<a id="m1nddocument_provider_health"></a>
## `document_provider_health`
Report availability, mode, detail, and install hints for optional universal-document providers.
"python": "python3",
"providers": [
{ "name": "docling", "available": true, "mode": "broad-spectrum canonicalizer" },
{ "name": "grobid", "available": false, "mode": "scholarly pdf lane", "install_hint": "Set M1ND_GROBID_URL to a reachable GROBID service." }
]
- before assuming richer HTML/PDF/office extraction exists
- during environment setup
- when a provider-backed lane seems to be falling back unexpectedly
- [`ingest`](#m1ndingest)
- [`auto_ingest_status`](#m1ndauto_ingest_status)
<a id="m1nddocument_bindings"></a>
## `document_bindings`
Resolve deterministic document-to-code bindings for a universal document.
| `top_k` | `integer` | No | Maximum bindings to return. |
"bindings": [
"target_node_id": "file::src/auth/session.rs",
"target_label": "SessionPool",
"relation": "mentions_symbol",
"score": 0.92,
"confidence": "parsed",
"reason": "exact label match"
- when the question is “which code implements this doc?”
- when preparing an implementation map from a spec, paper, or note
- before editing code to match a document
- [`document_resolve`](#m1nddocument_resolve)
<a id="m1nddocument_drift"></a>
## `document_drift`
Analyze stale, missing, or ambiguous document/code bindings for a universal document.
"summary": {
"total_findings": 1,
"stale_bindings": 1,
"missing_targets": 0,
"ambiguous_targets": 0,
"unbacked_claims": 0,
"code_change_unreflected": 1
- after refactors or repo moves
- when document claims may no longer be backed by current code
- when a spec feels “probably stale” and you want a grounded first pass
<a id="m1ndauto_ingest_start"></a>
## `auto_ingest_start`
Start local-first document watchers for one or more roots and supported document families.
| `roots` | `string[]` | Yes | Filesystem roots to watch recursively. |
| `formats` | `string[]` | No | Supported document formats to auto-ingest. |
| `debounce_ms` | `integer` | No | Minimum quiet period before a change is eligible for ingestion. |
| `namespace` | `string` | No | Optional namespace for non-code document nodes. |
"id": 6,
"name": "auto_ingest_start",
"roots": ["/project/docs", "/project/wiki"],
"formats": ["universal", "light"],
"debounce_ms": 200
<a id="m1ndauto_ingest_status"></a>
## `auto_ingest_status`
Inspect the current auto-ingest runtime, queue depth, semantic counts, provider status, and provider route/fallback counts.
"running": true,
"queue_depth": 0,
"semantic_document_count": 12,
"semantic_claim_count": 34,
"drift_document_count": 1,
"provider_status": { "docling": true, "trafilatura": true, "grobid": false }
<a id="m1ndauto_ingest_tick"></a>
## `auto_ingest_tick`
Drain queued document changes immediately and apply them to the active graph.
"ingested_paths": ["/project/docs/specs/auth.md"],
"removed_paths": [],
"skipped_paths": [],
"errored_paths": []
<a id="m1ndauto_ingest_stop"></a>
## `auto_ingest_stop`
Stop active document watchers and persist the manifest state.
- [`auto_ingest_start`](#m1ndauto_ingest_start)
<a id="m1ndhealth"></a>
## `health`
Server health and statistics. Returns node/edge counts, query count, uptime, memory usage, plasticity state, and active sessions.
"name": "health",
"agent_id": "agent-1"
"status": "healthy",
"node_count": 9767,
"edge_count": 26557,
"queries_processed": 142,
"uptime_seconds": 3600.5,
"memory_usage_bytes": 52428800,
"plasticity_state": "active",
"last_persist_time": "2026-03-13T10:30:00Z",
"active_sessions": [
{ "agent_id": "agent-1", "last_active": "2026-03-13T11:25:00Z" }
- **Session start** -- verify the server is alive and the graph is loaded (prefer `north` to pre-orient; `health` is the raw liveness check)
- **Monitoring** -- periodic health checks in long sessions
- **Debugging** -- check memory usage and query counts
- [`north`](#m1ndnorth) -- composed in-session front door for orientation
- [`ingest`](#m1ndingest) -- load data if the graph is empty
- [`trust_selftest`](#m1ndtrust_selftest) -- one-call startup verdict for the degraded/recovery lane
- [`session_handshake`](#m1ndsession_handshake) -- classify whether this binding is trustworthy
- [`recovery_playbook`](#m1ndrecovery_playbook) -- return ordered recovery steps
- [`doctor`](#m1nddoctor) -- explain empty graphs, blocked retrieval, and binding/session continuity
- [`drift`](memory.md#m1nddrift) -- check what changed since last session
<a id="m1ndtrust_selftest"></a>
## `trust_selftest`
Returns a one-call trust verdict for agents. It composes the current binding
fingerprint, graph state, host-visible tool evidence, `session_handshake`, and
an optional `recovery_playbook`.
This is the degraded/recovery entry, not the default front door — reach for it
when trust looks off (blocked retrieval, `wrong_workspace_binding`, a
`Transport closed` error) or when you only need the trust layer. For normal
in-session orientation, call [`north`](#m1ndnorth), which composes this check
with `orient`, `boot_memory`, and `focus`.
The tool is diagnostic-only: it does not ingest, repair, run shell commands,
mutate files, refresh host bindings, or probe retrieval automatically.
| `observed_tool_count` | `integer` | No | -- | Tool count returned by the host client's `tools/list`. |
| `available_tools` | `array<string>` | No | `[]` | Tool names exposed by the host client. |
| `missing_tools` | `array<string>` | No | `[]` | Required tool names missing from the host client surface. |
| `observed_tool` | `string` | No | -- | Tool that produced a suspicious result. |
| `observed_proof_state` | `string` | No | -- | Observed proof state, such as `blocked`. |
| `observed_candidates` | `integer` | No | -- | Candidate count from suspicious retrieval. |
| `scope` | `string` | No | -- | Repo or scope path associated with the incident. |
| `error_text` | `string` | No | -- | Error text or host message. |
"id": 3,
"name": "trust_selftest",
"schema": "m1nd-trust-selftest-v0",
"ok": true,
"status": "ok",
"verdict": "full_trust",
"next_action": "proceed_with_m1nd_first",
"binding_fingerprint": {
"schema": "m1nd-binding-fingerprint-v0",
"process_id": 12345,
"node_count": 9767
},
"checks": {
"graph_populated": true,
"host_surface_complete": true,
"stale_binding_suspected": false,
"recovery_playbook_attached": false
"recovery_playbook": null
### Verdicts
- `full_trust` -- graph has content and the required recovery surface is present.
- `needs_ingest` -- graph is empty but `ingest` is available.
- `orientation_only` -- graph is empty and the current host surface cannot ingest.
- `degraded_host_tool_surface` -- the host is hiding required recovery tools.
- `wrong_workspace_binding` -- the requested `scope` points at a different
workspace than the active binding. Rebind with `M1ND_WORKSPACE_ROOT`, ingest
the requested workspace on the same binding, or use explicit federation for
intentional cross-repo work.
- `stale_binding_suspected` -- populated graph plus blocked/zero-candidate evidence suggests host/session split-brain.
- [`session_handshake`](#m1ndsession_handshake) -- cheaper sub-check used by the selftest
- [`recovery_playbook`](#m1ndrecovery_playbook) -- attached when the verdict needs action
- [`doctor`](#m1nddoctor) -- deeper runtime diagnosis when recovery asks for it
- [`ingest`](#m1ndingest) -- run only after `needs_ingest`
<a id="m1ndsession_handshake"></a>
## `session_handshake`
Classifies whether the current MCP binding is trustworthy before an agent leans
on retrieval. The tool is diagnostic-only: it does not ingest, repair, run shell
commands, or execute a retrieval probe.
Pass the host's `tools/list` evidence when available. That lets m1nd distinguish
a genuinely empty graph from a host surface that is hiding recovery tools such
as `ingest`.
| `scope` | `string` | No | -- | Absolute or repo-relative scope/path to validate against the active workspace binding. |
"name": "session_handshake",
"schema": "m1nd-session-handshake-v0",
"trust_mode": "full_trust",
"can_ingest": true,
"can_retrieve": true,
"can_recover": true,
"next_action": "continue with m1nd-first retrieval; use compiler/tests for runtime truth",
"runtime_root": "/tmp/m1nd-runtime",
"graph_path": "/tmp/m1nd-runtime/graph.json",
"graph_generation": 1,
"tool_surface": {
"degraded_host_tool_surface": false
"used_probe": false,
"probe": null
### Trust Modes
- `wrong_workspace_binding` -- the requested scope belongs to a different
workspace than the active binding. Follow `context_guard` and
`doctor_recovery` before retrieval.
- [`trust_selftest`](#m1ndtrust_selftest) -- preferred one-call startup verdict
- [`recovery_playbook`](#m1ndrecovery_playbook) -- what to do when trust mode is not full
- [`ingest`](#m1ndingest) -- load data after `needs_ingest`
- [`doctor`](#m1nddoctor) -- inspect the recovery payload under suspicion
- [`seek`](exploration.md#m1ndseek) -- first retrieval pass after `full_trust`
<a id="m1ndrecovery_playbook"></a>
## `recovery_playbook`
Returns deterministic next steps for a degraded host surface, empty graph,
orientation-only binding, or stale-looking retrieval. The tool is
diagnostic-only: it does not ingest, repair, run shell commands, mutate files,
or probe retrieval.
Use it after `session_handshake` reports anything other than `full_trust`, or
after a retrieval response reports `blocked` or zero candidates when the graph
should be populated.
If the incident involves an absolute path or another repository, pass it as
`scope`. The playbook returns `trust_mode=wrong_workspace_binding` and
`next_action=select_or_bind_workspace` when the active graph is healthy but the
call targeted a different workspace.
| `trust_mode` | `string` | No | -- | Prior handshake trust mode to preserve in the diagnostic trail. |
| `observed_candidates` | `integer` | No | -- | Candidate count from the suspicious retrieval. |
"id": 4,
"name": "recovery_playbook",
"observed_tool": "seek",
"observed_proof_state": "blocked",
"observed_candidates": 0
"schema": "m1nd-recovery-playbook-v0",
"status": "warn",
"trust_mode": "stale_binding_suspected",
"recovery_goal": "Prove whether host, binary, runtime, or graph identity drift is causing split-brain retrieval.",
"next_action": "call_doctor",
"steps": [
"id": "call_doctor",
"tool": "doctor",
"action": "Call doctor with the blocked or zero-candidate observation."
"id": "compare_binding_fingerprint",
"action": "Compare this binding_fingerprint with the host, repo-local stdio, and repo-local HTTP handshake outputs."
],
"non_claims": [
"No automatic repair was performed.",
"No ingest or graph mutation was performed."
- [`session_handshake`](#m1ndsession_handshake) -- classify the binding first
- [`doctor`](#m1nddoctor) -- inspect active graph/session/runtime clues
- [`ingest`](#m1ndingest) -- run only when the playbook says the graph needs it
<a id="m1nddoctor"></a>
## `doctor`
Diagnoses active graph, runtime, session, and stale-binding symptoms. Use it
when an agent just ingested a repo but retrieval returns `blocked`, zero
candidates, or a graph that feels empty.
`seek`, `search`, and `activate` include a ready `recovery` payload when they
return `blocked` or zero actionable candidates. An agent can pass
`recovery.arguments` directly to `doctor`.
Use the same tool for degraded host surfaces. If `tools/list` is missing
required recovery tools such as `ingest`, pass the observed count, available
tool names, and missing tool names to `doctor`. It will flag
`diagnostics.degraded_host_tool_surface` and explain whether the current host
binding should be treated as orientation-only.
If the suspicious call included a path from another repo, pass it as `scope`.
`doctor` will surface `context_guard.wrong_workspace_binding=true` and suggest
rebinding with `M1ND_WORKSPACE_ROOT`, same-binding ingest, or explicit
federation instead of diagnosing a stale graph.
| `observed_tool` | `string` | No | -- | Tool that returned a suspicious result. |
| `scope` | `string` | No | -- | Scope/path used by the suspicious call. |
"name": "doctor",
### Degraded Tool Surface Request
"observed_tool": "tools/list",
"observed_tool_count": 3,
"available_tools": ["seek", "audit", "doctor"],
"missing_tools": ["ingest"]
"schema": "m1nd-doctor-v0",
"diagnostics": {
"graph_has_nodes": true,
"agent_session_known": true,
"stale_binding_suspected": true,
"wrong_workspace_binding": false
"warnings": [
"seek reported blocked/zero-candidate retrieval while the active graph is populated"
"next_actions": [
"verify the same binding with stdio and HTTP smokes before declaring the graph stale"
- **After suspicious retrieval** -- distinguish empty graph from stale binding
- **After incomplete `tools/list`** -- identify a degraded host tool surface
- **After transport changes** -- confirm HTTP and stdio see the same session
- **Before shell fallback** -- give the agent a precise recovery path
- [`health`](#m1ndhealth) -- basic server health and graph counts
- [`ingest`](#m1ndingest) -- refresh graph state
- [`help`](exploration.md#m1ndhelp) -- tool guidance and examples
<a id="m1ndvalidate_plan"></a>
## `validate_plan`
Validate a proposed modification plan against the code graph. Detects gaps (affected files missing from the plan), risk level, test coverage, and suggested additions. Designed to be called before implementing a plan.
| `actions` | `object[]` | Yes | -- | Ordered list of planned actions. Each object has: `action_type` (string, required -- `"modify"`, `"create"`, `"delete"`, `"rename"`, `"test"`), `file_path` (string, required -- relative path), `description` (string, optional), `depends_on` (string[], optional -- other file_paths this action depends on). |
| `include_test_impact` | `boolean` | No | `true` | Analyze test coverage for modified files. |
| `include_risk_score` | `boolean` | No | `true` | Compute composite risk score. |
| `scope` | `string` | No | -- | Optional repo or scope path for multi-repo binding diagnostics. |
"name": "validate_plan",
"actions": [
{ "action_type": "modify", "file_path": "backend/session_pool.py", "description": "Add connection timeout" },
{ "action_type": "modify", "file_path": "backend/worker_pool.py", "description": "Update pool acquire to use timeout" },
{ "action_type": "test", "file_path": "backend/tests/test_session_pool.py" }
"actions_analyzed": 3,
"actions_resolved": 3,
"actions_unresolved": 0,
"gaps": [
"file_path": "backend/config.py",
"node_id": "file::config.py",
"reason": "imported by modified file session_pool.py -- timeout config likely needed here",
"severity": "warning",
"signal_strength": 0.72
"file_path": "backend/process_manager.py",
"node_id": "file::process_manager.py",
"reason": "in blast radius of worker_pool.py -- calls worker_pool.submit",
"severity": "info",
"signal_strength": 0.45
"risk_score": 0.52,
"risk_level": "medium",
"test_coverage": {
"modified_files": 2,
"tested_files": 1,
"untested_files": ["backend/worker_pool.py"],
"coverage_ratio": 0.5
"suggested_additions": [
{ "action_type": "modify", "file_path": "backend/config.py", "reason": "Timeout configuration likely needed" },
{ "action_type": "test", "file_path": "backend/tests/test_worker_pool.py", "reason": "Modified file has no test action in plan" }
"blast_radius_total": 47,
"elapsed_ms": 35.0
### Risk Levels
| Level | Score Range | Meaning |
|-------|------------|---------|
| `"low"` | < 0.3 | Small, well-tested change |
| `"medium"` | 0.3 -- 0.6 | Moderate scope, some gaps |
| `"high"` | 0.6 -- 0.8 | Large scope or missing tests |
| `"critical"` | >= 0.8 | Very high risk -- review carefully |
- **Before implementing** -- validate your plan catches all affected files
- **PR review** -- validate that a PR's changes are complete
- **Planning** -- estimate risk and scope before committing to a plan
- **Quality gate** -- reject plans with risk_score > threshold
- [`impact`](analysis.md#m1ndimpact) -- blast radius for a single node
- [`predict`](analysis.md#m1ndpredict) -- co-change prediction for a single node
- [`trace`](exploration.md#m1ndtrace) -- validate a fix plan for a specific error
<a id="m1ndlockcreate"></a>
## `lock_create`
Pin a subgraph region and capture a baseline snapshot for change monitoring. Locks are used to track what changes in a region of the graph while you work. The baseline is compared against the current state when you call `lock.diff`.
| `agent_id` | `string` | Yes | -- | Calling agent identifier. Lock is owned by this agent. |
| `scope` | `string` | Yes | -- | Scope type. Values: `"node"` (single nodes only), `"subgraph"` (BFS expansion from roots), `"query_neighborhood"` (nodes matching a query), `"path"` (ordered node list). |
| `root_nodes` | `string[]` | Yes | -- | Root nodes for the lock scope. Non-empty. Matched by external_id (exact), then label, then substring. |
| `radius` | `integer` | No | -- | BFS radius for `subgraph` scope. Range: 1 to 4. Required for subgraph scope. |
| `query` | `string` | No | -- | Query string for `query_neighborhood` scope. |
| `path_nodes` | `string[]` | No | -- | Ordered node list for `path` scope. |
### Scope Types
| Scope | Description |
|-------|-------------|
| `node` | Lock only the specified root nodes |
| `subgraph` | BFS expansion from root nodes up to `radius` hops |
| `query_neighborhood` | Nodes matching a query activation |
| `path` | An ordered list of nodes forming a path |
"name": "lock_create",
"scope": "subgraph",
"root_nodes": ["file::chat_handler.py"],
"radius": 2
"lock_id": "lock_agent1_001",
"baseline_nodes": 1639,
"baseline_edges": 707,
"graph_generation": 42,
"created_at_ms": 1710300000000
### Limits
- Max locks per agent: configurable (default: 10)
- Max baseline nodes: configurable (default: 5000)
- Max baseline edges: configurable (default: 10000)
- Total memory budget shared with perspectives
- **Change monitoring** -- lock a region before making changes, then diff to see what changed
- **Multi-agent coordination** -- lock regions to detect when other agents' changes affect your work
- **Regression detection** -- lock a stable region and watch for unexpected changes
- [`lock_watch`](#m1ndlockwatch) -- set automatic change detection
- [`lock_diff`](#m1ndlockdiff) -- compute what changed since baseline
- [`lock_release`](#m1ndlockrelease) -- release the lock when done
<a id="m1ndlockwatch"></a>
## `lock_watch`
Set a watcher strategy on a lock. Watchers determine when the lock automatically detects changes. Without a watcher, you must manually call `lock.diff`.
| `agent_id` | `string` | Yes | -- | Calling agent identifier. Must own the lock. |
| `lock_id` | `string` | Yes | -- | Lock to set the watcher on. |
| `strategy` | `string` | Yes | -- | Watcher strategy. Values: `"manual"` (no automatic detection), `"on_ingest"` (detect after every ingest), `"on_learn"` (detect after every learn call). Note: `"periodic"` is not supported in V1. |
"id": 5,
"name": "lock_watch",
"strategy": "on_ingest"
"strategy": "on_ingest",
"previous_strategy": null
- **Automatic monitoring** -- set `on_ingest` to detect changes after every code re-ingest
- **Learning feedback** -- set `on_learn` to detect when learning shifts edge weights in your region
- **Manual control** -- set `manual` to disable automatic detection
- [`lock_diff`](#m1ndlockdiff) -- manually trigger a diff (always available regardless of strategy)
- [`lock_create`](#m1ndlockcreate) -- create the lock first
<a id="m1ndlockdiff"></a>
## `lock_diff`
Compute what changed in a locked region since the baseline was captured. Returns new/removed nodes, new/removed edges, weight changes, and watcher event counts. Fast-path: if the graph generation has not changed, returns immediately with `no_changes: true`.
| `lock_id` | `string` | Yes | -- | Lock to diff. |
"name": "lock_diff",
"lock_id": "lock_agent1_001"
### Example Response (changes detected)
"diff": {
"no_changes": false,
"new_nodes": ["file::chat_handler.py::fn::new_method"],
"removed_nodes": [],
"new_edges": ["chat_handler.py|new_method->stream_parser.py|calls"],
"removed_edges": [],
"boundary_edges_added": [],
"boundary_edges_removed": [],
"weight_changes": [
{ "edge_key": "chat_handler.py|stream_parser.py|imports", "old_weight": 0.5, "new_weight": 0.72 }
"baseline_stale": false,
"elapsed_ms": 0.08
"watcher_events_drained": 2,
"rebase_suggested": null
### Example Response (no changes)
"no_changes": true,
"new_nodes": [],
"new_edges": [],
"weight_changes": [],
"elapsed_ms": 0.001
"watcher_events_drained": 0,
- **After ingest** -- check if your locked region was affected
- **After learning** -- check if feedback shifted weights in your region
- **Periodic check** -- poll for changes during long sessions
- **Before committing** -- verify no unexpected changes in the region
- [`lock_rebase`](#m1ndlockrebase) -- re-capture baseline after acknowledging changes
<a id="m1ndlockrebase"></a>
## `lock_rebase`
Re-capture the lock baseline from the current graph without releasing the lock. Use this after calling `lock.diff` and acknowledging the changes -- the new baseline becomes the reference for future diffs.
| `lock_id` | `string` | Yes | -- | Lock to rebase. |
"id": 7,
"name": "lock_rebase",
"previous_generation": 42,
"new_generation": 45,
"baseline_nodes": 1645,
"baseline_edges": 712,
"watcher_preserved": true
- **After acknowledging changes** -- rebase after reviewing a diff to reset the baseline
- **After stale warning** -- when `lock.diff` returns `baseline_stale: true`, rebase to fix it
- **Periodic refresh** -- rebase periodically in long sessions to keep baselines current
- [`lock_diff`](#m1ndlockdiff) -- the diff that triggers a rebase
- [`lock_create`](#m1ndlockcreate) -- creating a new lock is an alternative to rebasing
<a id="m1ndlockrelease"></a>
## `lock_release`
Release a lock and free its resources. Removes the lock state, cleans up pending watcher events, and frees memory. Irreversible.
| `lock_id` | `string` | Yes | -- | Lock to release. |
"id": 8,
"name": "lock_release",
"released": true
- **Done monitoring** -- release when you no longer need change detection
- **Memory pressure** -- locks consume memory proportional to baseline size
- **Session end** -- release all locks before ending a session
- **Automatic**: locks are also cascade-released when their associated perspective is closed via `perspective.close`
- [`lock_create`](#m1ndlockcreate) -- create a new lock
- [`perspective_close`](perspectives.md#m1ndperspectiveclose) -- cascade-releases associated locks
<a id="m1nddaemon_start"></a>
## `daemon_start`
Arm the per-brain code daemon: persist the watched roots (empty = the brain's own ingest roots) and initialize the daemon counters. Arming is a per-brain opt-in — the durable state lives in the brain's own store dir, survives owner restarts AND LRU eviction (the daemon re-arms on the next warm-boot/resolve), and the factory default is OFF.
**Freshness is honest, not continuous.** On a served (HTTP) owner ticks advance BY TRAFFIC — any non-recall verb touching the brain runs a due tick ("fresh when seen") — or via an explicit `daemon_tick`. Only a stdio owner additionally holds a live watch-event consumer and an idle clock. No surface claims a free-running monitor; `watch_backend` reports `native_fs` only while a real notify watcher exists.
Bursts coalesce: a branch checkout becomes ONE detection whose full changed set enters a persisted backlog, drained a bounded slice per tick (`max_files`) — no file is lost to truncation. After a burst settles (45 s quiet window, pushed by every activity tick), the daemon auto-reconciles the RATIFIED system-blocks store: it yields voluntarily to a live `candidate_lease`, keys the write on a fresh `store_version`, and gives OCC exactly one retry before raising an `auto_reconcile_conflict` alert.
| `watch_paths` | `string[]` | No | current ingest roots | Paths the daemon should watch (the per-brain default is the brain's own ingest roots). |
| `poll_interval_ms` | `integer` | No | `500` | Traffic/idle tick due-interval in milliseconds. |
- Opting a brain into standing freshness (per-brain, durable, default OFF)
- Before relying on daemon alerts or `daemon_tick`
- Before background/idle reconciliation should run
- [`daemon_status`](#m1nddaemon_status)
- [`daemon_tick`](#m1nddaemon_tick)
- [`alerts_list`](#m1ndalerts_list)
<a id="m1nddaemon_stop"></a>
## `daemon_stop`
Stop the daemon control plane without deleting persisted alert history.
- End of a daemon-backed session
- Before shutting down a host that should not keep reconciling
- [`daemon_start`](#m1nddaemon_start)
<a id="m1nddaemon_status"></a>
## `daemon_status`
Inspect daemon liveness and runtime counters. Returns watched roots, tracked files, recent tick metrics, and alert counts.
### Typical Output Fields
- `active`
- `watch_paths`
- `poll_interval_ms`
- `tracked_files`
- `tick_count`
- `last_tick_duration_ms`
- `last_tick_changed_files`
- `last_tick_deleted_files`
- `last_tick_alerts_emitted`
- `alert_count`
- To verify daemon startup worked
- To inspect whether reconciliation is actually happening
- To debug daemon slowness or alert silence
<a id="m1nddaemon_tick"></a>
## `daemon_tick`
Run one explicit daemon reconciliation pass. Polls watched roots, re-ingests changed files, detects deletions, and emits drift alerts.
| `max_files` | `integer` | No | `32` | Maximum changed files to process in one tick. |
- `changed_files_detected`
- `deleted_files_detected`
- `files_reingested`
- `ingested_files[]`
- `alerts_emitted`
- `alert_ids[]`
- `tick_at_ms`
- To force one reconciliation before reading daemon status
- To debug watched-root drift deterministically
- To reproduce daemon ingest issues outside background ticking
- [`cross_verify`](../api-reference/exploration.md#m1ndcross_verify)
<a id="m1ndalerts_list"></a>
## `alerts_list`
List persisted daemon and proactive alerts.
| `include_acked` | `boolean` | No | `false` | Include already acknowledged alerts. |
| `limit` | `integer` | No | `50` | Maximum alerts to return. |
- Reviewing daemon findings after a session
- Building an alert inbox for an agent or UI
- [`alerts_ack`](#m1ndalerts_ack)
<a id="m1ndalerts_ack"></a>
## `alerts_ack`
Acknowledge one or more persisted daemon/proactive alerts so they stop resurfacing in the unread queue.
| `alert_ids` | `string[]` | Yes | Alert IDs to acknowledge. |
- After reviewing or actioning daemon findings
- To keep the alert queue focused on new drift
<a id="m1ndedit_preview"></a>
## `edit_preview`
Preview a full-file write without touching disk. Returns a diff, freshness snapshot, and validation report so the caller can inspect before committing.
| `file_path` | `string` | Yes | Absolute or workspace-relative file path. |
| `new_content` | `string` | Yes | Candidate replacement content. |
| `description` | `string` | No | Human-readable summary of the edit. |
- Before risky writes
- When you want a two-phase edit protocol
- When a human or another agent should inspect the diff first
- [`edit_commit`](#m1ndedit_commit)
- [`apply`](../api-reference/lifecycle.md)
<a id="m1ndedit_commit"></a>
## `edit_commit`
Commit a previously previewed edit after freshness re-check and explicit confirmation.
| `preview_id` | `string` | Yes | Preview handle returned by `edit_preview`. |
| `confirm` | `boolean` | Yes | Must be `true` to commit the preview. |
| `reingest` | `boolean` | No | Re-ingest the modified file after commit. |
- After a human/agent approves an `edit_preview`
- When stale-source protection matters more than speed
- [`edit_preview`](#m1ndedit_preview)
<a id="m1ndpersist"></a>
## `persist`
Force graph and sidecar persistence immediately.
| `action` | `string` | Yes | Persistence action, such as save/load semantics supported by the current implementation. |
- Before shutdown
- Before risky host lifecycle transitions
- When you want an explicit persistence checkpoint
- [`health`](#m1ndhealth)
- [`boot_memory`](#m1ndboot_memory)
<a id="m1ndboot_memory"></a>
## `boot_memory`
Persist small canonical hot-state values next to the graph without polluting larger investigation trails.
| `action` | `string` | Yes | Memory action (`set`, `get`, `list`, `delete`, etc.). |
| `key` | `string` | No | Canonical key to address. |
| `value` | `json` | No | JSON value to store. |
- Short doctrine/state values that should stay hot
- Session bootstrapping facts an agent should retrieve quickly
- [`persist`](#m1ndpersist)
- [`trail_save`](memory.md#m1ndtrailsave)
<a id="m1ndheuristics_surface"></a>
## `heuristics_surface`
Explain why a node or file is currently ranked as risky or important. Surfaces trust/tremor/antibody/blast-style heuristic factors in one payload.
| `node_id` | `string` | No | Graph node to inspect. |
| `file_path` | `string` | No | File path to inspect. |
- After `predict`, `validate_plan`, or surgical flows rank something unexpectedly high
- When an agent needs explainability before editing or escalating
- [`validate_plan`](#m1ndvalidate_plan)
- [`apply_batch`](../api-reference/lifecycle.md)
<a id="m1ndaudit"></a>
## `audit`
Profile-aware one-call audit over topology, scans, verification, filesystem truth, and git state.
| `path` | `string` | Yes | Root path to audit. |
| `profile` | `string` | No | Audit profile such as `auto`, `quick`, `coordination`, or `production`. |
| `depth` | `string` | No | Audit depth. |
| `cross_verify` | `boolean` | No | Include graph-vs-disk verification. |
| `external_refs` | `boolean` | No | Include explicit external reference discovery. |
- First pass on an unfamiliar repo
- Long-running session orientation
- Pre-handoff or pre-merge structural review
- [`batch_view`](../api-reference/exploration.md#m1ndbatch_view)
- [`coverage_session`](../api-reference/exploration.md#m1ndcoverage_session)