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
git clone --depth 1 https://github.com/aeonfun/aeon /tmp/pr-review && cp -r /tmp/pr-review/skills/pr-review ~/.claude/skills/pr-reviewSKILL.md
<!-- 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 the review to a single repo.
> - **`--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) · `--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` 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/` to pull the `headRefOid` of any PR reviewed recently — used for dedup.
If `${var}` names an `owner/repo`, review only that repo. 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 PR's current `headRefOid` already appears in the last 2 days of `memory/logs/` against the same PR (already reviewed at this commit)
- 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 everySet up and run an Aeon agent instance — get started from scratch, pick which skills to turn on or install more from packs, reschedule or change what runs, edit what an existing skill does, fix a skill that isn't firing, set the STRATEGY.md north star and soul/ voice, turn a coding-agent chat into a scheduled Aeon skill, and mine past coding-agent conversations for recurring work worth automating as a skill. Use when the user mentions Aeon, aeon.yml, an Aeon skill / instance / routine / pack, asks to schedule, enable, edit, or debug an agent that runs on a cron, or asks what of their repeated/manual work Aeon could take over.
Mention/keyword sweep on social platforms for [REPLACE: KEYWORDS] — trends, sentiment, top posts
5 concrete real-life actions, leverage-scored against open loops with specificity and anti-fluff gates
Static config-correctness linter for this instance - catches the silent-failure class (unquoted schedules, duplicate keys, unconfigured skills, mode typos, broken requires/MCP refs) that no run-based health skill can see. Notifies only on problems.
Pull framework updates from the upstream Aeon repo into this instance - 3-way merges canon's new commits into a PR, never clobbering operator config.
Write a publication-ready article in one of three angles - a trending long-form piece, a watched-repo thesis, or a project-through-a-lens essay. Optional Replicate hero image with --visual.
Automatically merge open PRs that have passing CI, no blocking reviews, and no conflicts
Two-mode aeon.yml workflow builder - analyze inspects URLs and emits a tiered, signal-verified skill-enablement plan plus an aeon.yml diff; enable flips slugs to enabled:true and opens a PR.