refactor: extract the member-run recipe into library crates (#295 part 1)

The shell no longer defines what an aura backtest is. Tasks 1-9 of the
shell-boundary cycle — structural extraction, behaviour byte-identical:

- aura-runner (new; the C28 assembly position): input binding (the C26
  module, moved whole), the C1-load-bearing param<->config translators,
  harness assembly (wrap_r / run_signal_r / run_blueprint_member and the
  probe/reopen cluster), axis + risk-regime conventions (bind_axes et
  al.), the campaign family builders + MC guards, reproduce
  (process::exit -> RunnerError, shell remaps to identical bytes), the
  measurement-run orchestration, project loading (Env / cdylib load /
  charter / staleness, moved whole), the coverage gap-walk (deduplicated
  onto interior_gap_months), and DefaultMemberRunner — the public
  implementation of aura_campaign::MemberRunner (ex CliMemberRunner).
  The MemberRunner trait stays in aura-campaign; the column still
  imports no harness/data-binding machinery.
- aura-measurement (new; seeds C28 rung 3): the IcMetrics/IcKey
  vocabulary + information_coefficient, verbatim incl. serde derives
  (#294 duplicate-timestamp semantics move as-is, unresolved).
- aura-backtest: the pure per-run scaffold (point_from_params,
  wf_ms_sizes / fit_wf_ms_sizes, intersect_shared_window).
- shell residue: main.rs / campaign_run.rs keep argv/dispatch,
  argv->document translation, and presentation only;
  walkforward_summary_json_from_reports now calls the public
  aura_engine::param_stability instead of its inline twin.
- worked example (crates/aura-runner/examples/world_member_run.rs): a
  World program runs a member backtest through the library alone.

Held quality findings, adjudicated: the plan's literal pub-visibility
list for binding.rs kept (cosmetic); ~20 refusal sites inside
aura-runner (family/member/measure/translate) still process::exit —
behaviour-identical today, conversion to RunnerError is filed forward
(refs #297); rustfmt line-width drift on re-pathed call sites left for
a repo-wide fmt decision.

Verification: cargo test --workspace green (1471 passed, 0 failed);
cargo clippy --workspace --all-targets -D warnings clean. Byte-identity
is pinned by the untouched shell E2E suites (cli_run, measure_ic,
run_measurement, research_docs, run_refuses_unrunnable_blueprint,
tap_recording — zero assertion edits).

Remaining in this cycle: full-workspace c28_layering + shell-content
check, ledger amendments (C28 assembly position, C25/C14 control-surface
consequence, C26 realization note).

refs #295
This commit is contained in:
2026-07-21 05:20:27 +02:00
parent 2cf4574e33
commit 5c2ac982bc
29 changed files with 5048 additions and 4370 deletions
@@ -0,0 +1,43 @@
//! A World program driving the canonical member-run recipe as a library —
//! no `aura` binary involved (#295 acceptance evidence: builds against
//! library crates only). Runs one member backtest of the shipped breakout
//! blueprint over real archive data when present; skips cleanly otherwise.
use std::collections::BTreeMap;
use aura_campaign::{CellSpec, MemberRunner};
use aura_ingest::default_data_server;
use aura_runner::{DefaultMemberRunner, Env};
const SYMBOL: &str = "GER40";
// September 2024, inclusive epoch-ms — the same month the ger40 examples use.
const WINDOW_MS: (i64, i64) = (1_725_148_800_000, 1_727_740_799_999);
fn main() {
let server = default_data_server();
if !server.has_symbol(SYMBOL) {
println!("skip: no local archive — nothing to demonstrate.");
return;
}
let blueprint_json = std::fs::read_to_string(concat!(
env!("CARGO_MANIFEST_DIR"),
"/../aura-cli/examples/r_breakout.json"
))
.expect("shipped example blueprint");
let env = Env::std();
let runner = DefaultMemberRunner::new(&env, server, BTreeMap::new(), Vec::new());
let cell = CellSpec {
strategy_ordinal: 0,
strategy_id: aura_research::content_id_of(&blueprint_json),
blueprint_json,
axes: BTreeMap::new(),
instrument: SYMBOL.to_string(),
window_ms: WINDOW_MS,
regime: None,
regime_ordinal: 0,
};
match runner.run_member(&cell, &[], WINDOW_MS) {
Ok(report) => println!("member ran: {:?}", report.metrics),
Err(fault) => println!("member fault (data-dependent): {fault:?}"),
}
}