Flag security issues inline on pull requests

Posts security scan findings as targeted review comments on the exact lines of code that need fixing, with labels and check-run status updates via GitHub CLI.

Best for: Engineering teams running automated security scans and wanting findings to land where devs see them.

Engineering / code-reviewfor-engineersexecutionneeds-integrationfrom-repo

Skill file

Preview skill file
---
name: pr-github-ops
description: Post Superagent PR security scan findings as inline GitHub pull request review comments using the authenticated gh CLI. Use whenever you need to comment on a PR scan finding, manage Superagent PR labels, complete a GitHub check run, or avoid posting findings as general PR thread comments. Trigger for any Superagent sandbox PR scan handoff that owns GitHub side effects via gh.
---

# PR GitHub operations

Superagent PR scans run in a sandbox with an authenticated `gh` CLI. You own GitHub side effects after handoff: inline finding comments, managed labels, and check-run completion.

Read `pr-scan-context.json` first. It contains `owner`, `repo`, `prNumber`, `headSha`, `checkRunId`, `reviewedFindingPaths`, and `dismissedFingerprints`.

## Critical rule: inline comments, not thread comments

`gh pr comment` creates **issue comments** on the PR conversation thread. That is wrong for actionable findings.

For each finding with a changed file and diff line, post a **pull request review comment** anchored to that line in the Files changed view.

| Goal | Wrong | Right |
|------|-------|-------|
| Comment on a finding at a diff line | `gh pr comment` | `gh api` review comment or review with `comments[]` |
| Summary-only note with no line anchor | `gh pr comment` is acceptable | optional |

If you already posted findings with `gh pr comment`, delete those issue comments and repost inline before finishing the scan.

## Inspect before posting

```bash
owner=OWNER
repo=REPO
pr=PR_NUMBER

# Existing inline review comments
gh api "repos/${owner}/${repo}/pulls/${pr}/comments" --paginate

# Existing general PR thread comments (avoid duplicating here)
gh api "repos/${owner}/${repo}/issues/${pr}/comments" --paginate

# PR diff files and patches (confirm path + line are in the diff)
gh api "repos/${owner}/${repo}/pulls/${pr}/files" --paginate
```

Skip findings when:
- `file` is in `reviewedFindingPaths`
- fingerprint already exists in an inline comment
- you already posted an inline finding on that `file` this run (one inline finding per file)

## Finding comment body format

Every finding comment must include the Superagent marker and fingerprint.

```markdown
<!-- brin-pr-finding -->
**P0:** Workflow uses pull_request_target trigger for untrusted fork PRs

Short evidence sentence here.

Short recommendation sentence here.

<!-- superagent-finding-fingerprint:HEX_SHA256 -->
```

Severity to priority: `critical` → P0, `high` → P1, `medium` → P2, `low` → P3.

Fingerprint: SHA-256 of the normalized comment body **before** appending the fingerprint line. Lowercase, collapse whitespace, remove the marker and any existing fingerprint comment.

```bash
body='<!-- brin-pr-finding -->
**P1:** Overly broad permissions: write-all in privileged workflow

Grants broad write access to GITHUB_TOKEN.

Replace with least-privilege job permissions.'

printf '%s' "$body" \
  | sed 's/<!-- brin-pr-finding -->//g' \
  | tr '[:upper:]' '[:lower:]' \
  | tr -s '[:space:]' ' ' \
  | sed 's/^ //;s/ $//' \
  | sha256sum \
  | awk '{print $1}'
```

Append the fingerprint as the last line of the comment body.

Use `short_evidence` and `short_recommendation` in inline comments. Keep them terse.

## Post inline review comments with gh api

`line` must be a line number on the **RIGHT** (added) side of the PR diff for `path`. Confirm with the PR files API or diff before posting.

### Single inline comment

```bash
head_sha=HEAD_SHA_FROM_CONTEXT

gh api \
  "repos/${owner}/${repo}/pulls/${pr}/comments" \
  -X POST \
  -f commit_id="$head_sha" \
  -f path=".github/workflows/example.yml" \
  -f side=RIGHT \
  -F line=12 \
  -f body="$comment_body"
```

