Collapse issue triage into a single agentic workflow - #68616
Merged
Conversation
The triage orchestrator handed its drafted comment to the
triage-comment-reviewer worker via the call-workflow safe output. That
handoff is broken by an upstream gh-aw bug: the ingestion step sanitizes
safe-output items against a per-type field schema, and that schema has no
entry for call_workflow, so every field is stripped. The item arrives at
the handler as {"type":"call_workflow"}, the handler reads an undefined
workflow_name, and the safe_outputs job fails.
As a result the reviewer job has been skipped on every triaged issue since
2026-08-14: labels and issue type were applied but the triage comment was
never posted, and each run filed an [aw] failure issue (21 so far).
Collapse the two workflows into one. The orchestrator now posts the comment
itself via add-comment, whose validation schema does include item_number, so
it is not affected by the same bug. The reviewer's rules are preserved in
the orchestrator prompt: the vulnerability-report gate now suppresses the
comment (labels are still applied), and its comment-level ban-list is merged
with the orchestrator's existing content rules into one list.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 5956f28f-dc84-4eba-9f9a-d2941bca8610
Contributor
|
Hey @dotnet/aspnet-build, looks like this PR is something you want to take a look at. |
DeagleGross
enabled auto-merge (squash)
August 18, 2026 09:22
Contributor
There was a problem hiding this comment.
Pull request overview
This PR collapses the issue triage automation from a two-workflow orchestrator/worker model into a single workflow so the triage agent can post its own comment directly, avoiding the upstream gh-aw sanitizer bug that strips call_workflow payload fields.
Changes:
- Remove the separate
triage-comment-reviewerworkflow (and its lock file) and stop handing off triage comments viacall_workflow. - Update
issue-triage-agentto post the triage summary via anadd_commentsafe output and to suppress comments entirely for vulnerability-report issues. - Regenerate
issue-triage-agent.lock.ymlto reflect the new safe outputs and job graph.
Show a summary per file
| File | Description |
|---|---|
| .github/workflows/triage-comment-reviewer.md | Deleted: removes the second-pass triage comment reviewer workflow. |
| .github/workflows/triage-comment-reviewer.lock.yml | Deleted: removes the compiled lock workflow for the reviewer. |
| .github/workflows/issue-triage-agent.md | Updated: agent now posts the triage comment itself via safe outputs and includes a vulnerability-report comment suppression gate. |
| .github/workflows/issue-triage-agent.lock.yml | Updated: regenerated compiled workflow to remove call_workflow and add add_comment handling. |
Review details
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
Suppressed comments (2)
.github/workflows/issue-triage-agent.md:668
- The narrative instructions refer to
add-comment, but the safe output tool name emitted by gh-aw isadd_comment(underscore). Using the wrong name in this key decision point increases the risk of the agent emitting an invalid tool call and skipping comment posting/suppression. Recommend updating these instructions to consistently useadd_commentwhen referring to the tool invocation.
5. **Apply the vulnerability gate.** If the issue is a vulnerability report
per "Vulnerability Reports: Apply Labels, But Post No Comment" above,
stop here: call `noop` and do **not** call `add-comment`. The labels and
issue type you applied in steps 2–4 stay in place. Otherwise continue.
.github/workflows/issue-triage-agent.md:703
- Same tool-name mismatch in the No-op fallback section: the compiled tool is
add_comment, but the text saysadd-comment. Aligning here too reduces the chance the agent emits an invalid call when choosing betweennoopand posting a comment.
Call the `noop` tool — and do **not** call `add-comment` — in either of
these two cases:
- Files reviewed: 3/4 changed files
- Comments generated: 1
- Review effort level: Lite
Comment on lines
+219
to
+222
| **If the issue IS a vulnerability report:** still apply the area label, the | ||
| sub-type label, and the issue type exactly as you normally would (Step 7, | ||
| items 1–4), then **post no comment at all**. Skip Step 6, do **not** call | ||
| `add-comment`, and call `noop` instead: |
Youssef1313
approved these changes
Aug 18, 2026
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.
Problem
The issue triage agent runs as two gh-aw workflows:
issue-triage-agent(orchestrator) classifies the issue, applies the area label and issue type, drafts a triage comment, and hands that comment totriage-comment-reviewer(worker) via thecall-workflowsafe output. The worker re-reads the issue, decides whether the comment is safe to post, and posts it.That handoff is broken by an upstream gh-aw bug. Evidence chain, from the artifacts of run 31985189298:
safeoutputs.jsonl:{"type":"call_workflow","workflow_name":"triage-comment-reviewer","inputs":{…}}GH_AW_VALIDATION_JSONenv var. That schema has an entry fordispatch_workflowbut none forcall_workflow, so every field is whitelist-stripped. The collectedagent_output.jsonends up as literally{"type":"call_workflow"}.call_workflow.cjsin thesafe_outputsjob readsmessage.workflow_name, finds it undefined, and logsWorkflow name is empty.safe_outputsgoes tofailure, thecall-triage-comment-reviewerjob is skipped, and gh-aw files an[aw] Failed jobs: Issue Triage Agentissue.Net effect since 2026-08-14: labels and issue type were applied, the triage comment was never posted, and every triaged issue produced a noise failure issue — 21 so far (e.g. #68569, #68610).
This is not fixable on our side. The validation schema is compiled into gh-aw's Go source (
pkg/workflow/safe_outputs_validation_config.go, which listsdispatch_workflowbut notcall_workflow), there is no frontmatter override, and hand-patching the generated.lock.ymlwould be silently reverted by the nextgh aw compile. The bug is still present on gh-awmain.What changed
Collapse the two workflows into one.
issue-triage-agent.md: dropped thecall-workflowsafe output, addedadd-comment(max: 1,target: "*",hide-older-comments: true), so the orchestrator posts the comment itself.add_comment's validation schema does includeitem_number, so it is not affected by the same stripping bug.target: "*"is required because the workflow also supportsworkflow_dispatch, which carries no issue payload; the prompt instructs the agent to passitem_numberexplicitly on both trigger paths.set-issue-typeexactly once → removeneeds-area-label→ vulnerability gate → draft →add-comment.### [DRY RUN] Triage Summary.triage-comment-reviewer.mdandtriage-comment-reviewer.lock.yml.issue-triage-agent.lock.ymlregenerated with the pinned v0.86.2 compiler — the version already recorded in its metadata header — so there is no unrelated version-bump noise in the diff.This also halves the number of runs per triaged issue and the corresponding PAT-pool pressure, and makes triage immune to this class of gh-aw orchestration bug.
Rules preserved, not dropped
Removing the reviewer workflow does not weaken the rules. They were ported into the orchestrator prompt, rewritten from second-pass-reviewer voice ("strip this from the draft") into first-pass author voice ("do not write this").
Ported:
CVE-\d{4}-\d{4,}including the note that the sequence number is not fixed-width; specific exploit / attack vector / PoC; vulnerability-class language describing a reported attack; explicit security-fix request framed as such), the "independent of whether the vulnerability is actually in aspnetcore" rule with its three mis-filed examples, and the full "NOT a vulnerability report just because" carve-out. The consequence changes from "reviewer verdict FAIL" to: labels and issue type are still applied, but no comment is posted at all —noopinstead, and not even a polite "this isn't aspnetcore" explanation.#### Notescontent constraints, and the duplicate-citation rules.#### Potential Duplicates, which keeps its heading with- _None found_. Plus the rule against leaving fragments or dangling punctuation.Deliberately dropped, all of which are reviewer-specific machinery for editing someone else's draft and carry no meaning when the author applies the rules while writing:
PASS/REWRITE/FAILverdict vocabulary and the "take exactly one action" step, replaced by a directadd-comment-or-noopinstruction.Verification
Before, on
main: 21 consecutive runs failed, each with✗ Message N (call_workflow) failed: Workflow name is empty,safe_outputsatfailure,call-triage-comment-reviewerskipped, and no comment posted. Example: run 31985189298 on #68569.After, on this branch: two manual
workflow_dispatchruns, both with every job atsuccessincludingsafe_outputs, and nocall-triage-comment-reviewerjob present in the run graph at all.Processing message 2/2: add_comment→✓ completed successfully,Status: success, Successful: 2, Failed: 0. The collectedagent_output.jsonretained the full item —{"type":"add_comment","body":"### Triage Summary…","item_number":68564,…}— rather than the stripped{"type":"call_workflow"}seen onmain, which directly demonstrates the sanitizer problem is gone. The comment posted correctly, with#### Notesomitted (nothing to add) and- _None found_under Potential Duplicates, per the merged section-shape rules.area-authand typeBug, then suppressed the comment vianoopwithTriage comment suppressed: issue is a vulnerability report (…). The ported Step 2a gate works end-to-end from the collapsed prompt.