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
2 changes: 1 addition & 1 deletion .claude/skills/security-cve-allocate/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ Before touching the tracker, verify:
tell the user up front to install `uv` (one command:
`curl -LsSf https://astral.sh/uv/install.sh | sh`).
3. **Resolve the user's PMC status.** First try to read it from
[`config/user.md`](../../../config/user.md) → `role_flags.pmc_member`
`.apache-steward-overrides/user.md` → `role_flags.pmc_member`
(see [`config/README.md`](../../../config/README.md) for the config
layer explainer). If the file exists and the flag is set, use that
value and surface it in the Step 0 recap (*"loaded config for
Expand Down
10 changes: 5 additions & 5 deletions .claude/skills/security-issue-fix/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ tracker only to discover you cannot push the branch.
directly — a fork is required.
- **A clean local clone of `<upstream>`** reachable from the
agent's working directory. The path comes from the user's
[`config/user.md`](../../../config/user.md)
`.apache-steward-overrides/user.md`
`environment.upstream_clone`; if the file or key is missing,
the skill asks the user interactively and offers to save the
answer back into `config/user.md` so the next run is silent. The
answer back into `.apache-steward-overrides/user.md` so the next run is silent. The
skill does **not** guess filesystem layouts — there is no
hard-coded search path. The clone must:
- have a remote pointing at your fork;
Expand Down Expand Up @@ -313,22 +313,22 @@ change; it writes into a local clone of `<upstream>`. Before
touching any files:

1. Resolve the clone path from the user's
[`config/user.md`](../../../config/user.md)
`.apache-steward-overrides/user.md`
`environment.upstream_clone` (see
[`config/README.md`](../../../config/README.md) for the config
layer explainer). If the file is missing, the key is unset, or
the stored path does not resolve to a git repo with a remote
pointing at `<upstream>` or the user's fork, **ask the user
for the path interactively** and offer to save their answer back
into `config/user.md` so the next run is silent. Do **not**
into `.apache-steward-overrides/user.md` so the next run is silent. Do **not**
probe hard-coded paths like `~/code/airflow` — filesystem layouts
vary per user and a wrong guess masks a misconfigured clone.

2. Check `git remote -v`. Identify which remote is the **user's fork**
and which is the upstream `<upstream>`. Per the rule in
[`<upstream>/AGENTS.md`](https://github.com/<upstream>/blob/main/AGENTS.md),
push only to the user's fork, never to `<upstream>` directly.
If the user's `config/user.md` has
If the user's `.apache-steward-overrides/user.md` has
`environment.upstream_fork_remote` set, prefer that remote
name; otherwise use the first non-`origin` remote that looks like
a fork. If no fork remote is configured, **stop and ask the user
Expand Down
6 changes: 3 additions & 3 deletions .claude/skills/security-issue-import/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Before touching any candidate thread, verify:
(401, 403, 404), stop and tell the user to log in with
`gh auth login` or get added to `<tracker>`.
3. **PonyMail MCP status** (opt-in; primary read path when
enabled) — read `config/user.md` → `tools.ponymail`. If
enabled) — read `.apache-steward-overrides/user.md` → `tools.ponymail`. If
`enabled: true`, call `mcp__ponymail__auth_status()` once and
record `ponymail_enabled` + `ponymail_authenticated` in the
skill's observed-state bag. **When authenticated, downstream
Expand Down Expand Up @@ -246,7 +246,7 @@ lags the inbox by minutes-to-hours for brand-new messages, which
is exactly the window this skill most cares about.

When PonyMail MCP is enabled and authenticated (Step 0) **and**
`security@<project>.apache.org` is in `config/user.md` →
`security@<project>.apache.org` is in `.apache-steward-overrides/user.md` →
`tools.ponymail.private_lists`, run the archive as a **paired
authoritative check** against the Gmail result set:

Expand Down Expand Up @@ -550,7 +550,7 @@ in short:

**Backend selection.** When PonyMail MCP is enabled and
authenticated (Step 0) **and** `security@<project>.apache.org`
is in `config/user.md` → `tools.ponymail.private_lists`,
is in `.apache-steward-overrides/user.md` → `tools.ponymail.private_lists`,
**PonyMail MCP is the primary backend for this step**:

```text
Expand Down
10 changes: 5 additions & 5 deletions .claude/skills/security-issue-sync/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ Before reading any tracker state, verify:
`<tracker>`. A 401/403/404 means the user needs
`gh auth login` or collaborator access.
3. **PonyMail MCP status** (opt-in; primary read path when
enabled) — read `config/user.md` → `tools.ponymail`. If
enabled) — read `.apache-steward-overrides/user.md` → `tools.ponymail`. If
`enabled: true`, call `mcp__ponymail__auth_status()` once. Three
outcomes:
- **Authenticated session** — record
Expand All @@ -371,7 +371,7 @@ Before reading any tracker state, verify:
user who set `enabled: true` in config but has not
registered the MCP in Claude Code's `mcpServers` block gets
the Gmail-only path without a noisy error.
When `config/user.md` sets `enabled: false` or omits the
When `.apache-steward-overrides/user.md` sets `enabled: false` or omits the
`ponymail` block entirely, skip this sub-step; Gmail is the
only read backend. See
[`tools/ponymail/tool.md`](../../../tools/ponymail/tool.md)
Expand Down Expand Up @@ -475,7 +475,7 @@ set is the strongest signal for what milestone the security issue should carry.

**Backend selection.** When Step 0 recorded
`ponymail_authenticated: true` **and**
`security@<project>.apache.org` is in `config/user.md` →
`security@<project>.apache.org` is in `.apache-steward-overrides/user.md` →
`tools.ponymail.private_lists`, **PonyMail MCP is the primary
backend for this step** — the archive is authoritative and
reaches back further than any single user's Gmail window. Run the
Expand Down Expand Up @@ -613,7 +613,7 @@ it for: historical lookups, cross-list fan-outs
reliably find messages older than ~90 days. Gmail is the fallback
when (a) PonyMail is not enabled / not authenticated, (b) a
private list the query targets is not in
`config/user.md` → `tools.ponymail.private_lists`, or (c) the
`.apache-steward-overrides/user.md` → `tools.ponymail.private_lists`, or (c) the
signal is *just-arrived inbound mail* where Gmail's inbox latency
beats the archive's indexing delay. The per-issue budget is
≤ 2 archive searches (whichever backend) plus ≤ 3 Gmail inbox
Expand Down Expand Up @@ -720,7 +720,7 @@ uses for reporter threads. That is the load-bearing signal path.

**Backend selection.** When PonyMail MCP is enabled and
authenticated (Step 0) **and** `security@<project>.apache.org` is
in `config/user.md` → `tools.ponymail.private_lists`, **PonyMail
in `.apache-steward-overrides/user.md` → `tools.ponymail.private_lists`, **PonyMail
MCP is the primary path** for reviewer-comment archive queries:

```text
Expand Down
57 changes: 57 additions & 0 deletions .claude/skills/setup-steward/adopt.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,63 @@ Framework changes go via PR to `apache/airflow-steward`.
This directory is **committed** (overrides ship with the
adopter repo).

## Step 9b — Scaffold `.apache-steward-overrides/user.md` (FRESH only)

Create `<repo-root>/.apache-steward-overrides/user.md` with a
project-agnostic template. The security skills read this file at
run-time to resolve per-user preferences (PMC status, local clone
paths, optional tool backends). If the file is missing, the skills
fall back to interactive prompting and offer to save the answer
back into this file.

```markdown
# Per-user configuration for apache-steward

This file is committed in the adopter repo and holds preferences
that vary per developer (GitHub handle, local clone paths, optional
tool backends). It is **not** project-specific — those facts live in
`<project-config>/project.md`. Fill in the fields that apply to your
setup; the skills skip any block that is missing or marked `TODO`.

## `role_flags`

- `pmc_member: TODO` — set to `true` if you are a PMC member of the
adopting project. Used by `security-cve-allocate` to decide whether
you can submit the CVE allocation form directly or need to relay
the request to a PMC member.

## `environment`

- `upstream_clone: TODO` — absolute path to your local clone of the
public `<upstream>` repo. Used by `security-issue-fix` when it
writes changes and opens PRs. The skill validates that the clone
has a remote pointing at your fork before proceeding.
- `upstream_fork_remote: TODO` — name of the git remote that points
at your personal fork (e.g. `fork`, `your-github-handle`). If
omitted, the skill uses the first non-`origin` remote that looks
like a fork. Explicitly setting this avoids ambiguity when you
have multiple remotes.

## `tools`

### `ponymail`

- `enabled: false` — set to `true` if you have registered the
PonyMail MCP in your Claude Code `mcpServers` block. When enabled
and authenticated, the security skills use PonyMail as the primary
read backend for mailing-list archive queries; Gmail remains the
fallback for just-arrived inbound mail and the only backend for
draft composition.
- `private_lists: []` — list of private mailing-list addresses that
PonyMail should query (e.g. `["security@<project>.apache.org"]`).
Only used when `enabled: true`.
```

Show the file to the user and offer to fill in the `TODO` fields
interactively (one prompt per field, skipping any the user does not
yet know). After the interactive fill, write the file to disk and
git-add it.

## Step 10 — Worktree-aware post-checkout hook (FRESH only)

Install
Expand Down
2 changes: 1 addition & 1 deletion docs/prerequisites.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ checks and tests, pushes a branch to your fork, and opens a PR via
`gh pr create --web`. You need:

- a clean clone of `<upstream>` reachable from the agent's working
directory — the path comes from `config/user.md →
directory — the path comes from `.apache-steward-overrides/user.md →
environment.upstream_clone`, set interactively the first time
you run the skill;
- the adopting project's dev toolchain installed per its contributing
Expand Down
20 changes: 9 additions & 11 deletions docs/security/new-members-onboarding.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,12 @@ week. A good starting routine:
name — leaves the private channels.
6. **Set up your per-user config** if (and only if) you plan to run
the agent skills. Copy
[`config/user.md.example`](config/user.md.example) to
`config/user.md` and fill in your GitHub handle, email, PMC status,
and (for remediation-developer work) the path to your local
`<upstream>` clone. The full tutorial is in
[`config/README.md`](config/README.md) — it takes under five
minutes. You can skip this step on day one; skills fall back to
runtime prompts when `config/user.md` is missing.
`.apache-steward-overrides/user.md` (scaffolded automatically when
the project adopts steward) and fill in your GitHub handle, email,
PMC status, and (for remediation-developer work) the path to your
local `<upstream>` clone. You can skip this step on day one;
skills fall back to runtime prompts when
`.apache-steward-overrides/user.md` is missing.

You can start commenting on issues on day one. Just commenting,
voting on validity, suggesting severity — those are valuable
Expand Down Expand Up @@ -193,7 +192,7 @@ remediation-developer turn:
pre-fix sync, reads the discussion on the tracker to build a fix
plan, shows you the plan, and — only after you confirm — writes the
change in your local `<upstream>` clone (path from
`config/user.md → environment.upstream_clone`), runs the local
`.apache-steward-overrides/user.md → environment.upstream_clone`), runs the local
checks and tests, and opens a public `gh pr create --web` PR from
your fork. Every public surface (commit message, branch name, PR
title, PR body, newsfragment) is scrubbed for CVE / the tracker
Expand Down Expand Up @@ -230,9 +229,8 @@ shape the team are small enough to read in one sitting:
- [`README.md`](../../README.md) — the end-to-end handling process.
- [`<project-config>/canned-responses.md`](<project-config>/canned-responses.md) — reply templates.
- [`AGENTS.md`](../../AGENTS.md) — agent-facing conventions and confidentiality rules.
- [`config/README.md`](config/README.md) — how the per-project and
per-user configuration layers work, with a tutorial for your own
`config/user.md`.
- `.apache-steward-overrides/user.md` — per-user configuration (PMC status,
local clone paths, optional tool backends) scaffolded during adoption.
- [`<project-config>/`](<project-config>/) — project-specific content
(roster, release trains, security model, scope labels, milestones,
canned responses, fix-workflow specifics) — lives in the adopter's
Expand Down
2 changes: 1 addition & 1 deletion projects/_template/fix-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ TODO: list the project's developer toolchain. Example shape:

The `security-issue-fix` skill assumes a clean clone of `<upstream>`
reachable from the agent's working directory (path from
`config/user.md → environment.upstream_clone`), with a remote named
`.apache-steward-overrides/user.md → environment.upstream_clone`), with a remote named
for the user's GitHub fork that `gh pr create` can push to.

## Backport labels
Expand Down
4 changes: 2 additions & 2 deletions tools/gmail/draft-backends.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
# Gmail drafting backends

The skills create Gmail drafts via one of two backends, selected by the
user in [`config/user.md`](../../config/user.md) under
user in `.apache-steward-overrides/user.md` under
`tools.gmail.draft_backend`:

| Backend | Value | `threadId` attach? | Setup |
Expand Down Expand Up @@ -70,7 +70,7 @@ on disk, the skills should always use them. Resolution:

1. **Probe for `oauth_curl` credentials** in this order:
- `tools.gmail.oauth_credentials_path` from
[`config/user.md`](../../config/user.md) when set;
`.apache-steward-overrides/user.md` when set;
- the `$GMAIL_OAUTH_CREDENTIALS` environment variable;
- the default path `~/.config/apache-steward/gmail-oauth.json`.

Expand Down
2 changes: 1 addition & 1 deletion tools/gmail/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ only fetch bodies for the narrow set that actually warrants it
### Drafting backends

Draft creation runs through one of two backends, selected by the user
in [`config/user.md`](../../config/user.md) under
in `.apache-steward-overrides/user.md` under
`tools.gmail.draft_backend`. The full comparison and rationale live
in [`draft-backends.md`](draft-backends.md); the call shape per
backend is here.
Expand Down
2 changes: 1 addition & 1 deletion tools/gmail/tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ cannot compose reporter replies.

**Role when PonyMail MCP is opted into.** When a user sets
`tools.ponymail.enabled: true` in their
[`config/user.md`](../../config/README.md) and authenticates the
`.apache-steward-overrides/user.md` and authenticates the
MCP, PonyMail becomes the primary read backend for archive
queries (reporter-thread lookups, reviewer-comment searches,
`users@` / `dev@` archive scans, prior-rejection precedents).
Expand Down
2 changes: 1 addition & 1 deletion tools/ponymail/tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ The two are **not** interchangeable today. Specifically:

**Primary vs. fallback.** When a project declares both tools in
its manifest **and** the user opts into PonyMail MCP in
`config/user.md`, **PonyMail MCP is the primary read backend** for
`.apache-steward-overrides/user.md`, **PonyMail MCP is the primary read backend** for
archive queries (reporter-thread lookups, reviewer-comment
searches, advisory-URL scans, `[RESULT][VOTE]` attribution,
prior-rejection precedent searches). Gmail is the fallback —
Expand Down
Loading