openapi: "3.1.0"
info:
  title: "Cloak Harbor Personal Exposure Defense API"
  version: "0.10.0"
  description: "Defensive Personal Exposure Defense control plane. Public reads expose authorized-local case data under the configured visibility policy, configured empty stores return honest empty state, and fixture fallback is limited to environments without persistence. Protected actions require PLATPHORM_API_KEY and human approval."
  contact:
    name: "Cloak Harbor"
    url: "https://cloak.platphormnews.com"
servers:
  - 
    url: "https://cloak.platphormnews.com"
    description: "Cloak Harbor production domain"
tags:
  - 
    name: "system"
    description: "Health, docs, discovery and platform compliance"
  - 
    name: "legacy"
    description: "Compatibility endpoints for older clients; current case surfaces use /v1/principal, /v1/findings, /v1/evidence, and /case routes"
  - 
    name: "findings"
    description: "Exposure findings and evidence"
  - 
    name: "risk"
    description: "StealthScore and SigReduce risk rubric"
  - 
    name: "operations"
    description: "Kanban, calendar, actions and reports"
  - 
    name: "ui"
    description: "Product UI state and route/screen introspection"
  - 
    name: "integrations"
    description: "PlatPhorm integration status and protected server-side handoff triggers"
  - 
    name: "payments"
    description: "Stripe Checkout paywall status and webhook receipts"
  - 
    name: "mcp"
    description: "MCP JSON-RPC endpoint"
