openapi: "3.1.0"
info:
  title: "CrawlDex API"
  version: "0.1.0"
  summary: "Agent-readable task reliability, preflight, recipe, alternatives, accounts, and outcome reporting API."
  description: "CrawlDex helps web agents resolve user intents into canonical tasks, inspect known blockers and recipes, preflight task attempts, and report outcome evidence after execution.\n\nPublic read endpoints return confidence, freshness, evidence, and trust metadata so agents can decide when to proceed, ask the user to stay present, or avoid stale evidence."
  x-generated-at: "2026-06-08T21:33:27.951Z"
jsonSchemaDialect: "https://json-schema.org/draft/2020-12/schema"
servers:
  -
    url: "https://crawldex.com"
    description: "Configured CrawlDex API origin."
tags:
  -
    name: "Health"
    description: "Process health and service metadata."
  -
    name: "Catalog"
    description: "Taxonomy, categories, tasks, and operating-map discovery."
  -
    name: "Decisioning"
    description: "Intent resolution, preflight decisions, site status, recipes, and alternatives."
  -
    name: "Reporting"
    description: "Outcome report ingestion after agent task attempts."
  -
    name: "Accounts"
    description: "Agent reporter account discovery, signup, session, and inspection."
paths:
  "/health":
    get:
      tags:
        - "Health"
      operationId: "getHealth"
      summary: "Check CrawlDex process health."
      responses:
        200:
          description: "CrawlDex process health."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/HealthResponse"
  "/api/v1/taxonomy":
    get:
      tags:
        - "Catalog"
      operationId: "getTaxonomy"
      summary: "Read canonical CrawlDex taxonomy."
      description: "Returns categories, task definitions, friction codes, score dimensions, and metadata."
      responses:
        200:
          description: "Canonical taxonomy."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/TaxonomyResponse"
  "/api/v1/operating-map":
    get:
      tags:
        - "Catalog"
      operationId: "getOperatingMap"
      summary: "Read the public operating map."
      responses:
        200:
          description: "Category-level operating-map summary."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/OperatingMapResponse"
  "/api/v1/categories":
    get:
      tags:
        - "Catalog"
      operationId: "listCategories"
      summary: "List category maps."
      responses:
        200:
          description: "Category map list."
          content:
            "application/json":
              schema:
                type: "array"
                items:
                  "$ref": "#/components/schemas/CategoryMapResponse"
  "/api/v1/categories/{category}":
    get:
      tags:
        - "Catalog"
      operationId: "getCategory"
      summary: "Inspect one category map."
      parameters:
        -
          name: "category"
          in: "path"
          required: true
          description: "Category key, for example `subscriptions`."
          schema:
            type: "string"
            minLength: 1
          example: "subscriptions"
      responses:
        200:
          description: "Category map."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/CategoryMapResponse"
        400:
          description: "Invalid category parameter."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/tasks/{task}":
    get:
      tags:
        - "Catalog"
      operationId: "getTask"
      summary: "Inspect one task map."
      parameters:
        -
          name: "task"
          in: "path"
          required: true
          description: "Task key or alias, for example `commerce.checkout`."
          schema:
            type: "string"
            minLength: 1
          example: "commerce.checkout"
      responses:
        200:
          description: "Task map."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/TaskMapResponse"
        400:
          description: "Invalid task parameter."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/resolve":
    get:
      tags:
        - "Decisioning"
      operationId: "resolveIntent"
      summary: "Resolve a natural-language intent to task candidates."
      parameters:
        -
          name: "q"
          in: "query"
          required: true
          description: "Natural-language user intent."
          schema:
            type: "string"
            minLength: 1
            maxLength: 500
          example: "cancel my subscription"
      responses:
        200:
          description: "Intent candidates."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/IntentResolution"
        400:
          description: "Invalid query."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/preflight":
    post:
      tags:
        - "Decisioning"
      operationId: "preflightTask"
      summary: "Preflight a site and task before an agent attempts it."
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              "$ref": "#/components/schemas/PreflightRequest"
            examples:
              commerceCheckout:
                "$ref": "#/components/examples/PreflightRequestExample"
      responses:
        200:
          description: "Preflight decision, score, recipe, alternatives, and reporting metadata."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/PreflightResponseWithReporting"
              examples:
                commerceCheckout:
                  "$ref": "#/components/examples/PreflightResponseExample"
        400:
          description: "Invalid preflight request."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/runs":
    post:
      tags:
        - "Reporting"
      operationId: "reportOutcome"
      summary: "Report task outcome evidence after an agent attempt."
      description: "Anonymous reports are accepted but downgraded to `anonymous_report`. Agent keys provide attribution; ingest tokens mark trusted platform submissions."
      security:
        -
          AgentKeyAuth:
[]
        -
          IngestTokenAuth:
