review — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited review (Agent Skill) and scored it 87/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 3 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 3 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Review a GitHub pull request or GitLab merge request with craft-level attention to semantic HTML, CSS architecture, accessibility, TypeScript patterns, and code quality. Auto-detects platform. Proposes inline diff comments, shows them for approval, posts only what the user approves.
Input: $ARGUMENTS
Platform detection in order:
platform = githubgitlab.com, self-hosted GitLab) → platform = gitlab123) → resolve the remote URL, then apply rules 1–2 against it. Check git remote get-url upstream first (fork workflows push the PR/MR to the canonical upstream repo, not the contributor's origin fork); fall back to git remote get-url origin if no upstream remote exists. If cwd is not in a git repo, or neither remote resolves → ask the user for a URL.AskUserQuestion to ask the user for the PR/MR URL or number directly. Do not guess.Once platform is determined, verify CLI auth:
gh auth status — if not authed, surface the exact command and stop.GitHub (https://github.com/<owner>/<repo>/pull/<number>):
owner, repo, pull_number.owner/repo from the git remote.GitLab (https://gitlab.<host>/<project-path>/-/merge_requests/<iid>):
projectPath (everything between the host and /-/), URL-decode if needed.mrIid.projectPath from the git remote.Check if .claude/review-rules.md exists in the current working directory:
Use Glob to check: .claude/review-rules.mdRun in parallel (per-platform):
Record headRefOid as the commit SHA for positional comments later.
projectPath and mrIid — title, description, author, branches, state, draft status. Extract diff_refs.{base_sha, head_sha, start_sha} — needed for positional comments.projectPath and mrIid — per-file unified diffs with old/new paths and line numbers.projectPath and mrIid — existing discussions for dedupe.Classify each changed file:
| Category | Extensions / Patterns |
|---|---|
tsx/ts | .ts, .tsx |
css | .css, .scss, .module.css, .module.scss |
test | *.test.*, *.spec.*, __tests__/* |
config | *.json, *.yaml, *.yml, *.toml, .eslintrc.*, tsconfig.*, *.config.* |
binary | images, fonts, .woff2, .png, .jpg, .svg (if no text diff) |
other | everything else |
Skip entirely:
ignorePatterns, plus common: *.snap, lockfiles, generated type files)Determine review depth based on size:
For each changed file that wasn't skipped, fetch the full file at HEAD:
gh api /repos/<owner>/<repo>/contents/<path>?ref=<headRefOid> and base64-decode the content field. (Or gh api with Accept: application/vnd.github.raw to get raw contents directly.)mcp__gitlab__get_repository_file_contents with projectPath, file path, and head_sha as ref.Also fetch related context files to understand usage:
.tsx file changed → also read its .module.css / .module.scss (same directory, same base name).module.css changed → also read the .tsx that imports it.test.tsx / .spec.tsx existsImportant: Only generate comments on new or changed lines in the diff. The full files are for understanding context, not for reviewing unchanged code.
Dispatch the `abc:reviewer` subagent (the Agent tool with subagent_type: abc:reviewer) — it owns the universal review rulebook, volume scaling, comment tone, the actionable-comments-only rule, and the suggestion-block format. This skill does not inline those rules; reviewer.md is the single source of truth for them.
Pass everything the reviewer needs inline in the prompt (the agent has no platform access — it cannot fetch anything itself):
github / gitlab) and the PR/MR identifier — context only.headRefOid for GitHub, head_sha for GitLab) so line anchoring is unambiguous..claude/review-rules.md if it was found in Phase 0 (repo-specific overrides that augment the universal rules).The subagent returns a structured YAML list of proposed comments, one per issue on a new/changed line, each carrying:
error | warning | nit | questiona11y | css | typescript | test | quality | securitynew (added/modified lines) or old (removed lines)suggestion block when there's a concrete fix)(The exact output contract lives in the reviewer agent definition — match it when parsing the result for Phases 4–5.)
Before finalizing comments, check existing inline comments/discussions from Phase 1. If an existing comment already covers the same file + line + issue, skip it. At the end, note: "Skipped N comments that overlap with existing discussions."
Display all proposed comments in a numbered list:
## Review: {title}
**{N} comments** across {M} files ({X} errors, {Y} warnings, {Z} nits, {W} questions)
---
### 1. [error] `src/components/Card.tsx:42` — a11y
Non-interactive `<div>` has an `onClick` handler. Use `<button>` instead for keyboard accessibility and screen reader support.
<button type="button" onClick={handleClick} className={styles.card}>
---
### 2. [warning] `src/components/Card.module.css:18` — css
Hardcoded color `#333`. Use a design token instead.
color: var(--color-text-primary);
---
(etc.)Then use AskUserQuestion with these options:
If the user chooses "Let me edit", wait for their instructions. They can:
drop N, M, ... — remove specific comments by numberedit N: new text — replace a comment's bodykeep N, M, ... — only post these specific commentsReconfirm the final set before posting.
For each approved comment, POST to /repos/<owner>/<repo>/pulls/<number>/comments via gh api:
gh api -X POST /repos/<owner>/<repo>/pulls/<number>/comments \
-f body="<comment body>" \
-f commit_id="<headRefOid>" \
-f path="<new path>" \
-F line=<line> \
-f side="RIGHT" # RIGHT = new file (additions/modifications), LEFT = old file (deletions)Pass body via HEREDOC if it contains newlines or backticks (suggestion blocks).
Fallback: if a positional comment fails (stale diff, line out of range), post as a general PR comment via the already-granted gh api (PR-level comments use the issues-comments endpoint): gh api -X POST /repos/<owner>/<repo>/issues/<number>/comments -f body="**<path>:<line>** — <body>".
For each approved comment, post as an inline discussion using mcp__gitlab__discussion_new_with_position:
project_id: the project pathmerge_request_iid: the MR IIDbody: the comment body (with suggestion block if applicable)position_type: "text"base_sha: from diff_refs.base_shastart_sha: from diff_refs.start_shahead_sha: from diff_refs.head_shaold_path: the file's old path from the diffnew_path: the file's new path from the diffnew_line: for additions/modifications on the new sideold_line: for deletions on the old sidePost sequentially (not in parallel) on either platform to preserve ordering in the discussion thread.
Fallback (GitLab): if a positional comment fails, fall back to mcp__gitlab__discussion_new as a general MR-level comment. Prefix the body with the file and line: **{file}:{line}** — {original body}.
After posting, report:
## Done
Posted {N}/{total} comments on {PR/MR title}
- {X} errors, {Y} warnings, {Z} nits, {W} questions
- {F} failed to post as inline (posted as general comments instead)
- {S} skipped (duplicates of existing discussions)
{link to PR/MR}~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.