Kairo-Jinkendo/backend/steering/proposals/intake_triage.py
Lars b747200f3a
All checks were successful
Deploy Development / deploy (push) Successful in 46s
Test Suite / pytest-backend (push) Successful in 4m13s
Test Suite / lint-backend (push) Successful in 3s
Test Suite / compose-smoke (push) Has been skipped
Test Suite / k6 /api/health Baseline (push) Successful in 19s
Test Suite / playwright-smoke (push) Successful in 12s
feat(steering): K-Ext-2 Attention-Registry, Gate/Intake-Proposals, generische UI
Methodenuebergreifende Provider auf Kernel v0.3; verbindliche Coding Rules fuer Agenten in ADP und .cursor/rules.

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

94 lines
3.2 KiB
Python

"""Intake triage proposal — queue_inbox / continuous backlog (no sprint)."""
from __future__ import annotations
from typing import Any
from steering.eval_context import SteeringEvalContext
COMMITTABLE = frozenset({"new", "triaged", "accepted"})
_PRIORITY = {"critical": 0, "high": 1, "normal": 2, "low": 3}
_QUEUE_KIND_BIAS = {"bug": 0, "issue": 1, "incident": 1, "story": 2, "idea": 3}
def propose_intake_triage(
ctx: SteeringEvalContext,
*,
read_models: dict[str, Any] | None = None,
) -> list[dict[str, Any]]:
vocabulary = ctx.backlog_vocabulary
convertible = frozenset(vocabulary.get("convertible_kinds") or ["story", "bug", "issue"])
queue_mode = "queue_inbox" in ctx.steering_elements
candidates = [
item
for item in ctx.backlog_items
if item.get("status") in COMMITTABLE
and item.get("item_kind") != "epic"
and (item.get("item_kind") or "story") in convertible
]
if not candidates:
return []
def sort_key(item: dict[str, Any]) -> tuple:
kind = item.get("item_kind") or "story"
kind_bias = _QUEUE_KIND_BIAS.get(kind, 5) if queue_mode else 5
return (
_PRIORITY.get(item.get("priority") or "normal", 9),
kind_bias,
item.get("sort_order") if item.get("sort_order") is not None else 9999,
)
proposals: list[dict[str, Any]] = []
for rank, item in enumerate(sorted(candidates, key=sort_key)[:20], start=1):
kind = item.get("item_kind") or "story"
proposals.append(
{
"proposal_key": "intake_triage",
"scope_type": "backlog_item",
"scope_id": str(item["id"]),
"rank": rank,
"reason_code": "intake_triage_candidate",
"summary": "Triage-Kandidat (Heuristik — Ranker austauschbar)",
"title": item.get("title") or "Backlog-Item",
"item_kind": kind,
"priority": item.get("priority") or "normal",
"initiative_id": ctx.initiative_id,
"ranker_key": "heuristic_v0",
"confidence": "heuristic",
"factors": [
{
"code": "priority",
"weight": _PRIORITY.get(item.get("priority") or "normal", 9),
"label": "Priorität",
}
],
"dependency_refs": [],
"dependency_blocked": False,
"data_source": "steering_kernel",
}
)
return proposals
def intake_triage_attention_items(
*,
initiative_id: str,
proposals: list[dict[str, Any]],
) -> list[dict[str, Any]]:
if not proposals:
return []
return [
{
"kind": "intake_triage_suggested",
"severity": "info",
"title": "Eingang triagieren",
"summary": f"{len(proposals)} Item(s) — Kernel schlägt Triage-Reihenfolge vor",
"scope_type": "initiative",
"scope_id": initiative_id,
"initiative_id": initiative_id,
"reason_code": "intake_triage_suggested",
"data_source": "intake_triage",
}
]