Files
waggle-os/docs/ux-refactor/deltas/backend-api-delta.md
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

39 KiB
Raw Permalink Blame History

Backend API Delta — Waggle OS UX Refactor (Master List)

Purpose. The single, consolidated, de-duplicated, ordered master list of every backend endpoint the UX refactor must build or extend, plus every .mind/relational schema migration required. This is the build contract for the LOCKED execution model: in-place incremental refactor of apps/web + targeted local Fastify sidecar extensions. Every endpoint is built over the existing substrate — no new database, minimal-to-zero SQLite migration (see §M).

Sources (all read & grounded): PRD §16 (docs/.../Waggle_OS_UX_Refactor_PRD.md:1060-1158), PRD §8/§21 phase+sprint structure (:212-253, :1304-1374), PRD §15 data model (:918-1057); the 22 gap cards (docs/ux-refactor/gap-cards/S00S21); the route/substrate inventories (docs/ux-refactor/_inventory/{backend-routes,substrate-types,frontend}.md); the audited backend-map (docs/backend-map/sections/03a03g); and spot-verified live source under packages/server/src/local/routes/*.ts, packages/server/src/local/workspace-state.ts, packages/hive-mind-core/src/{workspace-manager,mind/schema,mind/db}.ts, packages/core/src/{install-audit,cron-store}.ts.

Scope. Everything is the Local Sidecar (packages/server/src/local/index.tsbuildLocalServer(), loopback :3333, flat /api/*, Bearer session-token). The desktop frontend talks ONLY to this server. The Clerk-gated Cloud server (packages/server/src/routes/*.ts) is out of scope — where its routes collide with PRD paths (notably /api/agents/*) the sidecar work is still net-new locally and flagged.


How to read this

Each row carries:

  • Method + Path — the PRD/refactor contract path (PRD-literal where §16 names it).
  • DispositionNET-NEW (no route serves this; build it) · EXTEND (a real handler exists; add alias/param/field/behavior) · NET-NEW (thin dispatcher/alias) (new path, delegates wholly to existing handlers, no new logic).
  • Build target — the exact route file to create or the existing file/handler/builder to extend (with line where load-bearing). Verified absent: agents.ts, artifacts.ts, home.ts, command.ts, mcps.ts, automations.ts, quick-capture.ts do not exist under packages/server/src/local/routes/ (grep-confirmed) — all are net-new files.
  • Substrate — the store(s) it reads/writes.
  • Shape — a 35 line request/response sketch.
  • Screens — gap-card IDs that consume it.

Counts are in §Counts at the bottom. De-dup note: §16 lists 65 endpoints but several are consumed by multiple screens (e.g. /api/workspaces/:id/state → S01+S02; /api/skills/* → S06+S19; /api/agents/* → S09+S18; the cron→automations aliases → S11+S20; connector/MCP → S07+S08+S14+S17; harvest → S15+S16). This master list states each endpoint once, attributing all consuming screens. Endpoints that EXIST as-is with zero backend work (e.g. GET /api/workspaces, GET /api/connectors, GET /api/memory/graph, the team CRUD core, the harvest engine) are excluded — they need only FE wiring. Only NET-NEW + EXTEND backend work is listed.


Phase 0 — Architecture alignment (PRD §8 Phase 0 / §21 Sprint 1)

No new endpoints. Backend-relevant work is type alignment + shared additive fields that later phases write through. Land these first because Phase 15 write paths depend on them.

Item Disposition Build target Substrate Notes / shape
WorkspaceConfig V2 additive fields EXTEND (no route, no migration) packages/hive-mind-core/src/workspace-manager.ts:5-58 (interface) + CreateWorkspaceOptions :60-95 workspace.json (file, NOT SQLite) Add optional description, type(WorkspaceType), status('active'|'paused'|'archived'), agentIds[], connectorIds[], mcpIds[], updatedAt, lastActiveAt. Default status:'active'; derive type from templateId/group for existing workspaces. No DB migration (JSON file). Consumed by S02/S17.
Stamp updatedAt on write EXTEND workspace-manager.ts:222 (update() currently stamps nothing but riskClassifiedAt) workspace.json One-line write-side touch.
Stamp lastActiveAt EXTEND agent loop / chat route write-back workspace.json Currently lastActive is DERIVED at read from session mtimes (workspace-context.ts:375-387); persist it.
Shared frontend type unions EXTEND (FE only) apps/web/src/lib/types.ts Add WorkspaceType, Scope, Confidence, MemoryKind, ArtifactKind, AgentType, AutonomyLevel, ExtensionType (PRD §15.2). Reconcile FE MemoryFrame/Workspace lossy projections against API shapes (substrate-types §e).

Phase 1 — Core runtime: Home, Workspace Desktop, Command Center (PRD §8 Phase 1 / §21 Sprint 23)

1a. Home Cockpit + Quick Capture (S01) — new home.ts + extend memory.ts

Method + Path Disposition Build target Substrate Shape Screens
GET /api/home/briefing NET-NEW new routes/home.ts; fans buildWorkspaceState() (workspace-state.ts:234) / buildWorkspaceNowBlock() (workspace-context.ts:191) over WorkspaceManager.list() and ranks memory_frames, session JSONL, awareness, cron_schedules, identity (for name) → { greeting, userName, date, workspaces:[{id,name,rank,summary,pending,nextActions}], suggestedActions[] }. Cross-workspace ranking aggregator (per-workspace builder is the seed; no cross-WS ranker exists today). S01
GET /api/home/overnight NET-NEW new routes/home.ts; aggregates over since-last-login window events/ai_interactions, notifications, cron_execution_history, memory_frames ?since=<iso> → { memoriesAdded, artifactsCreated, automationsCompleted, failures:[{source,error}], window:{from,to} }. No time-windowed delta exists today. S01
POST /api/quick-capture EXTEND (thin handler delegating to memory write) routes/memory.ts POST /api/memory/frames (:248) as the write primitive; new thin handler or alias memory_frames (personal .mind) + awareness (for kind:task) + POST /api/ingest (for kind:file) { kind:'note'|'task'|'link'|'file', content, workspaceId? } → { frameId }. Defaults to personal mind, stamps source:'quick-capture'; task also writes an awareness row so it surfaces in nextActions. No migration. S01

1b. Workspace Desktop (S02) — extend workspaces.ts

Method + Path Disposition Build target Substrate Shape Screens
GET /api/workspaces/:id/state EXTEND (thin route) new thin route in workspaces.ts returning the buildWorkspaceState() sub-object already computed inside /context (workspaces.ts:311) memory_frames + session JSONL + awareness → WorkspaceState { active, openQuestions, pending, blocked, completed, stale, recentDecisions, nextActions } (workspace-state.ts:38-55). pending+blocked seed the Tasks tab. No migration. S01, S02
GET /api/workspaces/:id/activity EXTEND (thin alias) new thin route over GET /api/events?workspaceId= (events.ts) ai_interactions / execution_traces / audit_events ?limit= → { events:[{ts,type,actor,summary}] }. Per-workspace audit feed. No migration. S02

No backend work for S02 Tasks (tasks.ts CRUD EXISTS), Members (/api/team/members EXISTS), or status-bar feeds (/api/fleet, /api/cron, /api/capabilities/status all EXIST — compose client-side; an aggregate /status route is optional and deferred). Artifacts tab is S05's scope; S02 ships an interim file-registry view via existing GET /api/workspaces/:id/files.

1c. Command Center (Ctrl+K) (S00, S03) — new command.ts

Method + Path Disposition Build target Substrate Shape Screens
GET /api/command/search?q= NET-NEW new routes/command.ts federating route reads /api/memory/search (memory.ts:120), WorkspaceManager.list(), /api/skills, /api/workspaces/:id/sessions/search (sessions.ts) — no new store ?q=&scope= → { results:[CommandResult{id,kind:'search'|'launch'|'create'|'run'|'navigate'|'extend', objectType, title, subtitle?, score, requiresApproval?, payload?}] }. Federates over ~4 substrates. S00, S03
POST /api/command/execute EXTEND existing POST /api/commands/execute (note plural, commands.ts) — extend for navigate/create/run/extend dispatch, OR add a singular /command/execute alias command runtime + dispatch targets { command, objectType?, payload?, workspaceId? } → { ok, result? }. Current runs slash-commands with a subset CommandContext; PRD's palette execute is broader. S00, S03
GET /api/command/recent NET-NEW (or client-derive first) new routes/command.ts reading ai_interactions (or derive from session/event history) ai_interactions (read-only) → { recent:[{command,ts,objectType}] }. No schema change. Cheapest v1 = client-side from session history; promote to server when a consumer needs cross-device. S03
GET /api/command/suggestions NET-NEW new routes/command.ts reusing deriveNextActions (workspace-state.ts:182-218) + folding in /api/skills/suggestions read-only over memory_frames/awareness/cron → { suggestions:[CommandResult] }. No migration. S03

Phase 2 — Work layer: Memory Center, Artifact Center, Workspace Creation, Onboarding (PRD §8 Phase 2 / §21 Sprint 45)

2a. Memory Center (S04, S16) — extend memory.ts + ONE optional migration

Method + Path Disposition Build target Substrate Shape Screens
GET /api/memory EXTEND (alias) accept bare path on existing GET /api/memory/frames (memory.ts:188) memory_frames ?scope=&kind=&confidence=&status= → { frames:[...] }. Alias only. S04
GET /api/memory/:id NET-NEW (thin) new thin read in memory.ts over FrameStore.getById(id) (no GET .../frames/:id exists today) memory_frames → { frame }. Drawer detail. No migration. S04
POST /api/memory EXTEND (alias) alias on POST /api/memory/frames (memory.ts:248) memory_frames { kind,title,content,scope,tags? } → { id }. S04
PATCH /api/memory/:id EXTEND extend PUT /api/memory/frames/:id (memory.ts:448) to accept PATCH + bare :id memory_frames (FrameStore.update) { content?, importance?, status?, tags? } → { ok }. S04
POST /api/memory/:id/archive NET-NEW (thin) new thin route; model archive as FrameStore.update(id, importance:'deprecated') OR status in the new metadata column memory_frames → { ok }. No hard delete. S04
DELETE /api/memory/:id EXTEND (alias) alias bare :id over DELETE /api/memory/frames/:id (memory.ts:551) memory_frames (FrameStore.delete) → { ok }. S04
POST /api/memory/merge NET-NEW new route in memory.ts; real logic (read N frames, synthesize merged content, write one, archive/delete originals) — reuse FrameStore + findDuplicate dedup memory_frames { frameIds:[...], strategy?:'concat'|'llm' } → { mergedId, archived:[...] }. Net-new logic, low schema risk. S04
Harvest preview/commit confidence + selection EXTEND POST /api/harvest/preview (harvest.ts:221) → return ALL items (or paged) + per-item confidence + normalized kind; POST /api/harvest/commit (harvest.ts:243) → accept { selectedIds?:[] } filter before the createIFrame loop (:382-409) in-memory parse (preview) / memory_frames (commit) Honors the trust-gate AC ("nothing imports without approval"). Preview confidence needs a classifier (LLM or heuristic). Preview-only confidence needs no migration. S16

2b. Artifact Center (S05) — new artifacts.ts (largest net-new domain; aggregation only)

Single largest entity gap: no Artifact type, table, or /api/artifacts* route exists anywhere (substrate-types §e). The backend is a thin net-new aggregation/normalization layer over three existing stores — NO new data store. A lightweight artifacts.json index holds title/status/ tags/relations; the bytes stay in the existing file/document/storage stores.

Method + Path Disposition Build target Substrate Shape Screens
GET /api/artifacts NET-NEW new routes/artifacts.ts; normalize 3 stores GET /api/workspaces/:id/files (workspaces.ts:594), document versions (documents.ts), storage files (workspaces.ts /storage/files) + artifacts.json index ?workspaceId=&kind=&status= → { artifacts:[Artifact{id,title,kind,workspaceId,status,mimeType,storagePath,tags,relatedMemoryIds,...}] }. S02, S05
POST /api/artifacts NET-NEW artifacts.ts; delegates byte-write to POST /api/ingest / files/upload / documents file/document stores + artifacts.json { title,kind,workspaceId,content?/file? } → { id }. S05
GET /api/artifacts/:id NET-NEW artifacts.ts; resolve composite id → normalized Artifact + relations + preview meta 3 stores + documents.ts versions → { artifact, relatedVersions[], relatedMemoryIds[] }. S05
PATCH /api/artifacts/:id NET-NEW artifacts.ts; update title/status/tags/relations in artifacts.json (move = re-point storagePath via files/move) artifacts.json (+ files/move) { title?, status?, tags?, relatedMemoryIds? } → { ok }. S05
DELETE /api/artifacts/:id NET-NEW (route) artifacts.ts; remove index entry + optionally backing file via files/delete/storage/delete artifacts.json + file stores ?deleteBacking=bool → { ok }. S05
GET /api/artifacts/search-related?q= NET-NEW artifacts.ts; lean on memory_frames_fts + wiki search internally memory_frames_fts, sessions, tasks, fleet ?q=&artifactId= → { related:[{type,id,title,score}] }. S05

2c. Workspace Creation (S17) — extend workspaces.ts write path

Method + Path Disposition Build target Substrate Shape Screens
POST /api/workspaces (extend body) EXTEND workspaces.ts:116-135 + WorkspaceManager.create (workspace-manager.ts:60-95) workspace.json Accept description, type, status, skills[], agentIds[], connectorIds[], mcpIds[] (the Phase-0 additive fields). No DB migration. S17
GET /api/workspace-templates (extend shape) EXTEND (optional) workspace-templates.ts:33 template store Add skills[]/mcps[]/type to WorkspaceTemplate so a chosen template pre-populates all 4 suggestion panels. S17

2d. Onboarding: First Launch, Who-Are-You, Tool Discovery, Memory Import (S12S15)

Method + Path Disposition Build target Substrate Shape Screens
PUT /api/profile (extend merge) EXTEND profile.ts:167-228 allow-list (:172-196) + UserProfile (:41-94) + DEFAULT_PROFILE (:96-135) profile.json (NOT SQLite) Add workType, teamSize, goals[] to the merged-fields allow-list + interface. Already mirrors identity → memory P/I frame (:201-224). No migration. S13
POST /api/harvest/sources/:id/sync NET-NEW (thin) new thin route in harvest.ts; resolve registered source + re-run commit harvest_sources + memory_frames → { runId }. Sync today = POST /api/harvest/commit. NOTE: current sources keyed by :source name (not :id) — keep name key or alias. No new substrate. S15, S16

S12 First Launch + S14 Tool Discovery need ZERO net-new backend — all source catalogs already have routes (GET /api/connectors, GET /api/tools/detect, GET /api/offline/status, GET /api/workspaces); selections persist client-side in OnboardingState (localStorage), optionally threaded via the extended PUT /api/profile. The full harvest engine (preview/commit/sources/progress/scan-claude-code/runs/extract-identity + POST /api/ingest) already EXISTS for S15 — only the /sources/:id/sync alias (above) and the S16 confidence/selection extension (Phase 2a) are new.


Phase 3 — Intelligence layer: Agents, Skills, Automations (PRD §8 Phase 3 / §21 Sprint 6)

3a. Agent Center + Agent Builder (S09, S18) — new sidecar agents.ts + agent store

Naming collision: /api/agents/* CRUD exists ONLY on the Clerk-gated Cloud server (packages/server/src/routes/agents.ts) — NOT the sidecar (confirmed absent). All of §16.7 is net-new locally: a new packages/server/src/local/routes/agents.ts registered in local/index.ts. Persistence (recommended v1): a {dataDir}/agents.json file store, mirroring the agent-groups JSON precedent (agent-groups.ts:29) — no SQLite migration. (Alternative: an agents table in mind/schema.ts with SCHEMA_VERSION bump — only if agents must be FTS/relation-queryable. See §M.)

Method + Path Disposition Build target Substrate Shape Screens
GET /api/agents NET-NEW new routes/agents.ts; reads agent store; overlay live status from /api/agents/active + /api/fleet agents.json (new) → { agents:[Agent{id,name,type,goal,personaId,model,autonomyLevel,status,lastRunAt,successRate,...}] }. May union saved agents + read-only personas for back-compat. S09, S18
POST /api/agents NET-NEW agents.ts; persist Agent (§15.5 fields); PRO-tier gate like personas.ts:32 agents.json + install_audit (if elevated tools/MCPs claimed) { name,type,goal,model,personaId?,autonomyLevel,memoryScopes,skillIds,connectorIds,mcpIds,permissions } → { id }. S18
GET /api/agents/:id NET-NEW agents.ts read over store agents.json → { agent }. S09, S18
PATCH /api/agents/:id NET-NEW agents.ts; mirror agent-groups.ts:74-90 PATCH shape agents.json { ...partial } → { ok }. S18
POST /api/agents/:id/run EXTEND resolve agent → call real executor POST /api/fleet/spawn (fleet.ts:66, the only path that runs runAgentLoop :185). Do NOT use agent-groups/:id/run (stub :105). fleet/orchestrator + execution_traces via TraceRecorder { input?, workspaceId? } → { sessionId }. Map agent persona/model/memoryScope/workspace onto spawn body. S09, S18
POST /api/agents/:id/pause EXTEND map agent→active session → POST /api/fleet/:workspaceId/pause (fleet.ts:260) fleet → { ok }. S09, S18
GET /api/agents/:id/traces NET-NEW (route over existing store) new thin read over execution_traces (mind/schema.ts:199, written by chat.ts/evolution.ts, no HTTP read today), filtered by agent/session; fallback session timeline sessions.ts execution_traces + ai_interactions ?limit= → { traces:[{ts,step,tool,outcome,cost}] }. S09, S18

3b. Skills Hub + Skill Builder (S06, S19) — extend skills.ts

Method + Path Disposition Build target Substrate Shape Screens
PATCH /api/skills/:id EXTEND add PATCH alias + :id:name over PUT /api/skills/:name (skills.ts:506) ~/.waggle/skills/*.md { content? } → { ok }. No new substrate. S06, S19
POST /api/skills/:id/test EXTEND add :id path variant routing to existing POST /api/skills/test (body-driven) skill file + parseSkillFrontmatter { testInput? } → { wouldInject, frontmatter }. Sandbox/dry-run only; no execution. S06, S19
POST /api/skills/:id/install NET-NEW (thin dispatcher) new dispatcher over POST /api/skills/starter-pack/:id, capability-packs/:id, marketplace/install (keep requireTier('PRO') for marketplace-sourced) marketplace.db + MarketplaceInstaller + SecurityGate + install_audit { source:'starter'|'pack'|'marketplace' } → { installed }. Resolves source + delegates. S06

Skill create is the existing structured POST /api/skills/create (skills.ts:431generateSkillMarkdown + redactSkillContent + audit + hash) — the Builder's real target, EXISTS. Publish reuses POST /api/marketplace/publish (PRO). Optional later: extend SkillFrontmatter for structured inputs/outputs/memoryAccess (Builder Steps 34) — open question, not in §16.8. No .mind migration (skills are flat files; marketplace is marketplace.db).

3c. Automation Center + Automation Builder (S11, S20) — alias cron as automations

The capability is cron (cron.ts, /api/cron/* — full CRUD + trigger + history). "Automations" = a rename/alias surface. Zero MISSING, all PARTIAL. Register a real /api/automations/* alias plugin (PRD vocabulary) OR point the new UI at /api/cron. Trigger/condition/actions ride in the existing job_config TEXT blob → no .mind migration for v1.

Method + Path Disposition Build target Substrate Shape Screens
GET /api/automations EXTEND (alias) alias of GET /api/cron (cron.ts:94); reshape toResponse to expose trigger/condition/actions/status from job_type+job_config cron_schedules → { automations:[...] }. S11, S20
POST /api/automations EXTEND (alias) alias of POST /api/cron (cron.ts:67); persist trigger/condition/actions into job_config (+ cron_expr for schedule triggers) cron_schedules { name,trigger,condition?,actions[],schedule? } → { id }. S11, S20
PATCH /api/automations/:id EXTEND (alias) alias of PATCH /api/cron/:id (cron.ts:124) cron_schedules { ...partial } → { ok }. Note real bug: FE updateCronJob calls PUT /api/cron/:id but only PATCH is registered (adapter.ts:836 vs cron.ts) — fix the adapter. S11, S20
POST /api/automations/:id/run EXTEND (alias) alias of POST /api/cron/:id/trigger (cron.ts:174; auto-enables + executes + notifies) cron_schedules + executor (index.ts:1379) → { runId }. S11, S20
POST /api/automations/:id/pause NET-NEW (thin) / EXTEND add thin /pause route OR adapter calls PATCH /api/cron/:id { enabled:false } cron_schedules.enabled + scheduler → { ok }. Add /pause for PRD contract. S11, S20
GET /api/automations/:id/logs EXTEND (alias) alias of GET /api/cron/:id/history (in notifications.ts:202cronStore.getExecutionHistory) cron_execution_history ?limit= → { logs:[...] }. S11, S20
POST /api/automations/test NET-NEW new dry-run route (PRD §12.10 "test before activate"); current POST /api/cron/:id/trigger really executes cron executor (no-persist mode) { trigger,actions[] } → { previewResult }. No log/notify side-effects. S20

Phase 4 — Extend layer: Connectors, MCPs, Marketplace, Install Audit (PRD §8 Phase 4 / §21 Sprint 7)

4a. Connector Hub (S07, S14) — extend connectors.ts

Method + Path Disposition Build target Substrate Shape Screens
POST /api/connectors/:id/sync NET-NEW new route in connectors.ts (WaggleConnector has connect/healthCheck/execute but no sync()) vault sub-key connector:<id>:lastSync (or small store) + activity event + install_audit → { lastSyncAt, ok }. Phased: MVP = healthCheck() + stamp lastSyncAt + emit event; full data re-pull is a larger connector-SDK addition. No .mind migration. S07
POST /api/connectors/:id/revoke EXTEND (alias) alias to POST /api/connectors/:id/disconnect (connectors.ts:107) + write install_audit action:'rejected'/revoke vault + install_audit → { ok }. Same intent, PRD verb. S07
POST /api/connectors/:id/connect (extend) EXTEND connectors.ts:55 — add auditStore.record(...) on success vault + install_audit (audit-trail enrichment, no shape change). S07, S14
GET /api/connectors (extend payload) EXTEND (optional) connectors.ts:6 — carry category (already on type, types.ts:299) + lastSyncAt so UI drops hardcoded CATEGORIES/sync-shim connector registry (payload enrichment). S07, S14
GET /api/connectors/health (aggregate) NET-NEW (optional, mockup) connectors.ts — fan healthCheck() across connectors connector registry → { connectors:[{id,status,lastSyncAt}], systemHealth }. Optional v1; compose client-side otherwise. S07
GET /api/connectors/activity NET-NEW (or use shared /api/extend/audit?type=connector) reads install_audit rows filtered to type:'connector' install_audit → { activity:[...] }. Prefer the shared /api/extend/audit (4c) which serves S07+S08+S21 with one route. No migration. S07

4b. MCP Hub (S08, S17) — new mcps.ts + persisted MCP-config store + runtime population

The deepest backend gap in the Extend layer. Today mcpRuntime is empty and never populated (local/index.ts:911); there is no GET /api/mcps, no persisted MCP-config store, no boot-time population. All routes live in a new packages/server/src/local/routes/mcps.ts. Substrate decision: persist installed MCP configs as a JSON file / .mcp.json (no migration) — confirm dataDir path + multi-workspace scoping (open question). The MCP catalog is static in @waggle/shared mcp-catalog.ts.

Method + Path Disposition Build target Substrate Shape Screens
GET /api/mcps NET-NEW routes/mcps.ts; join static catalog (@waggle/shared mcp-catalog.ts) + installed-state (capabilities/status.mcpServers[], .mcp.json, marketplace mcp-registry.ts) catalog + .mcp.json + install_audit → { mcps:[{id,name,status,installed,tools[],scope}] }. Reads existing substrate; no migration. S08, S17
POST /api/mcps/install EXTEND route through existing marketplace installer POST /api/marketplace/install (already handles installType:'mcp' → writes .mcp.json, installer.ts:580) marketplace.db + .mcp.json + install_audit { mcpId } → { installed }. Resolve MCP id → marketplace package → install. Audit already recorded. S08
POST /api/mcps/:id/test NET-NEW mcps.ts; resolve server, start() if needed, assert isHealthy() (mcp-runtime.ts:94,399) and/or tools/list round-trip McpRuntime → { ok, tools[], error? }. Open question: live spawn-and-handshake vs static manifest validation. S08
POST /api/mcps/:id/revoke NET-NEW mcps.ts; mcpRuntime.removeServer(name) (mcp-runtime.ts:327) + delete persisted config + install_audit action:'revoked' McpRuntime + .mcp.json + install_audit → { ok }. S08
POST /api/mcps (add custom) NET-NEW mcps.ts; persist config + add to runtime (blueprint API line 530) .mcp.json + McpRuntime { name, command, args[], env{}, workspaceId? } → { id }. S08
POST /api/mcps/:id/start · POST /api/mcps/:id/stop NET-NEW mcps.ts; map to McpRuntime start/stop (PRD §12.8 start/stop) McpRuntime → { status }. S08
PATCH /api/mcps/:id/permissions NET-NEW mcps.ts (blueprint API line 530) .mcp.json config { scope?, permissions? } → { ok }. S08
GET /api/mcps/:id/logs NET-NEW (phased) mcps.ts; needs a ring-buffer of stderr/stateChange in McpServerInstance (no log capture today) new in-memory ring buffer → { logs:[...] }. Defer to later phase if log-capture infra not built. S08

Boot-time runtime population (populate mcpRuntime from the persisted config at startup, local/index.ts:911) is the foundational non-route work item that unblocks all of the above.

4c. Marketplace / Extend + Install Audit (S21, shared S06/S07/S08)

Method + Path Disposition Build target Substrate Shape Screens
GET /api/marketplace EXTEND (alias) bare path = alias of GET /api/marketplace/search with default params (marketplace.ts:56) marketplace.db → { results:[...] }. S21
GET /api/extend/audit (shared governance read) EXTEND (param) the install-audit read route GET /api/audit/installs already EXISTS (skills.ts:685); add ?capability= / ?type= filter exposing getByCapability() (install-audit.ts:125) install_audit ?type=skill|connector|mcp|marketplace&limit= → { entries:[AuditEntry] }. Serves S06+S07+S08+S21 with one route. No migration. Note: substrate-types §d#1 listed this as missing; it is present — the work is the filter param, not a new route. S06, S07, S08, S21

No POST /api/share here — that is Phase 5 (Team). Per-workspace install scoping (§12.13) is net-new product surface; PRD §22 risk register says "start with catalog + install audit, postpone billing/public marketplace" — defer to Phase 4 polish.


Phase 5 — Team intelligence: Team Workspace, RBAC, Sharing, Audit (PRD §8 Phase 5 / §21 Sprint 8)

Team CRUD core EXISTS in team.ts (teams.db): GET/POST/PUT/DELETE /api/teams, /:id, /members, /members/:userId, /activity. No .mind migration for the team core (teams.db standalone; team_capability_policies/overrides/requests exist in migration 0001).

Method + Path Disposition Build target Substrate Shape Screens
POST /api/teams/:id/invite EXTEND (alias) thin /invite alias forwarding to POST /api/teams/:id/members (team.ts:581, owner/admin gated) team_members (teams.db) { email?, userId?, role? } → { ok }. No new substrate. S10
GET /api/teams/:id/audit EXTEND (alias) alias /audit → existing GET /api/teams/:id/activity (team.ts:690, reads audit_events via getAuditDb) audit_events → { events:[...] }. Or add audit-export shape. No new store. S10
PATCH /api/teams/:id/members/:memberId (fix gate) EXTEND (bug fix) team.ts:642 (:userId==:memberId); fix PUT(owner-only :615) vs PATCH(owner/admin :642) role-gate inconsistency team_members (behavior fix, no shape change). S10
POST /api/share NET-NEW new route (no /api/share anywhere — grep-confirmed); shares memory/artifact with role-appropriate perms workspace.json teamId linkage + (if frame-level) memory_frames metadata { objectType:'memory'|'artifact'|'workspace', objectId, teamId, role } → { ok }. Open: frame-level scope needs the memory_frames metadata migration (§M); v1 may scope implicitly via workspace teamId. Gate behind TEAMS tier like /api/team/*. S05, S10
POST /api/artifacts/:id/share NET-NEW (blueprint) maps to POST /api/share + artifact scope; gate TEAMS artifacts.json + team scope { teamId, role } → { ok }. Blueprint action not in §16.6; defer to Phase 5. S05
GET /api/teams/:id/governance (optional) NET-NEW (optional) surface team_capability_policies/overrides/requests (migration 0001); Enterprise proxy GET /api/team/governance/permissions (team.ts:418) is the remote analog team_capability_policies etc. → { policies[], overrides[], requests[] }. RBAC UI. S10

§M — Schema migrations required

Headline: the entire refactor needs AT MOST ONE conditional SQLite migration, and it is deferrable. Every other "schema addition" is to a JSON file (workspace.json, profile.json, agents.json, artifacts.json, .mcp.json) — not a database — so it is a pure additive TypeScript-interface change with no migration. The migration runner already does idempotent additive ADD COLUMN on memory_frames (precedent: it added source, mind/db.ts:116-124; pattern = pragma_table_info guard + ALTER TABLE … ADD COLUMN).

M1 — memory_frames.metadata (CONDITIONAL — Phase 2/Phase 5) — the only .mind SQLite migration

  • What: add one nullable column metadata TEXT NOT NULL DEFAULT '{}' to memory_frames (mind/schema.ts:47). Store {kind, title, scope, sourceId, sourceUrl, confidence, tags, evidence, relatedMemoryIds, relatedArtifactIds, status} as JSON (PRD §15.4 fields; PRD endorses metadata-first, :1013).
  • Why conditional: memory_frames is the only mind table without a JSON blob column (unlike awareness.metadata, knowledge_entities.properties, etc.). Needed ONLY when persisted confidence/provenance/scope/status becomes a real query/filter axis (S04 Memory Center filters; S16 persisted-confidence review; S10/S05 frame-level /api/share scope). NOT needed if S16 review is preview-only (pre-commit) and S04 filtering is in-app over the existing columns.
  • Risk: low — single additive nullable column; avoids touching the FTS/vec virtual tables and IPB scoring. Promotion path: if confidence becomes a primary indexed filter, a later migration adds confidence REAL as a real column (same ADD-COLUMN pattern).
  • Screens: S04, S16, S10, S05. Build target: packages/hive-mind-core/src/mind/db.ts migration block + mind/schema.ts.
  • What: the TS AuditRiskLevel includes 'critical' (install-audit.ts:16) but both DDL CHECK constraints allow only ('low','medium','high') (install-audit.ts:65 AND schema.ts:130 — duplicated DDL that must stay in sync). A record({riskLevel:'critical'}) throws a CHECK violation.
  • Why: Phase 4 connector/MCP/skill installs all route through auditStore.record(...). The marketplace route currently side-steps by mapping CRITICAL→riskLevel:'high'+approvalClass:'blocked' (marketplace.ts:224-319) — but any new Extend caller passing 'critical' crashes.
  • Fix (pick one): (a) widen both CHECK constraints to include 'critical' (additive CHECK migration — needs table rebuild for SQLite CHECK change, or relax to no-CHECK), OR (b) lock the CRITICAL→'high' mapping as the permanent contract and drop 'critical' from the TS union. (b) is zero-migration.
  • Risk: low. Screens: S06, S07, S08, S21 (all Extend installs). Build target: install-audit.ts:65 + mind/schema.ts:130 (kept in sync) OR the TS union.
  • What: an agents table in mind/schema.ts with a SCHEMA_VERSION bump.
  • Recommendation: do NOT do this for v1. Persist agents to {dataDir}/agents.json (file store, mirrors the agent-groups.json precedent agent-groups.ts:29) — no migration, reversible. Only add the table if agents must be FTS/relation-queryable. PRD §14.4 non-goal favors minimal backend.
  • Screens: S09, S18.

Non-migrations (additive JSON-file / interface changes only — listed for completeness, NOT migrations)

  • WorkspaceConfig V2 fields → workspace.json (Phase 0; substrate-types §a).
  • UserProfile workType/teamSize/goalsprofile.json (S13).
  • Agent entity → agents.json (Phase 3, M3 alt).
  • Artifact index → artifacts.json (Phase 2b).
  • MCP installed configs → .mcp.json (Phase 4b).
  • Automation trigger/condition/actions → existing job_config TEXT blob (Phase 3c; no schema change).
  • cron_schedules/cron_execution_history/notifications tables already exist with lazy creation (cron-store.ts:135-157) — no migration for Automations.

Counts

Counted as distinct backend endpoints (each method+path = 1). Endpoints that EXIST as-is and need only frontend wiring are excluded. Phase-0 non-route work (V2 fields, FE type unions, write- side stamps) is counted separately under "interface/field extensions", not as endpoints.

  • Total endpoints requiring backend work: 53 (NET-NEW + EXTEND, de-duplicated).
  • NET-NEW endpoints: 35
    • Home ×2 (/home/briefing, /home/overnight)
    • Command ×3 (/command/search, /command/recent, /command/suggestions)
    • Memory ×3 (/memory/:id, /memory/:id/archive, /memory/merge)
    • Artifacts ×6 (GET, POST, /:id, PATCH /:id, DELETE /:id, /search-related)
    • Agents ×5 (GET, POST, /:id, PATCH /:id, /:id/traces)
    • Skills ×1 (/skills/:id/install)
    • Automations ×1 (/automations/test)
    • Connectors ×3 (/:id/sync, /connectors/health, /connectors/activity)
    • MCPs ×8 (GET /mcps, /:id/test, /:id/revoke, POST /mcps custom, /:id/start, /:id/stop, PATCH /:id/permissions, /:id/logs)
    • Team ×3 (POST /api/share, POST /artifacts/:id/share, GET /teams/:id/governance)
    • (Several MCP/connector/team items are blueprint-implied beyond the §16 literal list; /api/automations/:id/pause is counted under EXTEND as a thin alias over the cron enabled flag.)
  • EXTEND endpoints: 18 (distinct backend touch-points; an EXTEND may be an alias, an added param, or added behavior)
    • /quick-capture (delegates to memory write)
    • /workspaces/:id/state, /workspaces/:id/activity (thin routes over existing builders/events)
    • /command/execute (broaden dispatch)
    • /memory GET, /memory POST, /memory/:id PATCH, /memory/:id DELETE (aliases over /memory/frames*)
    • /harvest/preview + /harvest/commit (confidence + selectedIds selection)
    • /harvest/sources/:id/sync (thin re-commit alias)
    • /workspaces POST (richer body)
    • /agents/:id/run, /agents/:id/pause (delegate to fleet)
    • /skills/:id PATCH, /skills/:id/test (:id variants)
    • 6× /automations/* aliases over /cron/* (GET, POST, PATCH, run, pause, logs)
    • /connectors/:id/revoke, /connectors/:id/connect (+audit), /connectors GET (payload)
    • /mcps/install (via marketplace installer)
    • /marketplace (bare-path alias)
    • /extend/audit filter param (over existing /audit/installs)
    • /teams/:id/invite, /teams/:id/audit, /teams/:id/members/:memberId (alias + role-gate fix)
  • Phase-0 interface/field extensions (NOT endpoints): 5WorkspaceConfig V2 fields + updatedAt/ lastActiveAt write-stamps (workspace-manager.ts), FE type unions (types.ts), UserProfile workType/teamSize/goals (profile.ts), WorkspaceTemplate shape, Connector interface fields.
  • PRD §16 cross-reference (from _inventory/backend-routes.md): of 65 §16-literal endpoints — 16 EXIST as-is (FE wiring only), 30 PARTIAL (→ EXTEND), 19 MISSING (→ NET-NEW). This master list adds ~16 blueprint-implied endpoints (MCP start/stop/logs/permissions/custom, connector health/activity, automations/test, team governance, artifact-share, extend/audit) beyond the §16 literal set.
  • Schema migrations: 1 conditional SQLite (M1 memory_frames.metadata) + 1 recommended CHECK fix (M2 install_audit risk-level) + 1 optional/deferred (M3 agents table — recommend NOT doing in v1). Net likely-to-ship: 1 (memory_frames.metadata); 0 strictly required if S16 confidence stays preview-only and /api/share scopes implicitly via workspace teamId.
  • New sidecar route files: 5 (home.ts, command.ts, artifacts.ts, agents.ts, mcps.ts)
    • 1 alias plugin (automations.ts → cron). New JSON file stores: 2 (agents.json, artifacts.json); plus reuse of .mcp.json, workspace.json, profile.json.