Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions project/ticket-118/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Ticket 118: Separate todo2code scan suggestion mapping

- **ID**: ticket-118
- **Owner**: unresolved:human
- **Status**: IN_PROGRESS
- **Workflow state**: EDIT
- **Created**: 2026-09-08

SESSION_EXECUTION_AUTHORIZATION: User requested continued refactoring, GitHub publication, deployment and testing.

AC-01: Extract conversion of one useful todo2code plan into a suggestion while
preserving usefulness checks, path bounds, truncation, priority normalization,
dedupe evidence and labels.

## Acceptance criteria

- [ ] AC-01: Scan output remains identical and the orchestration is simpler.

Validation: 15 focused tests, Koru-driven regressions, Ruff, managed
governance, Docker Compose and compileall passed.

## Tracking boundary

This directory contains the minimal reviewed intent. Optional participant prose
and raw command logs are not required delivery output.
29 changes: 29 additions & 0 deletions project/ticket-118/intent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"schema": "new-project.intent/v3",
"ticket": "ticket-118",
"summary": "Separate todo2code scan suggestion mapping",
"workstream": "application",
"classification": {
"kind": "SERVICE",
"priority": "P2",
"origin": "requested"
},
"allowedPaths": ["src/koru/scan.py", "tests/test_todo2code_discovery.py", "project/ticket-118/**"],
"forbiddenPaths": ["project/ticket-*/user-*.md"],
"stacks": ["python", "docker"],
"dependsOn": [],
"conflictsWith": [],
"integrationTicket": null,
"delivery": {
"acceptedBaseSha": "5aadcaaf87bd43c52ee33c414c7b9c10e6eeaa13",
"targetBranch": "main",
"outcome": "Publish a behavior-preserving extraction of todo2code scan suggestion mapping.",
"nonGoals": ["No changes to scan authority, suggestion schema, dependencies or public interfaces."],
"complexity": "S",
"estimatedMinutes": 30,
"budgets": {"maxImplementationFiles": 2, "maxAffectedComponents": 1, "maxPublicInterfaceChanges": 0, "maxRuntimeDependencies": 0},
"architecture": {"status": "accepted", "decision": "Move per-plan eligibility and suggestion construction into a focused helper while retaining artifact loading and iteration.", "components": [{"name": "todo2code-scan", "paths": ["src/koru/scan.py", "tests/test_todo2code_discovery.py"]}], "responsibilityChanges": false, "interfaceChanges": [], "dataChanges": [], "ui": {"impact": "none", "states": [], "evidence": []}, "rollback": "Revert protected merge."},
"runtimeDependencies": [],
"validation": [{"criterion": "AC-01", "commands": ["python -m pytest -q tests/test_todo2code_discovery.py", "./project/governance-check.sh", "docker compose config --quiet"], "evidence": "Focused regression, Koru run, fresh analysis and independent CI."}]
}
}
78 changes: 42 additions & 36 deletions src/koru/scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
import shutil
import subprocess
from collections import Counter
from collections.abc import Callable, Sequence
from collections.abc import Callable, Mapping, Sequence
from importlib.util import find_spec
from pathlib import Path
from typing import Any
Expand Down Expand Up @@ -1714,6 +1714,41 @@ def _scan_metrun_report(project: Path) -> list[Suggestion]:
]


def _todo2code_plan_suggestion(
plan: dict[str, Any], *, project: Path, plans_rel: str,
is_useful_plan: Callable[..., bool], plan_useful_paths: Callable[..., list[str]],
priority_map: Mapping[str, str], source: str,
dedupe_key: Callable[[dict[str, Any]], str],
) -> Suggestion | None:
"""Convert one useful grounded plan into a scan suggestion."""
if not is_useful_plan(plan, project=project):
return None
paths = plan_useful_paths(plan, project=project)
if not paths:
return None
title_raw = str(plan.get("title") or "todo2code code-change plan").strip()
title = title_raw if len(title_raw) <= 140 else title_raw[:139].rstrip() + "…"
description = str(plan.get("description") or title_raw).strip()
priority = priority_map.get(str(plan.get("priority") or "").upper(), "normal")
if priority not in {"high", "normal", "low"}:
priority = "normal"
evidence = plan.get("evidence") if isinstance(plan.get("evidence"), dict) else {}
return Suggestion(
signal="todo2code_plan", title=f"[todo2code] {title}",
description=(
f"{description}\n\nSource: `{plans_rel}` "
f"(plan id {plan.get('id') or 'n/a'}). Implement only declared target paths."
),
priority=priority, labels=("todo2code", "code-change", "scan", "useful-code-change"),
files=tuple(paths[:12]),
source_context={"signal": "todo2code_code_change_plan", "dedupe_key": dedupe_key(plan),
"plan_id": str(plan.get("id") or "").strip() or None,
"plan_hash": str(plan.get("planHash") or "").strip() or None,
"source_tool": source,
"diagnostic_ids": [str(v) for v in (evidence.get("diagnosticIds") or []) if str(v).strip()]},
)


def _scan_todo2code_plans(project: Path) -> list[Suggestion]:
"""Useful grounded code-change plans from ``t2c`` artifacts."""
try:
Expand Down Expand Up @@ -1746,42 +1781,13 @@ def _scan_todo2code_plans(project: Path) -> list[Suggestion]:

suggestions: list[Suggestion] = []
for plan in plans:
if not is_useful_plan(plan, project=project):
continue
paths = plan_useful_paths(plan, project=project)
if not paths:
continue
title_raw = str(plan.get("title") or "todo2code code-change plan").strip()
title = title_raw if len(title_raw) <= 140 else title_raw[:139].rstrip() + "…"
description = str(plan.get("description") or title_raw).strip()
priority = _PRIORITY_MAP.get(str(plan.get("priority") or "").upper(), "normal")
if priority not in {"high", "normal", "low"}:
priority = "normal"
evidence = plan.get("evidence") if isinstance(plan.get("evidence"), dict) else {}
suggestions.append(
Suggestion(
signal="todo2code_plan",
title=f"[todo2code] {title}",
description=(
f"{description}\n\n"
f"Source: `{plans_rel}` (plan id {plan.get('id') or 'n/a'}). "
"Implement only declared target paths."
),
priority=priority,
labels=("todo2code", "code-change", "scan", "useful-code-change"),
files=tuple(paths[:12]),
source_context={
"signal": "todo2code_code_change_plan",
"dedupe_key": _plan_dedupe_key(plan),
"plan_id": str(plan.get("id") or "").strip() or None,
"plan_hash": str(plan.get("planHash") or "").strip() or None,
"source_tool": TODO2CODE_SOURCE,
"diagnostic_ids": [
str(v) for v in (evidence.get("diagnosticIds") or []) if str(v).strip()
],
},
),
suggestion = _todo2code_plan_suggestion(
plan, project=project, plans_rel=plans_rel, is_useful_plan=is_useful_plan,
plan_useful_paths=plan_useful_paths, priority_map=_PRIORITY_MAP,
source=TODO2CODE_SOURCE, dedupe_key=_plan_dedupe_key,
)
if suggestion is not None:
suggestions.append(suggestion)
return suggestions


Expand Down
Loading