Every PR review is a debate: architecture, tradeoffs, style, quality. Then the PR merges and the debate dies. This distills those comments into rules your AI reviewer enforces on the next PR.
Outputs .cursor/BUGBOT.md and LESSONS.md. Claude Code skill. Runs on GitHub Actions. Works with Cursor Bugbot today.
claude install-skill sscarduzio/pr-war-stories
setEditorStatus is a React useState setter — guaranteed referentially stable. Adding it to deps is a no-op."Cursor Bugbot, CodeRabbit, and Copilot review every PR from scratch. They don't know your team's history or your past incidents.
Review comments explaining why something is wrong are the most valuable institutional knowledge. They live on PRs nobody reads again.
Dumping 50 rules into a config file means every rule competes for attention. The bot starts ignoring everything.
Not all knowledge belongs in the same place. Rules go where they're most effective.
Hierarchical rules the bot checks against every diff. Token-budgeted: fewer rules = more attention per rule.
Universal engineering lessons read by Claude Code and Cursor before developers write code.
Rules that apply to one file, placed in source code. The bot sees them when that file is in a PR.
Not everything belongs in BUGBOT.md. The wrong placement wastes the bot's attention or hides knowledge where nobody sees it.
A GitHub Action fires on merge, extracts review comments, and posts a harvest proposal on the PR. One command to classify. Rules apply on the next review.
Code lands on main
Harvest proposal posted
/pr-war-stories harvest
Enforces on next PR
Actual lessons extracted from merged PRs. Each one prevented the same bug from recurring.
Private Turborepo monorepo. 8 months of PRs, one extremely active hotspot module. This is where the "author-dismissals are the highest-yield source" doctrine was discovered.
useState is 1 frame late — use useRef for synchronous capture in callbacks
Promise.all on unbounded arrays causes OOM — bound concurrency to 3–5
mounted flag or useAsyncCallback
as const enum pattern over raw string unions for stable values
OntologyAPI.subscribe returns an unsub — you MUST call it
Private FastAPI / LangChain / ClickHouse backend. 500 merged PRs mined. Surfaced that GitHub Copilot Code Review's Copilot login has no [bot] suffix — the default filter would have misclassified 308 of its comments as human review input. Filter shipped in v0.7.
is None, not truthiness, when zero is a valid value in Python
imagePullPolicy explicitly — defaults vary by tag strategy
IngressRoute is a CRD, not a vanilla Ingress
timbr.* queries get row-level security free — etimbr does not
Public OSS. Slow-moving, 12-year-old project. JVM stack — completely different from Octostar. Full history mined from PR #6 to PR #1235.
X-Forwarded-For when TCP remote is missing — trivially spoofable.
Either[DomainError, _] for expected failures; throw only for invariants.
NonFatal(e), never catch Throwable — swallows OOM & JVM signals.
GroupId, not Group — names drift, IDs don't.
claude install-skill sscarduzio/pr-war-stories/pr-war-stories setup/pr-war-stories harvest/pr-war-stories auditWorks with Cursor Bugbot. Any GitHub repo. Any language. MIT licensed.