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

128 lines
6.8 KiB
JSON

{
"guards": [
{
"cmd": "test -d extensions/taskservs",
"id": "taskservs_dir_exists",
"reason": "extensions/taskservs/ directory not found — run from provisioning root",
"severity": "Block"
}
],
"id": "provisioning-dag-integrity",
"postconditions": [
"All taskservs have provides/requires/conflicts_with fields (or MISSING_FIELDS flagged)",
"All Required capabilities resolve to at least one provider (or UNRESOLVED flagged)",
"ConflictsWith pairs identified (enforcement delegated to provisioning-validate-formula per-formula)",
"Capability coverage table emitted"
],
"preconditions": [
"nickel is in PATH",
"jq is in PATH",
"extensions/taskservs/ directory exists with at least one metadata.ncl",
"NICKEL_IMPORT_PATH includes the provisioning/ root"
],
"steps": [
{
"action": "export_taskserv_metadata",
"actor": "Agent",
"cmd": "for ts in extensions/taskservs/*/; do name=$(basename $ts); meta=$ts/metadata.ncl; if [ -f \"$meta\" ]; then echo \"{\\\"name\\\": \\\"$name\\\", \\\"meta\\\": $(nickel export --format json --import-path . $meta 2>/dev/null || echo 'null')}\"; fi; done | jq -s 'map(select(.meta != null))'",
"depends_on": [],
"id": "export_all_metadata",
"note": "Export all taskserv metadata.ncl files as JSON. Filters out taskservs with missing or broken metadata.",
"on_error": {
"backoff_s": 5,
"max": 3,
"strategy": "Stop"
}
},
{
"action": "verify_capability_fields_present",
"actor": "Agent",
"cmd": "for ts in extensions/taskservs/*/; do name=$(basename $ts); meta=$ts/metadata.ncl; if [ -f \"$meta\" ]; then result=$(nickel export --format json --import-path . $meta 2>/dev/null); if [ $? -ne 0 ]; then echo \"EXPORT_FAIL: $name\"; continue; fi; has_provides=$(echo $result | jq 'has(\"provides\")'); has_requires=$(echo $result | jq 'has(\"requires\")'); has_conflicts=$(echo $result | jq 'has(\"conflicts_with\")'); if [ \"$has_provides\" != 'true' ] || [ \"$has_requires\" != 'true' ] || [ \"$has_conflicts\" != 'true' ]; then echo \"MISSING_FIELDS: $name (provides=$has_provides requires=$has_requires conflicts_with=$has_conflicts)\"; else echo \"OK: $name\"; fi; fi; done",
"depends_on": [],
"id": "check_fields_populated",
"note": "Check that every taskserv metadata.ncl has provides, requires, and conflicts_with fields. MISSING_FIELDS lines indicate incomplete migrations.",
"on_error": {
"backoff_s": 5,
"max": 3,
"strategy": "Continue"
}
},
{
"action": "index_all_capabilities",
"actor": "Agent",
"cmd": "for ts in extensions/taskservs/*/; do meta=$ts/metadata.ncl; if [ -f \"$meta\" ]; then nickel export --format json --import-path . $meta 2>/dev/null | jq -r --arg ts \"$(basename $ts)\" '.provides[]? | [$ts, .id] | @tsv'; fi; done | sort",
"depends_on": [
{
"kind": "Always",
"step": "check_fields_populated"
}
],
"id": "build_provides_index",
"note": "Build the capability provides index: one line per (taskserv, capability_id) pair. Used in resolution step.",
"on_error": {
"backoff_s": 5,
"max": 3,
"strategy": "Stop"
}
},
{
"action": "check_required_dep_coverage",
"actor": "Agent",
"cmd": "provides=$(for ts in extensions/taskservs/*/; do meta=$ts/metadata.ncl; if [ -f \"$meta\" ]; then nickel export --format json --import-path . $meta 2>/dev/null | jq -r '.provides[]?.id'; fi; done | sort -u); for ts in extensions/taskservs/*/; do name=$(basename $ts); meta=$ts/metadata.ncl; if [ -f \"$meta\" ]; then nickel export --format json --import-path . $meta 2>/dev/null | jq -r --arg ts \"$name\" '.requires[]? | select(.kind == \"Required\") | .capability' | while read cap; do if echo \"$provides\" | grep -qx \"$cap\"; then echo \"RESOLVED: $ts requires $cap\"; else echo \"UNRESOLVED: $ts requires $cap (Required — no provider found)\"; fi; done; fi; done",
"depends_on": [
{
"kind": "OnSuccess",
"step": "build_provides_index"
}
],
"id": "resolve_required_capabilities",
"note": "For every Required capability in requires[], check that at least one other taskserv provides it. UNRESOLVED lines are hard errors — the formula will fail at runtime.",
"on_error": {
"backoff_s": 5,
"max": 3,
"strategy": "Continue"
}
},
{
"action": "check_conflictswith_pairs",
"actor": "Agent",
"cmd": "all_names=$(for ts in extensions/taskservs/*/; do basename $ts; done); for ts in extensions/taskservs/*/; do name=$(basename $ts); meta=$ts/metadata.ncl; if [ -f \"$meta\" ]; then nickel export --format json --import-path . $meta 2>/dev/null | jq -r --arg ts \"$name\" '.conflicts_with[]?' | while read conflicting; do if echo \"$all_names\" | grep -qx \"$conflicting\"; then echo \"CONFLICT_PAIR: $name conflicts_with $conflicting (both present in registry)\"; fi; done; fi; done | sort -u",
"depends_on": [
{
"kind": "OnSuccess",
"step": "build_provides_index"
}
],
"id": "detect_conflict_pairs",
"note": "Detect declared ConflictsWith pairs where both extensions exist in the registry. These pairs must not appear together in the same formula. Emit as audit info — enforcement happens in provisioning-validate-formula.",
"on_error": {
"backoff_s": 5,
"max": 3,
"strategy": "Continue"
}
},
{
"action": "emit_integrity_summary",
"actor": "Agent",
"cmd": "echo '--- Extension Capability DAG Integrity Report ---' && echo '' && echo '== Capability Provides Index ==' && for ts in extensions/taskservs/*/; do meta=$ts/metadata.ncl; if [ -f \"$meta\" ]; then caps=$(nickel export --format json --import-path . $meta 2>/dev/null | jq -r '[.provides[]?.id] | join(\", \")' 2>/dev/null); reqs=$(nickel export --format json --import-path . $meta 2>/dev/null | jq -r '[.requires[]? | \"\\(.capability)[\\(.kind)]\"] | join(\", \")' 2>/dev/null); echo \" $(basename $ts): provides=[$caps] requires=[$reqs]\"; fi; done && echo '' && echo 'Run with --verbose to show RESOLVED/UNRESOLVED resolution details.'",
"depends_on": [
{
"kind": "Always",
"step": "resolve_required_capabilities"
},
{
"kind": "Always",
"step": "detect_conflict_pairs"
}
],
"id": "integrity_report",
"note": "Print the full capability coverage table showing what each taskserv provides and requires, then a resolution summary.",
"on_error": {
"backoff_s": 5,
"max": 3,
"strategy": "Stop"
}
}
],
"trigger": "Audit extension capability DAG for completeness, resolution coverage, and conflict safety"
}