paths:
  /api/health:
    get:
      tags:
        - "system"
      summary: "Service health"
      responses:
        200:
          description: "OK"
  /api/v1/health:
    get:
      tags:
        - "system"
      summary: "Versioned service health"
      responses:
        200:
          description: "OK"
  /api/docs:
    get:
      tags:
        - "system"
      summary: "Human-readable API docs"
      responses:
        200:
          description: "HTML docs"
  /api/mcp:
    get:
      tags:
        - "mcp"
      summary: "MCP metadata"
      responses:
        200:
          description: "MCP metadata"
    post:
      tags:
        - "mcp"
      summary: "MCP JSON-RPC 2.0 endpoint"
      responses:
        200:
          description: "JSON-RPC response"
  /v1/principal:
    get:
      tags:
        - "operations"
      summary: "Principal profile from redacted authorized-local state or public-safe fallback"
      responses:
        200:
          description: "OK"
  /v1/clients:
    get:
      tags:
        - "operations"
      summary: "List redacted saved client summaries"
      responses:
        200:
          description: "OK"
    post:
      tags:
        - "operations"
      summary: "Create an authorized client record"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Client created"
        400:
          description: "Missing identifier"
        401:
          description: "Unauthorized"
        409:
          description: "Postgres not configured"
  "/v1/clients/{id}":
    get:
      tags:
        - "operations"
      summary: "Get redacted client summary"
      responses:
        200:
          description: "OK"
        404:
          description: "Not found"
  /v1/findings:
    get:
      tags:
        - "findings"
      summary: "List exposure findings"
      responses:
        200:
          description: "OK"
    post:
      tags:
        - "findings"
      summary: "Create finding"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        401:
          description: "Unauthorized"
        501:
          description: "Not implemented for public write paths"
  "/v1/findings/{id}":
    get:
      tags:
        - "findings"
      summary: "Get finding detail"
      responses:
        200:
          description: "OK"
        404:
          description: "Not found"
  /v1/evidence:
    get:
      tags:
        - "findings"
      summary: "List redacted authorized-local evidence records or public-safe fallback"
      responses:
        200:
          description: "OK"
  "/v1/evidence/{id}":
    get:
      tags:
        - "findings"
      summary: "Get evidence detail with protected fields only when authorized"
      responses:
        200:
          description: "OK"
        404:
          description: "Not found"
  /v1/risk/stealthscore:
    get:
      tags:
        - "risk"
      summary: "StealthScore snapshot"
      responses:
        200:
          description: "OK"
  /v1/risk/rubric:
    get:
      tags:
        - "risk"
      summary: "SigReduce risk rubric"
      responses:
        200:
          description: "OK"
  /v1/risk/summary:
    get:
      tags:
        - "risk"
      summary: "Risk summary by finding"
      responses:
        200:
          description: "OK"
  /v1/kanban:
    get:
      tags:
        - "operations"
      summary: "Case Kanban board"
      responses:
        200:
          description: "OK"
  /v1/calendar:
    get:
      tags:
        - "operations"
      summary: "30-day cadence calendar"
      responses:
        200:
          description: "OK"
  /v1/actions:
    get:
      tags:
        - "operations"
      summary: "Action packet queue"
      responses:
        200:
          description: "OK"
  /v1/actions/draft:
    post:
      tags:
        - "operations"
      summary: "Draft an action packet"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Dry-run draft"
        401:
          description: "Unauthorized"
  /v1/reports:
    get:
      tags:
        - "operations"
      summary: "List report summaries"
      responses:
        200:
          description: "OK"
  /v1/production-readiness:
    get:
      tags:
        - "system"
      summary: "Production readiness from runtime, client, case, and Vercel ecosystem state"
      responses:
        200:
          description: "Readiness summary"
  /v1/vercel/notebook:
    get:
      tags:
        - "system"
      summary: "Public-safe Vercel Observability Notebook blueprint for daily operations"
      responses:
        200:
          description: "Notebook blueprint"
  /v1/portal/session/role:
    post:
      tags:
        - "operations"
      summary: "Create a scoped RBAC role session for the Michael Barbine admin, case-manager, or customer view"
      responses:
        200:
          description: "RBAC session cookie created"
        400:
          description: "Invalid role"
  /v1/portal/session/pilot-role:
    post:
      tags:
        - "operations"
      summary: "Legacy compatibility alias for scoped RBAC role sessions"
      responses:
        200:
          description: "RBAC session cookie created"
        400:
          description: "Invalid role"
  /v1/paywall/status:
    get:
      tags:
        - "payments"
      summary: "Inspect Stripe paywall readiness without exposing key values"
      responses:
        200:
          description: "Stripe readiness"
  /v1/paywall/checkout:
    post:
      tags:
        - "payments"
      summary: "Create a Stripe Checkout session for Custom Cloak when server-side Cloak3D Stripe config is present"
      responses:
        200:
          description: "Checkout created or free plan acknowledged"
        400:
          description: "Invalid plan or identity"
        502:
          description: "Stripe checkout failed"
        503:
          description: "Stripe secret missing"
  /v1/paywall/webhook:
    post:
      tags:
        - "payments"
      summary: "Receive verified Stripe webhook events and record protected billing intents"
      responses:
        200:
          description: "Webhook received"
        400:
          description: "Invalid webhook JSON"
        401:
          description: "Signature verification failed"
  /v1/reports/generate:
    post:
      tags:
        - "operations"
      summary: "Generate executive report"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Generated report"
        401:
          description: "Unauthorized"
  "/v1/reports/{id}/review":
    post:
      tags:
        - "operations"
      summary: "Record human report review intent"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Review intent recorded"
        401:
          description: "Unauthorized"
        404:
          description: "Not found"
  "/v1/reports/{id}/publish-docs":
    post:
      tags:
        - "operations"
      summary: "Publish a visibility-policy report to PlatPhorm Docs"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Docs handoff completed"
        401:
          description: "Unauthorized"
        404:
          description: "Not found"
        502:
          description: "Docs handoff failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  "/v1/reports/{id}/export-sheets":
    get:
      tags:
        - "operations"
      summary: "Preview Sheets export evidence references"
      responses:
        200:
          description: "Read-only export preview"
        404:
          description: "Not found"
    post:
      tags:
        - "operations"
      summary: "Export visibility-policy report rows to PlatPhorm Sheets"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Sheets handoff completed"
        401:
          description: "Unauthorized"
        404:
          description: "Not found"
        502:
          description: "Sheets handoff failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  "/v1/reports/{id}/upload-files":
    post:
      tags:
        - "operations"
      summary: "Upload visibility-policy report markdown to PlatPhorm Files"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Files handoff completed"
        401:
          description: "Unauthorized"
        404:
          description: "Not found"
        502:
          description: "Files handoff failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  "/v1/reports/{id}/run-browserops":
    post:
      tags:
        - "operations"
      summary: "Run a BrowserOps journey for the Cloak case surface"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "BrowserOps run requested"
        401:
          description: "Unauthorized"
        404:
          description: "Not found"
        502:
          description: "BrowserOps handoff failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  "/v1/reports/{id}/run-sandbox":
    post:
      tags:
        - "operations"
      summary: "Start a Sandbox lifecycle run with visibility-policy report context"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Sandbox lifecycle run requested"
        401:
          description: "Unauthorized"
        404:
          description: "Not found"
        502:
          description: "Sandbox handoff failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/self-case:
    post:
      tags:
        - "operations"
      summary: "Create or refresh a selected authorized client workload through server-side operator auth"
      responses:
        200:
          description: "Client workload created"
        409:
          description: "Postgres not configured"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/clients:
    get:
      tags:
        - "operations"
      summary: "List saved clients through server-side operator auth"
      responses:
        200:
          description: "Clients listed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
    post:
      tags:
        - "operations"
      summary: "Save an authorized client profile to Postgres"
      responses:
        200:
          description: "Client saved"
        400:
          description: "Missing identifier"
        409:
          description: "Postgres not configured"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/osint:
    post:
      tags:
        - "integrations"
      summary: "Run authorized OSINT/Pentest dry-run handoff and store evidence"
      responses:
        200:
          description: "OSINT handoff completed"
        502:
          description: "Pentest handoff failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/osint/connectors:
    get:
      tags:
        - "integrations"
      summary: "List configured OSINT connector adapters and missing local requirements"
      responses:
        200:
          description: "Connector catalog"
        503:
          description: "Server PLATPHORM_API_KEY missing"
    post:
      tags:
        - "integrations"
      summary: "Run authorized OSINT connector adapters and persist findings, evidence, tasks, and intent ledger rows"
      responses:
        200:
          description: "Connector run completed"
        400:
          description: "Invalid JSON"
        409:
          description: "Postgres not configured"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/osint/runs:
    get:
      tags:
        - "integrations"
      summary: "List persisted OSINT run ledger rows"
      responses:
        200:
          description: "OSINT runs listed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/phone/numverify:
    get:
      tags:
        - "integrations"
      summary: "Inspect Numverify phone-validation readiness for a selected client"
      responses:
        200:
          description: "Numverify readiness"
        503:
          description: "Server PLATPHORM_API_KEY missing"
    post:
      tags:
        - "integrations"
      summary: "Queue or run server-side Numverify validation for an authorized phone identifier"
      responses:
        200:
          description: "Phone verification queued or completed"
        400:
          description: "Invalid JSON"
        409:
          description: "Postgres not configured or provider blocked"
        502:
          description: "Numverify request failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/webhooks/test:
    post:
      tags:
        - "integrations"
      summary: "Emit or record a protected Cloak webhook event"
      responses:
        200:
          description: "Webhook event emitted or blocked with ledger row"
        409:
          description: "Postgres not configured"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/schedules/osint:
    get:
      tags:
        - "operations"
      summary: "List persisted OSINT schedules"
      responses:
        200:
          description: "Schedules listed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
    post:
      tags:
        - "operations"
      summary: "Create a daily, weekly, monthly, or one-time OSINT approval schedule"
      responses:
        200:
          description: "Schedule created"
        409:
          description: "Postgres not configured"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/schedules/osint/progress:
    post:
      tags:
        - "operations"
      summary: "Advance due OSINT schedules and move linked Kanban cards"
      responses:
        200:
          description: "Due schedules progressed"
        409:
          description: "Postgres not configured"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/infrastructure/aws:
    get:
      tags:
        - "infrastructure"
      summary: "Inspect AWS S3/RDS provisioning plan without exposing secrets"
      responses:
        200:
          description: "AWS plan"
        503:
          description: "Server PLATPHORM_API_KEY missing"
    post:
      tags:
        - "infrastructure"
      summary: "Ensure S3 evidence storage or request RDS PostgreSQL provisioning"
      responses:
        200:
          description: "AWS action completed"
        409:
          description: "Missing env or approval required"
        502:
          description: "AWS request failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/operator/workflows/self-case:
    get:
      tags:
        - "operations"
      summary: "Inspect Vercel Workflow readiness for the authorized self-case pipeline"
      responses:
        200:
          description: "Workflow readiness"
    post:
      tags:
        - "operations"
      summary: "Queue the durable Vercel Workflow self-case pipeline when running on Vercel"
      responses:
        200:
          description: "Workflow queued"
        409:
          description: "Workflow runtime unavailable or Postgres not configured"
        502:
          description: "Workflow start failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  "/v1/operator/reports/{id}/{action}":
    post:
      tags:
        - "integrations"
      summary: "Run server-side report generation or platform handoff action"
      responses:
        200:
          description: "Operator report action completed"
        404:
          description: "Unknown report/action"
        502:
          description: "Downstream handoff failed"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/integrations/status:
    get:
      tags:
        - "integrations"
      summary: "Integration status"
      responses:
        200:
          description: "OK"
  /v1/integrations/vercel-connect:
    get:
      tags:
        - "integrations"
      summary: "Inspect Vercel Connect OAuth readiness and callback metadata"
      responses:
        200:
          description: "Vercel Connect status"
    post:
      tags:
        - "integrations"
      summary: "Start Vercel Connect authorization or inspect token metadata without returning tokens to the browser"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Connect action result"
        401:
          description: "RBAC or platform auth required"
        502:
          description: "Vercel Connect request failed"
  /v1/trust-artifacts:
    get:
      tags:
        - "integrations"
      summary: "Public-safe platform trust artifact registry for AgentOps, TrustOps, WebhookLab, and Sandbox"
      responses:
        200:
          description: "Trust artifacts listed"
  /v1/ui:
    get:
      tags:
        - "ui"
      summary: "Product UI state"
      responses:
        200:
          description: "OK"
  /v1/ui/screens:
    get:
      tags:
        - "ui"
      summary: "Product screen and surface registry"
      responses:
        200:
          description: "OK"
  /v1/capabilities:
    get:
      tags:
        - "ui"
      summary: "PED OS capability catalog, screen bindings, and support flags"
      responses:
        200:
          description: "OK"
    post:
      tags:
        - "ui"
      summary: "Bootstrap Postgres capability support"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Bootstrapped"
        401:
          description: "Unauthorized"
        409:
          description: "Postgres not configured"
  /v1/cockpit/actions:
    get:
      tags:
        - "operations"
      summary: "List public cockpit action surfaces"
      responses:
        200:
          description: "Allowlisted cockpit action surfaces"
    post:
      tags:
        - "operations"
      summary: "Execute an allowlisted cockpit action through server-side operator routes"
      responses:
        200:
          description: "Action completed, blocked, or degraded honestly"
        400:
          description: "Unsupported action or invalid JSON"
        503:
          description: "Server PLATPHORM_API_KEY missing"
  /v1/setup:
    get:
      tags:
        - "system"
      summary: "Persistent backend setup status"
      responses:
        200:
          description: "OK"
    post:
      tags:
        - "system"
      summary: "Initialize Postgres persistence tables including case-state records"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Backend initialized"
        401:
          description: "Unauthorized"
        409:
          description: "Postgres not configured"
  /v1/workloads/self-case:
    post:
      tags:
        - "operations"
      summary: "Execute an authorized self-case workload with profile, evidence, findings, tasks, and audit intent"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Authorized self-case created"
        400:
          description: "Missing consent or display name"
        401:
          description: "Unauthorized"
        409:
          description: "Postgres not configured"
  "/v1/kanban/tasks/{id}/move":
    post:
      tags:
        - "operations"
      summary: "Move a persisted local case task between Kanban lanes"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Task moved"
        400:
          description: "Invalid lane"
        401:
          description: "Unauthorized"
        404:
          description: "Task not found"
        409:
          description: "Postgres not configured"
  /v1/loop:
    get:
      tags:
        - "ui"
      summary: "Defense loop ledger from principal to report"
      responses:
        200:
          description: "OK"
    post:
      tags:
        - "ui"
      summary: "Record a Postgres loop ledger checkpoint"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Checkpoint recorded"
        401:
          description: "Unauthorized"
        409:
          description: "Postgres not configured"
  /v1/intents:
    get:
      tags:
        - "operations"
      summary: "Read protected intent ledger"
      responses:
        200:
          description: "OK"
  "/v1/integrations/{service}/{action}":
    post:
      tags:
        - "integrations"
      summary: "Protected integration trigger or report handoff delegate"
      security:
        - 
          platformApiKey:
[]
        - 
          bearerAuth:
[]
      responses:
        200:
          description: "Handoff completed or protected intent recorded"
        401:
          description: "Unauthorized"
        501:
          description: "No executor implemented for this service/action"
        502:
          description: "Downstream handoff failed"
        503:
          description: "Missing server configuration"
  /events:
    get:
      tags:
        - "integrations"
      summary: "Public-safe event outbox with optional protected view"
      responses:
        200:
          description: "OK"
  /webhooks:
    post:
      tags:
        - "integrations"
      summary: "Signed idempotent webhook receiver"
      responses:
        200:
          description: "Received"
        400:
          description: "Bad request"
components:
  securitySchemes:
    platformApiKey:
      type: "apiKey"
      in: "header"
      name: "X-PlatPhorm-API-Key"
      description: "PLATPHORM_API_KEY"
    bearerAuth:
      type: "http"
      scheme: "bearer"
      description: "Authorization: Bearer $PLATPHORM_API_KEY"