<\!-- 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)
βœ“ Effect of this session's cleanup: ready queue 236 β†’ 217 (βˆ’19: 5 merged + 13 changes-requested stripped + 1 flipped), stale-ready (>4wk) 105 β†’ 88 (βˆ’17).
⚠ 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).

🚦 Triage funnel (mutually exclusive Β· 494 triage-scope PRs; the 6 maintainer-authored ready PRs are excluded β€” triage skips collaborator PRs)

211
Ready (queue, non-maint.)
15
Responded
34
Waiting (author silent)
139
Waiting for human maintainer comment
95
Drafts (author's court)
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

0 10 20 30 40 >12w 8-12w 4-8w 2-4w 0-2w 211 ready PRs by why they wait (oldest left -> newest right) 3 4 31 34 36 16 10 16 16 9 1 1 5 6 0 3 3 6 7 4
β–  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):

Workflow stepVol.DeterminismCI-automatable?
Mark-ready gate (real-CI-green + mergeable + 0 unresolved + not changes-req)53DeterministicYES β€” caught 13/53 false-positives by rule
CI-failing → draft + violations comment (check→category map)49DeterministicYES
Conflict β†’ rebase comment (mergeable_state=dirty)4DeterministicYES
Changes-requested β†’ strip ready + nudge (reviewDecision)13DeterministicYES
Stale-draft detection (idle thresholds)5DeterministicYES (flag only)
Workflow-approval safety scan (no workflow-file edits, no exfil patterns)9SemiPARTIAL β€” scan auto, approve = judgment
Unresolved-thread engagement split (replied/pushed after marker)10SemiPARTIAL
Stale-draft close decision5JudgmentNO β€” 3/5 kept (dependency / AIP / active first-timer)
Code-review correctness6JudgmentNO β€” caught a real "doesn't fix the bug" defect
Mentor reply1JudgmentNO
~80%
Fully deterministic
(124 of ~155 decision-points)
~12%
Semi-deterministic
(detection auto, action judgment)
~8%
Judgment-required
(review, mentor, close)

Highest-value CI automations (in order)

#GitHub ActionWhy it wins
1ready-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_REQUESTEDThe 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.
2red-CI drafter — convert to draft + post the quality-violations comment when required checks fail49 PRs this session; pure check-name→category mapping.
3conflict / changes-requested sweeper β€” comment + relabel on dirty or CHANGES_REQUESTED17 PRs; trivially rule-based, keeps the queue honest about author-vs-maintainer court.
4stale flagger β€” label (not close) drafts idle > thresholdDetection 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)

0 13 27 41 55 wk-3 wk-2 wk-1 now Drafts vs closes per week (contributor PRs only, wk 0-3 reliable) 22 11 8 45 17 52 36 21
β–  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)

ActionTotalBy triage (maintainer acted)By author (self)@potiuk
Draft-conversions173125  (72%)48  (28%)90 β€” 52% of all Β· 72% of triage
Closes12767  (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)

MaintainerContributor PRs closedShare
@kaxil4060%
@potiuk710%
@pierrejeambrun69%
@bbovenzi57%
@choo12160034%
@shahar123%
@Lee-W / @jason810496 / @eladkal / @ashb1 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)

#AreaScoreOpen PRs
1area:task-sdk173106
2area:providers159134
3area:API11272
4(no area)6763
5area:dev-tools6347
6area:UI5942
7area:DAG-processing5640
8area:Scheduler5145

πŸ“ˆ Closure velocity (wk 0–3, from prior snapshot)

Week agoMergedClosedBar (merged)
023555
120264
216160
317124
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)

0 45 90 135 180 wk-3 wk-2 wk-1 now PRs opened / week by author class 17 42 22 33 170 131 131 142 129 133 152 154
β–  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)

0 62 125 187 250 wk-3 wk-2 wk-1 now Merged / week 171 161 202 235

Open backlog at week-end (wk 0–3 only β€” 4–5 cap-distorted, omitted)

0 137 275 412 550 wk-3 wk-2 wk-1 now Open backlog at week-end 330 420 457 500
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)

AreaTotalReadyWaitingUntriagedDraft
area:providers13450113530
area:task-sdk1064193818
area:API722782314
(no area)63400158
area:dev-tools471112213
area:Scheduler452011111
area:UI42111228
area:DAG-processing40163128
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.