feat(brain-mcp): read-only enumeration surface over HTTP (list/get/graph) — unblocks brain-audit's real read backend #71
Open
opened 2026-06-26 21:40:47 +00:00 by mathias
·
2 comments
No Branch/Tag Specified
main
fix/pipeline-writes-158
fix/edit-path-io-192
fix/create-regular-188
fix/guard-special-179
fix/linkcheck-keeps-write-178
fix/write-dir-redirect-173
fix/tunnel-detect-174
fix/pipeline-root-157
w3/154-mcp-auth-wiring
fix/tunnel-traversal
test/in-brain-targets-171
fix/brain-scan-root-157
fix/graph-wiki-root-157
fix/vectorstore-root-157
fix/notes-root-157
fix/search-root-157
fix/brainwide-root-157
fix/raw-symlinks-153
feat/symlink-tripwire-157
fix/rest-auth-149
fix/123-brain-edit-envelope-check
feat/106-page-aware-extraction
fix/105-source-drift-on-main
fix/104-surface-merge-conflicts-on-main
agent/b1-compile-on-ingest
agent/104-surface-merge-conflicts
agent/105-source-drift
agent/107-loud-unconfigured-alerting
feat/brain-read-edit
fix/capture-i1-refusal-names-target
renovate/configure
feat/consolidate-single-harness
icebox/cmd-routing
feat/brain-pending-promote
fix/close-session-classification-refresh
fix/capture-summarywriter
v0.24.0
v0.23.1
v0.23.0
v0.22.0
v0.21.1
v0.21.0
v0.20.1
v0.20.0
v0.19.1
v0.19.0
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.0
v0.16.1
v0.16.0
v0.15.0
v0.14.0
v0.13.2
v0.13.1
v0.13.0
v0.12.1
v0.12.0
v0.11.2
icebox/cmd-routing-2026-07-01
v0.11.1
v0.11.0
v0.10.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.0
v0.1.0
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#71
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Why
mathias/brain-gardenerPhase-1brain-audit(issue #2) needs to read the entire brain corpus (every entry, every wing) to compute graph-health checks — orphans, broken[[wikilinks]], dup pairs, dangling supersede chains. The current brain-mcp surfaces can't enumerate that:/query= BM25 search (top-N matches), not "list all".brain_get= single path. MCPbrain_query= search, same ceiling.So there is no read path that returns the full set of entries. brain-audit's spine is blocked on it.
Decision context (from brain-gardener#2, comment 1770)
To not block the Phase-1 milestone, brain-audit will ship an interim filesystem reader over a read-only checkout of
git.d-ma.be/mathias/brain(wiki/<wing>/<hall>/<slug>.md+knowledge/<slug>.md), behind abrain.Readerinterface. That's strictly read-only, gives the full corpus + frontmatter, and satisfies both brain-audit invariants (no brain-write verb; no internet egress).This issue is the proper long-term backend that drops in behind the same
brain.Readerinterface once it exists.Proposed scope — strictly read-only
Add to the brain-mcp HTTP surface (
ingestion/), authed like/query:/list(orbrain_list) — enumerate all entry paths, optionally filtered by wing/hall. Paginated. Returns{path, content_hash, frontmatter}without bodies (cheap manifest)./getover HTTP — already exists asbrain_geton MCP; expose the same read on HTTP so non-MCP Go consumers can fetch{path, frontmatter, body, content_hash}./graphover HTTP — expose the existingbrain_graphneighbors/subgraph ops so wikilink-graph checks don't have to reconstruct edges client-side.Hard constraint: read-only. No write/update/tunnel verbs on this surface. brain-audit's invariant #1 (no brain-write path in the binary) means the consumer must not even be able to mutate through this API.
Open questions / feedback wanted
brain.Readerseam makes the swap a one-file change.)ingestion/(the brain-mcp server) or is there a cleaner home given the #43 brain-interface analysis?/listwithout bodies + lazy/getper node, or a single streaming full-dump endpoint? The audit reads everything, so a bulk dump might be simpler than N+1 gets — but breaks the per-node access pattern other consumers want.Related: #43 (brain interface mismatch), #47 (read-after-write semantics — same read surface).
Approved scope. Ship FS reader now; this is the fast-follow.
Three answers:
1. Interim FS reader — yes, acceptable; do NOT wait on this issue.
The
brain.Readerseam makes the swap a one-file change, so blocking the Phase-1 end-to-end milestone on a different repo's new endpoint would be self-inflicted. Ship the FS reader now (verified viable againstmathias/brainHEAD — 674 md, correctwiki/<wing>/<hall>/shape). This HTTP surface drops in behind the same interface later.2. Home —
ingestion/is right, but sequence after #43.It's the brain-mcp server, so that's the correct module. One dependency check: if #43 (brain-interface mismatch) is about to relocate or restructure that surface, build #71 after #43's structural call — don't bake new endpoints into a module that's about to move. Not a block, just a one-line check before you start.
3. Bulk-dump vs N+1 — do both; it's not actually a fork.
/list→ bodiless manifest{path, content_hash, frontmatter}, paginated, wing/hall filter. Cheap./getaccepting a set of paths (or a streaming full-dump) → the audit's read-everything path./getstays for per-node consumers.The audit uses
/list+ bulk-fetch; other consumers use single/get. Bonus from the manifest'scontent_hash: the audit can skip-unchanged across runs later (incremental audits).Hard constraint (non-negotiable)
The entire surface must be physically incapable of mutation — not merely "exposes no write," but no write/update/tunnel verb reachable through this auth scope at all. brain-audit's invariant #1 (no brain-write path in the binary) must hold even against a compromised or buggy consumer. If a write verb is reachable through the same credential, this surface fails its purpose.
No rush — FS reader is the unblock; this lands when #43 settles.
Re-gated: unblocked, no consumer waiting. Optimisation, not a dependency.
Checked against live state during the ADR-0009 sprint (2026-08-22). This issue's premise no longer holds.
It opens with "brain-audit's spine is blocked on it." It is not. brain-gardener#2 shipped and closed, and brain-audit is running in production today: three worklist commits authored
brain-audit CIon 2026-08-22, latestreports/2026-08-22-audit.jsoncarrying 1668 findings across all eight checks (ul-drift1046,orphan569,stale-date28,malformed10,broken-link8,thin4,deindex2,ul-gap1). Orphan and broken-link are exactly the whole-corpus graph checks this issue said could not be computed without an enumeration API.It shipped on the interim filesystem reader over a read-only checkout — the fallback this issue itself proposed, behind the
brain.Readerseam. So the lean recorded here ("ship FS reader now, this later; the seam makes the swap a one-file change") was taken, and it worked.Status
Open, re-gated as an optimisation. Deliberately not closed: the design is sound and the seam it targets still exists. But nothing is waiting on it, so it should not read as blocking work.
What would make it actionable again — any one of:
/listmanifest being needed by something other than audit (a UI, a search index rebuild, brain-ui).One answer this issue asked for, now available
ingestion/— settled by ADR-0009 and hyperguild#91 part 2. brain-mcp stays insideingestion; there is no separate home to move a read surface to.Two design notes for whenever it is picked up, both from work that postdates this issue:
recall/getshapes, not new mechanism-named endpoints. ADR-0012 governs; a/listverb added today would be a fresh rule-1 violation.getwith a manifest mode, orrecallwith an enumerate strategy, fits the set designed on #80.Refs: brain-gardener#2 (closed, live), #43, #80, #91, ADR-0009 (infra PR #296), ADR-0012.