refactor(stage1-r): rename the strategy-output param namespace exposure -> bias

Complete the deferred rename tail from cycle 0065's #126 (which renamed only the
typed metric, keeping the param namespace uniformly "exposure" so the single-run
rename would not smuggle in a ~30-site sweep-pinned change). Now renamed together
as one consistent unit, all driven by the Bias node's instance name:

- Bias::builder().named("exposure") -> .named("bias") (the harness builders +
  the engine fixtures in test_fixtures.rs / blueprint.rs);
- the derived knob path exposure.scale -> bias.scale (Composite::param_space
  derives the knob from the node name) -- the sweep .axis/.range bindings and
  .with() points (blueprint.rs, main.rs), the walkforward ParamSpecs
  (walkforward.rs), the member_key dir names, and the JSON byte-pins in
  cli_run.rs / report.rs / main.rs tests;
- the exposure_scale manifest param label -> bias_scale (the single-run manifest
  builders + the streaming_seam / real_bars fixtures).

The rename is surgical: the three targets (named("exposure"), exposure.scale,
exposure_scale) are syntactically distinct from the deliberately-kept "exposure"
forms, which are untouched -- SimBroker's pre-reframe exposure input slot +
prev_exposure + the exposure-integral; the LongOnly / gate / latch ports named
"exposure"; and the on-disk "exposure" tap label (the recorded bias series that
feeds `chart --tap exposure`, decoupled from the node name via
ColumnarTrace::from_rows("exposure", ...)).

No on-disk back-compat break: the knob path is a runtime param address, and
recorded params in old runs.jsonl / families.jsonl are inert data strings (a
pre-existing recorded "exposure.scale" still loads, it is just data).

INDEX.md cycle-0065 realization note amended: the param namespace is recorded as
the now-completed tail; the SimBroker slot + the on-disk tap label remain the
deliberate permanent keeps (#117), and exposure_sign_flips stays a serde alias.

Verified: cargo build --workspace --all-targets clean; clippy --all-targets
-D warnings clean; full suite 514 passed / 0 failed (source + byte-pins renamed
together); live `aura run` emits "bias_scale", `aura sweep` emits "bias.scale".

closes #134
refs #126 #117
This commit is contained in:
2026-06-24 14:40:51 +02:00
parent 5c6de45b6e
commit 68605b7d88
10 changed files with 65 additions and 62 deletions
+4 -4
View File
@@ -635,7 +635,7 @@ fn sweep_prints_four_family_json_lines_and_exits_zero() {
// `broker` (the commit value is the volatile git HEAD, pinned by params below).
assert!(first.starts_with("{\"family_id\":\"sweep-0\",\"report\":{\"manifest\":{"), "got: {stdout}");
assert!(
first.contains("\"params\":[[\"signals.trend.fast.length\",{\"I64\":2}],[\"signals.trend.slow.length\",{\"I64\":4}],[\"signals.momentum.fast.length\",{\"I64\":2}],[\"signals.momentum.slow.length\",{\"I64\":4}],[\"signals.momentum.signal.length\",{\"I64\":3}],[\"signals.blend.weights[0]\",{\"F64\":1.0}],[\"signals.blend.weights[1]\",{\"F64\":1.0}],[\"exposure.scale\",{\"F64\":0.5}]]"),
first.contains("\"params\":[[\"signals.trend.fast.length\",{\"I64\":2}],[\"signals.trend.slow.length\",{\"I64\":4}],[\"signals.momentum.fast.length\",{\"I64\":2}],[\"signals.momentum.slow.length\",{\"I64\":4}],[\"signals.momentum.signal.length\",{\"I64\":3}],[\"signals.blend.weights[0]\",{\"F64\":1.0}],[\"signals.blend.weights[1]\",{\"F64\":1.0}],[\"bias.scale\",{\"F64\":0.5}]]"),
"got: {stdout}"
);
let _ = std::fs::remove_dir_all(&cwd);
@@ -1035,7 +1035,7 @@ fn sweep_strategy_momentum_prints_eight_typed_bool_member_lines() {
/// Property (#105, the bool actually gates — observable on disk): the
/// `longonly.enabled` param is genuinely WIRED into the momentum harness, not a
/// no-op knob. For one grid point's two bool members (same `ema.length` +
/// `exposure.scale`, differing only in the bool), the `enabled=true` member
/// `bias.scale`, differing only in the bool), the `enabled=true` member
/// records a long-only exposure stream — every recorded value `>= 0` — while the
/// otherwise-identical `enabled=false` member records at least one NEGATIVE
/// exposure over the same deterministic showcase stream. This pins the gate's
@@ -1063,8 +1063,8 @@ fn momentum_longonly_true_clamps_exposure_nonnegative_false_keeps_negatives() {
// One grid point, its two bool members (identical but for the bool).
let base = cwd.join("runs/traces/gate");
let enabled = base.join("ema.length-5_exposure.scale-1_longonly.enabled-true");
let disabled = base.join("ema.length-5_exposure.scale-1_longonly.enabled-false");
let enabled = base.join("ema.length-5_bias.scale-1_longonly.enabled-true");
let disabled = base.join("ema.length-5_bias.scale-1_longonly.enabled-false");
let exposures = |dir: &std::path::Path| -> Vec<f64> {
let body = std::fs::read_to_string(dir.join("exposure.json")).expect("read exposure.json");