9df217d868
Downstream-consumer corpus for the #295 library surface: a standalone workspace (path-deps, no aura-cli in the link graph — cargo tree verified) exercising the four cycle axes as a World program would, public interface only: a DefaultMemberRunner member run over real GER40, a hand-authored campaign document through aura_campaign::execute, the IC + registry deflation dispatch as library calls, and load_family/reproduce round-trips. Run transcripts committed beside the sources. Findings routed separately: the family-id mismatch between the registry enumeration and the reproduce keying (list-then-reproduce dead-ends) to debug; the reproduce-API friction (no report on the simple path; DataSource/pip re-specification the manifest already holds, wrong pip silently DIVERGED) to a follow-up. Four working confirmations, chief among them the cycle's acceptance claim: all four axes compiled first-try from the public docs alone. refs #295
111 lines
4.2 KiB
Rust
111 lines
4.2 KiB
Rust
//! Axis 2 — campaign execution driven through `aura_campaign::execute` with the
|
|
//! default runner over a tiny hand-authored campaign + process document. Author
|
|
//! the two closed-vocabulary documents as JSON, canonicalize + content-address
|
|
//! them via aura-research, register the artifacts, then run the whole family/
|
|
//! validation machinery. Library crates only; no `aura` binary.
|
|
use std::collections::BTreeMap;
|
|
use std::num::NonZeroUsize;
|
|
|
|
use aura_campaign::{execute, MemberRunner};
|
|
use aura_ingest::default_data_server;
|
|
use aura_research::{
|
|
campaign_to_json, content_id_of, parse_campaign, parse_process, process_to_json,
|
|
};
|
|
use aura_runner::{DefaultMemberRunner, Env};
|
|
|
|
const SYMBOL: &str = "GER40";
|
|
const FROM_MS: i64 = 1_725_148_800_000; // 2024-09-01
|
|
const TO_MS: i64 = 1_727_740_800_000; // 2024-10-01
|
|
|
|
fn main() {
|
|
let server = default_data_server();
|
|
if !server.has_symbol(SYMBOL) {
|
|
println!("skip: no local {SYMBOL} archive — nothing to demonstrate.");
|
|
return;
|
|
}
|
|
|
|
// --- 1. the strategy blueprint (shipped example) + its content id ------------
|
|
let blueprint_json = std::fs::read_to_string(concat!(
|
|
env!("CARGO_MANIFEST_DIR"),
|
|
"/../../crates/aura-cli/examples/r_sma.json"
|
|
))
|
|
.expect("shipped example blueprint r_sma.json");
|
|
let bp_id = content_id_of(&blueprint_json);
|
|
|
|
// --- 2. a minimal process document: one selection-free sweep -----------------
|
|
let process_src = r#"{
|
|
"format_version": 1,
|
|
"kind": "process",
|
|
"name": "sb-explore-only-sweep",
|
|
"pipeline": [ { "block": "std::sweep" } ]
|
|
}"#;
|
|
let process_doc = parse_process(process_src).expect("process parses");
|
|
let process_canon = process_to_json(&process_doc);
|
|
let process_id = content_id_of(&process_canon);
|
|
|
|
// --- 3. a minimal campaign document referencing both by content id -----------
|
|
let campaign_src = format!(
|
|
r#"{{
|
|
"format_version": 1,
|
|
"kind": "campaign",
|
|
"name": "sb-ger40-sma-min",
|
|
"seed": 7,
|
|
"data": {{
|
|
"instruments": ["{SYMBOL}"],
|
|
"windows": [ {{ "from_ms": {FROM_MS}, "to_ms": {TO_MS} }} ]
|
|
}},
|
|
"strategies": [
|
|
{{
|
|
"ref": {{ "content_id": "{bp_id}" }},
|
|
"axes": {{ "fast.length": {{ "kind": "I64", "values": [2, 3] }} }}
|
|
}}
|
|
],
|
|
"process": {{ "ref": {{ "content_id": "{process_id}" }} }},
|
|
"presentation": {{ "persist_taps": [], "emit": ["family_table"] }}
|
|
}}"#
|
|
);
|
|
let campaign_doc = parse_campaign(&campaign_src).expect("campaign parses");
|
|
let campaign_canon = campaign_to_json(&campaign_doc);
|
|
let campaign_id = content_id_of(&campaign_canon);
|
|
|
|
// --- 4. wire the runner + registry, register the artifacts -------------------
|
|
let env = Env::std();
|
|
println!("runs root: {}", env.runs_root().display());
|
|
let reg = env.registry();
|
|
reg.put_blueprint(&bp_id, &blueprint_json).expect("store blueprint");
|
|
reg.put_process(&process_canon).expect("store process");
|
|
reg.put_campaign(&campaign_canon).expect("store campaign");
|
|
|
|
let runner = DefaultMemberRunner::new(&env, server, BTreeMap::new(), Vec::new());
|
|
let strategies = vec![(bp_id.clone(), blueprint_json.clone())];
|
|
|
|
println!("campaign_id={campaign_id}");
|
|
println!("executing campaign (1 cell, sweep over fast.length in [2,3])…");
|
|
match execute(
|
|
&campaign_id,
|
|
&campaign_doc,
|
|
&process_doc,
|
|
&strategies,
|
|
&runner as &dyn MemberRunner,
|
|
®,
|
|
NonZeroUsize::new(1).unwrap(),
|
|
) {
|
|
Ok(outcome) => {
|
|
println!("campaign ran OK. run#={} cells={}", outcome.run, outcome.cells.len());
|
|
for (ci, cell) in outcome.cells.iter().enumerate() {
|
|
println!(" cell {ci}: {} stage-families", cell.families.len());
|
|
for fam in &cell.families {
|
|
println!(
|
|
" stage {} block {} family_id={} members={}",
|
|
fam.stage,
|
|
fam.block,
|
|
fam.family_id,
|
|
fam.reports.len()
|
|
);
|
|
}
|
|
}
|
|
}
|
|
Err(fault) => println!("campaign fault: {fault:?}"),
|
|
}
|
|
}
|