Legionis: Definitive Execution Plan

Version: 3.0 (supersedes execution-plan.md V2.2) Date: 2026-02-13 Owner: Yohay Etsion Status: GO — the build guide Aligned To: PRD V1.5, Architecture Stack V1.4, System Prompt Deep Dive, Vercel Constraints Deep Dive


How to Use This Document

This is the step-by-step build plan. Each phase has a clear entry gate, specific deliverables, file-level implementation tasks, test criteria, and an exit gate. Open this before every build session, check off what's done, pick up where you left off.

Builder: Yohay + Claude Code (backend, architecture, integration) + Cursor (frontend UI, rapid iteration) Pace: ~15-20 hrs/week Total MVP: 8-10 weeks


Architecture Summary (Reference)

LayerTechnologyPackage
FrontendNext.js 14+ (App Router)next
StylingTailwind CSS 4 + Radix UItailwindcss, @radix-ui/*
Client StateZustandzustand
Server StateTanStack Query@tanstack/react-query
Agent RuntimeVercel AI SDK v6ai, @ai-sdk/anthropic, @ai-sdk/openai
DatabasePostgreSQL 16 (Neon)@neondatabase/serverless, drizzle-orm
ORMDrizzledrizzle-orm, drizzle-kit
AuthClerk@clerk/nextjs
PaymentsStripestripe, @stripe/stripe-js
Cloud StorageGoogle Drive API v3googleapis
SearchTypesensetypesense
Object StorageCloudflare R2@aws-sdk/client-s3 (S3-compatible)
MonitoringSentry@sentry/nextjs
AnalyticsPostHogposthog-js

Hosting: Vercel (single deployment — frontend + API routes) Monthly infra: ~$162


Pre-Development: Project Setup (Day 0)

P0.1 — Repository & Scaffold

npx create-next-app@latest legionis \
  --typescript --tailwind --app --src-dir \
  --import-alias "@/*"
cd legionis
git init && git add -A && git commit -m "Initial scaffold"

Directory structure (target):

legionis/
├── src/
│   ├── app/                    # Next.js App Router pages
│   │   ├── (auth)/             # Auth pages (sign-in, sign-up)
│   │   ├── (dashboard)/        # Main app (workspace, chat, settings)
│   │   ├── api/                # API routes
│   │   │   ├── chat/           # Agent/skill execution endpoint
│   │   │   ├── drive/          # Google Drive proxy routes
│   │   │   ├── webhooks/       # Stripe, Clerk webhooks
│   │   │   └── health/         # Health check
│   │   └── layout.tsx          # Root layout
│   ├── components/             # React components
│   │   ├── chat/               # Chat UI components
│   │   ├── explorer/           # File explorer components
│   │   ├── shared/             # Shared/common components
│   │   └── ui/                 # Radix-based primitives
│   ├── lib/                    # Core libraries
│   │   ├── agent/              # Agent runtime (Vercel AI SDK wrappers)
│   │   ├── db/                 # Drizzle schema + queries
│   │   ├── drive/              # Google Drive client
│   │   ├── prompt/             # Prompt compilation + caching
│   │   ├── stripe/             # Stripe helpers
│   │   └── utils/              # Shared utilities
│   ├── tools/                  # Custom AI SDK tool definitions
│   │   ├── read-file.ts
│   │   ├── write-file.ts
│   │   ├── edit-file.ts
│   │   ├── glob-files.ts
│   │   ├── grep-content.ts
│   │   ├── list-directory.ts
│   │   └── spawn-agent.ts
│   ├── personas/               # Compiled agent personas (build output)
│   └── middleware.ts           # Clerk auth middleware
├── scripts/
│   ├── compile-prompts.ts      # SKILL.md → compiled persona JSON
│   ├── seed-skills.ts          # Seed skill metadata into DB
│   └── migrate.ts              # DB migration runner
├── drizzle/                    # Migration files
├── os-source/                  # Git submodules for OS content
│   ├── product-org-os/         # PUBLIC submodule: 13 agents, 61 skills, 9 knowledge packs
│   └── extension-teams/        # PRIVATE submodule: 68 agents, 34 knowledge packs, 15 integrations
├── public/
├── .env.local                  # Local env vars (not committed)
├── drizzle.config.ts
├── next.config.ts
├── tailwind.config.ts
└── tsconfig.json

P0.2 — External Service Accounts

Create accounts and collect credentials before writing code:

ServiceActionEnv Var(s)Status
VercelCreate project, link repoAuto-configured via vercel link✅ Done
NeonCreate project + databaseDATABASE_URL✅ Done
ClerkCreate application (Google + MS + LinkedIn + email)NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, CLERK_SECRET_KEY✅ Done
StripeCreate products + prices ($10/$7/$5/$25) + trial configSTRIPE_SECRET_KEY, NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, STRIPE_WEBHOOK_SECRET, 4x STRIPE_*_PRICE_ID✅ Done (test mode)
Google CloudCreate OAuth 2.0 client (Drive API scopes)GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET✅ Done
Cloudflare R2Create bucketR2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY, R2_BUCKET_NAME, R2_ENDPOINTPending (Week 4)
TypesenseCreate cloud clusterTYPESENSE_HOST, TYPESENSE_API_KEYPending (Week 8)
SentryCreate Next.js projectSENTRY_DSNPending (Week 8)
PostHogCreate projectNEXT_PUBLIC_POSTHOG_KEYPending (Week 8)

5 of 9 services configured (Feb 14). Remaining 4 are not needed until later phases.
>
Vercel env vars complete (Feb 16): All 16 production env vars added to Vercel dashboard (Production + Preview + Development). Includes: Clerk (7), Neon (1), Stripe (7), Google Drive (3 + ENCRYPTION_KEY). GCP redirect URI also added to OAuth client.

P0.3 — OS Source Integration ✅

Both content sources are integrated as git submodules (open core model):

os-source/
├── product-org-os/           ← PUBLIC submodule (yohayetsion/product-org-os @ v3.0.1)
│   └── product-org-plugin/
│       ├── skills/           # 13 OS agent personas + 61 skill templates
│       ├── rules/            # 22 rules files
│       ├── reference/knowledge/  # 9 knowledge packs
│       └── integrations/     # 6 integration templates
└── extension-teams/          ← PRIVATE submodule (yohayetsion/extension-teams)
    ├── {9 team dirs}/        # 68 Extension Team agent SKILL.md files
    ├── reference/knowledge/  # 34 knowledge packs
    └── integrations/         # 15 integration templates

Update workflow: cd os-source/ && git pull && cd ../.. && git add os-source/ && git commit

Status: ✅ Done (Feb 15). Submodules pinned, 81 total agents available for compile-prompts.

P0.4 — Initial Deploy ✅

Push scaffold to Vercel. Verify https://legionis.vercel.app (or custom domain) shows the default Next.js page. This is the "it deploys" checkpoint.

Completed Feb 13 — commit 2348bec. legionis.vercel.app live. Auto-deploys on push.

Exit gate: Repo exists, deploys to Vercel, all external accounts created with env vars in .env.local and Vercel project settings.

Substantially met. 5/9 services configured, all deployed to Vercel (Feb 16). Remaining 4 (R2, Typesense, Sentry, PostHog) not needed until later phases.


Phase 1: Foundation (Weeks 1-2)

Week 1: Auth + Database + Billing

Goal: User can sign up, see a dashboard, subscribe, and hit a billing wall. No AI yet.

1.1 Database Schema (Neon + Drizzle)

Create src/lib/db/schema.ts:

// Core tables — define with drizzle-orm
users               // Clerk user ID, email, created_at, subscription_status
workspaces          // id, user_id, name, drive_folder_id, drive_access_token (encrypted), created_at
api_keys            // id, user_id, provider (anthropic|openai), encrypted_key, last_four, validated_at
conversations       // id, workspace_id, title, created_at, updated_at
messages            // id, conversation_id, role (user|assistant|system|tool), content, metadata, created_at
context_entries     // id, workspace_id, type (decision|bet|feedback|learning), entry_id (DR-YYYY-NNN), title, content, metadata (JSON), created_at
file_references     // id, workspace_id, drive_file_id, path, name, mime_type, context_entry_id (optional)
subscriptions       // id, user_id, stripe_customer_id, stripe_subscription_id, plan, status, trial_ends_at, current_period_end

Tasks:

  • ✓ Define Drizzle schema in src/lib/db/schema.ts
  • ✓ Generate initial migration: drizzle-kit generate
  • ✓ Run migration against Neon: drizzle-kit migrate
  • ✓ Create src/lib/db/index.ts — Neon serverless client + Drizzle instance
  • ✓ Create src/lib/db/queries/ — typed query helpers per table
  • Completed Feb 14 — commit c78bd8d. 8 tables: users, workspaces, api_keys, conversations, messages, context_entries, file_references, subscriptions. Migration 0000_whole_wonder_man.sql.

    1.2 Authentication (Clerk)

    Tasks:

  • ✓ Install @clerk/nextjs
  • ✓ Add to root layout
  • ✓ Create src/middleware.ts — protect /dashboard/* routes, allow /sign-in, /sign-up, /api/webhooks
  • ✓ Create src/app/(auth)/sign-in/[[...sign-in]]/page.tsx
  • ✓ Create src/app/(auth)/sign-up/[[...sign-up]]/page.tsx
  • ✓ Create src/app/api/webhooks/clerk/route.ts — sync user creation to users table
  • ✓ Test: sign up with email, sign up with Google, verify session persistence
  • Completed Feb 14 — commit c78bd8d. Svix signature verification on webhook. User CRUD in src/lib/db/queries/users.ts. Root page auth-aware redirect. Tested: Google sign-in → dashboard → Neon user row verified.

    1.3 Billing (Stripe)

    Tasks:

  • ✓ Create Stripe products: "Legionis Individual" ($10/mo), "Legionis Team" ($7/seat/mo, min 3), "Add-on Team" (+$5/mo), "Full Organization" ($25/mo)
  • ✓ Configure 1-month free trial on all products
  • ✓ Create src/app/api/webhooks/stripe/route.ts — handle checkout.session.completed, customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed
  • ✓ Create src/lib/stripe/checkout.ts — create checkout session
  • ✓ Create src/lib/stripe/portal.ts — create billing portal session
  • ✓ Create src/app/dashboard/settings/billing/page.tsx + billing-client.tsx — plan display, trial countdown, upgrade CTA
  • Completed Feb 14 — commit ac749da. Stripe account "Legionis" (test mode). 4 products created via API. Webhook endpoint registered at https://legionis.vercel.app/api/webhooks/stripe. Full billing UI with plan cards, status badges, checkout buttons, portal link. Price IDs: individual price_1T0lKDCzBUEHrjdqtWL8qlKl, team price_1T0m4eCzBUEHrjdqpARE8Ym2, addon price_1T0m4nCzBUEHrjdqynA3See4, full-org price_1T0m4xCzBUEHrjdqbxtseHCp.
    >
    Note: Pricing updated from plan's $10/$8 to actual Agent Catalog pricing: $10/$7/$5/$25. Subscription gating middleware deferred — will implement when chat API route is built (Week 2).
    >
    ~~Action needed: Add 7 Stripe env vars to Vercel dashboard.~~ ✅ Done (Feb 16).

    1.4 Dashboard Shell

    Tasks:

  • ✓ Create src/app/dashboard/layout.tsx — sidebar + main content area
  • ✓ Sidebar: workspace selector (Radix DropdownMenu), conversation list (Radix ScrollArea), file explorer (placeholder with "Soon" label), settings link
  • ✓ Create src/app/dashboard/page.tsx — personalized greeting from DB, QuickAction cards
  • ✓ Create src/app/dashboard/settings/page.tsx + layout.tsx — settings layout with tabbed nav (Profile, API Keys, Billing, Storage) using lucide-react icons
  • ✓ Install and configure Radix UI primitives: DropdownMenu, ScrollArea (Dialog, Tooltip, Tabs available but not yet used)
  • ✓ Dark theme by default (Tailwind dark mode — zinc-900 palette)
  • Completed Feb 14 — commit ce76779. Also created: settings/api-keys/page.tsx (Anthropic + OpenAI cards, disabled), settings/storage/page.tsx (Drive connection placeholder). Clerk UserButton integrated in sidebar. lucide-react installed for icons.

    Week 1 Exit Gate:

  • ✓ User can sign up (email or Google)
  • ✓ User lands on dashboard with sidebar
  • ✓ Stripe trial is active (30 days)
  • ✓ Settings page shows billing status
  • ✓ Database has correct schema, migrations run cleanly
  • ✓ Deploys to Vercel successfully
  • Week 1 substantially complete. One exit gate item (subscription gating) deferred to Week 2 — it requires the chat API route to gate against.


    Week 2: Agent Runtime Core + Custom Tools

    Goal: A single agent (PM) can receive a message, use tools to read/write files in memory, and stream a response. No Google Drive yet — local/mock storage first.

    2.1 Prompt Compiler (compile-prompts.ts)

    The build script that transforms OS source into SaaS-ready prompts. This is the bridge between the open-source plugin and the SaaS product.

    Input: os-source/product-org-os/product-org-plugin/skills//SKILL.md + os-source/extension-teams//SKILL.md + os-source/product-org-os/product-org-plugin/rules/*.md Output: src/personas/compiled-personas.json + src/personas/compiled-rules.json

    Three-layer architecture (from system prompt deep dive):

    LayerContentTokensCaching
    L1: Core ProtocolCompiled rules (response format, routing, V2V, context, delegation, principles, meeting mode, no-fabrication)~1,500Global cache (all users, all agents)
    L2: Agent PersonaCompressed SKILL.md (identity, how-I-think, RACI, deliverables, collaboration, skills, V2V phase)~500Per-agent cache (shared across users)
    L3: Domain RulesConditional rules (decision-system, strategy, roadmaps, GTM, requirements, maturity, auto-context, context-graph) + knowledge packs~300-500Per-task (loaded based on skill/domain)

    Tasks:

      {
        "coreProtocol": "...(L1 text)...",
        "agents": {
          "product-manager": { "persona": "...(L2)", "skills": [...], "primaryPhases": [...], "emoji": "📝", "displayName": "Product Manager" },
          ...
        },
        "domainRules": {
          "decisions": "...(L3 conditional)...",
          "strategy": "...",
          ...
        },
        "knowledgePacks": {
          "prioritization": "...",
          "pricing-frameworks": "...",
          ...
        },
        "skillTemplates": {
          "prd": { "description": "...", "template": "...", "phase": 3 },
          ...
        }
      }
      

    2.2 Agent Runtime (src/lib/agent/)

    The core engine that executes agents using Vercel AI SDK.

    src/lib/agent/runtime.ts — Main agent execution:

    // Core function signature
    async function executeAgent(params: {
      agentKey: string;           // "product-manager", "vp-product", etc.
      userMessage: string;        // User's input
      conversationHistory: Message[];
      workspace: Workspace;       // Drive connection, file context
      apiKey: string;             // User's decrypted API key
      provider: 'anthropic' | 'openai';
      model: string;              // "claude-sonnet-4-5-20250929", etc.
      onStream?: (chunk: string) => void;
    }): Promise
    

    Tasks:

      // Per-request provider creation (BYOT)
      function createProvider(apiKey: string, provider: 'anthropic' | 'openai') {
        if (provider === 'anthropic') return createAnthropic({ apiKey });
        if (provider === 'openai') return createOpenAI({ apiKey });
      }
      

    2.3 Custom Tool Definitions (src/tools/)

    These replace Claude Code's built-in Read, Write, Edit, Glob, Grep. In MVP, they operate on an in-memory file system (Week 4 swaps to Google Drive).

    src/tools/read-file.ts:

    export const readFileTool = tool({
      description: 'Read a file from the workspace',
      parameters: z.object({
        path: z.string().describe('File path relative to workspace root'),
      }),
      execute: async ({ path }, { workspace }) => {
        return await workspace.readFile(path);
      }
    });
    

    Tasks:

    2.4 Chat API Route

    src/app/api/chat/route.ts:

    export async function POST(req: Request) {
      // 1. Auth check (Clerk)
      // 2. Get workspace + API key for user
      // 3. Determine agent (from @mention or auto-route)
      // 4. Assemble system prompt (L1 + L2 + L3)
      // 5. Call streamText() with tools
      // 6. Return SSE stream via .toDataStreamResponse()
    }
    

    Tasks:

    Week 2 Exit Gate:

    Phase 2: Core Product (Weeks 3-4)

    Week 3: Chat UI + Skill Dispatch + Persona System

    Goal: Working chat interface where a user can type messages, invoke skills with /, mention agents with @, and see streaming responses with agent identity.

    3.1 Chat Interface (src/components/chat/)

    Tasks:

    3.2 Skill Palette

    Tasks:

    3.3 Agent Selector

    Tasks:

    3.4 Skill Dispatch System

    When user invokes /prd authentication, the system must:

  • Parse the skill name
  • Load the skill template
  • Inject the template as a specialized system prompt addition
  • Execute with the agent runtime
  • Tasks:

    - Parse /skill-name [arguments] from user input - Look up skill template from compiled personas - Determine owning agent (from SKILL.md frontmatter) - Inject skill template into system prompt as additional context - Execute via executeAgent() with skill context - Parse user input for domain keywords - Match against routing table (from compiled personas) - Return recommended agent key - Support explicit @agent override

    3.5 All 39 Agent Personas

    Tasks:

    - 13 OS agents: pm, cpo, vp-product, pm-dir, pmm-dir, pmm, product-mentor, bizops, bizdev, ci, prod-ops, ux-lead, value-realization - 6 Design: design-dir, ui-designer, visual-designer, interaction-designer, user-researcher, motion-designer - 6 Architecture: chief-architect, api-architect, data-architect, security-architect, cloud-architect, ai-architect - 14 Marketing: marketing-dir, content-strategist, copywriter, seo-specialist, cro-specialist, paid-media, email-marketer, social-media, growth-hacker, market-researcher, video-producer, pr-specialist, analytics-specialist, brand-strategist Week 3 Exit Gate:

    Week 4: Google Drive Integration

    Goal: Replace in-memory filesystem with real Google Drive. User connects Drive, selects workspace folder, and all agent file operations go through Drive API.

    4.1 OAuth Flow

    Tasks:

    4.2 Workspace Initialization

    Tasks:

    - List user's Drive folders for selection - Create new folder option - Create V2V context structure inside selected folder:
        [Selected Folder]/
        ├── context/
        │   ├── decisions/
        │   ├── bets/
        │   ├── feedback/
        │   ├── learnings/
        │   ├── interactions/
        │   ├── portfolio/
        │   ├── documents/
        │   ├── assumptions/
        │   ├── handoffs/
        │   ├── roi/
        │   └── index.json        # Structured context index
        └── deliverables/
        
    - Store folder_id as workspace root in database

    4.3 Drive-Backed File Tools

    Swap in-memory FS with real Drive API calls in all tools:

    Tasks:

    - readFile(folderId, path) — resolve path to file ID → download content - writeFile(folderId, path, content) — create or update file at path - editFile(folderId, path, oldStr, newStr) — download, replace, re-upload - listDirectory(folderId, path) — list files in subfolder - globFiles(folderId, pattern) — search by name pattern - grepContent(folderId, pattern, path?) — download + search content - getFileById(fileId) — direct ID-based access

    4.4 File Explorer

    Tasks:

    ~~Action needed: Add GOOGLE_REDIRECT_URI=https://legionis.vercel.app/api/drive/callback to Vercel dashboard env vars.~~ ✅ Done (Feb 16). Also added https://legionis.vercel.app/api/drive/callback as authorized redirect URI in Google Cloud Console. When app.legionis.ai goes live, add that URL too.

    Week 4 Exit Gate:


    Phase 3: Agent System (Weeks 5-6)

    Week 5: BYOT + Full Agent Roster + Context Layer

    Goal: All 39 agents operational with BYOT key routing. Context layer (save, recall, feedback) works against Drive storage.

    5.1 API Key Management (BYOT)

    Tasks:

    - Master key in env var (ENCRYPTION_MASTER_KEY) - Per-key DEK (data encryption key) generated on save - AES-256-GCM encryption - Add Anthropic API key field - Add OpenAI API key field (optional) - Show only last 4 chars after save - Validate key on save (test API call) - Clear error messages for invalid keys - Per-request key lookup: decrypt user's key → create provider - Model selection: user chooses default model in settings - Fallback: if Anthropic key invalid, try OpenAI (if configured)

    5.1b Quality/Efficiency Model Routing

    Goal: Users control the quality-cost tradeoff with a global setting that overrides per-agent model defaults.

    Three-position setting: Maximum Quality (always top-tier models) | Balanced (default — uses SKILL.md model per agent) | Maximum Efficiency (always cheapest sufficient model).

    Current compiled persona model distribution: 12 agents use "sonnet" (OS agents), 69 agents use "opus" (Extension Teams). provider-factory.ts already resolves abstract model names via MODEL_MAP. The toggle intercepts agentModel before resolveModel().

    Tasks:

    - applyQualityPreference(preference, agentModel) → returns overridden model - maximum_quality → always returns "opus" - balanced → returns agentModel unchanged (SKILL.md default) - maximum_efficiency → always returns "haiku" - Segmented control: Efficiency / Balanced (selected) / Quality - Live cost indicator below toggle: updates per position - "Customize per agent" disclosure link (expandable, initially collapsed) — shows agent list with per-agent model override dropdown (post-launch enhancement, stub only for now)

    5.2 All 81 Agents Operational

    Tasks:

    - Verify emoji + display name header - Verify first-person voice - Verify domain-appropriate response - "How should we price the enterprise tier?" → @bizops - "Write user stories for checkout" → @pm - "Analyze our competitor landscape" → @ci - "Review the API design" → @api-architect (Extension) - "Write landing page copy" → @copywriter (Extension) - (5 more domain-specific prompts)

    5.3 Context Layer Implementation

    The context layer is the "organizational memory" that persists across sessions. Stored in the user's Google Drive workspace.

    Tasks:

    - saveDecision(workspace, decision) → write to context/decisions/YYYY/ + update index - saveBet(workspace, bet) → write to context/bets/YYYY/ + update index - saveFeedback(workspace, feedback) → write to context/feedback/YYYY/ + update index - saveLearning(workspace, learning) → write to context/learnings/index.md - recallByTopic(workspace, topic) → search index.json topicIndex - getPortfolioStatus(workspace) → read context/portfolio/active-bets.md - logInteraction(workspace, interaction) → append to daily log + update index.json - Read/write context/index.json (structured JSON index with topic, product, phase, status indexes) - Auto-generate IDs: DR-YYYY-NNN, SB-YYYY-NNN, FB-YYYY-NNN, etc. - Cross-reference management: link decisions ↔ bets ↔ feedback ↔ learnings - Before agent produces a deliverable, query index for relevant context - Inject up to 5 relevant items as "Auto-Context" section in prompt - Skip for retrieval operations (/context-recall, /feedback-recall) - /context-save → calls saveDecision or saveBet - /context-recall → calls recallByTopic - /feedback-capture → calls saveFeedback - /feedback-recall → searches feedback index - /portfolio-status → reads portfolio state

    5.4 Legionis Tokens (Managed Token Plan)

    Goal: Users who don't want to manage their own API keys can opt into Legionis Tokens — platform-provided AI at a 30% markup over provider costs. BYOT remains the default and recommended path.

    Architecture: When a user selects "Managed Tokens", requests route through Legionis's pooled API keys instead of the user's own keys. Every request is metered for billing.

    Tasks:

    - Platform API key pool: Legionis-owned Anthropic + OpenAI keys (env vars: LEGIONIS_ANTHROPIC_KEY, LEGIONIS_OPENAI_KEY) - Provider selection logic: pick provider based on agent model + user preference - Per-request cost calculation: track input/output tokens, apply provider pricing, add 30% markup
      usage_events: id, user_id, workspace_id, conversation_id, agent_key, model, provider,
                    input_tokens, output_tokens, provider_cost_micros, markup_micros, total_cost_micros,
                    quality_preference, token_source (byot|managed), created_at
      
    - Log every managed-token request to usage_events table - Provider cost lookup table: current rates for all models (claude-opus, claude-sonnet, claude-haiku, gpt-4o, gpt-4o-mini) - Calculate: provider_cost = (input_tokens × input_rate) + (output_tokens × output_rate) - Calculate: markup = provider_cost × 0.30 - Calculate: total_cost = provider_cost + markup - Real-time spend dashboard data: daily/weekly/monthly aggregates - Spend alerts: configurable threshold (default: warn at $50/month) - Optional monthly spending cap (hard stop when reached) - Check user's token_source setting: 'byot' or 'managed' - If BYOT: use user's decrypted key (existing flow) - If Managed: use LEGIONIS_ANTHROPIC_KEY or LEGIONIS_OPENAI_KEY, enable metering - Token source toggle: "Bring Your Own Keys" (default, recommended) vs "Use Legionis Tokens" - If BYOT selected: show existing API key fields - If Managed selected: show spend dashboard with current balance, usage history, cost breakdown - Clear cost comparison: "Your cost: provider rate + 30%. Example: Claude Sonnet at $3/$15 per MTok → $3.90/$19.50 with Legionis Tokens" - Managed token users: metered billing via Stripe Usage Records API - Create Stripe metered price for token consumption - Daily usage report: aggregate usage_events → report to Stripe - Monthly invoice includes: platform subscription + token usage - After signup, present choice as two side-by-side cards: - Card 1: "Bring Your Own Keys" — "Lower cost, full transparency. Paste your Anthropic or OpenAI API key." (recommended badge) - Card 2: "Use Legionis Tokens" — "No setup needed. 30% service fee included in your usage." - Create Legionis Anthropic account (separate from personal) with spending limits - Create Legionis OpenAI account (separate from personal) with spending limits - Store keys as LEGIONIS_ANTHROPIC_KEY and LEGIONIS_OPENAI_KEY in Vercel env vars

    5.5 Conversation Persistence

    Tasks:

    Week 5 Exit Gate:

    Week 6: Sub-Agents + Skill Execution + Delegation

    Goal: Agents can spawn sub-agents, invoke skills, and collaborate using the 4 delegation patterns. Full skill execution pipeline works for all 61 skills.

    6.1 Sub-Agent Spawning

    The spawnAgent tool allows an agent to create a child agent (nested generateText() call).

    Tasks:

    - Accept: agentKey, task, context - Assemble child agent system prompt (L1 + L2 for target agent) - Execute generateText() (not streaming — parent agent consumes result) - Enforce max depth: 3 levels - Return child agent's response to parent - Parse [CONSULTATION], [DELEGATION], [REVIEW], [DEBATE] prefixes in spawn prompts - Tag child agent response with pattern type for attribution

    6.2 Full Skill Execution Pipeline

    Tasks:

    - Phase 1: /strategic-intent or /market-analysis - Phase 2: /decision-record or /pricing-strategy - Phase 3: /prd or /user-story - Phase 4: /campaign-brief or /sales-enablement - Phase 5: /value-realization-report - Phase 6: /outcome-review or /retrospective - Context: /context-save, /context-recall, /feedback-capture - CREATE mode: /prd authentication → creates new PRD - UPDATE mode: /prd update auth PRD with MFA scope → updates existing - FIND mode: /prd find authentication → lists related PRDs - Decisions → context/decisions/YYYY/ - PRDs → deliverables/ (or user-specified path) - Context entries → appropriate context subfolder

    6.3 ROI Tracking

    Tasks:

    - Map skills/agents to baseline times (from reference/roi-baselines.md) - Assess complexity: simple (0.5×), standard (1.0×), complex (1.5×), enterprise (2.0×) - Calculate: base time × complexity factor - Track elapsed time per operation - Per-session accumulator - Write session log to context/roi/session-log.md in workspace - Update monthly history in context/roi/history/YYYY-MM.md Week 6 Exit Gate:

    Phase 4: Multi-Agent & Gateway Orchestration (Weeks 7-8)

    Week 7: Gateway System + PLT Meeting Mode

    Goal: @product and @plt gateways work. PLT spawns 3-4 agents in parallel, displays individual perspectives with alignment/tension/synthesis.

    7.1 Gateway Engine

    Tasks:

    - Parse gateway invocation (@product, @plt, @design, @architecture, @marketing) - Analyze request to determine ownership complexity (SINGLE / PRIMARY+ / MULTI) - Select agents based on RACI mapping + domain analysis - For SINGLE: spawn one agent, pass through response - For PRIMARY+: spawn lead + supporting agents - For MULTI: spawn all needed agents in parallel - Accept array of agent configs - Execute all generateText() calls concurrently (Promise.allSettled) - Collect responses with timing data - Handle partial failures (some agents succeed, some fail) - Enforce max parallel: 4 agents - Stagger start times by 500ms to reduce rate limit risk - V2V phase detection - RACI-based agent selection - Complexity assessment (route to PLT if cross-functional) - Always spawns 3-4 agents based on topic - Composition varies: VP Product always included, others by domain - Meeting Mode output format mandatory - Route to team leader + relevant specialists

    7.2 Meeting Mode UI

    Tasks:

    - Header: topic + "Present: 📈 VP Product, 📝 PM, 📣 Dir PMM" - Individual sections: collapsible, each with emoji + Display Name header - Agent responses in first person (verbatim from agent output) - Divider between agents - Alignment section: bullet points of agreement - Tension section: bullet points of disagreement - Synthesis section: senior agent's synthesis - Aggregate ROI at bottom

    7.3 Aggregate ROI for Multi-Agent

    Tasks:

    - Sum per-agent savings - Show total + per-agent breakdown - Format: ⏱️ Total: ~X hrs saved (vs. manual equivalent) └─ 📈 VP: ~A min | 📝 PM: ~B min | 📣 Dir PMM: ~C min Week 7 Exit Gate:

    Week 8: Onboarding + Settings + Polish

    Goal: Complete onboarding flow, settings page, and polish for beta readiness. Everything works end-to-end.

    8.1 Onboarding Flow

    First-time user experience:

    Sign up → Connect API Key → Connect Google Drive → Select/Create Workspace → Guided First Interaction
    

    Tasks:

    1. "Welcome to Legionis" — brief value prop 2. "Connect Your AI" — API key setup with link to Anthropic console 3. "Connect Your Storage" — Google Drive OAuth 4. "Create Your Workspace" — folder selection/creation 5. "Try Your First Skill" — guided /prd or /decision-record invocation

    8.2 Settings Page

    Tasks:

    8.3 Search (Typesense)

    Tasks:

    8.4 Error Handling & Edge Cases

    Tasks:

    8.5 Monitoring & Analytics

    Tasks:

    - user_signed_up, trial_started, trial_converted, subscription_cancelled - skill_invoked (which skill, agent, duration) - agent_spawned (which agent, duration, tool_calls) - plt_session (agents involved, duration) - file_created, context_saved, context_recalled - onboarding_step_completed, onboarding_completed Week 8 Exit Gate:

    Phase 5: Beta & Launch (Weeks 9-10)

    Week 9: Beta Testing

    Goal: 5-10 beta users test the full product. Identify and fix P0/P1 bugs.

    9.1 Beta User Recruitment

    Tasks:

    9.2 Beta Test Plan

    Each beta user should test:

    AreaTest Script
    OnboardingSign up → connect API key → connect Drive → create workspace → first skill
    SkillsInvoke 5 different skills, verify output quality and file creation
    AgentsSpawn 3 different agents, verify persona + domain accuracy
    PLTRun 1 PLT session, verify Meeting Mode display
    ContextSave 3 decisions → recall by topic → verify cross-references
    File ExplorerBrowse workspace, preview files, verify Drive sync
    BillingView trial status, check billing page

    9.3 Bug Triage

    Tasks:

    - Skill <5s p95 - Agent <15s p95 - PLT <60s p95 - Search <200ms p95 Week 9 Exit Gate:

    Week 10: Launch Preparation

    Goal: Production-ready. Domain configured, landing page live, monitoring active.

    10.1 Production Setup

    Tasks:

    10.2 Landing Page

    Tasks:

    - Hero: "Your AI Product Organization" + CTA "Start Free Trial" - Feature sections: 39 agents, 61 skills, Meeting Mode, context layer - Pricing: $10/mo individual, $8/seat/mo team, 1-month free trial - BYOT explanation: "Your keys, your costs, your control" - Demo/video: Meeting Mode in action

    10.3 Legal & Compliance

    Tasks:

    10.4 Launch Checklist

    Run through PRD Section 12 launch checklist:

    Technical:

    Business: Week 10 Exit Gate: LAUNCH


    Post-Launch: Growth Phase (Weeks 11-20)

    After launch, focus shifts to retention, enrichment, expansion, and external tool integrations.

    Weeks 11-12: External Tool Integration Framework + First Wave

    Goal: Users can connect external tools (Jira, Slack, GitHub, Figma, etc.) via OAuth. Agents use connected tools to perform real operations. Graceful fallback when tools aren't connected.

    11.1 Integration Framework (Week 11)

    The framework provides a generic OAuth + API call pipeline that all integrations share. Individual integrations are configuration on top of this framework.

    Architecture: Hybrid OAuth model. Users click "Connect [Tool]" → standard OAuth 2.0 flow → Legionis stores encrypted tokens in tool_connections table → agents call tool APIs directly using stored tokens. The OS integration templates inform what API calls to make; the platform provides the authenticated HTTP client. No MCP servers needed in production.

    DB Schema:

    tool_connections:
      id, user_id, workspace_id,
      service (jira|slack|github|figma|...),
      provider_config (JSON: instance_url, project_key, etc.),
      encrypted_oauth_tokens (access_token, refresh_token, expiry),
      scopes,
      status (connected|expired|error),
      connected_at, last_used_at
    

    Tasks:

    - initiateOAuth(service, scopes) → redirect URL - handleCallback(service, code) → exchange for tokens → encrypt → store - refreshToken(connectionId) → auto-refresh before expiry - Support both OAuth 2.0 Authorization Code (most tools) and API key (simpler tools) - Map service names → OAuth config (client_id, auth_url, token_url, scopes) - Map service names → API client factory - Map OS integration templates → executable API operations - Runtime check: isConnected(userId, service) → boolean - Wraps fetch with OAuth token injection - Auto-refresh on 401 - Rate limiting and retry logic - Audit logging (all external API calls logged) - Agent calls: { service: "jira", operation: "create_issue", params: {...} } - Tool checks: user has service connected? - If yes: execute API call with stored tokens → return result - If no: return graceful fallback ("Jira is not connected. Here are the issues to create manually: [list]") - Marketplace-style grid of available integrations (3 columns desktop, 1 mobile) - Each card: tool logo, name, connection status (green dot / "Connect" button) - "Used by X agents" indicator per integration - Connect → OAuth flow → redirect back → status updates - Disconnect button with confirmation - Group by category: Project Management, Communication, Design, Code, Analytics, Finance, Legal, IT

    11.2 Wave 1 Integrations: Project Management + Communication (Week 11)

    Priority integrations for launch-adjacent value. These cover the most common "where does the output go?" question.

    Jira / Atlassian (Operations, Product):

    - searchIssues(jql)POST /rest/api/3/search/jql - getIssue(key)GET /rest/api/3/issue/{key} - createIssue(project, type, summary, description)POST /rest/api/3/issue - getBoard(id)GET /rest/agile/1.0/board/{id} - getSprint(id)GET /rest/agile/1.0/sprint/{id} Slack (Communication, all teams): - postMessage(channel, text)POST /api/chat.postMessage - listChannels()GET /api/conversations.list - getHistory(channel)GET /api/conversations.history GitHub (Architecture): - listPRs(repo), getPR(repo, number), createIssue(repo, title, body) - getSecurityAlerts(repo), searchCode(query) Linear (Project Management alternative): - searchIssues(query), createIssue(team, title, description), getCycles(team)

    11.3 Wave 2 Integrations: Design + Marketing (Week 12)

    Figma (Design Team):

    - getFile(fileKey), getComponents(fileKey), getStyles(fileKey), getComments(fileKey) Google Analytics (GA4) (Marketing Team): - runReport(property, metrics, dimensions, dateRange) - runRealtimeReport(property) - runFunnelReport(property, steps) Mailchimp / SendGrid / HubSpot Email (Marketing Team): - getCampaignStats(id), getListInfo(id), createCampaign(params), getDeliverability() SEO Tools — Google Search Console (Marketing Team): - queryAnalytics(site, dateRange, dimensions), listSitemaps(site), getIndexStatus(site)

    Weeks 13-14: Wave 3 Integrations: Finance + Legal + IT + Corp Dev

    Xero / QuickBooks (Finance Team):

    - getProfitLoss(period), getBalanceSheet(date), getCashFlow(period) - getInvoices(status, dateRange), getBankTransactions(dateRange) Stripe Billing (Finance Team): - getSubscriptions(status), getRevenue(period), getCustomers(params) - getMRR(), getChurnRate(period), getInvoices(status) DocuSign / PandaDoc (Legal Team): - searchAgreements(query), getAgreement(id), getAuditTrail(id) - listTemplates(), getEnvelopeStatus(id) Vanta / Drata (Legal Team): - getTests(framework), getFrameworkStatus(), getVendors(), getEvidence(testId) ServiceNow / Jira Service Management (IT Governance Team): - getIncidents(query), createIncident(params), getChanges(query) - getCMDB(ciType), getSLAStatus(), getKnowledgeArticles(query) Okta / Microsoft Entra ID (IT Governance Team): - listUsers(filter), getUser(id), listGroups(), getGroupMembers(id) - listApplications(), getSignInLogs(dateRange), getPrivilegedRoles() Salesforce / HubSpot CRM (Corp Dev Team): - queryRecords(soql), getRecord(type, id), createRecord(type, data) - getPipeline(id), getDeals(stage), getActivities(recordId) PitchBook / Crunchbase (Corp Dev Team): - searchCompanies(query), getCompany(id), getFundingRounds(companyId) - getInvestors(companyId), getComparables(criteria) Notion / Confluence (Operations Team): - searchPages(query), getPage(id), createPage(parent, title, content) - queryDatabase(id, filter), updatePage(id, content) Miro (Operations Team): - getBoards(), getBoard(id), createStickyNote(boardId, content) - createShape(boardId, shape), createConnector(boardId, start, end)

    Integration Summary (All Waves)

    WaveWeekIntegrationsTeams ServedPlatforms
    111Project Mgmt + Communication + CodeOperations, Product, ArchitectureJira, Slack, GitHub, Linear
    212Design + MarketingDesign, MarketingFigma, GA4, Mailchimp/SendGrid/HubSpot, Search Console
    313-14Finance + Legal + IT + Corp Dev + KnowledgeFinance, Legal, IT, Corp Dev, OperationsXero/QBO, Stripe, DocuSign/PandaDoc, Vanta/Drata, ServiceNow/JSM, Okta/Entra, Salesforce/HubSpot CRM, PitchBook/Crunchbase, Notion/Confluence, Miro

    Total: ~30 platforms across 15 integration categories serving all 9 teams + Product Org.

    Exit Gate (Week 14):


    Weeks 15-20: Enrichment + Expansion

    FocusDeliverableWeek
    Per-agent model overrideUsers can set Opus vs Sonnet per agent in settings. Stored in user_agent_preferences table. Enhances the global Quality/Efficiency toggle from Week 5.1b with per-agent granularity. Settings UI: agent grid with model dropdown.15
    Knowledge packsAll 43 packs loaded conditionally per agent domain15
    Team personalitiesEach of the 10 teams has a configurable personality tagline. Stored in team_config table. Injected into L2 persona layer. Default taglines ship; workspace admins can customize.16
    File explorer v2Create, rename, delete, drag-drop, bulk operations16
    Additional model providersGoogle Gemini via @ai-sdk/google, Mistral via @ai-sdk/mistral17
    Voice inputPush-to-talk, transcription via Whisper API18
    OneDrive integrationMicrosoft Graph API OAuth + file operations (cloud storage, not tool integration)19
    Dropbox integrationDropbox API v2 OAuth + file operations20
    Advanced onboardingRole-based skill recommendations, example workspaces20


    Appendix A: Key Technical Decisions (Pre-Made)

    These decisions are MADE. Do not re-litigate during build.

    DecisionChoiceRationaleReference
    Agent runtimeVercel AI SDK v6Pure API, multi-model, BYOT, unlimited subagentssdk-comparison-presentation.html
    BackendNext.js API Routes (not separate Hono)Single deployment, native AI SDK integrationArchitecture Stack V1.4
    StorageGoogle Drive first (not local FS)Stable file IDs, cloud-native, cross-deviceArchitecture Stack V1.4
    Prompt architecture3-layer cached (L1+L2+L3)87% token reduction, ~$0.71/mo user costSystem Prompt Deep Dive
    AuthClerkPre-built UI, social login, org supportArchitecture Stack V1.4
    DatabaseNeon PostgreSQL + DrizzleServerless, branching, scale-to-zero, type-safe ORMArchitecture Stack V1.4
    BillingStripe1-month trial, $10/mo individual, $8/seat/mo teamPRD V1.5
    PLT timeout300s Fluid Compute (default)5x headroom vs 60s targetVercel Constraints Deep Dive
    Subagent depthMax 3 levelsPrevents runaway chains, sufficient for delegationPRD V1.5
    Model defaultClaude Sonnet 4.5Best balance of quality and speedArchitecture Stack V1.4
    Token planBYOT default + Managed Tokens at 30% markupBYOT preserves transparency USP; managed tokens reduce onboarding frictionGateway meeting 2026-02-18
    Model routing3-tier global toggle (Quality/Balanced/Efficiency)Users control cost-quality tradeoff; intercepted before resolveModel()Gateway meeting 2026-02-18
    Tool integrationsHybrid OAuth (not MCP in production)Standard OAuth UX; direct API calls; OS templates inform operationsGateway meeting 2026-02-18
    Integration rollout3 waves post-launch (Weeks 11-14)Not a launch blocker; graceful fallback already worksGateway meeting 2026-02-18

    Appendix B: Environment Variables

    Auth (Clerk)

    NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_... CLERK_SECRET_KEY=sk_... CLERK_WEBHOOK_SECRET=whsec_...

    Database (Neon)

    DATABASE_URL=postgresql://...

    Stripe

    STRIPE_SECRET_KEY=sk_... NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_... STRIPE_WEBHOOK_SECRET=whsec_... STRIPE_INDIVIDUAL_PRICE_ID=price_... STRIPE_TEAM_PRICE_ID=price_...

    Google Drive

    GOOGLE_CLIENT_ID=... GOOGLE_CLIENT_SECRET=... GOOGLE_REDIRECT_URI=https://app.legionis.ai/api/drive/callback

    Encryption

    ENCRYPTION_MASTER_KEY=...

    Cloudflare R2

    R2_ACCESS_KEY_ID=... R2_SECRET_ACCESS_KEY=... R2_BUCKET_NAME=legionis-storage R2_ENDPOINT=https://...r2.cloudflarestorage.com

    Typesense

    TYPESENSE_HOST=... TYPESENSE_API_KEY=... TYPESENSE_PORT=443 TYPESENSE_PROTOCOL=https

    Monitoring

    SENTRY_DSN=https://... NEXT_PUBLIC_POSTHOG_KEY=phc_... NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com

    App

    NEXT_PUBLIC_APP_URL=https://app.legionis.ai

    Legionis Tokens (Managed Plan) — Week 5.4

    LEGIONIS_ANTHROPIC_KEY=sk_ant_... LEGIONIS_OPENAI_KEY=sk_... STRIPE_METERED_PRICE_ID=price_... # Metered price for token consumption

    OAuth — External Tool Integrations (Weeks 11-14)

    Per-service OAuth client IDs/secrets added as integrations are built

    JIRA_CLIENT_ID=... JIRA_CLIENT_SECRET=... SLACK_CLIENT_ID=... SLACK_CLIENT_SECRET=... GITHUB_CLIENT_ID=... GITHUB_CLIENT_SECRET=...

    Additional service OAuth creds added per wave

    Appendix C: Weekly Session Template

    Start each build session by:

  • Open this document
  • Find current week
  • Check remaining unchecked tasks
  • Pick the next task
  • Work with Claude Code / Cursor
  • Check off completed items
  • Note any blockers or deviations
  • End each session by:

  • Commit and push
  • Verify Vercel preview deployment
  • Update checked items in this doc
  • Note any carry-over items for next session

  • Document Status: V3.0 — Definitive Build Guide Supersedes: execution-plan.md V2.2 Start Condition: This document is ready to execute. All architectural decisions are made, all dependencies are available, all service accounts need creation.