chore(cli,docs): #220 cycle-close audit — doc reconcile + dispatch dedup
Cycle-close audit for the verb-axis-generalization cycle (a2294c7,e7efe1f,b849bb7). Architect drift review: what holds — all four verbs route through the one validate_and_register_axes seam into the campaign executor; RGrid gone workspace-wide; zero too_many_arguments allows in verb_sugar.rs; no r_sma_open embed at the verb dispatch sites (the aura-graph default embed survives by design). Five drift items found, all resolved fix-path in this commit: - README (blueprint-verbs section + mc row), glossary (walk-forward entry), and ledger (verb-dissolution passage) reconciled to the shipped generic grammar; the ledger HISTORY note now separates the two supersessions correctly (#159 retired the built-in --strategy demo surface; #220 de-welded the verbs) instead of mis-attributing the weld removal to #159. - Four stale characterization doc-comments in cli_run.rs reworded: the retired welded grammar is now named as the pinned grades' provenance, not the current spelling; one dangling reference to a deleted test repointed to the live anchor. - The quadruplicated dispatch blocks extracted into two shared helpers beside validate_and_register_axes: exit_axis_register_error (the AxisRegisterError exit-map, byte-identical stderr + exit codes) and campaign_window_ms (from_choice -> full_window -> unix-ms clip); generalize's explicit unclipped (Some, Some) passthrough arm is untouched — only its fallback arm, which already ran the identical mechanics, calls the helper. Regression gate green, no baseline moved (nothing to ratify): cargo test --workspace exit 0, 62 test-result groups, 0 failures; clippy --workspace --all-targets -D warnings clean; cargo doc --workspace --no-deps 0 warnings. Spent cycle spec + plan working files discarded per lifecycle. refs #220
This commit is contained in:
@@ -44,16 +44,18 @@ Invoke it as `aura <command> …` (examples below use the plain name).
|
|||||||
## Running & orchestrating a loaded blueprint
|
## Running & orchestrating a loaded blueprint
|
||||||
|
|
||||||
These verbs all take the **blueprint file as their first positional argument**
|
These verbs all take the **blueprint file as their first positional argument**
|
||||||
and drive a family of runs over it. (`walkforward`, `mc`, and `generalize` also
|
and drive a family of runs over it. `walkforward`, `mc`, and `generalize` share
|
||||||
accept a legacy built-in form selected by `--strategy` instead of a `.json`
|
`sweep`'s generic grammar — the blueprint positional plus `--real` and a
|
||||||
path, for the engine's own bundled example strategies — see `--help`.)
|
repeatable `--axis <name>=<csv>` (`generalize` takes `--real <SYM1,SYM2,…>`, at
|
||||||
|
least two instruments, with a single value per axis) — see `--help`.
|
||||||
|
|
||||||
| Command | Purpose |
|
| Command | Purpose |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `aura run <bp.json>` | Run one backtest of a **closed** blueprint and print its report. An open (free-knob) blueprint is refused with a clean error — bind it, or use `sweep`. |
|
| `aura run <bp.json>` | Run one backtest of a **closed** blueprint and print its report. An open (free-knob) blueprint is refused with a clean error — bind it, or use `sweep`. |
|
||||||
| `aura sweep <bp.json> --list-axes` | **Discover** the blueprint's open, sweepable knobs. Prints each as `<name>:<kind>`. Run this first to learn the axis names. |
|
| `aura sweep <bp.json> --list-axes` | **Discover** the blueprint's open, sweepable knobs. Prints each as `<name>:<kind>`. Run this first to learn the axis names. |
|
||||||
| `aura sweep <bp.json> --axis <name>=<csv> [--axis …]` | Run a **grid family** over the named axes and persist it. |
|
| `aura sweep <bp.json> --axis <name>=<csv> [--axis …]` | Run a **grid family** over the named axes and persist it. |
|
||||||
| `aura mc <bp.json> --seeds <n>` | Run a **Monte-Carlo family** of `n` seeded realizations. Wants a **closed** blueprint (the inverse of sweep). |
|
| `aura mc <bp.json> --seeds <n>` | Run a **synthetic Monte-Carlo family** of `n` seeded realizations. Wants a **closed** blueprint (the inverse of sweep). |
|
||||||
|
| `aura mc <bp.json> --real <sym> --axis <name>=<csv> [--axis …]` | Run a **Monte-Carlo R-bootstrap campaign** over recorded data — driven through the same generated-campaign pipeline as `sweep`; `--block-len`/`--resamples`/`--seed` tune the bootstrap. |
|
||||||
| `aura walkforward <bp.json> --axis <name>=<csv> [--axis …]` | Run an **in-sample-refit walk-forward family** — rolling optimize + out-of-sample test across windows, stitched into one verdict + parameter stability. `--select` chooses the per-window objective. |
|
| `aura walkforward <bp.json> --axis <name>=<csv> [--axis …]` | Run an **in-sample-refit walk-forward family** — rolling optimize + out-of-sample test across windows, stitched into one verdict + parameter stability. `--select` chooses the per-window objective. |
|
||||||
| `aura runs families` | List every persisted family (id, kind, member count). |
|
| `aura runs families` | List every persisted family (id, kind, member count). |
|
||||||
| `aura runs family <id> [rank <metric>]` | List one family's members, optionally ranked best-first by an R metric (e.g. `sqn_normalized`, `expectancy_r`). |
|
| `aura runs family <id> [rank <metric>]` | List one family's members, optionally ranked best-first by an R metric (e.g. `sqn_normalized`, `expectancy_r`). |
|
||||||
|
|||||||
+52
-81
@@ -2509,6 +2509,44 @@ fn validate_and_register_axes(
|
|||||||
Ok((canonical, raw_axes))
|
Ok((canonical, raw_axes))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Exit-map for a `validate_and_register_axes` failure — the stderr line and
|
||||||
|
/// exit code every campaign dispatcher (sweep/generalize/walkforward/mc)
|
||||||
|
/// preserves: an unknown axis is a usage error (exit 2, echoed before the
|
||||||
|
/// archive is touched), a registry write failure a runtime error (exit 1).
|
||||||
|
fn exit_axis_register_error(e: AxisRegisterError) -> ! {
|
||||||
|
match e {
|
||||||
|
AxisRegisterError::UnknownAxis(m) => {
|
||||||
|
eprintln!("aura: {m}");
|
||||||
|
std::process::exit(2)
|
||||||
|
}
|
||||||
|
AxisRegisterError::Registry(m) => {
|
||||||
|
eprintln!("aura: {m}");
|
||||||
|
std::process::exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The shared campaign window in Unix-ms, clipped to the archive. `full_window`
|
||||||
|
/// probes the ARCHIVE's actual first/last bar in range (never the literal ms
|
||||||
|
/// request) and returns aura's native epoch-ns `Timestamp` (the ms->ns crossing
|
||||||
|
/// happens once, at the ingest seam — C3); the campaign document's `Window`
|
||||||
|
/// field is Unix-ms (same currency as `--from`/`--to` and every existing
|
||||||
|
/// campaign fixture, e.g. `campaign_doc_json` in research_docs.rs). Convert
|
||||||
|
/// back through the seam's own `aura_ingest::epoch_ns_to_unix_ms` at this one
|
||||||
|
/// seam-crossing (never reimplement the division inline) so the executor's
|
||||||
|
/// `unix_ms_to_epoch_ns` re-normalizes exactly once downstream, not twice.
|
||||||
|
/// Shared by the campaign dispatchers — sweep/walkforward/mc always clip;
|
||||||
|
/// generalize reaches here only through its no-explicit-window fallback (an
|
||||||
|
/// explicit `--from`+`--to` pair passes through unclipped there BY DESIGN).
|
||||||
|
fn campaign_window_ms(choice: DataChoice, env: &project::Env) -> (i64, i64) {
|
||||||
|
let source = DataSource::from_choice(choice, env);
|
||||||
|
let (from_ts, to_ts) = source.full_window(env);
|
||||||
|
(
|
||||||
|
aura_ingest::epoch_ns_to_unix_ms(from_ts),
|
||||||
|
aura_ingest::epoch_ns_to_unix_ms(to_ts),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/// `aura run`: the loaded-blueprint branch (an existing `.json` first-positional) or
|
/// `aura run`: the loaded-blueprint branch (an existing `.json` first-positional) or
|
||||||
/// the built-in harness-kind dispatch.
|
/// the built-in harness-kind dispatch.
|
||||||
fn dispatch_run(a: RunCmd, env: &project::Env) {
|
fn dispatch_run(a: RunCmd, env: &project::Env) {
|
||||||
@@ -2638,33 +2676,17 @@ fn dispatch_generalize(a: GeneralizeCmd, env: &project::Env) {
|
|||||||
std::process::exit(2);
|
std::process::exit(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let (canonical, raw_axes) =
|
let (canonical, raw_axes) = validate_and_register_axes(&doc, &axes, env)
|
||||||
validate_and_register_axes(&doc, &axes, env).unwrap_or_else(|e| match e {
|
.unwrap_or_else(|e| exit_axis_register_error(e));
|
||||||
AxisRegisterError::UnknownAxis(m) => {
|
|
||||||
eprintln!("aura: {m}");
|
|
||||||
std::process::exit(2);
|
|
||||||
}
|
|
||||||
AxisRegisterError::Registry(m) => {
|
|
||||||
eprintln!("aura: {m}");
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Window: the explicit --from/--to when both present (byte-identical to the
|
// Window: the explicit --from/--to when both present (byte-identical to the
|
||||||
// retired welded path, verified by the exact-grade anchor); otherwise the
|
// retired welded path, verified by the exact-grade anchor); otherwise the
|
||||||
// first symbol's full archive window as the single shared campaign window.
|
// first symbol's full archive window as the single shared campaign window.
|
||||||
let (from_ms, to_ms) = match (from, to) {
|
let (from_ms, to_ms) = match (from, to) {
|
||||||
(Some(f), Some(t)) => (f, t),
|
(Some(f), Some(t)) => (f, t),
|
||||||
_ => {
|
_ => campaign_window_ms(
|
||||||
let source = DataSource::from_choice(
|
DataChoice::Real { symbol: symbols[0].clone(), from_ms: from, to_ms: to },
|
||||||
DataChoice::Real { symbol: symbols[0].clone(), from_ms: from, to_ms: to },
|
env,
|
||||||
env,
|
),
|
||||||
);
|
|
||||||
let (from_ts, to_ts) = source.full_window(env);
|
|
||||||
(
|
|
||||||
aura_ingest::epoch_ns_to_unix_ms(from_ts),
|
|
||||||
aura_ingest::epoch_ns_to_unix_ms(to_ts),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let inv = verb_sugar::SugarInvocation {
|
let inv = verb_sugar::SugarInvocation {
|
||||||
axes: &raw_axes,
|
axes: &raw_axes,
|
||||||
@@ -2796,34 +2818,11 @@ fn dispatch_sweep(a: SweepCmd, env: &project::Env) {
|
|||||||
// strip are single-sourced in `validate_and_register_axes`
|
// strip are single-sourced in `validate_and_register_axes`
|
||||||
// (data-free, so this fires before the archive is touched).
|
// (data-free, so this fires before the archive is touched).
|
||||||
let (canonical, raw_axes) = validate_and_register_axes(&doc, &axes, env)
|
let (canonical, raw_axes) = validate_and_register_axes(&doc, &axes, env)
|
||||||
.unwrap_or_else(|e| match e {
|
.unwrap_or_else(|e| exit_axis_register_error(e));
|
||||||
AxisRegisterError::UnknownAxis(m) => {
|
|
||||||
eprintln!("aura: {m}");
|
|
||||||
std::process::exit(2);
|
|
||||||
}
|
|
||||||
AxisRegisterError::Registry(m) => {
|
|
||||||
eprintln!("aura: {m}");
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let symbol = symbol.clone();
|
let symbol = symbol.clone();
|
||||||
let source = DataSource::from_choice(data, env);
|
// Archive-clipped Unix-ms window; the ns->ms seam-crossing
|
||||||
let (from_ts, to_ts) = source.full_window(env);
|
// rationale lives on `campaign_window_ms`.
|
||||||
// `full_window` probes the ARCHIVE's actual first/last bar
|
let (from_ms, to_ms) = campaign_window_ms(data, env);
|
||||||
// and returns aura's native epoch-ns `Timestamp` (the
|
|
||||||
// ms->ns crossing happens once, at the ingest seam — C3);
|
|
||||||
// the campaign document's `Window` field is Unix-ms (same
|
|
||||||
// currency as `--from`/`--to` and every existing campaign
|
|
||||||
// fixture, e.g. `campaign_doc_json` in research_docs.rs).
|
|
||||||
// Convert back through the seam's own
|
|
||||||
// `aura_ingest::epoch_ns_to_unix_ms` at this one
|
|
||||||
// seam-crossing (never reimplement the division inline) so
|
|
||||||
// the executor's `unix_ms_to_epoch_ns` re-normalizes
|
|
||||||
// exactly once downstream, not twice.
|
|
||||||
let (from_ms, to_ms) = (
|
|
||||||
aura_ingest::epoch_ns_to_unix_ms(from_ts),
|
|
||||||
aura_ingest::epoch_ns_to_unix_ms(to_ts),
|
|
||||||
);
|
|
||||||
let inv = verb_sugar::SugarInvocation {
|
let inv = verb_sugar::SugarInvocation {
|
||||||
axes: &raw_axes,
|
axes: &raw_axes,
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
@@ -2900,16 +2899,7 @@ fn dispatch_walkforward(a: WalkforwardCmd, env: &project::Env) {
|
|||||||
// strip are single-sourced in `validate_and_register_axes`
|
// strip are single-sourced in `validate_and_register_axes`
|
||||||
// (data-free, so this fires before the archive is touched).
|
// (data-free, so this fires before the archive is touched).
|
||||||
let (canonical, raw_axes) = validate_and_register_axes(&doc, &axes, env)
|
let (canonical, raw_axes) = validate_and_register_axes(&doc, &axes, env)
|
||||||
.unwrap_or_else(|e| match e {
|
.unwrap_or_else(|e| exit_axis_register_error(e));
|
||||||
AxisRegisterError::UnknownAxis(m) => {
|
|
||||||
eprintln!("aura: {m}");
|
|
||||||
std::process::exit(2);
|
|
||||||
}
|
|
||||||
AxisRegisterError::Registry(m) => {
|
|
||||||
eprintln!("aura: {m}");
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// Unlike `dispatch_generalize` (a single run per instrument, insensitive
|
// Unlike `dispatch_generalize` (a single run per instrument, insensitive
|
||||||
// to a day's edge shift), `blueprint_walkforward_family` sources its span
|
// to a day's edge shift), `blueprint_walkforward_family` sources its span
|
||||||
// from `DataSource::wf_full_span`, which — for Real — ALWAYS clips
|
// from `DataSource::wf_full_span`, which — for Real — ALWAYS clips
|
||||||
@@ -2918,15 +2908,10 @@ fn dispatch_walkforward(a: WalkforwardCmd, env: &project::Env) {
|
|||||||
// calendar placement, so the roller must clip identically here too, even
|
// calendar placement, so the roller must clip identically here too, even
|
||||||
// when both flags are given, or the per-window winners and OOS pips diverge
|
// when both flags are given, or the per-window winners and OOS pips diverge
|
||||||
// from the committed exact-grade anchor.
|
// from the committed exact-grade anchor.
|
||||||
let source = DataSource::from_choice(
|
let (from_ms, to_ms) = campaign_window_ms(
|
||||||
DataChoice::Real { symbol: symbol.clone(), from_ms: from, to_ms: to },
|
DataChoice::Real { symbol: symbol.clone(), from_ms: from, to_ms: to },
|
||||||
env,
|
env,
|
||||||
);
|
);
|
||||||
let (from_ts, to_ts) = source.full_window(env);
|
|
||||||
let (from_ms, to_ms) = (
|
|
||||||
aura_ingest::epoch_ns_to_unix_ms(from_ts),
|
|
||||||
aura_ingest::epoch_ns_to_unix_ms(to_ts),
|
|
||||||
);
|
|
||||||
let (is_ms, oos_ms, step_ms) = wf_ms_sizes();
|
let (is_ms, oos_ms, step_ms) = wf_ms_sizes();
|
||||||
let inv = verb_sugar::SugarInvocation {
|
let inv = verb_sugar::SugarInvocation {
|
||||||
axes: &raw_axes,
|
axes: &raw_axes,
|
||||||
@@ -3017,31 +3002,17 @@ fn dispatch_mc(a: McCmd, env: &project::Env) {
|
|||||||
// strip are single-sourced in `validate_and_register_axes`
|
// strip are single-sourced in `validate_and_register_axes`
|
||||||
// (data-free, so this fires before the archive is touched).
|
// (data-free, so this fires before the archive is touched).
|
||||||
let (canonical, raw_axes) = validate_and_register_axes(&doc, &axes, env)
|
let (canonical, raw_axes) = validate_and_register_axes(&doc, &axes, env)
|
||||||
.unwrap_or_else(|e| match e {
|
.unwrap_or_else(|e| exit_axis_register_error(e));
|
||||||
AxisRegisterError::UnknownAxis(m) => {
|
|
||||||
eprintln!("aura: {m}");
|
|
||||||
std::process::exit(2);
|
|
||||||
}
|
|
||||||
AxisRegisterError::Registry(m) => {
|
|
||||||
eprintln!("aura: {m}");
|
|
||||||
std::process::exit(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// `blueprint_walkforward_family` sources its span from
|
// `blueprint_walkforward_family` sources its span from
|
||||||
// `DataSource::wf_full_span`, which for Real ALWAYS clips `--from`/`--to`
|
// `DataSource::wf_full_span`, which for Real ALWAYS clips `--from`/`--to`
|
||||||
// to the archive's actual first/last bar in range: a holiday/weekend edge
|
// to the archive's actual first/last bar in range: a holiday/weekend edge
|
||||||
// shifts every IS/OOS window's calendar placement, so the roller must clip
|
// shifts every IS/OOS window's calendar placement, so the roller must clip
|
||||||
// identically here too, even when both flags are given, or the per-window
|
// identically here too, even when both flags are given, or the per-window
|
||||||
// winners and pooled OOS series diverge from the committed exact-grade anchor.
|
// winners and pooled OOS series diverge from the committed exact-grade anchor.
|
||||||
let source = DataSource::from_choice(
|
let (from_ms, to_ms) = campaign_window_ms(
|
||||||
DataChoice::Real { symbol: symbol.clone(), from_ms: from, to_ms: to },
|
DataChoice::Real { symbol: symbol.clone(), from_ms: from, to_ms: to },
|
||||||
env,
|
env,
|
||||||
);
|
);
|
||||||
let (from_ts, to_ts) = source.full_window(env);
|
|
||||||
let (from_ms, to_ms) = (
|
|
||||||
aura_ingest::epoch_ns_to_unix_ms(from_ts),
|
|
||||||
aura_ingest::epoch_ns_to_unix_ms(to_ts),
|
|
||||||
);
|
|
||||||
let (is_ms, oos_ms, step_ms) = wf_ms_sizes();
|
let (is_ms, oos_ms, step_ms) = wf_ms_sizes();
|
||||||
let inv = verb_sugar::SugarInvocation {
|
let inv = verb_sugar::SugarInvocation {
|
||||||
axes: &raw_axes,
|
axes: &raw_axes,
|
||||||
|
|||||||
@@ -1036,9 +1036,11 @@ fn aura_sweep_real_blueprint_subset_axes_refuses_without_store_litter() {
|
|||||||
/// The synthetic seed-resweep `mc` is undefined over real bars (one realization ->
|
/// The synthetic seed-resweep `mc` is undefined over real bars (one realization ->
|
||||||
/// identical members), so a bare `aura mc --real EURUSD` — with no R candidate — is
|
/// identical members), so a bare `aura mc --real EURUSD` — with no R candidate — is
|
||||||
/// REJECTED (usage on stderr, exit 2) at the binary boundary. The real path is
|
/// REJECTED (usage on stderr, exit 2) at the binary boundary. The real path is
|
||||||
/// reachable ONLY via `--strategy r-sma` (the R-bootstrap over the pooled OOS R
|
/// reachable ONLY via the blueprint positional + `--axis` campaign form (the
|
||||||
/// series, `mc_strategy_r_sma_prints_a_bootstrap_line_deterministically`); a
|
/// R-bootstrap over the pooled OOS R series,
|
||||||
/// `--real` without it stays a usage error. NOT gated — the refusal precedes any
|
/// `mc_r_bootstrap_real_e2e_pins_the_exact_current_grade`; spelled
|
||||||
|
/// `--strategy r-sma` before the #220 argv migration); a `--real` without a
|
||||||
|
/// blueprint stays a usage error. NOT gated — the refusal precedes any
|
||||||
/// data access, so it is CI-safe on every machine.
|
/// data access, so it is CI-safe on every machine.
|
||||||
#[test]
|
#[test]
|
||||||
fn mc_rejects_real_flag_with_usage_exit_2() {
|
fn mc_rejects_real_flag_with_usage_exit_2() {
|
||||||
@@ -1770,14 +1772,16 @@ fn walkforward_dissolved_refuses_name_and_trace_together() {
|
|||||||
assert!(stderr.contains("mutually exclusive"), "name/trace refusal: {stderr}");
|
assert!(stderr.contains("mutually exclusive"), "name/trace refusal: {stderr}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Property (#210 T3, dispatch split): a successful `aura walkforward --strategy
|
/// Property (#210 T3, dispatch split): a successful real-data walkforward
|
||||||
/// r-sma --real` durably auto-registers exactly one generated process document, one
|
/// (`aura walkforward <blueprint> --real --axis …`; spelled `--strategy r-sma
|
||||||
|
/// --real` before the #220 argv migration) durably auto-registers exactly one
|
||||||
|
/// generated process document, one
|
||||||
/// generated campaign document (carrying the `--name` handle and the stop as a
|
/// generated campaign document (carrying the `--name` handle and the stop as a
|
||||||
/// non-empty single risk regime), and one campaign-run record — mirroring the
|
/// non-empty single risk regime), and one campaign-run record — mirroring the
|
||||||
/// generalize dissolution's audit trail. The persisted family set is exactly one
|
/// generalize dissolution's audit trail. The persisted family set is exactly one
|
||||||
/// `Sweep` family (the pipeline's leading `std::sweep(argmax)` stage) plus one
|
/// `Sweep` family (the pipeline's leading `std::sweep(argmax)` stage) plus one
|
||||||
/// `WalkForward` family (the per-window OOS reports) — the observable proof that
|
/// `WalkForward` family (the per-window OOS reports) — the observable proof that
|
||||||
/// `dispatch_walkforward`'s r-sma-real branch now runs through the one campaign
|
/// `dispatch_walkforward`'s real-data path runs through the one campaign
|
||||||
/// executor rather than the deleted inline roller. Gated on the shared GER40
|
/// executor rather than the deleted inline roller. Gated on the shared GER40
|
||||||
/// archive; skips cleanly on a data refusal.
|
/// archive; skips cleanly on a data refusal.
|
||||||
#[test]
|
#[test]
|
||||||
@@ -3234,19 +3238,22 @@ fn exit_codes_partition_usage_two_from_runtime_one() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Characterization pin (byte-identity anchor for the mc R-bootstrap dissolution,
|
/// Characterization pin (byte-identity anchor for the mc R-bootstrap dissolution,
|
||||||
/// #210, the last verb). The current `aura mc --strategy r-sma --real` runs the
|
/// #210, the last verb; argv since migrated to the generic form by #220).
|
||||||
/// inline rolling walk-forward, pools the per-window OOS trade-R series, and
|
/// `aura mc <blueprint> --real --axis …` pools the per-window OOS trade-R
|
||||||
/// r-bootstraps E[R] (`mc_r_bootstrap_report`). The dissolution reroutes this
|
/// series and r-bootstraps E[R] through the campaign
|
||||||
/// through the campaign `[std::sweep(argmax), std::walk_forward, std::monte_carlo]`
|
/// `[std::sweep(argmax), std::walk_forward, std::monte_carlo]`
|
||||||
/// process, whose terminal monte_carlo stage does the identical
|
/// process, whose terminal monte_carlo stage does the
|
||||||
/// `StageBootstrap::PooledOos(r_bootstrap(...))` seeded from the campaign seed -- so
|
/// `StageBootstrap::PooledOos(r_bootstrap(...))` seeded from the campaign seed -- so
|
||||||
/// the campaign seed must carry the mc `--seed`. The wf winners are
|
/// the campaign seed carries the mc `--seed`. The wf winners are
|
||||||
/// deflation-seed-independent (argmax), so the pooled series, and thus the
|
/// deflation-seed-independent (argmax), so the pooled series, and thus the
|
||||||
/// bootstrap, is stable across that seed remap (the walkforward anchor already
|
/// bootstrap, is stable across that seed remap (the walkforward anchor already
|
||||||
/// proved winner seed-independence). The multi-point grid makes the per-window
|
/// proved winner seed-independence). The multi-point grid makes the per-window
|
||||||
/// winner selection non-degenerate. This pins the EXACT current bootstrap grade of
|
/// winner selection non-degenerate. The pinned bootstrap grade of this fixed 2025
|
||||||
/// a fixed 2025 GER40 invocation; after the dissolution the same command must
|
/// GER40 invocation ORIGINATES from the pre-#210 inline rolling walk-forward
|
||||||
/// reproduce these bytes (the acceptance gate). Gated on the GER40 archive; skips
|
/// (`mc_r_bootstrap_report`) under the retired welded `aura mc --strategy r-sma
|
||||||
|
/// --real` grammar, and survived both the campaign dissolution and the #220 argv
|
||||||
|
/// migration byte-identically (the acceptance gate then, the regression anchor
|
||||||
|
/// now). Gated on the GER40 archive; skips
|
||||||
/// cleanly on a data refusal.
|
/// cleanly on a data refusal.
|
||||||
#[test]
|
#[test]
|
||||||
fn mc_r_bootstrap_real_e2e_pins_the_exact_current_grade() {
|
fn mc_r_bootstrap_real_e2e_pins_the_exact_current_grade() {
|
||||||
@@ -3350,7 +3357,9 @@ fn mc_dissolves_a_non_r_sma_blueprint() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Property: `aura mc --strategy r-sma --real` is now thin sugar over the one campaign
|
/// Property: real-data `aura mc <blueprint> --real --axis …` (the #210 dissolution
|
||||||
|
/// of the retired welded `--strategy r-sma` form, argv since migrated by #220) is
|
||||||
|
/// thin sugar over the one campaign
|
||||||
/// path — a successful run durably auto-registers exactly one generated process
|
/// path — a successful run durably auto-registers exactly one generated process
|
||||||
/// document, one generated campaign document (carrying the constant "mc" name and the
|
/// document, one generated campaign document (carrying the constant "mc" name and the
|
||||||
/// stop as a non-empty single risk regime), and one campaign-run record, and emits the
|
/// stop as a non-empty single risk regime), and one campaign-run record, and emits the
|
||||||
|
|||||||
+13
-6
@@ -2374,12 +2374,19 @@ the project layout and docs-by-role are open (#192 context).
|
|||||||
(`<bp.json> --real`), while `aura sweep --strategy r-sma --real` stays the inline built-in
|
(`<bp.json> --real`), while `aura sweep --strategy r-sma --real` stays the inline built-in
|
||||||
path (its member lines carry no instrument/topology_hash/selection stamp and register no
|
path (its member lines carry no instrument/topology_hash/selection stamp and register no
|
||||||
campaign document) — the built-in `--strategy` demo surface is #159's hard-wired-harness
|
campaign document) — the built-in `--strategy` demo surface is #159's hard-wired-harness
|
||||||
retirement target, not the dissolution's; for generalize/walkforward/mc the dissolved form
|
retirement target, not the dissolution's; for generalize/walkforward/mc the dissolved
|
||||||
is `--strategy r-sma --real`. [HISTORY — #159 (cuts 1b-4) has since landed
|
form is now the same generic grammar as sweep — an arbitrary blueprint positional plus
|
||||||
(post-2026-07-07): the retirement target has been hit — the built-in
|
`--real` and repeatable `--axis <wrapped-name>=<csv>` (#220). [HISTORY — superseded in
|
||||||
`--strategy` sweep/demo surface is retired and the inline `--strategy r-sma
|
two steps. #159 (cuts 1b-4, post-2026-07-07) retired the built-in `--strategy`
|
||||||
--real` path no longer exists; the surviving form is `aura <verb>
|
sweep/demo surface: the inline `aura sweep --strategy r-sma --real` path no longer
|
||||||
<blueprint.json> --axis …` over examples/r_*.json.] Milestone closed 2026-07-07 on a green end-to-end fieldtest
|
exists. #220 then removed the verbs' weld — at milestone close the dissolved form of
|
||||||
|
generalize/walkforward/mc was still the welded `--strategy r-sma --real`; #220 made
|
||||||
|
the three verbs blueprint-generic (arbitrary blueprint + arbitrary `--axis`; mc keeps
|
||||||
|
the synthetic `--seeds` family unchanged beside the new `--real --axis` campaign mode;
|
||||||
|
generalize takes `--real <SYM1,SYM2,…>`, >=2, with one value per axis), deleted the
|
||||||
|
welded `--strategy` grammar (clap rejects it, exit 2), dissolved `RGrid`, and unified
|
||||||
|
the verbs on the #214 invocation struct. The surviving form everywhere is `aura <verb>
|
||||||
|
<blueprint.json> --real … --axis …` over examples/r_*.json.] Milestone closed 2026-07-07 on a green end-to-end fieldtest
|
||||||
(0 bugs; behaviour preservation, campaign-substrate reach-through, and the risk-regime axis
|
(0 bugs; behaviour preservation, campaign-substrate reach-through, and the risk-regime axis
|
||||||
all confirmed); residual findings are discoverability/ergonomics follow-ups (#216 risk-axis
|
all confirmed); residual findings are discoverability/ergonomics follow-ups (#216 risk-axis
|
||||||
discoverability, #217 verb knob asymmetry, #218 no-project store litter).
|
discoverability, #217 verb knob asymmetry, #218 no-project store litter).
|
||||||
|
|||||||
+1
-1
@@ -301,7 +301,7 @@ The **optional** documented pre-trade-gate seam in the execution chain (`stop-ru
|
|||||||
|
|
||||||
### walk-forward
|
### walk-forward
|
||||||
**Avoid:** —
|
**Avoid:** —
|
||||||
An orchestration axis: rolling in-sample optimize + out-of-sample test across moving windows, stitched into one out-of-sample verdict plus parameter stability. As with `sweep`, every open knob named by `--list-axes` is **required** on a loaded blueprint — a subset is refused with the missing knob named; pin one with a single-value axis, there is no default. The `aura walkforward --strategy r-sma --real` CLI verb is now thin sugar over the `campaign document` path — translated to a generated campaign (`std::sweep → std::walk_forward`) run through the one executor (#210).
|
An orchestration axis: rolling in-sample optimize + out-of-sample test across moving windows, stitched into one out-of-sample verdict plus parameter stability. As with `sweep`, every open knob named by `--list-axes` is **required** on a loaded blueprint — a subset is refused with the missing knob named; pin one with a single-value axis, there is no default. The `aura walkforward <blueprint.json> --real <sym> --axis <name>=<csv> …` CLI verb is thin sugar over the `campaign document` path — translated to a generated campaign (`std::sweep → std::walk_forward`) run through the one executor (#210; blueprint-generic over arbitrary blueprints and axes since #220).
|
||||||
|
|
||||||
### World
|
### World
|
||||||
**Avoid:** —
|
**Avoid:** —
|
||||||
|
|||||||
Reference in New Issue
Block a user