{ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://runbook-tutorials.invalid/schema/runbook-pack/v0.2", "title": "Runbook pack manifest v0.2", "type": "object", "required": [ "spec", "id", "title", "owner", "exercise_status", "engine" ], "additionalProperties": false, "properties": { "spec": { "const": "runbook-pack/v0.2" }, "id": { "type": "string", "pattern": "^[a-z0-9]+([.-][a-z0-9]+)*$" }, "title": { "type": "string", "minLength": 3 }, "owner": { "type": "string", "minLength": 1 }, "outcome": { "type": "string" }, "exercise_status": { "type": "string", "pattern": "^(unexercised|exercised [0-9]{4}-[0-9]{2}-[0-9]{2} by \\S+)$" }, "engine": { "enum": [ "native", "legacy-command" ] }, "confirm_phrase": { "type": "string", "minLength": 8, "description": "Typed by the operator to confirm an irreversible step." }, "timeout": { "$ref": "#/$defs/timeout", "description": "Default for auto-confirm runs." }, "legacy": { "type": "object", "required": [ "command" ], "additionalProperties": false, "properties": { "command": { "type": "array", "items": { "type": "string" }, "minItems": 1 }, "cwd": { "type": "string" }, "url": { "type": "string" }, "note": { "type": "string" } } }, "framing": { "type": "array", "items": { "type": "string" }, "description": "Things to keep in mind; shown first; not gates." }, "actors": { "type": "array", "items": { "$ref": "#/$defs/actor" } }, "datapoints": { "type": "array", "items": { "$ref": "#/$defs/datapoint" } }, "stages": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/stage" } }, "artefacts": { "type": "array", "items": { "$ref": "#/$defs/artefact" } }, "ownership": { "type": "array", "items": { "$ref": "#/$defs/ownership" } } }, "allOf": [ { "if": { "properties": { "engine": { "const": "native" } } }, "then": { "required": [ "stages", "framing" ] } }, { "if": { "properties": { "engine": { "const": "legacy-command" } } }, "then": { "required": [ "legacy" ] } } ], "$defs": { "id": { "type": "string", "pattern": "^[a-z][a-z0-9-]*$" }, "dpid": { "type": "string", "pattern": "^[a-z][a-z0-9_]*$" }, "timeout": { "type": "object", "required": [ "seconds" ], "additionalProperties": false, "properties": { "seconds": { "type": "integer", "minimum": 1 }, "on_timeout": { "enum": [ "stop", "push-through" ], "default": "stop" } } }, "actor": { "type": "object", "required": [ "id", "role", "description" ], "additionalProperties": false, "properties": { "id": { "$ref": "#/$defs/id" }, "role": { "type": "string" }, "description": { "type": "string" }, "privileges": { "type": "array", "items": { "type": "string" } } } }, "datapoint": { "type": "object", "required": [ "id", "label", "type" ], "additionalProperties": false, "properties": { "id": { "$ref": "#/$defs/dpid" }, "label": { "type": "string" }, "type": { "enum": [ "string", "text", "enum", "path", "bool", "int" ] }, "values": { "type": "array", "items": { "type": "string" } }, "default": { "type": [ "string", "integer", "boolean" ] }, "pattern": { "type": "string" }, "help": { "type": "string" }, "dimensions": { "type": "object", "additionalProperties": { "type": "string" } }, "ask_in": { "$ref": "#/$defs/id" }, "produced_by": { "$ref": "#/$defs/id" }, "confirmed_by": { "$ref": "#/$defs/id" }, "secret": { "const": false } } }, "check": { "type": "object", "additionalProperties": false, "properties": { "done_when": { "type": "string", "minLength": 3 }, "command": { "type": "string" }, "expect": { "enum": [ "manual", "exit-0", "output-contains" ] }, "contains": { "type": "string" }, "datapoints_ok": { "type": "array", "items": { "$ref": "#/$defs/dpid" }, "minItems": 1 } }, "anyOf": [ { "required": [ "done_when" ] }, { "required": [ "datapoints_ok" ] } ] }, "alternative": { "type": "object", "required": [ "id", "title", "verify" ], "additionalProperties": false, "properties": { "id": { "$ref": "#/$defs/id" }, "title": { "type": "string" }, "command": { "type": "string" }, "reversible": { "type": "boolean" }, "rollback": { "type": "string" }, "verify": { "$ref": "#/$defs/check" }, "recommended_when": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" } } }, "idempotent": { "enum": [ "idempotent", "non-idempotent", "conditional" ] }, "idempotent_note": { "type": "string" } } }, "step": { "type": "object", "required": [ "id", "title", "actor", "owner" ], "additionalProperties": false, "properties": { "id": { "$ref": "#/$defs/id" }, "title": { "type": "string" }, "actor": { "$ref": "#/$defs/id" }, "owner": { "type": "string" }, "description": { "type": "string" }, "command": { "type": "string" }, "reversible": { "type": "boolean", "default": true }, "rollback": { "type": "string" }, "confirm_phrase": { "type": "string", "minLength": 8 }, "verify": { "$ref": "#/$defs/check" }, "requires": { "type": "array", "items": { "type": "string" } }, "uses": { "type": "array", "items": { "$ref": "#/$defs/dpid" } }, "produces": { "type": "array", "items": { "type": "string" } }, "evidence": { "type": "array", "items": { "type": "string" } }, "one_of": { "type": "array", "minItems": 2, "items": { "$ref": "#/$defs/alternative" } }, "timeout": { "$ref": "#/$defs/timeout" }, "downstream_risk": { "type": "string" }, "auto_confirm": { "enum": [ "allowed", "manual-only" ], "default": "allowed" }, "idempotent": { "enum": [ "idempotent", "non-idempotent", "conditional" ], "description": "Is re-running this step after a partial or complete earlier attempt safe? Omit if unknown. Values are words, never yes/no: YAML reads unquoted yes/no as booleans." }, "idempotent_note": { "type": "string", "description": "Required when idempotent is conditional: under what condition." } }, "anyOf": [ { "required": [ "verify" ] }, { "required": [ "one_of" ] } ] }, "gate": { "type": "object", "required": [ "id", "title", "goal", "checks" ], "additionalProperties": false, "properties": { "id": { "$ref": "#/$defs/id" }, "title": { "type": "string" }, "goal": { "type": "string", "minLength": 3 }, "blocking": { "type": "boolean", "default": true }, "checks": { "type": "array", "minItems": 1, "items": { "$ref": "#/$defs/check" } }, "waivable": { "type": "object", "required": [ "by", "needs_reason" ], "additionalProperties": false, "properties": { "by": { "$ref": "#/$defs/id" }, "needs_reason": { "const": true } } }, "timeout": { "$ref": "#/$defs/timeout" }, "downstream_risk": { "type": "string" } } }, "stage": { "type": "object", "required": [ "id", "title", "goal" ], "additionalProperties": false, "properties": { "id": { "$ref": "#/$defs/id" }, "title": { "type": "string" }, "goal": { "type": "string", "minLength": 3 }, "framing": { "type": "array", "items": { "type": "string" } }, "requires": { "type": "array", "items": { "type": "string" } }, "steps": { "type": "array", "items": { "$ref": "#/$defs/step" } }, "gates": { "type": "array", "items": { "$ref": "#/$defs/gate" } }, "stages": { "type": "array", "items": { "$ref": "#/$defs/stage" } } }, "anyOf": [ { "required": [ "steps" ] }, { "required": [ "stages" ] } ] }, "artefact": { "type": "object", "required": [ "id", "title", "location", "produced_by" ], "additionalProperties": false, "properties": { "id": { "$ref": "#/$defs/id" }, "title": { "type": "string" }, "location": { "type": "object", "required": [ "datapoint" ], "additionalProperties": false, "properties": { "datapoint": { "$ref": "#/$defs/dpid" }, "path": { "type": "string" } } }, "produced_by": { "$ref": "#/$defs/id" }, "lives_until": { "$ref": "#/$defs/id" } } }, "ownership": { "type": "object", "required": [ "concern", "owner" ], "additionalProperties": false, "properties": { "concern": { "type": "string" }, "owner": { "type": "string" } } } } }