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
Methodenuebergreifende Provider auf Kernel v0.3; verbindliche Coding Rules fuer Agenten in ADP und .cursor/rules. Co-authored-by: Cursor <cursoragent@cursor.com>
94 lines
3.2 KiB
Python
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",
|
|
}
|
|
]
|