Skip to main content

pr-review

Review open PRs two ways - default is a per-PR deep review with severity-tagged findings, inline comments, and a verdict; --survey runs a risk-tiered triage digest of what's safe to merge first

Informações da origem

Repositório
aeonfun/aeon
Última atividade na origem
1 de outubro de 2026 às 19:44
Idioma detectado do SKILL.md
inglês
Estrelas
759
Forks
271

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
pr-review
description
Review open PRs two ways - default is a per-PR deep review with severity-tagged findings, inline comments, and a verdict; --survey runs a risk-tiered triage digest of what's safe to merge first
metadata
{"title":"PR Review","category":"basics","var":"","tags":["dev","community"]}
<!-- autoresearch: variation B — sharper output: severity-tagged & capped findings, inline comments on exact lines, one-line verdict; folds in skip rules (A) and SHA dedup + large-diff fallback (C). Absorbs pr-merge as the `--survey` risk-tiered triage-digest branch (no capability lost). --> > **${var}** — Selects the branch and scopes it. > - **Default (no `--survey`)** → per-PR deep review. `${var}` empty reviews every repo in `memory/watched-repos.md`; `${var}=owner/repo` scopes to one repo; `${var}=owner/repo#N` scopes to that exact PR. > - **`--survey`** (alias `survey`) → risk-tiered triage digest (the former `pr-merge`). In this branch the remaining tokens follow pr-merge's grammar: pass `dry-run` to skip notify (article + state still write), pass `owner/repo` to override the target repo, combine with a space (`--survey dry-run owner/repo`). Empty target = `aeonfun/aeon`. > > Examples: `` (review every watched repo) · `owner/repo` (review one repo) · `owner/repo#42` (review exactly PR 42) · `--survey` (triage digest of aeonfun/aeon) · `--survey dry-run` (refresh digest, no notify) · `--survey owner/repo` (triage a specific repo). ## Shared preamble (every run) Read `memory/MEMORY.md` for high-level context. Scan the last ~3 days of `memory/logs/` for recent activity and to avoid re-reporting the same signal. **Parse `${var}` → branch:** split `${var}` on whitespace. - If a `--survey` or `survey` token is present → **SURVEY branch** (jump to "Survey branch"). Remove that token; the remaining tokens are parsed by the survey branch (`dry-run`, `owner/repo` override, unknown → BAD_VAR). - Otherwise → **REVIEW branch** (default; continue below). The remaining `${var}` is an optional `owner/repo` or `owner/repo#N` scope (empty = every watched repo). The two branches never share mutation logic: the REVIEW branch posts PR comments/reviews via `gh`; the SURVEY branch writes the digest article + state file and (gated) notifies — neither performs an actual `gh pr merge`. Dispatch to exactly one branch per run. --- # REVIEW branch (default) — per-PR deep review Read `memory/MEMORY.md` and `memory/watched-repos.md`. Read the last 2 days of `memory/logs/` for context on recent reviews. Whether a commit was already reviewed is decided by GitHub, not the logs (see the skip rules): a run can post its review and then lose its log entry. If `${var}` names `owner/repo#N`, fetch and review only that exact open PR; do not list or comment on any other PR. If `${var}` names `owner/repo`, review that repo's open PRs. Otherwise review every repo listed in `memory/watched-repos.md`. If `memory/watched-repos.md` is empty or missing (and no `owner/repo` was passed), log `PR_REVIEW_NO_REPOS` and end. ## What this branch optimizes for Noise is the documented failure mode of automated PR review. Every finding emitted must be severity-tagged, line-specific, and justified with a one-sentence "why it matters". If there is nothing worth saying, say so in one line and move on. ## For each repo ```bash gh pr list -R owner/repo --state open --limit 20 \ --json number,title,author,isDraft,labels,headRefOid,updatedAt ``` ### Skip rules Skip a PR if any of the following hold (record the skip reason for the run summary): - `isDraft: true` - title matches `^(WIP|\[WIP\]|Draft:)` (case-insensitive) - has label `no-review`, `do-not-merge`, `wip`, or `blocked` - author login contains `[bot]` (dependabot, renovate, etc.) or equals `aeonframework` - this account already posted a receipt-bearing review on this PR at its current `headRefOid`. Ask GitHub: ```bash ./scripts/dev-loop-review.sh reviewed owner/repo#NUMBER <headRefOid> ``` exit `0` → skip as `dup-SHA`; exit `2` (the reviews could not be read) → skip as `review-check-unavailable` and let the next run decide; exit `1` → not yet reviewed at this commit. It counts exactly what the dev-loop gate counts, so a second review can never make the gate see two receipts. It works on either token: with `GH_GLOBAL` it counts that account's reviews, and on the `GITHUB_TOKEN` fallback (which cannot read `/user`) it counts `github-actions[bot]`, the login that token reviews as. - a bot reviewer (`coderabbitai`, `copilot-pull-request-reviewer`, `claude`) posted a review in the last 30 min — skip to avoid piling on. Check via: ```bash gh api repos/owner/repo/pulls/NUMBER/reviews --jq '.[] | {user: .user.login, submitted_at}' ``` ### For each remaining PR 1. **Fetch context**: ```bash gh pr view NUMBER -R owner/repo \ --json title,body,headRefOid,baseRefName,files,additions,deletions ``` If the `body` contains `Fixes #N` or `Closes #N`, fetch the linked issue for context: ```bash gh issue view N -R owner/repo --json title,body,labels ``` 2. **Fetch the diff**: ```bash gh pr diff NUMBER -R owner/repo ``` - If `additions + deletions > 3000`, review only the top-5 largest-delta files from the `files` array (not the full diff). - If `gh pr diff` fails, fall back to per-file patches: ```bash gh api repos/owner/repo/pulls/NUMBER/files --jq '.[] | {path, patch}' ``` - If the diff comes back empty (e.g. mid-rebase), skip the PR with reason `empty-diff`. 3. **Early-exit for trivial PRs**: if the diff is docs-only (`.md`/`.rst`/`docs/**`), lockfile-only, or test-only, skip deep review and post the 1-line ack form in step 6. 4. **Review with severity tagging**. Every finding must carry exactly one tag: - `[CRITICAL]` — correctness break, security hole, data loss, API break, regression - `[ISSUE]` — likely bug, missing edge case, wrong behavior under a realistic input - `[NIT]` — naming, style, minor cleanup (dropped by default) Rules: - Cap at **5 findings total** per PR. Drop NITs first, then the lowest-impact ISSUEs. - Drop all NITs unless there are zero CRITICAL/ISSUE findings *and* a NIT is genuinely useful. - Every finding must name `path/to/file:LINE` and include a one-sentence "why it matters" — the consequence, not just "this is wrong". - No praise, no diff restating, no "this PR adds X" summaries. 5. **Determine a verdict**: - `approve-ready` — no CRITICAL, no ISSUE - `blocked: <one-phrase reason>` — at least one CRITICAL - `discussion-needed` — ISSUE findings but no CRITICAL 6. **Post the review**. Send **both** a consolidated summary comment *and* inline line-specific comments — inline for precision, summary for consumers that parse review bodies. For each line-specific finding: ```bash gh api repos/owner/repo/pulls/NUMBER/comments \ -f body="[SEVERITY] finding text — why it matters" \ -f path="path/to/file" \ -f commit_id="$HEAD_SHA" \ -F line=LINE_NUMBER \ -f side="RIGHT" ``` Then the consolidated summary as a review — include the verdict **and** a bulleted recap of every inline finding (severity + `file:line` + one-sentence rationale), so downstream body-parsers don't miss them: ```bash gh pr review NUMBER -R owner/repo --comment --body "**Verdict**: <verdict> <one-line rationale if blocked or discussion-needed; omit if approve-ready> **Findings** (mirrored as inline comments): - [CRITICAL] path/to/file:LINE — why it matters - [ISSUE] path/to/file:LINE — why it matters <!-- aeon-review:{"schema":1,"target":"owner/repo#N","sha":"<full-headRefOid>","verdict":"blocked|discussion-needed","critical":N,"issues":M} -->" ``` If there are no CRITICAL/ISSUE findings, skip inline comments and post the approve-ready line followed by its receipt: ```text **Verdict**: approve-ready — no blockers. <!-- aeon-review:{"schema":1,"target":"owner/repo#N","sha":"<full-headRefOid>","verdict":"approve-ready","critical":0,"issues":0} --> ``` Use exactly one receipt in every completed review, including trivial-PR early-exits. The target and full `headRefOid` must match the PR fetched in step 1, and the counts must equal the `[CRITICAL]` and `[ISSUE]` bullets in the consolidated body. This is routing input for a later chain step. Do not emit it only when the PR itself was skipped (draft, bot, or duplicate SHA), and keep the human-readable blocked reason outside the receipt. For trivial-PR early-exits (step 3), post the category line — `Docs-only change — no blockers.` / `Dependency-bump — no review needed.` / `Test-only change — no production code touched.` — followed by the same approve-ready receipt from above. A trivial PR is reviewed, not skipped; omitting its receipt makes the dev-loop fail closed because it cannot distinguish an approval from an incomplete review. **Fallback**: if inline-comment creation fails (missing permissions, commit_id mismatch), consolidate all findings into the review body, preserving the severity tags and `file:line` refs. Do not silently drop findings. ## Notify and log (REVIEW branch) The captured final output must include the same `**Verdict**` line and exact `<!-- aeon-review:{...} -->` receipt posted to GitHub for every reviewed PR. Do not replace them with a generic "review posted" summary. The chain consumes the receipt, and the notification gate uses the verdict line as its signal. Send **one** combined message per run via `./notify`: ``` *PR Review — ${today}* Reviewed N, skipped K (drafts: x, bots: y, dup-SHA: z, bot-reviewed-recently: w). - owner/repo#123: [verdict] — N critical, M issues ``` **Telegram summary.** When the run was scoped to a **single repo** (`${var}=owner/repo`), send a Telegram summary of the review with `./notify -f review.md` so the operator sees the verdict at a glance. Skip it on an all-repos run. If every PR was skipped, do not notify — just log. Log to `memory/logs/${today}.md` under the shared `### pr-review` heading with a mode discriminator: ``` ### pr-review - **Mode**: review (per-PR deep review) - owner/repo#123 (SHA abc1234): [verdict] — N critical, M issues - Skipped: owner/repo#124 (draft), owner/repo#125 (bot-reviewed-recently) ``` If no open PRs across all repos, log `PR_REVIEW_OK` and end. --- # SURVEY branch (`--survey`) — risk-tiered triage digest *(This is the former `pr-merge` skill, folded in verbatim. It surveys the queue and buckets by blast radius; it does **not** merge anything — `auto-merge` owns the actual-merge action behind its own author-allowlist + size-cap + branch-protection policy. This branch is the decision-support layer that lives *before* auto-merge, sized for the much larger pool of PRs auto-merge's safety policy intentionally skips.)* Today is ${today}. The open-PR queue on `aeonfun/aeon` has crossed the threshold where a human reviewer working alone falls behind: yesterday (June 1) eighteen PRs were merged in a single 37-minute Monday catch-up window, but on every prior weekend day they stacked up untouched. As community skill packs become the primary contribution model and external contributors keep landing skill PRs every other day, the queue's *steady-state* size will keep climbing — `skill-scan` evaluates one inbound skill PR at a time, but no skill answers the operator's actual morning question: *"of the N open PRs right now, which N1 can I merge in one click and which N2 need real review?"* This branch is that answer. It surveys every open PR on a target repo, categorises each by the files it touches, runs `scripts/skill-scan.sh` against every changed `SKILL.md` (the same scanner `install-skill` runs before installing a skill), and emits one structured Telegram digest with four risk buckets sorted by PR age. The operator can fire-and-forget the FAST_TRACK bucket, glance at SKILL_PASS, and budget real attention for INFRA_REVIEW + SKILL_WARN_OR_BLOCK + CORE_REVIEW. Read `memory/MEMORY.md` for context. Read the last 8 days of `memory/logs/` for prior-run context (skip if dispatched). Read `soul/SOUL.md` + `soul/STYLE.md` if populated to match voice in the notification. ## Why a separate branch from pr-triage / install-skill / auto-merge | Skill | Scope | Action | |-------|-------|--------| | `pr-triage` | Per external PR, first-touch | Welcomes + labels + leaves a verdict comment | | `install-skill` | One skill being installed from another repo | Runs `scripts/skill-scan.sh` first; a HIGH finding blocks the install | | `auto-merge` | All bot-authored PRs that pass a strict safety policy | Merges if CLEAN | | **`pr-review --survey`** | **All open PRs across the watched-repos queue** | **One operator-facing digest sorted by risk + age — no per-PR comment, no merge action** | The four compose. `pr-triage` runs once per PR open; `install-skill` scans each skill before it lands; `auto-merge` runs against the bot subset; this survey branch is the **morning brief** over everything else — the open backlog the operator still has to think about. Building a fifth verdict layer into any of the existing three would either bloat their per-PR cost or skip the operator-overview question entirely. ## Inputs | Source | Purpose | Auth | |--------|---------|------| | `gh api repos/{repo}/pulls?state=open&per_page=100 --paginate` | Open PR list with author, draft state, base ref, age, mergeable state, head SHA, statusCheckRollup summary, labels | `GH_TOKEN` | | `gh api repos/{repo}/pulls/{N}/files?per_page=100 --paginate` | Per-PR list of changed file paths + status (added/modified/removed) — the only signal we trust for bucketing | `GH_TOKEN` | | `gh api repos/{repo}/contents/{path}?ref={head_sha}` | Each changed `SKILL.md` body — fed to `scan.sh` for PASS/WARN/BLOCK verdict | `GH_TOKEN` | | `scripts/skill-scan.sh` (local) | Scanner reused verbatim (no fork, no shadow copy) — same source `install-skill` runs | Local script | | `memory/watched-repos.md` (local) | Read only the `## Trusted Authors` section — those authors' PRs surface in a separate `TRUSTED_AUTHOR` row that bypasses the FAST_TRACK / CORE_REVIEW buckets | Local file | No new secrets. GitHub access via `gh` CLI (`GH_TOKEN`) per CLAUDE.md. Writes: - `output/articles/pr-merge-${today}.md` — full digest with one row per open PR, sortable by bucket + age (every non-error run, including `QUIET`) - `memory/topics/pr-merge-state.json` — prior-run snapshot (per-PR bucket + first_seen date + last_head_sha, used to suppress re-notification on the same head SHA) - `memory/logs/${today}.md` — one log block per run - Notification via `./notify` — only when ≥1 new PR appeared in a non-FAST_TRACK bucket since the last run, or a SKILL_BLOCK / CORE_REVIEW PR is present and operator has not been notified about it on this head SHA yet, or it's the first (baseline) run (see step 8) ## Steps ### 0. Bootstrap ```bash mkdir -p memory/topics output/articles [ -f memory/topics/pr-merge-state.json ] || cat > memory/topics/pr-merge-state.json <<'EOF' {"last_run":null,"last_status":null,"last_repo":null,"prs":{}} EOF ```
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub