fix(triage-panel): paginate scheduled sweep oldest-first via MCP#1193
Merged
Conversation
The scheduled sweep agent was processing only one issue per daily cron run despite a documented MAX_ISSUES_PER_RUN=10 ceiling and a 13-deep human-authored untriaged backlog. The 2026-05-06 sweep (run 25437842915) labelled exactly one issue (#1161) and exited with 'All other open issues were already status/triaged or authored by bots (skipped)' even though most older issues lacked status/triaged. Root cause from the agent stdio trace: - The prompt example showed 'gh issue list --limit 200' but shared/apm.md tells the agent shell gh is unauthenticated, so the agent calls the MCP list_issues tool instead. - That single MCP call returned ~140 KB ('Output too large to read at once') and the agent set BATCH_ALLOW_LIST = [<head of list>] from the truncated slice without paginating. - The MCP tool defaults sort newest-first, contradicting the prompt's oldest-first requirement, and the labels filter only matches positive labels (no 'lacks status/triaged' semantics). Update the SCHEDULED_SWEEP step to: - Call list_issues with orderBy=CREATED_AT, direction=ASC, perPage=30. - Mandate pagination via 'after: endCursor' until 10 eligibles found, hasNextPage=false, or 5 pages scanned. - Tell the agent to drop perPage to 15 if a single page can't be read in one tool response. - Drop the misleading shell gh example. Lockfile imports the prompt at runtime ({{#runtime-import .github/workflows/triage-panel.md}}) so this is a .md-only change; gh aw compile produces no lockfile diff. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Updates the triage-panel scheduled sweep prompt so the agent uses GitHub MCP pagination (oldest-first) to reliably find up to 10 eligible untriaged issues per run, preventing silent backlog growth.
Changes:
- Rewrites the SCHEDULED_SWEEP candidate-gathering instructions to use GitHub MCP
list_issueswith oldest-first ordering and mandatory pagination. - Adds guardrails for tool-output size by reducing
perPagewhen responses are too large. - Documents the behavior change in the changelog.
Show a summary per file
| File | Description |
|---|---|
| CHANGELOG.md | Notes the scheduled sweep pagination/ordering behavior change for release visibility. |
| .github/workflows/triage-panel.md | Updates the prompt to use MCP list_issues with pagination/ordering and clarifies filtering steps. |
Copilot's findings
- Files reviewed: 2/2 changed files
- Comments generated: 3
| - `shared/apm.md` no longer wraps the `target` input in a `|| 'all'` fallback. The defensive expression broke gh-aw's bare-expression substitution regex, causing consumer-supplied `target:` values to be silently dropped; the `import-schema` default already covers the omitted-input case. (#1185) | ||
| - `apm install --target all` no longer enumerates the experimental `copilot-cowork` target, which was crashing project-scope installs with a "requires --global" error and made `gh aw` workflows that pin `target: all` unusable. (#1191) | ||
| - Stabilized `test_install_over_defer_threshold_starts_live_once` on slow CI runners by joining the deferred-start timer thread instead of relying on a 100ms grace window. (#1191) | ||
| - `triage-panel` scheduled sweep now paginates the candidate query oldest-first via the GitHub MCP `list_issues` tool instead of a single 200-issue page, so daily runs actually drain the untriaged backlog rather than processing one issue per cron tick. |
Comment on lines
+281
to
+288
| list_issues( | ||
| owner: "microsoft", | ||
| repo: "apm", | ||
| state: "OPEN", | ||
| orderBy: "CREATED_AT", | ||
| direction: "ASC", | ||
| perPage: 30, | ||
| ) |
| state: "OPEN", | ||
| orderBy: "CREATED_AT", | ||
| direction: "ASC", | ||
| perPage: 30, |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
The
triage-panelscheduled sweep has been processing one issue per daily cron run instead of the documentedMAX_ISSUES_PER_RUN=10, silently letting the untriaged backlog grow. Root cause is a prompt bug intriage-panel.md, not anything in the engine. Fix is a.md-only edit (lockfile imports the prompt at runtime).Problem (WHY)
Maintainer flagged: "I have not seen [the panel] labelling issues lately."
Investigation:
13 currently-open, human-authored, untriaged issues: Claude support - name collisions because plugins are deployed without namespacing #1120, RFE: Add brownfield agent context discovery to apm init #1122, RFE: Extend brownfield discovery to cover agent harness (hooks, commands, styles) #1130, [FEATURE] Skip instructions in CLAUDE.md when already deployed to .claude/rules/ #1138, [aw] No-Op Runs #1144, [aw] PR Review Panel failed #1151, [FEATURE] apm find — trace a file back to the package that brought it #1156, [FEATURE] Adding permissions as a primitive #1157, Refactor test-integration.sh to fixture-driven pytest discovery (eliminate manual test wiring) #1166, Audit unmarked integration tests + swap test-integration.sh to pytest discovery (PR2 of #1166) #1168, [aw] Daily Test Improver failed #1177, [cli-consistency] CLI Consistency Report -- 2026-05-07 #1187, [BUG] YAML field
targetis not honored #1188.Last successful sweep (2026-05-06, run 25437842915) labelled exactly one issue (Docs: clarify install-time discovery rules for marketplace-published plugins (
.apm/<type>/vs root convention dirs) #1161) and exited with:-- which is false.
Today's scheduled run 25496929817 crashed on the
cowork-in-allbug (already fixed by ci(panels): pin target=copilot for pr-review-panel and triage-panel #1192).From the agent stdio trace of the 2026-05-06 run:
Then:
So the agent:
list_issuescall (~140 KB response).BATCH_ALLOW_LIST = [1161]from the head of whatever slice it did see.perPage. Never re-ordered oldest-first.Why the agent went off-script: the SCHEDULED_SWEEP prompt example showed
gh issue list --limit 200, butshared/apm.mdtells the agent that shellghis unauthenticated and to use the GitHub MCPlist_issuestool. The MCP tool defaults to newest-first and lacks "exclude label" semantics, neither of which the prompt addresses.Approach (WHAT)
Rewrite the SCHEDULED_SWEEP "Step 1: Gather candidates" subsection in
.github/workflows/triage-panel.mdto:gh issue listexample.list_issueswithorderBy: CREATED_AT, direction: ASC, perPage: 30.after: <endCursor>until either 10 eligibles found, orhasNextPage: false, or 5 pages scanned (a healthy sweep is allowed to be small).perPageto 15 if a single page can't be read in one tool response.The lockfile uses
{{#runtime-import .github/workflows/triage-panel.md}}to pull the prompt at runtime, sogh aw compileproduces zero lockfile diff. Verified locally.Validation
gh aw compile triage-panel-> 0 errors, 0 warnings, 0 lockfile diff..github/workflows/triage-panel.md+ a CHANGELOG line.Trade-offs
min(N_eligibles, 10)entries" check, but that would risk noisy CI failures from edge cases. Prompt clarity is the cheaper fix.safe-output-toolsstill cap atadd_labels(max:70), which is ~10 issues at 7 labels each.How to test
After merge, watch the next daily scheduled run of
.github/workflows/triage-panel.lock.yml. Expected: the agent processes up to 10 untriaged issues (oldest first) in a single sweep, draining the current 13-issue queue across two cron ticks.