Shared memory and context tools for agentic work.
Code Rooms
# Agent Tasknotes
Operational notes from real agent usage of `m1nd`.
This file is not a polished roadmap. It is a running capture surface for
moments where an agent used `m1nd`, did not get the exact answer it needed,
and had to compensate.
The rule:
- if an agent reaches for shell/tools outside `m1nd` because the current
surface could not answer the real task directly, add a short note here
- keep notes concrete and falsifiable
- prefer one note per friction point
- when a note is resolved by code, move it to the resolved section with the
commit/PR reference
## Open Notes
### 2026-06-24 — OPTIONAL real local embeddings for `seek` (first cut, OFF by default)
- UPDATE 2026-06-27: `embed` is now ON by default in `m1nd-mcp` (the shipped
server has semantic recall out of the box; model fetched on first use, graceful
trigram fallback). The embedding cache is gitignored as a runtime artifact and
is not written when empty. Build a lean binary with `--no-default-features
--features serve`.
- Context: `seek`'s "semantic" slot was character-trigram TF-IDF over labels —
it cannot match intent queries whose words never appear in the node label.
- First cut: a cargo feature `embed` (OFF by default; `m1nd-core/embed`,
forwarded by `m1nd-mcp/embed`) wires FAST STATIC embeddings via `model2vec-rs`
(`potion-base-8M`, ~29 MB, MIT, L2-normalized; output dim probed at load).
Model chosen by deep research as the leanest all-rounder serving BOTH code and
l1ght prose in one space; `M1ND_EMBED_MODEL` overrides (e.g. potion-code-16M for
code-max, potion-multilingual-128M for non-English). `SemanticEngine::build`
computes a per-node embedding side-map over `label + provenance.excerpt`;
`seek` embeds the query once and blends `sem = 0.7*cosine + 0.3*legacy_trigram`
for Phase-1 survivors. `embeddings_used` in the response is now TRUTHFUL.
- HONESTY: these are STATIC embeddings — a real upgrade over label-only
trigrams, but NOT transformer-grade (no attention/contextualization). The
ONNX/bge tier is the path for maximal quality. No string should imply
transformer semantics.
- Deferred: embedding AST body text (not just the
excerpt); and the ONNX/transformer quality tier (runner-up: jina-v2-base-code
pure-Rust via candle, the right upgrade once nodes carry real bodies + an ANN
index). The model is gitignored under `m1nd-core/assets/`; it is
downloaded-on-first-use from Hugging Face (`DEFAULT_HF_REPO`) or pointed at a
vendored copy via `M1ND_EMBED_MODEL` — no model blob is committed.
### 2026-05-05 — scope normalization failures should prefill doctor recovery too
- Context: `seek`, `search`, and `activate` now attach `graph_state` and a
ready `doctor` recovery payload when retrieval returns `blocked` or zero
actionable candidates.
- Remaining friction: hard parameter errors, such as ambiguous auto-ingest
scopes, still return normal invalid-param recovery text rather than a
structured `doctor` payload.
- Desired behavior:
- invalid-param retrieval errors include compact graph/session breadcrumbs
when the active graph state is relevant
- scope/path normalization failures point at `doctor` with prefilled observed
fields
## Resolved Notes
### 2026-06-24 — embeddings now persist in a content-addressed cache (was: recomputed every build)
- Context: with `embed` on, `SemanticEngine::build` recomputed every node's
static embedding on every boot and re-ingest — a model load + N encodes each
time, the main cost of keeping `embed` warm.
- Resolution: a new `embed_cache.rs` sidecar (`EmbeddingCache`, bincode, atomic
temp+rename) keyed by a STABLE FNV-1a hash of `(model_id, label+excerpt)`.
`SemanticEngine::build_with_cache(graph, weights, cache_path, persist)` loads
the warm cache and reuses any vector whose `(model, text)` is unchanged,
re-embedding only changed/new nodes, then persists EXACTLY the current graph's
entries (self-pruning — no stale / cross-repo growth). The in-memory map stays
keyed by `NodeId`, so the `seek` path is untouched. The cache lives next to the
snapshot in `runtime_dir`, derived in `SessionState::initialize` and refreshed
by `rebuild_engines`. Advisory: any version/model/dim mismatch or corruption →
full recompute (never a wrong vector). `model_id` folds the weights-file byte
length, so an in-place model swap invalidates the cache. Read-only attachers
REUSE the cache but never write it (`persist=false`) — one writer per file,
honoring the read-only contract. All OFF by default behind `embed`.
- Still deferred: NodeStorage SoA embedding fields + an ANN index over the
persisted vectors (the next unlock — vector search over the whole graph).
### 2026-05-06 — agents need one startup verdict, not stitched diagnostics
- Context: `health`, `session_handshake`, and `recovery_playbook` exposed the
right primitives, but every agent still had to remember how to compose them
when a host binding was partial or retrieval looked stale.
- Resolution: `trust_selftest` now returns `m1nd-trust-selftest-v0` with a
single verdict (`full_trust`, `needs_ingest`, `orientation_only`,
`degraded_host_tool_surface`, or `stale_binding_suspected`), the binding
fingerprint, graph state, embedded session handshake, and an optional
recovery playbook. It is diagnostic-only: no ingest, repair, probe, or
mutation happens automatically.
- Follow-up: agents should call `trust_selftest` first when the live MCP
surface exposes it, fall back to `session_handshake` when it does not, and use
`recovery_playbook` only when the verdict is not `full_trust` or retrieval
evidence is suspicious.
### 2026-05-05 — session startup needs a cheap trust handshake
- Context: after adding `doctor` and degraded-surface diagnostics, the remaining
risk was making every agent run a heavy smoke or repeated retrieval probes at
the start of a session.
- Resolution: `scripts/mcp_agent_smoke.py` now has `--handshake-only`, returning
`m1nd-session-handshake-v0` with `trust_mode`, `can_ingest`, `can_retrieve`,
`can_recover`, tool-surface status, health summary, and next action. It calls
`doctor` only under suspicion, and `--handshake-probe` is opt-in.
- Follow-up: the same contract is now exposed as the official MCP
`session_handshake` tool. The smoke harness calls the tool when the live
surface supports it, and falls back to its local implementation for older
binaries.
### 2026-05-05 — recovery should be in-band, not chat memory
- Context: `session_handshake` could classify a session as trusted, needing
ingest, orientation-only, or degraded, but agents still needed remembered
operator doctrine to decide the next safe action.
- Resolution: `recovery_playbook` now returns `m1nd-recovery-playbook-v0` with
ordered recovery steps plus `m1nd-binding-fingerprint-v0`. The playbook is
diagnostic-only: no ingest, repair, probe, or filesystem mutation happens
automatically.
### 2026-05-05 — host MCP surfaces can hide required recovery tools
- Context: another agent saw m1nd through a host-provided surface where `audit`
was available but `ingest` was not exposed.
- Friction: without `ingest`, an agent cannot repair, refresh, or prove the
active graph from inside that host session, even if other m1nd tools respond.
- Resolution: `doctor` now accepts `observed_tool_count`, `available_tools`, and
`missing_tools` from `tools/list`, flags
`diagnostics.degraded_host_tool_surface`, and tells the agent to treat m1nd as
orientation-only until the MCP binding is refreshed. The smoke harness also
emits structured `degraded_host_tool_surface` details instead of a bare
missing-tool string.
- Follow-up: `health` now exposes `m1nd-tool-surface-contract-v0` and
`m1nd-host-binding-alignment-v0`, so even a partial host that only exposes
`health` can tell agents which tools should be visible and when the host is
showing a degraded binding.
### 2026-05-05 — retrieval responses need inline active-graph breadcrumbs
- Context: the new `doctor` tool could diagnose active graph/runtime/session
state after a stale-looking retrieval, but the retrieval response itself did
not include enough continuity breadcrumbs for instant self-recovery.
- Resolution: `seek`, `search`, and `activate` now include a compact
`graph_state` plus a ready `recovery.suggested_tool=recovery_playbook`
payload when they return `blocked` or zero actionable candidates. The smoke
harness also runs a negative seek after populated ingest to prove the
recovery payload and playbook exist.
### 2026-05-05 — injected MCP surface can lose graph state across ingest and seek
- Context: real agent smoke from a host-provided `m1nd` MCP surface after
re-ingesting the current repo.
- Friction: `ingest` returned a populated graph, but immediate `seek` calls
returned `proof_state=blocked` with `total_candidates_scanned=0`, forcing the
agent back to shell search for repo orientation.
- Cross-check: the local stdio binary on the same checkout exposed the full
tool surface and `ingest -> seek` scanned the expected graph candidates.
- Resolution: `doctor` now distinguishes empty graph, populated graph with
blocked/zero-candidate retrieval, missing ingest roots, unknown workspace
root, session gaps, and host-binding split-brain clues. The repo-local smoke
harness now proves `initialize/tools -> ingest -> seek -> help -> doctor`
over stdio and HTTP. HTTP tool dispatch also tracks `agent_id` before calling
the shared dispatcher, matching stdio session semantics more closely.
### 2026-04-05 — proactive write insights still lack runtime-backed mismatch signals
- Context: first proactive-insight slice on `apply` / `apply_batch`
- Friction: the system now emits useful structural guidance after writes, but it
still does not compare those edits against runtime overlay evidence
- `runtime_hotspot_mismatch`
- stronger cross-repo contract drift when federation is active
- per-insight latency budgets in benchmarks
### 2026-04-05 — daemon can tick for delta ingest, but it still is not a background watcher
- Context: daemon control plane + explicit `daemon_tick`
- Friction: the daemon can now poll watched roots and incrementally re-ingest
changed files, but it still needs an explicit tick call instead of a true
background filesystem / SCM watcher
- autonomous background ticks
- watchman/native notify acceleration
- latency budgets for `single-file changed -> alert available`
### 2026-04-05 — `audit` still composes more than it understands
- Context: first implementation of `m1nd.audit`
- Friction: `audit` is already useful, but it is still mainly an orchestrator
over existing tools, not yet a deep profile-specialized intelligence pass
- richer per-profile recommendations
- stronger `coordination` semantics around docs/config/reference truth
- stronger `production` semantics around runtime risk ranking
- Likely next step: strengthen the profile registry so `audit` changes not only
tool selection but also grading, recommendation logic, and narrative output
### 2026-04-05 — `federate_auto` now covers explicit paths, manifests, imports, route-level API matches, contract artifacts, and schema/component names, but deeper service discovery is still missing
- Context: `federate_auto` now bridges explicit path evidence, manifest/workspace
signals, package/import identity matches, shared `/api/...` routes, and basic
contract artifacts into repo candidates, namespaces, and optional one-shot federation
- Friction: repos that are only implied by multi-artifact service contracts,
behavior-level protocol flow, or deeper schema structure still need manual enumeration
- stronger schema discovery beyond token-level message/component/operation matches
- future semantic linking donor lane (stack-graphs / SCIP-class ideas)
### 2026-04-05 — `coverage_session` is useful but still shallow
- Context: real MCP smoke using `search`, `batch_view`, and `audit`
- Friction: coverage answers “what did I touch?” but not “what important area
did I still miss?” or “what should I inspect next?”
- importance-weighted unread files
- estimated remaining exploration
- per-tool coverage contribution
### 2026-04-05 — `federate_auto(scope="docs")` was polluted by non-doc semantic signals
- Context: real `execute=true` smoke on the live `m1nd` repo
- Root cause: semantic discovery lanes ignored the requested `scope`, so
import/API heuristics could outrank the explicit doc evidence and surface
nearby worktrees instead of the external repos actually referenced in docs
- Resolution: semantic discovery now respects scope and candidate ranking now
prefers stronger evidence families over weaker heuristic matches
- Landed in branch: `codex/m1nd-federate-field-hardening`
### 2026-04-05 — `cross_verify` counted symbol nodes as missing files
- Context: real MCP smoke on the `m1nd` repo returned a wildly inflated
`stale_confidence`
- Root cause: `cross_verify` treated all `file::...` IDs as file nodes,
including symbol IDs like `file::...::fn::...`
- Resolution: restricted graph-vs-disk comparison to `NodeType::File`
- Landed in branch: `codex/m1nd-audit-epic`
- Commit: `8b7f276`
### 2026-04-05 — `audit` replace-mode inherited stale ingest roots
- Context: sequential audit smokes across different repos
- Root cause: `replace` ingest kept older `ingest_roots`, contaminating later
path normalization and inventory
- Resolution: replace-mode now resets active ingest roots and updates
`workspace_root`
### 2026-04-05 — repo-wide isolation hypotheses returned weak evidence
- Context: the field report asked for orphan enumeration instead of
`inconclusive`
- Root cause: `hypothesize` only handled unary isolated claims after resolving a
concrete subject node
- Resolution: added repo-wide isolated/orphan claim parsing and degree-0 file
enumeration
- Commit: `e9d444d`