Merge pull request 'feat: register work-issue task routing for role-aware MCP (Closes #139)' (#385) from feat/issue-139-role-aware-work-issue-routing into master

This commit was merged in pull request #385.
This commit is contained in:
2026-07-07 10:24:04 -05:00
8 changed files with 254 additions and 0 deletions
+122
View File
@@ -2328,6 +2328,30 @@ CREATE_ISSUE_FORBIDDEN_CROSS_MODE_FIELDS = (
("Terminal review mutation", ("terminal review mutation",)),
)
WORK_ISSUE_WORKFLOW_MARKERS = (
"workflows/work-issue.md",
"work-issue.md",
)
WORK_ISSUE_TASK_MARKERS = (
"work-issue",
"work issue",
)
WORK_ISSUE_FORBIDDEN_CROSS_MODE_FIELDS = (
("Selected PR", ("selected pr",)),
("Review decision", ("review decision",)),
("Merge result", ("merge result",)),
("Merge preflight", ("merge preflight",)),
("Already-landed gate", ("already-landed gate",)),
("Pinned reviewed head", ("pinned reviewed head",)),
("Terminal review mutation", ("terminal review mutation",)),
("Duplicate search terms", ("duplicate search terms",)),
("Issues created", ("issues created",)),
("Issues skipped as duplicates", ("issues skipped as duplicates",)),
("Requested issue task", ("requested issue task",)),
)
def _handoff_section_lines(report_text):
"""Return the lines of the Controller Handoff section, or None."""
@@ -3520,6 +3544,104 @@ def assess_create_issue_workflow_source(report_text: str) -> dict:
}
def assess_work_issue_workflow_source(report_text: str) -> dict:
"""#139: work-issue reports must cite the canonical workflow file."""
lower = (report_text or "").lower()
reasons = []
if not any(marker in lower for marker in WORK_ISSUE_WORKFLOW_MARKERS):
reasons.append(
"work-issue report missing workflow source "
"(workflows/work-issue.md)"
)
if not any(marker in lower for marker in WORK_ISSUE_TASK_MARKERS):
reasons.append(
"work-issue report missing task mode declaration (work-issue)"
)
return {
"complete": not reasons,
"downgraded": bool(reasons),
"reasons": reasons,
}
def assess_work_issue_mode_isolation(report_text: str) -> dict:
"""#139: reject review-merge/create-issue handoff fields in work-issue runs."""
section = _handoff_section_lines(report_text)
reasons = []
if section is None:
return {
"complete": True,
"downgraded": False,
"reasons": [],
}
labels = []
for line in section:
stripped = line.strip().lstrip("-*").strip()
if ":" in stripped:
labels.append(stripped.split(":", 1)[0].strip().lower())
for name, aliases in WORK_ISSUE_FORBIDDEN_CROSS_MODE_FIELDS:
if any(
label.startswith(alias)
for label in labels
for alias in aliases
):
reasons.append(
f"work-issue handoff must not include cross-mode field "
f"'{name}'"
)
legacy_workspace = any(
label.startswith("workspace mutations") for label in labels
)
precise_categories = any(
label.startswith("file edits by author")
for label in labels
)
if legacy_workspace and not precise_categories:
reasons.append(
"work-issue handoff must use precise mutation categories "
"instead of legacy 'Workspace mutations'"
)
return {
"complete": not reasons,
"downgraded": bool(reasons),
"reasons": reasons,
}
def assess_work_issue_final_report(report_text: str) -> dict:
"""#139: composite verifier for work-issue final reports."""
checks = {
"workflow_source": assess_work_issue_workflow_source(report_text),
"mode_isolation": assess_work_issue_mode_isolation(report_text),
}
reasons = []
downgraded = False
for name, result in checks.items():
verdict = result.get("verdict")
if verdict in ("missing", "incomplete"):
downgraded = True
reasons.extend(result.get("reasons") or [])
elif result.get("downgraded") or not result.get("complete", True):
downgraded = True
reasons.extend(
f"{name}: {r}" for r in (result.get("reasons") or [])
)
grade = "A" if not downgraded else "downgraded"
return {
"grade": grade,
"downgraded": downgraded,
"checks": checks,
"reasons": reasons,
"complete": not downgraded,
}
def assess_create_issue_mode_isolation(report_text: str) -> dict:
"""#337: reject work-issue/review-merge handoff fields in create-issue runs."""
section = _handoff_section_lines(report_text)