provisioning-code/.ncl-cache/a2a80207bb8aa848c8a0679d0c10732622d8a5b0edcfee69003a720e64df3cc5.json

94 lines
4 KiB
JSON

{
"id": "validate-keeper-policy",
"postconditions": [
"No policy.ncl files contain Nickel function definitions",
"All policy.ncl files export valid JSON conforming to PolicyDef schema",
"All policy.ncl files declare version = 1",
"Validation report produced listing pass/fail per workspace"
],
"preconditions": [
"{policy_repos_root} exists and contains at least one policy-<workspace>/ directory",
"nickel is available in PATH",
"schemas/lib/keeper_policy.ncl is accessible at {schemas_root}/keeper_policy.ncl",
"Each policy-<workspace>/ directory contains policy.ncl"
],
"steps": [
{
"action": "list_policy_repos",
"actor": "Agent",
"cmd": "find {policy_repos_root} -maxdepth 1 -type d -name 'policy-*' | sort",
"depends_on": [],
"id": "discover_policy_repos",
"note": "Enumerate all policy-<workspace> repos present in the configured clones root. Hard stop — if no repos are found the subsequent steps have nothing to validate.",
"on_error": {
"strategy": "Stop"
}
},
{
"action": "grep_forbidden_patterns",
"actor": "Agent",
"cmd": "find {policy_repos_root} -name 'policy.ncl' | xargs grep -lE 'fun |let [a-z_]+ = fun ' 2>/dev/null && echo 'VIOLATION: function definitions found in policy files' || echo 'OK: no function definitions'",
"depends_on": [
{
"kind": "OnSuccess",
"step": "discover_policy_repos"
}
],
"id": "check_declarative_only",
"note": "ADR-038 constraint policy-files-are-declarative-only: policy.ncl files must contain only data conforming to PolicyDef schema. Any Nickel function definition (fun or let x = fun) is a hard violation.",
"on_error": {
"strategy": "Stop"
}
},
{
"action": "nickel_export_each_policy",
"actor": "Agent",
"cmd": "find {policy_repos_root} -name 'policy.ncl' | while read f; do ws=$(basename $(dirname $f)); echo \"--- $ws\"; echo \"let kp = import \\\"{schemas_root}/keeper_policy.ncl\\\" in (import \\\"$f\\\") | kp.PolicyDef\" | nickel export /dev/stdin 2>&1 && echo \"$ws: OK\" || echo \"$ws: SCHEMA FAIL\"; done",
"depends_on": [
{
"kind": "OnSuccess",
"step": "check_declarative_only"
}
],
"id": "validate_schema_conformance",
"note": "Apply keeper_policy.ncl PolicyDef contract to each policy.ncl. A policy that fails to export against the schema is invalid and will be rejected by keeper-daemon at startup.",
"on_error": {
"strategy": "Continue"
}
},
{
"action": "verify_schema_version",
"actor": "Agent",
"cmd": "find {policy_repos_root} -name 'policy.ncl' | while read f; do ws=$(basename $(dirname $f)); v=$(nickel export \"$f\" 2>/dev/null | jq -r '.version // \"MISSING\"'); echo \"$ws version: $v\"; [ \"$v\" = \"1\" ] || echo \"$ws: WARNING — expected version=1, got $v\"; done",
"depends_on": [
{
"kind": "Always",
"step": "validate_schema_conformance"
}
],
"id": "check_version_field",
"note": "Verify each policy file declares schema_version = 1. Version mismatch means keeper-daemon will reject the policy file at startup (fail-fast per ADR-038).",
"on_error": {
"strategy": "Continue"
}
},
{
"action": "emit_validation_report",
"actor": "Agent",
"cmd": "echo '=== keeper policy validation complete ===' && echo 'All violations above must be resolved before keeper-daemon will start'",
"depends_on": [
{
"kind": "Always",
"step": "check_version_field"
}
],
"id": "summary_report",
"note": "Final report: any VIOLATION or SCHEMA FAIL lines above indicate files that keeper-daemon will refuse to load.",
"on_error": {
"strategy": "Stop"
}
}
],
"strategy": "Override",
"trigger": "Validate all workspace keeper policy files: schema conformance + declarative-only enforcement"
}