#!/usr/bin/env nu # domains/rustelo/commands.nu — CLI dispatch for RusteloApp projects. # Delegates to ontoref --project-root for domain-level operations. # publish-contract / probe deliver the content-publisher consumption contract # (ADR-046 view discipline, ADR-056 verification) to any onboarded RusteloApp. # Locate the site workspace (dir containing site/content) under a project root. def site-workspace [root: string]: nothing -> string { if ([$root, "site", "content"] | path join | path exists) { $root } else if ([$root, "code", "site", "content"] | path join | path exists) { $"($root)/code" } else { "" } } def main [cmd?: string, ...rest: string] { let domain_root = (^ontoref project root rustelo | str trim) match ($cmd | default "") { "layers" => { with-env { ONTOREF_PROJECT_ROOT: $domain_root } { ^ontoref describe features } }, "plugins" => { print " (rustelo plugin registry — not yet implemented)" }, "routes" => { print " (rustelo route manifest — not yet implemented)" }, "wasm" => { print " (rustelo WASM targets — not yet implemented)" }, "publish-contract" => { publish-contract $domain_root }, "probe" => { probe }, _ => { print " rustelo: layers | plugins | routes | wasm | publish-contract | probe" print " publish-contract the 6-answer content-publisher contract (+ oracle), from the producer" print " probe run the end-to-end publish->activate->index oracle in THIS project" }, } } # Print the producer-declared content-publisher contract. Resolved from the # rustelo project root — works from any RusteloApp, no copy. def publish-contract [domain_root: string] { let ncl = $"($domain_root)/domains/rustelo/ontology/publishing-contract.ncl" if not ($ncl | path exists) { print $" ✗ contract not found at ($ncl)" return } let res = (do { ^nickel export --import-path ($ncl | path dirname) $ncl } | complete) if $res.exit_code != 0 { print " ✗ contract export failed:" print $res.stderr return } let c = ($res.stdout | from json) print "" print $" (ansi cyan_bold)Rustelo content-publisher contract(ansi reset) [profile: ($c.profile)]" print $" (ansi green)activate(ansi reset) ($c.activate_cmd)" print $" (ansi green)serve(ansi reset) ($c.serve_cmd)" print $" (ansi green)index(ansi reset) ($c.content_root)" for q in $c.questions { let tag = if $q.side == "ContentOnly" { $"(ansi green)content-only(ansi reset)" } else { $"(ansi yellow)recompile(ansi reset)" } print "" print $" (ansi white_bold)◆ ($q.id)(ansi reset) [($tag)]" print $" (ansi default_dimmed)Q(ansi reset) ($q.question)" print $" (ansi default_dimmed)A(ansi reset) ($q.answer)" print $" (ansi magenta)oracle(ansi reset) ($q.oracle)" } let gaps = ($c.known_gaps? | default []) if ($gaps | length) > 0 { print "" print $" (ansi yellow_bold)Known gaps(ansi reset) — declared producer-side limitations, plan around them" for g in $gaps { print $" (ansi yellow)▲ ($g.id)(ansi reset) [($g.side)/($g.status)]" print $" (ansi default_dimmed)area(ansi reset) ($g.area)" print $" (ansi default_dimmed)symptom(ansi reset) ($g.symptom)" print $" (ansi magenta)oracle(ansi reset) ($g.oracle)" } } print "" } # Run the end-to-end binding oracle in the CURRENT RusteloApp: publish a trivial # item, activate (content_processor), assert it entered the index, clean up. # Witnessed verification (ADR-056) — proves the contract before generating pages. def probe [] { let root = ($env.ONTOREF_PROJECT_ROOT? | default (pwd | path expand)) let ws = (site-workspace $root) if ($ws | is-empty) { print $" ✗ no site/content found under ($root) (looked at site/ and code/site/) — not a content-only RusteloApp" return } if (which content_processor | is-empty) { print " ✗ content_processor not on PATH — install the rustelo content tooling" return } let probe_md = $"($ws)/site/content/blog/en/getting-started/_ontoref-probe.md" let probe_dir = ($probe_md | path dirname) mkdir $probe_dir "---\nid: \"_ontoref-probe\"\ntitle: \"Ontoref Probe\"\nslug: \"_ontoref-probe\"\nexcerpt: \"Auto-generated contract probe.\"\nauthor: \"ontoref\"\ndate: \"2026-01-01\"\npublished: true\ncategory: \"getting-started\"\ntags: [\"probe\"]\n---\n\n# Ontoref Probe\n\nWitnessed publish->activate->index oracle.\n" | save -f $probe_md cd $ws let act = (do { ^content_processor --content-type blog --language en } | complete) let html = $"($ws)/site/r/blog/en/getting-started/_ontoref-probe.html" let idx = $"($ws)/site/r/blog/en/getting-started/index.json" let html_ok = ($html | path exists) let idx_ok = if ($idx | path exists) { (open --raw $idx | str contains "_ontoref-probe") } else { false } # Clean up the probe artifacts and re-index to drop it from the index. rm -f $probe_md $html $"($ws)/site/r/blog/en/getting-started/_ontoref-probe.json" do { ^content_processor --content-type blog --language en } | complete | ignore print "" if ($act.exit_code == 0) and $html_ok and $idx_ok { print $" (ansi green_bold)GREEN(ansi reset) publish->activate->index oracle passed" print $" item indexed at site/r/blog/en/getting-started/ and present in index.json" print $" next: serve \(rustelo-htmx-server\) and GET /blog/getting-started/ -> expect HTTP 200" } else { print $" (ansi red_bold)RED(ansi reset) oracle failed — activate exit=($act.exit_code), html=($html_ok), in_index=($idx_ok)" if $act.exit_code != 0 { print $act.stderr } } print "" }