Why
Current break: src/trend_analysis/regimes.py:53-57 converts regime numbers without checking finiteness, while src/trend_analysis/regimes.py:72, 91-103 applies Python bool() to configuration flags and stores unchecked threshold and neutral-band values. src/trend_analysis/pipeline_helpers.py:281-294 can pass a NaN fund-count multiplier to int(round(...)); src/trend_analysis/pipeline_helpers.py:344-360 can emit NaN or infinity target volatility. As a result, enabled: "false" enables the subsystem and supplied non-finite controls either crash later or reach portfolio calculations.
Scope
Validate regime flags as booleans and validate supplied regime numeric controls as finite before regime classification and risk-off overrides consume them.
Implementation Notes
Use one documented boolean coercion rule for YAML-compatible flag values. Reject non-finite supplied values rather than treating them as defaults, including risk-off count and target-volatility modifiers.
Tasks
Acceptance Criteria
pytest tests/test_regime_annualise.py::test_regime_control_values_reject_non_finite_and_string_boolean tests/test_pipeline_optional_features.py::test_regime_overrides_reject_non_finite_modifiers passes.
- temporarily remove the finite-value guard and confirm tests/test_regime_annualise.py::test_regime_control_values_reject_non_finite_and_string_boolean fails; revert.
Non-Goals
- Do not change regime-label selection semantics in
src/trend_analysis/regimes.py.
- Scaffold-only completion does NOT count: accepting a string flag or non-finite modifier that reaches a regime calculation is a failure of this issue.
Why
Current break:
src/trend_analysis/regimes.py:53-57converts regime numbers without checking finiteness, whilesrc/trend_analysis/regimes.py:72, 91-103applies Pythonbool()to configuration flags and stores unchecked threshold and neutral-band values.src/trend_analysis/pipeline_helpers.py:281-294can pass a NaN fund-count multiplier toint(round(...));src/trend_analysis/pipeline_helpers.py:344-360can emit NaN or infinity target volatility. As a result,enabled: "false"enables the subsystem and supplied non-finite controls either crash later or reach portfolio calculations.Scope
Validate regime flags as booleans and validate supplied regime numeric controls as finite before regime classification and risk-off overrides consume them.
Implementation Notes
Use one documented boolean coercion rule for YAML-compatible flag values. Reject non-finite supplied values rather than treating them as defaults, including risk-off count and target-volatility modifiers.
Tasks
src/trend_analysis/regimes.pyto reject string boolean flags and non-finite regime threshold or neutral-band values.src/trend_analysis/pipeline_helpers.pyto reject non-finite risk-off fund-count and target-volatility modifiers.tests/test_regime_annualise.pywith invalid boolean and non-finite base-control coverage.tests/test_pipeline_optional_features.pywith non-finite risk-off override coverage.Acceptance Criteria
pytest tests/test_regime_annualise.py::test_regime_control_values_reject_non_finite_and_string_boolean tests/test_pipeline_optional_features.py::test_regime_overrides_reject_non_finite_modifierspasses.Non-Goals
src/trend_analysis/regimes.py.