feat: the IC becomes the second metric vocabulary; rosters single-sourced
The A1 cut of #147 item 2, part 2 of 2 (the consumers), completing what part 1 (the MetricVocabulary substrate) set up: - aura-campaign's RANKABLE_METRICS hand-copy becomes a re-export of the backtest vocabulary's roster; the #190 guard test extends to pin the roster nesting (rankable == vocabulary roster, rankable within per-member, per-member within the research vocabulary) and the legacy exposure_sign_flips alias, so any drift fails a test loudly. The research and per-member rosters themselves stay hand-copies by ratified isolation (#190 accepted residual) — now oracle-pinned instead of trusted. - aura-cli gains IcMetrics + IcKey implementing MetricVocabulary: the second PRODUCTION implementor. The standalone `aura measure ic` reduction now computes its permutation p via the shared null_draw + one_sided_p_laplace building blocks (independent draws instead of chained shuffles — statistically equivalent, deterministic per seed; emitted p values may differ in the last digits from #290's). - Acceptance proven at the registry boundary: an engineered SweepFamily<IcMetrics> deflates through optimize_deflated to a LOW overfit probability and a noise family to a HIGH one (the permutation null, dispatched by the vocabulary — the deflation machinery is no longer baked-in R-only); same seed reproduces the identical FamilySelection; cross-vocabulary names are refused with the family's own roster in the prose (the C10 guard). A new cli_run E2E exercises the legacy alias through the real `aura runs family … rank` boundary. Deviation from the plan, forced by the compiler: IcMetrics additionally derives Debug (unwrap_err on the deflation Result needs it; mirrors RunMetrics). Verification: full workspace suite green (no FAILED, no compile errors), clippy -D warnings clean, C18 goldens (cli_run, measure_ic, c28_layering) green unchanged. A2 — measurement runs as sweep-family citizens — stays deliberately deferred until a concrete campaign demand exists. closes #147
This commit is contained in:
@@ -144,14 +144,10 @@ pub const PER_MEMBER_METRICS: &[&str] = &[
|
||||
"sqn", "net_expectancy_r",
|
||||
];
|
||||
|
||||
/// The registry's rankable roster (`resolve_metric`'s name set) — the metrics
|
||||
/// a sweep/walk_forward stage may select on. Hand-copied (#190); drift fails
|
||||
/// safe (a name the registry would refuse is refused here first, before any
|
||||
/// member runs).
|
||||
pub const RANKABLE_METRICS: &[&str] = &[
|
||||
"total_pips", "max_drawdown", "bias_sign_flips",
|
||||
"sqn", "sqn_normalized", "expectancy_r", "net_expectancy_r",
|
||||
];
|
||||
/// The rankable subset a stage's `rank_by`/`select` may name — re-exported
|
||||
/// from the backtest vocabulary (single source, #147): this roster and the
|
||||
/// registry's refusal prose can no longer drift.
|
||||
pub use aura_backtest::RANKABLE_METRICS;
|
||||
|
||||
/// Deflation resample count — re-exported from `aura-registry`'s shared
|
||||
/// definition (single-sourced, #199).
|
||||
|
||||
@@ -107,3 +107,31 @@ fn metric_vocabulary_covers_all_shipped_scalar_metrics() {
|
||||
top-level enumeration)"
|
||||
);
|
||||
}
|
||||
|
||||
/// #147: the rankable roster is single-sourced from the vocabulary impl, the
|
||||
/// rosters nest (rankable ⊆ per-member ⊆ research vocabulary), and the legacy
|
||||
/// CLI alias keeps resolving. Any drift fails here, loudly.
|
||||
#[test]
|
||||
fn rankable_roster_is_single_sourced_and_nested() {
|
||||
use aura_engine::MetricVocabulary;
|
||||
|
||||
assert_eq!(
|
||||
aura_campaign::RANKABLE_METRICS,
|
||||
<RunMetrics as MetricVocabulary>::known(),
|
||||
"campaign roster must BE the vocabulary's roster"
|
||||
);
|
||||
for name in aura_campaign::RANKABLE_METRICS {
|
||||
assert!(
|
||||
aura_campaign::PER_MEMBER_METRICS.contains(name),
|
||||
"rankable metric '{name}' missing from PER_MEMBER_METRICS"
|
||||
);
|
||||
}
|
||||
for name in aura_campaign::PER_MEMBER_METRICS {
|
||||
assert!(
|
||||
aura_research::metric_vocabulary().contains(name),
|
||||
"per-member metric '{name}' missing from the research vocabulary"
|
||||
);
|
||||
}
|
||||
// the pre-rename CLI alias must keep resolving (back-compat).
|
||||
assert!(<RunMetrics as MetricVocabulary>::resolve("exposure_sign_flips").is_some());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user