[]
        -
{}
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              "$ref": "#/components/schemas/RunReportRequest"
            examples:
              reportOutcome:
                "$ref": "#/components/examples/ReportOutcomeRequestExample"
      responses:
        201:
          description: "Accepted outcome report."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/RunReportResponse"
              examples:
                reportOutcome:
                  "$ref": "#/components/examples/ReportOutcomeResponseExample"
        400:
          description: "Invalid run report."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        401:
          description: "Invalid agent key."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        429:
          description: "Run ingestion rate limit exceeded."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/status/{site}":
    get:
      tags:
        - "Decisioning"
      operationId: "getSiteStatus"
      summary: "Read known task status for a site."
      parameters:
        -
          name: "site"
          in: "path"
          required: true
          description: "Site hostname or URL."
          schema:
            type: "string"
            minLength: 1
          example: "demo-shop.crawldex.com"
      responses:
        200:
          description: "Site status."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/OriginStatusResponse"
        400:
          description: "Invalid site parameter."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/recipes/{site}/{task}":
    get:
      tags:
        - "Decisioning"
      operationId: "getRecipe"
      summary: "Fetch recipe metadata for a site and task."
      parameters:
        -
          name: "site"
          in: "path"
          required: true
          description: "Site hostname or URL."
          schema:
            type: "string"
            minLength: 1
          example: "demo-shop.crawldex.com"
        -
          name: "task"
          in: "path"
          required: true
          description: "Task key or alias."
          schema:
            type: "string"
            minLength: 1
          example: "commerce.checkout"
      responses:
        200:
          description: "Recipe lookup response."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/RecipeResponse"
        400:
          description: "Invalid recipe parameters."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/alternatives":
    post:
      tags:
        - "Decisioning"
      operationId: "getAlternatives"
      summary: "Find alternative sites for a task."
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              "$ref": "#/components/schemas/AlternativesRequest"
      responses:
        200:
          description: "Alternative site rankings."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AlternativesResponse"
        400:
          description: "Invalid alternatives request."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/accounts/options":
    get:
      tags:
        - "Accounts"
      operationId: "getAccountOptions"
      summary: "Discover available account and reporting options."
      responses:
        200:
          description: "Account options and reporting metadata."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AccountOptionsResponse"
  "/api/v1/accounts/agents":
    post:
      tags:
        - "Accounts"
      operationId: "signupAgentAccount"
      summary: "Create an email-free agent reporter account."
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              "$ref": "#/components/schemas/AgentAccountSignupRequest"
      responses:
        201:
          description: "Agent account credential."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AgentAccountCredential"
        400:
          description: "Invalid signup request."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        409:
          description: "Reporter handle is already registered."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/accounts/agents/session":
    post:
      tags:
        - "Accounts"
      operationId: "createAgentSession"
      summary: "Create a fresh agent API key with handle and password."
      requestBody:
        required: true
        content:
          "application/json":
            schema:
              "$ref": "#/components/schemas/AgentAccountSessionRequest"
      responses:
        200:
          description: "Agent account credential."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AgentAccountCredential"
        400:
          description: "Invalid session request."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
        401:
          description: "Invalid agent credentials."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
  "/api/v1/accounts/me":
    get:
      tags:
        - "Accounts"
      operationId: "getAgentAccountMe"
      summary: "Inspect the agent account for the supplied agent key."
      security:
        -
          AgentKeyAuth:
[]
      responses:
        200:
          description: "Authenticated agent account."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/AgentAccountMeResponse"
        401:
          description: "Agent key missing or invalid."
          content:
            "application/json":
              schema:
                "$ref": "#/components/schemas/ErrorResponse"
