2026-09-22 17:25:52 +02:00
|
|
|
//! iris - the shield over a portal site. A content push is an incoming
|
|
|
|
|
//! wormhole; nothing comes through until it checks out.
|
|
|
|
|
//!
|
|
|
|
|
//! `iris check` loads a content repo (a Gitea URL or a local checkout)
|
|
|
|
|
//! exactly the way the running site does, validates it, and holds it to
|
|
|
|
|
//! the business needs it declares in `needs.yaml` - a path within
|
|
|
|
|
//! budget for every kind of visitor, a desk for every handling group,
|
|
|
|
|
//! every finished state reachable, no record stranding. It also exports
|
|
|
|
|
//! what a trainer needs to grade the wording: personas as typed choice
|
|
|
|
|
//! tasks, and a resolved simulation model.
|
|
|
|
|
//!
|
|
|
|
|
//! `iris replay` runs simulated cases through the site's real aggregate
|
|
|
|
|
//! engine on a JetStream and reports every bucket by state; with
|
|
|
|
|
//! `--report-only` it takes the same scorecard from a live site's
|
|
|
|
|
//! buckets.
|
|
|
|
|
//!
|
|
|
|
|
//! Every type iris reads is portal's own, pinned to the portal release
|
|
|
|
|
//! it matches, so the lint and the site never disagree about what a
|
|
|
|
|
//! page is.
|
|
|
|
|
|
|
|
|
|
mod check;
|
|
|
|
|
mod local;
|
|
|
|
|
mod needs;
|
|
|
|
|
mod replay;
|
|
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
|
async fn main() -> anyhow::Result<()> {
|
|
|
|
|
let mut argv: Vec<String> = std::env::args().skip(1).collect();
|
|
|
|
|
// `iris --path questions` reads as `iris check --path questions`,
|
|
|
|
|
// so the content repos' one-line CI keeps working as it was.
|
|
|
|
|
match argv.first().map(String::as_str) {
|
|
|
|
|
Some("check") => {
|
|
|
|
|
argv.remove(0);
|
|
|
|
|
check::run(argv).await
|
|
|
|
|
}
|
|
|
|
|
Some("replay") => {
|
|
|
|
|
argv.remove(0);
|
|
|
|
|
replay::run(argv).await
|
|
|
|
|
}
|
|
|
|
|
Some("--version") | Some("-V") => {
|
2026-09-22 22:05:06 +02:00
|
|
|
println!("iris {v} (portal v{v})", v = env!("CARGO_PKG_VERSION"));
|
2026-09-22 17:25:52 +02:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
Some(flag) if flag.starts_with("--") => check::run(argv).await,
|
|
|
|
|
_ => {
|
|
|
|
|
eprintln!(
|
2026-09-23 11:48:33 +02:00
|
|
|
"iris {v} - matches portal v{v}\n\nusage:\n iris check (--repo <gitea-url> [--branch main] [--subdir questions] | --path <dir>) [--needs-tasks <out.jsonl> [--skim]] [--needs-sim <model.json>] [--access] [--needs-score <answers.jsonl> [--min-accuracy 0.8]]\n iris replay --path <dir> --nats <url> (--cases <cases.jsonl> | --report-only)",
|
2026-09-22 22:05:06 +02:00
|
|
|
v = env!("CARGO_PKG_VERSION")
|
2026-09-22 17:25:52 +02:00
|
|
|
);
|
|
|
|
|
std::process::exit(2)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|