Retire exercise_status: maturity is the only notion; add CLI tests (RBT-WP-0009-T01)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 295952@bnt-lap001
Assistant-Session: e93f64ad-516c-46eb-9666-aad8d300c477
This commit is contained in:
tegwick 2026-09-29 21:28:56 +02:00
parent b89e8eaa74
commit 6d3414d8b7
29 changed files with 444 additions and 218 deletions

View file

@ -3,96 +3,292 @@
"$id": "https://runbook-tutorials.invalid/schema/runbook-pack/v0.1",
"title": "Runbook pack manifest",
"type": "object",
"required": ["spec", "id", "title", "owner", "exercise_status", "engine"],
"required": [
"spec",
"id",
"title",
"owner",
"engine"
],
"additionalProperties": false,
"properties": {
"spec": {"const": "runbook-pack/v0.1"},
"id": {"type": "string", "pattern": "^[a-z0-9]+([.-][a-z0-9]+)*$"},
"title": {"type": "string", "minLength": 3},
"owner": {"type": "string", "minLength": 1, "description": "Repository that owns the procedure"},
"outcome": {"type": "string"},
"spec": {
"const": "runbook-pack/v0.1"
},
"id": {
"type": "string",
"pattern": "^[a-z0-9]+([.-][a-z0-9]+)*$"
},
"title": {
"type": "string",
"minLength": 3
},
"owner": {
"type": "string",
"minLength": 1,
"description": "Repository that owns the procedure"
},
"outcome": {
"type": "string"
},
"exercise_status": {
"type": "string",
"pattern": "^(unexercised|exercised [0-9]{4}-[0-9]{2}-[0-9]{2} by \\S+)$"
"deprecated": true,
"description": "Deprecated and ignored. Maturity is derived from run history (docs/maturity-and-projects.md); old packs that still carry this field keep loading."
},
"engine": {
"enum": [
"native",
"legacy-command"
]
},
"engine": {"enum": ["native", "legacy-command"]},
"legacy": {
"type": "object",
"required": ["command"],
"required": [
"command"
],
"additionalProperties": false,
"properties": {
"command": {"type": "array", "items": {"type": "string"}, "minItems": 1},
"cwd": {"type": "string"},
"url": {"type": "string"},
"note": {"type": "string"}
"command": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
},
"cwd": {
"type": "string"
},
"url": {
"type": "string"
},
"note": {
"type": "string"
}
}
},
"parameters": {"type": "array", "items": {"$ref": "#/$defs/parameter"}},
"prerequisites": {"type": "array", "items": {"$ref": "#/$defs/prerequisite"}},
"steps": {"type": "array", "items": {"$ref": "#/$defs/step"}},
"threat_checks": {"type": "array", "items": {"type": "string"}},
"ownership": {"type": "array", "items": {"$ref": "#/$defs/ownership"}}
"parameters": {
"type": "array",
"items": {
"$ref": "#/$defs/parameter"
}
},
"prerequisites": {
"type": "array",
"items": {
"$ref": "#/$defs/prerequisite"
}
},
"steps": {
"type": "array",
"items": {
"$ref": "#/$defs/step"
}
},
"threat_checks": {
"type": "array",
"items": {
"type": "string"
}
},
"ownership": {
"type": "array",
"items": {
"$ref": "#/$defs/ownership"
}
}
},
"allOf": [
{"if": {"properties": {"engine": {"const": "native"}}},
"then": {"required": ["steps", "threat_checks"]}},
{"if": {"properties": {"engine": {"const": "legacy-command"}}},
"then": {"required": ["legacy"]}}
{
"if": {
"properties": {
"engine": {
"const": "native"
}
}
},
"then": {
"required": [
"steps",
"threat_checks"
]
}
},
{
"if": {
"properties": {
"engine": {
"const": "legacy-command"
}
}
},
"then": {
"required": [
"legacy"
]
}
}
],
"$defs": {
"parameter": {
"type": "object",
"required": ["id", "label", "type"],
"required": [
"id",
"label",
"type"
],
"additionalProperties": false,
"properties": {
"id": {"type": "string", "pattern": "^[a-z][a-z0-9_]*$"},
"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"},
"secret": {"const": false, "description": "Parameters are never secret. Secrets are entered by the operator into the tool that owns them, never into the engine."}
"id": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]*$"
},
"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"
},
"secret": {
"const": false,
"description": "Parameters are never secret. Secrets are entered by the operator into the tool that owns them, never into the engine."
}
}
},
"prerequisite": {
"type": "object",
"required": ["text", "owner"],
"required": [
"text",
"owner"
],
"additionalProperties": false,
"properties": {"text": {"type": "string"}, "owner": {"type": "string"}}
"properties": {
"text": {
"type": "string"
},
"owner": {
"type": "string"
}
}
},
"check": {
"type": "object",
"required": ["done_when"],
"required": [
"done_when"
],
"additionalProperties": false,
"properties": {
"done_when": {"type": "string", "minLength": 3},
"command": {"type": "string"},
"expect": {"enum": ["manual", "exit-0", "output-contains"]},
"contains": {"type": "string"}
"done_when": {
"type": "string",
"minLength": 3
},
"command": {
"type": "string"
},
"expect": {
"enum": [
"manual",
"exit-0",
"output-contains"
]
},
"contains": {
"type": "string"
}
}
},
"step": {
"type": "object",
"required": ["id", "title", "owner", "verify"],
"required": [
"id",
"title",
"owner",
"verify"
],
"additionalProperties": false,
"properties": {
"id": {"type": "string", "pattern": "^[a-z][a-z0-9-]*$"},
"title": {"type": "string"},
"owner": {"type": "string"},
"description": {"type": "string"},
"command": {"type": "string", "description": "Template; {{param}} placeholders only"},
"risk": {"enum": ["read-only", "changes-state", "attended", "destructive"], "default": "read-only"},
"verify": {"$ref": "#/$defs/check"},
"rollback": {"type": "string"},
"evidence": {"type": "array", "items": {"type": "string"}, "description": "Names of non-secret facts recorded when the step completes"}
"id": {
"type": "string",
"pattern": "^[a-z][a-z0-9-]*$"
},
"title": {
"type": "string"
},
"owner": {
"type": "string"
},
"description": {
"type": "string"
},
"command": {
"type": "string",
"description": "Template; {{param}} placeholders only"
},
"risk": {
"enum": [
"read-only",
"changes-state",
"attended",
"destructive"
],
"default": "read-only"
},
"verify": {
"$ref": "#/$defs/check"
},
"rollback": {
"type": "string"
},
"evidence": {
"type": "array",
"items": {
"type": "string"
},
"description": "Names of non-secret facts recorded when the step completes"
}
}
},
"ownership": {
"type": "object",
"required": ["concern", "owner"],
"required": [
"concern",
"owner"
],
"additionalProperties": false,
"properties": {"concern": {"type": "string"}, "owner": {"type": "string"}}
"properties": {
"concern": {
"type": "string"
},
"owner": {
"type": "string"
}
}
}
}
}