Per head's parallel-prep brief while m/mBrian#73 (migration script +
[schema] node) is being built mBrian-side. NO mBrian-MCP-backed
implementation yet — the migration worker may refine the landed
node/edge shape and building the impl now risks rework.
Built ONLY the parts stable regardless of mBrian internals:
1. CONSUMER INVENTORY (docs/plans/slice-b-adapter-contract.md §1)
- Every *store.Store read method (15 methods) with signature + semantics
- Every call site across web/, internal/aggregate/, mcp/ — table form
- Item / ItemLink field-by-field shape contract: which fields come
direct from node columns, which from edge-walk, which from
metadata-unpack
- Direct pgxpool access flagged out-of-scope (admin counts, bulk
tx, links event-date update — slice C reworks those)
- Views (5j) explicitly NOT in scope per m's Q5=(a)
2. INTERFACE CONTRACT (store/adapter.go)
- ItemReader Go interface — 15 methods, pure projax-shaped structs
in/out, zero mBrian type leakage
- var _ ItemReader = (*Store)(nil) compile-time assertion proving the
existing pgx-backed *Store satisfies the contract today
3. SKELETON (store/adapter.go MBrianReader)
- Empty struct (mBrian client choice deferred to slice B impl)
- All 15 methods stubbed, return errNotImplementedSliceB
- var _ ItemReader = (*MBrianReader)(nil) keeps the stubs in lockstep
with the interface as slice B grows
- Each stub carries a one-line comment naming the §3 gap(s) it
resolves at impl time
- `go build ./...` green; `go vet ./store/` green
4. GAP FLAGS (docs/plans/slice-b-adapter-contract.md §3)
- item_links.rel free-form annotation → mBrian edge.note (add to
m/mBrian#73 §1 for the migration script)
- ItemLink.RefID per-rel-type extraction rule (caldav URL vs gitea
owner/repo vs mai project uuid)
- paths[] recomputation cost (per-request memoisation)
- AllTags aggregation (full-scan ok at m's scale; tag-graph deferred
per m's Q8)
- Roots / MaiOrphans "no outbound child_of edge" predicate
- ItemsCreatedInRange scoped to projax_origin marker
- Item.Source / SourceRefID constant + mai-edge-derived fields
- ItemLinkWithItem join shape (two queries + in-memory join vs bulk
MCP helper)
- Admin counts — recommend adding Counts(ctx) to ItemReader for cohesion
Stays parked after this. Slice B IMPL (mBrian-MCP client wiring + per-
method bodies + handler rename from s.Store.X to s.Items.X) waits on
the migration completing and uuid map landing.