openapi: 3.0.1
info:
  title: Wizard Fortress Proposal Port
  description: |
    Open-source GPT Action for Wizard Fortress.
    Submit a proposal. Receive a digest-bound object in AWAITING_HUMAN_APPROVAL.
    This API cannot execute, approve, apply, or reach local Ara.
  version: "1.0.0"
  contact:
    name: Wizard Fortress
    url: https://www.wizard-fortress.com/security/
  license:
    name: MIT
    url: https://www.wizard-fortress.com/
servers:
  - url: https://www.wizard-fortress.com
    description: Public proposal gate
paths:
  /api/health:
    get:
      operationId: getHealth
      summary: Liveness and mode
      description: Returns build identity and confirms execution is disabled.
      responses:
        "200":
          description: Gate is up
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Health"
  /api/v1/proposal:
    post:
      operationId: submitProposal
      summary: Submit a proposal packet
      description: |
        Accepts untrusted task text. Returns an immutable proposal.
        Status is always AWAITING_HUMAN_APPROVAL. Nothing is executed.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProposalRequest"
      responses:
        "200":
          description: Proposal recorded as awaiting human approval
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Proposal"
        "400":
          description: Malformed or over-budget packet
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "403":
          description: Forbidden operation or disabled worker
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/proposal/{id}:
    get:
      operationId: getProposal
      summary: Read a proposal the client already holds
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            maxLength: 128
      responses:
        "200":
          description: Proposal
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Proposal"
        "404":
          description: Unknown or expired ephemeral proposal
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  schemas:
    Health:
      type: object
      required: [ok, service, mode, execute]
      properties:
        ok:
          type: boolean
        service:
          type: string
        mode:
          type: string
          enum: [proposal_only]
        execute:
          type: string
          enum: [disabled]
        build:
          type: string
    ProposalRequest:
      type: object
      required: [task]
      properties:
        task:
          type: string
          minLength: 1
          maxLength: 8000
          description: What the human should review. Not a permission.
        context:
          type: string
          maxLength: 8000
        worker:
          type: string
          description: Ignored unless exactly mock
          default: mock
    Proposal:
      type: object
      required: [id, status, digest, execute, worker]
      properties:
        id:
          type: string
        status:
          type: string
          enum: [AWAITING_HUMAN_APPROVAL]
        digest:
          type: string
          description: SHA-256 hex of canonical proposal bytes
        execute:
          type: string
          enum: [disabled]
        worker:
          type: string
        task:
          type: string
        created_at:
          type: string
          format: date-time
        note:
          type: string
    Error:
      type: object
      required: [error, execute]
      properties:
        error:
          type: string
        execute:
          type: string
          enum: [disabled]
        detail:
          type: string
