{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://appcd-dev.github.io/solutions/schemas/guild-kinded-manifest.schema.json",
  "$comment": "Published copy for GitHub Pages. Source of truth: stackgen-cli/docs/schemas/guild-kinded-manifest.schema.json",
  "title": "Aiden kinded YAML manifest",
  "description": "JSON Schema for stackgen ai apply kinded YAML (Agent, Workflow, Runbook, Skill, Policy). Source of truth: stackgen-cli/docs/schemas/guild-kinded-manifest.schema.json",
  "type": "object",
  "required": [
    "apiVersion",
    "kind",
    "metadata"
  ],
  "properties": {
    "apiVersion": {
      "type": "string",
      "const": "guild.stackgen.com/v1",
      "description": "Wire apiVersion for kinded Aiden manifests."
    },
    "kind": {
      "type": "string",
      "enum": [
        "Agent",
        "Workflow",
        "Runbook",
        "Skill",
        "Policy"
      ],
      "description": "Resource kind. Apply order: Policy, Agent, Runbook, Skill, Workflow."
    },
    "metadata": {
      "$ref": "#/$defs/objectMeta"
    },
    "spec": {
      "type": "object",
      "description": "Kind-specific payload. See allOf branches for required fields per kind."
    }
  },
  "allOf": [
    {
      "if": {
        "properties": {
          "kind": {
            "const": "Agent"
          }
        },
        "required": [
          "kind"
        ]
      },
      "then": {
        "properties": {
          "spec": {
            "$ref": "#/$defs/agentSpec"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "kind": {
            "const": "Workflow"
          }
        },
        "required": [
          "kind"
        ]
      },
      "then": {
        "properties": {
          "metadata": {
            "allOf": [
              {
                "$ref": "#/$defs/objectMeta"
              },
              {
                "required": [
                  "name",
                  "domain"
                ]
              }
            ]
          },
          "spec": {
            "$ref": "#/$defs/workflowSpec"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "kind": {
            "const": "Runbook"
          }
        },
        "required": [
          "kind"
        ]
      },
      "then": {
        "properties": {
          "spec": {
            "$ref": "#/$defs/runbookSpec"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "kind": {
            "const": "Skill"
          }
        },
        "required": [
          "kind"
        ]
      },
      "then": {
        "properties": {
          "spec": {
            "$ref": "#/$defs/skillSpec"
          }
        }
      }
    },
    {
      "if": {
        "properties": {
          "kind": {
            "const": "Policy"
          }
        },
        "required": [
          "kind"
        ]
      },
      "then": {
        "properties": {
          "spec": {
            "$ref": "#/$defs/policySpec"
          }
        }
      }
    }
  ],
  "additionalProperties": false,
  "$defs": {
    "objectMeta": {
      "type": "object",
      "description": "Shared identity and apply flags for every kind.",
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "description": "Aiden resource name (unique per kind in the tenant)."
        },
        "domain": {
          "type": "string",
          "description": "Workflow domain (required when kind is Workflow)."
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Optional tags applied to the resource."
        },
        "approve": {
          "type": "boolean",
          "description": "When true, approve Workflow or Runbook version after upsert."
        }
      },
      "additionalProperties": false
    },
    "agentSpec": {
      "type": "object",
      "description": "Agent register/update payload for /api/v1/agents.",
      "properties": {
        "persona": {
          "type": "string",
          "description": "Inline agent persona (system prompt)."
        },
        "personaFile": {
          "type": "string",
          "description": "Path to persona markdown; supports Go text/template when --values is set."
        },
        "description": {
          "type": "string",
          "description": "Short human-readable agent description."
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Agent tags (metadata.tags takes precedence when set)."
        },
        "modelNames": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Registered model names in priority order."
        },
        "modelNamesFromAgent": {
          "type": "string",
          "description": "Copy model_names from another agent by name."
        },
        "integrations": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Integration names bound to the agent."
        },
        "remoteRunners": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Remote runner names attached to the agent."
        },
        "tools": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Explicit tool allow-list (integration-scoped names)."
        },
        "skills": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Skill names searchable by the agent."
        },
        "autoApproveTools": {
          "type": "array",
          "description": "Tools auto-approved without HITL when args match.",
          "items": {
            "$ref": "#/$defs/autoApproveToolRule"
          }
        },
        "autoDenyTools": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Tools always denied for this agent."
        },
        "hitl": {
          "$ref": "#/$defs/hitlConfig"
        },
        "knowledge": {
          "$ref": "#/$defs/knowledgeConfig"
        },
        "policyIds": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Policy IDs to attach after upsert."
        },
        "policyNames": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Policy names to resolve and attach after upsert."
        }
      },
      "anyOf": [
        {
          "required": [
            "persona"
          ]
        },
        {
          "required": [
            "personaFile"
          ]
        }
      ],
      "additionalProperties": false
    },
    "autoApproveToolRule": {
      "type": "object",
      "required": [
        "tool"
      ],
      "properties": {
        "tool": {
          "type": "string",
          "description": "Tool name or wildcard pattern (e.g. grafana-prod_*)."
        },
        "whenArgsContain": {
          "type": "object",
          "description": "Optional arg subset that must match for auto-approval.",
          "additionalProperties": true
        }
      },
      "additionalProperties": false
    },
    "hitlConfig": {
      "type": "object",
      "properties": {
        "alwaysAllowed": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Tools never requiring human approval."
        },
        "deniedTools": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Tools always requiring human approval."
        }
      },
      "additionalProperties": false
    },
    "knowledgeConfig": {
      "type": "object",
      "properties": {
        "memoryEnabled": {
          "type": "boolean",
          "description": "Enable agent long-term memory."
        }
      },
      "additionalProperties": false
    },
    "workflowSpec": {
      "type": "object",
      "description": "Workflow with jobs/needs/with sugar compiled to stages and stage_bindings.",
      "required": [
        "jobs"
      ],
      "properties": {
        "description": {
          "type": "string",
          "description": "Inline workflow description."
        },
        "descriptionFile": {
          "type": "string",
          "description": "Path to description markdown; supports Go text/template when --values is set."
        },
        "requiredInputs": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Input keys required at workflow run time."
        },
        "optionalInputs": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Optional input keys at workflow run time."
        },
        "runbookRefs": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Runbook SOP names attached to the workflow."
        },
        "exampleQueries": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Example natural-language queries for discovery."
        },
        "triggers": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/workflowTrigger"
          },
          "description": "Workflow trigger rules."
        },
        "metadata": {
          "$ref": "#/$defs/workflowMetadata",
          "description": "Planner and halguard tuning (camelCase or snake_case keys)."
        },
        "jobs": {
          "type": "object",
          "minProperties": 1,
          "description": "Named jobs compiled to stages. Key order is preserved in YAML.",
          "additionalProperties": {
            "$ref": "#/$defs/jobSpec"
          }
        }
      },
      "additionalProperties": false
    },
    "workflowTrigger": {
      "type": "object",
      "properties": {
        "field": {
          "type": "string",
          "description": "Trigger field to match."
        },
        "values": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Allowed values for field."
        },
        "type": {
          "type": "string",
          "enum": [
            "passive",
            "active"
          ],
          "description": "Trigger type (defaults to passive)."
        },
        "source": {
          "type": "string",
          "description": "Trigger source identifier."
        }
      },
      "additionalProperties": false
    },
    "workflowMetadata": {
      "type": "object",
      "description": "Workflow planner metadata. Accepts camelCase or snake_case spellings.",
      "properties": {
        "plannerMaxToolIterations": {
          "type": "integer"
        },
        "planner_max_tool_iterations": {
          "type": "integer"
        },
        "plannerMinToolCalls": {
          "type": "integer"
        },
        "planner_min_tool_calls": {
          "type": "integer"
        },
        "halguardSkipSubagentTaskTypes": {
          "type": "string"
        },
        "halguard_skip_subagent_task_types": {
          "type": "string"
        }
      },
      "additionalProperties": true
    },
    "jobSpec": {
      "type": "object",
      "description": "One workflow job (stage + binding sugar).",
      "properties": {
        "description": {
          "type": "string",
          "description": "Stage description."
        },
        "required": {
          "type": "boolean",
          "description": "Whether the stage is required (defaults false when action is set)."
        },
        "agent": {
          "type": "string",
          "description": "Agent name for this stage."
        },
        "action": {
          "type": "string",
          "description": "Stage action type (e.g. loop_stage, conditional_skip).",
          "examples": [
            "loop_stage",
            "conditional_skip"
          ]
        },
        "with": {
          "type": "object",
          "description": "Action config map. exit_gateFile / exitGateFile loads JSON into exit_gate.",
          "additionalProperties": true
        },
        "needs": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Job names this stage depends on (maps to depends_on). loop_stage allows at most one need."
        },
        "runbookRefs": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Runbooks attached to this stage."
        },
        "skillRefs": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Skills attached to this stage."
        },
        "note": {
          "type": "string",
          "description": "Inline stage note (prompt fragment)."
        },
        "noteFile": {
          "type": "string",
          "description": "Path to stage note file; supports Go text/template when --values is set."
        },
        "spawnContracts": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/spawnContract"
          },
          "description": "Sub-agent spawn contracts for this stage."
        }
      },
      "allOf": [
        {
          "if": {
            "properties": {
              "action": {
                "const": "loop_stage"
              }
            },
            "required": [
              "action"
            ]
          },
          "then": {
            "properties": {
              "needs": {
                "maxItems": 1
              }
            }
          }
        }
      ],
      "additionalProperties": false
    },
    "spawnContract": {
      "type": "object",
      "required": [
        "name"
      ],
      "properties": {
        "name": {
          "type": "string",
          "description": "Spawn contract name."
        },
        "taskType": {
          "type": "string",
          "description": "Sub-agent task type."
        },
        "toolNames": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Tools available to the spawned sub-agent."
        },
        "maxLlmCalls": {
          "type": "integer",
          "description": "Maximum LLM calls for the sub-agent."
        },
        "maxToolIterations": {
          "type": "integer",
          "description": "Maximum tool iterations for the sub-agent."
        },
        "timeoutSeconds": {
          "type": "integer",
          "description": "Sub-agent timeout in seconds."
        },
        "goal": {
          "type": "string",
          "description": "Inline sub-agent goal."
        },
        "goalFile": {
          "type": "string",
          "description": "Path to goal text file."
        },
        "context": {
          "type": "string",
          "description": "Inline sub-agent context."
        },
        "contextFile": {
          "type": "string",
          "description": "Path to context text file."
        },
        "summarizeOutput": {
          "type": "boolean",
          "description": "Summarize sub-agent output before returning."
        }
      },
      "additionalProperties": false
    },
    "runbookSpec": {
      "type": "object",
      "description": "Runbook SOP body for /api/v1/runbook-sops.",
      "properties": {
        "description": {
          "type": "string",
          "description": "Inline runbook markdown body."
        },
        "descriptionFile": {
          "type": "string",
          "description": "Path to runbook markdown; supports Go text/template when --values is set."
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Runbook tags (metadata.tags takes precedence when set)."
        },
        "prechecks": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Precheck steps before runbook execution."
        },
        "escalationTriggers": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Conditions that trigger escalation."
        },
        "metadata": {
          "type": "object",
          "description": "Opaque runbook metadata map.",
          "additionalProperties": true
        }
      },
      "additionalProperties": false
    },
    "skillSpec": {
      "type": "object",
      "description": "Skill card for /api/v1/skills.",
      "properties": {
        "skillMd": {
          "type": "string",
          "description": "Inline SKILL.md body."
        },
        "skillMdFile": {
          "type": "string",
          "description": "Path to SKILL.md; supports Go text/template when --values is set."
        },
        "files": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/skillCompanionFile"
          },
          "description": "Companion files bundled with the skill."
        }
      },
      "anyOf": [
        {
          "required": [
            "skillMd"
          ]
        },
        {
          "required": [
            "skillMdFile"
          ]
        }
      ],
      "additionalProperties": false
    },
    "skillCompanionFile": {
      "type": "object",
      "required": [
        "path"
      ],
      "properties": {
        "path": {
          "type": "string",
          "description": "Companion file path within the skill bundle."
        },
        "kind": {
          "type": "string",
          "description": "Companion file kind (defaults to doc).",
          "default": "doc"
        },
        "content": {
          "type": "string",
          "description": "Inline companion file content."
        },
        "contentFile": {
          "type": "string",
          "description": "Path to companion file content."
        }
      },
      "additionalProperties": false
    },
    "policySpec": {
      "type": "object",
      "description": "Policy for /api/v1/policies.",
      "properties": {
        "description": {
          "type": "string",
          "description": "Human-readable policy description."
        },
        "type": {
          "type": "string",
          "enum": [
            "logic",
            "temporal",
            "intervention",
            "routing",
            "egress"
          ],
          "default": "logic",
          "description": "Policy type (defaults to logic)."
        },
        "rego": {
          "type": "string",
          "description": "Inline Rego policy body."
        },
        "regoSource": {
          "type": "string",
          "description": "Alias for inline Rego policy body."
        },
        "regoFile": {
          "type": "string",
          "description": "Path to .rego file; supports Go text/template when --values is set."
        },
        "dataJson": {
          "type": "object",
          "description": "Optional OPA data document.",
          "additionalProperties": true
        },
        "tags": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Policy tags (metadata.tags takes precedence when set)."
        },
        "attachToAgents": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Agent names to attach this policy to after upsert."
        }
      },
      "anyOf": [
        {
          "required": [
            "rego"
          ]
        },
        {
          "required": [
            "regoSource"
          ]
        },
        {
          "required": [
            "regoFile"
          ]
        }
      ],
      "additionalProperties": false
    }
  }
}
