name: review-mr-post
description: Review a PETSc GitLab merge request and post the findings back as inline DiffNote comments (with apply-able suggestion blocks where possible). Use when the user asks to "post review comments on MR ", "leave inline comments on the MR", or "review and post" — anything that should land on GitLab, not stdout.
argument-hint: <MR_IID | diff-file | empty for current branch>
Adhere to @CLAUDE.md while reviewing and drafting comments.
Identify and fetch
Follow @../review-mr/identify.md (Sections 1–3) to resolve <MR_IID>, fetch metadata, and check for drift.
Review
Follow @../review-mr/review-procedure.md (Sections 4–6) to classify and verify findings. Then continue below to filter and post.
7. Filter findings
Only post findings that have a concrete, actionable fix (a code change the author can apply). Do NOT post:
- Informational or observational notes ("just noting...", "no issue, but...")
- Findings that acknowledge correctness but flag theoretical fragility
- Style nits with no specific suggested change
- Comments on code that was not changed in the MR (surrounding context is for understanding, not reviewing)
Each posted comment opens a discussion thread the author must resolve — avoid noise.
8. Post inline comments as DiffNotes
Use the GitLab Discussions API with JSON input to create inline DiffNote comments.
IMPORTANT: Use --input - with -H "Content-Type: application/json" — the -f flag with bracket notation does NOT work for nested position fields.
For each comment, use this Python pattern:
import json, re, subprocess
body = "<comment body with optional suggestion block>"
# Guard against patterns that break GitLab suggestion blocks:
# 1. Trailing backslash breaks suggestion rendering
# 2. Triple backticks inside suggestion body (e.g., in markdown files)
suggestion_match = re.search(r'(```suggestion[^\n]*\n)(.*?)(```)\s*$', body, re.DOTALL)
if suggestion_match:
opening, inner, _ = suggestion_match.groups()
if inner.count('```') > 0 or inner.rstrip('\n').endswith('\\'):
# Fall back to plain code block
body = body.replace(opening, '```\n', 1)
payload = {
"body": body,
"position": {
"position_type": "text",
"base_sha": "<BASE_SHA>",
"head_sha": "<HEAD_SHA>",
"start_sha": "<START_SHA>",
"new_path": "<file_path>",
"old_path": "<file_path>",
"new_line": <line_number_in_new_file>
}
}
p = subprocess.run(
["glab", "api", "projects/:id/merge_requests/<MR_IID>/discussions",
"-X", "POST", "--input", "-", "-H", "Content-Type: application/json"],
input=json.dumps(payload), capture_output=True, text=True, check=True
)
assert '"DiffNote"' in p.stdout, f"Unexpected response: {p.stdout}"
9. Use GitLab suggestion blocks for concrete fixes
When a comment has a specific code fix, include a suggestion block in the body so the author can click "Apply suggestion":
```suggestion:-0+0
corrected line here
```
-0+0means replace just the target line (thenew_linein the position). Use-N+Mto expand the range to N lines before and M lines after the target line.- CRITICAL: The suggestion body replaces the entire selected range. You MUST reproduce every line in the range, not just the changed ones. For example,
suggestion:-2+0selects 3 lines (2 before + the target); the body must contain all 3 lines (with your edits applied). Omitting unchanged lines will delete them. When in doubt, prefersuggestion:-0+0targeting a single line. - To insert a new line after the target, use
suggestion:-0+0and include both the original target line and the new line. - To delete a line, use an empty suggestion block.
- Only use suggestions for concrete fixes. Use plain comments for design/architectural feedback.
- Only comment on lines that are part of the MR diff. Do not suggest changes to unchanged code that happens to be near the diff.
10. Line number mapping
- For new files:
new_line= the line number in the file itself. - For modified files:
new_line= the line number in the new version of the file. Parse the@@hunk headers to map correctly.
11. Verify
After posting, confirm each response has "DiffNote" to ensure comments appear inline on the Changes tab.