"""Read model provider registry — K-Ext-1.""" from __future__ import annotations from dataclasses import dataclass from typing import Any, Callable from steering.eval_context import SteeringEvalContext ReadModelCompute = Callable[[SteeringEvalContext], Any] @dataclass(frozen=True) class ReadModelProvider: key: str requires_elements: frozenset[str] requires_data_slices: frozenset[str] compute: ReadModelCompute _PROVIDERS: list[ReadModelProvider] = [] def register_read_model(provider: ReadModelProvider) -> None: _PROVIDERS.append(provider) def compute_read_models(ctx: SteeringEvalContext) -> dict[str, Any]: """Run all matching read model providers for the initiative context.""" elements = ctx.steering_elements slices = frozenset(ctx.data_slices) result: dict[str, Any] = {} for provider in _PROVIDERS: if provider.requires_elements and not provider.requires_elements <= elements: continue if provider.requires_data_slices and not provider.requires_data_slices <= slices: continue result[provider.key] = provider.compute(ctx) return result def _register_builtin_read_models() -> None: from steering.read_models.epic_rollup import compute_epic_rollup register_read_model( ReadModelProvider( key="epic_rollup", requires_elements=frozenset({"backlog_epic_hierarchy"}), requires_data_slices=frozenset({"backlog"}), compute=lambda ctx: compute_epic_rollup( backlog_items=ctx.backlog_items, actions=ctx.actions, ), ) ) _register_builtin_read_models()