mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-08-29 10:09:43 +02:00
Improve issue triage product-label detection (#49905)
## Summary Issues that put the module in a `[Module]` title prefix (a common PowerToys convention) but omit the bug template's **"Area(s) with issue?"** section were left **Unclassified** with no `Product-*` label — e.g. #49899 *"[Screen Ruler] Settings crashes ..."* got no `Product-Screen Ruler` label despite the title. Root cause: product-label detection was purely deterministic and narrow. `parse_area` (`.github/scripts/issue-triage/issue-context.py`) only read the template area section or a 6-entry keyword map, and the agent prompt instructed the model to copy that candidate verbatim (and send `None` otherwise). The `[Module]` title convention was never consulted. ## Change (two layers) **1. Deterministic title-prefix matching (primary).** Parse the leading `[Module]` bracket(s) in the title and match against existing `Product-*` labels; upgrade the detected area when the body has no area signal. Fully deterministic and auditable — this alone fixes Screen Ruler and every other bracketed title. **2. Constrained AI fallback (secondary).** Expose the repo's `Product-*` labels as `Available product labels` in the deterministic evidence, and allow the agent — **only when the deterministic candidate is `None`** — to select the single best-matching existing label. This is safe because the publisher already validates the agent's `product_label` against the real label set, so the agent can only ever **add a valid existing label**, never invent one or remove/change others. The workflow prompt is `{{#runtime-import}}`-ed from `issue-triage.md`, so the lock file changes only by its `body_hash` (sync check); recompiled with the repo's current gh-aw `v0.84.3` to avoid unrelated version drift. ## Tests New unit tests in `tests/test_issue_context.py`: - `test_title_prefix_maps_to_existing_product_label` - `test_available_product_labels_are_sorted_and_filtered` - `test_prepare_labels_bracketed_title_without_area_section` All 30 tests pass (`python -m unittest tests.test_issue_context`). ## Files - `.github/scripts/issue-triage/issue-context.py` — title-prefix detection, available-label list, wiring - `.github/scripts/issue-triage/tests/test_issue_context.py` — new tests - `.github/workflows/issue-triage.md` — prompt allows constrained fallback - `.github/workflows/issue-triage.lock.yml` — recompiled (`body_hash` only) Generated with the GitHub Copilot CLI. Co-authored-by: niels9001 <niels9001@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 26025067-259e-43e3-9dc7-a9fc4b5ba58b
This commit is contained in:
11
.github/scripts/issue-triage/README.md
vendored
11
.github/scripts/issue-triage/README.md
vendored
@@ -59,8 +59,15 @@ that retain `Needs-Author-Feedback` for seven days without activity.
|
||||
- A content hash skips unchanged edits and unrelated comments.
|
||||
- Per-user rate limits, daily AI-credit limits, and per-issue concurrency bound
|
||||
repeated execution.
|
||||
- The agent has read-only issue/repository access. A separate validated
|
||||
safe-output job owns comment, label, and duplicate-suggestion writes.
|
||||
- The agent has no shell or GitHub API tools. It can only read the checked-out
|
||||
repository and call the structured safe-output tool.
|
||||
- Threat detection fails closed; publication requires an explicit successful
|
||||
detection result.
|
||||
- The publishing job rebuilds evidence from the current issue and accepts only
|
||||
deterministic product-label candidates, duplicate candidates, hashes, and
|
||||
classifications. Stale or manipulated model output fails before any write.
|
||||
- A separate validated safe-output job owns comment, label, and
|
||||
duplicate-suggestion writes.
|
||||
|
||||
## Retired automation
|
||||
|
||||
|
||||
Reference in New Issue
Block a user