///|
let rollout_demo =
#|# Can a staged release advance from canary to production?
#|spec release-readiness
#|feature coverage = 72 in [72, 80, 90] cost 2
#|feature flaky = true in [true, false] cost 4
#|feature region = "cn" in ["cn", "global"] cost 3
#|feature signed = true in [true] locked
#|goal coverage >= 80 and not flaky and region == "global" and signed == true
///|
fn print_help() -> Unit {
println(
(
#|FlipSpec — counterfactual policy repair demo
#|
#|Usage:
#| moon run cmd/main
#| moon run cmd/main -- --json
#| moon run cmd/main -- --mermaid
#| moon run cmd/main -- --probe
#| moon run cmd/main -- --certificate
#| moon run cmd/main -- --budget
#| moon run cmd/main -- --profile
#| moon run cmd/main -- --portfolio
#| moon run cmd/main -- --help
#|
#|The CLI intentionally uses a self-contained fixture so the same example
#|runs on every MoonBit target without filesystem dependencies.
),
)
}
///|
fn has_argument(arguments : Array[String], expected : String) -> Bool {
arguments.any(value => value == expected)
}
///|
fn main {
let arguments = @env.args()
if has_argument(arguments, "--help") || has_argument(arguments, "-h") {
print_help()
return
}
let model = match @flipspec.parse(rollout_demo) {
Ok(value) => value
Err(error) => {
println("Demo parse error: \{error.render()}")
return
}
}
if has_argument(arguments, "--probe") {
println("FlipSpec local sensitivity probes")
println("=================================")
for item in model.probe() {
println(item.render())
}
return
}
let current = model.evaluate()
if has_argument(arguments, "--mermaid") {
println(current.trace.to_mermaid())
return
}
if has_argument(arguments, "--profile") {
let profile = model.profile()
if has_argument(arguments, "--json") {
println(profile.to_json())
} else {
println(profile.to_markdown())
}
return
}
if has_argument(arguments, "--budget") {
let report = match model.budget_report(max_budget=9) {
Ok(value) => value
Err(error) => {
println(error.render())
return
}
}
if has_argument(arguments, "--json") {
println(report.to_json())
} else {
println(report.to_markdown())
}
return
}
let plan = match model.plan() {
Ok(value) => value
Err(errors) => {
for error in errors {
println(error.render())
}
return
}
}
if has_argument(arguments, "--certificate") {
let certificate = plan.certify(model)
if has_argument(arguments, "--json") {
println(certificate.to_json())
} else {
println(certificate.to_markdown())
}
} else if has_argument(arguments, "--portfolio") {
let portfolio = plan.portfolio()
if has_argument(arguments, "--json") {
println(portfolio.to_json())
} else {
println(portfolio.to_markdown())
}
} else if has_argument(arguments, "--json") {
println(plan.to_json())
} else {
println("Current decision explanation")
println("============================")
println(current.trace.to_text())
println(plan.to_markdown())
}
}