Files
Aura/fieldtests/cycle-295-shell-boundary/sb_2_campaign.rs
T
claude 9df217d868 fieldtest: shell-boundary — 4 examples, 6 findings
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
2026-07-21 07:10:09 +02:00

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,
&reg,
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:?}"),
}
}