130 lines
6.6 KiB
Text
130 lines
6.6 KiB
Text
# reflection/modes/validate-playbooks.ncl — TASK-C6
|
|
#
|
|
# Validates all playbooks under catalog/playbooks/ against the PlaybookDef schema
|
|
# and checks that required Nushell scripts exist and pass ide-check.
|
|
#
|
|
# Required params (substituted via {param} in cmd fields):
|
|
# {provisioning_root} — absolute path to provisioning/ directory
|
|
# {schemas_root} — path to provisioning/schemas/lib/ for playbook.ncl
|
|
|
|
{
|
|
id = "validate-playbooks",
|
|
trigger = "Validate all playbooks: schema conformance, script existence, and Nushell ide-check",
|
|
strategy = 'Override,
|
|
|
|
preconditions = [
|
|
"{provisioning_root}/catalog/playbooks/ exists",
|
|
"nickel is available in PATH",
|
|
"nu is available in PATH",
|
|
"jq is available in PATH",
|
|
"{schemas_root}/playbook.ncl is accessible",
|
|
],
|
|
|
|
steps = [
|
|
|
|
{
|
|
id = "discover_playbooks",
|
|
action = "list_playbook_dirs",
|
|
actor = 'Agent,
|
|
cmd = "find {provisioning_root}/catalog/playbooks -maxdepth 1 -type d ! -name playbooks | sort",
|
|
depends_on = [],
|
|
on_error = { strategy = 'Stop },
|
|
note = "Enumerate all playbook directories. Each must contain playbook.ncl at minimum.",
|
|
},
|
|
|
|
{
|
|
id = "check_playbook_ncl_exists",
|
|
action = "verify_manifest_present",
|
|
actor = 'Agent,
|
|
cmd = "find {provisioning_root}/catalog/playbooks -maxdepth 2 -name 'playbook.ncl' | while read f; do echo \"OK: $f\"; done; find {provisioning_root}/catalog/playbooks -maxdepth 1 -mindepth 1 -type d | while read d; do test -f \"$d/playbook.ncl\" || echo \"MISSING playbook.ncl in $d\"; done",
|
|
depends_on = [
|
|
{ step = "discover_playbooks", kind = 'OnSuccess },
|
|
],
|
|
on_error = { strategy = 'Continue },
|
|
note = "Every playbook directory must contain playbook.ncl. Missing manifests are reported but do not stop subsequent checks on other playbooks.",
|
|
},
|
|
|
|
{
|
|
id = "validate_schema_conformance",
|
|
action = "nickel_export_each_playbook",
|
|
actor = 'Agent,
|
|
cmd = "find {provisioning_root}/catalog/playbooks -maxdepth 2 -name 'playbook.ncl' | while read f; do name=$(basename $(dirname $f)); echo \"--- $name\"; echo \"let pb = import \\\"{schemas_root}/playbook.ncl\\\" in (import \\\"$f\\\") | pb.PlaybookDef\" | nickel export /dev/stdin 2>&1 | tail -1 && echo \"$name: schema OK\" || echo \"$name: SCHEMA FAIL\"; done",
|
|
depends_on = [
|
|
{ step = "check_playbook_ncl_exists", kind = 'Always },
|
|
],
|
|
on_error = { strategy = 'Continue },
|
|
note = "Apply PlaybookDef contract to each playbook.ncl. Schema failure means the playbook runner will refuse to execute this playbook.",
|
|
},
|
|
|
|
{
|
|
id = "check_step_scripts_exist",
|
|
action = "verify_step_scripts",
|
|
actor = 'Agent,
|
|
cmd = "find {provisioning_root}/catalog/playbooks -maxdepth 2 -name 'playbook.ncl' | while read f; do dir=$(dirname $f); name=$(basename $dir); nickel export \"$f\" 2>/dev/null | jq -r '.steps[].script' | while read script; do test -f \"$dir/$script\" && echo \"OK: $name/$script\" || echo \"MISSING: $name/$script\"; done; done",
|
|
depends_on = [
|
|
{ step = "validate_schema_conformance", kind = 'Always },
|
|
],
|
|
on_error = { strategy = 'Continue },
|
|
note = "Every step script declared in playbook.ncl must exist as a file relative to the playbook directory.",
|
|
},
|
|
|
|
{
|
|
id = "check_rollback_script",
|
|
action = "verify_rollback_nu_when_automatic",
|
|
actor = 'Agent,
|
|
cmd = "find {provisioning_root}/catalog/playbooks -maxdepth 2 -name 'playbook.ncl' | while read f; do dir=$(dirname $f); name=$(basename $dir); strategy=$(nickel export \"$f\" 2>/dev/null | jq -r '.rollback_strategy // \"none\"'); if [ \"$strategy\" = \"automatic\" ]; then test -f \"$dir/rollback.nu\" && echo \"OK: $name/rollback.nu\" || echo \"MISSING rollback.nu for automatic rollback: $name\"; fi; done",
|
|
depends_on = [
|
|
{ step = "validate_schema_conformance", kind = 'Always },
|
|
],
|
|
on_error = { strategy = 'Continue },
|
|
note = "When rollback_strategy = 'automatic, rollback.nu MUST exist. validate-playbooks reflection mode enforces this before any execution.",
|
|
},
|
|
|
|
{
|
|
id = "nushell_ide_check_scripts",
|
|
action = "nu_ide_check_all_playbook_scripts",
|
|
actor = 'Agent,
|
|
cmd = "find {provisioning_root}/catalog/playbooks -name '*.nu' | while read f; do result=$(nu --ide-check 50 \"$f\" 2>&1); [ -z \"$result\" ] && echo \"OK: $f\" || echo \"FAIL: $f\\n$result\"; done",
|
|
depends_on = [
|
|
{ step = "check_step_scripts_exist", kind = 'Always },
|
|
{ step = "check_rollback_script", kind = 'Always },
|
|
],
|
|
on_error = { strategy = 'Continue },
|
|
note = "All .nu files in playbook directories must pass nu --ide-check 50 with zero diagnostics. This catches Nushell syntax errors and undefined variable references before runtime.",
|
|
},
|
|
|
|
{
|
|
id = "run_dry_run_tests",
|
|
action = "execute_dry_run_tests",
|
|
actor = 'Agent,
|
|
cmd = "find {provisioning_root}/catalog/playbooks -path '*/tests/dry_run.nu' | while read f; do name=$(basename $(dirname $(dirname $f))); echo \"--- dry_run: $name\"; nu \"$f\" 2>&1 && echo \"$name dry_run: PASS\" || echo \"$name dry_run: FAIL\"; done",
|
|
depends_on = [
|
|
{ step = "nushell_ide_check_scripts", kind = 'Always },
|
|
],
|
|
on_error = { strategy = 'Continue },
|
|
note = "When tests/dry_run.nu is present, execute it as a smoke test. Failures are reported but do not fail the overall validation — the dry_run.nu is advisory, not mandatory.",
|
|
},
|
|
|
|
{
|
|
id = "summary_report",
|
|
action = "emit_playbook_validation_report",
|
|
actor = 'Agent,
|
|
cmd = "echo '=== playbook validation complete ===' && echo 'All MISSING and FAIL entries above must be resolved before playbooks can be executed'",
|
|
depends_on = [
|
|
{ step = "run_dry_run_tests", kind = 'Always },
|
|
],
|
|
on_error = { strategy = 'Stop },
|
|
note = "Final summary. MISSING and FAIL lines are blocking. dry_run FAIL lines are advisory.",
|
|
},
|
|
|
|
],
|
|
|
|
postconditions = [
|
|
"All playbook directories contain playbook.ncl",
|
|
"All playbook.ncl files conform to PlaybookDef schema",
|
|
"All step scripts exist relative to their playbook directory",
|
|
"All playbooks with rollback_strategy = automatic have rollback.nu",
|
|
"All .nu files pass nu --ide-check 50 with zero diagnostics",
|
|
"Dry-run tests (where present) executed and results reported",
|
|
],
|
|
}
|