openapi: "3.1.0"
info:
  title: "Cloak Harbor Personal Exposure Defense API"
  version: "0.3.0-demo"
  description: "Defensive Personal Exposure Defense control plane. Public reads expose redacted authorized-local self-case data when present, with deterministic synthetic fallback. Protected actions require PLATPHORM_API_KEY and human approval."
  contact:
    name: "Cloak Harbor"
    url: "https://cloak.platphormnews.com"
servers:
  - 
    url: "https://cloak.platphormnews.com/api"
    description: "Cloak Harbor production domain"
tags:
  - 
    name: "system"
    description: "Health, docs, discovery and platform compliance"
  - 
    name: "demo"
    description: "Synthetic fallback fixtures and screenshot-ready demo references"
  - 
    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: "UI scaffold state and route/screen introspection"
  - 
    name: "integrations"
    description: "PlatPhorm integration status and protected server-side handoff triggers"
  - 
    name: "mcp"
    description: "MCP JSON-RPC endpoint"
paths:
  /health:
    get:
      tags:
        - "system"
      summary: "Service health"
      responses:
        200:
          description: "OK"
  /v1/health:
    get:
      tags:
        - "system"
      summary: "Versioned service health"
      responses:
        200:
          description: "OK"
  /docs:
    get:
      tags:
        - "system"
      summary: "Human-readable API docs"
      responses:
        200:
          description: "HTML docs"
  /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/demo/principal:
    get:
      tags:
        - "demo"
      summary: "Synthetic principal scenario"
      responses:
        200:
          description: "OK"
  /v1/demo/runbook:
    get:
      tags:
        - "demo"
      summary: "30-day demo runbook"
      responses:
        200:
          description: "OK"
  /v1/demo/slides:
    get:
      tags:
        - "demo"
      summary: "Screenshot-ready slide targets"
      responses:
        200:
          description: "OK"
  /v1/principal:
    get:
      tags:
        - "demo"
      summary: "Principal profile from redacted authorized-local state or synthetic fallback"
      responses:
        200:
          description: "OK"
  /v1/clients:
    get:
      tags:
        - "operations"
      summary: "List redacted client summaries including Jordan sample and Michael self-case"
      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 in synthetic demo"
  "/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 synthetic 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/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 redacted 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":
    post:
      tags:
        - "operations"
      summary: "Export redacted 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 redacted 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 redacted 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 the Michael self-case through server-side operator auth"
      responses:
        200:
          description: "Self-case 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/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/ui:
    get:
      tags:
        - "ui"
      summary: "UI scaffold state"
      responses:
        200:
          description: "OK"
  /v1/ui/screens:
    get:
      tags:
        - "ui"
      summary: "Demo 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/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"