Vital Sign · Design Spec · m1nd-mcp (backend only)
A passive health signal that detects when a serving brain answers a request with a
foreign skeleton — a skeleton whose slug does not belong to that brain. Born from a real
incident where a brain bound to ~/m1nd served sk_keyvault_candidate for
days with no alarm.
Given the serving brain's identity (project_root basename, or a
display name when present) and the store's skeleton (skeleton_id + block ids),
return one of three honest answers:
ABSOLUTE: this is a vital sign, not a gate. It MUST NOT cause any read or write to fail, be refused, or change behavior. It only reports.
A session bound to the root brain ~/m1nd kept answering system_blocks_snapshot
with a store whose skeleton_id was sk_keyvault_candidate — a skeleton that
belonged to a different project (keyvault). For days nothing surfaced the
mismatch: the snapshot looked well-formed, the north packet read normally, no metric tripped.
The missing piece was a coherence check — the serving brain's identity vs. the served skeleton's slug — surfaced where operators and agents already look: the snapshot result and the orientation packet.
The engine already exists and is already pub. The maker's job is to surface it,
not to rewrite it. Verified present in the worktree:
// m1nd-mcp/src/skeleton_scan.rs:154
pub enum SkeletonCoherence {
Ok,
Mismatch { expected_slug: String, found_slug: String, reason: String },
}
// m1nd-mcp/src/skeleton_scan.rs:1473
pub fn skeleton_coherence(
project_root: Option<&str>,
display_name: Option<&str>,
skeleton: Option<(&str, &[String])>, // (skeleton_id, block_ids)
) -> Option<SkeletonCoherence>
display_name wins when non-empty; else basename_of(project_root)
(session.rs:519). Empty store ⇒ the whole call returns None ⇒ silent.sanitize_slug
(skeleton_scan.rs:1512): lowercase, non-alphanumeric → _, trim leading/trailing
_, empty → "repo". This is exactly what builds sk_<slug>_candidate
at skeleton_scan.rs:489 and sb_<slug>_… block ids.skeleton_id == "sk_<expected>" or
skeleton_id.starts_with("sk_<expected>_"). So sk_m1nd_candidate matches
expected m1nd — and sk_keyvault_candidate does not match expected m1nd.sb_<expected_slug>_; the first
offender becomes the reason.sk_ then _candidate; fall back to
sanitize_slug(skeleton_id). So a sk_keyvault_candidate served by the
m1nd brain yields Mismatch{expected_slug:"m1nd", found_slug:"keyvault"}.skeleton_scan uses to mint ids. The coherence engine already calls it. The surface code MUST
call skeleton_coherence() and MUST NOT invent a parallel sanitizer; otherwise a future drift
between mint-rule and check-rule silently re-opens the incident.skeleton_coherence fieldsystem_blocks_snapshot resultHandler: handle_system_blocks_snapshot (system_blocks_handlers.rs:70).
It already returns a READ-only JSON and already loads the store — the coherence field is computed from
the same load, adding zero new I/O.
{
"present": true,
"store_version": 1,
"block_count": 3,
"store": { … }
}
{
"present": true,
"store_version": 1,
"block_count": 3,
"skeleton_coherence": {
"status": "mismatch",
"expected_slug": "m1nd",
"found_slug": "keyvault",
"reason": "skeleton_id slug does not match …"
},
"store": { … }
}
{"status":"ok"}.{"status":"mismatch", expected_slug, found_slug, reason} —
names both slugs so the operator sees who-served-whose-skeleton.null) alongside the existing honest
"no skeleton yet" — silent, no false alarm.state.workspace_root (basename) / display name; skeleton_id +
block ids from the loaded SystemBlockStore.The orientation packet is composed in the HTTP routing layer (the caller of
project_brains::bootstrap, per project_brains.rs:242). When coherence is a
Mismatch, append one sickness line to the packet the agent reads on orientation:
{
"north": {
…
"skeleton_coherence": {
"status": "sick",
"expected_slug": "m1nd",
"found_slug": "keyvault",
"advice": "this brain is serving a foreign skeleton; rebind or re-ingest before trusting block scope"
}
}
}
Mismatch. Ok and empty-store
add nothing — no noise on healthy brains.bootstrap(); inject there. The packet is already built for every
orientation — this is one extra field, conditionally.Four cases. Two are incident-specific and MUST be added as tests; two are covered by existing engine tests and are listed for completeness.
| # | Serving brain identity | skeleton_id | block ids | Verdict | Why |
|---|---|---|---|---|---|
| 1 | ~/m1nd → slug m1nd |
sk_keyvault_candidate | sb_keyvault_… | Mismatch{expected:"m1nd", found:"keyvault"} |
The incident. expected m1nd; the served slug is keyvault. Both named. |
| 2 | ~/m1nd → slug m1nd |
sk_m1nd_candidate | sb_m1nd_… | Ok | Own-root skeleton. Healthy baseline — no false alarm. |
| 3 | (no store) | — | — | Silent (None) | Empty store = no signal. Snapshot says "no skeleton yet"; packet omits the line. |
| 4 | My-Repo → slug my_repo |
sk_my_repo_candidate | sb_my_repo_… | Ok | Sanitization is part of the rule: My-Repo → my_repo, and
sk_my_repo_candidate starts with sk_my_repo_. No false positive. |
Existing engine tests already proving the spine: skeleton_coherence_has_no_signal_without_a_skeleton,
skeleton_coherence_reuses_scan_slug_rules (case 4 family),
skeleton_coherence_reports_identity_and_block_mismatches — all in skeleton_scan.rs test module.
| File | Role | Action |
|---|---|---|
| m1nd-mcp/src/skeleton_scan.rs | Engine: SkeletonCoherence enum (:154),
skeleton_coherence() (:1473),
sanitize_slug (:1512). |
reuse No new sanitizer. Add the two incident tests (cases 1 & 4). |
| m1nd-mcp/src/system_blocks_handlers.rs | handle_system_blocks_snapshot (:70). |
wire Compute coherence from the loaded store + brain identity; emit skeleton_coherence. |
| m1nd-mcp/src/* (routing) | Where the north/orientation packet is composed after bootstrap(). |
wire On Mismatch, append the sickness line. Silent otherwise. |
| docs/ (snapshot + north surface) | Agent-facing doc describing the snapshot fields & the orientation packet. | doc gate Document the new field + sickness line. |
| m1nd-ui/** | The served web UI. | FORBIDDEN Do not touch. Backend signal only. |
skeleton_coherence present on system_blocks_snapshot for the
present:true arm; omitted/silent for the absent-store arm.Mismatch; absent on Ok and empty.cargo test -p m1nd-mcp --lib ·
cargo clippy -p m1nd-mcp --all-targets -- -D warnings ·
cargo fmt --check.Max Kle1nz <kleinz@cosmophonix.com>),
English, no AI mentions, no push.