112 lines
5.6 KiB
Text
112 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 ""
|
||
|
|
}
|