Skip to content
Merged
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
26 changes: 19 additions & 7 deletions .github/workflows/qwen-autofix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1036,17 +1036,26 @@ jobs:
| select(((.author_association // "") | IN($trust[])) or (.user.login // "") == $rb)
| select((.state // "") | IN("CHANGES_REQUESTED", "COMMENTED")) ] | length' \
"${WORKDIR}/rv.json")"
# /review posts Suggestion-level findings as inline comments prefixed
# `**[Suggestion]**`. They are recommendations, not blockers — keep them
# out of the autofix loop, exactly as the suggestion-summary comment they
# replaced always was. Anchored to the body start and paired with the
# /review footer so a human comment that merely quotes the prefix stays
# actionable. jq's `^` is string-anchored, so tolerate leading whitespace
# the review model may emit; `**[Critical]**` can never match either way.
QWEN_SUGGESTION_FILTER='^[[:space:]]*\*\*\[Suggestion\]\*\*'
N_COMMENTS="$(jq --arg wm "${EFF_WM}" --arg rb "${REVIEW_BOT}" --arg ab "${AUTOFIX_BOT}" \

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] This filters the inline review-comment list, but a suggestion-only /review still leaves a COMMENTED review row, and N_REVIEWS above counts every COMMENTED review from the review bot. In that case the scan still sees N_REVIEWS=1 / N_COMMENTS=0, so the autofix job is queued and can burn one of its rounds even though the **[Suggestion]** comments were excluded. Please also exclude the suggestion-only /review body from N_REVIEWS, NEWEST, and the ## Reviews feedback render, or use a marker/body state the workflow can classify as non-actionable.

— GPT-5 via Qwen Code /review

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I think still needs to be covered here: the new filter removes /review Suggestion inline comments from N_COMMENTS, but a Suggestion-only review still submits a trusted COMMENTED review with the body Reviewed — no blockers. Suggestions are inline.

That means a bot PR with only non-blocking Suggestions still has N_REVIEWS=1, so review-scan will enqueue it for the autofix loop even though the inline Suggestion comments were filtered out. The same gap also affects the later NEWEST calculation / feedback.md rendering path, where COMMENTED reviews are treated as actionable review feedback.

Could we apply the same non-actionable Suggestion-only gate to the review-level channel as well, not just to inline comments?

--argjson trust "${TRUSTED_ASSOC}" '
--argjson trust "${TRUSTED_ASSOC}" --arg sf "${QWEN_SUGGESTION_FILTER}" '
[ .[]
| select((.created_at // "") > $wm)
| select((.user.login // "") != $ab)
| select(((.author_association // "") | IN($trust[])) or (.user.login // "") == $rb) ] | length' \
| select(((.author_association // "") | IN($trust[])) or (.user.login // "") == $rb)
| select((((.body // "") | test($sf)) and ((.body // "") | test("via Qwen Code /review"))) | not) ] | length' \
"${WORKDIR}/rc.json")"
# Issue-level PR comments (e.g. /review suggestion summaries) are
# also actionable feedback. Exclude the bot's own eval markers.
# Exclude known non-actionable bot comments (triage stages,
# coverage reports, suggestion summaries, force-push reminders).
# Issue-level PR comments are also actionable feedback. Exclude the
# bot's own eval markers, and known non-actionable bot comments
# (triage stages, coverage reports, legacy suggestion summaries,
# force-push reminders).
BOT_COMMENT_FILTER='<!-- (autofix-eval|qwen-triage|qwen-review-suggestion-summary|pr-force-push|qwen-review-ack) '
N_ISSUE_COMMENTS="$(jq --arg wm "${EFF_WM}" --arg rb "${REVIEW_BOT}" --arg ab "${AUTOFIX_BOT}" \
--argjson trust "${TRUSTED_ASSOC}" --arg bf "${BOT_COMMENT_FILTER}" '
Expand Down Expand Up @@ -1275,12 +1284,15 @@ jobs:
"${WORKDIR}/rv.json"
echo
echo "## Inline comments"
# Mirrors the review-scan gate: /review `**[Suggestion]**` findings are
# recommendations, not blockers, so they never become autofix work.
jq -r --arg wm "${WATERMARK}" --arg rb "${REVIEW_BOT}" --arg ab "${AUTOFIX_BOT}" \
--argjson trust "${TRUSTED_ASSOC}" '
--argjson trust "${TRUSTED_ASSOC}" --arg sf '^[[:space:]]*\*\*\[Suggestion\]\*\*' '
.[]
| select((.created_at // "") > $wm)
| select((.user.login // "") != $ab)
| select(((.author_association // "") | IN($trust[])) or (.user.login // "") == $rb)
| select((((.body // "") | test($sf)) and ((.body // "") | test("via Qwen Code /review"))) | not)
| "- \(.path // "?"):\(.line // "?") @\(.user.login): \(.body // "" | gsub("\r"; ""))"' \
"${WORKDIR}/rc.json"
echo
Expand Down
3 changes: 2 additions & 1 deletion docs/users/features/code-review.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ Or, after running `/review 123`, type `post comments` to publish findings withou

**What gets posted:**

- High-confidence Critical and Suggestion findings as inline comments on specific lines
- High-confidence Critical and Suggestion findings as inline comments on specific lines, each prefixed with `**[Critical]**` or `**[Suggestion]**` so blockers are distinguishable from recommendations
- Where the fix is a single localized edit, a ` ```suggestion ` block you can apply in one click
- For Approve/Request changes verdicts: a review summary with the verdict
- For Comment verdict with all inline comments posted: no separate summary (inline comments are sufficient)
- Model attribution footer on each comment (e.g., _— qwen3-coder via Qwen Code /review_)
Expand Down
5 changes: 4 additions & 1 deletion packages/cli/src/commands/review.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,14 @@ describe('reviewCommand', () => {
'pr-context',
'load-rules',
'presubmit',
'post-suggestions',
'cleanup',
]);
});

it('does not register the removed `post-suggestions` subcommand', () => {
expect(registeredSubcommands()).not.toContain('post-suggestions');
});

it('does not register the removed `deterministic` subcommand', () => {
expect(registeredSubcommands()).not.toContain('deterministic');
});
Expand Down
6 changes: 2 additions & 4 deletions packages/cli/src/commands/review.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,22 @@ import { fetchPrCommand } from './review/fetch-pr.js';
import { prContextCommand } from './review/pr-context.js';
import { loadRulesCommand } from './review/load-rules.js';
import { presubmitCommand } from './review/presubmit.js';
import { postSuggestionsCommand } from './review/post-suggestions.js';
import { cleanupCommand } from './review/cleanup.js';

export const reviewCommand: CommandModule = {
command: 'review',
describe:
'Internal helpers used by the /review skill (PR worktree setup, context fetch, rules loading, presubmit checks, suggestion summary publishing, cleanup)',
'Internal helpers used by the /review skill (PR worktree setup, context fetch, rules loading, presubmit checks, cleanup)',
builder: (yargs: Argv) =>
yargs
.command(fetchPrCommand)
.command(prContextCommand)
.command(loadRulesCommand)
.command(presubmitCommand)
.command(postSuggestionsCommand)
.command(cleanupCommand)
.demandCommand(
1,
'Specify a subcommand: fetch-pr, pr-context, load-rules, presubmit, post-suggestions, or cleanup.',
'Specify a subcommand: fetch-pr, pr-context, load-rules, presubmit, or cleanup.',
)
.version(false),
handler: () => {
Expand Down
213 changes: 0 additions & 213 deletions packages/cli/src/commands/review/post-suggestions.test.ts

This file was deleted.

Loading
Loading