ontoref-code/domains/rustelo/commands.nu
2026-07-10 01:44:59 +01:00

111 lines
5.6 KiB
Text

#!/usr/bin/env nu
# domains/rustelo/commands.nu — CLI dispatch for RusteloApp projects.
# Delegates to ontoref --project-root <rustelo> 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/<slug> -> 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 ""
}