Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/Texarkanine/.cursor-rules --skill pr-feedback-judge명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Basic PR Review - looks for critical blocking issues and a decent attempt to find other high-impact but non-blocking issues near and in the changed code.
Niko Memory Bank System - Preflight Phase - Pre-Build Plan Validation
Niko Memory Bank System - Niko Phase - Initialization & Entry Point
SOC 직업 분류 기준
SKILL.md 표시 중
| name | pr-feedback-judge |
| description | Invoke with /pr-feedback-judge |
| disable-model-invocation | true |
Evaluate one or more pieces of GitHub PR review feedback against the standard "valid? worth fixing? in scope for this PR?" rubric and emit a per-item verdict with an explicit disposition.
Access requirements. Prefers the gh CLI for direct, batched fetches. Falls back to a registered GitHub MCP server. Requires one or the other — anonymous public access is not supported. Judging also depends on reaching the code under review when the claim leaves the hunk or an outdated anchor must be resolved; see Reading the Code Under Review.
Always fetch the actual comment text and consider it before forming any opinion. Do not improvise a verdict from the URL slug or the file path alone. The reviewer's actual words — and the diff hunk they were anchored to — MUST be retrieved and considered before you judge. Check whether the anchor still describes the current code before treating a line number as trustworthy. Fetch first, then evaluate. Every time.
Classify each input URL by its fragment, then dispatch. Each shape fetches material; only actionable findings become Items.
| URL fragment | Shape | API path (under https://api.github.com) | Fetches |
|---|---|---|---|
(none) — …/pull/N | Whole PR | /repos/{o}/{r}/pulls/{N}/comments + /repos/{o}/{r}/issues/{N}/comments + /repos/{o}/{r}/pulls/{N}/reviews (all paginated) | All inlines (incl. anchor fields), conversation comments, and review bodies — then filter to findings |
#pullrequestreview-<rid> | PR review | /repos/{o}/{r}/pulls/{N}/reviews/<rid> + /repos/{o}/{r}/pulls/{N}/reviews/<rid>/comments | That review's body + its inlines (incl. anchor fields) — then filter to findings |
#discussion_r<cid> | Inline review comment | /repos/{o}/{r}/pulls/comments/<cid> | Single inline (incl. diff_hunk, path, in_reply_to_id, and anchor fields) — then filter |
#issuecomment-<cid> | Conversation comment | /repos/{o}/{r}/issues/comments/<cid> (+ that author's reviews/inlines on the PR — see below) | Linked comment as context; resolve the author's review findings on the PR |
If a URL doesn't match any of these shapes: emit "could not classify URL: <url>" for that item and continue with the rest. Do not crash, do not guess.
#issuecomment-…Bot (and human) "review" posts often land as conversation comments that are mostly summary. When the user passes #issuecomment-<cid>:
user.login.pulls/{N}/comments and pulls/{N}/reviews (filter client-side by user).Same rule when a whole-PR fetch includes such a conversation comment: use it as context for that author; do not emit an Item for the summary itself.
Every inline carries an anchor value — computed by the T1 --jq projection, or derived locally under T2:
| Value | When | Consequence for judgment |
|---|---|---|
current | line is non-null | Read current code at line only when the code source is verified at the PR head SHA |
outdated | subject_type is line and line is null | Do not read current code at any line number. Locate the referenced text by searching the current file for the content of diff_hunk. Require exactly one match; if zero or many, report the anchor unresolved and do not judge against a guessed occurrence |
file | subject_type is file | A null line is expected; it carries no staleness meaning |
Derivation when no --jq runs: file if subject_type == "file"; else outdated if line == null; else current.
original_line and original_commit_id address the historical blob the reviewer saw. Retain them for reporting. Never use them to index current code.
An actionable finding is a concrete claim about the PR's code, tests, docs, config, or behavior that asks for a change, raises a defect, or poses a substantive question about the diff.
Read but do not Item-ize (no per-item block, no triage row, no "nothing to address about the flowchart" verdicts):
Human (or bot) review body with real findings and few/no inlines: emit one Item per distinct finding in the body. A single undifferentiated blob of feedback → one Item for that blob.
Linked URL that yields zero findings after filtering: one line — no actionable findings in <url> (summary/context only) — then continue. Do not invent Items to fill the rubric.
Anchor state is not a filter. An outdated anchor whose finding still stands is still an Item. Anchor state informs the verdict, never item-ness.
Default: judge from diff_hunk plus the reviewer's text. Escalate only when the claim reaches outside the hunk, or an outdated anchor must be resolved by locating that content in the current file.
Choose the first sufficient rung. Declare which rung you used.
gh api "repos/{o}/{r}/pulls/{N}" --jq .head.sha (or equivalent). If git rev-parse HEAD equals that SHA, read against that commit — git show HEAD:{path}, git ls-tree HEAD, git grep {pattern} HEAD — not the working tree (a dirty tree is not PR-head evidence). This is the only rung where a current line can be trusted verbatim. Do not use a comment's commit_id as a stand-in for the PR head.git remote -v, pick the remote whose URL matches {o}/{r}; if none matches, fall through to rung 3. Then git fetch {remote} pull/{N}/head (additive: sets FETCH_HEAD, does not touch the index, working tree, or any branch). Read against the ref — git show FETCH_HEAD:{path}, git ls-tree FETCH_HEAD, git grep {pattern} FETCH_HEAD. All read-only; no checkout. Materialize a worktree only to run something (git worktree add --detach into mktemp -d), then git worktree remove.gh api "repos/{o}/{r}/contents/{path}?ref={sha}" -H "Accept: application/vnd.github.raw".gh api repos/{o}/{r} --jq .size first (KB). Above tolerance, stay on raw fetches and say why. When cloning: --filter=blob:none --depth 1 --single-branch into mktemp -d.When no code source is reachable, or an outdated anchor is unresolved, state that the verdict rests on diff_hunk alone.
Evaluate tiers in this exact order. Use the first one available; do not fall through to a lower tier if a higher one is present.
gh CLIDetection:
command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1
If both succeed, use gh api for all fetches. T1 wins on efficiency: it has direct O(1) endpoints for both single-comment URL shapes and composes naturally with batched shell pipelines.
Project every comment and review fetch to the fields below. Measured: inlines drop from ~20.5 KB to ~15.1 KB per page on a busy PR; do not strip the anchor fields to chase a tighter filter — those fields are what staleness detection needs. The projection also computes anchor so classification arrives in the data rather than as a per-item derivation.
For the current diff use gh pr diff {N} -R {o}/{r} (works outside any checkout) or gh api repos/{o}/{r}/pulls/{N} -H "Accept: application/vnd.github.diff". Never fetch bare pulls/{N} JSON for diff purposes. Never use the application/vnd.github.patch media type.
Per-shape invocation recipes:
# Whole PR (paginated). Inline projection retains every field the anchor model needs — do not strip them.
gh api --paginate "repos/{o}/{r}/pulls/{N}/comments" \
--jq '.[] | {id, user:{login:.user.login}, path, subject_type, line, original_line, commit_id, original_commit_id, side, in_reply_to_id, body, diff_hunk, anchor:(if .subject_type=="file" then "file" elif .line==null then "outdated" else "current" end)}'
gh api --paginate "repos/{o}/{r}/issues/{N}/comments" \
--jq '.[] | {id, user:{login:.user.login}, body}'
gh api --paginate "repos/{o}/{r}/pulls/{N}/reviews" \
--jq '.[] | {id, user:{login:.user.login}, state, body}'
# Specific PR review
gh api "repos/{o}/{r}/pulls/{N}/reviews/{rid}" \
--jq '{id, user:{login:.user.login}, state, body}'
gh api --paginate "repos/{o}/{r}/pulls/{N}/reviews/{rid}/comments" \
--jq '.[] | {id, user:{login:.user.login}, path, subject_type, line, original_line, commit_id, original_commit_id, side, in_reply_to_id, body, diff_hunk, anchor:(if .subject_type=="file" then "file" elif .line==null then "outdated" else "current" end)}'
# Single inline review comment (direct, O(1))
gh api "repos/{o}/{r}/pulls/comments/{cid}" \
--jq '{id, user:{login:.user.login}, path, subject_type, line, original_line, commit_id, original_commit_id, side, in_reply_to_id, body, diff_hunk, anchor:(if .subject_type=="file" then "file" elif .line==null then "outdated" else "current" end)}'
# Single conversation comment (direct, O(1))
gh api "repos/{o}/{r}/issues/comments/{cid}" \
--jq '{id, user:{login:.user.login}, body}'
Detection: scan the harness's registered-MCP-servers list (the same block of MCP metadata exposed to you at invocation time) for any server whose name, identifier, or description contains github (case-insensitive substring). If one matches, use its read-only PR/issue tools.
Once a GitHub MCP is detected, read its tool schemas at runtime and pick the tool that matches each URL shape. Filter locally to the same fields the T1 projection keeps, and derive anchor with the rule under Anchor State.
If neither T1 nor T2 is available, emit verbatim:
Cannot fetch GitHub data. Install GitHub CLI and run
gh auth login, or register a GitHub MCP server with your harness.
Do not attempt anonymous curl. Do not scrape HTML. Do not pre-fetch the URL via any other path. Stop and surface the message.
Emit the following block verbatim before evaluating any items:
Evaluating each piece of PR feedback. I'll fetch the actual comment text first — never judging from the URL alone — then for each item answer three questions and state the disposition.
- Valid? Is the reviewer technically right about the code? Why or why not?
- Worth fixing? Is the issue real and severe enough to act on at all? Why or why not?
- In scope for this PR? Should it be fixed on this branch, deferred to a follow-up, dismissed, or already satisfied on the current head? Why or why not?
The three answers compose into a disposition. Feedback can be valid but not worth fixing, valid and worth fixing but out of scope for this PR, or valid when written and already satisfied by the current head — I'll spell each one out.
### Item N — [link to comment](url) by @author
**Where**: `path/to/file.ts:L42` · anchor: current|outdated|file · code: <rung or "diff_hunk only">
(or "(conversation comment)" / "(review body)" when there is no line anchor)
**Reviewer's point** *(quoted or paraphrased)*:
> …
**1. Valid?** ✅ / ❌ — …
**2. Worth fixing?** ✅ / ❌ — …
**3. In scope for this PR?** ✅ / ❌ / 🕒 follow-up — …
**Disposition**: fix in this PR | already addressed | defer to follow-up | dismiss with acknowledgment | dismiss
Disposition vocabulary is fixed (5 values). Pick exactly one per item. Use the emoji set ✅ / ❌ / 🕒 only.
already addressed means the finding was valid when written and the current PR head already satisfies it. It requires code evidence from the ladder; an outdated anchor alone never justifies it. Question 1 is judged as of when the comment was written; already addressed resolves question 3 (mark ✅ and say the head already satisfies it).If — and only if — the total number of items to evaluate is greater than 5 (e.g., a whole-PR URL on a busy PR), emit a compact triage table before the per-item blocks:
| # | Item | Author | Disposition |
|---|---|---|---|
| 1 | [discussion_r123](url) | @reviewer | fix in this PR |
| 2 | [discussion_r456](url) | @reviewer | already addressed |
| 3 | [discussion_r789](url) | @reviewer | dismiss |
For 5 or fewer items, skip the table — the per-item blocks alone are clearer at that scale.
N items evaluated · X to fix in this PR · A already addressed · Y deferred · Z dismissed.
For each invocation:
#issuecomment-…, also fetch that author's inlines and reviews on the PR (author resolution above).
Batch-fetch discipline (specific to this step): if you end up with 3 or more structurally-identical gh api calls in one invocation (e.g., the user gave you multiple #discussion_r… URLs all hitting pulls/comments/<cid>), issue them as one batched shell pipeline, not a sequential loop of tool calls. Example:
for cid in 123 456 789; do
gh api "repos/Texarkanine/a16n/pulls/comments/${cid}" \
--jq '{id, user:{login:.user.login}, path, subject_type, line, original_line, commit_id, original_commit_id, side, in_reply_to_id, body, diff_hunk, anchor:(if .subject_type=="file" then "file" elif .line==null then "outdated" else "current" end)}'
done | jq -s '.'
For T2 (MCP), batching is per-tool — make the minimum number of distinct MCP calls (e.g., one get_review_comments for the whole PR, then filter locally to all the requested cids).
in_reply_to_id, make one extra call to fetch the parent thread (cheap — single comment). The parent provides the context the reviewer was responding to.anchor. Decide whether code beyond diff_hunk is needed. If so, obtain the PR head.sha (see rung 1), select and declare a rung from Reading the Code Under Review.<url>" for that item; continue with the rest.<url>. Either the PR is private and your gh auth doesn't cover it, the comment was deleted, or the URL is malformed. Cannot evaluate this item." Continue with the rest.gh rate-limit error → surface gh's message verbatim. Do not retry blindly. Stop.code: field and the verdict prose. Do not invent file contents.diff_hunk matches in the current file → same as hunk-only: say the anchor is unresolved; do not pick an occurrence at random.fix in this PR, defer to follow-up) are inapplicable — say so and prefer dismiss-family wording or "not actionable by this operator." already addressed still applies: it is a factual claim about the current head, not a prescription for the author to act.