Use `-F line=12` for numeric fields. Use `-f` for strings.

### Batch inline comments (preferred for multiple findings)

Write `review.json`:

```json
{
  "commit_id": "HEAD_SHA",
  "event": "COMMENT",
  "body": "<!-- brin-pr-finding -->\nSuperagent found 2 security concern(s).",
  "comments": [
    {
      "path": ".github/workflows/example.yml",
      "line": 4,
      "side": "RIGHT",
      "body": "<!-- brin-pr-finding -->\n**P0:** ...\n\n...\n\n<!-- superagent-finding-fingerprint:abc123... -->"
    },
    {
      "path": ".github/workflows/example.yml",
      "line": 8,
      "side": "RIGHT",
      "body": "<!-- brin-pr-finding -->\n**P1:** ...\n\n...\n\n<!-- superagent-finding-fingerprint:def456... -->"
    }
  ]
}
```

Post it:

```bash
gh api \
  "repos/${owner}/${repo}/pulls/${pr}/reviews" \
  -X POST \
  --input review.json
```

Post at most 50 inline comments per review. If you have more findings, split across multiple reviews.

### Fallback when no diff line exists

Only when a finding has no valid `file` + `line` in the PR diff, post a single consolidated issue comment:

```bash
gh api \
  "repos/${owner}/${repo}/issues/${pr}/comments" \
  -X POST \
  -f body="$fallback_body"
```

Never post the same finding both inline and on the thread.

## Delete stale or misplaced comments

```bash
# Delete inline review comment
gh api "repos/${owner}/${repo}/pulls/comments/COMMENT_ID" -X DELETE

# Delete general PR thread comment
gh api "repos/${owner}/${repo}/issues/comments/COMMENT_ID" -X DELETE
```

Delete stale Superagent finding comments whose fingerprints are no longer in the current findings set. Delete thread comments you replaced with inline comments.

## Managed labels

Only touch Superagent managed labels. Preserve all unrelated labels.

```bash
gh pr edit "$pr" --repo "${owner}/${repo}" --add-label "pr:flagged"
gh pr edit "$pr" --repo "${owner}/${repo}" --remove-label "pr:verified"
```

Clean scan:

```bash
gh pr edit "$pr" --repo "${owner}/${repo}" --remove-label "pr:flagged" --add-label "pr:verified"
```

## Complete the check run

Use `checkRunId` from context. Always set `status=completed`.

```bash
check_run_id=CHECK_RUN_ID_FROM_CONTEXT

gh api \
  "repos/${owner}/${repo}/check-runs/${check_run_id}" \
  -X PATCH \
  -f status=completed \
  -f conclusion=action_required \
  -f 'output[title]=PR requires security review' \
  -f 'output[summary]=2 security concern(s) detected.' \
  -f 'output[text]=Optional longer details.'
```

Conclusions:
- `success` — clean scan
- `action_required` — findings need review
- `neutral` — inconclusive scan

## End-to-end workflow

1. Read `pr-scan-context.json` and PR input JSON.
2. Run security analysis (other skills) and produce findings with `file`, `line`, `severity`, `title`, `short_evidence`, `short_recommendation`.
3. List existing inline and thread comments; compute fingerprints; skip dismissed/reviewed/duplicate findings.
4. Post findings as inline review comments with `gh api` (single comment or batch review). Do not use `gh pr comment` for findings.
5. Delete stale or misplaced Superagent finding comments.
6. Set managed PR labels.
7. Complete the check run.
8. Write the agent receipt JSON with `github_operations_completed: true` and `posted_comment_ids` when available.

Source

Creator's repository · superagent-ai/skills

View on GitHub

Security

Security checks in progress
Results will appear here once audits complete
Checked by 3 independent security firms
Does it try to trick the AI?Not yet checkedPending · Gen Agent Trust Hub
Does it sneak in hidden code?Not yet checkedPending · Socket
Does it have known bugs?Not yet checkedPending · Snyk