Kairo-Jinkendo/backend/steering/read_models/registry.py
Lars a5154cbd3b
Some checks failed
Deploy Development / deploy (push) Successful in 47s
Test Suite / pytest-backend (push) Failing after 4m15s
Test Suite / k6 /api/health Baseline (push) Has been skipped
Test Suite / playwright-smoke (push) Has been skipped
Test Suite / lint-backend (push) Successful in 2s
Test Suite / compose-smoke (push) Has been skipped
feat(steering): Kernel v0.4 Agent-Slots, Tech Debt und Review-Attention
K-Ext-4/P8 deklarative Agent-Slots; P7 tech_debt Read Model und Vokabular; Review-Attention in den Kernel verlagert.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 11:54:48 +02:00

94 lines
2.9 KiB
Python

"""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
requires_any_element: frozenset[str] = frozenset()
_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_any_element and not (
provider.requires_any_element & 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
from steering.read_models.execution_graph import compute_execution_graph_read_model
from steering.read_models.planning_debt import compute_planning_debt_read_model
from steering.read_models.tech_debt import compute_tech_debt_summary
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_read_model(
ReadModelProvider(
key="planning_debt",
requires_elements=frozenset({"gate_fulfillment"}),
requires_data_slices=frozenset({"roadmap", "actions"}),
compute=compute_planning_debt_read_model,
)
)
register_read_model(
ReadModelProvider(
key="execution_graph",
requires_elements=frozenset(),
requires_any_element=frozenset({"critical_path", "gate_fulfillment"}),
requires_data_slices=frozenset({"actions"}),
compute=compute_execution_graph_read_model,
)
)
register_read_model(
ReadModelProvider(
key="tech_debt_summary",
requires_elements=frozenset(),
requires_data_slices=frozenset({"backlog", "actions"}),
compute=compute_tech_debt_summary,
)
)
_register_builtin_read_models()