Files
iris/src/main.rs
T
Bendik Aagaard LynghaugandClaude Fable 5.1 959e5f6ef0
Test / test (push) Successful in 29s
check: compile and validate the access policy; --access prints the matrix
Every check now compiles the content into portal's Cedar policy and
fails when it does not validate against the schema - a rule the
schema cannot express would grant nothing at runtime. `--access`
prints the matrix: action, resource, who, and the state move where it
applies. Pinned to portal v0.3.40, where the policy lives.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L4jrCgLiKKHAEFuZUJjckH
2026-09-23 11:48:33 +02:00

55 lines
2.2 KiB
Rust

//! 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") => {
println!("iris {v} (portal v{v})", v = env!("CARGO_PKG_VERSION"));
Ok(())
}
Some(flag) if flag.starts_with("--") => check::run(argv).await,
_ => {
eprintln!(
"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)",
v = env!("CARGO_PKG_VERSION")
);
std::process::exit(2)
}
}
}