plunder
Skill1 starsChanged 51 days agoApache-2.0View on GitHub
Have the AI report this repo's real shipping signal — PRs opened, review findings `roast` caught and whether they were fixed or declined, and time-to-land — grounded in live git/GitHub history, not an invented score. Use when the user says plunder, asks for shipping stats, wants a retrospective on PRs or reviews, or wants to know how the clan's actually been doing.
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. About 0 are common, 9 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 8
Use this skill when the user wants a real, repo-wide look at what shipping has actually looked like — not one branch's status, and not a …
- Distinctive: line 37
Stop. Never touch a PR/issue — this skill only reads.
- Distinctive: line 46
Not a benchmark score. There is no invented "hours saved" or "lines reviewed" number here — every figure is a real count or a real elapsed …
- Distinctive: line 49
Not permission to act on anything it finds — a slow time-to-land or a high decline rate is information, not an instruction to change how …
- Very specific: line 55
Run when the user explicitly asks for a plunder count/tally, shipping stats, a retrospective on PRs or reviews, or how many findings roast …
- Very specific: line 58
Do not run automatically; every other status-reporting skill here (runes, reckoning, watchtower) is invoke-on-purpose, and this one is no …
- Very specific: line 107
Verify this attribution once against a real PR with a known roast review before trusting it at repo scale — this exact lookup hasn't been …
- Distinctive: line 144
Keep it to what was actually counted — don't pad a thin result with filler, and don't round a real count into a marketing-sounding figure.
- Distinctive: line 163
Never touch a PR or issue, resolve a thread, or post a reply as part of this skill — it only reads.
- Distinctive: line 165
Never invent a figure the data doesn't support — no benchmark-style "hours saved" or synthetic score.
- Very specific: line 168
Never attribute a review thread to roast without verifying which review it actually belongs to.
- Distinctive: line 172
Never claim a "fixed" or "declined" count includes unanchored or attribution-unverified findings — neither has a classified thread, and …
- Very specific: line 179
Stop and say so if neither the GitHub MCP connector nor gh is available — don't report a partial or guessed count as complete.
- Very specific: line 181
Stop and say so if any individual required fetch fails partway through — a paginated PR/review-thread listing, a per-PR get_reviews page, …
- Very specific: line 186
Stop after presenting the summary.
- Distinctive: line 197
If blocked, drop the orc voice and state the blocker plainly.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Plunder Workflow
Use this skill when the user wants a real, repo-wide look at what shipping has actually looked like — not one branch's status, and not a synthetic benchmark score, but counts pulled from this repo's own PR and review history.
Contents
- At A Glance
- What This Is Not
- Trigger Rules
- Requirements
- Prerequisites
- Default Path
- Summary Format
- Guardrails
- Stop Conditions
- Handoff
- Response Examples
At A Glance
- Enumerate every pull request in the target repo, across every state.
- Count findings
roastcaught per PR by parsing its own posted scoreboard tables, and classify each finding's fate — fixed, declined and standing, or declined and later settled — from the same review-thread signalreckoningalready reads. - Compute time-to-land (
merged_at - created_at) for every merged PR and report the real median across them. - Report the totals. Never invent a number nothing in the data supports.
- Stop. Never touch a PR/issue — this skill only reads.
What This Is Not
- Not
runes:runesreports one branch's live status; Plunder reports repo-wide historical totals. - Not
reckoning:reckoninglists standing declined-finding debt only; Plunder reports the fuller picture — every finding's fate, PR counts, and time-to-land — and does not stop at what's still owed. - Not a benchmark score. There is no invented "hours saved" or "lines reviewed" number here — every figure is a real count or a real elapsed time pulled from this repo's own history.
- Not permission to act on anything it finds — a slow time-to-land or a high decline rate is information, not an instruction to change how the clan works.
Trigger Rules
- Run when the user explicitly asks for a plunder count/tally, shipping
stats, a retrospective on PRs or reviews, or how many findings
roasthas caught. - Do not run automatically; every other status-reporting skill here
(
runes,reckoning,watchtower) is invoke-on-purpose, and this one is no different.
Requirements
- A GitHub MCP connector configured for this session with at least read
access to pull requests, their review comments, and their reviews, or
ghinstalled and authenticated as a fallback. Without either, stop and say the count can't run rather than reporting a partial or empty result as complete.
Prerequisites
- Confirm which repo to count: the current one by default, or one the user
names — the same default
reckoninguses. - Enumerate every pull request in that repo the same way
reckoningdoes:list_pull_requestswithstate: all, paginating through every page, orgh api --paginate "repos/$owner/$repo/pulls?state=all" --jq '.[] | {number, html_url, state, created_at, merged_at}'when MCP is unavailable.merged_atis what distinguishes "merged" from "closed without merging," since GitHub reports both asstate: "closed". This count is the PR population — every PR in the repo, not only ones a marker identifies asship-opened, since no such marker exists; say this assumption plainly in the report rather than silently narrowing the count. - For each PR, fetch its reviews (
pull_request_readmethodget_reviews), paginating through every page at the requestedperPagesize until a page returns fewer reviews than that size — a PR with more reviews than one page holds still needs everyroastpass counted, not just the first page's. Across every page, find each review whose body ends inroast's delta-tracking marker (<!-- roast:review head=<sha> -->, fromskills/roast/SKILL.md's Comment Format) and parse that review's scoreboard table — the| 🚨 Critical | ⚠️ Important | 💡 Minor | 🤔 Judgment calls |rowroastalways posts — for that pass's finding counts. Sum across everyroastpass on the PR; a PR reviewed twice contributes both passes' counts, not just the latest. - For each PR, fetch its review threads via
pull_request_readmethodget_review_comments, the same callreckoninguses, which returns each thread'sis_resolvedstatus and full comment list. To attribute a thread to a specificroastreview (rather than a human reviewer's own comment), the review-comment shape needs the owning review's id or body, which this MCP method's documented output doesn't confirm it carries; if it doesn't, fall back to agh api graphqlquery for the PR'sreviewThreads(first: 100, after: $cursor)requesting each thread'scomments(first: 1) { nodes { pullRequestReview { body } } }and match threads whose first comment's owning review body carries theroastmarker. Loop pagination the same wayreckoning's own GraphQL fallback does, for both threads and comments, until eachhasNextPageis false. Verify this attribution once against a real PR with a knownroastreview before trusting it at repo scale — this exact lookup hasn't been exercised in this repo before, unlike the rest of this skill's data sources. - Within each
roast-attributed thread, classify its fate the same wayreckoningreads the<!-- orchraft:declined -->markershipwrites (skills/ship/SKILL.mdDefault Path step 12): resolved with no decline reply → fixed; a decline reply present and the thread still unresolved → declined, standing; a decline reply present and the thread later resolved → declined, settled; unresolved with no decline reply → open, unaddressed. A finding with no diff-line anchor (posted inroast's own "Unanchored findings" summary section, not as a thread) has no thread to classify at all — count it in the scoreboard total but report it separately as unclassifiable (unanchored), rather than guessing. A thread that does have a diff-line anchor but whose owning review couldn't be confirmed asroast's (the attribution lookup itself failed or returned ambiguous results) is a different case — report it separately as unclassifiable (attribution-unverified), never folded into the unanchored bucket, since the two have different causes and a future fix targets them differently. - For time-to-land, use only PRs with a non-null
merged_at. Compute each one'smerged_at - created_atand the median across all of them.
Default Path
- Resolve the target repo (see Prerequisites).
- Enumerate every PR and record its state,
created_at, andmerged_at. - For each PR, sum its
roast-posted scoreboard counts across every pass. - For each PR, classify every
roast-attributed thread's fate per Prerequisites, tallying unclassifiable (unanchored) and unclassifiable (attribution-unverified) findings as separate totals. - Compute time-to-land per merged PR and the median across them.
- Report the totals per Summary Format, or that the repo has no PR/review history yet.
Summary Format
Keep it to what was actually counted — don't pad a thin result with filler, and don't round a real count into a marketing-sounding figure.
- Repo — name, and how many PRs were counted (open, merged, and closed-without-merging, mutually exclusive).
- Findings caught — total
roastscoreboard count by severity (Critical/Important/Minor/Judgment calls), across every pass on every PR. - Findings by fate — counts for fixed, declined-and-standing, declined-and-settled, open-and-unaddressed, unclassifiable (unanchored), and unclassifiable (attribution-unverified), reported as separate totals rather than merged into one bucket, since the two have different causes.
- Time-to-land — the median across merged PRs, plus the count it's computed from. Omit if no PR in the repo has merged yet.
- Assumption noted — that the PR count treats every PR in the repo as
the population, since no marker distinguishes a
ship-opened PR from a manually opened one.
Guardrails
- Never touch a PR or issue, resolve a thread, or post a reply as part of this skill — it only reads.
- Never invent a figure the data doesn't support — no benchmark-style "hours saved" or synthetic score. Every number is a real count or a real elapsed time.
- Never attribute a review thread to
roastwithout verifying which review it actually belongs to; when that attribution can't be confirmed, report the thread as unclassifiable (attribution-unverified) rather than guessing its fate. - Never claim a "fixed" or "declined" count includes unanchored or attribution-unverified findings — neither has a classified thread, and both are reported as their own separate totals, never merged with each other or with a classified fate.
Stop Conditions
- Stop and say so if neither the GitHub MCP connector nor
ghis available — don't report a partial or guessed count as complete. - Stop and say so if any individual required fetch fails partway
through — a paginated PR/review-thread listing, a per-PR
get_reviewspage, or a GraphQL attribution query alike. Name which operation failed and report the result as incomplete, never a partial count presented as the full total. - Stop after presenting the summary; do not proceed into
ship,roast,land, or any mutation without the user separately asking for it.
Handoff
- Unless the user asked for plain output, open with a fresh one-line phrase
in the orc voice, speaking as the Quartermaster from
context/personality.md(the target repo's copy when it exists, otherwise${CLAUDE_PLUGIN_ROOT}/context/personality.md). If they did, open with the plain summary instead. - Present the summary per Summary Format.
- If blocked, drop the orc voice and state the blocker plainly.
Response Examples
Opening lines are samples of the orc voice; write a fresh one each time.
Real history to report (illustrative — actual output names real numbers):
💰 Hrrm. The chest is full: N raids counted, most came home clean. ✨
Repo: <owner>/<repo> (N PRs counted: X open, Y merged, Z closed without
merging)
Findings caught: A critical, B important, C minor, D judgment calls
By fate: E fixed, F declined (standing), G declined (settled),
H open/unaddressed, I unclassifiable (unanchored), K unclassifiable
(attribution-unverified)
Time-to-land: median J hours across Y merged PRs
Note: counts every PR in the repo as the population — no marker
distinguishes a ship-opened PR from a manually opened one.No history yet:
💰 Hah! The chest is empty — no pull requests to count yet.
Repo: <owner>/<repo> (0 PRs)Blocked, no GitHub access:
⚠️ Plunder is blocked: neither the GitHub MCP connector nor `gh` is
available. No count was performed.Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

