Update Magpie floor to 0.9.0 and adopt contributor-growth skills (#73755)

* Raise the Magpie floor to 0.9.0.dev202609251939

The committed floor still pointed at a 0.2.0 dev build, so contributors
running an old Magpie install passed the pre-flight check and ran skills
against framework behaviour the project's overrides no longer match.
Raising the floor to the current release makes every skill's pre-flight
prompt them to update.

Generated-by: Claude Opus 5

* Adopt Magpie contributor-growth skills and record reconciliation

Contributor-growth skills (committer readiness, nominations, onboarding)
help the PMC spot and onboard new committers, so every contributor's
agent should have them available rather than only those who install
them by hand.

The reconciliation stamp records which skills' configuration was
checked against 0.9.0, so each skill's pre-flight only proposes a
re-check when that skill's config surface actually changes in a later
Magpie release instead of nagging on every run.

Generated-by: Claude Opus 5

* Share Magpie skill configuration with all contributors

The reconciliation stamp is project-wide, but the config files that made
most of those skills resolve existed only in one maintainer's gitignored
local store, so every other contributor's pre-flight still reported the
same gaps. Committing the project-level configuration makes the stamp
hold for everyone.

The reviewer roster stays per-machine: it reflects who each maintainer
routes reviews to and is refreshed when the reviewer-routing skill runs,
so reviewer-routing is left out of the stamp.

Generated-by: Claude Opus 5

* Set Airflow's contributor-growth thresholds and fill Magpie config

The contributor-growth skills compared candidates against framework
defaults tuned for a small project, so almost every regular Airflow
contributor would have looked "ready". The thresholds now reflect the
level of sustained activity the Airflow PMC has expected, as a floor for
surfacing candidates rather than a decision rule.

Visibly automated contributions — comments restating what is already
there, and work maintainers had to push back on as unreviewed generated
output — are judged against Airflow's own Gen-AI contribution and triage
guidelines, which the configuration now links to.

The remaining release-train, onboarding and roster TODOs are filled from
public sources; the private security tracker and team roster stay out of
the committed file and are configured locally by the security team.

Generated-by: Claude Opus 5

* Reconcile Magpie configuration against 0.9.0.dev202609261254

Several skills changed shape in the newer Magpie build, so the recorded
fingerprints no longer matched and every contributor's pre-flight would
propose the same re-check. Refreshing them records that the project's
configuration still resolves against the current skills.

The committed issue-tracker configuration also brought the issue
reassessment and reproducer skills into scope; they get the reproducer,
runtime and reassessment-pool settings they require, following Airflow's
Breeze-only execution rules and existing issue triage process.

Generated-by: Claude Opus 5

* Raise the Magpie floor to 0.9.0.dev202609261254

The shared contributor-growth configuration relies on the automated
contribution discounting added in apache/magpie#1399, which first ships
in this build. With the older floor, contributors could pass the
pre-flight check on a build that silently ignores those settings.

Generated-by: Claude Opus 5
This commit is contained in:
Jarek Potiuk authored and GitHub committed 2026-09-26 18:23:41 +02:00
1 parent 005fd649bd
commit 909ca179bc
15 files changed
+2266 -1

No files matched your search

@@ -0,0 +1,272 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — committer-onboarding configuration](#apache-airflow--committer-onboarding-configuration)
- [Intake model](#intake-model)
- [Intake-model-specific keys](#intake-model-specific-keys)
- [Governance model](#governance-model)
- [Governance-model-specific keys](#governance-model-specific-keys)
- [Cross-references](#cross-references)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — committer-onboarding configuration
**This file enumerates the capability-flag vocabulary for the
`committer-onboarding` skill.** It is the contributor-growth
counterpart to `release-management-config.md`'s backend-flag model:
an adopter declares the intake and governance model that suits their
community, and the skill emits onboarding steps shaped for that model,
without any skill-body edit.
**Currently the `committer-onboarding` skill defaults to the ASF-PMC
/ ICLA model** (the ASF default). This file establishes the flag
vocabulary so that a non-ASF adopter can declare their model here;
the skill will read these flags in a follow-on update. New adopters
should copy this file into their own
`<project-config>/committer-onboarding-config.md` and replace every
`TODO`.
Related scaffolds in the same adopter directory:
- `committer-readiness.md` — activity thresholds the
`contributor-to-committer` readiness tracker compares against
(added by the `contributor-to-committer` skill).
- [`contributor-nomination-config.md`](contributor-nomination-config.md)
— nomination-brief thresholds and assessment window.
- [`pmc-roster.md`](pmc-roster.md) — PMC-member roster used by
`release-vote-tally` to classify binding vs non-binding votes.
---
## Intake model
Declares how new committers are formally onboarded to the project's
IP policy after a vote passes.
```yaml
committer_intake:
# Model under which new committers are formally onboarded to the
# project's IP policy.
# ASF default: icla — every new committer must file a signed ICLA
# with the Apache Software Foundation before commit bits are
# granted. The skill checks Whimsy and blocks the account-request
# step if no ICLA is on file.
# Override when:
# dco — Developer Certificate of Origin (Linux Foundation model).
# A per-commit `Signed-off-by:` line replaces the one-time CLA;
# the skill links the DCO guide and verifies that the candidate's
# recent merged PRs carry sign-off.
# no-cla — No formal contributor agreement required (open/trust-
# based model). The skill skips IP-check steps entirely.
# Allowed values: icla, dco, no-cla
# Consumed by: committer-onboarding (intake-check step).
model: icla # icla | dco | no-cla (ASF project; COMMITTERS.rst requires a CLA on file)
```
### Intake-model-specific keys
Fill in only the block that matches your `model` above; leave the
others absent or blank.
#### `icla` model
```yaml
committer_intake_icla:
# URL the skill links when asking the nominator to check the
# candidate's ICLA status.
# ASF default: Whimsy's committer lookup.
# Non-ASF adopters using ICLA: point at your foundation's CLA
# query endpoint.
# Consumed by: committer-onboarding.
lookup_url: https://whimsy.apache.org/roster/committer/
# Whether ICLA filing is a hard prerequisite that the skill refuses
# to bypass. When true, the skill blocks until the nominator
# confirms the ICLA is on file; when false, the skill flags the
# gap but allows the nominator to proceed with a warning.
# ASF default: true.
# Consumed by: committer-onboarding.
mandatory: true
```
#### `dco` model
```yaml
committer_intake_dco:
# Reference URL the skill links in onboarding communications
# explaining what DCO sign-off means for contributors.
# Linux Foundation / CNCF projects typically link
# https://developercertificate.org/ plus their own CONTRIBUTING.md.
# Consumed by: committer-onboarding.
reference_url: null # n/a — Airflow uses the icla model, not DCO
# Minimum number of the candidate's recently merged PRs that must
# carry a valid `Signed-off-by:` line before the skill considers
# the DCO check passed.
# Set to 0 to skip the check (honour-system model).
# Consumed by: committer-onboarding.
min_signed_off_prs: 1
```
#### `no-cla` model
```yaml
committer_intake_nocla:
# Free-text explanation shown in the onboarding checklist in place
# of an IP-agreement check. Leave null for a default message.
# Consumed by: committer-onboarding.
explanation: null
# e.g. "This project uses an Apache-2.0 inbound/outbound model; no
# CLA or DCO sign-off is required — contributors retain copyright."
```
---
## Governance model
Declares how committer and PMC (or equivalent) status is formally
tracked, voted on, and applied after a vote passes.
```yaml
committer_governance:
# Model under which committer and committee status is granted and
# tracked.
# ASF default: asf-pmc — the PMC votes on the dev@ list, submits a
# secretary account-creation request via Whimsy, and the new
# committer appears on the Apache Whimsy committee/committer roster.
# Override when:
# github-codeowners — CODEOWNERS file + GitHub maintainer-team
# membership drives merge permissions; no formal committee vote
# and no external account-creation request.
# maintainer-roster — an adopter-managed roster file voted on by
# existing maintainers, outside any foundation's governance
# machinery.
# Allowed values: asf-pmc, github-codeowners, maintainer-roster
# Consumed by: committer-onboarding (roster-management steps).
model: asf-pmc # asf-pmc | github-codeowners | maintainer-roster
```
### Governance-model-specific keys
Fill in only the block that matches your `model` above.
#### `asf-pmc` model
```yaml
committer_governance_asf_pmc:
# Whether the project is an incubating podling or a graduated
# top-level project. This switches between Whimsy's PPMC
# self-service UI (podling) and `committee-info.txt` edits (TLP).
# Allowed values: podling, tlp
# Consumed by: committer-onboarding (roster-management path
# selection).
stage: tlp # podling | tlp (top-level project since January 2019, airflow-core/docs/project.rst)
# Whimsy URL the skill links the nominator to for roster management.
# TLP default: committee detail page.
# Podling default: PPMC roster page.
# Consumed by: committer-onboarding.
whimsy_roster_url: https://whimsy.apache.org/roster/committee/airflow
# TLP example: https://whimsy.apache.org/roster/committee/<project>
# Podling example: https://whimsy.apache.org/roster/ppmc/<project>
# URL of the ASF's new-committer / new-PMC-member secretary request
# form. The skill prints this and asks the nominator to fill it in.
# ASF default: the standard secretary request page.
# Consumed by: committer-onboarding.
secretary_request_url: https://whimsy.apache.org/officers/acreq
# Dev-list address the skill uses when drafting the welcome
# announcement. Matches `dev_list` in project.md — kept here for
# self-contained configuration.
# Consumed by: committer-onboarding.
dev_list: dev@airflow.apache.org
```
#### `github-codeowners` model
```yaml
committer_governance_github_codeowners:
# GitHub team slug (in `org/team` form) that maps to the
# committer/maintainer team. The skill invites the new committer
# to this team after the vote passes.
# Consumed by: committer-onboarding.
maintainers_team: apache/airflow-committers
# Path to the CODEOWNERS file in the upstream repo, relative to
# the repo root. The skill optionally opens a PR adding the new
# committer's handle to the file.
# Leave null to skip the CODEOWNERS update.
# Consumed by: committer-onboarding.
codeowners_file: CODEOWNERS # or null
# Whether a GitHub-discussion or a GitHub-issue thread is the
# canonical "vote thread" for this model.
# Allowed values: github-discussion, github-issue, off-band
# `off-band` = the vote happened in Slack / email / another channel
# and the skill just records the outcome.
# Consumed by: committer-onboarding (vote-validation step).
vote_channel: off-band # votes are held on the private PMC mailing list
```
#### `maintainer-roster` model
```yaml
committer_governance_maintainer_roster:
# Path to the roster file (relative to <project-config>/) that
# the skill updates when a vote passes.
# Consumed by: committer-onboarding.
roster_file: null # n/a — Airflow uses the asf-pmc model (roster in Whimsy)
# Minimum number of approvals required from existing listed
# maintainers before the skill considers the vote passed.
# Consumed by: committer-onboarding (vote-validation step).
min_approvals: 3 # ASF rule: at least 3 binding +1 votes and no veto
# Channel where votes are held — used by the skill when
# summarising the vote result.
# Allowed values: github-discussion, github-issue, mailing-list,
# slack-channel, off-band
# Consumed by: committer-onboarding.
vote_channel: mailing-list
```
---
## Cross-references
- `committer-readiness.md` — activity thresholds for the
`contributor-to-committer` readiness tracker (added by the
`contributor-to-committer` skill).
- [`contributor-nomination-config.md`](contributor-nomination-config.md)
— nomination-brief thresholds and assessment window.
- [`pmc-roster.md`](pmc-roster.md) — PMC-member roster for vote tally.
- [`committer-onboarding`](../../.agents/skills/magpie-committer-onboarding/SKILL.md)
— the skill that reads this configuration.
@@ -0,0 +1,169 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — committer-readiness configuration](#apache-airflow--committer-readiness-configuration)
- [Assessment window](#assessment-window)
- [Committer thresholds](#committer-thresholds)
- [PMC thresholds](#pmc-thresholds)
- [Project-specific notes *(optional)*](#project-specific-notes-optional)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — committer-readiness configuration
Per-project thresholds for the
[`contributor-to-committer`](../../skills/contributor-to-committer/SKILL.md)
readiness tracker. Copy into your `<project-config>/` directory and
replace every TODO.
**Thresholds are optional.** If this file does not declare thresholds,
the skill falls back to `contributor-nomination-config.md` thresholds,
or asks the maintainer at run time. Only declare thresholds here if
your PMC has agreed on explicit criteria — they vary across projects
and there are no meaningful universal defaults.
**This file is separate from `contributor-nomination-config.md`** so
that the readiness tracker and the nomination brief can be tuned
independently. If your project uses the same bar for both, you can
set this file's thresholds to the same values and keep a single place
to update them.
---
## Assessment window
| Key | Value | Notes |
|---|---|---|
| `assessment_window_months` | `6` | How many months of activity to assess. 6 is common; slower-moving projects may prefer 12. |
---
## Committer thresholds
Calibrate against recent successful nominations on your project, not
against framework defaults. The numbers below are a low bar for a
mid-size active project.
| Dimension | Default (low bar) | Project value | Notes |
|---|---|---|---|
| `prs_merged` | `5` | `40` | Merged PRs — the clearest signal of sustained code contribution |
| `reviews_total` | `3` | `20` | Total review acts — shows engagement with others' work |
| `reviews_substantive` | `2` | `3` | Reviews with real inline feedback (≥ 3 comments or > 50 char body) |
| `issues_filed` | `0` | `2` | Set to 0 to treat as non-required; many valid tracks don't involve filing issues |
| `threads_commented` | `5` | `35` | PR/issue comment threads — basic community presence |
| `area_breadth` | `0` | `5` | Distinct `area:*` labels across merged PRs; 0 = no breadth requirement |
---
## PMC thresholds
PMC membership requires demonstrated community leadership beyond code.
Raise these well above the committer bar for any project that treats
PMC as a senior track.
| Dimension | Default (low bar) | Project value | Notes |
|---|---|---|---|
| `prs_merged` | `10` | `40` | |
| `reviews_total` | `8` | `100` | PMC members are expected to help evaluate others' work |
| `reviews_substantive` | `4` | `8` | |
| `issues_filed` | `0` | `2` | |
| `threads_commented` | `10` | `150` | |
| `area_breadth` | `2` | `8` | PMC members typically span multiple project areas |
---
## Automated and low-signal contributions
How the readiness tracker discounts visibly automated or low-signal GitHub activity.
The full definition — detection heuristics, aggregation, and how the brief reports raw and adjusted counts — is [`automated-contributions.md`](https://github.com/apache/magpie/blob/main/skills/contributor-nomination/automated-contributions.md).
The discount is a signal for the humans reading the brief, never an automatic disqualification.
Using AI tools, and disclosing that use, is not penalised; only restatement, content maintainers pushed back on, and work closed after that pushback are discounted.
Each key is resolved from this file first, then from `contributor-nomination-config.md`, then from the default below.
| Key | Default | Project value | Notes |
|---|---|---|---|
| `automated_contribution_weight` | `0.25` | | Weight (0–1) of a merged or open PR, issue, review or comment that drew maintainer pushback as looking generated, unreviewed, restating, fabricated, or unwanted |
| `restatement_comment_weight` | `0` | | Weight (0–1) of a comment or review body that only restates the description, earlier comments, or the diff |
| `closed_after_pushback_weight` | `0` | | Weight (0–1) of a PR or issue closed unmerged after that pushback; `0` removes it from every metric |
| `automated_pushback_phrases` | empty | | Extra phrases your maintainers use when pushing back, added to the generic list |
Set all three weights to `1` to turn the arithmetic off; flagged items are still listed in the brief.
### Project expectations for AI-assisted contributions
List the documents in which your project states what it expects from AI-assisted and automated contributions — a generative-AI contribution policy, PR guidelines, a review or triage guide.
Use paths relative to the repository root, or `https://` URLs, optionally with a `#section` anchor.
```yaml
automated_contribution_expectations:
- contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
- contributing-docs/25_maintainer_pr_triage.md#why-the-first-pass-is-automated
- contributing-docs/25_maintainer_pr_triage.md#for-contributors
```
When the list is present, the skill reads each document, judges contributions against it first, and cites the document and section each flagged item conflicts with.
When it is empty or none of the documents can be read, the skill falls back to the framework's generic heuristics and says so in the brief.
The skill does not go looking for policy documents this list does not name.
---
## Project-specific notes *(optional)*
Free text surfaced at the top of every readiness brief. Use for norms
the maintainer should see — e.g. multi-repo projects, non-GitHub
contribution tracks that are particularly valued, or cultural notes
about how the PMC calibrates nominations.
```text
Source: COMMITTERS.rst ("Guidelines to become an Airflow Committer" and
"Guidelines for promoting Committers to Airflow PMC"). There is no strict
numeric protocol; the PMC weighs combined contributions across areas.
- The numeric thresholds are a floor for surfacing candidates, never a
decision rule: activity volume alone does not make a candidate. Breadth
across areas, dev list participation, release testing and sustained
activity weigh as much as the counts.
- Committer prerequisites: consistent contribution over at least three
months; visibility on the dev list, Slack or GitHub issues/discussions
(including non-binding votes and testing release candidates); helping
other contributors (reviews, constructive feedback); contributions to
community health.
- Non-code paths count: it is possible to become a committer (and PMC
member) without changing code, but only with visible presence in the
community channels. Such exceptions are rare.
- Areas the PMC looks at: Airflow Core, Task SDK, airflowctl, API, Docker
image, Helm chart, dev tools (Breeze / CI), providers, security team work,
issue triage, documentation.
- PMC: committer for at least 3 months; currently active; consistent
voting on release candidates for at least the past 3 release cycles;
AIP engagement; reviews and merges; community involvement.
- Airflow spans one main repository (apache/airflow) plus apache/airflow-site
and apache/airflow-client-* repos; check activity across them.
```
@@ -0,0 +1,186 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — contributor-nomination configuration](#apache-airflow--contributor-nomination-configuration)
- [Assessment window](#assessment-window)
- [Thresholds *(optional — leave blank if not configured)*](#thresholds-optional--leave-blank-if-not-configured)
- [Committer thresholds](#committer-thresholds)
- [PMC thresholds](#pmc-thresholds)
- [Required areas by target *(optional)*](#required-areas-by-target-optional)
- [Project-specific notes *(optional)*](#project-specific-notes-optional)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — contributor-nomination configuration
Per-project configuration for the
[`contributor-nomination`](../../skills/contributor-nomination/SKILL.md)
skill. Copy into your `<project-config>/` directory and replace
every TODO.
**Thresholds are optional.** If this file does not declare
thresholds, the skill asks the maintainer for the project's
typical bar at run time and reports raw numbers for the PMC to
judge. Only declare thresholds here if your PMC has agreed on
explicit criteria — thresholds vary enormously across projects
and there are no meaningful framework defaults.
---
## Assessment window
| Key | Value | Notes |
|---|---|---|
| `nomination_window_months` | `6` | How many months of activity to assess. 6 is a common starting point; slower-moving projects may prefer 12. |
---
## Thresholds *(optional — leave blank if not configured)*
Declare only if your PMC has agreed on explicit criteria for
what counts as sufficient activity on this project. These
replace the run-time question to the maintainer about the
project bar. Calibrate against your project's own contribution
history — recent successful nominations are the best reference.
### Committer thresholds
The values below are a reasonable low bar for a mid-size active
project, not a universal standard. Calibrate in either direction:
- **Raise them** if your project is large or high-velocity and
recent successful nominations reflect significantly more activity.
- **Lower them** if your project is small, early-stage, or
deliberately gives committership freely as a welcoming gesture.
That is a valid project culture — these defaults should not
imply otherwise.
| Area | Default (low bar) | Project value | Notes |
|---|---|---|---|
| PRs merged | 5 | `40` | Reasonable floor for a mid-size project; set lower if your project is small or welcomes contributors freely |
| Reviews given | 3 | `20` | Shows engagement with others' work |
| Substantive reviews | 2 | `3` | Reviews with real inline feedback |
| Issues filed | 0 | `2` | Not required — many valid tracks don't involve filing issues |
| Comments | 5 | `35` | Basic community presence |
| Mailing list presence | none | Visible on dev list, Slack or GitHub issues/discussions, incl. non-binding votes and RC testing (COMMITTERS.rst) | Qualitative — fill in if your project tracks this |
### PMC thresholds
| Area | Default (low bar) | Project value | Notes |
|---|---|---|---|
| PRs merged | 10 | `40` | |
| Reviews given | 8 | `100` | PMC members are expected to help evaluate others' work |
| Substantive reviews | 4 | `8` | |
| Community leadership signal | "present" | present — mentoring, answering users, spreading the word, RC voting over 3+ release cycles (COMMITTERS.rst) | Qualitative — some evidence of guiding others or shaping direction |
---
## Automated and low-signal contributions
How the nomination brief discounts visibly automated or low-signal GitHub activity.
The full definition — detection heuristics, aggregation, and how the brief reports raw and adjusted counts — is [`automated-contributions.md`](https://github.com/apache/magpie/blob/main/skills/contributor-nomination/automated-contributions.md).
The discount is a signal for the humans reading the brief, never an automatic disqualification.
Using AI tools, and disclosing that use, is not penalised; only restatement, content maintainers pushed back on, and work closed after that pushback are discounted.
Each key is resolved from this file, then from the default below.
The readiness tracker falls back to these values when `committer-readiness.md` does not set its own.
| Key | Default | Project value | Notes |
|---|---|---|---|
| `automated_contribution_weight` | `0.25` | | Weight (0–1) of a merged or open PR, issue, review or comment that drew maintainer pushback as looking generated, unreviewed, restating, fabricated, or unwanted |
| `restatement_comment_weight` | `0` | | Weight (0–1) of a comment or review body that only restates the description, earlier comments, or the diff |
| `closed_after_pushback_weight` | `0` | | Weight (0–1) of a PR or issue closed unmerged after that pushback; `0` removes it from every metric |
| `automated_pushback_phrases` | empty | | Extra phrases your maintainers use when pushing back, added to the generic list |
Set all three weights to `1` to turn the arithmetic off; flagged items are still listed in the brief.
### Project expectations for AI-assisted contributions
List the documents in which your project states what it expects from AI-assisted and automated contributions — a generative-AI contribution policy, PR guidelines, a review or triage guide.
Use paths relative to the repository root, or `https://` URLs, optionally with a `#section` anchor.
```yaml
automated_contribution_expectations:
- contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions
- contributing-docs/25_maintainer_pr_triage.md#why-the-first-pass-is-automated
- contributing-docs/25_maintainer_pr_triage.md#for-contributors
```
When the list is present, the skill reads each document, judges contributions against it first, and cites the document and section each flagged item conflicts with.
When it is empty or none of the documents can be read, the skill falls back to the framework's generic heuristics and says so in the brief.
The skill does not go looking for policy documents this list does not name.
---
## Required areas by target *(optional)*
Only declare if your project's PMC has a formal policy.
Leaving this blank means the skill treats all contribution
tracks (code, docs, testing, community) as equally valid paths.
| Target | Required areas | Notes |
|---|---|---|
| `committer` | none | e.g. `none` — many projects accept doc/community committers |
| `pmc` | community or code | e.g. `review or community` |
---
## Project-specific notes *(optional)*
Free text surfaced at the top of every brief. Use for project
norms the nominator should know — e.g. "This project has
multiple active repositories; ask the maintainer to check
contributor activity across all of them, not just `<upstream>`."
```text
Source: COMMITTERS.rst ("Guidelines to become an Airflow Committer" and
"Guidelines for promoting Committers to Airflow PMC"). There is no strict
numeric protocol; the PMC weighs combined contributions across areas.
- The numeric thresholds are a floor for surfacing candidates, never a
decision rule: activity volume alone does not make a candidate. Breadth
across areas, dev list participation, release testing and sustained
activity weigh as much as the counts.
- Committer prerequisites: consistent contribution over at least three
months; visibility on the dev list, Slack or GitHub issues/discussions
(including non-binding votes and testing release candidates); helping
other contributors (reviews, constructive feedback); contributions to
community health.
- Non-code paths count: it is possible to become a committer (and PMC
member) without changing code, but only with visible presence in the
community channels. Such exceptions are rare.
- Areas the PMC looks at: Airflow Core, Task SDK, airflowctl, API, Docker
image, Helm chart, dev tools (Breeze / CI), providers, security team work,
issue triage, documentation.
- PMC: committer for at least 3 months; currently active; consistent
voting on release candidates for at least the past 3 release cycles;
AIP engagement; reviews and merges; community involvement.
- Airflow spans one main repository (apache/airflow) plus apache/airflow-site
and apache/airflow-client-* repos; check activity across them.
```
@@ -0,0 +1,66 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Contributor-sentiment thresholds](#contributor-sentiment-thresholds)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Contributor-sentiment thresholds
Signal thresholds for `contributor-sentiment`, which measures whether the
project got healthier to contribute to. Copy this file into your
`<project-config>/` directory and change only the values you disagree with —
**every key below is optional, and the default applies when it is absent or
when the whole file is.**
The skill compares a measurement window against a pre-adoption baseline and
reports each signal as pass or fail. These caps decide where "fail" starts, so
they are a statement about what the project considers a regression, not a
tuning knob for making the report look better.
---
```yaml
contributor_sentiment:
# Maximum allowed rise, in percentage points, in the fraction of first
# responses classified as dismissive.
tone_regression_cap_pp: 5
# Maximum allowed rise, as a percentage, in median time to first reply.
reply_increase_cap_pct: 50
# Maximum allowed drop, in percentage points, in the share of first-time
# contributors who opened a second PR.
retention_decline_cap_pp: 10
# Maximum allowed rise in the Gini coefficient of review load. Rising means
# review work concentrating on fewer people.
gini_increase_cap: 0.10
# Default measurement window, in months, when the invocation names none.
window_months: 6
```
@@ -0,0 +1,93 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — good-first-issue authoring configuration](#apache-airflow--good-first-issue-authoring-configuration)
- [Identifiers](#identifiers)
- [Getting-started link](#getting-started-link)
- [Out-of-scope topics](#out-of-scope-topics)
- [AI-attribution footer](#ai-attribution-footer)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — good-first-issue authoring configuration
This file configures the
[`good-first-issue-author`](../../skills/good-first-issue-author/SKILL.md)
skill (Agentic Mentoring, `experimental`). Copy it into your own
`<project-config>/good-first-issue-config.md` and replace every
`<placeholder>` with your project's value. If a required key is missing,
the skill aborts and points back here rather than guessing.
## Identifiers
| Key | Value | Notes |
|---|---|---|
| `good_first_issue_label` | `good first issue` | The label proposed on the drafted issue. The skill proposes it; a maintainer applies it on confirmation. |
| `max_effort_hours` | `4` | Upper bound on the estimated effort a good first issue may carry. A candidate that clearly exceeds it is `scope-too-large`. |
## Getting-started link
A single link the drafted issue points a newcomer at. The skill links it
rather than paraphrasing. The link must resolve from a GitHub issue body
(not a repo-rendered file), so use an absolute URL: relative paths like
`CONTRIBUTING.md` 404 when rendered inside an issue. The link must
resolve before the skill drafts an issue; do not leave a placeholder URL
in this row.
| Trigger | Link | One-line label |
|---|---|---|
| Newcomer onboarding | `https://github.com/apache/airflow/blob/main/contributing-docs/03a_contributors_quick_start_beginners.rst` | Your first Airflow pull request (15-minute guide) |
Pick the section of the contributing guide that is genuinely
newcomer-shaped (a "Your first contribution" / "Getting started" section,
not the top of the file, which usually lands on a doctoc TOC).
## Out-of-scope topics
The skill always declines (decision `unsuitable`) when a candidate touches
one of these. Adjust for your project; the defaults below are typical of
an Apache project.
- Security-sensitive work (vulnerabilities, CVE-adjacent, embargoed)
- Deprecation or removal timing (which release drops X)
- Licensing questions (compatibility, header policy)
- Architectural taste on a project-specific subsystem
## AI-attribution footer
Appended verbatim to every drafted issue body, disclosing AI authorship.
```markdown
---
_This issue was drafted with the help of an AI-assisted tool and reviewed by an Apache Airflow maintainer before posting. If anything here is unclear or looks wrong, say so on the issue: a real person is reading._
```
Replace `<PROJECT>` with the project's display name (read from
[`<project-config>/project.md`](project.md)).
@@ -0,0 +1,166 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — issue-tracker configuration](#apache-airflow--issue-tracker-configuration)
- [URL and project key](#url-and-project-key)
- [Authentication](#authentication)
- [Default query templates](#default-query-templates)
- [Tracker-specific notes](#tracker-specific-notes)
- [Cross-references](#cross-references)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — issue-tracker configuration
The project's **general-issue tracker** configuration — where issues
live, how to authenticate, and how to query. Consumed by the
`issue-*` skill family (`issue-triage`, `issue-reassess`,
`issue-reproducer`, `issue-fix-workflow`).
This file is distinct from the `tracker_repo` field in
[`project.md`](project.md), which declares the **security** tracker
used by the `security-issue-*` skill family. Many projects use
different trackers for the two: e.g., a private GitHub repo for
security and a public JIRA project for general issues. Adopters
that use the same tracker for both can point both at the same
location.
## URL and project key
| Key | Value |
|---|---|
| `url` | `https://github.com/apache/airflow` |
| `project_key` | `apache/airflow` |
| `tracker_type` | `github-issues` |
| `issue_url_template` | `https://github.com/apache/airflow/issues/<N>` |
Skills resolve `<issue-tracker>` to `url` and `<issue-tracker-project>`
to `project_key`.
## Authentication
Public GitHub repository: reads work anonymously; writes use the maintainer's
`gh` CLI login.
- **Anonymous read** — true if the tracker permits unauthenticated
browsing (many JIRA instances do). Set `anonymous_read: true` if
so; skills can do the classification phase without credentials.
- **Authenticated write** — credentials needed to post comments,
link issues, or apply any mutation. Document where credentials
come from:
- JIRA: API token in `~/.config/<tracker>-token` or an env var
- GitHub Issues: `gh` CLI auth status
- Other: project-specific
| Key | Value |
|---|---|
| `anonymous_read` | `true` |
| `auth_method` | `gh-cli` |
| `auth_env_var` | *(none — `gh` reads its token from the OS keyring; `GH_TOKEN` only if set explicitly)* |
## Default query templates
The project's canonical queries for the triage / reassess
pools, derived from `ISSUE_TRIAGE_PROCESS.rst` and `.github/workflows/stale.yml`. Skills use these as defaults; users can override per-invocation.
For JIRA-based projects, queries are JQL (not used — Airflow is on GitHub Issues):
```text
# n/a: triage pool — newly-filed, unsorted issues
project = <project_key> AND resolution = Unresolved AND status = Open
# n/a: reassess pool — silent wishlists and EOL issues
project = <project_key> AND resolution = Unresolved AND
fixVersion in unreleasedVersions() AND status = Open
# n/a: reopened pool — issues that were closed and reopened
project = <project_key> AND status changed FROM "Closed" TO "Open"
```
For GitHub-Issues-based projects, queries are `gh search issues`
syntax:
```text
# triage pool — issue templates auto-apply `needs-triage`; the triager removes
# it once the issue is accepted and has kind:* / area:* labels
is:open is:issue label:needs-triage repo:apache/airflow
# reassess pool — accepted bug reports gone quiet (ISSUE_TRIAGE_PROCESS.rst
# "Stale Policy": ask the author to recheck on the latest version)
is:open is:issue label:kind:bug -label:needs-triage sort:updated-asc repo:apache/airflow
# awaiting-author pool — stale bot marks these stale after 14 days, closes 7 days later
is:open is:issue label:pending-response repo:apache/airflow
```
Adopters who use other trackers (Bugzilla, GitLab, custom) substitute
the appropriate query language.
## Tracker-specific notes
Airflow-specific quirks:
- **Label taxonomy** (`ISSUE_TRIAGE_PROCESS.rst`) — `kind:*` (bug, feature,
documentation, task, meta), `area:*` (`area:core`, `area:providers`,
`area:helm-chart`, finer `area:scheduler`, `area:UI`, …), `provider:<name>`
for provider issues, `affected_version:<X.Y>` on core bugs only (latest
reproducing version), `good first issue`, `pending-response`,
`needs-triage`. Invalid issues get `duplicate`, `Can't Reproduce`,
`invalid` or `won't fix` (the doc says `wontfix`; the GitHub label is `won't fix`).
- **Discussions** — vague ideas go to GitHub Discussions (Ideas); support
requests to Discussions (Q&A), with a comment explaining why.
- **Assignee timeliness** — no activity for 2 weeks → remind the assignee;
1 more week → unassign.
- **Security** — never triage vulnerability reports on public issues; they go
to `security@airflow.apache.org` per the security policy.
Generic notes:
- **Rate limits** — most public trackers throttle. JIRA Cloud's free
tier is 1500 requests / 5 minutes; GitHub's API is 5000 / hour
authenticated.
- **Anon vs auth differences** — if anonymous queries return fewer
fields than authenticated ones (e.g., JIRA's `worklog`), skills
must know to escalate.
- **Custom fields** — JIRA projects often define custom fields
(`customfield_NNNNN`). Document any the skills need to read.
- **Project board / kanban integration** — if the tracker has a
separate "board" view with workflow states, document where it is
and whether the skills should reconcile against it.
## Cross-references
- [`project.md`](project.md) — the manifest; declares
`upstream_default_branch` and the security `tracker_repo` (distinct
from this file's general-issue tracker).
- [`reassess-pool-defaults.md`](reassess-pool-defaults.md) — pool
definitions consumed by `issue-reassess`, extending the default
queries above.
- [`runtime-invocation.md`](runtime-invocation.md) — how `issue-reproducer`
runs the extracted code.
@@ -0,0 +1,70 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — onboarding-concierge configuration](#apache-airflow--onboarding-concierge-configuration)
- [Out-of-scope topics](#out-of-scope-topics)
- [AI-attribution footer](#ai-attribution-footer)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — onboarding-concierge configuration
Copy this file into your own `<project-config>/onboarding-concierge-config.md`
and replace every `<placeholder>` with your project's value.
| Key | Value | Notes |
|---|---|---|
| `contributing_guide_url` | `https://github.com/apache/airflow/blob/main/contributing-docs/README.rst` | Absolute `https://` URL of the project's primary contributing guide. Linked in every answer. |
| `maintainer_team_handle` | `@apache/airflow-committers` | GitHub team the skill `@`-mentions on hand-off. Example: `@apache/airflow-committers`. |
| `ai_attribution_footer` | *(see below)* | Literal markdown appended to every drafted answer. |
## Out-of-scope topics
Topics that always trigger hand-off regardless of how the question is phrased.
Remove rows that do not apply to your project; add rows for project-specific
surfaces that AI should not improvise on.
- `security` — vulnerability reports, CVE allocation, embargoed work
- `deprecation` — timing decisions for removing or changing APIs
- `license` — license compatibility, header policy
- `architecture` — design-taste questions about project structure or evolution
## AI-attribution footer
```markdown
---
_Note: This reply was drafted by an AI-assisted mentoring tool and may
contain mistakes. Once you have addressed the points above, a
Apache Airflow maintainer — a real person — will take the next look.
We use this [two-stage process](https://github.com/apache/airflow/blob/main/contributing-docs/25_maintainer_pr_triage.md#why-the-first-pass-is-automated) so that our
maintainers' limited time is spent where it matters most: the conversation
with you._
```
Replace `<two_stage_process_doc_url>` with your project's documented
mentoring/triage policy URL and `<PROJECT>` with the project's display name
(read from `<project-config>/project.md`).
+129
View File
@@ -0,0 +1,129 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow: PMC roster](#apache-airflow-pmc-roster)
- [Roster](#roster)
- [Resolution](#resolution)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow: PMC roster
**This file is a placeholder ahead of the release-management
skill family landing.** None of the `release-*` skills exist
yet, see
[`docs/release-management/README.md`](../../docs/release-management/README.md).
The roster below is what `release-vote-tally` will read to
classify each `[VOTE]` reply as binding (PMC member) or
non-binding (committer / community).
PMC membership for Apache Airflow. Update every time a new PMC
member is added per a `[VOTE]` thread on the project's private list
or per a Board resolution removing a member. Authoritative source
is the project's record under <https://projects.apache.org/committee.html?airflow>
(roster: <https://whimsy.apache.org/roster/committee/airflow>); this file
mirrors it so the tally skill can resolve a `From:` address without
hitting the public LDAP every run.
## Roster
| Apache ID | Name | Primary email | Binding since |
|---|---|---|---|
| `aizhamal` | Aizhamal Nurmamat kyzy | `aizhamal@apache.org` | `2019-11-21` |
| `saguziel` | Alex Guziel | `saguziel@apache.org` | `2018-12-19` |
| `alexvanboxel` | Alex Van Boxel | `alexvanboxel@apache.org` | `2018-12-19` |
| `amoghdesai` | Amogh Desai | `amoghdesai@apache.org` | `2025-06-26` |
| `taragolis` | Andrey Anshin | `taragolis@apache.org` | `2024-01-15` |
| `arthur` | Arthur Wiedmer | `arthur@apache.org` | `2018-12-19` |
| `ash` | Ash Berlin-Taylor | `ash@apache.org` | `2018-12-19` |
| `bolke` | Bolke de Bruin | `bolke@apache.org` | `2018-12-19` |
| `bbovenzi` | Brent Bovenzi | `bbovenzi@apache.org` | `2023-03-15` |
| `bugraoz` | Bugra Ozturk | `bugraoz@apache.org` | `2026-01-14` |
| `criccomini` | Chris Riccomini | `criccomini@apache.org` | `2018-12-19` |
| `davydov` | Dan Davydov | `davydov@apache.org` | `2018-12-19` |
| `dimberman` | Daniel Imberman | `dimberman@apache.org` | `2020-07-07` |
| `dstandish` | Daniel Standish | `dstandish@apache.org` | `2022-09-22` |
| `eladkal` | Elad Kalif | `eladkal@apache.org` | `2021-08-30` |
| `ephraimanierobi` | Ephraim Anierobi | `ephraimanierobi@apache.org` | `2021-08-31` |
| `fokko` | Fokko Driesprong | `fokko@apache.org` | `2018-12-19` |
| `hitesh` | Hitesh Shah | `hitesh@apache.org` | `2018-12-19` |
| `husseinawala` | Hussein Awala | `husseinawala@apache.org` | `2023-07-29` |
| `jghoman` | Jakob Homan | `jghoman@apache.org` | `2018-12-19` |
| `potiuk` | Jarek Potiuk | `potiuk@apache.org` | `2019-10-18` |
| `jedcunningham` | Jedidiah Cunningham | `jedcunningham@apache.org` | `2022-01-04` |
| `jscheffl` | Jens Scheffler | `jscheffl@apache.org` | `2024-08-06` |
| `joygao` | Joy Gao | `joygao@apache.org` | `2018-12-19` |
| `kamilbregula` | Kamil Breguła | `kamilbregula@apache.org` | `2020-07-07` |
| `kaxilnaik` | Kaxil Naik | `kaxilnaik@apache.org` | `2018-12-19` |
| `sekikn` | Kengo Seki | `sekikn@apache.org` | `2019-12-01` |
| `keviny` | Kevin Yang | `keviny@apache.org` | `2019-11-21` |
| `maximebeauchemin` | Maxime Beauchemin | `maximebeauchemin@apache.org` | `2018-12-19` |
| `onikolas` | Niko Oliveira | `onikolas@apache.org` | `2026-05-21` |
| `gopidesu` | Pavan Kumar | `gopidesu@apache.org` | `2026-08-08` |
| `pierrejeambrun` | Pierre Jeambrun | `pierrejeambrun@apache.org` | `2023-03-14` |
| `rahulvats` | Rahul Vats | `rahulvats@apache.org` | `2026-01-14` |
| `shahar` | Shahar Epstein | `shahar@apache.org` | `2025-12-23` |
| `sanand` | Siddharth Anand | `sanand@apache.org` | `2018-12-19` |
| `msumit` | Sumit Maheshwari | `msumit@apache.org` | `2018-12-19` |
| `tfeng` | Tao Feng | `tfeng@apache.org` | `2018-12-19` |
| `turbaszek` | Tomasz Urbaszek | `turbaszek@apache.org` | `2020-07-07` |
| `uranusjr` | Tzu-ping Chung | `uranusjr@apache.org` | `2022-09-22` |
| `vikramkoka` | Vikram Koka | `vikramkoka@apache.org` | `2024-10-19` |
| `vincbeck` | Vincent Beck | `vincbeck@apache.org` | `2025-10-02` |
| `weilee` | Wei Lee | `weilee@apache.org` | `2025-09-30` |
| `xddeng` | Xiaodong Deng | `xddeng@apache.org` | `2020-12-25` |
A `[VOTE]` reply counts as binding when:
1. The `From:` address matches a row's `Primary email` exactly, **or**
2. The `From:` address contains `@apache.org` and the local part
matches a row's `Apache ID` exactly.
Rule (2) is the fallback because PMC members occasionally vote from
`<id>@apache.org` rather than the `Primary email` recorded here.
Personal Gmail / corporate addresses MUST appear in `Primary email`
to count.
## Resolution
`release-vote-tally`'s resolution algorithm:
1. Normalise the `From:` header to `local@domain` form.
2. Try exact match against `Primary email` (case-insensitive).
3. If `domain == apache.org`, try the local-part against the
`Apache ID` column.
4. If neither hits, the vote is classified non-binding and
surfaced for RM review.
If a binding voter casts a vote from an address not on this roster,
the skill flags `BINDING-CANDIDATE-UNRESOLVED` and refuses to count
the vote until the RM either (a) updates this roster to include the
address, or (b) confirms the vote is non-binding.
The roster is the source of truth for the tally skill. The skill
never infers binding status from message content (e.g. a sign-off
that says "PMC member" does not promote a non-roster voter to
binding).
@@ -0,0 +1,82 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0 -->
# Apache Airflow — code-review criteria sources
Generated from this repository. Ground truth is the
source files themselves; this file only points at them.
## repo_wide_source_files
| File | What it covers |
|---|---|
| `.github/instructions/code-review.instructions.md` | The review checklist every Airflow PR is checked against |
| `AGENTS.md` (`CLAUDE.md` is a symlink to it) | Architecture boundaries, security model, coding standards, testing standards, commit/PR conventions, newsfragment rules |
| `contributing-docs/05_pull_requests.rst` | PR conventions incl. Gen-AI disclosure |
## Per-area source files
| Subtree | File |
|---|---|
| `providers/` | `providers/AGENTS.md` |
| `providers/common/ai/` | `providers/common/ai/AGENTS.md` |
| `providers/elasticsearch/` | `providers/elasticsearch/AGENTS.md` |
| `providers/opensearch/` | `providers/opensearch/AGENTS.md` |
| `airflow-core/src/airflow/ui/` | `airflow-core/src/airflow/ui/AGENTS.md` |
| `airflow-core/src/airflow/api_fastapi/execution_api/` | `airflow-core/src/airflow/api_fastapi/execution_api/AGENTS.md` |
| `airflow-core/src/airflow/_shared/` | `airflow-core/src/airflow/_shared/AGENTS.md` |
| `task-sdk/src/airflow/sdk/_shared/` | `task-sdk/src/airflow/sdk/_shared/AGENTS.md` |
| `task-sdk/src/airflow/sdk/execution_time/schema/` | `task-sdk/src/airflow/sdk/execution_time/schema/AGENTS.md` |
| `registry/` | `registry/AGENTS.md` |
| `dev/` | `dev/AGENTS.md`, `dev/ide_setup/AGENTS.md` |
| `scripts/ci/prek/` | `scripts/ci/prek/AGENTS.md` |
Any other `AGENTS.md` under a touched path is auto-discovered via `git ls-files`.
## security_model_calibration
| Key | Value |
|---|---|
| `file` | `airflow-core/docs/security/security_model.rst` |
| `supplementary` | `airflow-core/docs/security/jwt_token_authentication.rst`, `AGENTS.md` § Security Model |
## Backports / version-specific PRs
| Key | Value |
|---|---|
| `backport_branch_pattern` | `v[0-9]-[0-9]-test` (e.g. `v3-1-test`, `v3-3-test`) |
## Section anchors
Base: `https://github.com/apache/airflow/blob/main/.github/instructions/code-review.instructions.md`
| Section | Anchor |
|---|---|
| Architecture boundaries | `#architecture-boundaries` |
| Database / query correctness | `#database-and-query-correctness` |
| Code quality | `#code-quality-rules` |
| Testing | `#testing-requirements` |
| API correctness | `#api-correctness` |
| UI (React/TypeScript) | `#ui-code-reacttypescript` |
| Generated files | `#generated-files` |
| AI-generated code signals | `#ai-generated-code-signals` |
| Quality signals to check | `#quality-signals-to-check` |
| Commits and PRs | `https://github.com/apache/airflow/blob/main/AGENTS.md#commits-and-prs` |
| Security model | `https://github.com/apache/airflow/blob/main/airflow-core/docs/security/security_model.rst` |
@@ -0,0 +1,166 @@
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [`pr-management-quick-merge` configuration (template)](#pr-management-quick-merge-configuration-template)
- [Thresholds](#thresholds)
- [Real-CI patterns](#real-ci-patterns)
- [Path globs](#path-globs)
- [`tier_a_allow_globs` — documentation / text only (highest confidence)](#tier_a_allow_globs--documentation--text-only-highest-confidence)
- [`tier_b_allow_globs` — low-risk code (test / example only)](#tier_b_allow_globs--low-risk-code-test--example-only)
- [`deny_globs` — absolute disqualifiers (consequential areas; one match drops the PR even at one line)](#deny_globs--absolute-disqualifiers-consequential-areas-one-match-drops-the-pr-even-at-one-line)
- [Merge-command template](#merge-command-template)
- [Approve action](#approve-action)
- [Note on automated merge (Agentic Autonomous)](#note-on-automated-merge-agentic-autonomous)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# `pr-management-quick-merge` configuration (template)
Per-project configuration for the
[`pr-management-quick-merge`](../../skills/pr-management-quick-merge/SKILL.md)
skill. This is the **`_template` default**; new adopters copy it into their own
`<project-config>/pr-management-quick-merge-config.md` and tune the thresholds
and path globs for their repository layout.
The default globs below are shaped for a Python monorepo; an
adopter with a different layout replaces them wholesale. When a field is absent,
the skill falls back to the default noted in its row.
## Thresholds
| Key | Default | Meaning |
|---|---|---|
| `max_churn` | `20` | Maximum `additions + deletions` for a quick-merge candidate. Pure deletions count. |
| `max_files` | `3` | Maximum number of changed files. |
| `default_tiers` | `A,B` | Which tiers are surfaced when the run does not pass `tier:`. |
## Real-CI patterns
`real_ci_patterns` is **read from the shared
[`<project-config>/pr-management-config.md`](pr-management-config.md)** — do not
duplicate it here. The skill uses it for the
[Real-CI guard](../../skills/pr-management-triage/classify-and-act.md#real-ci-guard)
in gate G2 so a SUCCESS rollup that comes only from bot checks
(`Mergeable`/`DCO`/`boring-cyborg`) is not mistaken for green CI.
## Path globs
Matched against repo-relative POSIX paths. Deny is evaluated first and wins
(see [`candidate-rules.md` Path matching](../../skills/pr-management-quick-merge/candidate-rules.md#path-matching)).
### `tier_a_allow_globs` — documentation / text only (highest confidence)
```text
**/*.rst
**/*.md
**/docs/**
docs/**
**/newsfragments/**
**/changelog.rst
**/i18n/**
**/locales/**
**/*.po
spelling_wordlist.txt
```
### `tier_b_allow_globs` — low-risk code (test / example only)
```text
**/tests/**
**/test_*.py
**/*_test.py
**/examples/**
**/example_*/**
```
### `deny_globs` — absolute disqualifiers (consequential areas; one match drops the PR even at one line)
```text
**/migrations/**
**/versions/**
**/alembic*/**
pyproject.toml
**/pyproject.toml
uv.lock
setup.cfg
**/requirements*.txt
.github/**
**/Dockerfile*
scripts/ci/**
**/security/**
**/auth*/**
**/jwt*/**
# Core application code — Apache Airflow security-sensitive module paths.
airflow-core/src/airflow/jobs/**
airflow-core/src/airflow/models/**
airflow-core/src/airflow/executors/**
airflow-core/src/airflow/api_fastapi/**
airflow-core/src/airflow/serialization/**
task-sdk/src/airflow/sdk/execution_time/**
# Repository / GitHub settings (branch protection, merge buttons, PR cap)
.asf.yaml
```
Tune `deny_globs` toward over-inclusion: a false deny just means a PR waits for
`pr-management-code-review`; a false allow means a maintainer may merge a
core/security/build change after only a skim. When unsure, add the path here.
## Merge-command template
| Key | Default | Meaning |
|---|---|---|
| `merge_command_template` | `gh pr merge <N> --squash --repo apache/airflow` | The **copy-paste command the skill prints** next to each candidate for the maintainer to run *themselves*. The skill never executes it — it is presentation only (see [`SKILL.md` Golden rule 1](../../skills/pr-management-quick-merge/SKILL.md#golden-rules)). Set the merge method (`--squash` / `--merge` / `--rebase`) to your project's convention. Airflow: `.asf.yaml` enables squash merges only. |
## Approve action
The skill's one permitted mutation is an APPROVE review, submitted only on the
maintainer's explicit per-PR confirmation (see
[`SKILL.md` Step 3b](../../skills/pr-management-quick-merge/SKILL.md#step-3b--optional-approve-action)).
| Key | Default | Meaning |
|---|---|---|
| `enable_approve` | `true` | Whether the `[A]pprove NN` action is offered. Set `false` to make the skill purely read-only (surface-only, no approvals). |
| `approve_requires_diff_view` | `true` | When `true`, `[A]pprove NN` is rejected unless the maintainer ran `[V]iew diff` for that PR earlier in the session. Keep `true` — approving the maintainer's own review act should follow actually reading the diff. |
| `approve_body` | *(empty)* | Optional text posted as the APPROVE review body. **Leave empty** for a bare approve (no agent-drafted prose, no attribution footer needed). If set, the text is an agent-drafted GitHub message and the skill appends the `Drafted-by:` attribution footer per [`AGENTS.md`](../../AGENTS.md) automatically. |
The approve adds exactly one approving review (the maintainer's). It never uses
`--admin` or any branch-protection bypass: if the repo requires more than one
approval, one approve will not unblock the merge, and the skill says so rather
than implying the PR is mergeable.
## Note on automated merge (Agentic Autonomous)
This skill **surfaces** candidates; it does not merge. Automated merge — even
narrowly-scoped and per-PR-confirmed — is the framework's `mode:Autonomous`, off until
the Triage/Mentoring/Drafting modes have a two-quarter track record (see
[`docs/labels-and-capabilities.md`](../../docs/labels-and-capabilities.md)).
There is therefore **no `enable_merge` knob** in this config: the capability is
gated at the framework level, not per adopter. When the gate lifts, the merge
action will ship as a separate, explicitly Mode-D-labelled change with its own
config and safety protocol.
@@ -0,0 +1,201 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — reassessment pool defaults](#apache-airflow--reassessment-pool-defaults)
- [Pool: `open-eol`](#pool-open-eol)
- [Pool: `reopened`](#pool-reopened)
- [Pool: `stale-unresolved`](#pool-stale-unresolved)
- [Pool: project-specific](#pool-project-specific)
- [Pool-selection guidance](#pool-selection-guidance)
- [Cross-references](#cross-references)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — reassessment pool defaults
Named issue pools for [`issue-reassess`](../../skills/issue-reassess/SKILL.md)
sweep campaigns. Each pool is a query against `<issue-tracker>` that
surfaces a particular kind of candidate.
Express each pool as a query the tracker accepts (JQL for JIRA,
`gh search` for GitHub Issues, etc.). The skill picks one pool per
sweep; the user can override per-invocation.
This file extends the default-triage-pool query in
[`issue-tracker-config.md`](issue-tracker-config.md) with named
named-and-rationalised pools tuned to specific reassessment goals.
Airflow is on GitHub Issues, so every pool below is GitHub issue-search
syntax, usable as `gh search issues "<query>"` or
`gh api -X GET search/issues -f q='<query>'`. GitHub search has no
relative dates: `<cutoff-12m>` / `<cutoff-90d>` stand for the ISO date
12 months / 90 days before the sweep (e.g. `2025-09-26`); the skill
substitutes them. Sweeps skip issues labelled `pinned` or `security`,
and never reassess a vulnerability report on the public tracker (those go
to `security@airflow.apache.org`).
## Pool: `open-eol`
Open issues whose `fixVersion` is end-of-life. Often contains:
- Long-fixed-but-never-closed issues (silent fixes).
- Wishlists that the team has resisted.
- Real bugs that fell through the cracks at end-of-life.
Airflow has no `fixVersion`; the equivalent is the `affected_version:<X.Y>`
label (latest version the bug reproduces on, per
`ISSUE_TRIAGE_PROCESS.rst`). When a release line goes end-of-life its
labels are renamed with an `_eol_` prefix — all of Airflow 2.x
(EOL 2026-04-22) is now `_eol_affected_version:2.1` …
`_eol_affected_version:2.11`. Reassess each against `main`
(`breeze shell --use-airflow-version` for the old version) and ask the
reporter to reconfirm on Airflow 3 if it still reproduces.
```text
repo:apache/airflow is:issue is:open label:"_eol_affected_version:2.1","_eol_affected_version:2.2","_eol_affected_version:2.3","_eol_affected_version:2.4","_eol_affected_version:2.5","_eol_affected_version:2.6","_eol_affected_version:2.7","_eol_affected_version:2.8","_eol_affected_version:2.9","_eol_affected_version:2.10","_eol_affected_version:2.11" -label:pinned sort:updated-asc
```
When a further release line goes EOL, add its renamed
`_eol_affected_version:<X.Y>` labels to the comma-separated (OR) list.
JIRA example:
```text
project = <KEY> AND resolution = Unresolved AND
fixVersion in releasedVersions() AND
fixVersion was in unreleasedVersions() AND status = Open
```
## Pool: `reopened`
Issues that were closed and later reopened. Surfaces:
- Persistent wishlists the team keeps resisting (often classified
`feature-request-disguised-as-bug` per the nature taxonomy in
[`issue-reproducer/verdict-composition.md`](../../skills/issue-reproducer/verdict-composition.md)).
- True regressions where a fix was reverted or didn't stick.
GitHub records `state_reason: reopened` on such issues, and issue search
exposes it as `reason:reopened`:
```text
repo:apache/airflow is:issue is:open reason:reopened -label:pinned sort:updated-asc
```
JIRA example:
```text
project = <KEY> AND status changed FROM "Closed" TO "Open"
```
## Pool: `stale-unresolved`
Open issues with no activity in the last 12 months. Useful for
periodic hygiene sweeps to confirm-or-close.
Inactive `kind:bug` issues are already handled by the
`.github/workflows/recheck-old-bug-report.yml` bot: after 365 days without
activity it labels them `Stale Bug Report`, asks the author to recheck on
the latest version, and closes them 30 days later. This pool therefore
excludes issues the bot has already flagged, and mainly surfaces
`kind:feature` / `kind:task` / `kind:documentation` issues the bot never
touches:
```text
repo:apache/airflow is:issue is:open updated:<<cutoff-12m> -label:"Stale Bug Report" -label:pinned -label:security sort:updated-asc
```
JIRA example:
```text
project = <KEY> AND resolution = Unresolved AND
updated < -52w
```
## Pool: project-specific
Adopters can add pools tuned to their specific concerns — e.g.,
issues lacking a component label, issues filed before a specific
major release, issues with specific keyword overlap.
Airflow pools:
- **`triage-backlog`** — issues still carrying `needs-triage` 90+ days
after filing. `ISSUE_TRIAGE_PROCESS.rst`: while `needs-triage` remains,
the triage team checks periodically whether the issue should be
accepted, closed, or converted to a GitHub Discussion (Ideas / Q&A).
```text
repo:apache/airflow is:issue is:open label:needs-triage created:<<cutoff-90d> sort:created-asc
```
- **`stale-bug-report`** — bugs the recheck bot has flagged and will
close within 30 days. Reassessing them before closure separates
silently fixed bugs (close as fixed, with evidence) from still-live
ones (remove the label; the bot re-adds `needs-triage` on activity).
```text
repo:apache/airflow is:issue is:open label:"Stale Bug Report" sort:updated-asc
```
- **`accepted-bugs-quiet`** — accepted bug reports gone quiet; the
reassess default already declared in
[`issue-tracker-config.md`](issue-tracker-config.md) (the triager
removed `needs-triage`, so nobody is watching them).
```text
repo:apache/airflow is:issue is:open label:kind:bug -label:needs-triage -label:"Stale Bug Report" updated:<<cutoff-90d> sort:updated-asc
```
`pending-response` issues are deliberately **not** a pool: the
`.github/workflows/stale.yml` bot already marks them stale after 14 days
without an author response and closes them 7 days later.
## Pool-selection guidance
The skill picks one pool per sweep. Hints for picking:
- **First-ever sweep** of an existing project: start with
`open-eol` (highest density of silent fixes; fastest to clear).
- **Periodic hygiene** sweeps: rotate through pools each quarter.
- **Pre-release** check sweeps: `stale-unresolved` and any
release-version-specific pool.
- **Specific concern** (e.g., complaint about wishlist accumulation):
`reopened`.
For Airflow specifically: `open-eol` is small (about 25 open issues on
2026-09-26) and every hit is a 2.x-era report, so it is the natural first
sweep. For a pre-release sweep of an Airflow 3 minor, use
`label:"affected_version:<X.Y>"` for the release line being superseded.
Run `stale-bug-report` before the recheck bot's 30-day close window
expires so fixed bugs close with evidence rather than as "no response".
## Cross-references
- [`issue-tracker-config.md`](issue-tracker-config.md) — the
default-triage pool (distinct from these reassess pools).
- [`reproducer-conventions.md`](reproducer-conventions.md) —
evidence layout for each issue in a sweep.
+273
View File
@@ -0,0 +1,273 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — release trains, release managers, security team roster](#apache-airflow--release-trains-release-managers-security-team-roster)
- [Release branches currently in flight](#release-branches-currently-in-flight)
- [Current release managers](#current-release-managers)
- [Known release-manager rotations](#known-release-manager-rotations)
- [Release managers for releases currently relevant to the security tracker](#release-managers-for-releases-currently-relevant-to-the-security-tracker)
- [Security team roster](#security-team-roster)
- [What this means for sync and fix skills](#what-this-means-for-sync-and-fix-skills)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — release trains, release managers, security team roster
Fast-moving project state. Update every time a release ships, a new
release branch opens, or a security-team member joins / rotates off.
## Release branches currently in flight
Snapshot as of 2026-09-26, derived from the `upstream` branch list, the
open GitHub milestones, the `backport-to-*` labels and `.github/boring-cyborg.yml`.
Airflow ships several independent trains; each `dev/README_RELEASE_*.md` is the
source of truth for its process.
- **`main`** — Airflow core `3.4.0` (milestone `Airflow 3.4.0`); Task SDK and
the Python client follow the core version line. Providers are released from
`main` in date-identified waves (`providers/<YYYY-MM-DD>` tags; latest
`providers/2026-09-22`). Helm Chart `2.0.0` (milestone `Airflow Helm Chart
2.0.0`) is developed on `main` (see `dev/README_HELM_CHART2_DEV.md`).
Also carries the Go / Java / TS SDK milestones (`Go SDK 1.0 GA`,
`Java SDK 1.0 GA`, `TS SDK 1.0 Beta`).
- **`v3-3-test`** (cut to `v3-3-stable`) — patch branch for Airflow core
`3.3.x` (with Task SDK `1.3.x`, Python client `3.3.x`). Last release `3.3.2`
(2026-09-17). Next patch is `3.3.3` (milestone `Airflow 3.3.3`).
**Default target for new core security fixes** (backport label
`backport-to-v3-3-test`).
- **`chart/v1-2x-test`** — Helm Chart `1.2x.x` maintenance line (bug fixes,
doc fixes and deprecation warnings only). Last release `helm-chart/1.22.0`
(2026-06-04). Next is `1.23.0` (milestone `Airflow Helm Chart 1.23.0`).
Where a chart fix targets depends on where the bug exists (see
`dev/README_HELM_CHART2_DEV.md`); fixes on `main` that also apply to 1.2x
get the `backport-to-chart/v1-2x-test` label.
- **`airflow-ctl/v0-1-test`** (cut to `airflow-ctl/v0-1-stable`) — airflowctl
`0.1.x` line; releases are never cut from `main`. Last release
`airflow-ctl/0.1.5` (2026-06-03). Backport label
`backport-to-airflow-ctl/v0-1-test`.
- **`providers-fab/v1-5`** — FAB provider `1.5.x` maintenance branch
(backport label `backport-to-providers-fab/v1-5`). All other providers
release from `main` only; provider security fixes target `main`.
- **`v3-2-test` and older `vX-Y-test`** — no open milestone and no active
`backport-to-*` label; treated as having no further releases planned.
`v2-11-test` is explicitly EOL (label `_eol_backport-to-v2-11-test`).
## Current release managers
Two sources identify the release manager for a given cut:
1. The [Release Plan](https://cwiki.apache.org/confluence/display/AIRFLOW/Release+Plan)
wiki page (release schedule for core, providers,
Helm chart and airflowctl; `dev/verify_release_calendar.py` cross-checks it
against the public release calendar).
2. The `[RESULT][VOTE]` thread on `dev@airflow.apache.org`
(archive: <https://lists.apache.org/list.html?dev@airflow.apache.org>).
The sender of the `[RESULT][VOTE] …` message **is** the release
manager for that specific cut.
## Known release-manager rotations
Rotations are published on the
[Release Plan](https://cwiki.apache.org/confluence/display/AIRFLOW/Release+Plan)
wiki page (providers waves, core, Helm chart, airflowctl).
Snapshot as of 2026-09-26, from the Release Plan wiki page (read 2026-09-26)
cross-checked against the `[RESULT][VOTE]` senders on `dev@airflow.apache.org`
since 2026-03. GitHub handles are from `.github/CODEOWNERS`.
- **Airflow core (3.x), Task SDK, Python client** — Rahul Vats
(`vatsrahul1001`), supported by Kaxil Naik (`kaxil`). Rahul sent every core,
Task SDK and Python client `[RESULT][VOTE]` from 3.1.8 through 3.3.2.
Planned next: `3.4.0` (feature freeze 2026-10-05, RC 2026-10-19, release
2026-10-26). `3.3.3` is not yet on the wiki schedule.
- **Providers waves** — rotation Hussein Awala (`hussein-awala`), Jarek
Potiuk (`potiuk`), Vincent Beck (`vincbeck`), Shahar Epstein (`shahar1`),
Niko Oliveira (`o-nikolas`). Upcoming cuts per the wiki: 2026-09-22 Shahar
Epstein (no `[RESULT]` yet), 2026-10-06 Jarek Potiuk, 2026-10-20 Hussein
Awala, 2026-11-03 Niko Oliveira. Jens Scheffler (`jscheffl`) also ran
waves in 2026-03 and 2026-05, but is not in the current rotation.
- **Helm chart** — rotation Jed Cunningham (`jedcunningham`), Jens Scheffler
(`jscheffl`), Buğra Öztürk (`bugraoz93`), Jarek Potiuk (`potiuk`). Recent
RMs: 1.20.0 Jens Scheffler, 1.21.0 Buğra Öztürk, 1.22.0 Jarek Potiuk. The
wiki slots for weeks of 2026-06-15 (Jed Cunningham, "either 2.0 or another
1.23.0"), 2026-07-20 and 2026-08-17 (both Buğra Öztürk) have no `[RESULT]`
thread yet; `1.23.0` is still open.
- **airflowctl** — rotation Buğra Öztürk (`bugraoz93`), Jarek Potiuk
(`potiuk`). Recent RMs: 0.1.3 and 0.1.5 Buğra Öztürk, 0.1.4 Jarek Potiuk.
The wiki lists Buğra Öztürk for a possible `1.0.0` (week of 2026-06-22),
which has not been voted on.
- **Java SDK** — Tzu-ping Chung (`uranusjr`); `1.0.0-beta1` released
2026-07-13.
- **Airflow 2** — Jarek Potiuk (`potiuk`). `2.11.2` was voted 2026-03-14; the
wiki marks the week of 2026-04-20 as the last Airflow 2 release.
- **apache-airflow-mypy** — Hussein Awala (`hussein-awala`). `0.1.0` was
released 2026-06-12; later releases are on demand.
## Release managers for releases currently relevant to the security tracker
Snapshot as of 2026-09-26, covering releases since 2026-03. The RM is the
sender of the `[RESULT][VOTE]` thread linked below. Where that thread was sent
from a non-ASF address, the email listed is the RM's `@apache.org` address
from their own public CVE advisories on `users@airflow.apache.org`. CVE ids
and fixed versions come from those advisories
(<https://lists.apache.org/list.html?users@airflow.apache.org>). Helm chart
and airflowctl releases in this window carried no published CVEs.
**Airflow core (+ Task SDK).** RM for all of these: Rahul Vats,
`rahulvats@apache.org`, `vatsrahul1001`.
- **3.3.2** (voted 2026-09-17), <https://lists.apache.org/thread/8g8tgsk028gxfh1r741dzv63fkm0mbvh>:
CVE-2026-75157, CVE-2026-82355, CVE-2026-86473, CVE-2026-75158.
- **3.3.1** (voted 2026-08-12), <https://lists.apache.org/thread/nqt073s4yg6cg8rjm15hxvlsm2xk9c8d>:
CVE-2026-58076, CVE-2026-59244, CVE-2026-59242, CVE-2026-54183,
CVE-2026-67260, CVE-2026-67587, CVE-2026-65017, CVE-2026-68968,
CVE-2026-68969, CVE-2026-68970, CVE-2026-68971, CVE-2026-68076.
- **3.3.0** (voted 2026-07-06), <https://lists.apache.org/thread/d1bs8o1r98xwwcornpnfj62dntzg4gwn>:
CVE-2026-33264, CVE-2026-49487, CVE-2026-48828, CVE-2026-49296,
CVE-2026-48891, CVE-2026-48892.
- **3.2.2** (voted 2026-05-29), <https://lists.apache.org/thread/nloffbvgotm1bpvv7s46060wyytfyoky>:
CVE-2026-40861, CVE-2026-40961, CVE-2026-40963, CVE-2026-41014,
CVE-2026-49267, CVE-2026-41017, CVE-2026-41084, CVE-2026-42252,
CVE-2026-42360, CVE-2026-42358, CVE-2026-42359, CVE-2026-45360,
CVE-2026-45426, CVE-2026-46764, CVE-2026-48726, CVE-2026-49298,
CVE-2026-45192.
- **3.2.1** (voted 2026-04-22), <https://lists.apache.org/thread/x1zs0wkbd98ckwnnnghnxstzo9fov5qx>:
CVE-2026-38743, CVE-2026-40690.
- **3.2.0** (voted 2026-04-07), <https://lists.apache.org/thread/rorz8rq9dn3myvngotnk2xs1mjngvw2m>:
CVE-2026-34538, CVE-2025-57735, CVE-2025-66236, CVE-2026-33858,
CVE-2026-31987, CVE-2026-30912, CVE-2026-32690, CVE-2026-32228,
CVE-2026-25917, CVE-2026-25219. It also covers two documentation-only
advisories about unsafe examples: CVE-2025-54550 and CVE-2026-30898.
- **3.1.8** (voted 2026-03-11), <https://lists.apache.org/thread/k2pmyynlzz7jznw8fxkcqqb3mcnqo4mh>:
CVE-2026-30911, CVE-2026-28779, CVE-2026-26929, CVE-2026-28563.
- **Upcoming:** `3.3.3` and `3.4.0` (planned for 2026-10-26), with Rahul Vats
as RM per the wiki.
**Providers waves.** Each wave is paired with the advisories that its RM
announced right after it. The advisory names the fixed provider version, but
does not name the wave.
- **2026-09-09**, Vincent Beck, `vincbeck@apache.org`, `vincbeck`,
<https://lists.apache.org/thread/1cby0k2cd5c6m96v5nmcy3vtd5dzbbnc>:
fab 3.9.0 (CVE-2026-86466, CVE-2026-82310, CVE-2026-86462,
CVE-2026-82311), keycloak 0.10.0 (CVE-2026-76187, CVE-2026-76186),
apache-kafka 2.0.0 (CVE-2026-86792), akeyless 0.3.1 (CVE-2026-86465).
- **2026-08-25**, Niko Oliveira, `onikolas@apache.org`, `o-nikolas`,
<https://lists.apache.org/thread/690qgkdrpg9x0ctmxo13dfpzqv0v1zy5>:
fab 3.8.1 (CVE-2026-75156).
- **2026-08-06 / 2026-08-08**, Jarek Potiuk, `potiuk@apache.org`, `potiuk`,
<https://lists.apache.org/thread/j44vmoh7z9b077zvn7vhk2fooycdmmpr>,
<https://lists.apache.org/thread/r23ry6mjjs36o4s5y0zqqqqw8r6pd5qr>:
amazon 9.34.0 (CVE-2026-68872), yandex 4.5.1 (CVE-2026-68871),
microsoft-azure 14.1.0 (CVE-2026-68870), google 22.3.0 (CVE-2026-68868).
- **2026-07-22**, Shahar Epstein, `shahar@apache.org`, `shahar1`,
<https://lists.apache.org/thread/zx2z4ddbs4mg0w9wmbb5yo727qhgsro8>:
fab 3.7.3 (CVE-2026-59243).
- **2026-07-06**, Vincent Beck, `vincbeck@apache.org`, `vincbeck`,
<https://lists.apache.org/thread/4m1jqkb6r4lq0qq8j2lppp0z1yq0xwsb>:
git 0.4.1 (CVE-2026-58065), fab 3.7.2 (CVE-2026-59245).
- **2026-06-26 / 2026-07-01**, Shahar Epstein, `shahar@apache.org`, `shahar1`,
<https://lists.apache.org/thread/1p87439ns9f14fbh75d3spl3dlhn5xrn>,
<https://lists.apache.org/thread/q6pbq23t260fs3tkcok0vr1pbosg9wy3>:
google 22.2.1 (CVE-2026-49297).
- **2026-06-16**, Shahar Epstein, `shahar@apache.org`, `shahar1`,
<https://lists.apache.org/thread/xjz945gp3ltlxckkwol7mjsvsf4g1c3m>:
ftp 3.15.1 (CVE-2026-49486).
- **2026-06-02 / 2026-06-08**, Jarek Potiuk, `potiuk@apache.org`, `potiuk`,
<https://lists.apache.org/thread/zds5qxglnft3gv1qdzt8thbr6j3b26c7>,
<https://lists.apache.org/thread/wbzxbyc0vqlc3rzrovy5nlqcy8gkr9cs>:
samba 4.12.6 (CVE-2026-49818), sftp 5.8.1 (CVE-2026-50203).
- **2026-05-19**, Jens Scheffler, `jscheffl@apache.org`, `jscheffl`,
<https://lists.apache.org/thread/2q2t3l5lxvsy01fbjl4bh5g0tcfhbn0f>:
google 22.0.0 (CVE-2026-45361), fab 3.6.4 (CVE-2026-46745).
- **2026-05-05**, Vincent Beck, `vincbeck@apache.org`, `vincbeck`,
<https://lists.apache.org/thread/yqo5xszpkflwk5ok16cp5mtzsmywhljz>:
cncf-kubernetes 10.17.0 (CVE-2026-27173), amazon 9.28.0 (CVE-2026-42526).
- **2026-04-26**, Shahar Epstein, `shahar@apache.org`, `shahar1`,
<https://lists.apache.org/thread/sxjpbp9gdnokomjlx8nqosh7l91c7tsn>:
opensearch 1.9.1 (CVE-2026-43826), elasticsearch 6.5.3 (CVE-2026-41018).
- **2026-04-21**, Shahar Epstein, `shahar@apache.org`, `shahar1`,
<https://lists.apache.org/thread/rmcdvbl3qm2gob3xdbv4sqbtgk87z8sq>:
smtp 3.0.0 (CVE-2026-41016).
- **2026-04-08 / 2026-04-12**, Jarek Potiuk, `potiuk@apache.org`, `potiuk`,
<https://lists.apache.org/thread/l8jn2zj1kw352kfjr3lyvjjr891opdfy>,
<https://lists.apache.org/thread/t031q7379j0q0yqfk6jq82mz7qvj65ml>:
keycloak 0.7.0 (CVE-2026-40948).
- **2026-03-24**, Jens Scheffler, `jscheffl@apache.org`, `jscheffl`,
<https://lists.apache.org/thread/czl9jcy5nhd5kxzwlch6vkqwtyt9cqzh>:
databricks, fixed version per the advisory (CVE-2026-32794).
- **2026-02-26 / 2026-03-03**, Jarek Potiuk, `potiuk@apache.org`, `potiuk`,
<https://lists.apache.org/thread/8dj1yl3jgccfb6f4zf46qgvhlbs71drw>,
<https://lists.apache.org/thread/pm3qwh6zz4x0m7r2vsrpdvlhy0qpfhl4>:
http 6.0.0 (CVE-2025-69219), amazon 9.22.0 (CVE-2026-25604).
- **Not yet attributed:** hashicorp 4.8.0 (CVE-2026-97636) was announced on
2026-09-24 by Jarek Potiuk, and no `[RESULT][VOTE]` thread pins it to a
wave. The 2026-09-22 wave (Shahar Epstein per the wiki) has no `[RESULT]`
yet.
When this list becomes stale, the sync skill will surface it as a
blocker.
## Security team roster
The private security tracker repository is intentionally not named in this
public file. Security-team members configure it in their personal, gitignored
`.apache-magpie-local/release-trains.md`, which takes precedence over this file
(lookup order: `.apache-magpie-local/`, then `.apache-magpie-overrides/`). The **authoritative** source is the collaborator list of the
tracker repository — anyone listed as a collaborator, regardless of
permission level, is on the security team.
```bash
gh api repos/<tracker>/collaborators --jq '.[].login'
```
Snapshot (update in the same change as member joins / rotates):
> Intentionally not recorded in this public file. Security-team members
> keep the roster snapshot in their personal, gitignored
> `.apache-magpie-local/release-trains.md`, which takes precedence per file
> (lookup order: `.apache-magpie-local/`, then `.apache-magpie-overrides/`).
## What this means for sync and fix skills
Explicit defaults for the generic skills:
- Default milestone for a new patch-train security issue: `Airflow 3.3.3`
(core). Helm chart: `Airflow Helm Chart 1.23.0`. Providers have no
milestones — fixes ship in the next providers wave from `main`.
- Default backport labels: `backport-to-v3-3-test` (core / Task SDK),
`backport-to-chart/v1-2x-test` (Helm chart 1.2x),
`backport-to-airflow-ctl/v0-1-test` (airflowctl),
`backport-to-providers-fab/v1-5` (FAB provider 1.5.x only). The
`automatic-backport.yml` workflow strips the `backport-to-` prefix to get
the target branch, so use the slash form; `backport-to-airflow-ctl-v0-1-test`
(hyphen form) does not map to a branch.
- Legacy / do-not-use: `v3-2-test` and older core branches;
`_eol_backport-to-v2-11-test` marks the retired 2.11 line.
- None beyond the above.
@@ -0,0 +1,166 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — reproducer evidence-package layout](#apache-airflow--reproducer-evidence-package-layout)
- [Campaign directory layout](#campaign-directory-layout)
- [Optional probe files](#optional-probe-files)
- [Why frozen copies](#why-frozen-copies)
- [Cross-references](#cross-references)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — reproducer evidence-package layout
Directory layout used by [`issue-reproducer`](../../skills/issue-reproducer/SKILL.md)
when writing per-issue evidence packages, and consumed by
[`issue-reassess-stats`](../../skills/issue-reassess-stats/SKILL.md)
for campaign-level aggregation.
## Campaign directory layout
Evidence packages live under the repository's gitignored `files/` folder
(`AGENTS.md` puts all generated output there, and Breeze mounts it at
`/files`, so the reproducer is runnable in the container without copying):
```text
files/airflow-reassess/<campaign-id>/<ISSUE-KEY>/
├── description.md (frozen copy of the issue body at extraction time)
├── issue.json (frozen JSON snapshot from the tracker)
├── original.py (verbatim code from the issue, untouched)
├── reproducer.py (the adapted runnable form)
├── run.log (captured stdout + stderr from execution)
└── verdict.json (the structured verdict)
```
Substitute:
- `<project>` — `airflow` (lower-cased `short_name` from
[`project.md`](project.md)); already expanded in the path above.
- `<campaign-id>` — the campaign identifier
(e.g., `pilot-2026-09-26`).
- `<ISSUE-KEY>` — the GitHub issue number in `apache/airflow`, without
`#` (e.g., `45123`).
- `<ext>` — `.py`. Every Airflow reproducer is Python: a Dag file, a
plain script, or a pytest module (Helm-chart issues use the chart's
pytest-based tests under `chart/tests/`, run with `breeze testing helm-tests`, still `.py`).
Airflow-specific conventions for `reproducer.py`:
- **Shape.** Prefer, in order: (1) a single Dag file run with
`airflow dags test <dag_id>` for scheduling / task-execution bugs;
(2) a plain script for library-level bugs (hooks, serialization,
utilities); (3) a pytest module for bugs only observable through the
test fixtures. When the reproducer later becomes a regression test in a
fix PR, it moves to the mirrored tests path
(`airflow/cli/cli_parser.py` → `tests/cli/test_cli_parser.py`) and must
follow the Testing Standards in `AGENTS.md`.
- **Dag authoring.** Use the Task SDK public API — `from airflow.sdk
import DAG, task` (and other `airflow.sdk` imports) — not the legacy
`airflow.models` / `airflow.decorators` paths, unless the issue is
explicitly about an Airflow 2 or deprecated import path. Give the Dag a
unique `dag_id` such as `repro_<ISSUE-KEY>`, a fixed past `start_date`,
`schedule=None` and `catchup=False`, so `airflow dags test` runs exactly
one Dag run.
- **Minimal.** Keep only what triggers the reported behaviour; replace
external systems with in-process equivalents where that does not change
the bug. Put the expected vs. actual behaviour in a top-of-file comment
that names the issue number.
- **Version.** Run first against `main` (the default Breeze image). When
`main` passes, re-run against the version in the issue's
`affected_version:<X.Y>` label or its "Apache Airflow version" field
with `breeze shell --use-airflow-version <X.Y.Z>` — that is what
distinguishes *fixed since* from *never reproduced*. Record both runs
and versions in `verdict.json`. Airflow 2.x reached end-of-life on
2026-04-22 (its version labels are renamed `_eol_affected_version:2.*`);
a bug that reproduces only on 2.x is flagged as EOL-only in the verdict
for a maintainer to decide on.
- **No secrets.** This is a public repository and the evidence may be
quoted on public issues: never put real connection URIs, passwords,
tokens, cloud credentials or hostnames from the reporter's environment
into `reproducer.py` or `run.log`. Use placeholder connections
(`AIRFLOW_CONN_<ID>` env vars with placeholder values) and redact any
credential that appears verbatim in `original.py` or `description.md`.
- **Security reports.** If an issue turns out to describe a
vulnerability, stop — do not write or run a reproducer on the public
tracker; the report goes to `security@airflow.apache.org` per the
[security policy](https://github.com/apache/airflow/security/policy).
- **Prose.** Write "Dag" (title case) in `verdict.json` text and any
comment drafted from it; keep `DAG` only as the literal code token.
- **Execution.** Run only through Breeze as described in
[`runtime-invocation.md`](runtime-invocation.md), never with `python` /
`pytest` / `airflow` directly on the host.
## Optional probe files
When a [cross-family probe](../../skills/issue-reproducer/probe-templates.md)
was run alongside the reproducer, also persist:
```text
├── cross-type-probe.py (the probe script across type variants)
├── cross-type-probe.log (captured output)
├── operator-variants-probe.py (across operator variants)
└── operator-variants-probe.log
```
A separate `cross-type-probe-findings.md` is added when the probe
surfaces project-wide signal worth recording outside `verdict.json`.
For Airflow the useful variant axes are: metadata-DB backend
(`--backend sqlite|postgres|mysql`), Airflow version
(`main` vs. `--use-airflow-version <X.Y.Z>`), executor (e.g.
`LocalExecutor` vs. `CeleryExecutor`), and — for operator bugs — the
sibling operators in the same provider. Name the probe file after the
axis (e.g. `backend-probe.py`, `version-probe.log`) when it is not a
type or operator probe.
## Why frozen copies
`description.md` and `issue.json` are deliberately **frozen** at
extraction time. The tracker may change (comments added, fields
edited, status changed) between extraction and re-verification.
Frozen copies make the verdict auditable against the same input
state the agent reviewed.
The same logic applies when re-running a campaign against a newer
codebase — comparing fresh runs against frozen description gives a
clean before/after, where comparing against live tracker state
introduces moving targets.
For `apache/airflow`, take the snapshot with
`gh issue view <ISSUE-KEY> -R apache/airflow --json number,title,body,labels,state,createdAt,updatedAt,author,comments,url`
and write `body` to `description.md`.
## Cross-references
- [`runtime-invocation.md`](runtime-invocation.md) — how the
reproducer is executed.
- [`reassess-pool-defaults.md`](reassess-pool-defaults.md) — named
pools that surface candidates for evidence packages.
- [`issue-reproducer/verdict-composition.md`](../../skills/issue-reproducer/verdict-composition.md) —
the `verdict.json` schema.
@@ -0,0 +1,183 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Apache Airflow — runtime invocation](#apache-airflow--runtime-invocation)
- [Build prerequisite](#build-prerequisite)
- [Run a single file](#run-a-single-file)
- [Capture conventions](#capture-conventions)
- [Network and dependency handling](#network-and-dependency-handling)
- [Cross-references](#cross-references)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- SPDX-License-Identifier: Apache-2.0
https://www.apache.org/licenses/LICENSE-2.0 -->
# Apache Airflow — runtime invocation
How to invoke the project's runtime on a single source file. Used
by [`issue-reproducer`](../../skills/issue-reproducer/SKILL.md)
when running extracted code from issue descriptions.
The `<runtime>` placeholder resolves from the *Run a single file*
section below.
**Hard rule** (from [`AGENTS.md`](../AGENTS.md)): never run `pytest`,
`python` or `airflow` directly on the host. Every reproducer runs inside
the [Breeze](../dev/breeze/doc/README.rst) container, which is the same
environment Airflow CI uses. The only host-side exception is a pure-unit
pytest (no database, no system dependencies) run through
`uv run --project <PROJECT> pytest ...`; fall back to Breeze as soon as it
fails on a missing system dependency.
## Build prerequisite
Breeze must be installed and the CI image built for the Python version
you run with:
- Install the per-worktree `breeze` shim once per machine:
`scripts/tools/setup_breeze` (installs `~/.local/bin/breeze`, which runs
Breeze via `uv run --locked` from the current worktree's `dev/breeze` —
see [ADR 0017](../dev/breeze/doc/adr/0017-use-uvx-to-run-breeze-from-local-sources.md)).
- Docker must be running (see
[`dev/breeze/doc/01_installation.rst`](../dev/breeze/doc/01_installation.rst)).
- Build or refresh the CI image before a campaign so the first reproducer
does not pay the build cost inside its timeout:
`breeze ci-image build --python <python>`.
- Python versions: `3.10` (default), `3.11`, `3.12`, `3.13`, `3.14` —
`ALLOWED_PYTHON_MAJOR_MINOR_VERSIONS` in
`dev/breeze/src/airflow_breeze/global_constants.py`; `requires-python`
in `airflow-core/pyproject.toml`. Use the default unless the issue names
a specific Python version.
- Metadata-database backend: `sqlite` (default), `postgres` or `mysql`
via `--backend`. Use the backend the issue reports when the bug is
backend-specific (migrations, locking, SQL dialect); otherwise the
default.
Paths inside the container: the repository is mounted at `/opt/airflow`,
the gitignored `files/` folder at `/files`. Scratch reproducer scripts go
in `files/` or `dev/` (`dev/` is mounted as `/opt/airflow/dev/`) — never
elsewhere in the source tree.
## Run a single file
Three runtime shapes, chosen by what the reproducer is. `<file>` is the
in-container path of the reproducer (host `files/<...>` →
`/files/<...>`); `<args>` is optional argv.
Recipe — plain Python script against `main` sources:
```text
breeze run python <file> <args>
```
Recipe — Dag file (the common case for Airflow bug reports). Point the
Dags folder at the reproducer's own directory so no other Dag is parsed,
migrate the throwaway metadata DB, then run one Dag run in-process:
```text
breeze run bash -c "airflow db migrate >/dev/null && \
AIRFLOW__CORE__DAGS_FOLDER=$(dirname <file>) airflow dags test <dag_id>"
```
Recipe — pytest reproducer placed in the matching tests directory
(`airflow-core/tests/unit/...`, `providers/<name>/tests/unit/...`,
`task-sdk/tests/...`):
```text
breeze run pytest <file> -xvs
# pure-unit, no DB / system deps only:
uv run --project <PROJECT> pytest <file> -xvs
```
Add `--backend postgres|mysql` and/or `--python <X.Y>` to any `breeze run`
line when the issue requires it.
Reproducing against a **released** version instead of `main`:
`breeze run` has no `--use-airflow-version`; use `breeze shell`, which
accepts the command as trailing arguments and reinstalls Airflow from
PyPI at entry:
```text
breeze shell --use-airflow-version <X.Y.Z> [--airflow-extras <extras>] \
"<same command as above>"
```
`--use-airflow-version` also accepts `wheel` / `sdist` (from `dist/`),
`<owner>/<repo>:<branch>`, or a PR number — useful for checking whether an
open PR fixes the issue. Documented in
[`dev/breeze/doc/03_developer_tasks.rst`](../dev/breeze/doc/03_developer_tasks.rst).
## Capture conventions
How to capture stdout, stderr, and exit code in a way the skill can
parse.
| Stream | Convention |
|---|---|
| `stdout` | Capture in full. Breeze prints its own banner and entrypoint output before the command's output; the verdict is based only on the command's output that follows it. |
| `stderr` | Capture and merge into `run.log` (`2>&1`). Airflow logs, task tracebacks and Python warnings go to stderr. |
| `exit code` | `breeze run` / `breeze shell "<cmd>"` propagate the inner command's exit code: 0 = success, non-zero = failure. For `airflow dags test`, do not rely on the exit code alone — also read the final Dag run / task instance states and any traceback in the output. |
| `timeout` | 600s per invocation. Container start-up and (for `--use-airflow-version`) the PyPI reinstall at entry take minutes before the reproducer body starts; a run that times out during start-up is `inconclusive`, not `fails`. |
## Network and dependency handling
The Breeze CI image already contains Airflow core, the Task SDK and all
providers installed from local sources, so a reproducer against `main`
does not resolve dependencies at runtime. Network access is needed only
when building the image or when `--use-airflow-version` /
`--airflow-extras` install from PyPI at container entry.
- A reproducer that needs a provider or library not in the image must
not `pip install` it silently. When running a released version, pass it
via `--airflow-extras`; otherwise record the missing dependency in the
verdict as `inconclusive`.
- A failed PyPI install at entry, an image-build failure, or a
`ModuleNotFoundError` for a provider is an **environment** failure —
check for it in the output before classifying the run as `passes` or
`fails`.
- Reproducers needing an external system (Kafka, MongoDB, …) use
`breeze --integration <name>` (see
[`dev/breeze/doc/03_developer_tasks.rst`](../dev/breeze/doc/03_developer_tasks.rst));
cloud-service reproducers that need real credentials cannot be run and
are recorded as `inconclusive`.
- Each `breeze run` starts a fresh container, so the metadata DB and
installed packages do not leak between reproducers; no per-campaign
cache isolation is needed.
| Key | Value |
|---|---|
| `resolves_dependencies_at_runtime` | `false` |
| `cache_isolation_flag` | *(not applicable — each `breeze run` uses a fresh container)* |
## Cross-references
- [`reassess-pool-defaults.md`](reassess-pool-defaults.md) — named
pools for `issue-reassess` sweeps.
- [`reproducer-conventions.md`](reproducer-conventions.md) —
per-issue evidence-package directory layout.
- [`issue-tracker-config.md`](issue-tracker-config.md) — tracker
URL and project key.
+44 -1
View File
@@ -2,10 +2,53 @@
method: marketplace
url: apache/magpie
min_version: 0.2.0.dev202609222337
min_version: 0.9.0.dev202609261254
plugins:
- magpie-setup
- magpie-utilities
- magpie-agent-guard
- magpie-release-management
- magpie-contributor-growth
reconciled:
version: 0.9.0.dev202609261254
at: 2026-09-26
skills:
activity-sweep: sha256:748187f2d78d9991
announce-draft: sha256:1b0ebe953b9fa334
archive-sweep: sha256:7cb626368f367e76
audit-report: sha256:bed8d4c39f43581d
backlog-stats: sha256:34d5f05ebb5ee5b3
code-review: sha256:261649569ebac577
committer-onboarding: sha256:0b1081376b51a75a
contributor-to-committer: sha256:57f8813ba1ea4a69
deduplicate: sha256:cee70e29c6fadb04
good-first-issue-author: sha256:ac2d0fda09c67231
good-first-issue-sweep: sha256:591ae352325ca83d
isolated-setup-install: sha256:eb1b228a501f2772
issue-import-from-scan: sha256:3aa895ba2115c1d9
issue-import-via-forwarder: sha256:7be6fd9a774bbde5
issue-invalidate: sha256:af16fa7d6f65328a
keys-sync: sha256:bc9f77e9dcb305da
mentor: sha256:3c380e6ecb0fb4c8
newcomer-issue-explainer: sha256:8cfe453a3113abe2
nomination: sha256:4dbd3136d81a2f87
onboarding-concierge: sha256:4105a6571bcb70c2
pr-stale-sweep: sha256:2c5b8030569b63e6
pr-triage: sha256:4a3a20f254a3b7c7
prepare: sha256:5cfba199f4348e98
promote: sha256:e4f8b18462e8da1d
quick-merge: sha256:ea4648413feb1eca
rc-cut: sha256:3bbf726eae07fe4e
reassess: sha256:26b90046cd97aef2
reassess-stats: sha256:17acede01fa2f929
reproducer: sha256:573d724afd671f6f
sentiment: sha256:c325db1d99634a51
stale-sweep: sha256:d2a78aaabcc57f26
stats: sha256:6f0c574efb46849a
triage: sha256:9b2993211bdc0e80
verify-rc: sha256:eb35d109439cd24b
vote-draft: sha256:3b74a3ec69e4b358
vote-tally: sha256:b0b69aea022307a5
welcome: sha256:a61c6575d69da08a