{"owner":"microsoft","repo":"agent-governance-toolkit","hasSpec":true,"specFile":"docs/studio/openapi.yaml","branch":"HEAD","format":"yaml","version":"3.x (YAML)","title":"agent-governance-toolkit","description":"","endpoints":[],"spec":"# Copyright (c) Microsoft Corporation. Licensed under the MIT License.\n#\n# AGT Studio Engine API - OpenAPI 3.1 specification\n#\n# This is the machine-readable companion to docs/studio/engine-api-contract.md.\n# Every operation declares x-capability-flags with runtime_mutating,\n# user_intent_required, and read_only_surface.\n#\n# Validate: npx @redocly/cli lint docs/studio/openapi.yaml\n\nopenapi: \"3.1.0\"\n\ninfo:\n  title: \"AGT Studio Engine API\"\n  version: \"1.0.0\"\n  description: |\n    Engine API for AGT Studio (AGT v1).\n\n    This document is the machine-readable companion to\n    `docs/studio/engine-api-contract.md`. All requests and responses\n    conform to the schemas defined here.\n\n    **Capability flags** (`x-capability-flags`) appear on every operation:\n    - `runtime_mutating`: the operation persists state changes to disk\n    - `user_intent_required`: MUST only be invoked from an explicit user gesture\n    - `read_only_surface`: safe to expose on a read-only Studio surface\n\n    Exactly one operation has `runtime_mutating: true`: `POST /policy/save`.\n\n    **Authentication:** Loopback connections (127.0.0.1 / ::1) require no\n    token. Non-loopback connections must supply a Bearer token read from\n    `~/.config/agt/studio-token`. `GET /health` and `GET /versions` are\n    exempt from authentication on all connections.\n\n    **Reserved route:** `GET /events` is reserved for a WebSocket channel\n    defined in Epic 7a. A v1 engine MUST return `426 Upgrade Required` for\n    non-WebSocket requests to that path.\n  license:\n    name: MIT\n    url: https://opensource.org/licenses/MIT\n  contact:\n    name: Agent Governance Toolkit\n    email: agentgovtoolkit@microsoft.com\n\nservers:\n  - url: \"http://127.0.0.1:{port}/api/v1\"\n    description: \"Local loopback (no authentication required)\"\n    variables:\n      port:\n        default: \"8080\"\n        description: \"Engine listen port (set via AGT_PORT)\"\n\nsecurity:\n  - BearerToken: []\n\ntags:\n  - name: health\n    description: Liveness and version probes\n  - name: policy\n    description: Policy listing, validation, testing, and saving\n  - name: audit\n    description: Audit log retrieval\n  - name: trust\n    description: Trust scores and trust graph\n  - name: agents\n    description: Registered agent listing\n  - name: decisions\n    description: Policy decision history (HTTP poll; WS in Epic 7a)\n  - name: meta\n    description: Engine metadata and version negotiation\n\n# Reserved routes are not callable HTTP operations in v1, so they are declared\n# here (with capability flags) instead of under `paths`, where every operation\n# would be required to define success responses. The WebSocket message schema is\n# defined in Epic 7a (issue #16).\nx-reserved-routes:\n  - route: /api/v1/events\n    method: WS\n    summary: Real-time event stream (policy decisions, agent events, trust updates)\n    reserved_for: Epic 7a (issue #16)\n    http_behavior: >-\n      A v1 engine MUST return 426 Upgrade Required for plain HTTP requests to\n      this path and MUST NOT implement it as a regular HTTP endpoint.\n    x-capability-flags:\n      runtime_mutating: false\n      user_intent_required: false\n      read_only_surface: true\n\npaths:\n  /health:\n    get:\n      operationId: getHealth\n      summary: Engine health probe\n      description: |\n        Returns engine health status and version. No authentication required\n        on any connection type. Used by Studio on startup and for periodic\n        health checks.\n      tags:\n        - health\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      security: []\n      responses:\n        \"200\":\n          description: Engine is healthy or degraded but responsive\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/HealthResponse\"\n              example:\n                status: ok\n                version: \"0.3.0\"\n                uptime_seconds: 3661.4\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /policies:\n    get:\n      operationId: listPolicies\n      summary: List all loaded policies\n      description: |\n        Returns a paginated list of all policies currently loaded in the\n        engine. This endpoint fixes the counts-only gap in the existing\n        `policy_server.py` implementation, which returns only totals rather\n        than full policy objects.\n      tags:\n        - policy\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      parameters:\n        - $ref: \"#/components/parameters/PageParam\"\n        - $ref: \"#/components/parameters/LimitParam\"\n      responses:\n        \"200\":\n          description: Paginated policy list\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/PolicyListResponse\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /policies/{id}:\n    get:\n      operationId: getPolicy\n      summary: Get a single policy by ID\n      description: Returns full detail for one policy, including raw content and rule count.\n      tags:\n        - policy\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      parameters:\n        - name: id\n          in: path\n          required: true\n          schema:\n            type: string\n          description: Policy identifier (derived from filename)\n          example: \"pg-staging-reads\"\n      responses:\n        \"200\":\n          description: Policy detail\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/PolicyDetail\"\n        \"404\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /policy/validate:\n    post:\n      operationId: validatePolicy\n      summary: Validate policy syntax (lint only, no side effects)\n      description: |\n        Parses and lints a policy document. This operation is read-only:\n        no state persists after the response. Uses POST because request bodies\n        can be large.\n      tags:\n        - policy\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/ValidatePolicyRequest\"\n            example:\n              content: \"name: example\\nrules:\\n  - id: r1\\n    action: allow\\n\"\n              format: yaml\n      responses:\n        \"200\":\n          description: Validation result (valid or list of errors)\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/ValidatePolicyResponse\"\n              examples:\n                valid:\n                  summary: Policy is valid\n                  value:\n                    valid: true\n                    errors: []\n                invalid:\n                  summary: Policy has errors\n                  value:\n                    valid: false\n                    errors:\n                      - line: 3\n                        col: 5\n                        message: \"Policy rule 'r1' references an undefined action type.\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /policy/test:\n    post:\n      operationId: testPolicy\n      summary: Run regression fixtures against policies\n      description: |\n        Executes a set of test fixtures against the loaded policies using the\n        `policy_test.replay` engine. No state persists after the response.\n        Uses POST because fixture bodies can be large.\n      tags:\n        - policy\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/TestPolicyRequest\"\n            example:\n              fixtures:\n                - id: \"allow-read-staging\"\n                  input:\n                    action: \"sql_select\"\n                    resource: \"staging.users\"\n                  expected_verdict: \"allow\"\n                  expected_rule: \"pg-staging-reads\"\n      responses:\n        \"200\":\n          description: Replay report with per-fixture results\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/TestPolicyResponse\"\n              example:\n                total: 1\n                passed: 1\n                failed: 0\n                results:\n                  - fixture_id: \"allow-read-staging\"\n                    passed: true\n                    expected_verdict: \"allow\"\n                    actual_verdict: \"allow\"\n                    expected_rule: \"pg-staging-reads\"\n                    actual_rule: \"pg-staging-reads\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /policy/save:\n    post:\n      operationId: savePolicy\n      summary: Persist a policy to disk (the sole write endpoint)\n      description: |\n        Writes a policy to the engine's policy directory. This is the ONLY\n        endpoint with `runtime_mutating: true` in the Studio surface.\n\n        `user_intent_required: true` means the Studio client MUST only call\n        this endpoint from a direct user gesture (clicking \"Save\" or \"Publish\").\n        It MUST NOT be called speculatively, from a timer, or as a background\n        side effect.\n\n        Requires authentication on non-loopback connections. The studio-token\n        must carry write scope; read-only tokens are rejected with 403.\n      tags:\n        - policy\n      x-capability-flags:\n        runtime_mutating: true\n        user_intent_required: true\n        read_only_surface: false\n      requestBody:\n        required: true\n        content:\n          application/json:\n            schema:\n              $ref: \"#/components/schemas/SavePolicyRequest\"\n            example:\n              id: \"my-new-policy\"\n              content: \"name: my-new-policy\\nrules:\\n  - id: r1\\n    action: allow\\n\"\n              format: yaml\n              commit_message: \"Add allow rule for staging reads\"\n      responses:\n        \"200\":\n          description: Policy saved successfully\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/SavePolicyResponse\"\n              example:\n                id: \"my-new-policy\"\n                saved_at: \"2026-06-13T10:35:00Z\"\n                version: \"a1b2c3d4\"\n        \"401\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"403\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /audit/log:\n    get:\n      operationId: getAuditLog\n      summary: Retrieve paginated audit log entries\n      description: |\n        Returns audit log entries from the engine's in-memory and persistent\n        audit store. Supports filtering by agent DID and time range.\n        Entries include the Merkle chain hash from ADR 0017.\n      tags:\n        - audit\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      parameters:\n        - $ref: \"#/components/parameters/PageParam\"\n        - $ref: \"#/components/parameters/LimitParam\"\n        - name: agent_did\n          in: query\n          required: false\n          schema:\n            type: string\n          description: Filter entries to a specific agent DID\n          example: \"did:mesh:abc123\"\n        - name: from\n          in: query\n          required: false\n          schema:\n            type: string\n            format: date-time\n          description: Earliest entry timestamp to include (ISO 8601, inclusive)\n          example: \"2026-06-01T00:00:00Z\"\n        - name: to\n          in: query\n          required: false\n          schema:\n            type: string\n            format: date-time\n          description: Latest entry timestamp to include (ISO 8601, inclusive)\n          example: \"2026-06-13T23:59:59Z\"\n      responses:\n        \"200\":\n          description: Paginated audit log entries\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/AuditLogListResponse\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /trust/scores:\n    get:\n      operationId: getTrustScores\n      summary: List agent trust scores\n      description: |\n        Returns trust scores for all known agents, or for a single agent\n        when `agent_did` is specified.\n      tags:\n        - trust\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      parameters:\n        - $ref: \"#/components/parameters/PageParam\"\n        - $ref: \"#/components/parameters/LimitParam\"\n        - name: agent_did\n          in: query\n          required: false\n          schema:\n            type: string\n          description: Filter to a single agent DID\n          example: \"did:mesh:abc123\"\n      responses:\n        \"200\":\n          description: Paginated trust score list\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/TrustScoreListResponse\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /trust/graph:\n    get:\n      operationId: getTrustGraph\n      summary: Get the full trust graph\n      description: |\n        Returns all agents as nodes and all trust, delegation, and sponsor\n        relationships as directed edges. Used by the Studio graph\n        visualization panel.\n      tags:\n        - trust\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      responses:\n        \"200\":\n          description: Trust graph with nodes and edges\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/TrustGraph\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /agents:\n    get:\n      operationId: listAgents\n      summary: List registered agents\n      description: Returns a paginated list of all agents registered in the engine.\n      tags:\n        - agents\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      parameters:\n        - $ref: \"#/components/parameters/PageParam\"\n        - $ref: \"#/components/parameters/LimitParam\"\n      responses:\n        \"200\":\n          description: Paginated agent list\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/AgentListResponse\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /decisions:\n    get:\n      operationId: listDecisions\n      summary: Retrieve recent policy decisions (HTTP poll)\n      description: |\n        Returns a paginated list of recent policy decisions. In v1, Studio\n        polls this endpoint for updates. In Epic 7a, decisions will also\n        stream in real time over the WebSocket channel at `/api/v1/events`.\n      tags:\n        - decisions\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      parameters:\n        - $ref: \"#/components/parameters/PageParam\"\n        - $ref: \"#/components/parameters/LimitParam\"\n        - name: agent_did\n          in: query\n          required: false\n          schema:\n            type: string\n          description: Filter decisions by agent DID\n        - name: verdict\n          in: query\n          required: false\n          schema:\n            type: string\n            enum:\n              - allow\n              - deny\n              - warn\n              - require_approval\n          description: Filter decisions by verdict\n      responses:\n        \"200\":\n          description: Paginated decision list\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/DecisionListResponse\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\n  /versions:\n    get:\n      operationId: getVersions\n      summary: Engine and API contract version information\n      description: |\n        Returns the engine software version and the API contract version.\n        Studio checks `api` on startup and shows an upgrade message if it\n        does not equal `\"1.0.0\"`. No authentication required on any\n        connection type.\n      tags:\n        - meta\n      x-capability-flags:\n        runtime_mutating: false\n        user_intent_required: false\n        read_only_surface: true\n      security: []\n      responses:\n        \"200\":\n          description: Version information\n          content:\n            application/json:\n              schema:\n                $ref: \"#/components/schemas/VersionInfo\"\n              example:\n                engine: \"0.3.0\"\n                api: \"1.0.0\"\n                python: \"3.12.3\"\n                capabilities:\n                  - \"capability-flags-v1\"\n                  - \"pagination-v1\"\n        \"4XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n        \"5XX\":\n          $ref: \"#/components/responses/ErrorResponse\"\n\ncomponents:\n  securitySchemes:\n    BearerToken:\n      type: http\n      scheme: bearer\n      description: |\n        Bearer token read from `~/.config/agt/studio-token`.\n\n        Required for non-loopback connections (all addresses other than\n        127.0.0.1 and ::1). Loopback connections do not require a token.\n\n        `GET /health` and `GET /versions` are exempt from authentication\n        on all connection types.\n\n        Full token format and rotation policy: see the threat model in\n        issue #6 (microsoft/agent-governance-toolkit#6).\n\n  parameters:\n    PageParam:\n      name: page\n      in: query\n      required: false\n      schema:\n        type: integer\n        minimum: 1\n        default: 1\n      description: \"1-based page number (default: 1)\"\n\n    LimitParam:\n      name: limit\n      in: query\n      required: false\n      schema:\n        type: integer\n        minimum: 1\n        maximum: 100\n        default: 20\n      description: \"Items per page, 1-100 (default: 20)\"\n\n  responses:\n    ErrorResponse:\n      description: Error response using the standard error envelope\n      content:\n        application/json:\n          schema:\n            $ref: \"#/components/schemas/Error\"\n          example:\n            status: 404\n            code: POLICY_NOT_FOUND\n            message: \"Policy with id 'my-policy' not found\"\n            details: {}\n\n  schemas:\n\n    # ── Error envelope ──────────────────────────────────────────────────\n\n    Error:\n      type: object\n      required:\n        - status\n        - code\n        - message\n      properties:\n        status:\n          type: integer\n          description: HTTP status code mirrored in the response body\n          minimum: 400\n          maximum: 599\n          example: 404\n        code:\n          type: string\n          description: Machine-readable error code in SCREAMING_SNAKE_CASE\n          pattern: \"^[A-Z][A-Z0-9_]*$\"\n          example: POLICY_NOT_FOUND\n        message:\n          type: string\n          description: Human-readable description safe to display in the UI\n          example: \"Policy with id 'my-policy' not found\"\n        details:\n          type: object\n          description: Optional endpoint-specific diagnostic information\n          additionalProperties: true\n\n    # ── Pagination ──────────────────────────────────────────────────────\n\n    PaginationMeta:\n      type: object\n      required:\n        - page\n        - limit\n        - total\n        - has_next\n      properties:\n        page:\n          type: integer\n          minimum: 1\n          description: Current page number (1-based)\n          example: 1\n        limit:\n          type: integer\n          minimum: 1\n          maximum: 100\n          description: Items per page\n          example: 20\n        total:\n          type: integer\n          minimum: 0\n          description: Total number of items across all pages\n          example: 87\n        has_next:\n          type: boolean\n          description: Whether more pages exist after this one\n          example: true\n\n    # ── Health ──────────────────────────────────────────────────────────\n\n    HealthResponse:\n      type: object\n      required:\n        - status\n        - version\n      properties:\n        status:\n          type: string\n          enum:\n            - ok\n            - degraded\n          description: Engine health status\n        version:\n          type: string\n          description: Engine software version\n          example: \"0.3.0\"\n        uptime_seconds:\n          type: number\n          format: double\n          description: Seconds since engine process start\n          example: 3661.4\n\n    # ── Policy ──────────────────────────────────────────────────────────\n\n    PolicySummary:\n      type: object\n      required:\n        - id\n        - name\n        - format\n        - source\n      properties:\n        id:\n          type: string\n          description: Unique identifier derived from the policy filename\n          example: \"pg-staging-reads\"\n        name:\n          type: string\n          description: Human-readable policy name\n          example: \"PostgreSQL Staging Read Access\"\n        format:\n          type: string\n          enum:\n            - yaml\n            - json\n          description: File format of the policy\n        source:\n          type: string\n          description: File path relative to the policy directory\n          example: \"pg-staging-reads.yaml\"\n        description:\n          type: string\n          description: Policy description if present in the file header\n          example: \"Allows SELECT on staging schema tables\"\n\n    PolicyListResponse:\n      type: object\n      required:\n        - items\n        - pagination\n      properties:\n        items:\n          type: array\n          items:\n            $ref: \"#/components/schemas/PolicySummary\"\n        pagination:\n          $ref: \"#/components/schemas/PaginationMeta\"\n\n    PolicyDetail:\n      allOf:\n        - $ref: \"#/components/schemas/PolicySummary\"\n        - type: object\n          required:\n            - content\n            - rules_count\n          properties:\n            content:\n              type: string\n              description: Raw policy file content\n            rules_count:\n              type: integer\n              minimum: 0\n              description: Number of rules declared in the policy\n              example: 3\n            last_modified:\n              type: string\n              format: date-time\n              description: Last modification timestamp of the policy file on disk\n\n    ValidationError:\n      type: object\n      required:\n        - message\n      properties:\n        line:\n          type: integer\n          minimum: 1\n          description: Line number of the error (1-based)\n          example: 3\n        col:\n          type: integer\n          minimum: 1\n          description: Column number of the error (1-based)\n          example: 5\n        message:\n          type: string\n          description: Human-readable error description\n          example: \"Policy rule 'r1' references an undefined action type.\"\n\n    ValidatePolicyRequest:\n      type: object\n      required:\n        - content\n        - format\n      properties:\n        content:\n          type: string\n          description: Raw policy content to validate\n        format:\n          type: string\n          enum:\n            - yaml\n            - json\n          description: Format of the content\n\n    ValidatePolicyResponse:\n      type: object\n      required:\n        - valid\n        - errors\n      properties:\n        valid:\n          type: boolean\n          description: True if the policy passes all parse and lint checks\n        errors:\n          type: array\n          items:\n            $ref: \"#/components/schemas/ValidationError\"\n          description: List of parse or lint errors; empty when valid\n\n    FixtureInput:\n      type: object\n      required:\n        - id\n        - input\n        - expected_verdict\n      properties:\n        id:\n          type: string\n          description: Unique fixture identifier\n          example: \"allow-read-staging\"\n        input:\n          type: object\n          description: Evaluation context passed to the policy engine\n          additionalProperties: true\n          example:\n            action: \"sql_select\"\n            resource: \"staging.users\"\n        expected_verdict:\n          type: string\n          enum:\n            - allow\n            - deny\n            - warn\n            - require_approval\n          description: Expected policy verdict for this input\n        expected_rule:\n          type: string\n          description: Expected matched rule name (optional assertion)\n          example: \"pg-staging-reads\"\n\n    FixtureResult:\n      type: object\n      required:\n        - fixture_id\n        - passed\n        - expected_verdict\n        - actual_verdict\n      properties:\n        fixture_id:\n          type: string\n          example: \"allow-read-staging\"\n        passed:\n          type: boolean\n        expected_verdict:\n          type: string\n        actual_verdict:\n          type: string\n        expected_rule:\n          type:\n            - string\n            - \"null\"\n          description: Expected rule (null if not asserted)\n        actual_rule:\n          type:\n            - string\n            - \"null\"\n          description: Actual matched rule (null if no rule matched)\n        fixture_path:\n          type: string\n          description: Path to the fixture file (empty for inline fixtures)\n        resolution_metadata:\n          type:\n            - object\n            - \"null\"\n          additionalProperties: true\n          description: >-\n            Optional diagnostic metadata from the policy resolver, passed\n            through verbatim from policy_test.FixtureResult.resolution_metadata.\n\n    TestPolicyRequest:\n      type: object\n      required:\n        - fixtures\n      properties:\n        policy_dir:\n          type: string\n          description: Policy directory override (defaults to engine policy_dir)\n        fixtures:\n          type: array\n          items:\n            $ref: \"#/components/schemas/FixtureInput\"\n          description: Inline fixtures to execute against the loaded policies\n          minItems: 1\n\n    TestPolicyResponse:\n      type: object\n      required:\n        - total\n        - passed\n        - failed\n        - results\n      properties:\n        total:\n          type: integer\n          minimum: 0\n          description: Total number of fixtures run\n        passed:\n          type: integer\n          minimum: 0\n          description: Fixtures that matched their expected verdict\n        failed:\n          type: integer\n          minimum: 0\n          description: Fixtures that did not match their expected verdict\n        results:\n          type: array\n          items:\n            $ref: \"#/components/schemas/FixtureResult\"\n\n    SavePolicyRequest:\n      type: object\n      required:\n        - id\n        - content\n        - format\n      properties:\n        id:\n          type: string\n          description: |\n            Policy identifier used as the filename. Must match the pattern\n            `^[a-z0-9][a-z0-9_-]{0,63}$`.\n          pattern: \"^[a-z0-9][a-z0-9_-]{0,63}$\"\n          example: \"my-new-policy\"\n        content:\n          type: string\n          description: Full policy content to persist to disk\n        format:\n          type: string\n          enum:\n            - yaml\n            - json\n          description: File format to write\n        commit_message:\n          type: string\n          description: Human-readable description of this change, written to the audit log\n          maxLength: 512\n          example: \"Add allow rule for staging reads\"\n\n    SavePolicyResponse:\n      type: object\n      required:\n        - id\n        - saved_at\n      properties:\n        id:\n          type: string\n          description: Saved policy identifier\n          example: \"my-new-policy\"\n        saved_at:\n          type: string\n          format: date-time\n          description: ISO 8601 timestamp of when the policy was written to disk\n          example: \"2026-06-13T10:35:00Z\"\n        version:\n          type: string\n          description: Opaque version token for optimistic concurrency checks\n          example: \"a1b2c3d4\"\n\n    # ── Audit ───────────────────────────────────────────────────────────\n\n    AuditLogEntry:\n      type: object\n      required:\n        - entry_id\n        - timestamp\n        - agent_did\n        - action\n        - outcome\n      properties:\n        entry_id:\n          type: string\n          description: Unique entry identifier\n          example: \"aud-0001\"\n        timestamp:\n          type: string\n          format: date-time\n          description: When the audited event occurred\n          example: \"2026-06-13T10:30:00Z\"\n        agent_did:\n          type: string\n          description: DID of the agent that performed the action\n          example: \"did:mesh:abc123\"\n        action:\n          type: string\n          description: Action that was audited\n          example: \"sql_execute\"\n        outcome:\n          type: string\n          enum:\n            - success\n            - failure\n            - denied\n          description: Result of the action\n        resource:\n          type:\n            - string\n            - \"null\"\n          description: Target resource of the action\n          example: \"staging.users\"\n        target_did:\n          type:\n            - string\n            - \"null\"\n          description: DID of a target agent if applicable\n        policy_decision:\n          type:\n            - string\n            - \"null\"\n          description: Policy verdict that produced this audit entry\n          example: \"allow\"\n        entry_hash:\n          type: string\n          description: SHA-256 hash of this entry for Merkle chain integrity (ADR 0017)\n          example: \"e3b0c44298fc1c149afb\"\n\n    AuditLogListResponse:\n      type: object\n      required:\n        - items\n        - pagination\n      properties:\n        items:\n          type: array\n          items:\n            $ref: \"#/components/schemas/AuditLogEntry\"\n        pagination:\n          $ref: \"#/components/schemas/PaginationMeta\"\n\n    # ── Trust ───────────────────────────────────────────────────────────\n\n    TrustScoreItem:\n      type: object\n      required:\n        - agent_did\n        - trust_score\n        - trust_level\n      properties:\n        agent_did:\n          type: string\n          description: Agent DID\n          example: \"did:mesh:abc123\"\n        trust_score:\n          type: integer\n          minimum: 0\n          maximum: 1000\n          description: Numeric trust score (0-1000)\n          example: 750\n        trust_level:\n          type: string\n          enum:\n            - untrusted\n            - probationary\n            - standard\n            - trusted\n            - verified_partner\n          description: >-\n            Categorical trust level derived from the score. Mirrors\n            trust_level_for_score in agentmesh.trust.levels (the single source\n            of truth used by the trust engine and CLI).\n          example: \"trusted\"\n        last_updated:\n          type: string\n          format: date-time\n          description: Timestamp of the most recent score change\n\n    TrustScoreListResponse:\n      type: object\n      required:\n        - items\n        - pagination\n      properties:\n        items:\n          type: array\n          items:\n            $ref: \"#/components/schemas/TrustScoreItem\"\n        pagination:\n          $ref: \"#/components/schemas/PaginationMeta\"\n\n    TrustGraphNode:\n      type: object\n      required:\n        - agent_did\n        - trust_score\n      properties:\n        agent_did:\n          type: string\n          description: Agent DID\n          example: \"did:mesh:abc123\"\n        trust_score:\n          type: integer\n          minimum: 0\n          maximum: 1000\n          description: Current trust score for graph rendering\n          example: 750\n        name:\n          type: string\n          description: Human-readable agent name (if registered)\n          example: \"data-agent-prod\"\n\n    TrustGraphEdge:\n      type: object\n      required:\n        - from_did\n        - to_did\n        - relationship\n      properties:\n        from_did:\n          type: string\n          description: Source agent DID\n          example: \"did:mesh:abc123\"\n        to_did:\n          type: string\n          description: Target agent DID\n          example: \"did:mesh:def456\"\n        relationship:\n          type: string\n          enum:\n            - trusts\n            - delegates\n            - sponsors\n          description: Type of trust relationship from source to target\n          example: \"trusts\"\n        weight:\n          type: number\n          format: double\n          description: Optional edge weight for graph layout (0.0-1.0)\n          minimum: 0.0\n          maximum: 1.0\n\n    TrustGraph:\n      type: object\n      required:\n        - nodes\n        - edges\n      properties:\n        nodes:\n          type: array\n          items:\n            $ref: \"#/components/schemas/TrustGraphNode\"\n          description: All registered agents as graph nodes\n        edges:\n          type: array\n          items:\n            $ref: \"#/components/schemas/TrustGraphEdge\"\n          description: All trust, delegation, and sponsor relationships as directed edges\n\n    # ── Agents ──────────────────────────────────────────────────────────\n\n    AgentSummary:\n      type: object\n      required:\n        - did\n        - trust_score\n      properties:\n        did:\n          type: string\n          description: Agent DID (did:mesh:...)\n          example: \"did:mesh:abc123\"\n        name:\n          type: string\n          description: Human-readable agent name\n          example: \"data-agent-prod\"\n        trust_score:\n          type: integer\n          minimum: 0\n          maximum: 1000\n          description: Current numeric trust score\n          example: 750\n        trust_level:\n          type: string\n          enum:\n            - untrusted\n            - probationary\n            - standard\n            - trusted\n            - verified_partner\n          description: >-\n            Categorical trust level. Mirrors trust_level_for_score in\n            agentmesh.trust.levels.\n          example: \"trusted\"\n        last_active:\n          type:\n            - string\n            - \"null\"\n          format: date-time\n          description: Timestamp of the most recent event from this agent\n        capabilities:\n          type: array\n          items:\n            type: string\n          description: List of granted capability strings\n          example:\n            - \"read:data\"\n            - \"write:audit\"\n\n    AgentListResponse:\n      type: object\n      required:\n        - items\n        - pagination\n      properties:\n        items:\n          type: array\n          items:\n            $ref: \"#/components/schemas/AgentSummary\"\n        pagination:\n          $ref: \"#/components/schemas/PaginationMeta\"\n\n    # ── Decisions ───────────────────────────────────────────────────────\n\n    Decision:\n      type: object\n      required:\n        - decision_id\n        - timestamp\n        - agent_did\n        - action\n        - verdict\n        - reason\n      properties:\n        decision_id:\n          type: string\n          description: Unique decision identifier\n          example: \"dec-001\"\n        timestamp:\n          type: string\n          format: date-time\n          description: When the policy decision was made\n          example: \"2026-06-13T10:30:00Z\"\n        agent_did:\n          type: string\n          description: DID of the agent whose action was evaluated\n          example: \"did:mesh:abc123\"\n        action:\n          type: string\n          description: Action that was evaluated\n          example: \"sql_execute\"\n        resource:\n          type:\n            - string\n            - \"null\"\n          description: Target resource of the evaluated action\n          example: \"production.orders\"\n        verdict:\n          type: string\n          enum:\n            - allow\n            - deny\n            - warn\n            - require_approval\n          description: Policy verdict\n          example: \"deny\"\n        matched_rule:\n          type:\n            - string\n            - \"null\"\n          description: Name of the rule that produced the verdict\n          example: \"deny-prod-writes\"\n        policy_name:\n          type:\n            - string\n            - \"null\"\n          description: Name of the policy that matched\n          example: \"production-guardrails\"\n        reason:\n          type: string\n          description: Human-readable reason for the verdict\n          example: \"Rule 'deny-prod-writes' matched: direct writes to production are blocked\"\n\n    DecisionListResponse:\n      type: object\n      required:\n        - items\n        - pagination\n      properties:\n        items:\n          type: array\n          items:\n            $ref: \"#/components/schemas/Decision\"\n        pagination:\n          $ref: \"#/components/schemas/PaginationMeta\"\n\n    # ── Version ─────────────────────────────────────────────────────────\n\n    VersionInfo:\n      type: object\n      required:\n        - engine\n        - api\n      properties:\n        engine:\n          type: string\n          description: Engine software version (semver)\n          example: \"0.3.0\"\n        api:\n          type: string\n          description: |\n            API contract version. Must equal \"1.0.0\" for this spec.\n            Studio shows an upgrade message if this does not match.\n          example: \"1.0.0\"\n        python:\n          type: string\n          description: Python runtime version (informational)\n          example: \"3.12.3\"\n        capabilities:\n          type: array\n          items:\n            type: string\n          description: |\n            Optional list of capability identifiers the engine supports.\n            Well-known values: \"capability-flags-v1\", \"pagination-v1\".\n          example:\n            - \"capability-flags-v1\"\n            - \"pagination-v1\"\n"}