generated from coulomb/repo-seed
Include ranked suggestions in daily triage digest (STATE-WP-0061).
Expose State Hub ranked_suggestions from /state/summary in the daily_triage_digest resolver so WSJF triage can prioritize gated needs.
This commit is contained in:
@@ -513,11 +513,19 @@ def _daily_triage_digest(params: dict[str, Any]) -> str:
|
|||||||
max_workstreams = int(params.get("max_workstreams", 12))
|
max_workstreams = int(params.get("max_workstreams", 12))
|
||||||
max_next_steps = int(params.get("max_next_steps", 8))
|
max_next_steps = int(params.get("max_next_steps", 8))
|
||||||
open_workstreams = _open_workstream_digest(summary, workplan_index, max_workstreams)
|
open_workstreams = _open_workstream_digest(summary, workplan_index, max_workstreams)
|
||||||
|
ranked_suggestions = summary.get("ranked_suggestions") or []
|
||||||
|
if not isinstance(ranked_suggestions, list):
|
||||||
|
ranked_suggestions = []
|
||||||
|
|
||||||
digest = {
|
digest = {
|
||||||
"generated_at": summary.get("generated_at"),
|
"generated_at": summary.get("generated_at"),
|
||||||
"totals": summary.get("totals", {}),
|
"totals": summary.get("totals", {}),
|
||||||
"open_workstreams": open_workstreams,
|
"open_workstreams": open_workstreams,
|
||||||
"next_steps": [_safe_next_step(item) for item in next_steps[:max_next_steps]],
|
"next_steps": [_safe_next_step(item) for item in next_steps[:max_next_steps]],
|
||||||
|
"ranked_suggestions": [
|
||||||
|
_safe_ranked_suggestion(item)
|
||||||
|
for item in ranked_suggestions[: int(params.get("max_suggestions", 10))]
|
||||||
|
],
|
||||||
"inbox": {
|
"inbox": {
|
||||||
"unread_count": len(inbox),
|
"unread_count": len(inbox),
|
||||||
"samples": [_safe_inbox_item(item) for item in inbox[:3]],
|
"samples": [_safe_inbox_item(item) for item in inbox[:3]],
|
||||||
@@ -619,6 +627,19 @@ def _safe_next_step(item: dict[str, Any]) -> dict[str, Any]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _safe_ranked_suggestion(item: dict[str, Any]) -> dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"id": item.get("id"),
|
||||||
|
"title": _short_text(item.get("title", ""), 120),
|
||||||
|
"stage": item.get("stage"),
|
||||||
|
"domain_slug": item.get("domain_slug"),
|
||||||
|
"origin_ref": item.get("origin_ref"),
|
||||||
|
"relevance": item.get("relevance"),
|
||||||
|
"wsjf": item.get("wsjf"),
|
||||||
|
"last_requested_at": item.get("last_requested_at"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def _safe_inbox_item(item: dict[str, Any]) -> dict[str, Any]:
|
def _safe_inbox_item(item: dict[str, Any]) -> dict[str, Any]:
|
||||||
return {
|
return {
|
||||||
"id": item.get("id"),
|
"id": item.get("id"),
|
||||||
|
|||||||
@@ -486,6 +486,18 @@ def test_daily_triage_digest_is_curated_scalar_json(monkeypatch) -> None:
|
|||||||
"/state/summary": {
|
"/state/summary": {
|
||||||
"generated_at": "2026-05-19T05:20:00Z",
|
"generated_at": "2026-05-19T05:20:00Z",
|
||||||
"totals": {"tasks": {"todo": 4, "wait": 1}},
|
"totals": {"tasks": {"todo": 4, "wait": 1}},
|
||||||
|
"ranked_suggestions": [
|
||||||
|
{
|
||||||
|
"id": "sug-1",
|
||||||
|
"title": "Issue-core ingestion API key path",
|
||||||
|
"stage": "suggestion",
|
||||||
|
"domain_slug": "custodian",
|
||||||
|
"origin_ref": "issue-core-ingestion-api-key",
|
||||||
|
"relevance": 2,
|
||||||
|
"wsjf": 4.7,
|
||||||
|
"last_requested_at": "2026-05-19T04:00:00Z",
|
||||||
|
}
|
||||||
|
],
|
||||||
"topics": [
|
"topics": [
|
||||||
{
|
{
|
||||||
"slug": "custodian",
|
"slug": "custodian",
|
||||||
@@ -594,3 +606,4 @@ def test_daily_triage_digest_is_curated_scalar_json(monkeypatch) -> None:
|
|||||||
assert digest["deterministic_scoring"]["future_mode"] == (
|
assert digest["deterministic_scoring"]["future_mode"] == (
|
||||||
"code_score_high_gain_high_effort_candidates"
|
"code_score_high_gain_high_effort_candidates"
|
||||||
)
|
)
|
||||||
|
assert digest["ranked_suggestions"][0]["origin_ref"] == "issue-core-ingestion-api-key"
|
||||||
|
|||||||
Reference in New Issue
Block a user