flowrs-engine/crates/flowrs-core/tests/agent_corpus.rs
flowRS fd958c0547 flowRS engine, cut from flowRS 3451b065
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-02 19:04:39 -05:00

112 lines
4.5 KiB
Rust

//! Every verified example still verifies.
//!
//! The corpus is what the agent is shown as "a graph that works". An entry that stopped
//! building — a widget renamed, a port retyped, a parameter's range narrowed — would teach
//! the model something false with the authority of a proven example. So each entry is
//! re-proven here: parsed, checked, compiled with cargo, run, compared across tiers, and
//! held to the stages its `proof:` line claims passed (a claim of `tiers` is a claim that
//! the comparison RAN and agreed, not that it was skipped).
use flowrs_core::graph::corpus;
use flowrs_core::graph::verify::{self, Native, Stage, Status};
use flowrs_core::graph::widget::builtin_registry;
fn cargo_available() -> bool {
if std::process::Command::new("cargo")
.arg("-V")
.output()
.is_ok()
{
return true;
}
assert_eq!(
std::env::var("FLOWRS_ALLOW_MISSING_CARGO").as_deref(),
Ok("1"),
"agent_corpus: no cargo on PATH; the corpus cannot be proven without it \
(set FLOWRS_ALLOW_MISSING_CARGO=1 to skip on purpose)"
);
false
}
#[test]
fn every_corpus_entry_builds_and_passes_what_it_claims() {
if !cargo_available() {
eprintln!("SKIP agent_corpus: no cargo (FLOWRS_ALLOW_MISSING_CARGO=1)");
return;
}
let reg = builtin_registry();
let tc = Native::default();
let mut failures = Vec::new();
// Which entries' tier agreement holds the whole program, and which holds it node by node.
let (mut whole, mut per_widget): (Vec<&str>, Vec<&str>) = (Vec::new(), Vec::new());
for e in corpus::entries() {
let parsed = match e.parse() {
Ok(p) => p,
Err(err) => {
failures.push(format!("{}: does not parse: {err:?}", e.slug));
continue;
}
};
let v = verify::check_graph(None, &parsed.graph, &parsed.origin, reg, &tc, &e.expect);
if !v.verified() {
failures.push(format!("{}: not verified\n{}", e.slug, v.feedback()));
continue;
}
for stage in &e.proof {
match v.status(*stage) {
Some(Status::Passed(_)) => {}
other => failures.push(format!(
"{}: claims {} passed, it is {other:?}",
e.slug,
stage.label()
)),
}
}
// An entry with test vectors must claim the tests it has.
if !e.expect.values.is_empty() && !e.proof.contains(&Stage::Tests) {
failures.push(format!(
"{}: has test vectors but does not claim `tests`",
e.slug
));
}
if let Some(Status::Passed(note)) = v.status(Stage::Tiers) {
if note.contains("widget node(s) agree") {
per_widget.push(e.slug);
} else {
whole.push(e.slug);
}
// A graph on flowrs-dsp (its filters, its spectra) is held whole: the oscillator, the
// filter and the spectrum run together, not node by node. (A test record's graph is
// compared per widget: the editor holds a record as JSON text, the program as a struct.)
let dsp = parsed.graph.to_rust().is_ok_and(|p| {
p.lines()
.any(|l| l.starts_with("// Cargo.toml needs:") && l.contains("flowrs_dsp"))
});
if dsp && !note.contains("the whole program, built against") {
failures.push(format!(
"{}: built on flowrs-dsp, but its tiers held only per widget: {note}",
e.slug
));
}
}
println!("{:<22} {}", e.slug, v.stage_line());
}
println!("tiers held whole: {whole:?}\ntiers held per widget: {per_widget:?}");
assert!(failures.is_empty(), "\n{}", failures.join("\n\n"));
}
/// The corpus must cover what the lessons teach and what the agent edits most: at least
/// the size it shipped with, and at least one entry proven all the way to tier agreement
/// from each of the language primitives, the widget library, and a held-wire loop.
#[test]
fn the_corpus_covers_primitives_widgets_and_loops_to_tier_agreement() {
let all = corpus::entries();
assert!(all.len() >= 19, "{}", all.len());
let tiers = |slug: &str| {
corpus::get(slug)
.unwrap_or_else(|| panic!("{slug}"))
.proof
.contains(&Stage::Tiers)
};
assert!(tiers("sum_to_5") && tiers("float_sum") && tiers("held_counter"));
}