{
  "components": {
    "schemas": {
      "ActionKind": {
        "description": "The 12 atomic behavior types accepted by the engine.\n\nTwo namespaces. The four ``task.*`` types mark task boundaries; the eight\n``step.*`` types describe agent behavior within a task. The split names a\nreal asymmetry rather than a routing difference: a boundary marker carries\nno verb and neither ``input`` nor ``output``, while a behavioral step\ncarries the full {properties, input, output} triplet, which is what makes\nan absent ``output`` readable as an *intended* action.\n\nBoth are emitted on one path and evaluated at ``step_execution``.\n``TASK_BOUNDARY_KINDS`` names the four for callers that need to tell\nthem apart \u2014 prefer it over matching on the ``task.`` prefix.",
        "enum": [
          "task.start",
          "task.end",
          "task.error",
          "task.idle",
          "step.resource",
          "step.message",
          "step.self",
          "step.model",
          "step.credential",
          "step.exec",
          "step.gate",
          "step.unknown"
        ],
        "title": "ActionKind",
        "type": "string"
      },
      "Behavior": {
        "additionalProperties": false,
        "description": "A single agent step, used for both intended and completed steps.\n\nIntended steps (pre-execution) have ``output=None`` and ``seq=None``.\nCompleted steps (post-execution) have ``output`` populated and a ``seq``\nassigned when the step is recorded.\n\n``input``, ``output``, ``properties`` and ``meta`` accept only I-JSON\n(RFC 7493) values, recursively: ``dict`` with ``str`` keys, ``list``,\n``str``, ``bool``, ``None``, ``int`` with magnitude at most ``2**53 - 1``,\nand finite ``float``. Anything else -- ``NaN``, a larger integer, a tuple,\nset, bytes, datetime or ``Decimal`` -- is refused with a ``ValueError``\nnaming its path (``input.items[2]: float NaN is not I-JSON ...``), because\nit could not be exported, hashed or audited without being altered.\n\nIdentifiers are refused with a ``ValueError`` naming the field and the\nrule (``task_id 'run/42': use letters, digits and . _ : - only (1-100\ncharacters)``), because from 1.1 they are hashed, signed and used in lock\nand storage keys.\n\nFields\n------\nagent_id:\n    Registered agent identifier. Letters, digits and ``. _ : -``, 0-255\n    characters (empty for an offline, unregistered runner).\ntask_id:\n    Current task identifier. The engine uses this to key its internal\n    history tracker. Letters, digits and ``. _ : -``, 1-100 characters.\n    A ``task.start`` may carry ``meta[\"parent_task_id\"]``, which follows\n    the same rule.\naction_id:\n    Correlates a step outcome with its evaluation. Optional on intent and\n    may be absent on task boundary markers. Unique per (``agent_id``,\n    ``task_id``): the one legal reuse is pairing an intended step with its\n    own completion. A duplicate is refused with ``ValueError``. Letters,\n    digits and ``. _ : -``, 1-255 characters.\naag_version:\n    The AAG vocabulary version, on ``task.start`` only. Letters, digits\n    and ``. + -``, 1-64 characters.\ntimestamp:\n    When the agent initiated this step, recorded by the client. Defaults\n    to the UTC clock at construction, so build an intended step when the\n    intent is formed. It is also the time time-based rules (such as\n    ``working_hours_only``) evaluate against: a preflight is judged at the\n    time the intent was formed, not when the action later executes. ``KyvvuRunner.evaluate()`` refuses one further than\n    ``max_clock_skew_seconds`` from the host clock; ``PolicyEngine`` and\n    ``KyvvuRunner.record()`` do not, so recorded history replays as is.\nseq:\n    Orders a task's recorded steps: strictly increasing per\n    (``agent_id``, ``task_id``), assigned by the recording client.\n    Consumers must not assume it is contiguous, starts at a particular\n    value, or reflects wall-clock order; a value supplied by the caller\n    may be ignored. ``None`` for an intended step.\nkind:\n    The atomic behavior category. Set by the template.\nverb:\n    Direction/mutation intent. ``None`` for step types that carry no verb\n    (``step.exec``, ``step.gate``, ``step.unknown``, and the four\n    ``task.*`` boundary types).\nstep_name:\n    Human-readable label for this step (e.g. ``\"chat_gpt-4o\"``). Any\n    I-JSON text of 1-255 characters with no control characters\n    (U+0000-U+001F, U+007F-U+009F).\ninput:\n    Input data for this step. Visible to rule functions.\noutput:\n    Output data. Populated for completed steps; ``None`` for intended steps.\n    A completed ``step.gate`` carries ``decision`` (``pass`` or ``deny``).\nproperties:\n    Nested key-value object carrying contextual information. Standard\n    groups: ``target``, ``auth``, ``data``, ``model``, ``exec``,\n    ``idle``, ``self``, ``message``, ``transport``, ``raw``. A\n    ``step.gate`` carries bare ``kind`` (``human`` or ``guardrail``).\n    Custom groups are allowed and passed through unchanged.\nmeta:\n    Correlation and provenance fields outside the behavior itself.\n    **Keys starting with ``kyvvu.`` are reserved** for what the engine\n    and the Python client write (``kyvvu.eval``, ``kyvvu.manifests``); the runner\n    refuses a caller-supplied ``kyvvu.*`` meta key in ``evaluate()`` and\n    ``record()``.",
        "properties": {
          "aag_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Aag Version"
          },
          "action_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Action Id"
          },
          "agent_id": {
            "title": "Agent Id",
            "type": "string"
          },
          "input": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Input"
          },
          "kind": {
            "$ref": "#/components/schemas/ActionKind"
          },
          "meta": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Meta"
          },
          "output": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Output"
          },
          "properties": {
            "additionalProperties": true,
            "title": "Properties",
            "type": "object"
          },
          "seq": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Seq"
          },
          "step_name": {
            "title": "Step Name",
            "type": "string"
          },
          "task_id": {
            "title": "Task Id",
            "type": "string"
          },
          "timestamp": {
            "format": "date-time",
            "title": "Timestamp",
            "type": "string"
          },
          "verb": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Verb"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "agent_id",
          "task_id",
          "kind",
          "step_name"
        ],
        "title": "Behavior",
        "type": "object"
      },
      "EndTaskRequest": {
        "description": "``agent_id`` lets the runner check task ownership before eviction.\n\nBoth follow the identifier grammar of :class:`~kyvvu_engine.schemas.Behavior`\n(422 otherwise).",
        "properties": {
          "agent_id": {
            "title": "Agent Id",
            "type": "string"
          },
          "task_id": {
            "title": "Task Id",
            "type": "string"
          }
        },
        "required": [
          "task_id",
          "agent_id"
        ],
        "title": "EndTaskRequest",
        "type": "object"
      },
      "EndTaskResponse": {
        "properties": {
          "status": {
            "title": "Status",
            "type": "string"
          },
          "task_id": {
            "title": "Task Id",
            "type": "string"
          }
        },
        "required": [
          "status",
          "task_id"
        ],
        "title": "EndTaskResponse",
        "type": "object"
      },
      "EvaluateRequest": {
        "description": "Request body for ``POST /evaluate``.\n\n``intended`` is a wire-level :class:`~kyvvu_engine.schemas.Behavior`.\nIt forbids unknown fields, so a serialized ``Behavior`` round-trips as-is\nand requests containing any other key are rejected with 422.\n\n``intended.action_id`` is optional (the server generates one) and unique\nper (``agent_id``, ``task_id``): reuse it only for the ``/record`` of this\nsame step. ``meta`` keys starting with ``kyvvu.`` are reserved (422).",
        "properties": {
          "context": {
            "$ref": "#/components/schemas/ServeContext"
          },
          "intended": {
            "$ref": "#/components/schemas/Behavior"
          }
        },
        "required": [
          "intended",
          "context"
        ],
        "title": "EvaluateRequest",
        "type": "object"
      },
      "EvaluateResponse": {
        "description": "Response body for ``POST /evaluate`` and ``/register_agent``.\n\n``recorded_seq`` is set when the server recorded the evaluated step\nitself: a blocked ``step.*`` behaviour is recorded by ``/evaluate``\n(decision D1), and the caller must not ``/record`` it. Clients must\nignore fields they do not know.",
        "properties": {
          "action": {
            "title": "Action",
            "type": "string"
          },
          "action_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Action Id"
          },
          "blocked": {
            "default": false,
            "title": "Blocked",
            "type": "boolean"
          },
          "policies": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "title": "Policies",
            "type": "array"
          },
          "recorded_seq": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recorded Seq"
          },
          "risk_score": {
            "title": "Risk Score",
            "type": "number"
          }
        },
        "required": [
          "action",
          "risk_score",
          "policies"
        ],
        "title": "EvaluateResponse",
        "type": "object"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "title": "HTTPValidationError",
        "type": "object"
      },
      "ManifestRef": {
        "description": "Provenance record for a manifest that contributed policies.\n\nDescribes where a set of policies came from so a reviewer can determine\n\"this step was evaluated under manifest M (SHA Z), assigned at T by user U.\"\nPopulated by the API layer from an :class:`Assignment` row and forwarded to\nthe engine via :attr:`EvalContext.manifests`. All fields beyond the\nidentifiers are optional so non-manifest policy sets degrade gracefully.\n\nFields\n------\nmanifest_id:\n    The ``Assignment`` row id that materialised these policies.\nmanifest_name:\n    Human-readable manifest name from the YAML.\nrepo:\n    Source repository identifier (e.g. ``owner/name``), if known.\npath:\n    File path of the manifest within the repo.\nsha:\n    Git blob SHA pinned at assignment time.\nassigned_at:\n    ISO-8601 timestamp when the manifest was assigned.\nassigned_by:\n    Identifier of the user who created the assignment.",
        "properties": {
          "assigned_at": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assigned At"
          },
          "assigned_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assigned By"
          },
          "manifest_id": {
            "title": "Manifest Id",
            "type": "integer"
          },
          "manifest_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Manifest Name"
          },
          "path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Path"
          },
          "repo": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Repo"
          },
          "sha": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sha"
          }
        },
        "required": [
          "manifest_id"
        ],
        "title": "ManifestRef",
        "type": "object"
      },
      "PolicyLoadState": {
        "description": "Why the policy set currently in the engine looks the way it does.\n\nA policy *count* cannot distinguish situations that demand very different\nresponses: an agent with nothing assigned, an agent whose policy fetch\nfailed, and an agent whose entire policy set was rejected as unloadable all\nreport zero policies and all evaluate as ``allow``. This enum is the\nmissing distinction.\n\nValues\n------\nenforcing:\n    At least one policy is loaded and being enforced.\nnone_configured:\n    The load succeeded and the source genuinely has no policies. Nothing is\n    being enforced, and that is the source's answer, not a failure.\nunavailable:\n    Nothing is loaded. Either no load has been attempted yet, or the fetch\n    failed and no cached set was available to fall back on.\nstale_cache:\n    Policies *are* being enforced, but the set is not known to match its\n    source: the last fetch failed (whether the set in effect came from\n    memory or from a disk cache), or the disk cache that is the configured\n    source has outlived ``policy_cache_max_age_seconds``. Staleness is a\n    property of the **load**, not of which source the set came from \u2014 the\n    long-lived agent whose API went down keeps enforcing what it has, and\n    this is the state that says so.\n\nThere is no \"some policies were dropped\" state: a policy that cannot\nbe loaded raises :class:`~kyvvu_engine.errors.PolicyLoadError` out of the\nload, so a set is either loaded whole or refused whole.",
        "enum": [
          "enforcing",
          "none_configured",
          "unavailable",
          "stale_cache"
        ],
        "title": "PolicyLoadState",
        "type": "string"
      },
      "PolicyStatus": {
        "description": "Status of the runner's policy cache.\n\nReturned by :meth:`~kyvvu_engine.io.runner.KyvvuRunner.policy_status`.\n\nFields\n------\nloaded:\n    ``True`` if policies have been loaded at least once.\nlast_success:\n    Wall-clock time of last successful policy fetch.\nlast_attempt:\n    Wall-clock time of last fetch attempt (success or failure).\npolicy_count:\n    Number of active policies in the engine.\nstale:\n    ``True`` if the last fetch failed and the cache has exceeded TTL.\nsource:\n    Where the current policies came from: ``\"api\"``, ``\"local\"``,\n    ``\"disk_cache\"``, or ``\"none\"``.\nlast_fetch_at:\n    Alias for ``last_success`` (backward compatibility).\nlast_fetch_succeeded:\n    Whether the most recent fetch attempt succeeded.\ninstance_id:\n    The runner's instance identifier.\nttl_remaining_seconds:\n    Seconds until the in-memory cache expires and a re-fetch is triggered.\nload_state:\n    Which :class:`PolicyLoadState` the last load ended in. This is the\n    field that tells \"no policies assigned\" apart from \"fetch failed\" and\n    from \"the source answered with nothing\"; ``policy_count`` alone cannot.\npolicies_offered:\n    How many policies were handed to the loader. Read together with\n    ``policy_count``; they differ only transiently, because a\n    policy that cannot be loaded refuses the whole load.\nregistration_blocked_by:\n    Names of the ``agent_registration`` policies whose violation blocked\n    the agent's registration when it was last evaluated, at\n    ``register_agent()`` or again after a refresh changed the\n    registration policies. Empty when it is not blocked.\nregistration_blocked:\n    Whether the registration is blocked. While it is, every ``step.*``\n    evaluation is refused with ``KyvvuBlockedError`` naming those\n    policies; task boundaries are not. Cleared by a later evaluation of\n    the registration that does not block.\ngoverned:\n    Whether at least one validated policy is in effect.\nstale_cause:\n    Why the set in effect is not known to match its source, while it is\n    not; ``None`` when it does. ``client_upgrade_required`` is the\n    one that means ``pip install -U``.\nclient_upgrade:\n    What the platform said when it last refused this client as too old,\n    or ``None``. Cleared by the next accepted fetch.\nagent_id:\n    The agent this runner governs: the platform ``agent_id`` the\n    policy set was served for, when the platform is the source and has\n    said; otherwise the ``agent_id`` the runner bound to on its first\n    evaluation or record; ``None`` before either. With the platform as the\n    source this is the ``agent_id`` a caller must send, and any other is\n    refused with :class:`~kyvvu_engine.errors.AgentBindingError`.\napplicable_policy_count:\n    How many of the loaded policies apply to ``agent_id``: the\n    workspace-wide ones plus those naming that agent, counted the way\n    ``policy_count`` is. ``None`` while ``agent_id`` is. Equal to\n    ``policy_count`` for the agent a set was fetched for; lower means some\n    loaded policies never apply to this agent.",
        "properties": {
          "agent_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Id"
          },
          "applicable_policy_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Applicable Policy Count"
          },
          "client_upgrade": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Upgrade"
          },
          "governed": {
            "description": "Whether the current load state has policies in effect.",
            "readOnly": true,
            "title": "Governed",
            "type": "boolean"
          },
          "instance_id": {
            "default": "",
            "title": "Instance Id",
            "type": "string"
          },
          "last_attempt": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Attempt"
          },
          "last_fetch_at": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Fetch At"
          },
          "last_fetch_succeeded": {
            "default": false,
            "title": "Last Fetch Succeeded",
            "type": "boolean"
          },
          "last_success": {
            "anyOf": [
              {
                "format": "date-time",
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Success"
          },
          "load_state": {
            "$ref": "#/components/schemas/PolicyLoadState",
            "default": "unavailable"
          },
          "loaded": {
            "default": false,
            "title": "Loaded",
            "type": "boolean"
          },
          "policies_offered": {
            "default": 0,
            "title": "Policies Offered",
            "type": "integer"
          },
          "policy_count": {
            "default": 0,
            "title": "Policy Count",
            "type": "integer"
          },
          "registration_blocked": {
            "description": "Whether the agent's registration is blocked by a policy.",
            "readOnly": true,
            "title": "Registration Blocked",
            "type": "boolean"
          },
          "registration_blocked_by": {
            "items": {
              "type": "string"
            },
            "title": "Registration Blocked By",
            "type": "array"
          },
          "source": {
            "default": "none",
            "title": "Source",
            "type": "string"
          },
          "stale": {
            "default": false,
            "title": "Stale",
            "type": "boolean"
          },
          "stale_cause": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StaleCause"
              },
              {
                "type": "null"
              }
            ]
          },
          "ttl_remaining_seconds": {
            "default": 0.0,
            "title": "Ttl Remaining Seconds",
            "type": "number"
          }
        },
        "required": [
          "registration_blocked",
          "governed"
        ],
        "title": "PolicyStatus",
        "type": "object"
      },
      "RecordRequest": {
        "description": "Request body for ``POST /record``.\n\n``step`` names the Behavior object, not its ordinal. The same strict-input\nrules as :class:`EvaluateRequest` apply to its fields. ``step.action_id``\nis unique per (``agent_id``, ``task_id``): it is the ``action_id`` the\n``/evaluate`` of this step returned, or one not used before in the task.",
        "properties": {
          "context": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ServeContext"
              },
              {
                "type": "null"
              }
            ]
          },
          "step": {
            "$ref": "#/components/schemas/Behavior"
          }
        },
        "required": [
          "step"
        ],
        "title": "RecordRequest",
        "type": "object"
      },
      "RecordResponse": {
        "properties": {
          "seq": {
            "title": "Seq",
            "type": "integer"
          },
          "task_id": {
            "title": "Task Id",
            "type": "string"
          }
        },
        "required": [
          "seq",
          "task_id"
        ],
        "title": "RecordResponse",
        "type": "object"
      },
      "RegisterAgentRequest": {
        "properties": {
          "agent_data": {
            "additionalProperties": true,
            "title": "Agent Data",
            "type": "object"
          },
          "context": {
            "$ref": "#/components/schemas/ServeContext"
          }
        },
        "required": [
          "agent_data",
          "context"
        ],
        "title": "RegisterAgentRequest",
        "type": "object"
      },
      "ServeContext": {
        "additionalProperties": false,
        "description": "The ``context`` object of ``/evaluate`` and ``/register_agent``.\n\nStricter than :class:`~kyvvu_engine.schemas.EvalContext`, which in-process\ncallers build from typed code: over HTTP an unknown key is a 422 naming it\n(a misspelt ``agent_allowed_tool`` used to be dropped, so the tool\nallowlist saw nothing and the rule failed open), and ``environment`` and\n``risk_classification`` must be one of the platform's enum values.",
        "properties": {
          "agent_allowed_tools": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Allowed Tools"
          },
          "agent_id": {
            "title": "Agent Id",
            "type": "string"
          },
          "agent_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Name"
          },
          "agent_owner": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Owner"
          },
          "agent_purpose": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Agent Purpose"
          },
          "environment": {
            "default": "development",
            "enum": [
              "development",
              "qa",
              "staging",
              "production"
            ],
            "title": "Environment",
            "type": "string"
          },
          "manifests": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/ManifestRef"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Manifests"
          },
          "project_root": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Root"
          },
          "risk_classification": {
            "anyOf": [
              {
                "enum": [
                  "high",
                  "limited",
                  "minimal",
                  "unacceptable",
                  "unclassified"
                ],
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Risk Classification"
          },
          "task_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Task Id"
          },
          "user_id": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id"
          }
        },
        "required": [
          "agent_id"
        ],
        "title": "ServeContext",
        "type": "object"
      },
      "StaleCause": {
        "description": "Why the set in effect is not known to match its source.\n\n:class:`PolicyLoadState` says *that* a set is stale; this says why, because\nthe remedies differ: a network problem, a policy definition this engine\nrefuses, and an engine the platform no longer serves are three different\nfixes, and only the last is ``pip install -U``.\n\nValues\n------\nfetch_failed:\n    The last fetch did not complete (network, timeout, an HTTP error).\nset_refused:\n    The source answered with a set this engine refuses to load\n    (:class:`~kyvvu_engine.errors.PolicyLoadError`).\nclient_upgrade_required:\n    The platform refused this client as too old to serve\n    (:class:`~kyvvu_engine.errors.KyvvuClientUpgradeRequired`). The set in\n    effect is the last one fetched before that.\ncache_expired:\n    The configured disk cache has outlived\n    ``policy_cache_max_age_seconds``.\nlocal_source_unreadable:\n    The configured manifest could not be read.\ncaller_marked:\n    A caller of :meth:`~kyvvu_engine.io.runner.KyvvuRunner.load_policies`\n    passed ``stale=True``.",
        "enum": [
          "fetch_failed",
          "set_refused",
          "client_upgrade_required",
          "cache_expired",
          "local_source_unreadable",
          "caller_marked"
        ],
        "title": "StaleCause",
        "type": "string"
      },
      "ValidationError": {
        "properties": {
          "ctx": {
            "title": "Context",
            "type": "object"
          },
          "input": {
            "title": "Input"
          },
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Location",
            "type": "array"
          },
          "msg": {
            "title": "Message",
            "type": "string"
          },
          "type": {
            "title": "Error Type",
            "type": "string"
          }
        },
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError",
        "type": "object"
      },
      "Verb": {
        "description": "HTTP-style verb describing the direction and mutation intent of a step.",
        "enum": [
          "GET",
          "POST",
          "PATCH",
          "DELETE"
        ],
        "title": "Verb",
        "type": "string"
      }
    }
  },
  "info": {
    "description": "Local policy evaluation server for kyvvu-engine",
    "title": "kyvvu-serve",
    "version": "1.0.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/end_task": {
      "post": {
        "description": "Close a task; a foreign agent ID or an unopened task gets 409.",
        "operationId": "end_task_end_task_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndTaskRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndTaskResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "End Task"
      }
    },
    "/evaluate": {
      "post": {
        "description": "Preflight evaluation for this sidecar's agent; another agent gets 409.",
        "operationId": "evaluate_evaluate_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EvaluateRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvaluateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Evaluate"
      }
    },
    "/health": {
      "get": {
        "description": "Liveness probe \u2014 returns the runner's policy cache status.",
        "operationId": "health_health_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyStatus"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Health"
      }
    },
    "/record": {
      "post": {
        "description": "Record a completed step for this sidecar's agent; another gets 409.",
        "operationId": "record_record_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecordRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecordResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Record"
      }
    },
    "/register_agent": {
      "post": {
        "description": "Evaluate agent-registration policies; an agent this server does not govern gets 409.",
        "operationId": "register_agent_register_agent_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterAgentRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EvaluateResponse"
                }
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Register Agent"
      }
    }
  },
  "servers": [
    {
      "url": "http://127.0.0.1:8080"
    }
  ],
  "tags": []
}
