Add five behave scenarios exercising the previously-uncovered error
branches in AdaptiveContextSelector (select_strategy and
select_strategies with an unconfigured plan_type) and ContextFusion
(fuse_results and fuse_with_selector with an unconfigured plan_type),
plus a scenario constructing a valid-weight StrategyWeight to cover
the success path of the field_validator.
ISSUES CLOSED: #5255
Architecture test requires all @dataclass-decorated classes to inherit
from Pydantic BaseModel. Replace StrategyWeight, AdaptiveStrategyConfig,
and FusedResult plain dataclasses with BaseModel subclasses, using
Field(default_factory=...) for mutable defaults and @field_validator for
validation logic that was previously in __post_init__.
ISSUES CLOSED: #5255
The adaptive_context_strategy.feature suite was failing on 13 scenarios
(2 failed, 11 errored) and ruff format was rejecting the step file:
* step_register_config_with_table, step_fuse_custom_weights,
step_verify_normalized_weights, and step_verify_fusion_metadata read
no-header 2-column Gherkin tables as if they had key/value headers;
behave promotes the first row to headings, so the first key/value pair
was lost and the second-row lookups erroneously fed table data through
float() / dict keys. Added a _table_pairs helper that recovers the
promoted-heading pair and iterates the remaining rows.
* step_register_multiple_strategies, step_register_multiple_configs,
step_verify_plan_types, and step_verify_plan_type_enum captured the
inner quotes of multi-token quoted-CSV placeholders (e.g.
'"coding"' vs 'coding'). Added _strip_quoted_csv to normalise them.
* step_have_registered_config validated against the strategy registry
but never registered the strategy it was passed; the "Get
configuration for plan type" scenario calls it without a prior
registration. Auto-register on first use.
* step_get_config wrote to context.config, which behave reserves for
its own runtime configuration object; the assignment raised
KeyError. Renamed to context.fetched_config.
* No When step matched the bare 'I fuse the results for plan type
"{plan_type}"' (scenarios 127/169). Added the matching step.
* ContextFusion._normalize_weights returned 1/N when no weights were
supplied; the "equal weights" scenarios pin the semantics to
unscaled 1.0-per-strategy. Switched the empty-weights branch
accordingly. Explicit non-empty weights still normalise to sum 1.0
so the custom-weights and selector-weights scenarios continue to
produce the same scores.
* Reformatted the over-wrapped @when decorator on
step_try_unregistered_primary to satisfy ruff format.
ISSUES CLOSED: #5255
Implements adaptive context strategy selector that chooses the best context
strategy based on plan type, and context fusion that combines results from
multiple strategies with configurable weights.
Features:
- AdaptiveContextSelector: Intelligent strategy selection per plan type
- ContextFusion: Weighted combination of multiple strategy results
- PlanType enumeration: coding, analysis, documentation, refactoring, testing, debugging
- AdaptiveStrategyConfig: YAML-compatible configuration for strategy selection
- FusedResult: Ranked file list with strategy contributions and metadata
- Full type annotations and comprehensive Behave BDD tests
Closes#5255