{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "$id": "https://lcm.local/schemas/pav1/composite.schema.json",
    "title": "PAv1 composites/<name>.yaml — CompositeScenario (PROPOSED / DEFERRED)",
    "description": "PROPOSED, NOT YET WIRED INTO SYNC VALIDATION. A content-defined, parameterised group of CLOSED primitives (and other composites), callable from any step via `uses: composite:<name>@<version>`. Pressure-test artefact for ADR-057 §2.8 (composition & reuse) and ADR-058 §2.5 (composite scope-frame). This schema is framed in the ADR-057 `uses`/`with`/`capture` step-DAG vocabulary, which currently DIVERGES from the live scenario.schema.json (ServerlessWorkflow `do`/`call`) and lifecycle.schema.json (`name`/`handler`) — reconciling those is a precondition to building this. Do not copy into src/core/.../content_store/schemas/ until the hybrid is promoted from specified to built.",
    "type": "object",
    "additionalProperties": false,
    "required": ["apiVersion", "kind", "metadata", "spec"],
    "properties": {
        "apiVersion": { "const": "pav1" },
        "kind": { "const": "CompositeScenario" },
        "metadata": {
            "type": "object",
            "additionalProperties": false,
            "required": ["name", "version"],
            "properties": {
                "name": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" },
                "version": { "type": "string", "pattern": "^v?[0-9]+(\\.[0-9]+){0,2}$" }
            }
        },
        "spec": {
            "type": "object",
            "additionalProperties": false,
            "required": ["steps"],
            "properties": {
                "description": { "type": "string" },
                "parameters": {
                    "description": "Typed input schema. Bound from the caller step's `with:`. Seeds the composite's fresh vars.* frame (ADR-058 §2.5).",
                    "type": "object",
                    "additionalProperties": { "$ref": "#/$defs/parameter" }
                },
                "export": {
                    "description": "The ONLY values returned to the caller. Map of exported-name -> output reference (a jq expression over the composite's own scopes, typically vars.*). Promoted into the caller's vars.<step_id>.* (ADR-058 §2.5).",
                    "type": "object",
                    "minProperties": 0,
                    "additionalProperties": { "type": "string", "minLength": 1 }
                },
                "steps": {
                    "description": "The composite body — the same step DAG as a JobDefinition (ADR-057 §2.4), but each step's `uses` MUST resolve to a closed primitive or another composite (never imperative code).",
                    "type": "array",
                    "minItems": 1,
                    "items": { "$ref": "#/$defs/step" }
                }
            }
        }
    },
    "$defs": {
        "parameter": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type"],
            "properties": {
                "type": {
                    "type": "string",
                    "enum": ["string", "ip_address", "network_mask", "integer", "number", "boolean", "list", "object"]
                },
                "description": { "type": "string" },
                "required": { "type": "boolean", "default": false },
                "default": {}
            }
        },
        "step": {
            "type": "object",
            "additionalProperties": false,
            "required": ["id", "uses"],
            "properties": {
                "id": {
                    "type": "string",
                    "pattern": "^[a-z][a-z0-9_]*$",
                    "description": "Unique within the composite; also the capture namespace (vars.<id>.*)."
                },
                "uses": {
                    "type": "string",
                    "pattern": "^(composite:)?[a-z][a-zA-Z0-9_.]*@v?[0-9]+(\\.[0-9]+){0,2}$",
                    "description": "A closed primitive (e.g. collect@v1, evaluate.regex@v1) OR another composite (composite:<name>@<ver>). The validator checks `with`/`capture` against the resolved unit's I/O schema (ADR-057 §2.7). A composite referencing itself transitively is rejected at sync (max depth 3, cycle detection — ADR-057 §2.8)."
                },
                "target": {
                    "type": "string",
                    "description": "Connector name from PAv1/connectors.yaml. Omitted for pause/report/cml.* and resolved-by-loop targets."
                },
                "with": {
                    "type": "object",
                    "description": "Inputs to the resolved unit. Values may contain ${ jq } over { session, content, runtime_env, vars } (ADR-058)."
                },
                "capture": {
                    "type": "object",
                    "description": "Map of <var> -> <output-key>. Writes the named output into vars.<id>.<var> (ADR-058 §2.3). Under `for_each`, captures are namespaced per iteration — see ADR-057 §2.8 open question OQ-1.",
                    "additionalProperties": { "type": "string", "minLength": 1 }
                },
                "when": {
                    "type": "string",
                    "description": "jq boolean gate in ${ }. Step skipped when false."
                },
                "for_each": { "$ref": "#/$defs/for_each" },
                "on_error": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                        "action": { "type": "string", "enum": ["fail", "continue", "retry"] },
                        "retries": { "type": "integer", "minimum": 0 },
                        "backoff": { "type": "number", "minimum": 0 }
                    },
                    "required": ["action"]
                },
                "timeout": { "type": "number", "exclusiveMinimum": 0 },
                "stage": { "type": "string", "enum": ["setup", "collect", "evaluate", "report"], "default": "setup" }
            }
        },
        "for_each": {
            "type": "object",
            "additionalProperties": false,
            "required": ["var", "in"],
            "description": "Step modifier (ADR-057 §2.8, from SPEC-001 D18). Runs the step once per element of the resolved list, binding `var` into vars.* for the iteration. Dot-notation (@var.field) is available for object lists.",
            "properties": {
                "var": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" },
                "in": { "type": "string", "minLength": 1, "description": "A list value or ${ jq } resolving to a list. Empty list -> step skipped, no failure." },
                "stop_on_fail": { "type": "boolean", "default": true },
                "mode": { "type": "string", "enum": ["sequential"], "default": "sequential", "description": "concurrent reserved for future use." }
            }
        }
    }
}