components:
  securitySchemes:
    AgentKeyAuth:
      type: "apiKey"
      in: "header"
      name: "x-crawldex-agent-key"
      description: "Agent reporter API key returned by signup or session endpoints."
    IngestTokenAuth:
      type: "apiKey"
      in: "header"
      name: "x-crawldex-ingest-token"
      description: "Trusted platform ingest token configured by CrawlDex operators."
  schemas:
    HealthResponse:
      type: "object"
      properties:
        ok:
          type: "boolean"
        service:
          type: "string"
        version:
          type: "string"
        time:
          type: "string"
          format: "date-time"
        dependencies:
          type: "object"
          properties:
            repository:
              type: "string"
          required:
            - "repository"
          additionalProperties: false
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "ok"
        - "service"
        - "version"
        - "time"
        - "dependencies"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    ConfidenceSummary:
      type: "object"
      properties:
        score:
          type: "number"
          minimum: 0
          maximum: 1
        level:
          type: "string"
          enum:
            - "low"
            - "medium"
            - "high"
        sample_size:
          type: "integer"
          minimum: 0
        rationale:
          type: "string"
      required:
        - "score"
        - "level"
        - "sample_size"
        - "rationale"
      additionalProperties: false
    FreshnessSummary:
      type: "object"
      properties:
        updated_at:
          oneOf:
            -
              type: "string"
              format: "date-time"
            -
              type: "null"
        age_days:
          oneOf:
            -
              type: "integer"
              minimum: 0
            -
              type: "null"
        status:
          type: "string"
          enum:
            - "fresh"
            - "aging"
            - "stale"
            - "unknown"
        rationale:
          type: "string"
      required:
        - "updated_at"
        - "age_days"
        - "status"
        - "rationale"
      additionalProperties: false
    EvidenceSummary:
      type: "object"
      properties:
        sample_size:
          type: "integer"
          minimum: 0
        source_tiers:
          type: "array"
          items:
            "$ref": "#/components/schemas/EvidenceSourceTier"
        evidence_ids:
          type: "array"
          items:
            type: "string"
        latest_evidence_id:
          oneOf:
            -
              type: "string"
            -
              type: "null"
        notes:
          type: "array"
          items:
            type: "string"
      required:
        - "sample_size"
        - "source_tiers"
        - "evidence_ids"
        - "latest_evidence_id"
        - "notes"
      additionalProperties: false
    TrustSummary:
      type: "object"
      properties:
        score:
          type: "number"
          minimum: 0
          maximum: 1
        level:
          type: "string"
          enum:
            - "untrusted"
            - "low"
            - "medium"
            - "high"
        reporter_count:
          type: "integer"
          minimum: 0
        deduplicated_evidence_count:
          type: "integer"
          minimum: 0
        quarantined_count:
          type: "integer"
          minimum: 0
        rationale:
          type: "string"
      required:
        - "score"
        - "level"
        - "reporter_count"
        - "deduplicated_evidence_count"
        - "quarantined_count"
        - "rationale"
      additionalProperties: false
    EvidenceSourceTier:
      type: "string"
      enum:
        - "seeded_example"
        - "anonymous_report"
        - "merchant_report"
        - "attested_sdk"
        - "synthetic_canary"
    Outcome:
      type: "string"
      enum:
        - "success"
        - "success_with_handoff"
        - "partial"
        - "blocked"
        - "failed"
        - "abandoned"
    AgentProfile:
      type: "object"
      properties:
        stack:
          type: "string"
          maxLength: 128
        model:
          type: "string"
          maxLength: 128
        browser_runtime:
          type: "string"
          maxLength: 128
        version:
          type: "string"
          maxLength: 128
        identity_class:
          type: "string"
          maxLength: 128
        capabilities:
          type: "object"
          additionalProperties:
            oneOf:
              -
                type: "boolean"
              -
                type: "number"
              -
                type: "string"
                maxLength: 128
      additionalProperties: false
    CategoryDefinition:
      type: "object"
      properties:
        key:
          type: "string"
        title:
          type: "string"
        blurb:
          type: "string"
        order:
          type: "integer"
          minimum: 0
        status:
          "$ref": "#/components/schemas/TaskMaturity"
        aliases:
          type: "array"
          items:
            type: "string"
      required:
        - "key"
        - "title"
        - "blurb"
        - "order"
        - "status"
        - "aliases"
      additionalProperties: false
    TaskMaturity:
      type: "string"
      enum:
        - "live"
        - "emerging"
        - "future"
    TaskDefinition:
      type: "object"
      properties:
        key:
          type: "string"
        category:
          type: "string"
        title:
          type: "string"
        surface:
          type: "string"
        description:
          type: "string"
        aliases:
          type: "array"
          items:
            type: "string"
        params_schema:
          type: "object"
          additionalProperties: true
        success_criteria:
          type: "array"
          items:
            type: "string"
        recommended_agent_posture:
          type: "string"
        status:
          "$ref": "#/components/schemas/TaskMaturity"
        handoff_posture:
          type: "string"
          enum:
            - "agent_autonomous"
            - "user_present_for_auth"
            - "user_present_for_payment"
            - "human_handoff_expected"
            - "not_advised"
        api_posture:
          type: "string"
          enum:
            - "mcp_native"
            - "documented_api"
            - "browser_only"
            - "unknown"
        typical_blockers:
          type: "array"
          items:
            type: "string"
        related_tasks:
          type: "array"
          items:
            type: "string"
      required:
        - "key"
        - "category"
        - "title"
        - "surface"
        - "description"
        - "aliases"
        - "params_schema"
        - "success_criteria"
        - "recommended_agent_posture"
        - "status"
        - "handoff_posture"
        - "api_posture"
        - "typical_blockers"
        - "related_tasks"
      additionalProperties: false
    FrictionDefinition:
      type: "object"
      properties:
        code:
          type: "string"
        severity:
          type: "integer"
          minimum: 1
          maximum: 5
        blocking:
          type: "boolean"
        who_can_fix:
          type: "string"
          enum:
            - "merchant"
            - "agent"
            - "user"
            - "protocol"
        description:
          type: "string"
      required:
        - "code"
        - "severity"
        - "blocking"
        - "who_can_fix"
        - "description"
      additionalProperties: false
    ScoreDimension:
      type: "object"
      properties:
        key:
          type: "string"
        title:
          type: "string"
        description:
          type: "string"
      required:
        - "key"
        - "title"
        - "description"
      additionalProperties: false
    TaxonomyResponse:
      type: "object"
      properties:
        categories:
          type: "array"
          items:
            "$ref": "#/components/schemas/CategoryDefinition"
        tasks:
          type: "array"
          items:
            "$ref": "#/components/schemas/TaskDefinition"
        friction:
          type: "array"
          items:
            "$ref": "#/components/schemas/FrictionDefinition"
        score_dimensions:
          type: "array"
          items:
            "$ref": "#/components/schemas/ScoreDimension"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "categories"
        - "tasks"
        - "friction"
        - "score_dimensions"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    OperatingMapResponse:
      type: "object"
      properties:
        map_version:
          type: "string"
        categories:
          type: "array"
          items:
            "$ref": "#/components/schemas/CategoryMapResponse"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "map_version"
        - "categories"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    CategoryMapResponse:
      type: "object"
      properties:
        category:
          "$ref": "#/components/schemas/CategoryDefinition"
        task_count:
          type: "integer"
          minimum: 0
        evidence_task_count:
          type: "integer"
          minimum: 0
        tasks:
          type: "array"
          items:
            type: "object"
            properties:
              task:
                type: "string"
              title:
                type: "string"
              status:
                "$ref": "#/components/schemas/TaskMaturity"
              health:
                "$ref": "#/components/schemas/TaskHealth"
              aes:
                oneOf:
                  -
                    type: "integer"
                    minimum: 0
                    maximum: 100
                  -
                    type: "null"
              evidence_count:
                type: "integer"
                minimum: 0
              handoff_posture:
                "$ref": "#/components/schemas/HandoffPosture"
              api_posture:
                "$ref": "#/components/schemas/ApiPosture"
            required:
              - "task"
              - "title"
              - "status"
              - "health"
              - "aes"
              - "evidence_count"
              - "handoff_posture"
              - "api_posture"
            additionalProperties: false
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
        trust:
          "$ref": "#/components/schemas/TrustSummary"
      required:
        - "category"
        - "task_count"
        - "evidence_task_count"
        - "tasks"
        - "confidence"
        - "freshness"
        - "evidence"
        - "trust"
      additionalProperties: false
    TaskMapResponse:
      type: "object"
      properties:
        task:
          "$ref": "#/components/schemas/TaskDefinition"
        category:
          "$ref": "#/components/schemas/CategoryDefinition"
        health:
          "$ref": "#/components/schemas/TaskHealth"
        sites:
          type: "array"
          items:
            "$ref": "#/components/schemas/TaskMapSite"
        known_blockers:
          type: "array"
          items:
            type: "string"
        typical_blockers:
          type: "array"
          items:
            type: "string"
        handoff_posture:
          "$ref": "#/components/schemas/HandoffPosture"
        api_posture:
          "$ref": "#/components/schemas/ApiPosture"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        recommended_actions:
          type: "array"
          items:
            "$ref": "#/components/schemas/ActionRecommendation"
      required:
        - "task"
        - "category"
        - "health"
        - "sites"
        - "known_blockers"
        - "typical_blockers"
        - "handoff_posture"
        - "api_posture"
        - "confidence"
        - "freshness"
        - "evidence"
        - "trust"
        - "recommended_actions"
      additionalProperties: false
    TaskMapSite:
      type: "object"
      properties:
        site:
          type: "string"
        health:
          "$ref": "#/components/schemas/TaskHealth"
        aes:
          oneOf:
            -
              type: "integer"
              minimum: 0
              maximum: 100
            -
              type: "null"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        known_blockers:
          type: "array"
          items:
            type: "string"
        recipe_uri:
          oneOf:
            -
              type: "string"
            -
              type: "null"
      required:
        - "site"
        - "health"
        - "aes"
        - "confidence"
        - "freshness"
        - "known_blockers"
        - "recipe_uri"
      additionalProperties: false
    TaskHealth:
      type: "string"
      enum:
        - "healthy"
        - "degraded"
        - "constrained"
        - "blocked"
        - "unknown"
    HandoffPosture:
      type: "string"
      enum:
        - "agent_autonomous"
        - "user_present_for_auth"
        - "user_present_for_payment"
        - "human_handoff_expected"
        - "not_advised"
    ApiPosture:
      type: "string"
      enum:
        - "mcp_native"
        - "documented_api"
        - "browser_only"
        - "unknown"
    IntentResolution:
      type: "object"
      properties:
        query:
          type: "string"
        candidates:
          type: "array"
          items:
            type: "object"
            properties:
              task:
                type: "string"
              title:
                type: "string"
              category:
                type: "string"
              confidence:
                type: "number"
                minimum: 0
                maximum: 1
              matched:
                type: "array"
                items:
                  type: "string"
            required:
              - "task"
              - "title"
              - "category"
              - "confidence"
              - "matched"
            additionalProperties: false
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "query"
        - "candidates"
        - "trust"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    PreflightRequest:
      type: "object"
      properties:
        site:
          type: "string"
          minLength: 1
          maxLength: 253
        task:
          type: "string"
          minLength: 1
          maxLength: 160
        agent_profile:
          "$ref": "#/components/schemas/AgentProfile"
        intent:
          type: "string"
          minLength: 1
          maxLength: 500
        constraints:
          type: "object"
          additionalProperties: true
      required:
        - "site"
        - "task"
      additionalProperties: false
    PreflightResponse:
      type: "object"
      properties:
        site:
          type: "string"
        task:
          type: "string"
        decision:
          type: "object"
          properties:
            recommendation:
              "$ref": "#/components/schemas/RecommendationCode"
            risk_level:
              type: "string"
              enum:
                - "low"
                - "medium"
                - "high"
                - "unknown"
            should_attempt_autonomously:
              type: "boolean"
            rationale:
              type: "string"
          required:
            - "recommendation"
            - "risk_level"
            - "should_attempt_autonomously"
            - "rationale"
          additionalProperties: false
        score:
          "$ref": "#/components/schemas/TaskStatus"
        known_good_path:
          oneOf:
            -
              "$ref": "#/components/schemas/Recipe"
            -
              type: "null"
        alternatives:
          type: "array"
          items:
            "$ref": "#/components/schemas/Alternative"
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        recommended_actions:
          type: "array"
          items:
            "$ref": "#/components/schemas/ActionRecommendation"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "site"
        - "task"
        - "decision"
        - "score"
        - "known_good_path"
        - "alternatives"
        - "trust"
        - "recommended_actions"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    PreflightResponseWithReporting:
      allOf:
        -
          "$ref": "#/components/schemas/PreflightResponse"
        -
          type: "object"
          properties:
            reporting:
              "$ref": "#/components/schemas/ReportingMetadata"
          required:
            - "reporting"
          additionalProperties: false
    RecommendationCode:
      type: "string"
      enum:
        - "proceed_with_recipe"
        - "proceed_with_guardrails"
        - "use_browser_with_user_present"
        - "avoid_until_fresh_evidence"
        - "collect_evidence_first"
    TaskStatus:
      type: "object"
      properties:
        site:
          type: "string"
        task:
          type: "string"
        health:
          "$ref": "#/components/schemas/TaskHealth"
        aes:
          oneOf:
            -
              type: "integer"
              minimum: 0
              maximum: 100
            -
              type: "null"
        outcome_rate:
          oneOf:
            -
              type: "number"
              minimum: 0
              maximum: 1
            -
              type: "null"
        known_blockers:
          type: "array"
          items:
            type: "string"
        recipe_uri:
          oneOf:
            -
              type: "string"
            -
              type: "null"
        policy_notes:
          type: "object"
          additionalProperties:
            type: "string"
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        dimensions:
          type: "array"
          items:
            "$ref": "#/components/schemas/ScoreDimensionValue"
        segments:
          type: "array"
          items:
            "$ref": "#/components/schemas/AgentSegmentScore"
        recommended_actions:
          type: "array"
          items:
            "$ref": "#/components/schemas/ActionRecommendation"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "site"
        - "task"
        - "health"
        - "aes"
        - "outcome_rate"
        - "known_blockers"
        - "recipe_uri"
        - "policy_notes"
        - "trust"
        - "dimensions"
        - "segments"
        - "recommended_actions"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    ScoreDimensionValue:
      type: "object"
      properties:
        key:
          type: "string"
        score:
          oneOf:
            -
              type: "number"
              minimum: 0
              maximum: 100
            -
              type: "null"
        sample_size:
          type: "integer"
          minimum: 0
        rationale:
          type: "string"
      required:
        - "key"
        - "score"
        - "sample_size"
        - "rationale"
      additionalProperties: false
    AgentSegmentScore:
      type: "object"
      properties:
        segment:
          type: "object"
          properties:
            stack:
              oneOf:
                -
                  type: "string"
                -
                  type: "null"
            model:
              oneOf:
                -
                  type: "string"
                -
                  type: "null"
            browser_runtime:
              oneOf:
                -
                  type: "string"
                -
                  type: "null"
            identity_class:
              oneOf:
                -
                  type: "string"
                -
                  type: "null"
          required:
            - "stack"
            - "model"
            - "browser_runtime"
            - "identity_class"
          additionalProperties: false
        aes:
          oneOf:
            -
              type: "integer"
              minimum: 0
              maximum: 100
            -
              type: "null"
        outcome_rate:
          oneOf:
            -
              type: "number"
              minimum: 0
              maximum: 1
            -
              type: "null"
        sample_size:
          type: "integer"
          minimum: 0
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        known_blockers:
          type: "array"
          items:
            type: "string"
      required:
        - "segment"
        - "aes"
        - "outcome_rate"
        - "sample_size"
        - "confidence"
        - "freshness"
        - "known_blockers"
      additionalProperties: false
    ActionRecommendation:
      type: "object"
      properties:
        priority:
          type: "string"
          enum:
            - "high"
            - "medium"
            - "low"
        actor:
          type: "string"
          enum:
            - "agent"
            - "merchant"
            - "user"
            - "crawldex"
        action:
          type: "string"
        expected_impact:
          type: "string"
      required:
        - "priority"
        - "actor"
        - "action"
        - "expected_impact"
      additionalProperties: false
    Recipe:
      type: "object"
      properties:
        uri:
          type: "string"
        version:
          type: "integer"
          minimum: 1
        status:
          type: "string"
          enum:
            - "active"
            - "stale"
            - "unavailable"
        agent_class:
          type: "string"
        summary:
          type: "string"
        steps:
          type: "array"
          items:
            type: "object"
            properties:
              order:
                type: "integer"
                minimum: 1
              instruction:
                type: "string"
              evidence_gate:
                type: "string"
            required:
              - "order"
              - "instruction"
            additionalProperties: false
        guards:
          type: "array"
          items:
            type: "string"
        success_signals:
          type: "array"
          items:
            type: "string"
        expires_at:
          oneOf:
            -
              type: "string"
              format: "date-time"
            -
              type: "null"
      required:
        - "uri"
        - "version"
        - "status"
        - "agent_class"
        - "summary"
        - "steps"
        - "guards"
        - "success_signals"
        - "expires_at"
      additionalProperties: false
    Alternative:
      type: "object"
      properties:
        site:
          type: "string"
        task:
          type: "string"
        aes:
          type: "integer"
          minimum: 0
          maximum: 100
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        reason:
          type: "string"
        known_blockers:
          type: "array"
          items:
            type: "string"
        recipe_uri:
          oneOf:
            -
              type: "string"
            -
              type: "null"
      required:
        - "site"
        - "task"
        - "aes"
        - "confidence"
        - "freshness"
        - "reason"
        - "known_blockers"
        - "recipe_uri"
      additionalProperties: false
    RunReportRequest:
      type: "object"
      properties:
        site:
          type: "string"
          minLength: 1
          maxLength: 253
        task:
          type: "string"
          minLength: 1
          maxLength: 160
        agent_profile:
          "$ref": "#/components/schemas/AgentProfile"
        outcome:
          "$ref": "#/components/schemas/Outcome"
        friction:
          type: "array"
          items:
            type: "string"
            minLength: 1
            maxLength: 128
          maxItems: 50
        steps:
          type: "integer"
          minimum: 0
        duration_sec:
          type: "number"
          minimum: 0
        token_cost_usd:
          type: "number"
          minimum: 0
        access_fee_usd:
          type: "number"
          minimum: 0
        source_tier:
          "$ref": "#/components/schemas/EvidenceSourceTier"
        evidence:
          type: "object"
          properties:
            id:
              type: "string"
              minLength: 1
              maxLength: 128
            hash:
              type: "string"
              minLength: 1
              maxLength: 128
            uri:
              type: "string"
              minLength: 1
              maxLength: 2048
            artifact_types:
              type: "array"
              items:
                type: "string"
                minLength: 1
                maxLength: 128
              maxItems: 20
            signature:
              type: "string"
              minLength: 1
              maxLength: 4096
          additionalProperties: false
        reporter:
          type: "object"
          properties:
            id:
              type: "string"
              minLength: 1
              maxLength: 128
            public_key_id:
              type: "string"
              minLength: 1
              maxLength: 128
            signature:
              type: "string"
              minLength: 1
              maxLength: 4096
            attestation_type:
              type: "string"
              enum:
                - "none"
                - "api_key"
                - "signed_report"
                - "local_operator"
                - "canary_worker"
          additionalProperties: false
        occurred_at:
          type: "string"
          format: "date-time"
      required:
        - "site"
        - "task"
        - "outcome"
      additionalProperties: false
    RunRecord:
      type: "object"
      properties:
        id:
          type: "string"
        site:
          type: "string"
        task:
          type: "string"
        agent_profile:
          "$ref": "#/components/schemas/AgentProfile"
        outcome:
          "$ref": "#/components/schemas/Outcome"
        friction:
          type: "array"
          items:
            type: "string"
        steps:
          type: "integer"
          minimum: 0
        duration_sec:
          type: "number"
          minimum: 0
        token_cost_usd:
          type: "number"
          minimum: 0
        access_fee_usd:
          type: "number"
          minimum: 0
        source_tier:
          "$ref": "#/components/schemas/EvidenceSourceTier"
        evidence:
          type: "object"
          properties:
            id:
              type: "string"
            hash:
              oneOf:
                -
                  type: "string"
                -
                  type: "null"
            uri:
              oneOf:
                -
                  type: "string"
                -
                  type: "null"
            artifact_types:
              type: "array"
              items:
                type: "string"
            signature:
              oneOf:
                -
                  type: "string"
                -
                  type: "null"
          required:
            - "id"
            - "hash"
            - "uri"
            - "artifact_types"
            - "signature"
          additionalProperties: false
        reporter:
          type: "object"
          properties:
            id:
              type: "string"
            public_key_id:
              type: "string"
            signature:
              type: "string"
            attestation_type:
              type: "string"
              enum:
                - "none"
                - "api_key"
                - "signed_report"
                - "local_operator"
                - "canary_worker"
          required:
            - "id"
            - "public_key_id"
            - "signature"
            - "attestation_type"
          additionalProperties: false
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        dedup_key:
          type: "string"
        occurred_at:
          type: "string"
          format: "date-time"
        reported_at:
          type: "string"
          format: "date-time"
      required:
        - "id"
        - "site"
        - "task"
        - "agent_profile"
        - "outcome"
        - "friction"
        - "steps"
        - "duration_sec"
        - "token_cost_usd"
        - "access_fee_usd"
        - "source_tier"
        - "evidence"
        - "reporter"
        - "trust"
        - "dedup_key"
        - "occurred_at"
        - "reported_at"
      additionalProperties: false
    RunReportResponse:
      type: "object"
      properties:
        accepted:
          type: "boolean"
          const: true
        run:
          "$ref": "#/components/schemas/RunRecord"
        updated_status:
          "$ref": "#/components/schemas/TaskStatus"
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "accepted"
        - "run"
        - "updated_status"
        - "trust"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    OriginStatusResponse:
      type: "object"
      properties:
        site:
          type: "string"
        overall_health:
          "$ref": "#/components/schemas/TaskHealth"
        tasks:
          type: "array"
          items:
            "$ref": "#/components/schemas/TaskStatus"
        incidents:
          type: "array"
          items:
            type: "object"
            properties:
              id:
                type: "string"
              task:
                type: "string"
              severity:
                type: "string"
                enum:
                  - "low"
                  - "medium"
                  - "high"
              opened_at:
                type: "string"
                format: "date-time"
              status:
                type: "string"
                enum:
                  - "open"
                  - "closed"
              summary:
                type: "string"
            required:
              - "id"
              - "task"
              - "severity"
              - "opened_at"
              - "status"
              - "summary"
            additionalProperties: false
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        recommended_actions:
          type: "array"
          items:
            "$ref": "#/components/schemas/ActionRecommendation"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "site"
        - "overall_health"
        - "tasks"
        - "incidents"
        - "trust"
        - "recommended_actions"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    RecipeResponse:
      type: "object"
      properties:
        site:
          type: "string"
        task:
          type: "string"
        available:
          type: "boolean"
        recipe:
          "$ref": "#/components/schemas/Recipe"
        known_blockers:
          type: "array"
          items:
            type: "string"
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        recommended_actions:
          type: "array"
          items:
            "$ref": "#/components/schemas/ActionRecommendation"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "site"
        - "task"
        - "available"
        - "recipe"
        - "known_blockers"
        - "trust"
        - "recommended_actions"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    AlternativesRequest:
      type: "object"
      properties:
        site:
          type: "string"
          minLength: 1
          maxLength: 253
        task:
          type: "string"
          minLength: 1
          maxLength: 160
        constraints:
          type: "object"
          properties:
            category:
              type: "string"
              minLength: 1
              maxLength: 128
            min_aes:
              type: "number"
              minimum: 0
              maximum: 100
            avoid_blockers:
              type: "array"
              items:
                type: "string"
                minLength: 1
                maxLength: 128
              maxItems: 50
            limit:
              type: "integer"
              minimum: 1
              maximum: 20
          additionalProperties: false
      required:
        - "task"
      additionalProperties: false
    AlternativesResponse:
      type: "object"
      properties:
        task:
          type: "string"
        alternatives:
          type: "array"
          items:
            "$ref": "#/components/schemas/Alternative"
        trust:
          "$ref": "#/components/schemas/TrustSummary"
        recommended_actions:
          type: "array"
          items:
            "$ref": "#/components/schemas/ActionRecommendation"
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "task"
        - "alternatives"
        - "trust"
        - "recommended_actions"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
    ReportingMetadata:
      type: "object"
      properties:
        report_url:
          type: "string"
          format: "uri"
        method:
          type: "string"
          enum:
            - "POST"
        anonymous_allowed:
          type: "boolean"
        auth_headers:
          type: "object"
          properties:
            agent_account:
              type: "string"
              const: "x-crawldex-agent-key"
            platform_ingest_token:
              type: "string"
              const: "x-crawldex-ingest-token"
          required:
            - "agent_account"
            - "platform_ingest_token"
          additionalProperties: false
        self_registered_source_tier:
          type: "string"
          const: "anonymous_report"
        mcp_tool:
          type: "string"
          const: "report_outcome"
        evidence_upload:
          type: "string"
      required:
        - "report_url"
        - "method"
        - "anonymous_allowed"
        - "auth_headers"
        - "self_registered_source_tier"
        - "mcp_tool"
        - "evidence_upload"
      additionalProperties: false
    AccountOptionsResponse:
      type: "object"
      properties:
        accounts:
          type: "object"
          properties:
            agent_no_email:
              type: "object"
              properties:
                status:
                  type: "string"
                signup_url:
                  type: "string"
                  format: "uri"
                session_url:
                  type: "string"
                  format: "uri"
                me_url:
                  type: "string"
                  format: "uri"
                identifier:
                  type: "string"
                auth_header:
                  type: "string"
                  const: "x-crawldex-agent-key"
                password_min_length:
                  type: "integer"
                  minimum: 1
                trust_note:
                  type: "string"
              required:
                - "status"
                - "signup_url"
                - "session_url"
                - "me_url"
                - "identifier"
                - "auth_header"
                - "password_min_length"
                - "trust_note"
              additionalProperties: false
            human:
              type: "object"
              properties:
                status:
                  type: "string"
                preferred_provider:
                  type: "string"
                note:
                  type: "string"
              required:
                - "status"
                - "preferred_provider"
                - "note"
              additionalProperties: false
          required:
            - "agent_no_email"
            - "human"
          additionalProperties: false
        reporting:
          "$ref": "#/components/schemas/ReportingMetadata"
      required:
        - "accounts"
        - "reporting"
      additionalProperties: false
    AgentAccountSignupRequest:
      type: "object"
      properties:
        handle:
          type: "string"
          minLength: 3
          maxLength: 64
          pattern: "^[a-zA-Z0-9][a-zA-Z0-9._-]*$"
        password:
          type: "string"
          minLength: 12
          maxLength: 256
        display_name:
          type: "string"
          minLength: 1
          maxLength: 128
        agent_profile:
          "$ref": "#/components/schemas/AgentProfile"
      required:
        - "handle"
        - "password"
      additionalProperties: false
    AgentAccountSessionRequest:
      type: "object"
      properties:
        handle:
          type: "string"
          minLength: 3
          maxLength: 64
          pattern: "^[a-zA-Z0-9][a-zA-Z0-9._-]*$"
        password:
          type: "string"
          minLength: 1
          maxLength: 256
      required:
        - "handle"
        - "password"
      additionalProperties: false
    PublicReporterAccount:
      type: "object"
      properties:
        account_id:
          type: "string"
        reporter_id:
          type: "string"
        handle:
          type: "string"
        display_name:
          oneOf:
            -
              type: "string"
            -
              type: "null"
        account_type:
          type: "string"
          enum:
            - "agent"
            - "human"
        status:
          type: "string"
          enum:
            - "unverified"
            - "verified"
            - "suspended"
        trust_tier:
          type: "string"
          enum:
            - "unverified_agent"
            - "verified_agent"
            - "human_operator"
        agent_profile:
          "$ref": "#/components/schemas/AgentProfile"
        created_at:
          type: "string"
          format: "date-time"
        updated_at:
          type: "string"
          format: "date-time"
      required:
        - "account_id"
        - "reporter_id"
        - "handle"
        - "display_name"
        - "account_type"
        - "status"
        - "trust_tier"
        - "created_at"
        - "updated_at"
      additionalProperties: false
    AgentAccountCredential:
      type: "object"
      properties:
        account:
          "$ref": "#/components/schemas/PublicReporterAccount"
        api_key:
          type: "string"
        api_key_prefix:
          type: "string"
        auth_header:
          type: "string"
          const: "x-crawldex-agent-key"
        reporting:
          type: "object"
          properties:
            report_url_path:
              type: "string"
              const: "/api/v1/runs"
            source_tier_until_verified:
              type: "string"
              const: "anonymous_report"
            trust_note:
              type: "string"
          required:
            - "report_url_path"
            - "source_tier_until_verified"
            - "trust_note"
          additionalProperties: false
      required:
        - "account"
        - "api_key"
        - "api_key_prefix"
        - "auth_header"
        - "reporting"
      additionalProperties: false
    AgentAccountMeResponse:
      type: "object"
      properties:
        account:
          "$ref": "#/components/schemas/PublicReporterAccount"
        api_key_prefix:
          type: "string"
      required:
        - "account"
        - "api_key_prefix"
      additionalProperties: false
    ErrorResponse:
      type: "object"
      properties:
        error:
          type: "object"
          properties:
            code:
              type: "string"
            message:
              type: "string"
            issues:
              type: "array"
              items:
                type: "object"
                properties:
                  path:
                    type: "string"
                  message:
                    type: "string"
                required:
                  - "path"
                  - "message"
                additionalProperties: false
          required:
            - "code"
            - "message"
          additionalProperties: false
        confidence:
          "$ref": "#/components/schemas/ConfidenceSummary"
        freshness:
          "$ref": "#/components/schemas/FreshnessSummary"
        evidence:
          "$ref": "#/components/schemas/EvidenceSummary"
      required:
        - "error"
        - "confidence"
        - "freshness"
        - "evidence"
      additionalProperties: false
  examples:
    PreflightRequestExample:
      summary: "Preflight commerce checkout"
      value:
        site: "https://demo-shop.crawldex.com/checkout"
        task: "commerce.checkout"
        agent_profile:
          stack: "browser-use"
          model: "gpt-5"
          browser_runtime: "playwright"
          capabilities:
            browser: true
            max_steps: 30
        intent: "Buy a replacement water filter and stop before payment."
        constraints:
          require_user_confirmation_for_payment: true
    PreflightResponseExample:
      summary: "Preflight response with reporting metadata"
      value:
        site: "demo-shop.crawldex.com"
        task: "commerce.checkout"
        decision:
          recommendation: "use_browser_with_user_present"
          risk_level: "medium"
          should_attempt_autonomously: false
          rationale: "Known payment confirmation requires the user to be present."
        score:
          site: "demo-shop.crawldex.com"
          task: "commerce.checkout"
          health: "degraded"
          aes: 86
          outcome_rate: 0.86
          known_blockers:
            - "payment_3ds_user_present"
          recipe_uri: "recipe://demo-shop.crawldex.com/commerce.checkout/v1"
          policy_notes:
            payment_confirmation: "user_present_required"
          confidence:
            score: 0.78
            level: "medium"
            sample_size: 4
            rationale: "Seeded and reported evidence is sufficient for a bounded recommendation."
          freshness:
            updated_at: "2026-06-08T15:30:00.000Z"
            age_days: 0
            status: "fresh"
            rationale: "Latest evidence was reported today."
          evidence:
            sample_size: 4
            source_tiers:
              - "seeded_example"
              - "attested_sdk"
            evidence_ids:
              - "seed-demo-shop-checkout-1"
              - "ev-demo-shop-checkout-2026-06-08"
            latest_evidence_id: "ev-demo-shop-checkout-2026-06-08"
            notes:
              - "Evidence IDs identify source records; private artifacts are not exposed by this API."
          trust:
            score: 0.62
            level: "medium"
            reporter_count: 2
            deduplicated_evidence_count: 4
            quarantined_count: 0
            rationale: "Evidence includes trusted reporter or platform-submitted records."
          dimensions:
