{
  "schema": "cluster-onboarding-guide/v1",
  "entrypoint": "/v1/onboarding",
  "representations": {
    "html": "/v1/onboarding",
    "markdown": "/v1/onboarding?format=markdown",
    "json": "/v1/onboarding?format=json"
  },
  "authentication": {
    "scheme": "Bearer",
    "source": "private access supplied by the human or host",
    "participant_scopes": [
      "fleet:read",
      "seed:write"
    ],
    "operator_issuer": "/v1/seed-access",
    "participant_can_issue_access": false
  },
  "limits": {
    "archive_bytes": 536870912,
    "expanded_archive_bytes": 5368709120,
    "json_body_bytes_exclusive": 65536,
    "pending_slots_per_owner": 8,
    "upload_framing": "Content-Length; no chunked transfer"
  },
  "preservation_tools_commit": "4d4ccd5e9eaf4092e62cbdefa9fbc6288d2cbcd8",
  "portable_tools": "/downloads/being-seed-tools-4d4ccd5.tgz",
  "completion": {
    "prepared": "originals preserved; separate working context prepared",
    "active": false,
    "automatic_runtime_activation": false,
    "remaining": [
      "native context and HMK acceptance",
      "canonical signed body enrollment",
      "dedicated SSH",
      "provider login",
      "single Telegram consumer acceptance",
      "first bot welcome"
    ]
  },
  "requests": {
    "create": {
      "method": "POST",
      "path": "/v1/seeds",
      "required_headers": {
        "Idempotency-Key": "UUID"
      },
      "body": {
        "name": "lowercase environment ID",
        "label": "daimon name",
        "mode": "import or new",
        "browser": "optional boolean",
        "soul": "required initial SOUL only for new"
      }
    },
    "upload": {
      "method": "POST",
      "path": "/v1/seeds/{name}/archive",
      "body": "raw ZIP/TGZ bytes",
      "required_headers": {
        "Content-Length": "archive byte size",
        "X-Archive-SHA256": "64 lowercase hex characters"
      }
    },
    "selection": {
      "method": "GET",
      "path": "/v1/seeds/{name}/selection",
      "result": "private verified candidates"
    },
    "prepare": {
      "method": "POST",
      "path": "/v1/seeds/{name}/prepare",
      "body": {
        "selection": "reviewed selection object; null for new"
      }
    },
    "connections": {
      "method": "POST",
      "path": "/v1/seeds/{name}/connections",
      "body_fields": {
        "telegram_bot_token": "private bot token",
        "telegram_chat_id": "nonzero integer",
        "telegram_topic_id": "optional nonzero integer",
        "ssh_public_key": "public key only"
      }
    },
    "progress": {
      "method": "GET",
      "path": "/v1/seeds",
      "result": "owner-scoped paginated progress"
    }
  },
  "retry_rules": [
    "Reuse the same creation UUID and exact specification.",
    "If uploaded, discover the existing archive instead of uploading again.",
    "An exact preparation retry preserves later receiving memory writes.",
    "Failed or partial attempts require attention; never overwrite them."
  ],
  "api": {
    "openapi": "3.0.3",
    "info": {
      "title": "clusterd",
      "version": "0.1.0",
      "description": "HTTP API over clusterctl (issue #17; design: docs/design/clusterd.md). Mutations adapt clusterctl; read models add owner scoping, redaction, explicit observation boundaries and bounded snapshot pagination. Errors mirror clusterctl exit codes: 0->200, 2->400, 3->404, 6->409, 10->500."
    },
    "servers": [
      {
        "url": "/",
        "description": "This HTTPS origin"
      }
    ],
    "paths": {
      "/v1/onboarding": {
        "get": {
          "operationId": "seedOnboarding",
          "summary": "Human interface or public Markdown/JSON agent guide",
          "description": "Uses `n/a` as its source; mutations retain the same clusterctl business-logic boundary while reads may add owner scoping, redaction, observation envelopes, and bounded snapshot pagination.\n\nRequired bearer scope: `None` (route is public)",
          "parameters": [
            {
              "name": "X-Request-Id",
              "in": "header",
              "required": false,
              "description": "Echoed back; a uuid4 is generated when absent.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Actor",
              "in": "header",
              "required": false,
              "description": "Advisory only. Authenticated routes use the bearer token actor as the authoritative actor.",
              "schema": {
                "type": "string",
                "default": "anonymous"
              }
            },
            {
              "name": "format",
              "in": "query",
              "required": false,
              "schema": {
                "type": "string",
                "enum": [
                  "html",
                  "markdown",
                  "json"
                ]
              }
            }
          ],
          "security": [],
          "responses": {
            "200": {
              "description": "clusterctl result JSON (exit 0)"
            },
            "500": {
              "description": "internal error (CLI exit 10)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            }
          }
        }
      },
      "/v1/seeds": {
        "get": {
          "operationId": "listSeeds",
          "summary": "Owner-scoped seed preparation progress",
          "description": "Uses `clusterctl seed list --json` as its source; mutations retain the same clusterctl business-logic boundary while reads may add owner scoping, redaction, observation envelopes, and bounded snapshot pagination.\n\nRequired bearer scope: `fleet:read` \u2014 enforced (issue #18). Owner-scoped tokens may only touch daimons whose spec created_by matches the owner.",
          "parameters": [
            {
              "name": "X-Request-Id",
              "in": "header",
              "required": false,
              "description": "Echoed back; a uuid4 is generated when absent.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Actor",
              "in": "header",
              "required": false,
              "description": "Advisory only. Authenticated routes use the bearer token actor as the authoritative actor.",
              "schema": {
                "type": "string",
                "default": "anonymous"
              }
            },
            {
              "name": "limit",
              "in": "query",
              "schema": {
                "type": "integer",
                "minimum": 1,
                "maximum": 200
              }
            },
            {
              "name": "cursor",
              "in": "query",
              "schema": {
                "type": "string",
                "maxLength": 512
              }
            }
          ],
          "security": [
            {
              "bearerAuth": []
            }
          ],
          "responses": {
            "200": {
              "description": "Bounded immutable snapshot page",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/SnapshotPage"
                  }
                }
              }
            },
            "400": {
              "description": "invalid limit/cursor or cursor scope mismatch",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "409": {
              "description": "cursor snapshot expired or was evicted; restart pagination",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "401": {
              "description": "missing/unknown/expired/revoked bearer token ({error: unauthorized})",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "403": {
              "description": "authenticated but denied: insufficient scope, not your daimon (owner mismatch), or unattended-steward-denied",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "500": {
              "description": "internal error (CLI exit 10)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            }
          }
        },
        "post": {
          "operationId": "createSeed",
          "summary": "Create an import slot or a new being context",
          "description": "Uses `clusterctl seed create` as its source; mutations retain the same clusterctl business-logic boundary while reads may add owner scoping, redaction, observation envelopes, and bounded snapshot pagination.\n\nRequired bearer scope: `seed:write` \u2014 enforced (issue #18). Owner-scoped tokens may only touch daimons whose spec created_by matches the owner.",
          "parameters": [
            {
              "name": "X-Request-Id",
              "in": "header",
              "required": false,
              "description": "Echoed back; a uuid4 is generated when absent.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Actor",
              "in": "header",
              "required": false,
              "description": "Advisory only. Authenticated routes use the bearer token actor as the authoritative actor.",
              "schema": {
                "type": "string",
                "default": "anonymous"
              }
            },
            {
              "name": "Idempotency-Key",
              "in": "header",
              "required": true,
              "description": "uuid. Retry with the same key replays the cached clusterctl result (idempotent-replay: true); reuse for a different operation/target is a 409 conflict. Dedupe is clusterctl's own idempotency store.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Human-Approval",
              "in": "header",
              "required": false,
              "description": "Base64url clusterd-human-approval/v1 artifact. Required for steward@* execution and signed by a separately provisioned human authority over the exact 409 intent. Caller attendance headers carry no authority.",
              "schema": {
                "type": "string",
                "maxLength": 16384
              }
            },
            {
              "name": "X-Confirm",
              "in": "header",
              "required": false,
              "description": "'none' executes non-destructive mutations (start/stop/restart) directly. Destructive-class routes ALWAYS require a confirmation token regardless.",
              "schema": {
                "type": "string",
                "enum": [
                  "none"
                ]
              }
            }
          ],
          "security": [
            {
              "bearerAuth": []
            }
          ],
          "responses": {
            "200": {
              "description": "clusterctl result JSON (exit 0)"
            },
            "401": {
              "description": "missing/unknown/expired/revoked bearer token ({error: unauthorized})",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "403": {
              "description": "authenticated but denied: insufficient scope, not your daimon (owner mismatch), or unattended-steward-denied",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "400": {
              "description": "missing Idempotency-Key",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "409": {
              "description": "conflict (CLI exit 6: idempotency-key reuse, lock held)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "429": {
              "description": "mutation rate limit: 60 mutations/minute per token (sliding window)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "500": {
              "description": "internal error (CLI exit 10)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            }
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "/v1/seed-access": {
        "post": {
          "operationId": "createSeedAccess",
          "summary": "Operator issues a short-lived owner-scoped access token once",
          "description": "Uses `clusterd --token-create` as its source; mutations retain the same clusterctl business-logic boundary while reads may add owner scoping, redaction, observation envelopes, and bounded snapshot pagination.\n\nRequired bearer scope: `seed:write` \u2014 enforced (issue #18). Owner-scoped tokens may only touch daimons whose spec created_by matches the owner.",
          "parameters": [
            {
              "name": "X-Request-Id",
              "in": "header",
              "required": false,
              "description": "Echoed back; a uuid4 is generated when absent.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Actor",
              "in": "header",
              "required": false,
              "description": "Advisory only. Authenticated routes use the bearer token actor as the authoritative actor.",
              "schema": {
                "type": "string",
                "default": "anonymous"
              }
            },
            {
              "name": "X-Human-Approval",
              "in": "header",
              "required": false,
              "description": "Base64url clusterd-human-approval/v1 artifact. Required for steward@* execution and signed by a separately provisioned human authority over the exact 409 intent. Caller attendance headers carry no authority.",
              "schema": {
                "type": "string",
                "maxLength": 16384
              }
            },
            {
              "name": "X-Confirm",
              "in": "header",
              "required": false,
              "description": "'none' executes non-destructive mutations (start/stop/restart) directly. Destructive-class routes ALWAYS require a confirmation token regardless.",
              "schema": {
                "type": "string",
                "enum": [
                  "none"
                ]
              }
            }
          ],
          "security": [
            {
              "bearerAuth": []
            }
          ],
          "responses": {
            "200": {
              "description": "clusterctl result JSON (exit 0)"
            },
            "401": {
              "description": "missing/unknown/expired/revoked bearer token ({error: unauthorized})",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "403": {
              "description": "authenticated but denied: insufficient scope, not your daimon (owner mismatch), or unattended-steward-denied",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "409": {
              "description": "conflict (CLI exit 6: idempotency-key reuse, lock held)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "429": {
              "description": "mutation rate limit: 60 mutations/minute per token (sliding window)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "500": {
              "description": "internal error (CLI exit 10)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            }
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "/v1/seeds/{seed}/archive": {
        "post": {
          "operationId": "uploadSeed",
          "summary": "Stream a bounded private archive with SHA-256",
          "description": "Uses `clusterctl seed upload` as its source; mutations retain the same clusterctl business-logic boundary while reads may add owner scoping, redaction, observation envelopes, and bounded snapshot pagination.\n\nRequired bearer scope: `seed:write` \u2014 enforced (issue #18). Owner-scoped tokens may only touch daimons whose spec created_by matches the owner.",
          "parameters": [
            {
              "name": "X-Request-Id",
              "in": "header",
              "required": false,
              "description": "Echoed back; a uuid4 is generated when absent.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Actor",
              "in": "header",
              "required": false,
              "description": "Advisory only. Authenticated routes use the bearer token actor as the authoritative actor.",
              "schema": {
                "type": "string",
                "default": "anonymous"
              }
            },
            {
              "name": "seed",
              "in": "path",
              "required": true,
              "schema": {
                "type": "string"
              }
            },
            {
              "name": "X-Archive-SHA256",
              "in": "header",
              "required": true,
              "schema": {
                "type": "string",
                "pattern": "^[0-9a-f]{64}$"
              }
            },
            {
              "name": "X-Human-Approval",
              "in": "header",
              "required": false,
              "description": "Base64url clusterd-human-approval/v1 artifact. Required for steward@* execution and signed by a separately provisioned human authority over the exact 409 intent. Caller attendance headers carry no authority.",
              "schema": {
                "type": "string",
                "maxLength": 16384
              }
            },
            {
              "name": "X-Confirm",
              "in": "header",
              "required": false,
              "description": "'none' executes non-destructive mutations (start/stop/restart) directly. Destructive-class routes ALWAYS require a confirmation token regardless.",
              "schema": {
                "type": "string",
                "enum": [
                  "none"
                ]
              }
            }
          ],
          "security": [
            {
              "bearerAuth": []
            }
          ],
          "responses": {
            "200": {
              "description": "clusterctl result JSON (exit 0)"
            },
            "401": {
              "description": "missing/unknown/expired/revoked bearer token ({error: unauthorized})",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "403": {
              "description": "authenticated but denied: insufficient scope, not your daimon (owner mismatch), or unattended-steward-denied",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "404": {
              "description": "not found (CLI exit 3)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "409": {
              "description": "conflict (CLI exit 6: idempotency-key reuse, lock held)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "429": {
              "description": "mutation rate limit: 60 mutations/minute per token (sliding window)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "500": {
              "description": "internal error (CLI exit 10)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            }
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      },
      "/v1/seeds/{seed}/selection": {
        "get": {
          "operationId": "discoverSeed",
          "summary": "Verify and discover private receiving candidates",
          "description": "Uses `clusterctl seed discover` as its source; mutations retain the same clusterctl business-logic boundary while reads may add owner scoping, redaction, observation envelopes, and bounded snapshot pagination.\n\nRequired bearer scope: `seed:write` \u2014 enforced (issue #18). Owner-scoped tokens may only touch daimons whose spec created_by matches the owner.",
          "parameters": [
            {
              "name": "X-Request-Id",
              "in": "header",
              "required": false,
              "description": "Echoed back; a uuid4 is generated when absent.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Actor",
              "in": "header",
              "required": false,
              "description": "Advisory only. Authenticated routes use the bearer token actor as the authoritative actor.",
              "schema": {
                "type": "string",
                "default": "anonymous"
              }
            },
            {
              "name": "seed",
              "in": "path",
              "required": true,
              "schema": {
                "type": "string"
              }
            }
          ],
          "security": [
            {
              "bearerAuth": []
            }
          ],
          "responses": {
            "200": {
              "description": "clusterctl result JSON (exit 0)"
            },
            "401": {
              "description": "missing/unknown/expired/revoked bearer token ({error: unauthorized})",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "403": {
              "description": "authenticated but denied: insufficient scope, not your daimon (owner mismatch), or unattended-steward-denied",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "404": {
              "description": "not found (CLI exit 3)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "500": {
              "description": "internal error (CLI exit 10)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            }
          }
        }
      },
      "/v1/seeds/{seed}/prepare": {
        "post": {
          "operationId": "prepareSeed",
          "summary": "Preserve originals and prepare receiving context",
          "description": "Uses `clusterctl seed prepare` as its source; mutations retain the same clusterctl business-logic boundary while reads may add owner scoping, redaction, observation envelopes, and bounded snapshot pagination.\n\nRequired bearer scope: `seed:write` \u2014 enforced (issue #18). Owner-scoped tokens may only touch daimons whose spec created_by matches the owner.",
          "parameters": [
            {
              "name": "X-Request-Id",
              "in": "header",
              "required": false,
              "description": "Echoed back; a uuid4 is generated when absent.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Actor",
              "in": "header",
              "required": false,
              "description": "Advisory only. Authenticated routes use the bearer token actor as the authoritative actor.",
              "schema": {
                "type": "string",
                "default": "anonymous"
              }
            },
            {
              "name": "seed",
              "in": "path",
              "required": true,
              "schema": {
                "type": "string"
              }
            },
            {
              "name": "X-Human-Approval",
              "in": "header",
              "required": false,
              "description": "Base64url clusterd-human-approval/v1 artifact. Required for steward@* execution and signed by a separately provisioned human authority over the exact 409 intent. Caller attendance headers carry no authority.",
              "schema": {
                "type": "string",
                "maxLength": 16384
              }
            },
            {
              "name": "X-Confirm",
              "in": "header",
              "required": false,
              "description": "'none' executes non-destructive mutations (start/stop/restart) directly. Destructive-class routes ALWAYS require a confirmation token regardless.",
              "schema": {
                "type": "string",
                "enum": [
                  "none"
                ]
              }
            }
          ],
          "security": [
            {
              "bearerAuth": []
            }
          ],
          "responses": {
            "200": {
              "description": "clusterctl result JSON (exit 0)"
            },
            "401": {
              "description": "missing/unknown/expired/revoked bearer token ({error: unauthorized})",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "403": {
              "description": "authenticated but denied: insufficient scope, not your daimon (owner mismatch), or unattended-steward-denied",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "404": {
              "description": "not found (CLI exit 3)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "409": {
              "description": "conflict (CLI exit 6: idempotency-key reuse, lock held)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "429": {
              "description": "mutation rate limit: 60 mutations/minute per token (sliding window)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "500": {
              "description": "internal error (CLI exit 10)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            }
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      },
      "/v1/seeds/{seed}/connections": {
        "post": {
          "operationId": "seedConnections",
          "summary": "Store private bot data and a public SSH key",
          "description": "Uses `clusterctl seed connections` as its source; mutations retain the same clusterctl business-logic boundary while reads may add owner scoping, redaction, observation envelopes, and bounded snapshot pagination.\n\nRequired bearer scope: `seed:write` \u2014 enforced (issue #18). Owner-scoped tokens may only touch daimons whose spec created_by matches the owner.",
          "parameters": [
            {
              "name": "X-Request-Id",
              "in": "header",
              "required": false,
              "description": "Echoed back; a uuid4 is generated when absent.",
              "schema": {
                "type": "string",
                "format": "uuid"
              }
            },
            {
              "name": "X-Actor",
              "in": "header",
              "required": false,
              "description": "Advisory only. Authenticated routes use the bearer token actor as the authoritative actor.",
              "schema": {
                "type": "string",
                "default": "anonymous"
              }
            },
            {
              "name": "seed",
              "in": "path",
              "required": true,
              "schema": {
                "type": "string"
              }
            },
            {
              "name": "X-Human-Approval",
              "in": "header",
              "required": false,
              "description": "Base64url clusterd-human-approval/v1 artifact. Required for steward@* execution and signed by a separately provisioned human authority over the exact 409 intent. Caller attendance headers carry no authority.",
              "schema": {
                "type": "string",
                "maxLength": 16384
              }
            },
            {
              "name": "X-Confirm",
              "in": "header",
              "required": false,
              "description": "'none' executes non-destructive mutations (start/stop/restart) directly. Destructive-class routes ALWAYS require a confirmation token regardless.",
              "schema": {
                "type": "string",
                "enum": [
                  "none"
                ]
              }
            }
          ],
          "security": [
            {
              "bearerAuth": []
            }
          ],
          "responses": {
            "200": {
              "description": "clusterctl result JSON (exit 0)"
            },
            "401": {
              "description": "missing/unknown/expired/revoked bearer token ({error: unauthorized})",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "403": {
              "description": "authenticated but denied: insufficient scope, not your daimon (owner mismatch), or unattended-steward-denied",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "404": {
              "description": "not found (CLI exit 3)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "409": {
              "description": "conflict (CLI exit 6: idempotency-key reuse, lock held)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "429": {
              "description": "mutation rate limit: 60 mutations/minute per token (sliding window)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            },
            "500": {
              "description": "internal error (CLI exit 10)",
              "content": {
                "application/json": {
                  "schema": {
                    "$ref": "#/components/schemas/ErrorEnvelope"
                  }
                }
              }
            }
          },
          "requestBody": {
            "required": true,
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "components": {
      "schemas": {
        "ErrorEnvelope": {
          "type": "object",
          "required": [
            "error",
            "action",
            "target",
            "request_id"
          ],
          "properties": {
            "error": {
              "type": "string"
            },
            "action": {
              "type": "string"
            },
            "target": {
              "type": "string"
            },
            "request_id": {
              "type": "string",
              "format": "uuid"
            }
          }
        },
        "SnapshotPage": {
          "type": "object",
          "required": [
            "schema",
            "items",
            "page"
          ],
          "properties": {
            "schema": {
              "type": "string",
              "enum": [
                "clusterd-page/v1"
              ]
            },
            "items": {
              "type": "array",
              "items": {
                "type": "object"
              }
            },
            "page": {
              "type": "object",
              "required": [
                "limit",
                "count",
                "has_more",
                "next_cursor",
                "snapshot_id",
                "observed_at_ms",
                "expires_in_s",
                "truncated"
              ],
              "properties": {
                "limit": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 200
                },
                "count": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 200
                },
                "has_more": {
                  "type": "boolean"
                },
                "next_cursor": {
                  "type": "string",
                  "nullable": true
                },
                "snapshot_id": {
                  "type": "string"
                },
                "observed_at_ms": {
                  "type": "integer"
                },
                "expires_in_s": {
                  "type": "integer",
                  "minimum": 0
                },
                "truncated": {
                  "type": "boolean"
                }
              }
            }
          }
        },
        "ConfirmationChallenge": {
          "type": "object",
          "required": [
            "schema",
            "token",
            "operation",
            "target",
            "actor",
            "action_digest",
            "created_ms",
            "ttl_s"
          ],
          "properties": {
            "schema": {
              "type": "string",
              "enum": [
                "confirmation/v1"
              ]
            },
            "token": {
              "type": "string",
              "description": "single-use; send back as X-Confirm-Token"
            },
            "operation": {
              "type": "string"
            },
            "target": {
              "type": "string"
            },
            "actor": {
              "type": "string"
            },
            "action_digest": {
              "type": "string",
              "description": "sha256 of canonical JSON {operation,target,actor,args} \u2014 binds the confirmation to exactly that action"
            },
            "created_ms": {
              "type": "integer"
            },
            "ttl_s": {
              "type": "integer",
              "default": 900
            }
          }
        }
      },
      "securitySchemes": {
        "bearerAuth": {
          "type": "http",
          "scheme": "bearer",
          "description": "Scoped bearer token, format dcd_<uuid4hex> (issue #18, design \u00a72/\u00a73). ENFORCED: tokens are sha256-hashed at rest in state_dir/auth/tokens.json (auth-token/v1); manage via `scripts/clusterd --token-create | --token-revoke | --token-list`. Scopes are exact operation classes (fleet:read, lifecycle:write, backup:write, etc.). Owner-scoped tokens may only touch their own daimons. Revocation takes effect without restart. Every route except GET /v1/health requires a token (default-deny)."
        }
      }
    }
  }
}