{
  "openapi": "3.0.3",
  "info": {
    "title": "Gépvers Workshift",
    "version": "1.0.0",
    "description": "Fictional work samples. Read case.actions for field schemas. No real-world side effects. Private runs expire after 30 days."
  },
  "servers": [
    {
      "url": "https://gepvers.hu/api/v1"
    }
  ],
  "paths": {
    "/health": {
      "get": {
        "operationId": "health",
        "responses": {
          "200": {
            "description": "Service status and evaluator version"
          }
        }
      }
    },
    "/scenarios": {
      "get": {
        "operationId": "listScenarios",
        "responses": {
          "200": {
            "description": "Available work sample metadata"
          }
        }
      }
    },
    "/runs": {
      "post": {
        "operationId": "createRun",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRun"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Session"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision or sealed run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; wait 60 seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/runs/{run_id}": {
      "get": {
        "operationId": "getRun",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "RunToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Run"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision or sealed run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; wait 60 seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/runs/{run_id}/documents/{document_id}": {
      "get": {
        "operationId": "readDocument",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "RunToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Document body and provenance; first read is logged"
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision or sealed run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; wait 60 seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/runs/{run_id}/actions": {
      "post": {
        "operationId": "performAction",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "RunToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated run, rejected:true envelope containing current run, or report_id for publication."
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision or sealed run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; wait 60 seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/runs/{run_id}/finish": {
      "post": {
        "operationId": "finishRun",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "RunToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Revision"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated run, rejected:true envelope containing current run, or report_id for publication."
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision or sealed run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; wait 60 seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/runs/{run_id}/publish": {
      "post": {
        "operationId": "publishRun",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "RunToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated run, rejected:true envelope containing current run, or report_id for publication."
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Stale revision or sealed run",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; wait 60 seconds",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/reports/{report_id}": {
      "get": {
        "operationId": "getPublishedReport",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Published report, no run credentials"
          },
          "404": {
            "description": "Not found or expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "RunToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token scoped to one run, returned once at creation."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          }
        }
      },
      "CreateRun": {
        "type": "object",
        "required": [
          "scenario"
        ],
        "properties": {
          "scenario": {
            "type": "string",
            "enum": [
              "support",
              "invoices",
              "calendar"
            ]
          },
          "seed": {
            "type": "integer",
            "minimum": 1,
            "maximum": 999999,
            "default": 42
          },
          "actor": {
            "type": "string",
            "enum": [
              "human",
              "agent"
            ],
            "default": "human"
          },
          "label": {
            "type": "string",
            "maxLength": 60
          }
        }
      },
      "Session": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "token": {
            "type": "string"
          },
          "revision": {
            "type": "integer"
          },
          "expires_in_days": {
            "type": "integer"
          }
        }
      },
      "Revision": {
        "type": "object",
        "required": [
          "revision"
        ],
        "properties": {
          "revision": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "ActionRequest": {
        "type": "object",
        "required": [
          "revision",
          "action",
          "fields"
        ],
        "properties": {
          "revision": {
            "type": "integer",
            "minimum": 0
          },
          "action": {
            "type": "string",
            "description": "Choose from case.actions[].id."
          },
          "fields": {
            "type": "object",
            "description": "Must satisfy the selected runtime schema; evidence is an optional array of document IDs.",
            "additionalProperties": true
          }
        }
      },
      "Run": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "revision": {
            "type": "integer"
          },
          "case": {
            "type": "object",
            "description": "Brief, documents and action schemas."
          },
          "state": {
            "type": "object"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "grade": {
            "type": "object",
            "description": "Available after finish."
          },
          "finished_at": {
            "type": "string",
            "nullable": true
          },
          "report_id": {
            "type": "string",
            "nullable": true
          }
        }
      }
    }
  }
}
