Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .claude/skills/allocate-cve/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ confirm. The only action the skill performs unilaterally is
**reading** the tracker state and printing the allocation recipe for
the user to click through.

**Golden rule — only Apache Airflow PMC members can allocate CVEs.**
**Golden rule — only members of the project's PMC can allocate CVEs.**
The ASF Vulnogram form at `https://cveprocess.apache.org/allocatecve`
requires ASF OAuth with PMC-level access on the Airflow project. The
requires ASF OAuth with PMC-level access on the adopting project. The
full allocation mechanics (form-fill recipe, PMC-gated access, form
fields, fatal mis-allocation, after-allocation wire-back) live in
[`tools/vulnogram/allocation.md`](../../../tools/vulnogram/allocation.md);
Expand All @@ -61,8 +61,8 @@ the per-project URL templates live in
This is not something the skill can work around — a non-PMC user who
clicks *Allocate* sees the button grey out.

The current Airflow PMC roster lives on the ASF project page:
<https://projects.apache.org/committee.html?airflow>. Authoritative
The current PMC roster lives on the project's ASF committee page
(`https://projects.apache.org/committee.html?<project>`). Authoritative
GitHub handles for the subset of PMC members who also sit on the
security team are listed in
[`<project-config>/release-trains.md`](../../../<project-config>/release-trains.md)
Expand Down Expand Up @@ -113,7 +113,7 @@ anything else.
required if the tracker carries a reporter thread that needs a
status-update draft (Step 5).
- **A PMC member on call** — the Vulnogram allocation form is
PMC-gated. If the user is not on the Airflow PMC, the skill
PMC-gated. If the user is not on the project's PMC, the skill
still runs: it produces a relay message for a PMC member to
click through instead of stopping.

Expand All @@ -130,7 +130,7 @@ Before touching the tracker, verify:

1. **`gh` is authenticated** —
`gh api repos/<tracker> --jq .name` must return
`airflow-s`. A 401/403/404 means the user needs `gh auth login`
`<tracker>`. A 401/403/404 means the user needs `gh auth login`
or collaborator access; stop.
2. **`uv` is on the PATH** — `uv --version`. Without it the Step 4
CVE-JSON regeneration would fail silently mid-flow; better to
Expand Down Expand Up @@ -580,7 +580,7 @@ presenting.
nothing more. Do not try to automate the form fill — the ASF CVE
tool is ASF-OAuth-gated and agent automation of CNA allocation is
explicitly out of scope.
- **Only an Airflow PMC member can allocate.** The Vulnogram
- **Only a project PMC member can allocate.** The Vulnogram
allocation button is PMC-gated. If the user running this skill is
not a PMC member, the recipe is a **relay message** they post for
a PMC member to act on, not a form they can fill themselves.
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/deduplicate-security-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ in `README.md`.
## Step 0 — Pre-flight check

