Skip to content

feat: ship Slice J1 — pbrain integration (skills + CLI allowlist + auto-onboard)#82

Merged
joedanz merged 2 commits into
mainfrom
slice/J1-pbrain-skills
May 5, 2026
Merged

feat: ship Slice J1 — pbrain integration (skills + CLI allowlist + auto-onboard)#82
joedanz merged 2 commits into
mainfrom
slice/J1-pbrain-skills

Conversation

@joedanz
Copy link
Copy Markdown
Owner

@joedanz joedanz commented May 5, 2026

Summary

  • @mc/core/pbrain (new) ships pbrainBashAllowlist (Bash-only, pbrain * allowlist with shell-metachar denial) and runProjectOnboard (one-shot Claude SDK call bound to the pbrain project-onboard skill, bounded by maxTurns + abortSignal).
  • mc project add <path> now runs the onboarder after registry.add() succeeds — --no-pbrain to skip; pbrain failures never invert add's exit code. New mc project pbrain-backfill [--slug X | --all] retroactively onboards existing projects.
  • Chat lane gains pbrain access (read-only additionalDirectories: [skillsRoot], Bash(pbrain:*) allowlist via canUseTool, brainstorm prompt augmented with a "Pbrain access" section). The chat-no-project + pbrain case routes cwd to the pbrain skills tree to avoid exposing MC internals (state.db, dashboard.token) via the SDK's cwd auto-allow.
  • @mc/core/config.pbrain (new) — env-driven PBRAIN_ROOT (default ~/code/pbrain), validated against <root>/skills/; discriminated union mirrors discord/memory.vec.

Why this shape

Skills + CLI over MCP. Pbrain ships a pbrain serve MCP with ~30 tools. Wiring that into chat-bridge would tax every chat turn ~2.4k tokens (80 tokens × 30 schemas) for occasional-use operations. Skills + Bash-allowlist load on demand (~500–1500 tokens per invocation) and match how pbrain itself is designed to be consumed by agents. The in-process mc-memory MCP from I1b stays for its hot-path single-tool case — the tradeoff is asymmetric for the right reasons.

CLI runs the onboarder, not the daemon. Mission Control's EventBus<ProjectEvent> already publishes project.added from registry.add() — but the bus lives in whichever process called the registry, not across the CLI/daemon boundary. So a daemon-side subscriber wouldn't fire on mc project add. The CLI runs the onboarder itself (using a hoisted shared cliAgentRunner), which keeps mc project add self-contained and works whether or not the daemon is up.

Bash allowlist via canUseTool, not allowedTools. The SDK's allowedTools: ['Bash'] would auto-allow any shell command, and disallowedTools is a name-only blocklist. canUseTool is the only surface that expresses "Bash, but only pbrain *" — and we defend against shell metacharacter injection (pbrain query x; rm -rf /) with a regex on the trimmed command. Single-user dev tool, no privilege boundary, but a clean allowlist still bounds the agent's blast radius if a prompt-injection convinces it to try shelling out.

assistant_text_delta in onboarder is gone. /simplify quality review caught that the onboarder's assistant_text_delta case was overwriting summary with the most recent partial delta, then completed.result would replace it with the full text — but if an out-of-order delta arrived after completed, it would silently overwrite the good summary. Removed the case; rely on completed.result.

composeBrainstormPrompt lives in chat-bridge, not compose.ts. /simplify flagged that having both pbrain?: PbrainEnabledConfig and a pre-composed brainstormSystemPrompt on ChatBridgeOpts made callers responsible for synchronizing two views of the same state. Moved composition inside the bridge — caller passes the base prompt + pbrain config once. Tests still pin a stub via the basePrompt override.

Test status

  • 1340 / 1340 tests passing
  • pnpm build, pnpm typecheck, pnpm lint, pnpm test all green locally
  • /simplify ran (3 reviewers in parallel); applied 11 findings (assistant_text_delta bug fix, cwd-leak fix in chat-no-project + pbrain, OnboardProjectPick<Project,…>, hoisted pbrainBashAllowlist to a const, dropped narrative slice/swarm comments per CONTRIBUTING, etc.)

