This is an automated email from the ASF dual-hosted git repository.

potiuk pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow-steward.git


The following commit(s) were added to refs/heads/main by this push:
     new e501d82  refactor(skills): migrate config/user.md references to 
.apache-steward-overrides/user.md (#45)
e501d82 is described below

commit e501d8200c7228ae6c543ae5297295a5d683b639
Author: André Ahlert <[email protected]>
AuthorDate: Mon May 4 11:18:14 2026 -0300

    refactor(skills): migrate config/user.md references to 
.apache-steward-overrides/user.md (#45)
    
    The framework adopted a snapshot+overrides architecture in PR #38.
    Under that design, per-user configuration (PMC status, local clone
    paths, optional tool backends) lives in the adopter repo, not in the
    framework. The security skills, however, still referenced the legacy
    config/user.md path from the pre-snapshot architecture.
    
    Changes:
    - Update 4 security skills (sync, import, fix, cve-allocate) to read
      from .apache-steward-overrides/user.md instead of config/user.md.
    - Add Step 9b to setup-steward/adopt.md to scaffold a user.md
      template during first-time adoption.
    - Update docs and tool adapters that referenced config/user.md:
      onboarding, prerequisites, gmail, ponymail, fix-workflow template.
    
    The fallback-interactive behaviour is preserved: when the file is
    missing, skills ask the user and offer to save the answer back.
    
    Fixes the structural gap where the framework docs described a config/
    layer that was never created in the snapshot-based architecture.
    
    Signed-off-by: André Ahlert <[email protected]>
---
 .claude/skills/security-cve-allocate/SKILL.md |  2 +-
 .claude/skills/security-issue-fix/SKILL.md    | 10 ++---
 .claude/skills/security-issue-import/SKILL.md |  6 +--
 .claude/skills/security-issue-sync/SKILL.md   | 10 ++---
 .claude/skills/setup-steward/adopt.md         | 57 +++++++++++++++++++++++++++
 docs/prerequisites.md                         |  2 +-
 docs/security/new-members-onboarding.md       | 20 +++++-----
 projects/_template/fix-workflow.md            |  2 +-
 tools/gmail/draft-backends.md                 |  4 +-
 tools/gmail/operations.md                     |  2 +-
 tools/gmail/tool.md                           |  2 +-
 tools/ponymail/tool.md                        |  2 +-
 12 files changed, 87 insertions(+), 32 deletions(-)

diff --git a/.claude/skills/security-cve-allocate/SKILL.md 
b/.claude/skills/security-cve-allocate/SKILL.md
index 39652c4..77b91d5 100644
--- a/.claude/skills/security-cve-allocate/SKILL.md
+++ b/.claude/skills/security-cve-allocate/SKILL.md
@@ -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
diff --git a/.claude/skills/security-issue-fix/SKILL.md 
b/.claude/skills/security-issue-fix/SKILL.md
index b25ead4..43d2424 100644
--- a/.claude/skills/security-issue-fix/SKILL.md
+++ b/.claude/skills/security-issue-fix/SKILL.md
@@ -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;
@@ -313,14 +313,14 @@ 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.
 
@@ -328,7 +328,7 @@ touching any files:
    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
diff --git a/.claude/skills/security-issue-import/SKILL.md 
b/.claude/skills/security-issue-import/SKILL.md
index 1ff9f17..63bd4df 100644
--- a/.claude/skills/security-issue-import/SKILL.md
+++ b/.claude/skills/security-issue-import/SKILL.md
@@ -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
@@ -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:
 
@@ -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
diff --git a/.claude/skills/security-issue-sync/SKILL.md 
b/.claude/skills/security-issue-sync/SKILL.md
index e700eaf..8364ce4 100644
--- a/.claude/skills/security-issue-sync/SKILL.md
+++ b/.claude/skills/security-issue-sync/SKILL.md
@@ -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
@@ -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)
@@ -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
@@ -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
@@ -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
diff --git a/.claude/skills/setup-steward/adopt.md 
b/.claude/skills/setup-steward/adopt.md
index b1680e5..2e3aa0c 100644
--- a/.claude/skills/setup-steward/adopt.md
+++ b/.claude/skills/setup-steward/adopt.md
@@ -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
diff --git a/docs/prerequisites.md b/docs/prerequisites.md
index a45ae1f..76930ff 100644
--- a/docs/prerequisites.md
+++ b/docs/prerequisites.md
@@ -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
diff --git a/docs/security/new-members-onboarding.md 
b/docs/security/new-members-onboarding.md
index 007ece8..05ed5ab 100644
--- a/docs/security/new-members-onboarding.md
+++ b/docs/security/new-members-onboarding.md
@@ -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
@@ -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
@@ -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
diff --git a/projects/_template/fix-workflow.md 
b/projects/_template/fix-workflow.md
index 0a87bb7..9a77f12 100644
--- a/projects/_template/fix-workflow.md
+++ b/projects/_template/fix-workflow.md
@@ -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
diff --git a/tools/gmail/draft-backends.md b/tools/gmail/draft-backends.md
index 92fffe3..5457528 100644
--- a/tools/gmail/draft-backends.md
+++ b/tools/gmail/draft-backends.md
@@ -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 |
@@ -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`.
 
diff --git a/tools/gmail/operations.md b/tools/gmail/operations.md
index 0d75e26..2252d1d 100644
--- a/tools/gmail/operations.md
+++ b/tools/gmail/operations.md
@@ -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.
diff --git a/tools/gmail/tool.md b/tools/gmail/tool.md
index d3ce70f..1067049 100644
--- a/tools/gmail/tool.md
+++ b/tools/gmail/tool.md
@@ -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).
diff --git a/tools/ponymail/tool.md b/tools/ponymail/tool.md
index d28ec4d..1015476 100644
--- a/tools/ponymail/tool.md
+++ b/tools/ponymail/tool.md
@@ -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 —

Reply via email to