Post a real GitHub PR review with line-anchored inline comments; invoked by /orc:code-review after findings. For commenting on your OWN diff, prefer the bundled /code-review --comment.
Installs into .claude/skills of the current project.
Are you the author of Inline Review?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/higoralves-inline-review)
---
name: inline-review
description: Post a real GitHub PR review with line-anchored inline comments; invoked by /orc:code-review after findings. For commenting on your OWN diff, prefer the bundled /code-review --comment.
---
# Inline GitHub PR Review
Convert a list of structured findings (from `orc-pr-reviewer` and/or `orc-security-reviewer`) into a real GitHub PR review — inline comments anchored to specific files and lines, optional one-click apply suggestion blocks, and a review event (APPROVE / COMMENT / REQUEST_CHANGES) computed mechanically from finding severities.
This skill replaces the legacy text-block summary format. The reviewed author opens the PR and sees comments pinned next to the actual code, not a markdown wall they have to manually navigate.
## When to use
- Inside `/orc:code-review` Phase 5–7 after merging findings from agents.
- Anywhere else you need to post a structured PR review programmatically.
## When NOT to use
- For top-level PR comments without line anchors → use `gh pr comment`.
- For replying to an existing review comment → use the replies endpoint (`gh api repos/.../pulls/.../comments/<id>/replies`); see `orc:receiving-code-review`.
- For your OWN PR's response loop → use `/orc:address`, not this skill.
## The contract (schema, severities, event rule)
The finding schema, severity enum, severity→event mapping, event-computation
algorithm, confidence ≥0.8 rule, and self-contradiction detection are defined
**once**, in `orc:review-contract`. Read that skill before posting; this skill
owns only the posting mechanics below.
Posting-layer obligations from the contract, restated as duties (not schema):
- Compute the event mechanically from the severity set — the agent's narrative
verdict is ignored. `--soft-tests` relaxes only the `test` severity.
- Run self-contradiction detection on each agent `summary`; warn with a
`> **⚠️ Caution**` callout, then post the computed event anyway.
- Validate each finding's `path`/`line` per the contract's line-number
semantics before posting.
## Posting backend selection
Two paths produce identical end-result on GitHub. The orchestrator picks at runtime.
### Default: `gh api` (atomic batched POST)
One call posts everything atomically (all comments + overall body + event). Requires only `gh` CLI authenticated — already in orc's tool-check.
```bash
gh api repos/${OWNER}/${REPO}/pulls/${PR}/reviews \
--method POST \
--input - <<EOF
{
"event": "REQUEST_CHANGES",
"body": "Overall framing paragraph for the review.",
"comments": [
{
"path": "src/auth.ts",
"line": 42,
"side": "RIGHT",
"body": "null deref when token absent — guard with early return.\n\n\`\`\`suggestion\nconst token = parseToken(req);\nif (!token) return res.status(401).end();\n\`\`\`"
},
{
"path": "src/api.ts",
"start_line": 118,
"line": 120,
"side": "RIGHT",
"body": "user input flows into raw SQL — parameterize via \`$1\`/\`$2\`."
}
]
}
EOF
```
Capture the returned review URL from `.html_url` for echoing to the user.
### Fallback: GitHub MCP (3-call protocol)
When `mcp__plugin_github_github__pull_request_review_write` is available in the session (i.e. the user has the official GitHub MCP plugin installed), prefer it — per-comment dispatch can be more flexible if a future iteration wants per-comment validation.
```
Call 1 — create pending review (no event, holds empty body):
mcp__plugin_github_github__pull_request_review_write
method: "create"
owner: <owner>, repo: <repo>, pullNumber: <pr>
Call 2 — loop, once per finding:
mcp__plugin_github_github__add_comment_to_pending_review
subjectType: "LINE"
path: <path>
line: <line>
side: "RIGHT"
startLine: <start_line> | omit
body: <body with optional suggestion block>
Call 3 — submit pending with overall body + event:
mcp__plugin_github_github__pull_request_review_write
method: "submit_pending"
event: "REQUEST_CHANGES" | "COMMENT" | "APPROVE"
body: <overall framing paragraph>
```
The orchestrator's selection logic:
```
if "mcp__plugin_github_github__pull_request_review_write" in available_tools:
use_mcp_path()
else:
use_gh_api_path()
```
## Suggestion block rules
GitHub renders a triple-backtick `suggestion` block inside a comment body as a one-click "Apply suggestion" button. Use sparingly:
- **Length:** ≤ 6 lines of code. Longer suggestions are usually refactors disguised as fixes — describe in prose instead.
- **Completeness:** Committing the suggestion must FULLY resolve the issue. No partial fixes that leave the author guessing.
- **Mental compile:** The suggested code must be syntactically valid in the target language and reference only symbols visible at the comment's line. No imports the author has to add separately.
- **No refactor smuggling:** Don't suggest renames, file moves, or stylistic rewrites as committable suggestions. Those go in prose.
Format inside the comment `body`:
````
Brief prose description of the problem.
```suggestion
const token = parseToken(req);
if (!token) return res.status(401).end();
```
Optional follow-up prose (caveat, edge case, etc.).
````
If `suggestion_code` is set on a finding but doesn't meet the rules above, drop it from the suggestion block and keep the prose only.
## The preview gate (mandatory)
Before posting, ALWAYS show the user the constructed payload. No `--no-confirm` flag. Open with a `**📋 Preview — review for #<PR>**` headline (per the `orc:callouts` palette); the aligned comment list rides the `preview` of `Post the review as shown` (header `Post`, `orc:gates` §3 — fence fallback when `AskUserQuestion` is unavailable). The preview lists:
- The computed event (`APPROVE` / `COMMENT` / `REQUEST_CHANGES`)
- The overall body (≤ 2 sentences — see the cap below)
- One line per comment: `<path>:<line> [severity] <title>`
- Total comment count
- Any self-contradiction warnings (see severity-event rule above)
Then `AskUserQuestion`:
- `Post the review as shown`
- `Edit / drop specific comments` — loop back to drop or rewrite individual entries
- `Switch to summary-only mode` — fall back to text-block markdown, do not post
- `Cancel` — exit without posting; echo the constructed payload as JSON for the user to copy
This is the single most important UX rule. Auto-posting reviews is a trust-eroding move; the gate is cheap and catches mistakes at zero cost.
## Iron rules
1. **Severity-event mapping is computed mechanically.** Agents do NOT decide the event. The posting layer overrides any agent verdict that contradicts its own findings.
2. **Max 15 inline comments per review.** Over-commenting erodes signal. If agents return > 15, surface the count and ask the user which to drop before posting.
3. **Suggestion blocks ONLY when they meet all three rules** (length, completeness, mental compile). Don't smuggle refactors.
4. **Preview gate is mandatory.** No flag bypasses it.
5. **Comments are posted on lines the author actually modified in this PR.** Pre-existing bugs not touched by the diff get dropped at the agent layer (caveman-review rule); if any slip through, the orchestrator filters them by checking each `path:line` is in the diff before posting.
6. **No AI attribution in the review body or comments.** Same rule as everywhere else in orc — the comments speak for themselves.
## Tone
The comment body should follow `orc:caveman-review` discipline — terse, actionable, signal-only. The overall review body is hard-capped at **2 sentences (~40 words)**: one clause framing the PR + finding counts by severity (e.g. "CSV export for /reports. 2 bugs, 1 untested branch, 2 nits."). It never restates inline comments, never praises, never hedges — the inline comments carry all detail. No throat-clearing, no praise per finding. One line per problem in the comment body, suggestion block underneath if applicable.
## Comment-body templates
### Bug with concrete fix (suggestion block fits)
````
Null deref when `req.headers.authorization` is missing — `parseToken()` returns null and the next line accesses `.userId` unconditionally. 500 to client, no log.
```suggestion
const token = parseToken(req);
if (!token) return res.status(401).end();
```
````
### Bug without concrete fix (prose only)
```
Race condition: `cycleParticipants.id` is read in line 507 then mutated in line 512 by a concurrent worker. The intermediate state can leak into the cycleDetails projection. Either lock the row in the outer transaction or refetch after mutation.
```
### Test gap (no suggestion possible)
```
`evaluateeAllowedByStepFilter` has no test for `participants: []` (array, not object). `typeof [] === 'object'` passes the guard; `p.blacklistedUsers` is undefined; `safeIds(undefined)` returns []; the filter silently allows everyone. Add a test case with `participants: []` to pin the fail-open behavior, OR add an `Array.isArray(p)` guard.
```
### Question (low confidence, asking author)
```
q: This new `getWorkflowOverview` endpoint duplicates the admin router's. Is the intent to migrate one to the other, or are they meant to diverge? If the latter, worth a comment explaining the split.
```
## Getting help
```bash
# Inspect what the gh api invocation will look like (dry-run alternative)
echo "$PAYLOAD_JSON" | jq .
# After posting, fetch the posted review for verification
gh api repos/${OWNER}/${REPO}/pulls/${PR}/reviews/${REVIEW_ID}
# List all reviews on a PR
gh pr view ${PR} --json reviews
```
## References
- GitHub REST API — Reviews: https://docs.github.com/en/rest/pulls/reviews
- Suggestion block format: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/incorporating-feedback-in-your-pull-request#applying-suggested-changes
- Sibling skills: `orc:gh-cli` (the gh CLI / API surface), `orc:caveman-review` (tone discipline that comment bodies should follow).