You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Repair the safe-output submission failure behind #4704. In the recorded run for #4193, jq payload preparation was denied by the shell allowlist. The agent then submitted a diagnostic test message please ignore comment, consumed the one-comment quota, and could not publish its real triage summary.
Allow jq and document separate, checked JSON payload preparation followed by exactly one safeoutputs add_comment . submission. Explicitly prohibit diagnostic writes, -/@- body experiments, and retries after a submission error.
Add a trusted pre-publication validation step that checks the entire safe-output batch before any comments or labels are applied. Reject placeholder/unfinished comments, quoted or fenced templates, missing check rows or sections, multiple comments, label-only results, and mixed success/incomplete outcomes. Preserve explicit no-op and failure reporting.
Keep the existing trigger conditions, one-comment quota, label allowlist, on-demand label behavior, and read-only agent permissions. Checkout only the trusted validator at the event SHA, with persisted credentials disabled.
Regenerate the workflow lock with the existing gh-aw v0.88.2 compiler and add regression coverage to the lock-verification workflow.
Validation
All 24 Node.js validator regression tests pass, covering complete summaries, diagnostic and unfinished content, duplicate rows/sections, generic/XML/comparison prose, error and incomplete batches, operation ordering, and mode/Environment-consistent label operations. This suite does not test jq payload encoding.
gh aw compile succeeds; repeating compilation leaves the generated lock byte-for-byte unchanged.
git diff --check passes.
Rollout and recovery
Related to #4704; intentionally do not close that tracker on merge. The previously reported completion count included workflow-attributed placeholders and is being re-audited. This PR fixes the workflow, not the existing backlog results.
After this reaches the default branch, verify a small representative pilot, retry only genuinely incomplete issues in completion-gated batches within the existing daily credit budget, and delete confirmed placeholder comments only after replacement summaries succeed. Keep #4704 open until recovery is verified. No backlog retries or comment deletions are included in this PR.
Checklist
Tests added or updated
Public API changes documented — N/A; workflow-only change
Verified against customer repro (if applicable) — recorded workflow failure replayed; no product repro applies
Ensure no breaking changes introduced — no public API changes; malformed triage output is intentionally rejected
The validator ignores the collector's top-level errors array. gh-aw records rejected/over-quota safe-output calls there while retaining any valid items, so a valid-looking comment plus a failed label or second submission is currently published as success. Reject any non-empty output.errors before processing items, and cover that mixed batch in the regression tests.
function validateTriageOutput(output) {
if (!output || !Array.isArray(output.items) || output.items.length === 0 ||
output.items.some(item => !item || typeof item.type !== 'string')) {
throw new Error('Missing or malformed triage output: expected non-empty result items.');
.github/scripts/validate-triage-output.cjs:50
A batch containing both noop and report_incomplete has no comment, enters this branch, and returns successfully. Those are contradictory completed/no-action and failed outcomes, so this still permits a mixed success/incomplete batch. Reject incomplete && noop before the no-comment return and add a regression test.
if (comments.length === 0) {
if (!incomplete && !noop) {
throw new Error('Triage output has no summary or explicit no-op/incomplete result.');
}
if (output.items.some(item => ['add_labels', 'remove_labels'].includes(item.type))) {
Validate placeholders across duplicate rows and all prose
.github/scripts/validate-triage-output.cjs:92
find validates only the first occurrence of each required row, and the placeholder scan is limited to that selected value. A completed row followed by | Issue type | <fill in> | is therefore accepted, so an unfinished template can still be published despite the PR's whole-comment validation goal. After validating the required rows and sections, scan all non-quoted/non-fenced prose for placeholders; add a duplicate-row regression case as well.
Placeholder matcher rejects valid generics and XML tags
.github/scripts/validate-triage-output.cjs:11
This field-name matcher also rejects legitimate C# generics and XML tags whenever their type/tag name is one of these words. For example, a completed Analysis containing Task<Result>, List<Item>, or an XML <summary> tag is classified as unfinished (the current validator throws for Task<Result>), so valid triage output can be blocked. Make placeholder detection context-aware or restrict it to the workflow's actual template forms, and add regressions for these common code/documentation forms.
This issue also appears on line 43 of the same file.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Leading whitespace is stripped before heading validation, allowing an indented code-block heading to pass.
0 open findings
Previously missed (1)
In code that hasn't changed since last review
Validate heading before trimming leading indentation
.github/scripts/validate-triage-output.cjs:95
Checking the heading against body.trim() removes leading indentation before validation. A body whose first line is ## 🔍 Triage Summary therefore passes this check (and the remaining checks when its rows/sections are unindented), even though Markdown renders that first line as a code block rather than the required heading. Validate the original string start instead, and add an indented-heading regression case.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The validator accepts label actions that contradict the summary and on-demand triage rules.
0 open findings
Previously missed (1)
In code that hasn't changed since last review
Validate label actions against summary and Environment state
.github/scripts/validate-triage-output.cjs:90
The gate only checks that label actions follow the comment; it does not verify that they match the summary. A missing/partial Environment with remove_labels, a complete environment with add_labels, and an on-demand summary with either label action are all accepted, even though the workflow requires the opposite behavior (lines 321-328). This can corrupt the Waiting for Author state that controls future activations. Validate the number and type of label operations against the heading variant and parsed Environment row, and add regressions for these contradictory batches.
Addressed the current Copilot findings and remaining related gaps in 42d95c2:
Reject test simple body in required rows and sections.
Require Environment-consistent waiting-label operations for initial/follow-up triage; reject label mutations for on-demand triage.
Reject duplicate required rows/sections and unfinished templates in additional prose, covering the older review finding.
The generic/XML false-positive finding was already fixed in fd13931; its acceptance regressions remain intact.
All 24 validator tests pass. The new regression cases failed before the fixes. Both current inline threads have replies and are resolved. These checks validate the output batch; they do not make comment/label publication atomic.
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
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.
Summary
Repair the safe-output submission failure behind #4704. In the recorded run for #4193,
jqpayload preparation was denied by the shell allowlist. The agent then submitted a diagnostictest message please ignorecomment, consumed the one-comment quota, and could not publish its real triage summary.jqand document separate, checked JSON payload preparation followed by exactly onesafeoutputs add_comment .submission. Explicitly prohibit diagnostic writes,-/@-body experiments, and retries after a submission error.Validation
jqpayload encoding.gh aw compilesucceeds; repeating compilation leaves the generated lock byte-for-byte unchanged.git diff --checkpasses.Rollout and recovery
Related to #4704; intentionally do not close that tracker on merge. The previously reported completion count included workflow-attributed placeholders and is being re-audited. This PR fixes the workflow, not the existing backlog results.
After this reaches the default branch, verify a small representative pilot, retry only genuinely incomplete issues in completion-gated batches within the existing daily credit budget, and delete confirmed placeholder comments only after replacement summaries succeed. Keep #4704 open until recovery is verified. No backlog retries or comment deletions are included in this PR.
Checklist