a4712eb336
Walk-forward orchestration: a WindowRoller rolls (in-sample, out-of-sample) splits over a time span, walk_forward runs a disjoint harness per split via the shared run_indexed core (C1), and stitches the OOS pip-equity segments into one continuous curve. The varying dimension is the data window (axis 3), realized eager-agnostically (#71): the public surface carries WindowBounds + a per-window closure, never a materialized stream Vec; C2 no-look-ahead is a pure bounds invariant (oos.0 > is.1), checkable with zero ticks. The in-sample optimize (axis 2) is closure-supplied, not called by the engine: aura-engine cannot depend on aura-registry (C9), and C12 forbids baking search policy into the primitive. The CLI bridges both crates in run_walkforward. Param-stability shape (the load-bearing fork) resolved with the user as R2: on-demand, not stored. WalkForwardResult stores only raw per-window outcomes + the stitched curve; param_stability(&result) -> Vec<MetricStats> is a public on-demand reduction over the retained per-window chosen params (sweep-precedent: summaries computed on demand, not cached, vs McFamily's stored aggregate). A stored summary would be recomputable from the raw windows (redundant) and would force one statistic canonical when "stability" admits several. Recorded with provenance in the #69 reconciliation comment. MetricStats::from_values is extracted from McAggregate::from_draws (behaviour-preserving; the 7 mc tests guard) so the MC aggregate and the helper share one reduction. Empty OOS segment contributes 0.0 to the stitch offset (mirrors summarize's unwrap_or(0.0)). Gates: Step-1.5 precondition clean (no fork silently picked), self-review clean, grounding-check PASS (twice — re-run after each edit). Auto-sign panel escalated on the scope-fork design lens (param-stability shape) to human sign-off; the user resolved it (R2), so this is a user-signed spec, not boss-signed. refs #69