Test plan

  • pnpm test (1340/1340)
  • pnpm build (all packages)
  • pnpm typecheck (all packages)
  • ./node_modules/.bin/biome check . (clean)
  • Manual: mc project add ~/code/<some-repo> against the user's local pbrain — verify the pbrain skill kicks off, summary line prints, project still registers on pbrain failure
  • Manual: mc project add --no-pbrain ~/code/<some-repo> — verify no pbrain output
  • Manual: Discord chat to a routed channel — verify pbrain query "<x>" works in a chat session

Deferred / additive

  • pbrain access in the task lane (J1 is chat-only; promotion via /do resumes the same SDK session, so a task already inherits chat's pbrain context).
  • Pbrain MCP server opt-in (pbrain serve) — one-line addition next to the existing mc-memory MCP if a high-frequency loop ever justifies the schema cost.
  • Shared "iterate agentRunner.run(), capture terminal event" helper — chat-bridge, summarize-handler, and onboarder all do roughly this. /simplify flagged it; deferring until a fourth call site appears so the abstraction has real shape.
  • Reaction-emoji promotion (👍/do) from I1's deferred list.
  • Cross-conversation /do.

joedanz added 2 commits May 5, 2026 18:51
…uto-onboard)

Mission Control gains first-class pbrain access through skills + CLI rather
than MCP — keeping the per-turn schema cost off the chat-lane baseline while
making pbrain operations available on demand.

- @mc/core/config gains a pbrain block (env-driven PBRAIN_ROOT, default
  ~/code/pbrain, validated against <root>/skills/), discriminated union
  mirroring discord/memory.vec
- @mc/core/pbrain (new) ships pbrainBashAllowlist (a CanUseTool gate that
  permits only `pbrain` invocations + denies shell metacharacters) and
  runProjectOnboard (one-shot Claude SDK call bound to the pbrain
  project-onboard skill, bounded by maxTurns + abortSignal)
- chat-bridge composes the brainstorm prompt internally now (caller passes
  the base prompt + pbrain config once); pbrain-enabled chat-no-project
  routes cwd to the skills tree instead of the daemon's data dir to avoid
  exposing MC internals via SDK auto-allowed reads under cwd
- mc project add runs the onboarder after registry.add() succeeds
  (--no-pbrain to skip; pbrain failure never inverts add's exit code)
- mc project pbrain-backfill [--slug X | --all] retroactively onboards
  existing projects; continues iterating past per-project failures

All four gates green: 1340 tests, build, typecheck, biome clean.
Review feedback: exposing all 27 pbrain skills to the chat-lane was overkill
for a Socratic brainstorming persona, and the onboarder didn't need read
access to skills it wouldn't invoke.

- New @mc/core/pbrain/skills.ts: CHAT_LANE_SKILLS = ['query','brain-ops',
  'briefing'] (single source of truth for the curated trio); ONBOARD_SKILL
  = 'project-onboard'; chatLaneSkillDirs + onboardSkillDir helpers.
- chat-bridge: additionalDirectories now contains exactly the curated trio
  (and cwd, for the chat-no-project case, becomes the first curated skill
  dir rather than the broad skillsRoot). Other pbrain skills (ingestion,
  migration, scheduling, daily ops) stay invisible to the chat agent —
  direct CLI use only.
- onboarder: additionalDirectories narrowed from [skillsRoot] to
  [skillsRoot/project-onboard]; the SKILL.md probe + run still work
  unchanged.
- Brainstorm system prompt updated: names the three available skills
  explicitly and tells the agent to point users at the pbrain CLI for
  workflows outside chat scope.

All 4 gates green: 1345 tests, build, typecheck, biome clean.
@joedanz joedanz merged commit 1f8f973 into main May 5, 2026
3 checks passed
@joedanz joedanz deleted the slice/J1-pbrain-skills branch May 5, 2026 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant