Skip to content
Open
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
5 changes: 3 additions & 2 deletions skills/pr-management-triage/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -603,8 +603,9 @@ returns, for every PR on the page:
triaged" detection),
- `authorAssociation` and labels.

Accumulate every PR into a single in-memory list keyed by
number. Do not classify, do not present, do not prompt the
Accumulate every PR into a single in-memory list, then deduplicate
it by number after the final page, keeping each PR's last (freshest)
occurrence. Do not classify, do not present, do not prompt the
maintainer between pages — the fetch loop is uninterrupted,
runs to completion, and emits one progress line per page so
the maintainer can step away during the wait. See
Expand Down
20 changes: 17 additions & 3 deletions skills/pr-management-triage/fetch-and-batch.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,15 @@ loop:
break
cursor = result.search.pageInfo.endCursor
page += 1
return all_prs

seen_numbers = set()
deduped_prs_reversed = []
for pr in reverse(all_prs):
if pr.number in seen_numbers:
continue
seen_numbers.add(pr.number)
deduped_prs_reversed.append(pr)
return reverse(deduped_prs_reversed)
```

Key invariants:
Expand All @@ -231,8 +239,14 @@ Key invariants:
the loop is advancing if they glance over.
- **No classification, no prompts, no presentation inside the
loop.** Classification runs once in Step 2 over the entire
`all_prs` set. Presentation runs once in Step 3 over the
deduplicated set. Presentation runs once in Step 3 over the
classified set. The fetch loop is uninterrupted.
- **Deduplicate after the loop.** A PR updated during an
`updated-asc` search can move to a later page and be fetched
twice. Traverse the accumulated list from the end, keep the
first record for each PR number, then restore the list order.
This keeps the last (freshest) occurrence and its position in
the fetched ordering. Leave an already-unique list unchanged.
- **Skip prefetch heuristics.** With pages fetched serially up
front, there is no per-page maintainer wait to overlap with
a next-page prefetch — the old prefetch-during-interaction
Expand All @@ -245,7 +259,7 @@ Key invariants:
either a mis-targeted selector or an unhealthy backlog
worth flagging.

Stash the accumulated `all_prs` in the session cache as
Stash the deduplicated list in the session cache as
`fetched_prs` (see [`#session-cache`](#session-cache)) before
returning to Step 2 — a re-invocation within the same session
window can reuse the set if the maintainer wants to re-run with
Expand Down
2 changes: 1 addition & 1 deletion tools/skill-evals/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Suites are currently implemented for:
- **pr-management-code-review** — 115 cases across 27 suites (selector-resolution, step-1-selectors-match-chips, step-2.5-slop-detection, step-3-security-disclosure-scan, step-3-ai-authorship-disclosure, step-4-* checks, step-5-adversarial-integration, step-6-disposition, step-7b-review-body-attribution, review-risk-classify, injection-guard, review-disposition, review-handoff)
- **pr-management-mentor** — 20 cases across 2 steps (tone-checks, hand-off)
- **pr-management-stats** — 13 cases across 2 steps (classify, pressure-weight)
- **pr-management-triage** — 33 cases across 3 steps (pre-filter, decision-table, terminal-links)
- **pr-management-triage** — 35 cases across 4 steps (pre-filter, decision-table, terminal-links, pagination-dedup)
- **list-skills** — 7 cases across 2 steps (step-1-command, step-2-present)
- **setup-isolated-setup-verify** — 12 cases across 3 steps (runtime-routing, step-1-classify, step-2-recommend)
- **setup-isolated-setup-update** — 14 cases across 4 steps (runtime-routing, step-snapshot-drift, step-tool-freshness, step-after-report)
Expand Down
3 changes: 2 additions & 1 deletion tools/skill-evals/evals/pr-management-triage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

Behavioral evals for the `pr-management-triage` skill.

## Suites (33 cases total)
## Suites (35 cases total)

| Suite | Step | Cases | What it covers |
|---|---|---|---|
| pre-filter | Step 2 (pre-filters) | 10 | F1 (collaborator), F2 (bot), F3 (draft recent), F4 (already ready), F5a (active maintainer comment), F5b (maintainer ping unanswered), F6 (maintainer co-drafted), row-6 (viewer is author), row-7a (fresh PR); clean contributor continues |
| decision-table | Step 2 (decision table) | 18 | Rows 3/4 (already-triaged via body-fold block→skip), 7b (security signal), 9 (conflict→draft), 10 (all systemic→rerun), 11 (partial systemic→rerun), 12 (static-only→comment), 13 (flaky ≤2→rerun), 14a (author confirmed→mark-ready), 14b (pending confirmation→skip), 14c (threads addressed→request-author-confirmation), 15 (threads→ping), 16 (no CI→rebase), 18 (changes-requested+new-commits→ping), 19 (already ready→skip), 20 (passing→mark-ready), 21 (stale draft sweep→close), 22 (rollup anomaly→skip) |
| terminal-links | Golden rule 10 | 5 | Short, context-short, and full PR references use the canonical target; `NO_COLOR` and `TERM=dumb` select the plain-text fallback |
| pagination-dedup | Step 1 (full pagination) | 2 | A PR that moves to a later page is emitted once at its freshest occurrence; distinct PRs keep their fetched order |

The two body-fold cases (`case-17-fold-already-triaged`,
`case-18-fold-stale-after-push`) are the regression guard for the denoise
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"prs": [
{"number": 12, "updatedAt": "2026-08-05T10:05:00Z", "headRefOid": "head-12"},
{"number": 13, "updatedAt": "2026-08-05T10:10:00Z", "headRefOid": "head-13"},
{"number": 11, "updatedAt": "2026-08-05T10:15:00Z", "headRefOid": "fresh-11"}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->

The search is sorted by `updated-asc`. These pages were fetched serially:

Page 1:

```json
[
{"number": 11, "updatedAt": "2026-08-05T10:00:00Z", "headRefOid": "old-11"},
{"number": 12, "updatedAt": "2026-08-05T10:05:00Z", "headRefOid": "head-12"}
]
```

Page 2, after PR 11 was updated and moved to the end of the search:

```json
[
{"number": 13, "updatedAt": "2026-08-05T10:10:00Z", "headRefOid": "head-13"},
{"number": 11, "updatedAt": "2026-08-05T10:15:00Z", "headRefOid": "fresh-11"}
]
```

Page 2 reports `hasNextPage: false`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"prs": [
{"number": 21, "updatedAt": "2026-08-05T11:00:00Z", "headRefOid": "head-21"},
{"number": 22, "updatedAt": "2026-08-05T11:05:00Z", "headRefOid": "head-22"},
{"number": 23, "updatedAt": "2026-08-05T11:10:00Z", "headRefOid": "head-23"}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->

The search is sorted by `updated-asc`. These pages were fetched serially:

Page 1:

```json
[
{"number": 21, "updatedAt": "2026-08-05T11:00:00Z", "headRefOid": "head-21"},
{"number": 22, "updatedAt": "2026-08-05T11:05:00Z", "headRefOid": "head-22"}
]
```

Page 2:

```json
[
{"number": 23, "updatedAt": "2026-08-05T11:10:00Z", "headRefOid": "head-23"}
]
```

Page 2 reports `hasNextPage: false`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->

## Output format

Return ONLY valid JSON with this structure:

```json
{
"prs": [
{
"number": 123,
"updatedAt": "<timestamp>",
"headRefOid": "<commit>"
}
]
}
```

Return the PRs that should be handed to Step 2, in order. Do not include
any text outside the JSON object.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"skill_md": "skills/pr-management-triage/fetch-and-batch.md",
"step_heading": "## Full-pagination loop"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->

## Pagination result

{report}

Apply the full-pagination loop and return the PRs handed to Step 2. Return
JSON only.