#!/usr/bin/env nu # Verify every blog post that ships a graph sidecar (.ncl) is present in the # generated content graph (site/public/r/content_graph.json). A sidecar with no # entry means `just graph` was never re-run after the post was added — the post # would render without its mini-graph and ONTOLOGY CONTEXT relations. # # Read-only. Exits non-zero on any gap, so it works as a CI gate. # # Usage (from outreach/site): # nu scripts/build/check-graph-coverage.nu . def main [root: string = "."] { let graph_path = ($root | path join "site/public/r/content_graph.json") if not ($graph_path | path exists) { error make { msg: $"content_graph.json not found at ($graph_path) — run `just graph`" } } let keys = (open $graph_path | get mini | columns) let sidecars = (glob $"($root)/site/content/blog/**/*.ncl" | where { |p| ($p | path basename) != "_index.ncl" }) mut missing = 0 for s in $sidecars { let id = (open --raw $s | parse --regex 'id\s*=\s*"(?[^"]+)"' | get id.0?) if ($id == null) { print $" ($s | path basename): no id field" $missing = ($missing + 1) } else if ($id not-in $keys) { print $" MISSING in content graph: ($id) \(($s | path basename)\)" $missing = ($missing + 1) } } if $missing > 0 { error make { msg: $"graph-coverage: ($missing) post sidecar\(s\) absent from content_graph.json — run `just graph`" } } print $"graph-coverage: ($sidecars | length) sidecar\(s\) present in content graph" }