fix(campaign): walk_forward window-fit refusal speaks ms prose, not Debug (fieldtest 0107 F8)
The roller refusal leaked its raw Rust form through ExecFault::Window
(SpanTooShort { span: (Timestamp(...), ...), need: ... }) — the one
break in the cycle's Debug-free prose seam. The detail now phrases
both roller refusals in the doc's own ms unit:
'in_sample_ms + out_of_sample_ms = N ms exceeds the campaign window
[a, b] (L ms)'. RED-first: the wf_roller_refusal_maps_to_window_fault
pin was flipped to the prose form (observed RED on the old Debug
output), then the map_err phrased; live repro confirmed against the
fieldtest fixture.
Gates: workspace 987/0, clippy -D warnings clean.
refs #198
This commit is contained in:
@@ -13,7 +13,7 @@ use aura_analysis::{FamilySelection, SelectionMode};
|
||||
use aura_core::{zip_params, Cell, ParamSpec, Scalar, Timestamp};
|
||||
use aura_engine::{
|
||||
sweep, walk_forward, GridSpace, ListSpace, RollMode, RunManifest, RunMetrics, RunReport,
|
||||
Space, SweepFamily, SweepPoint, WindowBounds, WindowRoller, WindowRun,
|
||||
Space, SweepFamily, SweepPoint, WalkForwardError, WindowBounds, WindowRoller, WindowRun,
|
||||
};
|
||||
use aura_registry::{
|
||||
optimize, optimize_deflated, optimize_plateau, sweep_member_reports,
|
||||
@@ -508,7 +508,24 @@ fn run_walk_forward_stage(
|
||||
*step_ms as i64,
|
||||
roll_mode,
|
||||
)
|
||||
.map_err(|e| ExecFault::Window { stage, detail: format!("{e:?}") })?;
|
||||
.map_err(|e| ExecFault::Window {
|
||||
stage,
|
||||
// The detail string reaches user-facing seams verbatim — phrase both
|
||||
// roller refusals in the doc's ms unit, never a Debug form.
|
||||
detail: match e {
|
||||
WalkForwardError::SpanTooShort { .. } => format!(
|
||||
"in_sample_ms + out_of_sample_ms = {} ms exceeds the campaign window [{}, {}] ({} ms)",
|
||||
in_sample_ms + out_of_sample_ms,
|
||||
cell.window_ms.0,
|
||||
cell.window_ms.1,
|
||||
cell.window_ms.1 - cell.window_ms.0 + 1,
|
||||
),
|
||||
// Zero lengths are doc-tier faults (preflight); phrased anyway.
|
||||
WalkForwardError::NonPositiveLength { field, value } => {
|
||||
format!("walk_forward {field} must be > 0 (got {value})")
|
||||
}
|
||||
},
|
||||
})?;
|
||||
// A second identical roller enumerates the bounds up front: the engine's
|
||||
// walk_forward consumes its roller, and the parallel closure needs each
|
||||
// window's roll index for deterministic fault attribution.
|
||||
|
||||
@@ -861,8 +861,13 @@ mod wf_tests {
|
||||
ExecFault::Window { stage, detail } => {
|
||||
assert_eq!(stage, 1, "walk_forward is pipeline stage 1 here");
|
||||
assert!(
|
||||
detail.contains("SpanTooShort"),
|
||||
"detail carries the roller refusal: {detail}"
|
||||
detail.contains("in_sample_ms + out_of_sample_ms = 60 ms")
|
||||
&& detail.contains("(50 ms)"),
|
||||
"detail phrases the refusal in doc-unit ms prose: {detail}"
|
||||
);
|
||||
assert!(
|
||||
!detail.contains("SpanTooShort") && !detail.contains("Timestamp("),
|
||||
"no Debug form leaks through the detail seam: {detail}"
|
||||
);
|
||||
}
|
||||
other => panic!("expected ExecFault::Window, got {other:?}"),
|
||||
|
||||
Reference in New Issue
Block a user