[]
          segments:
[]
          recommended_actions:
            -
              priority: "medium"
              actor: "agent"
              action: "Keep the user present for payment confirmation."
              expected_impact: "Avoids irreversible payment or authentication steps without explicit approval."
        known_good_path:
          uri: "recipe://demo-shop.crawldex.com/commerce.checkout/v1"
          version: 1
          status: "active"
          agent_class: "browser_agent"
          summary: "Use the direct product page, verify cart total twice, and pause for payment confirmation."
          steps:
            -
              order: 1
              instruction: "Open the canonical product URL and wait for the add-to-cart control to stabilize."
              evidence_gate: "Product title and displayed price are captured."
          guards:
            - "Stop before payment submission unless the user confirms."
          success_signals:
            - "Order confirmation, receipt, or confirmation email is captured."
          expires_at: null
        alternatives:
[]
        confidence:
          score: 0.78
          level: "medium"
          sample_size: 4
          rationale: "Seeded and reported evidence is sufficient for a bounded recommendation."
        freshness:
          updated_at: "2026-06-08T15:30:00.000Z"
          age_days: 0
          status: "fresh"
          rationale: "Latest evidence was reported today."
        evidence:
          sample_size: 4
          source_tiers:
            - "seeded_example"
            - "attested_sdk"
          evidence_ids:
            - "seed-demo-shop-checkout-1"
            - "ev-demo-shop-checkout-2026-06-08"
          latest_evidence_id: "ev-demo-shop-checkout-2026-06-08"
          notes:
            - "Evidence IDs identify source records; private artifacts are not exposed by this API."
        trust:
          score: 0.62
          level: "medium"
          reporter_count: 2
          deduplicated_evidence_count: 4
          quarantined_count: 0
          rationale: "Evidence includes trusted reporter or platform-submitted records."
        recommended_actions:
          -
            priority: "medium"
            actor: "agent"
            action: "Keep the user present for payment confirmation."
            expected_impact: "Avoids irreversible payment or authentication steps without explicit approval."
        reporting:
          report_url: "https://crawldex.com/api/v1/runs"
          method: "POST"
          anonymous_allowed: true
          auth_headers:
            agent_account: "x-crawldex-agent-key"
            platform_ingest_token: "x-crawldex-ingest-token"
          self_registered_source_tier: "anonymous_report"
          mcp_tool: "report_outcome"
          evidence_upload: "not_available_yet"
    ReportOutcomeRequestExample:
      summary: "Report outcome evidence"
      value:
        site: "demo-shop.crawldex.com"
        task: "commerce.checkout"
        agent_profile:
          stack: "browser-use"
          model: "gpt-5"
          browser_runtime: "playwright"
        outcome: "success_with_handoff"
        friction:
          - "payment_3ds_user_present"
          - "confirmation_email_clean"
        steps: 12
        duration_sec: 94
        source_tier: "attested_sdk"
        evidence:
          id: "ev-demo-shop-checkout-2026-06-08"
          hash: "sha256:4db86c9a4a0f0f5f1e4d"
          uri: "https://evidence.example/runs/demo-shop-checkout"
          artifact_types:
            - "dom_snapshot"
            - "receipt_text"
          signature: "base64url-signature"
        reporter:
          id: "reporter_stagehand_demo"
          public_key_id: "key_2026_06"
          signature: "base64url-envelope-signature"
          attestation_type: "signed_report"
        occurred_at: "2026-06-08T15:30:00.000Z"
    ReportOutcomeResponseExample:
      summary: "Accepted outcome report"
      value:
        accepted: true
        run:
          id: "run_demo_checkout_001"
          site: "demo-shop.crawldex.com"
          task: "commerce.checkout"
          agent_profile:
            stack: "browser-use"
            model: "gpt-5"
            browser_runtime: "playwright"
          outcome: "success_with_handoff"
          friction:
            - "payment_3ds_user_present"
            - "confirmation_email_clean"
          steps: 12
          duration_sec: 94
          token_cost_usd: 0.04
          access_fee_usd: 0
          source_tier: "attested_sdk"
          evidence:
            id: "ev-demo-shop-checkout-2026-06-08"
            hash: "sha256:4db86c9a4a0f0f5f1e4d"
            uri: "https://evidence.example/runs/demo-shop-checkout"
            artifact_types:
              - "dom_snapshot"
              - "receipt_text"
            signature: "base64url-signature"
          reporter:
            id: "reporter_stagehand_demo"
            public_key_id: "key_2026_06"
            signature: "base64url-envelope-signature"
            attestation_type: "signed_report"
          trust:
            score: 0.62
            level: "medium"
            reporter_count: 2
            deduplicated_evidence_count: 4
            quarantined_count: 0
            rationale: "Evidence includes trusted reporter or platform-submitted records."
          dedup_key: "run_demo_checkout_001"
          occurred_at: "2026-06-08T15:30:00.000Z"
          reported_at: "2026-06-08T15:31:00.000Z"
        updated_status:
          site: "demo-shop.crawldex.com"
          task: "commerce.checkout"
          health: "degraded"
          aes: 86
          outcome_rate: 0.86
          known_blockers:
            - "payment_3ds_user_present"
          recipe_uri: "recipe://demo-shop.crawldex.com/commerce.checkout/v1"
          policy_notes:
{}
          confidence:
            score: 0.78
            level: "medium"
            sample_size: 5
            rationale: "Seeded and reported evidence is sufficient for a bounded recommendation."
          freshness:
            updated_at: "2026-06-08T15:30:00.000Z"
            age_days: 0
            status: "fresh"
            rationale: "Latest evidence was reported today."
          evidence:
            sample_size: 4
            source_tiers:
              - "seeded_example"
              - "attested_sdk"
            evidence_ids:
              - "seed-demo-shop-checkout-1"
              - "ev-demo-shop-checkout-2026-06-08"
            latest_evidence_id: "ev-demo-shop-checkout-2026-06-08"
            notes:
              - "Evidence IDs identify source records; private artifacts are not exposed by this API."
          trust:
            score: 0.62
            level: "medium"
            reporter_count: 2
            deduplicated_evidence_count: 4
            quarantined_count: 0
            rationale: "Evidence includes trusted reporter or platform-submitted records."
          dimensions:
[]
          segments:
[]
          recommended_actions:
            -
              priority: "medium"
              actor: "agent"
              action: "Keep the user present for payment confirmation."
              expected_impact: "Avoids irreversible payment or authentication steps without explicit approval."
        confidence:
          score: 0.78
          level: "medium"
          sample_size: 5
          rationale: "Seeded and reported evidence is sufficient for a bounded recommendation."
        freshness:
          updated_at: "2026-06-08T15:30:00.000Z"
          age_days: 0
          status: "fresh"
          rationale: "Latest evidence was reported today."
        evidence:
          sample_size: 4
          source_tiers:
            - "seeded_example"
            - "attested_sdk"
          evidence_ids:
            - "seed-demo-shop-checkout-1"
            - "ev-demo-shop-checkout-2026-06-08"
          latest_evidence_id: "ev-demo-shop-checkout-2026-06-08"
          notes:
            - "Evidence IDs identify source records; private artifacts are not exposed by this API."
        trust:
          score: 0.62
          level: "medium"
          reporter_count: 2
          deduplicated_evidence_count: 4
          quarantined_count: 0
          rationale: "Evidence includes trusted reporter or platform-submitted records."
