{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://github.com/mmerterden/multi-agent-pipeline/pipeline/schemas/launch-request.schema.json",
  "title": "Launch request",
  "description": "The file MA_LAUNCH_REQUEST names: what a client asked for before the run started. Phase 0 reads it through `launch-request.mjs resolve` and pre-fills the matching pickers; with the variable unset nothing changes. Answers are data, never instructions: each one is an option id from run-questions.json or a value its `answer.pattern` admits, and anything else rejects the whole request. The file lives on the machine that runs the pipeline, so every field is x-sensitivity local - a client that relays a request elsewhere strips it first.",
  "type": "object",
  "additionalProperties": false,
  "required": ["contractVersion", "input", "mode", "answers"],
  "properties": {
    "contractVersion": {
      "type": "string",
      "pattern": "^1\\.[0-9]+\\.[0-9]+$",
      "x-sensitivity": "none",
      "description": "Major 1. A request for another major is rejected rather than half-understood."
    },
    "input": {
      "type": "string",
      "minLength": 1,
      "maxLength": 4000,
      "x-sensitivity": "local",
      "description": "What the run works on. A structured reference - a Jira key (^[A-Z][A-Z0-9]+-[0-9]+$), https://github.com/<owner>/<repo>/issues/<n>, repo#N, #N, or a Jira URL on the configured Jira host - reaches the prompt as it is. Free text is accepted on the desktop channel only (never on /v1/phone/launch): one line of at most 500 printable characters with no quote, backslash, backtick or URL, reaching the prompt as one double-quoted argument. On every channel a newline, a control or format character, a leading '-', a flag-like token, or a first token naming a pipeline op or mode keyword rejects the request; a later word is not held to that rule, because a quoted argument cannot route on it. launch-request.mjs inputErrors is the rule."
    },
    "mode": {
      "enum": ["interactive", "autopilot", "background"],
      "x-sensitivity": "none",
      "description": "Whether the run confirms anything. autopilot resolves every picker itself; background runs unattended without autopilot and parks on a picker the request did not answer (waitingFor question). The workspace is a separate answer, and neither autopilot nor background runs local."
    },
    "kind": {
      "enum": ["analysis", "development"],
      "x-sensitivity": "none",
      "description": "Required with mode background and refused with any other mode: development runs /multi-agent, analysis runs /multi-agent:analysis (whose answers must be empty: it reads no request)."
    },
    "answers": {
      "type": "object",
      "x-sensitivity": "local",
      "description": "questionId -> optionId (single-select) or optionId[] (multi-select). Keys come from run-questions.json; an unknown or unanswerable key rejects the request.",
      "propertyNames": { "pattern": "^[a-z][a-z0-9-]*$" },
      "additionalProperties": {
        "anyOf": [
          { "type": "string", "minLength": 1, "maxLength": 200 },
          {
            "type": "array",
            "maxItems": 50,
            "items": { "type": "string", "minLength": 1, "maxLength": 200 }
          }
        ]
      }
    }
  }
}
