# PR Review Process This document describes how PRs flow through review at LDR. It's the maintainer-facing companion to [CONTRIBUTING.md](../../../CONTRIBUTING.md). > **Folder convention:** this is the first document under `docs/processes/`. Each folder under `docs/processes//` documents one organizational process, with `README.md` as the entry point so visiting the folder URL on GitHub renders it directly. Future processes (release, security review, etc.) should follow the same pattern. ## Overview PRs come from a mix of sources: core maintainers, the extended reviewer team, one-off external contributors, AI bots, and Dependabot. Triage labels are auto-applied at PR open and toggled by review events so reviewers can find the right work to focus on without manually scanning every PR. ## Quick reference | Label | Meaning | Who acts next | |-------|---------|---------------| | `external-contributor` | PR author is outside the maintainer team | First codeowner to triage | | `first-time-contributor` | Author's first PR to this repo | A maintainer should welcome and review | | `bot` | PR opened by an automated account (`*[bot]`, moltenbot, etc.) | A codeowner — apply higher scrutiny | | `needs-codeowner-review` | Awaiting first review from a global codeowner | Global codeowners | | `awaiting-author` | Codeowner requested changes; ball is with author | The PR author | | `awaiting-codeowner` | Author has responded; needs codeowner re-review | Global codeowners | | `needs-rework` | PR shows low engagement — broken tests, mechanical churn, ignored feedback, scope violation | The PR author (substantive rework) | Labels are managed by: - `.github/labels.yml` (declarative definitions) - `.github/workflows/labels-sync.yml` (creates/updates labels) - `.github/workflows/pr-triage.yml` (toggles them per PR) ## Who's a maintainer **Global codeowners** (review required for any path; merge approval): - @LearningCircuit - @hashedviking - @djpetti **Extended reviewer team** (codeowners for tests, CI, docs, and templates): - @scottvr - @tombii - @prashant-sharma-cmd - @elpikola - @shreydekate See [`.github/CODEOWNERS`](../../../.github/CODEOWNERS) for the full path-to-owner mapping. The global-owners list is mirrored in `.github/workflows/pr-triage.yml`; both must stay in sync. ## PR triage queue The canonical search filters maintainers and reviewers should run regularly. Each one returns the PRs that are most useful to act on next. **External PRs awaiting first codeowner look** — the most important queue: ``` is:open is:pr -author:dependabot[bot] -author:LearningCircuit -author:hashedviking -author:djpetti label:needs-codeowner-review ``` **Likely-stale PRs** (author hasn't responded; candidates to nudge or close — replace the date with ~30 days ago): ``` is:open is:pr label:awaiting-author updated:<2026-04-08 ``` **Bot PRs needing higher-scrutiny review** — treat these as proposals, not contributions: ``` is:open is:pr label:bot label:needs-codeowner-review ``` **First-time contributors** — extra welcoming and coaching: ``` is:open is:pr label:first-time-contributor ``` **Author has responded; needs re-review** — triage these regularly to avoid ping-pong delays: ``` is:open is:pr label:awaiting-codeowner ``` ## Lifecycle of a PR ``` PR opened (external) → needs-codeowner-review + external-contributor + first-time-contributor (if first PR) + bot (if automated account) needs-codeowner-review ──[codeowner: changes_requested]──> awaiting-author needs-codeowner-review ──[codeowner: approved]───────────> (no lifecycle label) awaiting-author ──[author pushes commit]──────────> awaiting-codeowner awaiting-author ──[codeowner dismisses review]───> needs-codeowner-review awaiting-codeowner ──[codeowner: approved]───────────> (no lifecycle label) awaiting-codeowner ──[codeowner: changes_requested]─> awaiting-author ``` `commented` reviews are a no-op — they don't move the lifecycle. Use approve / request-changes / dismiss to move state. ## Reviewer responsibilities When you pick up a PR with `needs-codeowner-review`: - Read the PR description for the contributor's verification narrative — what they tested by hand. Missing or generic descriptions are a signal — see "Spotting low-engagement PRs" below. - Submit one of: approve, request changes, or comment-with-questions. Don't leave the PR in limbo. - For external/bot PRs, double-check tests actually pass on the branch (CI green != tests pass meaningfully). When you see `awaiting-codeowner`: - The author has already responded. Don't make them wait — pick it up promptly or hand off. When you see `needs-rework`: - Don't review line-by-line. The PR is in a state that needs the author to take a substantive next step. ## Spotting low-engagement PRs Reviewers should look for these heuristics — they're stronger signals than "was AI used": - **Broken tests on the branch.** The author didn't run them locally before submitting. - **Mechanical churn across many files.** 30+ files of same-shape edits suggests a one-shot generation rather than considered changes. - **Author doesn't respond to specific review questions**, or responds with another regenerated diff rather than addressing the question directly. - **Generic description with no concrete verification narrative** — nothing in the PR body suggests the author exercised the change beyond pushing it. - **Atomic-scope violations.** Multiple unrelated changes bundled. CONTRIBUTING.md is explicit: one logical change per PR. ### Recommended response Apply `needs-rework`, post a comment listing the concrete issues, ask for either a split or a specific revision. **Do not do the fix work for the contributor unless they go silent for an extended period.** Doing the work for them rewards low-engagement submissions. ## Bot PRs specifically Bot-author PRs (`moltenbot000`, similar AI agents) have no human in the loop on the PR side. Iterating with the bot via PR comments rarely produces meaningful revisions — the bot typically regenerates rather than addressing specific feedback. Treat bot PRs as **proposals, not contributions**. If substantive issues exist: - Take the good parts forward as a maintainer-authored PR (cherry-pick + fix). - Close the bot PR with a clear rationale comment. PR #3847 was the working example for this pattern: a moltenbot PR with a sound architectural idea (loguru sink-level redaction) wrapped in mechanical call-site churn and broken tests. The right path was to land the patcher idea cleanly via a maintainer-authored PR and close the bot's submission. ## When to escalate - **Security findings during review** (exposed secrets, auth bypass, injection): apply `security-review-needed` and ping `@LearningCircuit`. See the [security review process](../security-review-process/README.md) for the security-specific flow. - **Legal or licensing concerns**: core team only (`@LearningCircuit @hashedviking @djpetti`). Do not merge. - **Persistent disagreement on approach**: pause, take it to Discord or an issue for broader input rather than escalating in PR comments. ## Out of scope here This document is about the **review** process. Adjacent processes (release, security review, deprecation) are documented separately under `docs/processes//` (when migrated) or in their existing locations.