Skip to content

PRD: Self-Hosted Multica as the AI Workforce Execution Engine

Status: Draft / Evaluation Author: Josh Lockhart Date: 2026-04-22 Decision owner: Josh Lockhart Target decision: Accept / Reject / Defer Related systems: agent_runner/, rails_api/app/interactions/ai_workforce/, admin_dashboard/src/views/AIWorkforceView.vue


1. Context

Objectuve's AI Workforce is a Rails-orchestrated, TypeScript-executed system that runs five scheduled AI employees (Gym, Scout, Cori, Brio, Stat) on cron, produces reviewable artifacts (draft posts, reports, code patches, email templates, recommendations), and ships approved outputs to GitHub / Slack / Mailtrap / docs. It went live in Phase 2 (Q1 2026) and is currently in shadow / semi-autonomous tiers.

The execution engine is a bespoke Cloud Run service (agent_runner/) built on @anthropic-ai/claude-agent-sdk@0.2.104. It wraps query() with custom scaffolding: memory injection, brand-voice post-filter, per-employee MCP scoping, HMAC-signed webhooks, OIDC auth, budget enforcement.

Multica (19.5k ★, Go + Next.js, PostgreSQL+pgvector, OSS) is a self-hostable, issue-driven agent management platform that treats agents as team members. Josh has used Multica externally (on his personal machine, outside this repo) to run coding crews against Objectuve stories — e.g., Maggie → Orion → Codi → Roy → Vicki → Dori as documented in ../guides/multica-agent-crew.md. There is no Multica infrastructure, config, or integration in this repo today. The multica-agent-crew.md file captures the crew pattern Josh has validated externally, but no code invokes it.

This PRD evaluates whether to replace the custom Agent Runner with a self-hosted Multica deployment, and outlines a migration approach if we choose to proceed.


2. Problem Statement

The current Agent Runner works but carries ongoing maintenance cost:

  • Bespoke TypeScript service (~1.5k LOC) with its own Dockerfile, Cloud Run deploy, OIDC wiring, HMAC signing.
  • Every new orchestration feature (better observability, run retries, streaming, crew patterns, multi-step pipelines) is built from scratch.
  • As the surface expands (more employees, more output kinds, potential multi-agent "crew" workflows), the custom code grows proportionally.
  • Josh's external Multica experimentation suggests Multica's issue-driven crew model is a cleaner mental model than our current "single employee produces one artifact per run" pattern, especially as AI Workforce expands into multi-step pipelines (scope → draft → review → ship).

Question: Does adopting a mature OSS platform let us delete custom code, improve operator ergonomics, and unlock multi-agent crews faster than we could build them ourselves?


