\!-- SPDX-License-Identifier: Apache-2.0
Reference rendering of the pr-management-stats dashboard (see ../../../skills/pr-management-stats/export.md).
Worked example over apache/airflow, 2026-06-09. Numbers are illustrative; the panel set + layout are the spec. -->
Apache Airflow β PR Backlog Dashboard
π Apache Airflow β PR Backlog Dashboard
Scope: apache/airflow Β· 500 open PRs Β· closed/merged since 2026-04-28 (6 wk) Β· viewer @potiuk Β· refreshed 2026-06-09 (post-cleanup)
β The closed/merged velocity series hit GitHub's 1000-result Search cap β weeks 0β3 are authoritative, 4β5 truncated.
Total open
500
405 non-draft Β· 95 draft
Non-maintainer
373
contributor-authored (127 are maintainers' own)
Ready for review (non-maint.)
211
of 217 ready; 88 are >4 wk old
Drafts (author's court)
95
57 non-maintainer Β· 19% of open
Ready-for-review queue (211) split by review state β same colors as the "why waiting" chart below:
108
Never reviewed (no maintainer look yet)
67
Discussed, no decision
13
Changes requested (author's court)
23
Approved (awaiting merge)
What the numbers above mean (all counts are of currently-open PRs):
β’ Total open β 500: every open PR on apache/airflow (drafts + non-drafts, contributors + maintainers).
β’ Non-maintainer β 373: of those, the ones authored by contributors (not committers). The other 127 are maintainers' own PRs, which triage/review treat separately. This 373 is the work the triage + review pipeline actually serves.
β’ Ready for review (non-maint.) β 211: contributor PRs carrying the ready for maintainer review label β i.e. they cleared triage and are waiting on a maintainer to review. (6 maintainer-authored PRs also carry the label but are excluded β maintainers self-manage.)
β’ Drafts (author's court) β 95: open PRs in GitHub draft state β work-in-progress the author still owns; not awaiting maintainer action.
The 4 coloured cards break the 211 ready PRs down by what each is actually waiting for (same colours + the line chart further below): 108 never reviewed (no maintainer has looked yet β the real backlog), 67 discussed but no decision (a maintainer engaged but neither approved nor requested changes), 13 changes requested (really the author's court β mislabeled ready), 23 approved (review done, just awaiting a merge).
Every open non-maintainer PR sits in exactly one of these five mutually-exclusive states (left β right β closest-to-merge β furthest):
β’ Ready (queue) β 211: carries the ready for maintainer review label β awaiting a maintainer's review. This is the bottleneck (see the split above).
β’ Responded β 15: a maintainer left review feedback and the author has since replied / pushed β back in the maintainer's court for a re-look.
β’ Waiting (author silent) β 34: a maintainer left feedback and the author has not responded for >7 days β the author's court; stale-ping candidates.
β’ Waiting for human maintainer comment β 139: open non-draft PRs with no ready label and no maintainer triage marker β no human maintainer has engaged yet. Not all neglected contributor work: 79 of 139 (57%) are maintainers' own PRs (triage skips collaborator PRs β they self-manage); only 60 are contributor PRs genuinely awaiting a first triage pass, most brand-new (76 <1 wk; 25 >4 wk). Real "needs first triage" β 60, not 139.
β’ Drafts (author's court) β 95: PRs in GitHub draft state β work-in-progress the author owns, not awaiting maintainer action (either opened as draft, or triage converted them for failing CI / conflicts / staleness). They re-enter the funnel only when the author re-marks "Ready for review."
π Why the ready-for-review queue (211) is actually waiting β non-maintainer PRs only (the 6 maintainer-authored ready PRs are excluded β triage skips collaborator PRs); by age
β never reviewed (no formal review, no non-triage maintainer comment) β discussed, no decision β changes requested β approved (awaiting merge)
π The headline finding:108 of 211 non-maintainer ready PRs (51%) have never had a real maintainer look β and the red "never reviewed" line climbs steeply toward the right (newer PRs) β 36 + 34 + 31 of them are <8 wk old, while only 3β4 are >8 wk β i.e. the ready label is being applied faster than anyone reviews, so fresh PRs pile up unreviewed. Breakdown: never-reviewed 108 Β· discussed-no-decision 67 Β· approved-awaiting-merge 23 Β· changes-requested 13 (still mislabeled ready β these sit in other areas beyond the two cleaned this session, so a queue-wide bot would catch them all). The "review-bound" diagnosis is really two problems: a first-review gap (the 108) and a decision/merge gap (the 67 + 23). (The 6 maintainer-authored ready PRs are excluded β they self-manage and triage skips them.)
π€ Workflow automation potential
Categorising every decision-point this session by whether the rule is deterministic (a GitHub Action could reproduce it exactly) or needs judgment (LLM/human):
ready-label bot β auto add/remove ready for maintainer review on every push from: real CI green (not just bot checks) + mergeable + 0 unresolved threads + reviewDecision β CHANGES_REQUESTED
The mark-ready gate is 100% deterministic yet humans get it wrong 25% of the time (the rollup-SUCCESS-but-real-CI-never-ran trap). A bot runs it continuously and never gets fooled β would have prevented all 13 false-positives + kept the 13 changes-requested out of the queue automatically.
2
red-CI drafter β convert to draft + post the quality-violations comment when required checks fail
49 PRs this session; pure check-nameβcategory mapping.
3
conflict / changes-requested sweeper β comment + relabel on dirty or CHANGES_REQUESTED
17 PRs; trivially rule-based, keeps the queue honest about author-vs-maintainer court.
4
stale flagger β label (not close) drafts idle > threshold
Detection is safe to automate; the close stays human (3/5 were wrongly closeable).
Keep human/LLM: code-review correctness, mentor replies, and close-vs-keep decisions β these are where the session's judgment actually changed outcomes (caught a non-fixing "fix", kept 3 PRs that rules would have closed, unblocked a stuck first-timer).
Drafts vs closes per week β contributor PRs only(bot & backport PRs excluded; wk 0β3 reliable)
β draft-conversions (ConvertToDraft events) β closed-unmerged. Bot-authored and backport PRs (base β main) are removed β that stripped 76 of 203 closes (51 bot + 57 backport = release-branch housekeeping, not contributor triage) and 4 of 127 drafted PRs. wk-0 draft bump is partly this session; closes wk 4β5 truncated by the Search cap.
Who does it β triage process vs author, and @potiuk's share (contributor PRs, 6-wk window)
Action
Total
By triage (maintainer acted)
By author (self)
@potiuk
Draft-conversions
173
125 (72%)
48 (28%)
90 β 52% of all Β· 72% of triage
Closes
127
67 (53%)
59 (46%)
7 β 6% of all Β· 10% of triage
72%
of triage drafts by @potiuk (one-maintainer-heavy β prime automation target)
10%
of triage closes by @potiuk (closing is @kaxil-heavy, see below)
Closing stats per person (contributor PRs closed by a maintainer β author; n = 67)
Maintainer
Contributor PRs closed
Share
@kaxil
40
60%
@potiuk
7
10%
@pierrejeambrun
6
9%
@bbovenzi
5
7%
@choo121600
3
4%
@shahar1
2
3%
@Lee-W / @jason810496 / @eladkal / @ashb
1 each
~1%
Both triage actions are single-maintainer-concentrated, but different people: @potiuk does 72% of triage drafting, @kaxil does 60% of contributor-PR closing. Drafting is fully deterministic β automate it (red-CI drafter). Closing needs judgment (3/5 close candidates this session were wrongly closeable) β keep human, but the @kaxil concentration is a bus-factor worth spreading. Definitions: triage = actor β author; author = self-action.
π₯ Pressure by area (refreshed)
#
Area
Score
Open PRs
1
area:task-sdk
173
106
2
area:providers
159
134
3
area:API
112
72
4
(no area)
67
63
5
area:dev-tools
63
47
6
area:UI
59
42
7
area:DAG-processing
56
40
8
area:Scheduler
51
45
π Closure velocity (wk 0β3, from prior snapshot)
Week ago
Merged
Closed
Bar (merged)
0
235
55
1
202
64
2
161
60
3
171
24
Avg 192 merged/wk Β· ~314 opened/wk. Inflow runs ahead of closes β but the exact net is cap-limited (see Trends caveat).
π Trends over time (last 6 weeks)
β Data limit: GitHub's Search API caps results at 1000, so closes older than ~4 weeks are truncated. That makes the absolute backlog and net-flow for weeks 4β5 unreliable (they read artificially low). Weeks 0β3 below are authoritative. True historical trends need an uncapped daily snapshot job β itself a good automation (a tiny scheduled Action writing open_count / ready_count / per-area to a CSV would give exact week-over-week deltas the Search API cannot).
PRs opened per week, by author class (reliable wk 0β3)
β first-time β contributor β maintainer. Roughly ~48% maintainer-authored, ~43% contributor, ~9% first-timer β steady week over week. Contributor + first-timer inflow (~50%) is exactly the volume the triage automation serves.
Merged per week (reliable wk 0β2; wk 3 partial)
Open backlog at week-end (wk 0β3 only β 4β5 cap-distorted, omitted)
Even within the reliable window the backlog is climbing (330 β 500 across the cap-clean weeks). Note this slope is partly inflated by the same truncation (older closes missing); the honest read is "backlog is growing, magnitude needs a snapshot job to pin down." This is the strongest argument for the daily-snapshot Action above.
π Detailed β top areas (Total / Ready / Waiting / Untriaged / Draft)
Area
Total
Ready
Waiting
Untriaged
Draft
area:providers
134
50
11
35
30
area:task-sdk
106
41
9
38
18
area:API
72
27
8
23
14
(no area)
63
40
0
15
8
area:dev-tools
47
11
1
22
13
area:Scheduler
45
20
1
11
11
area:UI
42
11
1
22
8
area:DAG-processing
40
16
3
12
8
Bottom line: the queue is review-bound, not triage-bound (211 contributor PRs ready, 88 >4 wk; inflow ~+72/wk). The cleanup measurably shrank the ready queue by 19. ~80% of the triage workflow is deterministic and CI-automatable β the single highest-leverage move is a ready-label GitHub Action that runs the mark-ready gate continuously (humans mis-call it 25% of the time). Reserve human/LLM effort for code-review correctness, mentoring, and close-vs-keep β the ~8% where judgment changed outcomes this session.
Read-only stats β no mutations. Triage detection via the Pull Request quality criteria marker. Generated by Claude Code (Opus 4.8) for @potiuk.