{
  "openapi": "3.1.0",
  "info": {
    "title": "Antifailure control plane",
    "version": "1.0.0",
    "description": "Environments, runs, verdicts, masking attestations, and network decisions across an organization. The control plane never receives database contents, model traffic, or secrets: it receives events, metadata, and artifacts that were opted in.",
    "license": {
      "name": "MIT",
      "identifier": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://app.antifailure.dev",
      "description": "Antifailure hosted control plane"
    }
  ],
  "components": {
    "securitySchemes": {
      "session": {
        "type": "apiKey",
        "in": "cookie",
        "name": "af_session"
      },
      "engineToken": {
        "type": "http",
        "scheme": "bearer"
      },
      "cliToken": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "OidcBinding": {
        "type": "object",
        "description": "A repository claimed for workflow identity. `lastUsedAt` and `revokedAt` are null rather than absent, so a caller can tell \"never used\" from a field this version does not send.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "repository": {
            "type": "string",
            "example": "acme/app"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "revokedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "repository",
          "createdAt",
          "lastUsedAt",
          "revokedAt"
        ],
        "additionalProperties": false
      },
      "Refusal": {
        "type": "object",
        "description": "A refusal from a hand-written route. `error` is one sentence for a person, and it names no internal path, table, or query.",
        "properties": {
          "error": {
            "type": "string"
          },
          "retryAfterSeconds": {
            "type": "integer",
            "minimum": 0,
            "description": "Present on 403 and 429. Wait this long before sending the same request again."
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      },
      "ServerFailure": {
        "type": "object",
        "description": "The unexpected path. Hono answers an unhandled error with plain text by default, and a caller should not need a second parser exactly when the service is least healthy, so this shape is guaranteed instead.",
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message",
              "resolution"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "A code from the published catalog at https://antifailure.dev/errors.v1.json."
              },
              "message": {
                "type": "string"
              },
              "resolution": {
                "type": "string"
              }
            },
            "additionalProperties": false
          },
          "requestId": {
            "type": "string",
            "description": "The same value as the x-request-id response header. Quote it when reporting the failure: it is the only thing that ties this answer to a log line, because nothing about the request payload is logged."
          }
        },
        "required": [
          "error",
          "requestId"
        ],
        "additionalProperties": false
      },
      "TrpcFailure": {
        "type": "object",
        "description": "The tRPC error envelope, produced by tRPC rather than by this service. `code` is the JSON-RPC integer; the readable one is `data.code`.",
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "message",
              "code",
              "data"
            ],
            "properties": {
              "message": {
                "type": "string"
              },
              "code": {
                "type": "integer"
              },
              "data": {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string",
                    "examples": [
                      "UNAUTHORIZED",
                      "FORBIDDEN",
                      "BAD_REQUEST"
                    ]
                  },
                  "httpStatus": {
                    "type": "integer"
                  },
                  "path": {
                    "type": "string"
                  }
                },
                "additionalProperties": true
              }
            },
            "additionalProperties": true
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": true
      },
      "TrpcResult": {
        "type": "object",
        "required": [
          "result"
        ],
        "properties": {
          "result": {
            "type": "object",
            "required": [
              "data"
            ],
            "properties": {
              "data": {}
            },
            "additionalProperties": true
          }
        },
        "additionalProperties": false
      },
      "Readiness": {
        "type": "object",
        "description": "Served by both the 200 and the 503. `version` and `commit` are what is actually deployed, which is the pair a rollback decision is made on.",
        "required": [
          "ready",
          "version",
          "commit"
        ],
        "properties": {
          "ready": {
            "type": "boolean"
          },
          "version": {
            "type": "string"
          },
          "commit": {
            "type": "string"
          },
          "reason": {
            "type": "string",
            "description": "Present only when ready is false. Why the database did not answer."
          }
        },
        "additionalProperties": false
      },
      "IngestResult": {
        "type": "object",
        "required": [
          "accepted",
          "duplicates",
          "rejected",
          "unprojected",
          "outcomes"
        ],
        "properties": {
          "accepted": {
            "type": "integer",
            "minimum": 0
          },
          "duplicates": {
            "type": "integer",
            "minimum": 0
          },
          "rejected": {
            "type": "integer",
            "minimum": 0
          },
          "unprojected": {
            "type": "integer",
            "minimum": 0
          },
          "outcomes": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "status"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "accepted",
                    "duplicate",
                    "rejected"
                  ]
                },
                "reason": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              },
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      }
    }
  },
  "x-permissions": [
    {
      "name": "environments.view",
      "description": "See environments, their state, and their preview URLs.",
      "roles": [
        "owner",
        "admin",
        "member",
        "viewer"
      ]
    },
    {
      "name": "environments.create",
      "description": "Bring an environment up for a branch or pull request.",
      "roles": [
        "owner",
        "admin",
        "member"
      ]
    },
    {
      "name": "environments.teardown",
      "description": "Tear an environment down, or put it to sleep.",
      "roles": [
        "owner",
        "admin",
        "member"
      ]
    },
    {
      "name": "masking.edit",
      "description": "Propose a change to a repository’s masking rules.",
      "roles": [
        "owner",
        "admin",
        "member"
      ]
    },
    {
      "name": "masking.approve",
      "description": "Approve a masking rule change so that it can be opened as a pull request.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "network.edit",
      "description": "Propose a change to the egress policy.",
      "roles": [
        "owner",
        "admin",
        "member"
      ]
    },
    {
      "name": "network.approve",
      "description": "Approve an egress policy change, including one that loosens it.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "agents.run",
      "description": "Start an agent run against an environment.",
      "roles": [
        "owner",
        "admin",
        "member"
      ]
    },
    {
      "name": "load.run",
      "description": "Start a load run against an environment.",
      "roles": [
        "owner",
        "admin",
        "member"
      ]
    },
    {
      "name": "members.manage",
      "description": "Invite, remove, and change the role of members.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "billing.manage",
      "description": "See and change the plan, payment method, and spending caps.",
      "roles": [
        "owner"
      ]
    },
    {
      "name": "audit.read",
      "description": "Read the audit log.",
      "roles": [
        "owner",
        "admin",
        "member",
        "viewer"
      ]
    },
    {
      "name": "audit.export",
      "description": "Export the audit log, and verify its hash chain.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "runtimes.manage",
      "description": "Register, tag, and remove runtimes.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "tokens.manage",
      "description": "Create and revoke the tokens engines use to send events.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "organization.settings",
      "description": "Change the organization’s display name.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "organization.delete",
      "description": "Ask for the organization to be deleted, follow that request, and call it off.",
      "roles": [
        "owner"
      ]
    },
    {
      "name": "sessions.manage",
      "description": "See who is signed in and sign any of them out.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "data.export",
      "description": "Take a copy of the organization’s configuration and history out of the product.",
      "roles": [
        "owner",
        "admin"
      ]
    },
    {
      "name": "account.close",
      "description": "Close your own account: erase your name, address and identity, and leave the organization.",
      "roles": [
        "owner",
        "admin",
        "member",
        "viewer"
      ]
    },
    {
      "name": "workloads.view",
      "description": "See workload definitions, their versions, and what their runs measured.",
      "roles": [
        "owner",
        "admin",
        "member",
        "viewer"
      ]
    },
    {
      "name": "workloads.edit",
      "description": "Create a workload, add a version to one, archive one, and promote an exploration into a workflow.",
      "roles": [
        "owner",
        "admin",
        "member"
      ]
    },
    {
      "name": "workloads.run",
      "description": "Start, cancel, and retry a workload run.",
      "roles": [
        "owner",
        "admin",
        "member"
      ]
    },
    {
      "name": "analytics.read",
      "description": "Read the analytics dashboard for this control plane installation. Granted here and checked again against the organization that operates the installation, because this is the one page that is not about the caller’s own organization.",
      "roles": [
        "owner",
        "admin"
      ]
    }
  ],
  "x-antifailure-event-types": [
    "environment.queued",
    "environment.creating",
    "environment.ready",
    "environment.sleeping",
    "environment.failed",
    "environment.torn_down",
    "run.started",
    "run.finished",
    "verdict.recorded",
    "artifact.stored",
    "golden.published",
    "network.decision",
    "workload.started",
    "workload.finished",
    "workload.cancelled"
  ],
  "paths": {
    "/health": {
      "get": {
        "operationId": "getLiveness",
        "summary": "Liveness",
        "security": [],
        "description": "Reports whether the control-plane process is answering. It does not touch the database.",
        "responses": {
          "200": {
            "description": "The process is answering.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "500": {
            "description": "The request failed for a reason the control plane did not expect. The body carries a correlation id; nothing about the request payload is logged or returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerFailure"
                }
              }
            }
          }
        }
      }
    },
    "/readyz": {
      "get": {
        "operationId": "getReadiness",
        "summary": "Readiness and deployed build",
        "security": [],
        "description": "Checks the application database and reports the version and commit that are actually serving.",
        "responses": {
          "200": {
            "description": "The process and its database are ready.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Readiness"
                }
              }
            }
          },
          "500": {
            "description": "The request failed for a reason the control plane did not expect. The body carries a correlation id; nothing about the request payload is logged or returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerFailure"
                }
              }
            }
          },
          "503": {
            "description": "The process is alive and its database did not answer. The body reports the deployed version and commit, which is what a rollback decision needs.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Readiness"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events": {
      "post": {
        "operationId": "ingestEngineEvents",
        "summary": "Send events from an engine",
        "description": "Authenticated by a per-engine bearer token, not a session. Events are idempotent by id and ordered by sequence within an environment, so a retry is safe and a late arrival does not move an environment backwards. A batch carries at most 500 events.",
        "security": [
          {
            "engineToken": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "events"
                ],
                "properties": {
                  "events": {
                    "type": "array",
                    "maxItems": 500,
                    "items": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "occurredAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Unique within the organization. A repeat is dropped."
                        },
                        "type": {
                          "type": "string",
                          "minLength": 1,
                          "description": "One of x-antifailure-event-types, or a newer type this control plane does not know. An unknown type is stored and projects nothing.",
                          "examples": [
                            "environment.queued",
                            "environment.creating",
                            "environment.ready",
                            "environment.sleeping",
                            "environment.failed",
                            "environment.torn_down",
                            "run.started",
                            "run.finished",
                            "verdict.recorded",
                            "artifact.stored",
                            "golden.published",
                            "network.decision",
                            "workload.started",
                            "workload.finished",
                            "workload.cancelled"
                          ]
                        },
                        "envId": {
                          "type": "string"
                        },
                        "sequence": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "occurredAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "payload": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "Type specific. An environment.* event should carry repository (owner/name) and branch on EVERY event and not only the first, because the environment row is created from whichever event arrives first and an event that cannot name its repository cannot create one. started_at is when the environment began existing, which is not when the event fired: usage and the expiry are measured from it, so an environment reported ready after its build is still billed for the build. ttl_seconds is the declared lifetime, added to that instant to give the expiry.",
                          "properties": {
                            "repository": {
                              "type": "string",
                              "description": "owner/name."
                            },
                            "branch": {
                              "type": "string"
                            },
                            "pull_request": {
                              "type": "integer",
                              "minimum": 1
                            },
                            "started_at": {
                              "type": "string",
                              "format": "date-time"
                            },
                            "ttl_seconds": {
                              "type": "number",
                              "minimum": 1
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Every event was accepted or was a duplicate. An accepted event that changed no environment row carries a note saying why, and is counted in unprojected; it is stored either way.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestResult"
                }
              }
            }
          },
          "207": {
            "description": "Some events were rejected. The outcomes array says which and why.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IngestResult"
                }
              }
            }
          },
          "400": {
            "description": "The body is not JSON, or it carries no events array. Nothing was stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "401": {
            "description": "The token is not valid.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "403": {
            "description": "The token is valid and the organization is suspended. Events are refused rather than dropped, so an engine should keep the batch and send it again after retryAfterSeconds.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "413": {
            "description": "The batch is larger than the limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "429": {
            "description": "Too many events. Retry-After says how long to wait before sending the same batch again.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "500": {
            "description": "The request failed for a reason the control plane did not expect. The body carries a correlation id; nothing about the request payload is logged or returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/auth/github-oidc": {
      "post": {
        "operationId": "exchangeWorkflowIdentity",
        "summary": "Exchange a GitHub Actions workflow identity for an engine token",
        "description": "How a job in a customer's CI authenticates with no token, no environment variable and no repository secret. The workflow asks GitHub for an identity token with the audience antifailure-control-plane (it needs `id-token: write`), posts it here, and receives an engine token good for 15 minutes on POST /v1/events.\n\nThe signature, issuer, audience and expiry are all checked, and none of that is what decides which organization the token belongs to. A signed identity proves which repository a job runs in and nothing about who that repository belongs to, because anybody can run Actions in a repository they own. Access comes from a claim on the repository instead.\n\nMost callers never make that claim themselves. When a repository has no claim and exactly one organization holds a live GitHub App installation on its owner, the claim is created on this first exchange and recorded as having come from the installation. What is refused is a repository with no claim AND no installation to stand in for one: an owner nobody has installed the App on reaches nobody, and an owner two organizations have installed on is refused rather than guessed at. POST /v1/oidc/bindings claims one by hand, for a repository the App is not installed on.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "token"
                ],
                "properties": {
                  "token": {
                    "type": "string",
                    "description": "The workflow identity token, minted for audience antifailure-control-plane."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "An engine token, returned once and stored nowhere. Present it as a bearer token on POST /v1/events exactly as a static one.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "token",
                    "expires_at"
                  ],
                  "properties": {
                    "token": {
                      "type": "string"
                    },
                    "expires_at": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "org_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "repository": {
                      "type": "string",
                      "description": "owner/name."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "The body is not JSON, or carries no token."
          },
          "401": {
            "description": "The identity token did not verify. `reason` is one of malformed, bad_algorithm, no_key, invalid_signature, wrong_issuer, wrong_audience, expired, not_yet_valid, no_repository or keys_unavailable, and `error` is a sentence the workflow author can act on."
          },
          "403": {
            "description": "The identity verified and grants nothing. `reason` is no_binding when the repository has not been claimed, binding_revoked when the claim was withdrawn, or installation_suspended."
          },
          "429": {
            "description": "Too many exchanges for this repository. A job needs one credential.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            }
          }
        }
      }
    },
    "/v1/workloads/claim": {
      "post": {
        "security": [
          {
            "engineToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "The answer."
          },
          "400": {
            "description": "The body is not JSON, or is missing a field."
          },
          "401": {
            "description": "The token is not valid."
          },
          "403": {
            "description": "The organization is suspended."
          },
          "404": {
            "description": "No such environment in this organization."
          },
          "409": {
            "description": "This token does not hold the lease."
          }
        },
        "operationId": "claimWorkloadRun",
        "summary": "Take the workload run waiting for an environment",
        "description": "Moves the oldest requested run for the environment to accepted and returns its compiled version, with a lease. Answers 200 and a null run when nothing is waiting, so a poller can tell that apart from a failure. The engine pulls rather than being told because a workflow_dispatch carries only the inputs the workflow declares."
      }
    },
    "/v1/workloads/runs/{runId}/heartbeat": {
      "post": {
        "security": [
          {
            "engineToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "The answer."
          },
          "400": {
            "description": "The body is not JSON, or is missing a field."
          },
          "401": {
            "description": "The token is not valid."
          },
          "403": {
            "description": "The organization is suspended."
          },
          "404": {
            "description": "No such environment in this organization."
          },
          "409": {
            "description": "This token does not hold the lease."
          }
        },
        "operationId": "heartbeatWorkloadRun",
        "summary": "Say the run is still going",
        "description": "Extends the lease and the deadline. A run whose deadline passes with nothing said about it ends as abandoned, which is the control plane admitting it never heard rather than a claim that the work failed."
      }
    },
    "/v1/commands/claim": {
      "post": {
        "security": [
          {
            "engineToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "The answer."
          },
          "400": {
            "description": "The body is not JSON, or is missing a field."
          },
          "401": {
            "description": "The token is not valid."
          },
          "403": {
            "description": "The organization is suspended."
          },
          "404": {
            "description": "No such environment in this organization."
          },
          "409": {
            "description": "This token does not hold the lease."
          }
        },
        "operationId": "claimRuntimeCommands",
        "summary": "Take the runtime commands waiting for this organization",
        "description": "Teardowns and cancellations, with a lease. Reachable while the organization is suspended, deliberately: a suspension stops new work, and stopping what is running is the opposite of new work."
      }
    },
    "/v1/commands/{id}/ack": {
      "post": {
        "security": [
          {
            "engineToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "The answer."
          },
          "400": {
            "description": "The body is not JSON, or is missing a field."
          },
          "401": {
            "description": "The token is not valid."
          },
          "403": {
            "description": "The organization is suspended."
          },
          "404": {
            "description": "No such environment in this organization."
          },
          "409": {
            "description": "This token does not hold the lease."
          }
        },
        "operationId": "ackRuntimeCommand",
        "summary": "Say what happened to a command",
        "description": "Only the holder of the lease may acknowledge, and an acknowledgement that matches no row answers 409 rather than 200: an acknowledgement nobody applied is the silent nothing the durable command exists to end."
      }
    },
    "/v1/oidc/bindings": {
      "post": {
        "security": [
          {
            "cliToken": []
          }
        ],
        "tags": [
          "Workflow identity"
        ],
        "operationId": "claimRepositoryBinding",
        "summary": "Claim a repository for workflow identity",
        "description": "Claims `owner/name` for this organization, so a workflow in it can exchange a GitHub identity token for an engine token. Needed when the App is not installed on the owner, which is the case the first exchange cannot resolve on its own.\n\nBehind the same permission as minting an engine token, because a claim grants a workflow the standing ability to mint one.\n\nNeeds a CLI token carrying `tokens.manage`, from `af login --scope tokens.manage`. OpenAPI cannot express a scope on a bearer scheme, so the requirement is stated here rather than in `security`, where only OAuth2 flows can carry scopes.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repository": {
                    "type": "string",
                    "example": "acme/app"
                  }
                },
                "required": [
                  "repository"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The claim, as the list renders it.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OidcBinding"
                }
              }
            }
          },
          "400": {
            "description": "The body is not JSON, or the repository is not `owner/name`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "401": {
            "description": "The bearer token is not a valid CLI token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "402": {
            "description": "This organization's plan does not include the hosted control plane.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "403": {
            "description": "The token does not carry `tokens.manage`. The message names the command that fixes it, because a caller told only that they are forbidden goes looking for a role problem.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "409": {
            "description": "Another organization already holds this repository. Nothing about the request is malformed, and sending it again unchanged will never work, which is why it is not a 400.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "500": {
            "description": "The request failed for a reason the control plane did not expect. The body carries a correlation id; nothing about the request payload is logged or returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerFailure"
                }
              }
            }
          }
        }
      },
      "get": {
        "security": [
          {
            "cliToken": []
          }
        ],
        "tags": [
          "Workflow identity"
        ],
        "operationId": "listRepositoryBindings",
        "summary": "List this organization's repository claims",
        "description": "Every claim this organization holds, with the audience a workflow must ask GitHub for. The audience is returned rather than documented alone so a caller building a workflow file reads it from the server that will check it.\n\nNeeds a CLI token carrying `tokens.manage`, from `af login --scope tokens.manage`.",
        "responses": {
          "200": {
            "description": "The claims and the audience.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "audience": {
                      "type": "string",
                      "example": "antifailure-control-plane"
                    },
                    "bindings": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/OidcBinding"
                      }
                    }
                  },
                  "required": [
                    "audience",
                    "bindings"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "The bearer token is not a valid CLI token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "402": {
            "description": "This organization's plan does not include the hosted control plane.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "403": {
            "description": "The token does not carry `tokens.manage`. The message names the command that fixes it, because a caller told only that they are forbidden goes looking for a role problem.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "500": {
            "description": "The request failed for a reason the control plane did not expect. The body carries a correlation id; nothing about the request payload is logged or returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/oidc/bindings/{binding}": {
      "delete": {
        "security": [
          {
            "cliToken": []
          }
        ],
        "tags": [
          "Workflow identity"
        ],
        "operationId": "revokeRepositoryBindingById",
        "summary": "Revoke a repository claim by id",
        "description": "Revokes the claim and kills every engine token minted through it. The count of tokens killed is in the answer.\n\nNeeds a CLI token carrying `tokens.manage`, from `af login --scope tokens.manage`.",
        "parameters": [
          {
            "name": "binding",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "What the revocation did.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "revoked": {
                      "type": "boolean"
                    },
                    "repository": {
                      "type": "string"
                    },
                    "alreadyRevoked": {
                      "type": "boolean",
                      "description": "True when the claim was already revoked, so a retry is not an error."
                    },
                    "tokensRevoked": {
                      "type": "integer",
                      "description": "How many live engine tokens this killed. Named, because \"revoked\" on its own does not tell somebody in an incident whether the credentials already out there are dead."
                    }
                  },
                  "required": [
                    "revoked",
                    "repository",
                    "alreadyRevoked",
                    "tokensRevoked"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The identifier is neither a uuid nor `owner/name`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "401": {
            "description": "The bearer token is not a valid CLI token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "402": {
            "description": "This organization's plan does not include the hosted control plane.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "403": {
            "description": "The token does not carry `tokens.manage`. The message names the command that fixes it, because a caller told only that they are forbidden goes looking for a role problem.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "404": {
            "description": "No claim here has that id or repository. The same answer whether it belongs to another organization or does not exist, which is what every other lookup on this server does.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "500": {
            "description": "The request failed for a reason the control plane did not expect. The body carries a correlation id; nothing about the request payload is logged or returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/oidc/bindings/{owner}/{name}": {
      "delete": {
        "security": [
          {
            "cliToken": []
          }
        ],
        "tags": [
          "Workflow identity"
        ],
        "operationId": "revokeRepositoryBindingByRepository",
        "summary": "Revoke a repository claim by repository name",
        "description": "The same operation as revoking by id, reachable with the name a person has in front of them. See the note above about why this is a second path rather than one segment.",
        "parameters": [
          {
            "name": "owner",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "What the revocation did.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "revoked": {
                      "type": "boolean"
                    },
                    "repository": {
                      "type": "string"
                    },
                    "alreadyRevoked": {
                      "type": "boolean",
                      "description": "True when the claim was already revoked, so a retry is not an error."
                    },
                    "tokensRevoked": {
                      "type": "integer",
                      "description": "How many live engine tokens this killed. Named, because \"revoked\" on its own does not tell somebody in an incident whether the credentials already out there are dead."
                    }
                  },
                  "required": [
                    "revoked",
                    "repository",
                    "alreadyRevoked",
                    "tokensRevoked"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The identifier is neither a uuid nor `owner/name`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "401": {
            "description": "The bearer token is not a valid CLI token.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "402": {
            "description": "This organization's plan does not include the hosted control plane.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "403": {
            "description": "The token does not carry `tokens.manage`. The message names the command that fixes it, because a caller told only that they are forbidden goes looking for a role problem.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "404": {
            "description": "No claim here has that id or repository. The same answer whether it belongs to another organization or does not exist, which is what every other lookup on this server does.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refusal"
                }
              }
            }
          },
          "500": {
            "description": "The request failed for a reason the control plane did not expect. The body carries a correlation id; nothing about the request payload is logged or returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServerFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/account.close": {
      "post": {
        "operationId": "trpc_account_close",
        "summary": "account.close",
        "description": "Requires the account.close permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold account.close.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/account.context": {
      "get": {
        "operationId": "trpc_account_context",
        "summary": "account.context",
        "description": "Requires the account.close permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold account.close.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/agents.run": {
      "post": {
        "operationId": "trpc_agents_run",
        "summary": "agents.run",
        "description": "Requires the agents.run permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "envId": {
                    "type": "string"
                  },
                  "workflows": {
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 200
                    }
                  },
                  "workflow": {
                    "default": "antifailure.yml",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[A-Za-z0-9._-]+\\.ya?ml$"
                  }
                },
                "required": [
                  "envId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold agents.run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/analytics.catalog": {
      "get": {
        "operationId": "trpc_analytics_catalog",
        "summary": "analytics.catalog",
        "description": "Requires the analytics.read permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold analytics.read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/analytics.overview": {
      "get": {
        "operationId": "trpc_analytics_overview",
        "summary": "analytics.overview",
        "description": "Requires the analytics.read permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "days": {
                      "default": 28,
                      "anyOf": [
                        {
                          "type": "number",
                          "const": 7
                        },
                        {
                          "type": "number",
                          "const": 28
                        },
                        {
                          "type": "number",
                          "const": 90
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold analytics.read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/analytics.series": {
      "get": {
        "operationId": "trpc_analytics_series",
        "summary": "analytics.series",
        "description": "Requires the analytics.read permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "days": {
                      "default": 28,
                      "anyOf": [
                        {
                          "type": "number",
                          "const": 7
                        },
                        {
                          "type": "number",
                          "const": 28
                        },
                        {
                          "type": "number",
                          "const": 90
                        }
                      ]
                    },
                    "name": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "name"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold analytics.read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/audit.export": {
      "post": {
        "operationId": "trpc_audit_export",
        "summary": "audit.export",
        "description": "Requires the audit.export permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "format": {
                    "default": "json",
                    "type": "string",
                    "enum": [
                      "json",
                      "csv"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold audit.export.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/audit.list": {
      "get": {
        "operationId": "trpc_audit_list",
        "summary": "audit.list",
        "description": "Requires the audit.read permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "action": {
                      "type": "string"
                    },
                    "limit": {
                      "default": 100,
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 500
                    },
                    "before": {
                      "type": "integer",
                      "minimum": -9007199254740991,
                      "maximum": 9007199254740991
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold audit.read.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/audit.verify": {
      "get": {
        "operationId": "trpc_audit_verify",
        "summary": "audit.verify",
        "description": "Requires the audit.export permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold audit.export.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/billing.get": {
      "get": {
        "operationId": "trpc_billing_get",
        "summary": "billing.get",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/billing.set": {
      "post": {
        "operationId": "trpc_billing_set",
        "summary": "billing.set",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": [
                      "free",
                      "team",
                      "enterprise"
                    ]
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "plan"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/deletion.advance": {
      "post": {
        "operationId": "trpc_deletion_advance",
        "summary": "deletion.advance",
        "description": "Requires the organization.delete permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "This route reads no input. The transport still requires a JSON content type, so send {}.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Ignored. The route declares no input validator."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold organization.delete.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/deletion.cancel": {
      "post": {
        "operationId": "trpc_deletion_cancel",
        "summary": "deletion.cancel",
        "description": "Requires the organization.delete permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "This route reads no input. The transport still requires a JSON content type, so send {}.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Ignored. The route declares no input validator."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold organization.delete.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/deletion.destroyExport": {
      "post": {
        "operationId": "trpc_deletion_destroyExport",
        "summary": "deletion.destroyExport",
        "description": "Requires the organization.delete permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "This route reads no input. The transport still requires a JSON content type, so send {}.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Ignored. The route declares no input validator."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold organization.delete.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/deletion.request": {
      "post": {
        "operationId": "trpc_deletion_request",
        "summary": "deletion.request",
        "description": "Requires the organization.delete permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "confirm": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 1000
                  }
                },
                "required": [
                  "confirm"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold organization.delete.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/deletion.status": {
      "get": {
        "operationId": "trpc_deletion_status",
        "summary": "deletion.status",
        "description": "Requires the organization.delete permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold organization.delete.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/environments.costs": {
      "get": {
        "operationId": "trpc_environments_costs",
        "summary": "environments.costs",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "hours": {
                      "default": 24,
                      "type": "integer",
                      "exclusiveMinimum": 0,
                      "maximum": 720
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/environments.create": {
      "post": {
        "operationId": "trpc_environments_create",
        "summary": "environments.create",
        "description": "Requires the environments.create permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repository": {
                    "type": "string"
                  },
                  "branch": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "workflow": {
                    "default": "antifailure.yml",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[A-Za-z0-9._-]+\\.ya?ml$"
                  },
                  "ttlHours": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 8760
                  }
                },
                "required": [
                  "repository"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.create.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/environments.get": {
      "get": {
        "operationId": "trpc_environments_get",
        "summary": "environments.get",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "envId": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "envId"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/environments.list": {
      "get": {
        "operationId": "trpc_environments_list",
        "summary": "environments.list",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "repository": {
                      "type": "string"
                    },
                    "branch": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "creating",
                        "running",
                        "sleeping",
                        "failed",
                        "torn_down"
                      ]
                    },
                    "createdBy": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    },
                    "limit": {
                      "default": 50,
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 200
                    },
                    "cursor": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/environments.readiness": {
      "get": {
        "operationId": "trpc_environments_readiness",
        "summary": "environments.readiness",
        "description": "Requires the environments.create permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "repository": {
                      "type": "string"
                    },
                    "workflow": {
                      "default": "antifailure.yml",
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100,
                      "pattern": "^[A-Za-z0-9._-]+\\.ya?ml$"
                    }
                  },
                  "required": [
                    "repository"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.create.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/environments.teardown": {
      "post": {
        "operationId": "trpc_environments_teardown",
        "summary": "environments.teardown",
        "description": "Requires the environments.teardown permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "envId": {
                    "type": "string"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  },
                  "workflow": {
                    "default": "antifailure.yml",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[A-Za-z0-9._-]+\\.ya?ml$"
                  }
                },
                "required": [
                  "envId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.teardown.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/exports.organization": {
      "post": {
        "operationId": "trpc_exports_organization",
        "summary": "exports.organization",
        "description": "Requires the data.export permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "This route reads no input. The transport still requires a JSON content type, so send {}.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Ignored. The route declares no input validator."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold data.export.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/health": {
      "get": {
        "operationId": "trpc_health",
        "summary": "health",
        "description": "Requires no permission.",
        "security": [],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/invitations.create": {
      "post": {
        "operationId": "trpc_invitations_create",
        "summary": "invitations.create",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "owner",
                      "admin",
                      "member",
                      "viewer"
                    ]
                  }
                },
                "required": [
                  "email",
                  "role"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/invitations.list": {
      "get": {
        "operationId": "trpc_invitations_list",
        "summary": "invitations.list",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/invitations.resend": {
      "post": {
        "operationId": "trpc_invitations_resend",
        "summary": "invitations.resend",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/invitations.revoke": {
      "post": {
        "operationId": "trpc_invitations_revoke",
        "summary": "invitations.revoke",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/load.run": {
      "post": {
        "operationId": "trpc_load_run",
        "summary": "load.run",
        "description": "Requires the load.run permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "envId": {
                    "type": "string"
                  },
                  "seconds": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 3600
                  },
                  "scale": {
                    "type": "number",
                    "minimum": 0.01,
                    "maximum": 100
                  },
                  "workflow": {
                    "default": "antifailure.yml",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[A-Za-z0-9._-]+\\.ya?ml$"
                  }
                },
                "required": [
                  "envId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold load.run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/masking.approve": {
      "post": {
        "operationId": "trpc_masking_approve",
        "summary": "masking.approve",
        "description": "Requires the masking.approve permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repository": {
                    "type": "string"
                  },
                  "table": {
                    "type": "string"
                  },
                  "column": {
                    "type": "string"
                  }
                },
                "required": [
                  "repository",
                  "table",
                  "column"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold masking.approve.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/masking.attestations": {
      "get": {
        "operationId": "trpc_masking_attestations",
        "summary": "masking.attestations",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "repository": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "repository"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/masking.propose": {
      "post": {
        "operationId": "trpc_masking_propose",
        "summary": "masking.propose",
        "description": "Requires the masking.edit permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repository": {
                    "type": "string"
                  },
                  "table": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "column": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "transform": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "link": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "repository",
                  "table",
                  "column",
                  "transform"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold masking.edit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/masking.rules": {
      "get": {
        "operationId": "trpc_masking_rules",
        "summary": "masking.rules",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "repository": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "repository"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/members.list": {
      "get": {
        "operationId": "trpc_members_list",
        "summary": "members.list",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/members.remove": {
      "post": {
        "operationId": "trpc_members_remove",
        "summary": "members.remove",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "githubLogin": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  }
                },
                "required": [
                  "githubLogin"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/members.setRole": {
      "post": {
        "operationId": "trpc_members_setRole",
        "summary": "members.setRole",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "githubLogin": {
                    "type": "string"
                  },
                  "role": {
                    "type": "string",
                    "enum": [
                      "owner",
                      "admin",
                      "member",
                      "viewer"
                    ]
                  }
                },
                "required": [
                  "githubLogin",
                  "role"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/members.sync": {
      "post": {
        "operationId": "trpc_members_sync",
        "summary": "members.sync",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "This route reads no input. The transport still requires a JSON content type, so send {}.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Ignored. The route declares no input validator."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/network.approve": {
      "post": {
        "operationId": "trpc_network_approve",
        "summary": "network.approve",
        "description": "Requires the network.approve permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "ruleId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "ruleId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold network.approve.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/network.decisions": {
      "get": {
        "operationId": "trpc_network_decisions",
        "summary": "network.decisions",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "envId": {
                      "type": "string"
                    },
                    "limit": {
                      "default": 100,
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 500
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/network.effective": {
      "get": {
        "operationId": "trpc_network_effective",
        "summary": "network.effective",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "repository": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/network.explain": {
      "get": {
        "operationId": "trpc_network_explain",
        "summary": "network.explain",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "repository": {
                      "type": "string"
                    },
                    "host": {
                      "type": "string",
                      "minLength": 1
                    },
                    "port": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 65535
                    },
                    "method": {
                      "type": "string",
                      "maxLength": 20
                    },
                    "path": {
                      "type": "string",
                      "maxLength": 2000
                    },
                    "tls": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "host"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/network.pending": {
      "get": {
        "operationId": "trpc_network_pending",
        "summary": "network.pending",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": false,
            "description": "JSON-encoded tRPC input. Every field has a default, so it may be omitted.",
            "content": {
              "application/json": {
                "schema": {
                  "default": {},
                  "type": "object",
                  "properties": {
                    "repository": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/network.propose": {
      "post": {
        "operationId": "trpc_network_propose",
        "summary": "network.propose",
        "description": "Requires the network.edit permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repository": {
                    "type": "string"
                  },
                  "host": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 253
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "block",
                      "allow",
                      "capture",
                      "mock",
                      "sandbox",
                      "synth"
                    ]
                  },
                  "paths": {
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "methods": {
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "repository",
                  "host",
                  "mode"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold network.edit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/org.billingContact": {
      "get": {
        "operationId": "trpc_org_billingContact",
        "summary": "org.billingContact",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/org.rename": {
      "post": {
        "operationId": "trpc_org_rename",
        "summary": "org.rename",
        "description": "Requires the organization.settings permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold organization.settings.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/org.resume": {
      "post": {
        "operationId": "trpc_org_resume",
        "summary": "org.resume",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "This route reads no input. The transport still requires a JSON content type, so send {}.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Ignored. The route declares no input validator."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/org.setBillingContact": {
      "post": {
        "operationId": "trpc_org_setBillingContact",
        "summary": "org.setBillingContact",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320
                  },
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/org.settings": {
      "get": {
        "operationId": "trpc_org_settings",
        "summary": "org.settings",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/org.status": {
      "get": {
        "operationId": "trpc_org_status",
        "summary": "org.status",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/org.suspend": {
      "post": {
        "operationId": "trpc_org_suspend",
        "summary": "org.suspend",
        "description": "Requires the members.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  }
                },
                "required": [
                  "reason"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold members.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/permissions": {
      "get": {
        "operationId": "trpc_permissions",
        "summary": "permissions",
        "description": "Requires no permission.",
        "security": [],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/repositories.list": {
      "get": {
        "operationId": "trpc_repositories_list",
        "summary": "repositories.list",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": false,
            "description": "JSON-encoded tRPC input. Every field has a default, so it may be omitted.",
            "content": {
              "application/json": {
                "schema": {
                  "default": {
                    "includeArchived": false
                  },
                  "type": "object",
                  "properties": {
                    "includeArchived": {
                      "default": false,
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/repositories.setup": {
      "get": {
        "operationId": "trpc_repositories_setup",
        "summary": "repositories.setup",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runs.artifacts": {
      "get": {
        "operationId": "trpc_runs_artifacts",
        "summary": "runs.artifacts",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "runId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "required": [
                    "runId"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runs.get": {
      "get": {
        "operationId": "trpc_runs_get",
        "summary": "runs.get",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "runId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "required": [
                    "runId"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runs.list": {
      "get": {
        "operationId": "trpc_runs_list",
        "summary": "runs.list",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "envId": {
                      "type": "string"
                    },
                    "limit": {
                      "default": 25,
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    }
                  },
                  "required": [
                    "envId"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runs.recent": {
      "get": {
        "operationId": "trpc_runs_recent",
        "summary": "runs.recent",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": false,
            "description": "JSON-encoded tRPC input. Every field has a default, so it may be omitted.",
            "content": {
              "application/json": {
                "schema": {
                  "default": {
                    "limit": 50
                  },
                  "type": "object",
                  "properties": {
                    "envId": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "complete",
                        "failed",
                        "cancelled"
                      ]
                    },
                    "limit": {
                      "default": 50,
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 200
                    },
                    "before": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runs.verdicts": {
      "get": {
        "operationId": "trpc_runs_verdicts",
        "summary": "runs.verdicts",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "runId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "required": [
                    "runId"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runtimes.list": {
      "get": {
        "operationId": "trpc_runtimes_list",
        "summary": "runtimes.list",
        "description": "Requires the environments.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": false,
            "description": "JSON-encoded tRPC input. Every field has a default, so it may be omitted.",
            "content": {
              "application/json": {
                "schema": {
                  "default": {
                    "includeRemoved": false
                  },
                  "type": "object",
                  "properties": {
                    "includeRemoved": {
                      "default": false,
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold environments.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runtimes.register": {
      "post": {
        "operationId": "trpc_runtimes_register",
        "summary": "runtimes.register",
        "description": "Requires the runtimes.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "provider": {
                    "type": "string",
                    "enum": [
                      "local",
                      "kubernetes"
                    ]
                  },
                  "labels": {
                    "default": [],
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 60,
                      "pattern": "^[a-z0-9][a-z0-9-]*$"
                    }
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "name",
                  "provider"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold runtimes.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runtimes.remove": {
      "post": {
        "operationId": "trpc_runtimes_remove",
        "summary": "runtimes.remove",
        "description": "Requires the runtimes.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold runtimes.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/runtimes.tag": {
      "post": {
        "operationId": "trpc_runtimes_tag",
        "summary": "runtimes.tag",
        "description": "Requires the runtimes.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "labels": {
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 60,
                      "pattern": "^[a-z0-9][a-z0-9-]*$"
                    }
                  }
                },
                "required": [
                  "name",
                  "labels"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold runtimes.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/sessions.list": {
      "get": {
        "operationId": "trpc_sessions_list",
        "summary": "sessions.list",
        "description": "Requires the sessions.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "includeRevoked": {
                      "default": false,
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold sessions.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/sessions.revoke": {
      "post": {
        "operationId": "trpc_sessions_revoke",
        "summary": "sessions.revoke",
        "description": "Requires the sessions.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold sessions.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/sessions.revokeForPerson": {
      "post": {
        "operationId": "trpc_sessions_revokeForPerson",
        "summary": "sessions.revokeForPerson",
        "description": "Requires the sessions.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "githubLogin": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  }
                },
                "required": [
                  "githubLogin"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold sessions.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/subscriptions.cancel": {
      "post": {
        "operationId": "trpc_subscriptions_cancel",
        "summary": "subscriptions.cancel",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/subscriptions.checkout": {
      "post": {
        "operationId": "trpc_subscriptions_checkout",
        "summary": "subscriptions.checkout",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "plan": {
                    "type": "string",
                    "enum": [
                      "team",
                      "enterprise"
                    ]
                  },
                  "successUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "cancelUrl": {
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "plan",
                  "successUrl",
                  "cancelUrl"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/subscriptions.current": {
      "get": {
        "operationId": "trpc_subscriptions_current",
        "summary": "subscriptions.current",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/subscriptions.invoices": {
      "get": {
        "operationId": "trpc_subscriptions_invoices",
        "summary": "subscriptions.invoices",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "limit": {
                      "default": 20,
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 100
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/subscriptions.portal": {
      "post": {
        "operationId": "trpc_subscriptions_portal",
        "summary": "subscriptions.portal",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "returnUrl": {
                    "type": "string",
                    "format": "uri"
                  }
                },
                "required": [
                  "returnUrl"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/subscriptions.reconcile": {
      "post": {
        "operationId": "trpc_subscriptions_reconcile",
        "summary": "subscriptions.reconcile",
        "description": "Requires the billing.manage permission, held by: owner.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "This route reads no input. The transport still requires a JSON content type, so send {}.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Ignored. The route declares no input validator."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold billing.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/tokens.list": {
      "get": {
        "operationId": "trpc_tokens_list",
        "summary": "tokens.list",
        "description": "Requires the tokens.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold tokens.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/tokens.revoke": {
      "post": {
        "operationId": "trpc_tokens_revoke",
        "summary": "tokens.revoke",
        "description": "Requires the tokens.manage permission, held by: owner, admin.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  }
                },
                "required": [
                  "id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold tokens.manage.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.addVersion": {
      "post": {
        "operationId": "trpc_workloads_addVersion",
        "summary": "workloads.addVersion",
        "description": "Requires the workloads.edit permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "slug": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 63,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "body": {},
                  "notes": {
                    "type": "string",
                    "maxLength": 2000
                  }
                },
                "required": [
                  "slug",
                  "body"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.edit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.archive": {
      "post": {
        "operationId": "trpc_workloads_archive",
        "summary": "workloads.archive",
        "description": "Requires the workloads.edit permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "slug": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 63,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "slug"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.edit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.cancel": {
      "post": {
        "operationId": "trpc_workloads_cancel",
        "summary": "workloads.cancel",
        "description": "Requires the workloads.run permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "runId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "required": [
                  "runId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.create": {
      "post": {
        "operationId": "trpc_workloads_create",
        "summary": "workloads.create",
        "description": "Requires the workloads.edit permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repository": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 63,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "observed_load",
                      "http_scenario",
                      "browser_workflow",
                      "exploration"
                    ]
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "body": {}
                },
                "required": [
                  "repository",
                  "slug",
                  "name",
                  "kind",
                  "body"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.edit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.get": {
      "get": {
        "operationId": "trpc_workloads_get",
        "summary": "workloads.get",
        "description": "Requires the workloads.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "slug": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 63,
                      "pattern": "^[a-z0-9][a-z0-9-]*$"
                    }
                  },
                  "required": [
                    "slug"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.inspect": {
      "get": {
        "operationId": "trpc_workloads_inspect",
        "summary": "workloads.inspect",
        "description": "Requires the workloads.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": true,
            "description": "JSON-encoded tRPC input. This route refuses a request without it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "runId": {
                      "type": "string",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                    }
                  },
                  "required": [
                    "runId"
                  ]
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.list": {
      "get": {
        "operationId": "trpc_workloads_list",
        "summary": "workloads.list",
        "description": "Requires the workloads.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": false,
            "description": "JSON-encoded tRPC input. Every field has a default, so it may be omitted.",
            "content": {
              "application/json": {
                "schema": {
                  "default": {
                    "includeArchived": false,
                    "limit": 50
                  },
                  "type": "object",
                  "properties": {
                    "repository": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "observed_load",
                        "http_scenario",
                        "browser_workflow",
                        "exploration"
                      ]
                    },
                    "includeArchived": {
                      "default": false,
                      "type": "boolean"
                    },
                    "limit": {
                      "default": 50,
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 200
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.promote": {
      "post": {
        "operationId": "trpc_workloads_promote",
        "summary": "workloads.promote",
        "description": "Requires the workloads.edit permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "repository": {
                    "type": "string"
                  },
                  "slug": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 63,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "fromRunId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "exploration": {},
                  "persona": {
                    "type": "string",
                    "maxLength": 200
                  }
                },
                "required": [
                  "repository",
                  "exploration"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.edit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.retry": {
      "post": {
        "operationId": "trpc_workloads_retry",
        "summary": "workloads.retry",
        "description": "Requires the workloads.run permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "runId": {
                    "type": "string",
                    "format": "uuid",
                    "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                  },
                  "workflow": {
                    "default": "antifailure.yml",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[A-Za-z0-9._-]+\\.ya?ml$"
                  }
                },
                "required": [
                  "runId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.runs": {
      "get": {
        "operationId": "trpc_workloads_runs",
        "summary": "workloads.runs",
        "description": "Requires the workloads.view permission, held by: owner, admin, member, viewer.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "input",
            "in": "query",
            "required": false,
            "description": "JSON-encoded tRPC input. Every field has a default, so it may be omitted.",
            "content": {
              "application/json": {
                "schema": {
                  "default": {
                    "limit": 50
                  },
                  "type": "object",
                  "properties": {
                    "slug": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 63,
                      "pattern": "^[a-z0-9][a-z0-9-]*$"
                    },
                    "envId": {
                      "type": "string"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "requested",
                        "accepted",
                        "running",
                        "succeeded",
                        "failed",
                        "cancelled",
                        "timed_out",
                        "abandoned"
                      ]
                    },
                    "limit": {
                      "default": 50,
                      "type": "integer",
                      "minimum": 1,
                      "maximum": 200
                    }
                  }
                }
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.view.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    },
    "/trpc/workloads.start": {
      "post": {
        "operationId": "trpc_workloads_start",
        "summary": "workloads.start",
        "description": "Requires the workloads.run permission, held by: owner, admin, member.",
        "security": [
          {
            "session": []
          }
        ],
        "parameters": [
          {
            "name": "x-antifailure-csrf",
            "in": "header",
            "required": true,
            "description": "The CSRF token returned by GET /auth/session.",
            "schema": {
              "type": "string",
              "minLength": 32
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "slug": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 63,
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "envId": {
                    "type": "string"
                  },
                  "version": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 9007199254740991
                  },
                  "requestKey": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "workflow": {
                    "default": "antifailure.yml",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "pattern": "^[A-Za-z0-9._-]+\\.ya?ml$"
                  }
                },
                "required": [
                  "slug",
                  "envId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tRPC result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcResult"
                }
              }
            }
          },
          "400": {
            "description": "The input did not satisfy this route's validator.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "401": {
            "description": "No session.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "403": {
            "description": "The role does not hold workloads.run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          },
          "500": {
            "description": "The route threw. tRPC formats this one, so it is a tRPC envelope rather than the ServerFailure body, and the stack is withheld: it names internal paths and table names to anyone who can provoke an error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrpcFailure"
                }
              }
            }
          }
        }
      }
    }
  }
}
