andreahlert opened a new pull request, #66126:
URL: https://github.com/apache/airflow/pull/66126
## Summary
Collapse `.github/skills/pr-triage/classify.md` (457 lines) +
`.github/skills/pr-triage/suggested-actions.md` (271 lines) into a single
ordered decision table at `classify-and-act.md` (340 lines) with a companion
`rationale.md` (390 lines, not in the hot path). The two-file split required
reading both files in lock-step on every classification; the implicit ordering
between them (C2b "evaluate before C2", the 9-row sub-ladder under
`deterministic_flag`, the Real-CI-guard reclassification path) was load-bearing
but invisible in either file in isolation.
The new table is first-match-wins across 22 rows. Each row yields a
`(classification, action, reason)` tuple in one place. Pre-filters F1-F5b run
before the table. Every compound predicate is named once in a glossary and
referenced from the rows.
Behaviour-preserving for every real PR shape exercised by the empirical
simulator landed in companion PR #66125 — 60 PRs across both ends of the live
`apache/airflow` open queue, zero divergences. Six theoretical edge cases shift
behaviour by design; all documented in the validation log that ships with that
companion PR.
## Why a single table
The previous split had two structural problems:
1. **Ordering was implicit.** `classify.md` C2b carried an "evaluate before
C2" prose note. The 9 sub-rows of `suggested-actions.md`'s `deterministic_flag`
table were evaluated top-to-bottom by reading discipline alone. The 6-commit
refinement series in #65648 that closed the `pending_workflow_approval` /
`mark-ready` race had the same root cause: an ordering invariant that wasn't
expressed structurally.
2. **Cross-file join on every classification.** Every PR went `classify.md
-> classification -> suggested-actions.md -> action`. A reader investigating
"why was this PR drafted?" had to traverse both files. The cross-reference
burden compounded with the per-classification sub-tables.
The new table makes ordering explicit (row numbers) and removes the
cross-file join (one row produces the full tuple). The promotion to "Golden
rule 1b" in #65648 is now a structural invariant of the table — Row 1 is always
evaluated first.
## Files
- DELETED: `.github/skills/pr-triage/classify.md` (457 lines)
- DELETED: `.github/skills/pr-triage/suggested-actions.md` (271 lines)
- NEW: `.github/skills/pr-triage/classify-and-act.md` (340 lines, hot path)
- NEW: `.github/skills/pr-triage/rationale.md` (390 lines, lazy-load)
- MODIFIED: `.github/skills/pr-triage/SKILL.md` (Step 2 + Step 3 collapsed
into Step 2)
- MODIFIED: cross-references in `actions.md`, `comment-templates.md`,
`fetch-and-batch.md`, `interaction-loop.md`, `stale-sweeps.md`
- MODIFIED: sibling skill cross-references in `pr-stats/SKILL.md`,
`pr-stats/classify.md`
- MODIFIED: `contributing-docs/25_maintainer_pr_triage.md`
## Behaviour preservation
Every concrete rule in the old two-file spec maps to a row, glossary entry,
or guard in the new table. Coverage audit + six fixture walk-throughs +
empirical run results live in the companion PR #66125
(`dev/pr-triage-validation.md`), since the validation infrastructure is the
simulator's deliverable.
Empirical confirmation, summarised: the simulator implements both specs as
pure Python functions and diffs `(classification, action)` per PR against the
live `apache/airflow` queue. Two 30-PR samples (oldest-updated and
newest-updated) returned zero divergences each.
## Intentional behaviour changes
Six edge-case PR shapes produce different outputs under the new spec — all
are theoretical (none appeared in the 60-PR empirical sample) and the new
direction is the more actionable one in every case:
- `action_required + viewer_is_author` -> new: Row 1 (`approve-workflow`);
old: refusal-skip
- `action_required + age < 30min` -> similar
- `data_anomaly + copilot_stale` -> new: Row 2 (`draft`); old: refusal-skip
- `copilot_stale + viewer_is_author` -> similar
- `data_anomaly + viewer_is_author` -> similar
- `data_anomaly + age < 30min` -> similar
The three `viewer_is_author` cases are essentially impossible in practice (a
maintainer is not a first-time contributor; pre-filter F1 already blocks
collaborator-authored PRs). The three `data_anomaly` cases route to a more
useful action than the old "silent skip — refresh next page" guidance.
## Refinements bundled in
A handful of small clarifications and bug fixes that came up during the
consolidation review:
- New `follow_up_ping` glossary entry — old C3 had a three-clause "no
follow-up ping" detection that wasn't reproducible from the prose alone; now
defined explicitly so an implementer can reproduce the old behaviour from
`classify-and-act.md` in isolation.
- New `first_time_no_real_ci` glossary entry — old C1 had an
`EXPECTED`-rollup fallback for first-time contributors that the new Row 1 was
originally missing; restored with explicit precondition.
- Row 16 ("no real CI ran -> `rebase`") gained an explicit `author NOT
first-time` guard. The old spec produced the same outcome by relying on
classification ordering (C1 caught first-time contributors before the
suggest-action phase). Making the guard explicit lets the row be read in
isolation and survives future row reordering.
- Row 22 (data anomaly) carries an evaluation-order note in the
cross-cutting hard rules — the row's table position is documentary;
implementations evaluate it immediately before the `passing` rows so a
`SUCCESS`-rollup-with-failed-checks PR cannot be auto-marked-ready.
- Pre-existing reference to `pr-triage/classify.md#c4-already_triaged` in
the `pr-stats` skill updated to point at the `already_triaged` rows in
`classify-and-act.md` (rows 3-4).
## Test plan
- [x] Coverage audit complete — every old rule mapped to a covering new row,
glossary entry, or guard (see #66125's `dev/pr-triage-validation.md` §1).
- [x] Six fixture walk-throughs (workflow approval, static-check failures,
unresolved-thread heuristic positive and negative, bot-only rollup,
viewer-is-author defense-in-depth) — all match between old and new specs.
- [x] Empirical simulator (#66125) — two 30-PR runs against
`apache/airflow`, zero divergences each.
- [x] Five iterations of code-reviewer passes — final iteration LGTM, zero
blocking + zero high findings.
- [x] Cross-reference integrity — every `[text](file.md#anchor)` reference
in the new files resolves to an existing heading.
---
##### Was generative AI tooling used to co-author this PR?
- [ ] Yes
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]