{
  "service": "@otto/api-server",
  "marketingPath": "/",
  "createAccountPath": "/create-account",
  "defaultTenantId": "family-office-cos-demo",
  "auth": {
    "required": true,
    "loginPath": "/login"
  },
  "homePath": "/home",
  "appPath": "/app",
  "routes": [
    {
      "method": "GET",
      "path": "/",
      "description": "Public Otto marketing homepage and server metadata."
    },
    {
      "method": "GET",
      "path": "/legal/extension-privacy",
      "description": "Public privacy policy for the Otto Runner Chrome extension."
    },
    {
      "method": "GET",
      "path": "/health",
      "description": "Basic liveness probe."
    },
    {
      "method": "GET",
      "path": "/operator/runs/:runId/replay",
      "description": "Replay UI for a completed browser_run_task run."
    },
    {
      "method": "GET",
      "path": "/operator/missions/:missionId/runs/:runId/replay",
      "description": "Read-only DAG replay UI for a typed-mission run."
    },
    {
      "method": "GET",
      "path": "/operator/tenants/:tenantId/runs/:runId/detail",
      "description": "Run-detail page (timeline, cost, artifacts) for a behavior run. PR #8."
    },
    {
      "method": "GET",
      "path": "/operator/tenants/:tenantId/runs/:runId/timeline",
      "description": "JSON: ordered decision-event timeline for the run. PR #8."
    },
    {
      "method": "GET",
      "path": "/operator/tenants/:tenantId/runs/:runId/cost",
      "description": "JSON: per-run cost breakdown (total + per-call + budget status). PR #8."
    },
    {
      "method": "GET",
      "path": "/operator/tenants/:tenantId/runs/:runId/artifacts",
      "description": "JSON: artifacts (Drive docs, sent emails, calendar events) the run produced. PR #8."
    },
    {
      "method": "POST",
      "path": "/operator/tenants/:tenantId/runs/:runId/feedback",
      "description": "Record thumbs-up/down + optional note on a run (PR #8)."
    },
    {
      "method": "POST",
      "path": "/operator/missions/:missionId/runs/:runId/save-as-eval",
      "description": "Convert a mission run into a downloadable EvalCase JSON fixture."
    },
    {
      "method": "POST",
      "path": "/operator/missions/:missionId/runs/:runId/fork",
      "description": "Fork a mission run from a chosen step. Form param from_step=:stepId; copies pre-fork rows under a new runId, enqueues a scheduled-event, redirects to the new replay."
    },
    {
      "method": "GET",
      "path": "/dashboard/browser-tasks",
      "description": "Tester cross-run health dashboard for browser_tasks."
    },
    {
      "method": "GET",
      "path": "/dashboard/missions",
      "description": "Mission run dashboard listing recent typed-DAG runs."
    },
    {
      "method": "GET",
      "path": "/dashboard/tenants/:tenantId/jobs/:jobId",
      "description": "Per-job dashboard view (Phase 2 PR #24). Auto-generated layout from the job's capabilities. Gated by ff_job_dashboards."
    },
    {
      "method": "GET",
      "path": "/dashboard/tenants/:tenantId/jobs/:jobId/widgets/:kind/data",
      "description": "Per-job widget data envelope (JSON). Gated by ff_job_dashboards."
    },
    {
      "method": "POST",
      "path": "/dashboard/tenants/:tenantId/jobs/:jobId/regenerate-layout",
      "description": "Manual operator regen of the per-job dashboard layout (Phase 2 PR #24)."
    },
    {
      "method": "GET",
      "path": "/builder/missions",
      "description": "Builder Studio mission list (typed-DAG definitions)."
    },
    {
      "method": "GET",
      "path": "/builder/missions/:missionId",
      "description": "Builder Studio mission detail / read-only editor."
    },
    {
      "method": "GET",
      "path": "/builder/missions/:missionId/edit",
      "description": "Builder Studio JSON editor for a mission definition. Optional ?suggest_for=:nodeId&from_run=:runId pre-applies a merged output_schema inferred from the run row."
    },
    {
      "method": "POST",
      "path": "/builder/missions/:missionId/save",
      "description": "Validate edited mission JSON. Persists to the writable MissionDefinitionStore when configured (redirects to detail). Falls back to download-only when no store is wired."
    },
    {
      "method": "GET",
      "path": "/builder/missions/new",
      "description": "Builder Studio create-new-mission form. Requires a writable MissionDefinitionStore."
    },
    {
      "method": "POST",
      "path": "/builder/missions",
      "description": "Create a new tenant-scoped mission. Validates JSON; persists; redirects to detail."
    },
    {
      "method": "POST",
      "path": "/builder/missions/:missionId/dispatch",
      "description": "Enqueue a one-off mission run; redirects to the replay UI."
    },
    {
      "method": "GET",
      "path": "/builder/browser-tasks",
      "description": "Redirect to the active template's browser-tasks editor for the operator's tenant."
    },
    {
      "method": "GET",
      "path": "/create-account",
      "description": "Public Otto account request page."
    },
    {
      "method": "GET",
      "path": "/login",
      "description": "Operator login page."
    },
    {
      "method": "GET",
      "path": "/home",
      "description": "Post-login landing page with agent picker."
    },
    {
      "method": "GET",
      "path": "/app",
      "description": "Primary operator app entrypoint."
    },
    {
      "method": "GET",
      "path": "/admin",
      "description": "Platform admin dashboard entrypoint."
    },
    {
      "method": "GET",
      "path": "/admin/dashboard",
      "description": "Platform admin dashboard snapshot."
    },
    {
      "method": "GET",
      "path": "/admin/telegram-bots",
      "description": "Tenant → Telegram bot directory with collision detection."
    },
    {
      "method": "POST",
      "path": "/admin/users",
      "description": "Create an operator user and grant tenant access."
    },
    {
      "method": "PATCH",
      "path": "/admin/users/:userId",
      "description": "Update an operator user's platform role and tenant access."
    },
    {
      "method": "POST",
      "path": "/admin/users/:userId/reset-password",
      "description": "Reset an operator user's password and revoke active sessions."
    },
    {
      "method": "POST",
      "path": "/admin/users/:userId/suspend",
      "description": "Suspend an operator user's access and revoke active sessions."
    },
    {
      "method": "POST",
      "path": "/admin/users/:userId/restore",
      "description": "Restore a suspended operator user's access."
    },
    {
      "method": "GET",
      "path": "/admin/tenants/:tenantId/flags",
      "description": "Read a tenant's feature flags + audit log."
    },
    {
      "method": "PATCH",
      "path": "/admin/tenants/:tenantId/flags",
      "description": "Set a tenant feature flag (audit-logged)."
    },
    {
      "method": "POST",
      "path": "/admin/tenants/:tenantId/approval-policy/upsert-rules",
      "description": "Surgical admin patch to a tenant's approval_policy (upsert rules by id, optionally set default_effect). Bypasses applyTenantSetupUpdate's full-template validator."
    },
    {
      "method": "GET",
      "path": "/admin/oauth-clients",
      "description": "List platform OAuth client status for every supported provider."
    },
    {
      "method": "POST",
      "path": "/builder/connector-suggestions",
      "description": "Operator-submitted request for a new connector that Otto does not support yet."
    },
    {
      "method": "GET",
      "path": "/admin/connector-suggestions",
      "description": "List of connector requests, ranked by how many operators asked for each provider."
    },
    {
      "method": "PUT",
      "path": "/admin/oauth-clients/:provider",
      "description": "Save platform OAuth client_id + client_secret for one provider."
    },
    {
      "method": "DELETE",
      "path": "/admin/oauth-clients/:provider",
      "description": "Clear stored platform OAuth client credentials for one provider."
    },
    {
      "method": "GET",
      "path": "/admin/tenants/:tenantId/webhook",
      "description": "Read a tenant's webhook connector config (secret redacted)."
    },
    {
      "method": "PUT",
      "path": "/admin/tenants/:tenantId/webhook",
      "description": "Set a tenant's webhook connector secret + signature header."
    },
    {
      "method": "DELETE",
      "path": "/admin/tenants/:tenantId/webhook",
      "description": "Remove a tenant's webhook connector config."
    },
    {
      "method": "PUT",
      "path": "/admin/tenants/:tenantId/webhook/rotate",
      "description": "Rotate a tenant's Telegram webhook secret with a dual-secret overlap window."
    },
    {
      "method": "GET",
      "path": "/admin/tenants/:tenantId/webhook/rotation",
      "description": "Read rotation metadata (previous_expires_at, rotated_at, rotated_by)."
    },
    {
      "method": "GET",
      "path": "/builder",
      "description": "Primary builder app entrypoint. Bare /builder redirects to /builder/new-agent; use ?wizard=1 for the legacy form wizard."
    },
    {
      "method": "GET",
      "path": "/builder/runtimes",
      "description": "Builder runtime catalog."
    },
    {
      "method": "GET",
      "path": "/builder/templates",
      "description": "Builder template catalog."
    },
    {
      "method": "GET",
      "path": "/builder/skills",
      "description": "Curated builder skill catalog."
    },
    {
      "method": "GET",
      "path": "/builder/tools",
      "description": "Available builtin tool catalog."
    },
    {
      "method": "GET",
      "path": "/builder/templates/:templateId/seed",
      "description": "Full template+instance seed for forking."
    },
    {
      "method": "GET",
      "path": "/builder/templates/:templateId/skills",
      "description": "Curated builder skills relevant to one template."
    },
    {
      "method": "GET",
      "path": "/builder/tenants",
      "description": "Builder tenant directory, including drafts."
    },
    {
      "method": "GET",
      "path": "/builder/templates/:templateId",
      "description": "Builder template detail."
    },
    {
      "method": "GET",
      "path": "/builder/skills/:skillId",
      "description": "Curated builder skill detail."
    },
    {
      "method": "GET",
      "path": "/builder/skill-library/groups",
      "description": "List skill library groups (e.g., Engineering Team, Product Strategy)."
    },
    {
      "method": "GET",
      "path": "/builder/skill-library/groups/:groupId",
      "description": "List skills in a library group."
    },
    {
      "method": "GET",
      "path": "/builder/skill-library/skills/:skillId",
      "description": "Fetch a single curated skill with full markdown."
    },
    {
      "method": "GET",
      "path": "/builder/skill-library/categories/:category",
      "description": "List skills by category."
    },
    {
      "method": "GET",
      "path": "/builder/skill-wizard/patterns",
      "description": "List available workflow pattern templates for the skill wizard."
    },
    {
      "method": "POST",
      "path": "/builder/skill-wizard/generate",
      "description": "Generate skill markdown from wizard configuration."
    },
    {
      "method": "POST",
      "path": "/builder/tenants",
      "description": "Create a draft builder tenant from a template."
    },
    {
      "method": "GET",
      "path": "/builder/new-agent",
      "description": "Chooser page for creating a new agent (Chat vs Wizard). Chat is recommended by default; ?studio=0 opts back to wizard-recommended."
    },
    {
      "method": "GET",
      "path": "/builder/agent-studio",
      "description": "Agent Studio chat — conversational agent creation. ?draft=<id> resumes an existing draft."
    },
    {
      "method": "POST",
      "path": "/builder/agent-studio/draft",
      "description": "Initial Agent Studio chat turn. Body: { description }. Returns { draftId, current, feedback } or { draftId, clarifyingQuestion }."
    },
    {
      "method": "POST",
      "path": "/builder/agent-studio/refine",
      "description": "Subsequent Agent Studio chat turn (GOLDEN RULE preserve). Body: { draftId, userMessage }."
    },
    {
      "method": "POST",
      "path": "/builder/agent-studio/deploy",
      "description": "Finalize Agent Studio draft into a deployed tenant. Body: { draftId }. Returns { tenantId, nextUrl }."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/skill-suggestions/:id/dismiss",
      "description": "Mark an Agent-Studio-recommended starter skill as dismissed. Redirects to first-run."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/skill-suggestions/:id/used",
      "description": "Mark an Agent-Studio-recommended starter skill as used (called by Job Studio on save after a suggestion-prefilled draft)."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/skills/:skillId/tools/:toolName/enable",
      "description": "Allowlist a write tool for one (tenant, skill) pair. Job Studio's Capability Plan posts here so operators can flip tools on without leaving the page. Bug Bash 3."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/skills/:skillId/tools/:toolName/disable",
      "description": "Disable a previously allowlisted write tool for one (tenant, skill) pair. Bug Bash 3."
    },
    {
      "method": "GET",
      "path": "/operator/:tenantId/firstRun",
      "description": "Post-deploy landing: finish-connecting panel + starter-skill suggestions. Reads from agent_studio_drafts + tenants/<id>/skill-suggestions/."
    },
    {
      "method": "DELETE",
      "path": "/builder/tenants/:tenantId",
      "description": "Delete an agent and all its data (platform admin only)."
    },
    {
      "method": "PATCH",
      "path": "/builder/tenants/:tenantId/display-name",
      "description": "Rename an agent (sets the human-readable display name; slug unchanged)."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/setup",
      "description": "Draft builder setup snapshot."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/setup",
      "description": "Save builder draft setup without deploying."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/oauth/google/start",
      "description": "Start Google OAuth for a builder setup connection field."
    },
    {
      "method": "GET",
      "path": "/builder/oauth/google/callback",
      "description": "Complete Google OAuth for a builder setup connection field."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/oauth/:provider/start",
      "description": "Start OAuth for one of slack, github, zoom, granola, stripe, discord, notion, microsoft."
    },
    {
      "method": "GET",
      "path": "/builder/oauth/:provider/callback",
      "description": "Complete OAuth for one of slack, github, zoom, granola, stripe, discord, notion, microsoft."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/connections/:fieldId/check",
      "description": "Run a smoke check for one builder connection field."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/connections/:fieldId/disconnect",
      "description": "Disconnect one builder connection field."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/browser-workspaces",
      "description": "List durable browser workspaces for authenticated site sessions."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/browser-workspaces/:workspaceId/open",
      "description": "Create/focus a browser workspace through the runner extension, with a renderable fallback when extension messaging is unavailable."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/browser-workspaces/:workspaceId/recheck",
      "description": "Ask the runner extension to recheck a browser workspace, or fall back to the legacy health check when no extension messaging path is available."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/brain",
      "description": "Builder Brain snapshot for one tenant."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/brain/sources",
      "description": "Builder Brain source diagnostic (all sources, body length + claim count)."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/brain/reextract",
      "description": "Re-run extraction on every stored Brain source with the current extractor."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/telegram/webhook/register",
      "description": "Re-register the Telegram webhook with the bot provider for one tenant."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/brain/search",
      "description": "Builder Brain search results for one tenant."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/context/sources",
      "description": "Ingest source material into the tenant Brain from the builder flow."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/context/upload",
      "description": "Upload a file (PDF, DOCX, TXT, MD) and ingest into the tenant Brain."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/context/fetch-url",
      "description": "Fetch a URL, extract readable content, and ingest into the tenant Brain."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/context/fetch-url/preview",
      "description": "Fetch a URL and preview extracted content without ingesting."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/context/drive-picker-config",
      "description": "Return public Google Picker browser config or a guarded missing-config message."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/context/drive-files",
      "description": "List Google Drive files through the saved Drive connection for builder-side picking."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/context/drive-files/:fileId/snippet",
      "description": "Read a short Google Drive text snippet through the saved Drive connection for builder-side preview."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/context/import-drive",
      "description": "Fetch a Google Drive file through the saved Drive connection and ingest it into the tenant Brain."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/sandbox/session",
      "description": "Create a builder sandbox session."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/sandbox/transcript",
      "description": "Read a builder sandbox transcript."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/sandbox/message",
      "description": "Send a builder sandbox message."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/deploy",
      "description": "Deploy the saved builder draft."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/deploy/status",
      "description": "Builder deployment status."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/skills",
      "description": "List custom skills for one tenant."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/skills",
      "description": "Create a custom skill for one tenant."
    },
    {
      "method": "PUT",
      "path": "/builder/tenants/:tenantId/skills/:skillId",
      "description": "Update a custom skill for one tenant."
    },
    {
      "method": "DELETE",
      "path": "/builder/tenants/:tenantId/skills/:skillId",
      "description": "Delete a custom skill for one tenant."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/skills/:skillId/optimization",
      "description": "List skill optimization versions, runs, and candidates for a custom skill."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/skills/:skillId/optimization/run",
      "description": "Run a bounded skill optimization attempt. Body may provide editOps + scoreComparison for manual/test mode, or use configured optimizer + score runner."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/skills/:skillId/optimization/candidates/:candidateId/accept",
      "description": "Accept an approval-ready skill optimization candidate, version it, and update the active custom skill markdown."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/deploy/validate",
      "description": "Preflight validation dry-run without deploying."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/workspace/export",
      "description": "Export compiled workspace files for one tenant."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/jobs/:jobId/evals",
      "description": "List eval suites for a job (Phase 1 PR #13). Returns the suites + most-recent run summary per suite."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/jobs/:jobId/evals/:evalSuiteId/run",
      "description": "Run an eval suite once. Body: { jobVersionId? }. Returns the structured SuiteResult (pass/fail per case)."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/jobs/:jobId/evals/:evalRunId",
      "description": "Read a completed eval run + its per-case results."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/run-once-page",
      "description": "Job Studio run-once page — streams the run trace + safety harness controls."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/run-once",
      "description": "Job Studio run-once (Phase 1 PR #11). Body: { goLive?: boolean }. Returns { runId, forceDryRun, eventsUrl }. First-run is always dryRun."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/runs/:runId",
      "description": "Job Studio run-once snapshot — current status + buffered events."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/runs/:runId/events",
      "description": "Job Studio run-once SSE event stream — closes on run_completed/run_failed."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/runs/:runId/save-as-eval",
      "description": "Save a completed run as a regression eval case (Phase 2 PR #22). Body: { name?, prohibitedTools?, prohibitedPhrases? }. Auto-creates the per-draft suite on first save; returns { evalCaseId, evalSuiteId, fixtureSize, reRunSupported }. Fixture jsonb is sanitized — no raw PII per Decision #10."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/promote-page",
      "description": "Job Studio promote-to-scheduled page (Phase 1 PR #12). Shows the three gates + schedule form + version history."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/promote",
      "description": "Job Studio promote-to-scheduled (Phase 1 PR #12). Body: { cron, tz, runId, signOff: true, note? }. Writes scheduler_jobs + scheduled_behavior_targets + version sidecar."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/rollback",
      "description": "Job Studio rollback (Phase 1 PR #12). Body: { targetVersion }. Pauses the current scheduler row and records the audit entry."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/versions",
      "description": "Job Studio promotion history (Phase 1 PR #12). Returns versions[] + history[] + current lifecycle state."
    },
    {
      "method": "GET",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/edge-twin",
      "description": "Optional Edge Twin assurance view for a promoted Job Studio workflow."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/edge-twin/promote",
      "description": "Opt a Job Studio workflow into Edge Twin governance mode."
    },
    {
      "method": "POST",
      "path": "/builder/tenants/:tenantId/jobs/:draftId/edge-twin/disable",
      "description": "Disable Edge Twin governance mode for one Job Studio workflow."
    },
    {
      "method": "GET",
      "path": "/builder/brain-clipper.zip",
      "description": "Download the latest Brain Clipper Chrome extension zip (proxied from GitHub)."
    },
    {
      "method": "GET",
      "path": "/tenants",
      "description": "Authenticated tenant directory."
    },
    {
      "method": "GET",
      "path": "/auth/session",
      "description": "Current operator session state."
    },
    {
      "method": "POST",
      "path": "/access-requests",
      "description": "Public Otto account request intake."
    },
    {
      "method": "POST",
      "path": "/auth/login",
      "description": "Create an operator session."
    },
    {
      "method": "POST",
      "path": "/auth/logout",
      "description": "Destroy the current operator session."
    },
    {
      "method": "POST",
      "path": "/bootstrap",
      "description": "Seed the demo tenant and build artifacts."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/app",
      "description": "Authenticated operator app for one tenant."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/readiness",
      "description": "Agent readiness checklist: model, channel, connectors, source pack, evals, schedule, policy, and demo/sandbox status."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/browser-health/trends",
      "description": "Browser automation health trends: status transitions, recovery attempts, patch proposal outcomes, alert dedupe, repeat fingerprints, and time-to-recovery."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/browser-learning",
      "description": "Tenant browser repair memory, repeat failure fingerprints, reviewable site-profile promotion proposals, metric events, and retention policy."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/capabilities",
      "description": "Capability matrix JSON for connector/tool risk, scopes, approval requirement, demo support, and tenant readiness."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/capabilities.html",
      "description": "Capability matrix operator page."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/ops-scorecard",
      "description": "Compact executive agent ops scorecard for operator home."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/fix-jobs/new",
      "description": "Create and open a Fix With Otto session from a runId query parameter."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/fix-jobs",
      "description": "Create a Fix With Otto session from a failed, weak, or downvoted run."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/fix-jobs/:sessionId",
      "description": "Guided Fix With Otto repair session."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/fix-jobs/:sessionId/feedback",
      "description": "Save operator correction on a Fix With Otto session."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/fix-jobs/:sessionId/save-eval",
      "description": "Save a sanitized eval case from a failed or weak run in Fix With Otto."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/fix-jobs/:sessionId/optimize",
      "description": "Generate a bounded optimization candidate for a Fix With Otto session."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/fix-jobs/:sessionId/accept",
      "description": "Approve and activate the optimization candidate for a Fix With Otto session."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/setup",
      "description": "Setup studio data for one tenant."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/setup",
      "description": "Save tenant setup and redeploy."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/models/discover",
      "description": "List a provider's available models from a (possibly unsaved) API key, for the Model Center dropdown."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/models/:modelId/ping",
      "description": "Ping a configured model to verify connectivity."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/sandbox/complete",
      "description": "Run a freeform prompt against a configured model slot."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/brain",
      "description": "Brain snapshot for one tenant."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/sources",
      "description": "Ingest a source into the tenant Brain."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/sources/youtube",
      "description": "Enqueue a YouTube video transcript for ingestion (captioned videos only in v1)."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/sources/podcast/episode",
      "description": "Enqueue a podcast episode for transcription + ingestion."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/brain/feeds/podcast",
      "description": "List podcast feed subscriptions for one tenant."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/feeds/podcast",
      "description": "Subscribe to a podcast RSS feed. Stores cursor at the latest episode; subsequent polls ingest newer episodes."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/feeds/podcast/poll-all",
      "description": "Poll every active podcast subscription for one tenant."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/feeds/podcast/:subscriptionId/poll",
      "description": "Poll one podcast subscription."
    },
    {
      "method": "DELETE",
      "path": "/tenants/:tenantId/brain/feeds/podcast/:subscriptionId",
      "description": "Archive a podcast subscription."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/brain/search",
      "description": "Search tenant Brain pages and records."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/proposals/:proposalId/approve",
      "description": "Approve a Brain thesis proposal."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/proposals/:proposalId/reject",
      "description": "Reject a Brain thesis proposal."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/proposals/backfill-approvals",
      "description": "Backfill approval-plane records for any pending Brain proposal without an approval_id. Idempotent; surfaces orphaned proposals in Activity → Needs you."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/brain/drive/files",
      "description": "List Google Drive files via the saved Drive connection (operator-side mirror of the builder route)."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/brain/drive/files/:fileId/snippet",
      "description": "Read a short Google Drive text snippet (operator-side mirror of the builder route)."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/drive/import",
      "description": "Fetch a Google Drive file and ingest it into the tenant Brain (operator-side mirror of the builder route)."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/theses/:thesisId/tombstone",
      "description": "Archive (tombstone) a Brain thesis. Removes it from default views but keeps history."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/brain/entities/:entityId",
      "description": "Read a single Brain entity record (incl. open_threads + relevance_score)."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/brain/entities/:entityId/events",
      "description": "Read the append-only timeline for one Brain entity."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/brain/entities/:entityId/threads",
      "description": "List open + resolved threads for one Brain entity."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/entities/:entityId/threads",
      "description": "Manually open a thread on a Brain entity."
    },
    {
      "method": "PATCH",
      "path": "/tenants/:tenantId/brain/entities/:entityId/threads/:threadId",
      "description": "Update / resolve a Brain entity thread."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/brain/entities/:entityId/recompile",
      "description": "Force a compiled-summary recompile on a Brain entity."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/workspace/export",
      "description": "Export compiled workspace files for one tenant."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/runtime",
      "description": "Current runtime snapshot."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/runtime/pause",
      "description": "Pause the active deployment."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/runtime/resume",
      "description": "Resume the active deployment."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/runtime/restart",
      "description": "Restart the active deployment."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/runtime/rollback",
      "description": "Rollback to a prior healthy deployment."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/dashboard",
      "description": "Dashboard snapshot JSON."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/dashboard.html",
      "description": "Rendered operator dashboard HTML."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/dashboard/widgets",
      "description": "Per-vertical dashboard widgets HTML. Gated by ff_job_dashboards."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/dashboard/widgets/:kind/data",
      "description": "Single dashboard widget data envelope (JSON). Gated by ff_job_dashboards."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/approvals",
      "description": "Pending approvals and recent decisions."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/approvals/:approvalId/approve",
      "description": "Approve a pending request."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/approvals/:approvalId/reject",
      "description": "Reject a pending request."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/missions/:envelopeId/approve-similar",
      "description": "Approve this envelope + graduate to an auto policy rule (PR #7). Requires ff_graduated_policy + tenant:policy-admin."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/missions/:envelopeId/require-similar",
      "description": "Approve this envelope + graduate to a require-approval policy rule (PR #7)."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/missions/:envelopeId/deny-similar",
      "description": "Deny this envelope + graduate to a deny policy rule (PR #7)."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/activity/events",
      "description": "Persisted activity events."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/activity/transcripts",
      "description": "Persisted transcript entries."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/activity/notifications",
      "description": "Operator notifications."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/activity/messages",
      "description": "Post an in-app operator message to Otto."
    },
    {
      "method": "GET",
      "path": "/tenants/:tenantId/secrets-access",
      "description": "Secret-access timeline (Glass Vault). Gated by ff_secrets_tab."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/conversations/:conversationId/reply",
      "description": "Persist an operator reply for one conversation."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/channels/telegram/webhook",
      "description": "Telegram webhook ingest endpoint."
    },
    {
      "method": "POST",
      "path": "/tenants/:tenantId/connectors/:connectorKind/push",
      "description": "Connector push ingest endpoint (verify + dedupe)."
    },
    {
      "method": "POST",
      "path": "/events/inbound/google/gmail",
      "description": "Gmail Pub/Sub push receiver. Verifies per-tenant token in ?token=, dedupes via UNIQUE (tenant, provider, external_event_id), fans out matched triggers. PR #15."
    },
    {
      "method": "POST",
      "path": "/events/inbound/google/calendar",
      "description": "Google Calendar push receiver. Verifies per-tenant token in X-Goog-Channel-Token header, dedupes via channel-id+message-number, fans out matched event_added/event_updated/event_cancelled triggers. PR #27."
    },
    {
      "method": "POST",
      "path": "/events/inbound/google/drive",
      "description": "Google Drive push receiver. Verifies per-tenant token in X-Goog-Channel-Token header, looks up tenant subscription, short-circuits on no-trigger, calls drive.changes.list with persisted cursor, fans out drive_change triggers per change. Cursor advance is CAS-protected against concurrent webhook deliveries. PR #28."
    },
    {
      "method": "GET",
      "path": "/operator/tenants/:tenantId/jobs/:jobId/triggers",
      "description": "Operator trigger CRUD page for one job: active + disabled triggers, last-fired, delivery history, create/edit/disable/delete forms. PR #15 (read) + PR #29 (CRUD). Query params: ?showDisabled=1 reveals soft-deleted/disabled rows; ?edit=<triggerId> opens the form in edit mode; ?flash=<msg> renders a green confirmation banner."
    },
    {
      "method": "POST",
      "path": "/operator/tenants/:tenantId/jobs/:jobId/triggers",
      "description": "Create a new event trigger via the operator form. Form fields: triggerKind=event, connectorKind, eventKind, config (JSON). Server-side validates the (connector, event) pair + rejects duplicate enabled filters on the same job. PR #29."
    },
    {
      "method": "POST",
      "path": "/operator/tenants/:tenantId/triggers/:triggerId?action=update",
      "description": "Edit an existing trigger via the operator form. Same body shape as the create endpoint. PR #29."
    },
    {
      "method": "POST",
      "path": "/operator/tenants/:tenantId/triggers/:triggerId/disable",
      "description": "Disable a trigger (sets enabled=false; preserves audit). PR #29."
    },
    {
      "method": "POST",
      "path": "/operator/tenants/:tenantId/triggers/:triggerId/enable",
      "description": "Re-enable a previously-disabled trigger. PR #29."
    },
    {
      "method": "POST",
      "path": "/operator/tenants/:tenantId/triggers/:triggerId/delete",
      "description": "Soft-delete (default; same as disable) or hard-delete (?hard=1) a trigger. PR #29."
    },
    {
      "method": "POST",
      "path": "/operator/tenants/:tenantId/trigger-deliveries/:deliveryId/replay",
      "description": "Re-fire one trigger delivery into the same job(s). PR #15."
    },
    {
      "method": "POST",
      "path": "/operator/tenants/:tenantId/triggers/:triggerId/test",
      "description": "Fire a synthetic event through one trigger's matching path. Validates the filter; does NOT enqueue a real run. PR #30."
    },
    {
      "method": "POST",
      "path": "/admin/tenants/:tenantId/gmail-pubsub-config",
      "description": "Set tenant Gmail Pub/Sub config (token, topic, labels). PR #15."
    },
    {
      "method": "POST",
      "path": "/local-runner/pair-start",
      "description": "Operator requests a capability-scoped pairing code for a local runner."
    },
    {
      "method": "POST",
      "path": "/local-runner/pair",
      "description": "Local runner redeems a pairing code for a runner token."
    },
    {
      "method": "POST",
      "path": "/local-runner/heartbeat",
      "description": "Local runner heartbeats with a fingerprint."
    },
    {
      "method": "POST",
      "path": "/local-runner/unpair",
      "description": "Local runner requests unpair from the server."
    },
    {
      "method": "GET",
      "path": "/local-runner/work",
      "description": "Local runner long-polls for queued Codex jobs."
    },
    {
      "method": "POST",
      "path": "/local-runner/work/:jobId/result",
      "description": "Local runner submits a Codex job result."
    },
    {
      "method": "POST",
      "path": "/local-runner/workspaces/:workspaceId/status",
      "description": "Local runner reports durable browser workspace status and auth proof."
    },
    {
      "method": "POST",
      "path": "/local-runner/computer-use",
      "description": "Server-mediated computer-use bridge for the runner extension. Wraps Anthropic computer-use API; key never leaves api-server."
    },
    {
      "method": "GET",
      "path": "/local-runner/status",
      "description": "Operator lists paired local runners and their online state."
    }
  ]
}