1. `gh api repos/<tracker> --jq .name` returns
`airflow-s`.
`<tracker>`.
2. Both issue numbers resolve —
`gh issue view <kept> --repo <tracker> --json number`
and the same for `<dropped>` — before any write.
Expand Down
20 changes: 10 additions & 10 deletions .claude/skills/fix-security-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ description: |
implementation plan, waits for explicit user confirmation, writes the
change in the user's local <upstream> clone, runs the local checks
and tests, opens a PR from the user's fork via `gh pr create --web`,
and updates the airflow-s tracking issue with the new PR link and any
and updates the <tracker> tracking issue with the new PR link and any
relevant labels. Public PR content is checked to make sure it does
**not** reveal the CVE, the security nature of the change, or any link
back to <tracker>.
Expand Down Expand Up @@ -138,7 +138,7 @@ continue.
1. **`gh` authenticated** —
`gh api repos/<tracker> --jq .name` and
`gh api repos/<upstream> --jq .name` both return. A 401/403
on the first means no airflow-s access; on the second it is a
on the first means no <tracker> access; on the second it is a
quota/auth issue — both require user action, stop.
2. **Fork exists and is pushable** —
`gh repo view <your-login>/airflow --json name --jq .name`
Expand Down Expand Up @@ -256,7 +256,7 @@ If **easily fixable**, extract and write down:
- the target branch (`main` almost always; a release branch only if
the user explicitly says so),
- any backport label that should be applied to the eventual PR, based
on the milestone on the `airflow-s` issue (the adopting project's
on the milestone on the `<tracker>` issue (the adopting project's
backport-label policy and current release branches live in
[`<project-config>/fix-workflow.md`](../../../<project-config>/fix-workflow.md#backport-labels)
and
Expand Down Expand Up @@ -330,7 +330,7 @@ verbatim.**
- **bad** (reveals security framing): `cve-2026-40690`,
`security-fix-218`, `vulnerable-deserialize-fix`.

Tracker identifiers on their own (e.g. `airflow-s-216`) are not
Tracker identifiers on their own (e.g. `<tracker>-216`) are not
flagged — they are public-safe identifiers per the
[Confidentiality of the tracker repository](../../../AGENTS.md#confidentiality-of-the-tracker-repository)
rule — but they also do not help anyone reading the branch URL
Expand Down Expand Up @@ -394,7 +394,7 @@ List:

### 4e. Backport label

If the `airflow-s` issue's milestone indicates a release branch that
If the `<tracker>` issue's milestone indicates a release branch that
has not yet been cut (e.g. `3.1.9`, `3.2.1`), note which
`backport-to-vX-Y-test` label the PR should carry so that the fix
lands on the intended patch release. If no backport is needed (the
Expand Down Expand Up @@ -520,7 +520,7 @@ only fires on merge, not on label application, so there is no race
with CI. Applying the label early ensures it is not forgotten.

**Grep the PR body one more time for forbidden terms** (`CVE`,
`airflow-s`, `vulnerability`, `security fix`, `advisory`, private
`<tracker>`, `vulnerability`, `security fix`, `advisory`, private
issue number, reporter name tied to a finding) before calling
`gh pr create --web`. If anything matches, abort and tell the user.

Expand All @@ -530,7 +530,7 @@ After the user submits the PR in the browser, capture the PR URL

---

## Step 9 — Update the airflow-s tracking issue
## Step 9 — Update the <tracker> tracking issue

Now that a public PR exists, update the private tracking issue:

Expand Down Expand Up @@ -565,7 +565,7 @@ Now that a public PR exists, update the private tracking issue:
The public `<upstream>` PR description and any follow-up public
comments must also obey the rule, but under the usual
public-surface confidentiality constraints (no `CVE-`,
`airflow-s`, *"security fix"*, etc. alongside the mention).
`<tracker>`, *"security fix"*, etc. alongside the mention).

2. **Update the issue body "PR with the fix" field** if it is empty
or points to a stale PR. Use `gh issue view --json body`, patch
Expand All @@ -575,7 +575,7 @@ Now that a public PR exists, update the private tracking issue:

3. **Maintain milestones and labels** — see the next section.

4. **Status update to the reporter** — if the airflow-s issue has an
4. **Status update to the reporter** — if the <tracker> issue has an
identified external reporter and the reporter has not yet been
told about the fix PR, delegate to the `sync-security-issue`
skill's "Status update to the reporter" category by re-running
Expand Down Expand Up @@ -720,7 +720,7 @@ Print a short recap:
- the branch name (in the user's fork),
- the list of files changed,
- the tests that were run and their results,
- the comment posted on the `airflow-s` issue,
- the comment posted on the `<tracker>` issue,
- the backport label that was applied (or a note that none was needed),
- the next step — typically *"wait for review; re-run
sync-security-issue after the PR merges to transition the issue
Expand Down
4 changes: 2 additions & 2 deletions .claude/skills/import-security-issue-from-pr/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ The first entry on the tracker's status rollup. Shape per
[`tools/github/status-rollup.md`](../../../tools/github/status-rollup.md):

```markdown
<!-- airflow-s status rollup v1 — all bot-authored status updates fold into this single comment. -->
<!-- <tracker> status rollup v1 — all bot-authored status updates fold into this single comment. -->
<details><summary><YYYY-MM-DD> · @<author-handle> · Import from PR (<scope>, <upstream>#<N>)</summary>

**Imported from public PR `<upstream>#<N>` on <YYYY-MM-DD>** (scope: `<scope>`, PR state: `<state>`).
Expand All @@ -391,7 +391,7 @@ This tracker was deliberately opened by the security team for a public fix that
Provenance: public PR <pr.url>, author `@<pr.author.login>`.
Extracted fields: scope=`<scope>`, *PR with the fix*=<pr.url>, *Remediation developer*=<pr.author.name>, *Affected versions*=`<per-scope shape>`, Severity=`Unknown`.

*Reporter credited as* intentionally left blank — public-PR imports do not credit the PR author as the CVE reporter (no responsible disclosure). See the [Reporter credit policy](https://github.com/<tracker>/blob/airflow-s/.claude/skills/import-security-issue-from-pr/SKILL.md#reporter-credit-policy-for-public-pr-imports) section of the skill for the rationale.
*Reporter credited as* intentionally left blank — public-PR imports do not credit the PR author as the CVE reporter (no responsible disclosure). See the [Reporter credit policy](https://github.com/<tracker>/blob/<tracker-default-branch>/.claude/skills/import-security-issue-from-pr/SKILL.md#reporter-credit-policy-for-public-pr-imports) section of the skill for the rationale.
```

Zero-whitespace rules from
Expand Down
12 changes: 6 additions & 6 deletions .claude/skills/import-security-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ candidate Gmail threads:

| Selector | Resolves to |
|---|---|
| `import new` (default) | every security@ thread received in the last **14 days** that has not yet been imported as an airflow-s issue and has not already been answered-and-closed on-thread |
| `import new` (default) | every security@ thread received in the last **14 days** that has not yet been imported as an <tracker> issue and has not already been answered-and-closed on-thread |
| `import since:YYYY-MM-DD` | every security@ thread received since the given date that is not yet imported |
| `import thread:<id>` | the single Gmail thread with that `threadId` — useful for re-importing after a manual discard, or for picking up a single message the automatic scan missed |
| `import last 30d` / `import all` / `import last 90d` (explicit request only) | a wider sweep — use when the skill has not been run in a while or the user is doing a backlog catch-up. The `all` alias is 90 days. |
Expand Down Expand Up @@ -257,7 +257,7 @@ most threads will be filtered out at Step 2.

---

## Step 2 — Deduplicate against existing airflow-s issues
## Step 2 — Deduplicate against existing <tracker> issues

For each candidate `threadId`, check whether that ID already appears in
an `<tracker>` issue body. The sync skill records each thread
Expand Down Expand Up @@ -323,7 +323,7 @@ check:
cannot review it"* / *"We do not consider this a
vulnerability"* / *"We do not consider this a security
issue"*
- *"Per the Airflow Security Model"* / *"documented in our
- *"Per the project's security model"* / *"documented in our
Security Model"* / *"this is by design"* / *"this is
expected behaviour"*
- *"This is explicitly out of scope"* / *"is explicitly
Expand Down Expand Up @@ -544,8 +544,8 @@ mailbox. The per-candidate budget is ≤ 2 archive searches

Hits whose author is on the security-team roster AND whose body
opens with a canned-response cue (*"Thank you for reporting …
this isn't a security issue"*, *"Per the Airflow Security
Model"*, *"This is expected behaviour for a Dag author"*, etc.)
this isn't a security issue"*, *"Per the project's security
model"*, *"This is documented / expected behaviour"*, etc.)
are prior rejections. Fetch each with
`mcp__claude_ai_Gmail__get_thread` (MINIMAL is enough when you
only need to confirm the canned-response shape; FULL_CONTENT is
Expand Down Expand Up @@ -1015,7 +1015,7 @@ For each confirmed `Report` / `ASF-security relay`:
`gh issue comment <N> --repo <tracker> --body-file <tmpfile>`:

```markdown
<!-- airflow-s status rollup v1 — all bot-authored status updates fold into this single comment. -->
<!-- <tracker> status rollup v1 — all bot-authored status updates fold into this single comment. -->
<details><summary><YYYY-MM-DD> · @<author-handle> · Import (<classification>, <reporter>)</summary>

**Imported from Gmail thread `<threadId>` on <YYYY-MM-DD>** (class: `<classification>`, reporter: `<reporter>`).
Expand Down
10 changes: 5 additions & 5 deletions .claude/skills/invalidate-security-issue/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ the close. Read the *Security mailing list thread* body field:
For `security@`-imported trackers, locate the Gmail `threadId`:

1. Read the rollup comment on the tracker (the first
`<details>` block with the `airflow-s status rollup v1`
`<details>` block with the `<tracker> status rollup v1`
marker). Look for `threadId` references in the *Provenance:*
line of the import entry.
2. If the rollup is missing or thin, fall back to a Gmail subject
Expand All @@ -197,7 +197,7 @@ Scan `tracker.comments[]` for posts that argue **why** the report
is not a security issue. Strong signals:

- Citations of the
[Apache Airflow Security Model](<security-model-url>)
[the project's security model](<security-model-url>)
(full URL, anchor links, paraphrases).
- Phrases like *"this is by design"*, *"out of scope"*,
*"documented behavior"*, *"requires X privileges already"*,
Expand Down Expand Up @@ -292,7 +292,7 @@ Reasoning summary in the [status rollup](#issuecomment-<rollup-id>); a draft rep
For PR-imported trackers, replace *"a draft reply to the reporter
is in Gmail awaiting review"* with *"no reporter notification
(PR-imported tracker — see the import-from-pr skill's
[Reporter credit policy](https://github.com/<tracker>/blob/airflow-s/.claude/skills/import-security-issue-from-pr/SKILL.md#reporter-credit-policy-for-public-pr-imports))"*.
[Reporter credit policy](https://github.com/<tracker>/blob/<tracker-default-branch>/.claude/skills/import-security-issue-from-pr/SKILL.md#reporter-credit-policy-for-public-pr-imports))"*.

The comment links must resolve once the rollup entry from Step 5e
has been posted (capture its URL and substitute before posting
Expand Down Expand Up @@ -416,11 +416,11 @@ upsert recipe). Shape:
- @<author>: > <quote 2> ([source](#issuecomment-<id>))
- ...

**Canned response selected:** *<canned section name>* in [`canned-responses.md`](https://github.com/<tracker>/blob/airflow-s/<project-config>/canned-responses.md#<anchor>).
**Canned response selected:** *<canned section name>* in [`canned-responses.md`](https://github.com/<tracker>/blob/<tracker-default-branch>/<project-config>/canned-responses.md#<anchor>).

**Reporter notification:** <one of:>
- **`security@`-imported:** Gmail draft `<draftId>` created on thread `<threadId>` — awaiting user review.
- **PR-imported:** none (no reporter; per [Reporter credit policy](https://github.com/<tracker>/blob/airflow-s/.claude/skills/import-security-issue-from-pr/SKILL.md#reporter-credit-policy-for-public-pr-imports)).
- **PR-imported:** none (no reporter; per [Reporter credit policy](https://github.com/<tracker>/blob/<tracker-default-branch>/.claude/skills/import-security-issue-from-pr/SKILL.md#reporter-credit-policy-for-public-pr-imports)).
- **Indeterminate import path:** none (flag from Step 2 surfaced; user explicitly chose silent close).

**Project board:** archived (item `<item-id>`).
Expand Down
Loading
Loading