openapi: 3.0.3
info:
  title: SOAT Formations API
  version: 1.0.0
  description: >
    API for managing Formations — a CloudFormation-inspired declarative
    deployment layer that lets you describe an entire AI agent stack in a
    single template and deploy it with one API call.
  contact:
    name: SOAT Team
    url: https://github.com/ttoss/soat
servers:
  - url: '{baseUrl}'
    description: Base URL of your SOAT deployment (e.g. https://your-soat.com or http://localhost:5047)
    variables:
      baseUrl:
        description: The base URL of your SOAT deployment
        default: http://localhost:5047
tags:
  - name: Formations
    description: Manage declarative formation stacks
security:
  - bearerAuth: []
paths:
  /api/v1/formations/validate:
    post:
      tags:
        - Formations
      summary: Validate a formation template
      description: >
        Validates a formation template without creating any resources.
        Returns a list of errors and warnings. Accepts the template as a
        JSON object or as a YAML/JSON string.
      operationId: validateFormation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                template:
                  $ref: '#/components/schemas/FormationTemplateInput'
                parameters:
                  type: object
                  additionalProperties:
                    type: string
                  description: >
                    Runtime parameter values that override or supply template
                    parameter defaults. Keys must match parameter names declared
                    in `template.parameters`. When provided, the validation
                    result also reports required parameters that are still
                    missing after applying these values.
                  nullable: true
      responses:
        '200':
          description: Validation result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationResult'
        '401':
          description: Unauthorized

  /api/v1/formations/plan:
    post:
      tags:
        - Formations
      summary: Plan a formation deployment
      description: >
        Computes a diff between the desired template and the current stack state
        without making any changes. Returns the list of planned actions.
      operationId: planFormation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - template
              properties:
                project_id:
                  x-soat-ref: projects
                  type: string
                  description: Project ID. Optional when authenticating with a project-scoped API key, which defaults to the key's project; required otherwise.
                  example: proj_V1StGXR8Z5jdHi6B
                formation_id:
                  x-soat-ref: formations
                  type: string
                  description: >-
                    Existing formation ID to compare against. Omit for new
                    formation planning.
                template:
                  $ref: '#/components/schemas/FormationTemplateInput'
                parameters:
                  type: object
                  additionalProperties:
                    type: string
                  description: >
                    Runtime parameter values that override or supply template
                    parameter defaults. Keys must match parameter names declared
                    in `template.parameters`. A parameter declared with
                    `use_previous_value: true` may be omitted to reuse its
                    stored value.
                  nullable: true
      responses:
        '200':
          description: Plan result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlanResult'
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden

  /api/v1/formations:
    get:
      tags:
        - Formations
      summary: List formations
      description: Returns all formation stacks for a project
      operationId: listFormations
      parameters:
        - name: project_id
          in: query
          description: Project ID (required if not using project key auth)
          schema:
            type: string
            example: proj_V1StGXR8Z5jdHi6B
      responses:
        '200':
          description: List of formations
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Formation'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden

    post:
      tags:
        - Formations
      summary: Create a new formation
      description: >
        Validates the template, creates the formation record, then provisions
        all declared resources in dependency order.
      operationId: createFormation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
                - template
              properties:
                project_id:
                  x-soat-ref: projects
                  type: string
                  description: Project ID. Optional when authenticating with a project-scoped API key, which defaults to the key's project; required otherwise.
                  example: proj_V1StGXR8Z5jdHi6B
                name:
                  type: string
                  description: Human-readable name for the formation stack
                  example: my-agent-stack
                template:
                  $ref: '#/components/schemas/FormationTemplateInput'
                parameters:
                  type: object
                  additionalProperties:
                    type: string
                  description: >
                    Runtime parameter values that override or supply template
                    parameter defaults. Keys must match parameter names declared
                    in `template.parameters`. Required parameters (those without
                    a default) must be provided here.
                  nullable: true
                metadata:
                  type: object
                  additionalProperties: true
                  nullable: true
      responses:
        '201':
          description: Formation created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Formation'
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '409':
          description: Formation with this name already exists

  /api/v1/formations/{formation_id}:
    get:
      tags:
        - Formations
      summary: Get a specific formation
      description: Returns the formation stack including its current resources.
      operationId: getFormation
      parameters:
        - name: formation_id
          in: path
          required: true
          schema:
            type: string
          example: form_V1StGXR8Z5jdHi6B
      responses:
        '200':
          description: Formation details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Formation'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not Found

    put:
      tags:
        - Formations
      summary: Update an formation
      description: >
        Applies a new template to the formation. Resources are created,
        updated, or deleted to reconcile the current state with the desired
        state.
      operationId: updateFormation
      parameters:
        - name: formation_id
          in: path
          required: true
          schema:
            type: string
          example: form_V1StGXR8Z5jdHi6B
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                template:
                  $ref: '#/components/schemas/FormationTemplateInput'
                parameters:
                  type: object
                  additionalProperties:
                    type: string
                  description: >
                    Runtime parameter values that override or supply template
                    parameter defaults. Keys must match parameter names declared
                    in `template.parameters`. Required parameters (those without
                    a default) must be provided here, unless the parameter is
                    declared with `use_previous_value: true`, in which case
                    omitting it reuses the previously stored value.
                  nullable: true
                metadata:
                  type: object
                  additionalProperties: true
                  nullable: true
      responses:
        '200':
          description: Updated formation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Formation'
        '400':
          description: Bad Request
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not Found

    delete:
      tags:
        - Formations
      summary: Delete an formation
      description: >
        Deletes the formation stack and all its managed resources in reverse
        dependency order.
      operationId: deleteFormation
      parameters:
        - name: formation_id
          in: path
          required: true
          schema:
            type: string
          example: form_V1StGXR8Z5jdHi6B
      responses:
        '200':
          description: Deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                required:
                  - success
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not Found

  /api/v1/formations/{formation_id}/events:
    get:
      tags:
        - Formations
      summary: List formation operation events
      description: >
        Returns all operations (create, update, delete) with their event logs
        for the formation, ordered chronologically.
      operationId: listFormationEvents
      parameters:
        - name: formation_id
          in: path
          required: true
          schema:
            type: string
          example: form_V1StGXR8Z5jdHi6B
      responses:
        '200':
          description: List of operations
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/FormationOperation'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Not Found

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  schemas:
    FormationTemplateInput:
      description: >
        A formation template supplied as either a JSON object or a YAML/JSON
        string. When a string is provided the server parses it with a YAML
        parser (JSON is valid YAML) before processing.
      oneOf:
        - $ref: '#/components/schemas/FormationTemplate'
        - type: string
          description: YAML or JSON string representation of a FormationTemplate

    FormationTemplate:
      type: object
      required:
        - resources
      properties:
        parameters:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ParameterDeclaration'
          description: >
            Declared parameters for this template. Each parameter may have a
            default value and an optional description. Parameters without a
            default must be supplied in the `parameters` field of the deploy
            request.
          nullable: true
        resources:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ResourceDeclaration'
          description: Map of logical resource IDs to resource declarations
        outputs:
          type: object
          additionalProperties: true
          description: >
            Map of output names to values. Values may use `{ "ref": "logicalId" }`
            to reference physical IDs of created resources, or `{ "param": "ParamName" }`
            and `{ "sub": "text ${ParamName}" }` to embed parameter values.
          nullable: true
        metadata:
          type: object
          additionalProperties: true
          nullable: true

    ParameterDeclaration:
      type: object
      properties:
        type:
          type: string
          description: Parameter type (currently only 'string' is supported)
          example: string
        default:
          type: string
          description: Default value used when the parameter is not supplied at deploy time
          nullable: true
        description:
          type: string
          description: Human-readable description of what this parameter represents
          nullable: true
        no_echo:
          type: boolean
          description: >
            When true, the parameter value should be treated as sensitive and
            not echoed in logs or UI. Analogous to NoEcho in CloudFormation.
          nullable: true
        use_previous_value:
          type: boolean
          description: >
            When true, omitting this parameter on update reuses its previously
            stored value instead of failing the required-parameter check —
            analogous to CloudFormation's UsePreviousValue, declared in the
            template. An explicitly supplied value still overrides. Has no
            effect on create (there is no previous value yet). The value is
            reused only where the underlying resource retains it (e.g. a
            secret's encrypted value); otherwise the last-applied value is used.
          nullable: true

    AgentResourceProperties:
      description: >-
        Creates an AI agent backed by a provider. The agent handles requests,
        runs tools, and can be attached to actors.
      type: object
      additionalProperties: false
      required:
        - ai_provider_id
      properties:
        ai_provider_id:
          x-soat-ref: ai-providers
          type: string
          description: Public ID of the AI provider
        name:
          type: string
          nullable: true
          description: Agent display name
        instructions:
          type: string
          nullable: true
          description: System instructions for the agent
        model:
          type: string
          nullable: true
          description: Model identifier (overrides provider default)
        tool_ids:
          x-soat-ref: tools
          type: array
          nullable: true
          items:
            type: string
          description: Agent tool IDs to attach
        max_steps:
          type: integer
          nullable: true
          description: Maximum number of agentic steps per generation
        tool_choice:
          nullable: true
          description: 'Controls how the model selects tools. Accepts a string (`"auto"`, `"required"`) or an object (`{ "type": "tool", "name": "my_tool" }`).'
        stop_conditions:
          type: array
          nullable: true
          description: Conditions that stop multi-step generation early. The loop stops when any condition is met.
          items:
            type: object
            properties:
              type:
                type: string
                description: 'Condition type — currently `hasToolCall`'
              tool_name:
                type: string
                nullable: true
                description: Tool name to match when type is `hasToolCall`
        active_tool_ids:
          x-soat-ref: tools
          type: array
          nullable: true
          items:
            type: string
          description: Subset of tool_ids that are active
        step_rules:
          type: array
          nullable: true
          description: Per-step overrides applied during multi-step generation. Steps not covered by a rule use the agent defaults.
          items:
            type: object
            properties:
              step:
                type: integer
                description: 1-indexed step number this rule applies to
              tool_choice:
                type: object
                nullable: true
                description: 'Tool choice override for this step, e.g. `auto`, `required`, or `{ type: tool, tool_name: search }`'
              active_tool_ids:
                x-soat-ref: tools
                type: array
                nullable: true
                items:
                  type: string
                description: Tool IDs active on this step
        boundary_policy:
          type: object
          nullable: true
          description: Restricts which SOAT actions the agent may invoke. Evaluated as the intersection with the caller's own policy.
          properties:
            statement:
              type: array
              description: List of IAM policy statements
              items:
                type: object
                properties:
                  effect:
                    type: string
                    description: 'Effect — `Allow` or `Deny`'
                  action:
                    type: array
                    items:
                      type: string
                    description: IAM action strings, e.g. `memories:*` or `agents:DeleteAgent`
                  resource:
                    type: array
                    nullable: true
                    items:
                      type: string
                    description: Resource SRN patterns (optional; omit to match all resources)
        temperature:
          type: number
          nullable: true
          description: Sampling temperature
        max_context_messages:
          type: integer
          nullable: true
          description: Maximum number of recent messages to include in the context window sent to the model. When null, all messages are included.
        single_session_per_actor:
          type: boolean
          nullable: true
          description: When true, only one open session per actor_id is allowed for this agent.
        knowledge_config:
          type: object
          nullable: true
          description: Knowledge retrieval configuration. When set, relevant documents and memory entries are injected into every generation.
          properties:
            memory_ids:
              x-soat-ref: memories
              type: array
              items:
                type: string
              description: Public IDs of memories to retrieve from
            memory_tags:
              type: array
              items:
                type: string
              description: Retrieve from all memories matching these tags
            document_ids:
              x-soat-ref: documents
              type: array
              items:
                type: string
              description: Public IDs of documents to retrieve from
            document_paths:
              type: array
              items:
                type: string
              description: Retrieve from all documents matching these path prefixes
            min_score:
              type: number
              description: Minimum similarity score (0–1) for retrieved chunks
            limit:
              type: integer
              description: Maximum number of chunks to inject
            write_memory_id:
              x-soat-ref: memories
              type: string
              nullable: true
              description: Public ID of the memory the agent can write to. When set, a `write_memory` tool is automatically available to the agent.
            extraction:
              description: Automatic fact extraction from completed generation turns (requires write_memory_id). Pass `true` to enable with defaults, or an object to customize the provider, model, and prompt used for the extraction completion.
              oneOf:
                - type: boolean
                - type: object
                  properties:
                    enabled:
                      type: boolean
                      description: Defaults to true when the object form is used. Set false to keep the configuration but disable extraction.
                    ai_provider_id:
                      x-soat-ref: ai-providers
                      type: string
                      description: AI provider override for extraction calls. Must belong to the agent's project. Its default_model becomes the model fallback.
                    model:
                      type: string
                      description: Model override for extraction calls.
                    prompt:
                      type: string
                      description: Replaces the default task instructions. The JSON response contract and the conversation transcript are always appended by the server.
        output_schema:
          type: object
          nullable: true
          description: JSON Schema describing the structured object the model must return. Non-streaming generations are constrained to this schema; the parsed value is returned as `output.object`.

    ActorResourceProperties:
      description: >-
        Creates a stateful conversation actor that wraps an agent or chat
        session and optionally links to a memory store.
      type: object
      additionalProperties: false
      required:
        - name
      properties:
        name:
          type: string
          description: Actor display name
        external_id:
          type: string
          nullable: true
          description: External identifier for idempotent actor creation
        instructions:
          type: string
          nullable: true
          description: Persona-specific instructions
        agent_id:
          x-soat-ref: agents
          type: string
          nullable: true
          description: Linked agent ID (mutually exclusive with chat_id)
        chat_id:
          x-soat-ref: chats
          type: string
          nullable: true
          description: Linked chat ID (mutually exclusive with agent_id)
        memory_id:
          x-soat-ref: memories
          type: string
          nullable: true
          description: Linked memory ID
        auto_create_memory:
          type: boolean
          description: Whether to auto-create memory when actor is created

    AiProviderResourceProperties:
      description: >-
        Configures an LLM provider connection (API key, model, endpoint)
        that agents use to generate responses.
      type: object
      additionalProperties: false
      required:
        - name
        - provider
        - default_model
      properties:
        name:
          type: string
          description: Provider display name
        provider:
          type: string
          description: Provider type (e.g. openai, anthropic)
        default_model:
          type: string
          description: Default model identifier (e.g. gpt-4o, claude-3-7-sonnet)
        secret_id:
          x-soat-ref: secrets
          type: string
          nullable: true
          description: Public ID of the secret containing the API key
        base_url:
          type: string
          nullable: true
          description: Custom base URL for the provider API (self-hosted or proxy)
        config:
          type: object
          nullable: true
          description: Provider-specific extra configuration

    ToolResourceProperties:
      description: >-
        Defines a tool (HTTP endpoint, MCP server, SOAT action, or pipeline)
        that agents can invoke during a generation.
      type: object
      additionalProperties: false
      required:
        - name
      properties:
        name:
          type: string
          description: Tool display name
        type:
          type: string
          nullable: true
          description: Tool type hint (e.g. http, mcp, soat, pipeline)
        description:
          type: string
          nullable: true
          description: Tool description shown to the model
        parameters:
          type: object
          nullable: true
          description: JSON Schema describing the tool's input parameters (free-form, user-defined)
        execute:
          type: object
          nullable: true
          description: HTTP execution configuration. Required for `http` tools.
          properties:
            url:
              type: string
              description: 'Endpoint URL. Supports `{param}` placeholders resolved from tool arguments.'
            method:
              type: string
              nullable: true
              description: 'HTTP method (default: `POST`)'
            headers:
              type: object
              nullable: true
              description: Static headers included in every request
        mcp:
          type: object
          nullable: true
          description: MCP server connection configuration. Required for `mcp` tools.
          properties:
            url:
              type: string
              description: MCP server URL
            headers:
              type: object
              nullable: true
              description: Headers included in every MCP request
        actions:
          type: array
          nullable: true
          items:
            type: string
          description: >-
            Allowlist of actions the tool exposes. For `soat` tools: SOAT
            platform action names. For `mcp` tools: an optional allowlist of MCP
            tool names to scope the server surface (`null` exposes every tool).
        preset_parameters:
          type: object
          nullable: true
          description: Pre-filled parameter values injected at execution time
        pipeline:
          type: object
          nullable: true
          description: >-
            Pipeline definition for `pipeline` tools: an ordered `steps` array,
            each invoking another tool by `tool_id` (optional `action`) with an
            `input` built from earlier results via JSON Logic over
            `{ input, steps }`, plus an optional `output` mapping. Step `input`
            keys and `var` paths use camelCase (the runtime form). Free-form,
            user-defined.
        discussion_id:
          type: string
          nullable: true
          description: >-
            For `discussion` tools: the ID of the discussion to invoke.
        output_mapping:
          type: object
          nullable: true
          description: >-
            Universal JSON Logic mapping applied to the tool's raw result, for
            every tool type. Evaluated over `{ output: <raw result> }`, e.g.
            `{ "var": "output.text" }`. For `pipeline` tools this runs after
            the pipeline's own `output` mapping.

    DocumentResourceProperties:
      description: >-
        Stores a text document in a project, optionally indexing it for
        knowledge retrieval.
      type: object
      additionalProperties: false
      required:
        - content
      properties:
        content:
          type: string
          description: Document text content
        path:
          type: string
          nullable: true
          description: Virtual path for organising the document
        filename:
          type: string
          nullable: true
          description: Original filename
        title:
          type: string
          nullable: true
          description: Document title
        metadata:
          type: object
          nullable: true
          description: Arbitrary metadata key-value pairs
        tags:
          type: object
          nullable: true
          description: Tag key-value pairs for filtering

    MemoryResourceProperties:
      description: >-
        Creates a named memory store that actors can read from and write to
        across conversations.
      type: object
      additionalProperties: false
      required:
        - name
      properties:
        name:
          type: string
          description: Memory display name
        description:
          type: string
          nullable: true
          description: What this memory stores
        tags:
          type: array
          nullable: true
          items:
            type: string
          description: Tag strings for filtering

    MemoryEntryResourceProperties:
      description: Adds a single text entry to a memory store.
      type: object
      additionalProperties: false
      required:
        - memory_id
        - content
      properties:
        memory_id:
          x-soat-ref: memories
          type: string
          description: Public ID of the parent memory (or ref expression)
        content:
          type: string
          description: Text content of the memory entry
        source_type:
          type: string
          enum: [manual, agent, extraction]
          nullable: true
          description: How this entry was created (defaults to manual)

    WebhookResourceProperties:
      description: >-
        Registers an HTTPS endpoint to receive SOAT platform event
        notifications.
      type: object
      additionalProperties: false
      required:
        - name
        - url
        - events
      properties:
        name:
          type: string
          description: Webhook display name
        description:
          type: string
          nullable: true
          description: Optional description
        url:
          type: string
          description: HTTPS endpoint that receives event payloads
        events:
          type: array
          items:
            type: string
          description: Event types to subscribe to (e.g. memory.updated)

    TriggerResourceProperties:
      description: >-
        Binds a starter (manual, webhook, or schedule) to an executable target
        (orchestration, agent, or tool). Firings run under the project owner's
        confined run-as identity.
      type: object
      additionalProperties: false
      required:
        - name
        - type
        - target_type
        - target_id
      properties:
        name:
          type: string
          description: Trigger display name (unique within the project)
        description:
          type: string
          nullable: true
          description: Optional description
        type:
          type: string
          enum:
            - manual
            - webhook
            - schedule
          description: Starter type. Immutable after creation
        target_type:
          type: string
          enum:
            - orchestration
            - agent
            - tool
          description: The kind of resource this trigger activates
        target_id:
          type: string
          description: >-
            Public ID of the target resource. Use { "ref": "LogicalId" } to
            reference an orchestration, agent, or tool defined in the template.
        action:
          type: string
          nullable: true
          description: Tool targets only — the action for soat/mcp tools
        input:
          type: object
          nullable: true
          description: Static input shallow-merged under each firing's runtime input
        cron:
          type: string
          nullable: true
          description: 5-field cron expression (UTC). Required when type is schedule
        active:
          type: boolean
          description: Whether the trigger fires (default true)
        policy_id:
          x-soat-ref: policies
          type: string
          nullable: true
          description: >-
            Optional boundary policy that further confines the run-as identity

    ApiKeyResourceProperties:
      description: >-
        Creates an API key scoped to the formation's project and optionally
        restricted by a set of policies. The key is owned by the project owner.
      type: object
      additionalProperties: false
      required:
        - name
      properties:
        name:
          type: string
          description: Human-readable label for the API key
        policy_ids:
          x-soat-ref: policies
          type: array
          items:
            type: string
          description: >-
            Optional list of policy public IDs that further restrict the key's
            permissions

    ChatResourceProperties:
      description: >-
        Creates a chat connected to an AI provider within the formation's project.
      type: object
      additionalProperties: false
      required:
        - ai_provider_id
      properties:
        ai_provider_id:
          x-soat-ref: ai-providers
          type: string
          description: Public ID of the AI provider to use for this chat
        name:
          type: string
          nullable: true
          description: Human-readable label for the chat
        system_message:
          type: string
          nullable: true
          description: System message to set the assistant behaviour
        model:
          type: string
          nullable: true
          description: Model override; defaults to the AI provider's default model

    ConversationResourceProperties:
      description: >-
        Creates a conversation within the formation's project.
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          nullable: true
          description: Human-readable label for the conversation
        status:
          type: string
          description: Initial status of the conversation (open or closed)
        actor_id:
          x-soat-ref: actors
          type: string
          nullable: true
          description: Public ID of an actor to associate with this conversation

    DiscussionResourceProperties:
      description: >-
        Declares a discussion (deliberation config) within the formation's
        project. Providing participants replaces the full set on update.
      type: object
      additionalProperties: false
      required:
        - name
        - ai_provider_id
      properties:
        name:
          type: string
          description: Display name of the discussion
        description:
          type: string
          nullable: true
        ai_provider_id:
          x-soat-ref: ai-providers
          type: string
          description: Default AI provider participants and synthesis fall back to
        model:
          type: string
          nullable: true
          description: Default model (falls back to the provider's default_model)
        max_rounds:
          type: integer
          nullable: true
          description: Rounds of deliberation (1–3, default 1)
        synthesis:
          type: object
          nullable: true
          description: Override for the final synthesis pass
        participants:
          type: array
          description: The deliberation participants (max 5)
          items:
            type: object

    FileResourceProperties:
      description: >-
        Registers a file record within the formation's project.
      type: object
      additionalProperties: false
      properties:
        prefix:
          type: string
          nullable: true
          description: Directory within the project. Optional; defaults to / (root). Combined with filename to form the file's key (path).
        filename:
          type: string
          nullable: true
          description: Original / download name and the key's leaf segment.
        content_type:
          type: string
          nullable: true
          description: MIME type of the file
        size:
          type: integer
          nullable: true
          description: File size in bytes
        metadata:
          type: string
          nullable: true
          description: JSON string with additional metadata

    PolicyResourceProperties:
      description: >-
        Creates an access-control policy within the formation's project.
      type: object
      additionalProperties: false
      required:
        - document
      properties:
        name:
          type: string
          nullable: true
          description: Human-readable label for the policy
        description:
          type: string
          nullable: true
          description: Description of what the policy grants
        document:
          type: object
          additionalProperties: true
          description: Policy document containing an array of statements

    SecretResourceProperties:
      description: >-
        Creates an encrypted secret within the formation's project.
      type: object
      additionalProperties: false
      required:
        - name
        - value
      properties:
        name:
          type: string
          description: Human-readable label for the secret
        value:
          type: string
          description: The secret value to encrypt and store

    SessionResourceProperties:
      description: >-
        Creates a session attached to an agent within the formation's project.
      type: object
      additionalProperties: false
      required:
        - agent_id
      properties:
        agent_id:
          x-soat-ref: agents
          type: string
          description: Public ID of the agent that owns this session
        name:
          type: string
          nullable: true
          description: Human-readable label for the session
        actor_id:
          x-soat-ref: actors
          type: string
          nullable: true
          description: Public ID of an actor to associate with this session
        auto_generate:
          type: boolean
          description: Whether to automatically generate a response when messages are sent
        inactivity_ttl_seconds:
          type: integer
          description: Number of seconds of inactivity after which the session expires. 0 means never expires.
        tool_context:
          type: object
          additionalProperties: true
          nullable: true
          description: Optional context object passed to tool calls

    IngestionRuleResourceProperties:
      description: >-
        Routes a file content_type to a converter (tool or agent) so
        ingestion can turn non-native files (images, audio, scanned PDFs)
        into Documents. See the Ingestion Rules module docs for the matching
        and converter-invocation model.
      type: object
      additionalProperties: false
      required:
        - content_type_glob
      properties:
        content_type_glob:
          type: string
          description: MIME type glob matched against a file's content_type (e.g. image/*, audio/mpeg, application/pdf)
        tool_id:
          x-soat-ref: tools
          type: string
          nullable: true
          description: Converter tool ID (mutually exclusive with agent_id)
        agent_id:
          x-soat-ref: agents
          type: string
          nullable: true
          description: Converter agent ID (mutually exclusive with tool_id)
        action:
          type: string
          nullable: true
          description: Operation id, required for soat/mcp tool converters
        preset_parameters:
          type: object
          nullable: true
          description: Merged into the tool input before invocation (tool converters only)
        native_extraction:
          type: string
          nullable: true
          description: >-
            For native types (PDF/text): `first` (default) converts only
            when native extraction yields no text; `skip` always converts.
        file_delivery:
          type: string
          nullable: true
          description: How the file reaches a tool converter — base64 (default) or download_url
        chunk_strategy:
          type: string
          nullable: true
          description: Default chunk strategy (page/whole/size), overridable per ingest request
        chunk_size:
          type: integer
          nullable: true
          description: Default window size in characters for the size strategy
        chunk_overlap:
          type: integer
          nullable: true
          description: Default overlap in characters for the size strategy
        metadata:
          type: object
          nullable: true
          description: Arbitrary JSON metadata

    OrchestrationResourceProperties:
      description: >-
        Creates a DAG orchestration that wires agents, tools, and knowledge
        lookups into a repeatable pipeline within the formation's project. Node
        resource references (`agent_id`, `tool_id`, `memory_id`,
        `orchestration_id`) accept `{ "ref": "LogicalId" }` expressions to point
        at other resources declared in the same template — the basis for
        deploying an agent "squad" (a team of agents plus the flow that
        coordinates them) as a single stack.
      type: object
      additionalProperties: false
      required:
        - name
        - nodes
        - edges
      properties:
        name:
          type: string
          description: Human-readable name for the orchestration
        description:
          type: string
          nullable: true
          description: Optional description of what the orchestration does
        nodes:
          type: array
          description: >-
            Ordered list of node definitions. A node's resource references
            (`agent_id`, `tool_id`, `memory_id`, `orchestration_id`) may use
            `{ "ref": "LogicalId" }` to bind to other resources in the template.
          items:
            type: object
            additionalProperties: true
        edges:
          type: array
          description: Directed connections between nodes
          items:
            type: object
            additionalProperties: true
        state_schema:
          type: object
          nullable: true
          additionalProperties: true
          description: Optional JSON Schema describing the run state
        input_schema:
          type: object
          nullable: true
          additionalProperties: true
          description: Optional JSON Schema describing the run input

    ResourceDeclaration:
      type: object
      required:
        - type
        - properties
      properties:
        type:
          type: string
          enum:
            - ai_provider
            - tool
            - agent
            - actor
            - api_key
            - chat
            - conversation
            - document
            - file
            - ingestion_rule
            - memory
            - memory_entry
            - orchestration
            - policy
            - secret
            - session
            - webhook
            - trigger
          description: Resource type
        properties:
          oneOf:
            - $ref: '#/components/schemas/AgentResourceProperties'
            - $ref: '#/components/schemas/ActorResourceProperties'
            - $ref: '#/components/schemas/AiProviderResourceProperties'
            - $ref: '#/components/schemas/ToolResourceProperties'
            - $ref: '#/components/schemas/ApiKeyResourceProperties'
            - $ref: '#/components/schemas/ChatResourceProperties'
            - $ref: '#/components/schemas/ConversationResourceProperties'
            - $ref: '#/components/schemas/DiscussionResourceProperties'
            - $ref: '#/components/schemas/DocumentResourceProperties'
            - $ref: '#/components/schemas/FileResourceProperties'
            - $ref: '#/components/schemas/IngestionRuleResourceProperties'
            - $ref: '#/components/schemas/MemoryResourceProperties'
            - $ref: '#/components/schemas/MemoryEntryResourceProperties'
            - $ref: '#/components/schemas/OrchestrationResourceProperties'
            - $ref: '#/components/schemas/PolicyResourceProperties'
            - $ref: '#/components/schemas/SecretResourceProperties'
            - $ref: '#/components/schemas/SessionResourceProperties'
            - $ref: '#/components/schemas/WebhookResourceProperties'
            - $ref: '#/components/schemas/TriggerResourceProperties'
          description: >
            Resource properties. Values may use `{ "ref": "logicalId" }` to
            reference physical IDs of other resources in the template,
            `{ "param": "ParamName" }` to substitute a parameter value, or
            `{ "sub": "text ${ParamName}" }` to interpolate parameter values
            into a string.
        depends_on:
          type: array
          items:
            type: string
          description: Explicit dependency list. In addition to implicit `ref` dependencies.
          nullable: true
        deletion_policy:
          type: string
          enum:
            - delete
            - retain
          description: >
            Controls what happens to the physical resource when it is removed
            from the stack. `delete` (default) deletes the physical resource.
            `retain` keeps the physical resource alive and only removes the
            formation record.
          nullable: true
        metadata:
          type: object
          additionalProperties: true
          nullable: true

    FormationResource:
      type: object
      properties:
        id:
          type: string
          description: Public ID of the resource record
        logical_id:
          type: string
          description: Logical identifier from the template
        resource_type:
          type: string
          description: Resource type (e.g. agent, memory)
        physical_resource_id:
          type: string
          nullable: true
          description: Public ID of the physical SOAT resource
        status:
          type: string
          enum:
            - pending
            - created
            - updated
            - deleted
            - failed
          description: Current resource status

    Formation:
      type: object
      properties:
        id:
          type: string
          description: Public ID of the formation
          example: form_V1StGXR8Z5jdHi6B
        project_id:
          x-soat-ref: projects
          type: string
          description: Project public ID
        name:
          type: string
          description: Human-readable formation name
        template:
          $ref: '#/components/schemas/FormationTemplate'
        outputs:
          type: object
          additionalProperties:
            type: string
          nullable: true
          description: Resolved output values after stack deployment
        status:
          type: string
          enum:
            - creating
            - active
            - updating
            - failed
            - deleting
            - deleted
            - delete_failed
          description: Formation status
        metadata:
          type: object
          additionalProperties: true
          nullable: true
        resources:
          type: array
          items:
            $ref: '#/components/schemas/FormationResource'
          description: Resources managed by this formation (present on get/create/update)
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    ValidationError:
      type: object
      properties:
        path:
          type: string
          description: JSON path to the field with the error
        message:
          type: string
          description: Error description

    ValidationResult:
      type: object
      properties:
        valid:
          type: boolean
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ValidationError'
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/ValidationError'

    PlanChange:
      type: object
      properties:
        logical_id:
          type: string
        resource_type:
          type: string
        action:
          type: string
          enum:
            - create
            - update
            - delete
            - no-op

    PlanResult:
      type: object
      properties:
        changes:
          type: array
          items:
            $ref: '#/components/schemas/PlanChange'

    FormationEvent:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        logical_id:
          type: string
        resource_type:
          type: string
        action:
          type: string
        status:
          type: string
          enum:
            - succeeded
            - failed
        physical_resource_id:
          type: string
          nullable: true
        error:
          type: string
          nullable: true

    FormationOperation:
      type: object
      properties:
        id:
          type: string
          description: Public ID of the operation
        operation_type:
          type: string
          enum:
            - validate
            - plan
            - create
            - update
            - delete
        status:
          type: string
          enum:
            - pending
            - running
            - succeeded
            - failed
        events:
          type: array
          items:
            $ref: '#/components/schemas/FormationEvent'
          nullable: true
        plan:
          allOf:
            - $ref: '#/components/schemas/PlanResult'
          nullable: true
        error:
          type: object
          additionalProperties: true
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
