feat: brain_pending + brain_promote — close the raw→wiki curation loop (#38) #70

Merged
mathias merged 2 commits from feat/brain-pending-promote into main 2026-06-26 14:49:28 +00:00
Owner

Implements #38 — the human-facing complement to brain_write: list what's pending review and promote it into the structured wiki in one call.

What landed

  • brain_pending (MCP) / GET /pending (REST) — lists brain/raw/ notes oldest-first with {filename, created_at, size_bytes, excerpt}. Absent/empty raw/[], not an error.
  • brain_promote (MCP) / POST /promote (REST) — moves raw/<file>wiki/<wing>/<hall>/<slug>.md:
    • rewrites frontmatter — sets wing/hall/promoted_at, preserves created_at + custom fields (reuses the #45 frontmatter editor),
    • atomic: hall/wing/slug/collision validation before any fs change; write-then-delete, never move — a collision or write failure leaves raw/ intact (no silent overwrite, no lost source),
    • rebuilds the wing _index, runs auto-tunnel, re-indexes the graph (MCP path),
    • default slug = filename minus the YYYY-MM-DD- prefix.

Reconciliation (flagged in #45's dispatch)

#38 says raw/ → wiki/; #43 reframed the curation split as knowledge/ → wiki/. Ground truth: raw/ = the retrospective-skill review queue (1 note today); knowledge/ = ~150 legacy entries. I implemented #38 on raw/ per its spec — the ongoing pending queue. The knowledge/ bulk pile is #22's one-time migration, not this. Kept the two concerns separate.

Acceptance

  • brain_pending oldest-first with excerpt; empty/absent → []
  • brain_promote moves + rewrites frontmatter + deletes source
  • invalid hall → clear error before touching fs
  • slug collision → error, no overwrite, source preserved
  • auto-tunnel + _index regen after promote
  • write-then-delete (atomic; source survives write failure)
  • REST GET /pending + POST /promote
  • Tests: pending-with-files, pending-empty, promote happy, invalid-hall, collision, missing-source, traversal, index-rebuild (api + mcp layers)
  • task check green

Closes #38

🤖 Generated with Claude Code

Implements #38 — the human-facing complement to `brain_write`: list what's pending review and promote it into the structured wiki in one call. ## What landed - **`brain_pending`** (MCP) / **`GET /pending`** (REST) — lists `brain/raw/` notes oldest-first with `{filename, created_at, size_bytes, excerpt}`. Absent/empty `raw/` → `[]`, not an error. - **`brain_promote`** (MCP) / **`POST /promote`** (REST) — moves `raw/<file>` → `wiki/<wing>/<hall>/<slug>.md`: - rewrites frontmatter — sets `wing`/`hall`/`promoted_at`, **preserves `created_at` + custom fields** (reuses the #45 frontmatter editor), - **atomic**: hall/wing/slug/**collision** validation before any fs change; **write-then-delete, never move** — a collision or write failure leaves `raw/` intact (no silent overwrite, no lost source), - rebuilds the wing `_index`, runs auto-tunnel, re-indexes the graph (MCP path), - default slug = filename minus the `YYYY-MM-DD-` prefix. ## Reconciliation (flagged in #45's dispatch) #38 says `raw/ → wiki/`; #43 reframed the curation split as `knowledge/ → wiki/`. Ground truth: `raw/` = the retrospective-skill review queue (1 note today); `knowledge/` = ~150 legacy entries. I implemented #38 on **`raw/` per its spec** — the ongoing pending queue. The `knowledge/` bulk pile is **#22**'s one-time migration, not this. Kept the two concerns separate. ## Acceptance - [x] `brain_pending` oldest-first with excerpt; empty/absent → `[]` - [x] `brain_promote` moves + rewrites frontmatter + deletes source - [x] invalid hall → clear error **before touching fs** - [x] slug collision → error, **no overwrite**, source preserved - [x] auto-tunnel + `_index` regen after promote - [x] write-then-delete (atomic; source survives write failure) - [x] REST `GET /pending` + `POST /promote` - [x] Tests: pending-with-files, pending-empty, promote happy, invalid-hall, collision, missing-source, traversal, index-rebuild (api + mcp layers) - [x] `task check` green Closes #38 🤖 Generated with [Claude Code](https://claude.com/claude-code)
mathias added 2 commits 2026-06-26 14:34:40 +00:00
Closes the human curation loop: list brain/raw/ notes awaiting review
(oldest-first, with excerpt) and promote one into brain/wiki/<wing>/<hall>/.

PromoteNote rewrites frontmatter (sets wing/hall/promoted_at, preserves
created_at + custom fields via the existing frontmatter editor), rebuilds
the wing _index, and runs auto-tunnel. Atomic from the caller's view:
hall/wing/slug/collision validation happens before any fs change, and the
source is deleted only after the destination write succeeds (write-then-
delete, never move) — a collision or write failure leaves raw/ intact.
Default slug = filename minus the YYYY-MM-DD- prefix.

Also exposes GET /pending + POST /promote for shell scripts (bad
hall/collision/missing-source → 400, not 500).

Scope note: operates on raw/ (the retrospective-skill review queue) per
this issue's spec. The knowledge/ legacy pile is #22's bulk-migration
concern, not this ongoing queue.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat(mcp): brain_pending + brain_promote tools + REST routes (#38)
CI / Lint / Test / Vet (pull_request) Successful in 13s
CI / Mirror to GitHub (pull_request) Has been skipped
ef11864121
Wires the curation primitives into the MCP surface (all three sites:
tools() descriptors, handleCall dispatch, package doc) and registers the
GET /pending + POST /promote REST routes. brain_promote additionally
re-indexes the promoted note into the graph (best-effort), matching the
other write paths. brain_pending is the human-review-queue complement to
the agent-facing brain_write.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mathias merged commit 0454527b83 into main 2026-06-26 14:49:28 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mathias/hyperguild#70