3. Current State (what we'd be replacing)

Summary of the custom capabilities that would need a Multica equivalent:

CapabilityWhere it lives todayCritical?
Cron-triggered runs (daily/weekly/biweekly)ScheduleRunsJob + CronoYes
Per-employee skill loading from .claude/skills/agent_runner/src/agent/skillLoader.tsYes
Per-employee MCP scoping (GitHub, PostHog, Sentry, Mailtrap, Slack)agent_runner/src/tools/mcpConfig.tsYes
Persistent memory injection (JSONB, ~2k token cap, FIFO rejection log)AiEmployeeMemory + promptBuilder.tsYes
Brand-voice post-filter (second query() call)agent_runner/src/agent/postFilter.tsYes
Per-run budget cap (MAX_RUN_BUDGET_USD) + monthly budget trackingTriggerRun + BudgetAlertJobYes
Autonomy tiers (shadow → semi → autonomous) with DB validation on promotionAiEmployee model validationsYes
Artifact approval queue + review UIReviewQueueView.vue + ApproveArtifact interactionYes
Delivery automation (GitHub PR, Slack webhook, Mailtrap sandbox, docs/)DeliverArtifactJobYes
HMAC-signed webhook back to Railsagent_runner/src/webhook/sender.tsYes
OIDC auth for Cloud Run → Cloud Run → LiteLLMagent_runner/src/auth/oidcToken.tsYes
LiteLLM proxy routing for model selection + rate limitsinfra/litellm/Yes
Tool call timeline in admin UIRunDetailView.vueNice-to-have

4. What Multica Provides (from README research)

Confirmed capabilities:

  • ✅ Self-hosted via Docker + PostgreSQL 17 + pgvector
  • ✅ Vendor-neutral (Claude Code, Codex, OpenClaw, Gemini, etc.)
  • ✅ Issue-driven task model (status state machine: backlogtodoin_progressin_reviewdone)
  • ✅ CLI for agent-to-agent handoffs (multica issue comment/status/assign)
  • ✅ Multi-workspace isolation
  • ✅ Real-time progress streaming via WebSocket
  • ✅ Persistent agent profiles ("agents as teammates")
  • ✅ 19.5k stars, 2.5k forks, 64 contributors — healthy OSS maturity

Gaps (not documented in the README, would need to confirm via repo/issues):

  • ❓ MCP server integration (not mentioned)
  • ❓ Scheduled/cron triggers (not mentioned — appears manual issue creation only)
  • ❓ Custom LLM proxy (LiteLLM) support
  • ❓ Per-agent budget caps / cost tracking
  • ❓ Approval-queue workflow for artifacts
  • ❓ Programmatic agent definition (appears DB/UI-configured)
  • ❓ License type (public repo, not explicit in README)
  • ❓ REST/GraphQL API surface for external orchestration
  • ❓ Fine-grained tool scoping per agent

5. Pros of Migrating to Multica

  1. Delete ~1.5k LOC of custom TypeScript. The Agent Runner service and its Dockerfile/Cloud Run deploy go away. LiteLLM could stay (Multica supports multiple providers) or be simplified.

  2. Crew model unlocks multi-step pipelines naturally. Our current "one employee = one run = one artifact" model doesn't compose. Multica's issue-handoff protocol (Maggie → Orion → Codi → Roy → Vicki) is exactly the pattern we'd need for, e.g., "Scout triages Sentry issue → Codi drafts fix PR → Roy reviews → Vicki ships." Josh has already validated this externally.

  3. Operator UX upgrade. Multica's issue board + WebSocket streaming + agent profiles are more polished than our bespoke admin dashboard AI Workforce views. Less maintenance on AIWorkforceView.vue, ReviewQueueView.vue, EmployeeDetailView.vue, RunDetailView.vue.

  4. Issue-driven trigger model matches real work better than cron. Most useful AI Workforce runs are reactive (new Sentry issue, new PR merged, weekly report due) — an issue board is a better primitive than cron for most of these.

  5. OSS community leverage. 64 contributors, 2.5k forks. Future features (better observability, new provider integrations, new crew patterns) land without us building them.

  6. Unified with Josh's external coding workflow. If we're already running Multica externally for coding crews on Objectuve stories, consolidating the AI Workforce onto the same platform eliminates conceptual fragmentation.

  7. Vendor neutrality. If Anthropic pricing/availability shifts, we can swap providers at the Multica layer without touching our Rails orchestration.


6. Cons / Risks / Gaps

  1. Brand-voice post-filter is architecturally unique. Our two-query design (main task → separate brand-voice validation query()) is load-bearing for every user-facing artifact. Multica doesn't document anything equivalent. We'd need to either (a) fork Multica, (b) build a post-filter as a distinct agent in the crew ("Dori reviews every artifact before Vicki ships"), or (c) keep the post-filter as a Rails-side step after Multica delivers. Option (b) is promising but adds a turn and cost.

  2. Scheduled runs not documented. Our AI Workforce is cron-driven (daily, weekly, biweekly). Multica appears issue-driven. We'd need to build a Rails-side scheduler that creates Multica issues on schedule — replacing one scheduler with another, not a net simplification.

  3. Per-agent MCP scoping not documented. We currently enforce "Scout can hit Sentry but not GitHub" at the SDK allowedTools level. Multica's scoping model is unknown. This is a compliance-style guarantee we shouldn't lose.

  4. Memory injection is custom. Our persistent memory (last run summary, performance stats, recent rejections) is serialized as markdown and injected into the system prompt. Multica's agent profile concept may or may not support this depth of state — needs investigation.

  5. Approval queue + artifact delivery automation not documented. AiArtifact.approval_status, DeliverArtifactJob, SyncUser-style PR creation, Slack webhook delivery — all custom. Multica issues can be "in_review" but the review queue + delivery routing would likely stay Rails-side.

  6. Autonomy tiers + DB validations. shadow → semi_autonomous → autonomous progression with approval-rate thresholds is enforced at the AiEmployee model level. Multica has no equivalent governance primitive.

  7. Budget caps. MAX_RUN_BUDGET_USD, monthly budget enforcement, BudgetAlertJob at 80% / 100% — no documented Multica equivalent. Losing this is a production-safety regression.

  8. Operational cost. A self-hosted Multica deployment adds: Cloud Run service(s), PostgreSQL 17+pgvector instance (separate from our existing Cloud SQL PG15), ongoing upgrade cadence, security patching. Not obviously cheaper than the current ~$20/mo Agent Runner Cloud Run + shared LiteLLM.

  9. Lock-in to pre-1.0 OSS. Multica is at v0.2.15. Breaking changes between minor versions are likely. The project's governance, license, and backward-compatibility guarantees aren't yet clear from the README.

  10. Migration cost is high and value is uncertain. We'd rebuild five employees + delivery flows + approval UI + budget/autonomy governance. Realistically 3–6 weeks of engineering, with a net-equivalent (not obviously better) end state for AI Workforce specifically.

  11. Testing story. Our RSpec coverage for AI Workforce interactions, jobs, and webhook handling (~80%+) would need to be re-scoped. Some tests become obsolete; many would need rewrites against Multica's API surface.


7. Recommendation

Do not migrate the AI Workforce to Multica at this time. The gap between Multica's issue-driven coding-crew model and our scheduled-operational-artifact model is larger than the README suggests, and the load-bearing features (brand-voice post-filter, per-agent MCP scoping, memory injection, approval queue, delivery automation, autonomy tiers, budget caps) don't have documented equivalents.

However, Multica is a strong fit for a distinct, additive use case: in-project coding crews. Josh has already validated this externally. Adopting Multica to run the Maggie/Orion/Codi/Roy/Vicki/Dori crew in the project — triggered by GitHub issues or Sentry alerts — would:

  • Give us a parallel "coding workforce" that complements the existing AI Workforce (not replaces it)
  • Let us exercise Multica against real Objectuve workloads before betting the AI Workforce on it
  • Leave the existing Agent Runner + Rails orchestration untouched until we have real operational data on Multica

If that pilot runs well for 2–3 months and Multica ships the missing primitives (MCP scoping, budget caps, scheduling), we can revisit migrating AI Workforce onto it.

Alternative if we disagree and want to proceed anyway: see Section 8.


8. If We Proceed: Phased Migration Approach

If the decision is to migrate AI Workforce onto self-hosted Multica despite the gaps above, a defensible rollout:

Phase A — Spike & fit assessment (1 week)

  • Stand up Multica locally via curl … | bash -s -- --with-server.
  • Port one employee (Brio, the brand-voice auditor — lowest blast radius, no MCP, no delivery) to a Multica agent.
  • Confirm/disprove: MCP support, budget caps, LiteLLM routing, REST API surface for Rails orchestration.
  • Go/no-go gate: If any of (MCP scoping, cost tracking, programmatic trigger) is absent, stop and reopen this PRD.

Phase B — Self-hosted deploy (1 week)

  • GCP Cloud Run service for Multica Go backend.
  • Cloud SQL PostgreSQL 17 + pgvector instance (separate from our PG15 production DB).
  • Cloud Run service for Multica Next.js frontend (or Firebase Hosting if static-compatible).
  • Secret Manager entries for Multica auth, DB creds, LLM provider keys.
  • OIDC for Rails → Multica API.
  • Staging environment first; production mirrors staging.

Phase C — Employee migration (2 weeks)

Migrate employees in this order (lowest risk first):

  1. Brio (brand-voice auditor, no MCP, no delivery) — proves the pattern
  2. Scout (Sentry REST, report output, docs/ delivery) — proves REST tool calling
  3. Stat (PostHog REST, report output, docs/ delivery) — proves scheduling
  4. Cori (GitHub MCP, draft_post, Slack delivery) — proves MCP + Slack
  5. Gym (GitHub MCP, draft_post, Slack delivery) — highest volume, last

For each: create Multica agent, port skill prompt, wire memory serialization, configure MCP/REST tools, run in shadow alongside existing Agent Runner for 1 week, compare artifact quality, cut over.

Phase D — Rails orchestration refactor (1 week)

  • Rewrite AgentRunnerClientMulticaClient (REST or whatever Multica exposes).
  • Replace ExecuteRunJob dispatch with Multica issue creation.
  • Keep ScheduleRunsJob (Crono stays) but have it create Multica issues instead of AiRun records.
  • Replace webhook (webhooks/ai_workforce_controller.rb) with Multica webhook format.
  • Keep AiArtifact approval queue + DeliverArtifactJob Rails-side (don't migrate these to Multica).
  • Keep AiEmployeeMemory Rails-side; sync to Multica agent profile on each run.

Phase E — Decommission Agent Runner (3 days)

  • Remove agent_runner/ service, Dockerfile, Cloud Run deploy.
  • Remove agent_runner entry from docker-compose.yml.
  • Remove OIDC + HMAC code that's now unused.
  • Update CLAUDE.md, docs/features/ai-workforce.md, docs/operations/ai-workforce-runbooks.md.
  • Update .github/workflows/ to drop agent_runner deploy.

Phase F — Observability + governance rebuild (1 week)

  • Rebuild autonomy-tier validation on AiEmployee to gate Multica issue assignments.
  • Rebuild budget caps as a Rails-side guard before creating Multica issues (if Multica doesn't support per-run caps).
  • Rebuild brand-voice post-filter as either (a) a Multica agent ("Brio reviews before Vicki ships") or (b) a Rails-side step after artifact return.
  • Restore admin dashboard equivalents of run detail / tool call timeline (may embed Multica's UI in an iframe).

Total estimate: 5–6 weeks engineering + 1–2 weeks hardening.


9. Decision Criteria / Open Questions

Questions we need answered before we can make a defensible call. Most of these require reading Multica's source / opening discussions on their repo, not just the README:

  1. Does Multica support MCP servers as tools? If not, is there a plugin pattern?
  2. Does Multica support scheduled/cron issue creation natively, or is that a Rails-side concern regardless?
  3. Does Multica expose a REST API for programmatic issue creation + status polling?
  4. Does Multica support custom LLM proxies (LiteLLM) or only direct provider SDKs?
  5. What's the license? (Affects whether we can fork for brand-voice post-filter.)
  6. What's the upgrade cadence / breaking-change policy at pre-1.0?
  7. Can agent profiles store arbitrary JSON metadata we could use for our memory format?
  8. Is there a budget / token-tracking primitive, or would we build it Rails-side?
  9. Has anyone else run Multica on Cloud Run + Cloud SQL at production scale?
  10. Does the Multica frontend embed cleanly in our admin dashboard, or would operators context-switch?

10. Non-goals

  • Not evaluating CrewAI, AutoGen, LangGraph, or other orchestration frameworks in this PRD.
  • Not proposing to adopt Multica's coding crew for this repo's development workflow — that's a separate (and stronger) proposal.
  • Not changing the 5-employee roster, autonomy tiers, or output kinds.
  • Not changing LiteLLM's role as the LLM proxy.

11. Verification

This PRD is verified when:

  • [ ] Josh reviews and accepts / rejects / requests revisions
  • [ ] If accepted: Phase A spike runs locally and produces a go/no-go on the 3 gate questions (MCP, budget, programmatic trigger)
  • [ ] If rejected: the alternative ("Multica for coding crews only") gets its own PRD
  • [ ] Either way: ../features/ai-workforce.md gets a one-paragraph "we evaluated Multica on 2026-04-22 and chose [X] because [Y]" breadcrumb so future-us doesn't re-open this question without new information

Last updated: 2026-05-13

Loading…