{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://guided-engineering.github.io/OpenPrompt-Specification/schemas/prompt.schema.json",
  "title": "OPS Prompt",
  "description": "A validated task contract: intent, context, constraints, ordered actions, expected outputs and the checks that decide completion. The reusable definition only; what happened during a run lives in a worklog entry. Semantics that a schema cannot express (agent resolution, path resolution, identifier uniqueness, requirement coverage) are defined in .guides/ops-contract.md and enforced by tools/ops-validate.",
  "type": "object",
  "required": [
    "apiVersion",
    "id",
    "version",
    "title",
    "agent",
    "objective",
    "context",
    "steps",
    "output",
    "verification"
  ],
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "type": "string",
      "minLength": 1,
      "description": "Optional editor hint. When present it must lead to this schema: either its $id, or a path relative to the prompt file that holds an identical copy."
    },
    "apiVersion": {
      "type": "string",
      "const": "guided-engineering/v1",
      "description": "Names the artifact family. It is not a release number and does not decide validity; this schema does."
    },
    "id": {
      "type": "string",
      "pattern": "^[a-z0-9]+([._-][a-z0-9]+)*$",
      "maxLength": 96,
      "description": "Stable identifier, unique among the prompts of a repository."
    },
    "version": {
      "type": "integer",
      "minimum": 1,
      "description": "Content revision of this prompt. Increment when the task definition changes in substance."
    },
    "title": {
      "type": "string",
      "minLength": 1,
      "maxLength": 160
    },
    "agent": {
      "type": "string",
      "pattern": "^[a-z][a-z0-9]*(-[a-z0-9]+)*$",
      "maxLength": 64,
      "description": "Id of the execution profile this task is written for. It must resolve in the repository's agent map. Declaring it does not start a process, create a subagent, or grant permissions."
    },
    "objective": {
      "type": "string",
      "minLength": 1,
      "description": "The intent: what must be true when the task is done, stated so that someone can check it."
    },
    "context": {
      "type": "string",
      "minLength": 1,
      "description": "Facts the executor needs before acting: where the work lives, how it is built and tested, what is already known."
    },
    "workspace": {
      "type": "string",
      "pattern": "^(?!.*(?:^|/)\\.\\.(?:/|$))\\./[^\\\\]*$",
      "description": "Task workspace, relative to the repository root and starting with './'. Default './'. Commands run here; inputs and outputs resolve here; the task changes nothing outside it except its own worklog entry."
    },
    "inputs": {
      "type": "array",
      "uniqueItems": true,
      "items": { "$ref": "#/definitions/relativePath" },
      "description": "Files or directories, relative to the workspace, that the task reads and that must exist before execution."
    },
    "dependencies": {
      "type": "array",
      "items": { "type": "string", "minLength": 1 },
      "description": "Preconditions in plain language: tools, access, prior work."
    },
    "constraints": {
      "type": "array",
      "items": { "type": "string", "minLength": 1 },
      "description": "Limits on scope and method that hold for the whole task."
    },
    "requirements": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "required": ["id", "text"],
        "additionalProperties": false,
        "properties": {
          "id": { "$ref": "#/definitions/localId" },
          "text": { "type": "string", "minLength": 1 }
        }
      },
      "description": "Optional numbered requirements. When declared, every requirement must be covered by at least one verification check."
    },
    "steps": {
      "type": "array",
      "minItems": 1,
      "description": "Ordered units of work. Steps run in the order written.",
      "items": {
        "type": "object",
        "required": ["id", "title", "actions"],
        "additionalProperties": false,
        "properties": {
          "id": { "$ref": "#/definitions/localId" },
          "title": { "type": "string", "minLength": 1 },
          "actions": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "minLength": 1,
              "description": "One action in imperative natural language."
            }
          },
          "requirements": { "$ref": "#/definitions/requirementRefs" }
        }
      }
    },
    "output": {
      "type": "array",
      "description": "Expected artifacts. May be empty when the result is only a state that the verification checks observe.",
      "items": {
        "type": "object",
        "required": ["file"],
        "additionalProperties": false,
        "properties": {
          "file": {
            "$ref": "#/definitions/relativePath",
            "description": "Path relative to the workspace. A '<name>' segment marks a value chosen during execution; the worklog entry then states the concrete path."
          },
          "rules": {
            "type": "array",
            "items": { "type": "string", "minLength": 1 }
          }
        }
      }
    },
    "verification": {
      "type": "array",
      "minItems": 1,
      "description": "The checks that decide completion. The task is complete only when every check passes against the final state of the workspace.",
      "items": {
        "type": "object",
        "required": ["id", "expect"],
        "additionalProperties": false,
        "properties": {
          "id": { "$ref": "#/definitions/localId" },
          "expect": {
            "type": "string",
            "minLength": 1,
            "description": "The observable condition that must hold."
          },
          "run": {
            "type": "string",
            "minLength": 1,
            "description": "Command that decides the check, run in the workspace. Exit code 0 means pass. Without it, the executor states how the condition was observed."
          },
          "requirements": { "$ref": "#/definitions/requirementRefs" }
        }
      }
    },
    "stopConditions": {
      "type": "array",
      "items": { "type": "string", "minLength": 1 },
      "description": "Situations in which the executor stops and reports instead of continuing."
    },
    "limits": {
      "type": "object",
      "additionalProperties": false,
      "minProperties": 1,
      "properties": {
        "repairAttempts": {
          "type": "integer",
          "minimum": 0,
          "maximum": 5,
          "description": "Maximum number of repair cycles for one failing check: a change made because that check failed, followed by re-running it. The count restarts when the check passes. Default 2. When a check still fails after that many cycles, the run stops as blocked."
        },
        "timeBudgetMinutes": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1440,
          "description": "Wall-clock budget for one run, in minutes, measured by the executor. When exceeded at a step boundary, the run stops as blocked. It is not a process timeout."
        }
      }
    },
    "tags": {
      "type": "array",
      "uniqueItems": true,
      "items": { "type": "string", "minLength": 1 }
    },
    "createdBy": {
      "type": "string",
      "minLength": 1,
      "description": "Who authored the definition: a person, a team, or a tool."
    }
  },
  "definitions": {
    "localId": {
      "type": "string",
      "pattern": "^[A-Za-z0-9]+([._-][A-Za-z0-9]+)*$",
      "maxLength": 64
    },
    "requirementRefs": {
      "type": "array",
      "minItems": 1,
      "uniqueItems": true,
      "items": { "$ref": "#/definitions/localId" }
    },
    "relativePath": {
      "type": "string",
      "minLength": 1,
      "pattern": "^(?![/\\\\])(?![A-Za-z]:)(?!.*(?:^|/)\\.\\.(?:/|$))[^\\\\]+$"
    }
  }
}
