Skip to main content

magpie-security-issue-import

Scan <security-list> for reports that have not yet been copied into <tracker> as tracking issues, present the proposed imports to the user, and — defaulting to *import unless the user rejects upfront* — create the tracking issues with the `Needs triage` project-board status and draft a receipt-of- confirmation reply to each reporter. This is the first step of the handling process: the entry point that converts an inbound email thread into a tracker the rest of the skills (security-issue-sync, security-issue-fix, generate-cve-json) operate on.

Informations de source

Dépôt
apache/airflow-steward
Dernière activité de la source
29 août 2026 à 19:20
Langue détectée de SKILL.md
anglais
Étoiles
87
Forks
85

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
magpie-security-issue-import
family
security
mode
Triage
description
Scan <security-list> for reports that have not yet been copied into <tracker> as tracking issues, present the proposed imports to the user, and — defaulting to *import unless the user rejects upfront* — create the tracking issues with the `Needs triage` project-board status and draft a receipt-of- confirmation reply to each reporter. This is the first step of the handling process: the entry point that converts an inbound email thread into a tracker the rest of the skills (security-issue-sync, security-issue-fix, generate-cve-json) operate on.
when_to_use
Invoke when a security team member says "import new reports", "check for unimported security@ messages", "import #<threadId>", or when they start a morning-triage sweep and want to see what has landed on security@ overnight. Also appropriate as a recurring check — the skill is cheap to run against the default 14-day Gmail window and a no-op when every recent thread is already tracked or already answered-and-closed on-thread. Use `import last 30d` / `import all` (= disclosure_governance.window_days, default 90d) for a wider backlog sweep when genuinely warranted.
argument-hint
[import] [last Nd|all] [skip threadId]
capability
capability:intake
license
Apache-2.0
<!-- Placeholder convention (see AGENTS.md#placeholder-convention-used-in-skill-files): <project-config> → adopting project's `.apache-magpie/` directory <tracker> → value of `tracker_repo:` in <project-config>/project.md <upstream> → value of `upstream_repo:` in <project-config>/project.md Before running any bash command below, substitute these with the concrete values from the adopting project's <project-config>/project.md. --> # security-issue-import This skill is the **on-ramp** of the security-issue handling process. It converts an inbound `<security-list>` email thread into an `<tracker>` tracking issue that follows the repo's issue template, then drafts the receipt-of-confirmation reply to the reporter. It never sends email. It never creates a tracker for a candidate the user has explicitly rejected. It never assumes a report is valid — the validity / invalid / CVE-worthy decision still happens later in the discussion on the created tracker (Step 3 of [`README.md`](../../README.md)). **Golden rule — propose, then default to import.** Every import this skill performs is a *proposal* that lists the candidate emails, the extracted fields, and the draft confirmation reply. The user's default disposition for any `Report` or forwarder-relayed candidate (the latter classified by the optional [`security-issue-import-via-forwarder`](../security-issue-import-via-forwarder/SKILL.md) sub-skill when `forwarders.enabled` is non-empty) is **"import as a new tracker landing in `Needs triage`"**; the user only has to type back when they want to *deviate* from that default — `skip NN` to reject a candidate upfront with no reply, or `NN:reject-with-canned <name>` to reject upfront *and* draft a specific canned negative-assessment / out-of-scope reply. A bare `all` (or no reply at all to the proposal — the user typing *"go"*, *"proceed"*, *"yes, all"*) means *"import every non-rejected candidate as proposed"*. The skill must still surface each candidate one-by-one in the proposal so the user can scan and override if needed; what the skill must *not* do is sit on a report waiting for an explicit per-candidate green light. The bias is toward landing trackers — a wrongly-imported report is cheap to close at Step 5 / 6 of the handling process; a wrongly-skipped one gets buried in the inbox and the reporter is left without a disposition. **Golden rule — rejection means no tracker, ever.** When the user rejects a candidate upfront — any of `skip NN`, `NN:reject-with-canned <name>`, an explicit *"reject 1"*, *"mark 1 invalid"*, *"don't import 1"*, or a `cancel` / `none` / *"hold off"* on the whole proposal — the skill **must not** create a tracker for that candidate. This holds even when the user also asks for a canned reply to be drafted: the draft is a courtesy to the reporter, the absence of a tracker is the disposition. There is no "create the tracker so the team can close it as invalid later" path; if the team has decided pre-triage that the report is invalid, the audit trail lives on the Gmail thread and on the `canned-responses.md` precedent, not in a tracker that exists only to be closed. A tracker is created **only** when the candidate is imported as a real `Report` (or a forwarder-relayed candidate classified by the [`security-issue-import-via-forwarder`](../security-issue-import-via-forwarder/SKILL.md) sub-skill) for triage. Non-import candidate classes (`automated-scanner`, `consolidated-multi-issue`, `media-request`, `spam`, `cross-thread-followup`, `cve-tool-bookkeeping`) keep the original "propose first, apply only on explicit confirm" rule — those never default to a tracker. **Golden rule — confidentiality.** The inbound thread on `<security-list>` is private. The skill may paste the email body verbatim into the created `<tracker>` tracking issue (that repo is also private). It must **never** paste the report content into a public surface — not into `<upstream>`, not into a public GHSA, not into any comment on a public repo. The same confidentiality rule documented in the "Confidentiality of `<tracker>`" section of [`AGENTS.md`](../../AGENTS.md) applies in full. **Golden rule — every `<tracker>` / `<upstream>` reference is clickable in the surface it lands on.** Whenever this skill emits a reference to a tracker issue, PR, or comment — the proposal shown to the user before import, the created tracker issue body (observed-state dump, sibling-tracker cross-links, prior-rejection cross-links, fix-already-public PR pointers), the receipt-of- confirmation draft email reply, the recap output — the reference must be one click away in whatever surface it lands on: - **On markdown surfaces** (the created tracker issue body, the draft email reply destined for the `<security-list>` thread, any markdown-rendered cross-link list): use the markdown link form per [`AGENTS.md` § *Linking tracker issues and PRs*](../../AGENTS.md#linking-tracker-issues-and-prs): - **Sibling `<tracker>` issue**: `[<tracker>#NNN](https://github.com/<tracker>/issues/NNN)` - **Public `<upstream>` PR** (e.g. fix-already-public match): `[<upstream>#NNN](https://github.com/<upstream>/pull/NNN)` - **Comment**: link to the `#issuecomment-<C>` anchor. - **On terminal surfaces** (the proposal shown to the user before import, the recap output): wrap the visible short form (`<tracker>#NNN`, `<upstream>#NNN`) in **OSC 8 hyperlink escape sequences** (`\e]8;;<URL>\e\\<short>\e]8;;\e\\`) so modern terminals (iTerm2, Kitty, GNOME Terminal, WezTerm, Windows Terminal, …) render the short text as clickable. Where OSC 8 is unsupported (CI logs, dumb terminals), fall back to printing the bare URL on the same line after the number. Bare `#NNN` with no link wrapper of any kind is never acceptable. The created tracker issue is read by the security team who drill into the cross-links to assess; the draft email reply lands on `<security-list>` where the reporter needs the references to be one click away. Both surfaces are private, but `<tracker>` URLs themselves are public-safe per the [Confidentiality of `<tracker>`](../../AGENTS.md#confidentiality-of-the-tracker-repository) rule — what stays private is the *contents* the link points at. **Self-check before posting any draft email or creating any tracker issue**: grep the body for bare `#\d+` / `<tracker>#\d+` tokens that aren't already inside a markdown link or an OSC 8 wrapper, and convert any match. --- ## Adopter overrides Before running the default behaviour documented below, this skill consults [`.apache-magpie-local/security-issue-import.md`](../../docs/setup/agentic-overrides.md) (personal, gitignored) and [`.apache-magpie-overrides/security-issue-import.md`](../../docs/setup/agentic-overrides.md) (committed, project-wide) in the adopter repo if it exists, and applies any agent-readable overrides it finds. See [`docs/setup/agentic-overrides.md`](../../docs/setup/agentic-overrides.md) for the contract — what overrides may contain, hard rules, the reconciliation flow on framework upgrade, upstreaming guidance. **Hard rule**: agents NEVER modify the snapshot under `<adopter-repo>/.apache-magpie/`. Local modifications go in the override file. Framework changes go via PR to `apache/magpie`. --- ## Snapshot drift Also at the top of every run, this skill compares the gitignored `.apache-magpie.local.lock` (per-machine fetch) against the committed `.apache-magpie.lock` (the project pin). On mismatch the skill surfaces the gap and proposes [`/magpie-setup upgrade`](../setup/upgrade.md). The proposal is non-blocking — the user may defer if they want to run with the local snapshot for now. See [`docs/setup/install-recipes.md` § Subsequent runs and drift detection](../../docs/setup/install-recipes.md#subsequent-runs-and-drift-detection) for the full flow. Drift severity: - **method or URL differ** → ✗ full re-install needed. - **ref differs** (project bumped tag, or `git-branch` local is behind upstream tip) → ⚠ sync needed. - **`svn-zip` SHA-512 mismatches the committed anchor** → ✗ security-flagged; investigate before upgrading. --- ## Prerequisites Before running, the skill needs: - **At least one configured mail-source backend** per [`<project-config>/project.md → Mail sources`](../../<project-config>/project.md#mail-sources). The skill treats every backend the same way — through the abstract operations defined in [`tools/mail-source/contract.md`](../../tools/mail-source/contract.md) (`list_recent_threads`, `read_thread`, `list_drafts`, `list_sent_since`, `create_draft`, `thread_url`). Reference adapters: [`gmail`](../../tools/gmail/tool.md) (full read+write), [`ponymail`](../../tools/ponymail/tool.md) (read-only ASF archive), [`imap`](../../tools/mail-source/imap/README.md) (stub), [`mbox`](../../tools/mail-source/mbox/README.md) (read-only offline archive — stub). To **discover new reports** the configured backends must collectively cover `list_recent_threads` + `read_thread`; to **draft the receipt-of-confirmation reply in Step 7** they must additionally cover `create_draft`. If no available backend covers `create_draft`, Step 7 surfaces a one-line *"no draft backend available"* note and the user composes the reply by hand. - **`gh` CLI authenticated** (`gh auth status` returns OK) with collaborator access to `<tracker>`. The skill calls `gh issue create` and `gh search issues` directly. See [Prerequisites for running the agent skills](../../docs/prerequisites.md#prerequisites-for-running-the-agent-skills) in `docs/prerequisites.md` for the overall setup. --- ## Step 0 — Pre-flight check Before touching any candidate thread, verify: 1. **Mail-source backends from `<project-config>/project.md → Mail sources` are available.** For each declared backend, run the backend's trivial health probe (per its adapter doc — Gmail: `mcp__claude_ai_Gmail__search_threads` with `pageSize: 1`; Ponymail: `mcp__ponymail__auth_status()`; IMAP: a `CAPABILITY` against the configured host; mbox: a `stat` on the archive path) and record the result in the skill's observed-state bag. Apply the [contract's resolution rule](../../tools/mail-source/contract.md#resolution-rule--which-backend-runs-an-operation) to figure out which backend serves which op for this run. * **`mandatory: yes` backend unavailable** → **stop immediately**. Surface *"mandatory mail-source backend `<name>` unavailable: `<reason>`; run aborted"*. The user fixes the auth / connection and re-invokes. * **`mandatory: no` backend unavailable** → continue with the remaining backends. If the resolution then leaves an operation with no provider (e.g. no available backend supports `create_draft`), the skill records *"no `<op>` backend available"* in the observed-state bag and the relevant downstream step omits that proposal with a clear hand-back to the user. * **Every declared backend healthy** → proceed; the observed-state bag records one provider per op so every dispatch later is unambiguous. 2. **`gh` is authenticated and has access.** Run `gh api repos/<tracker> --jq .name`; if it errors (401, 403, 404), stop and tell the user to log in with `gh auth login` or get added to `<tracker>`. 3. **(Reference-adopter guidance.)** The reference adopter lists `gmail` as primary `mandatory: yes` and — per the ASF default — `ponymail` as `mandatory: yes` too (`fallback` role for drafts, since PonyMail is read-only). So for the reference flow **both** backends are pre-flight prerequisites: a Gmail-MCP failure stops the run (drafts have no home), and a PonyMail-MCP miss — not registered, or registered but unauthenticated for the private `<security-list>` archive — stops it too, per item 1's `mandatory: yes` rule. Gmail handles reads of just-arrived inbound mail and all draft creation; PonyMail handles archive lookups (and is the primary read path when authenticated). Adopters whose `Mail sources` table sets `ponymail` to `mandatory: no` get the old degrade-quietly behaviour; the step-by-step references to "Gmail" below should be read as "the backend the resolution rule picked for the relevant op". 4. **Privacy-LLM contract.** This skill reads `<security-list>` bodies that may contain third-party PII the reporter discloses about other people. Run the gate-check first — non-zero exit is a hard stop: ```bash uv run --project <framework>/tools/privacy-llm/checker \ privacy-llm-check ``` The checker auto-locates `<project-config>/privacy-llm.md` (template at [`projects/_template/privacy-llm.md`](../../projects/_template/privacy-llm.md)) and verifies every entry in *Currently configured LLM stack* is approved per [`tools/privacy-llm/models.md`](../../tools/privacy-llm/models.md#the-pre-flight-check). In addition, verify: - `~/.config/apache-magpie/` is writable (the redactor's mapping file lives there); - the configured collaborator source is reachable via `gh api` (default: `<tracker>` from `project.md`); - the redaction-tuning knobs (collaborator exemption, enabled field types) are loaded into the skill's observed-state bag — they apply at filter-time below. Each subsequent body fetch in Steps 4 / 7 / 7g (template- field extraction, draft assembly, recap) follows the redact-after-fetch protocol in [`tools/privacy-llm/wiring.md`](../../tools/privacy-llm/wiring.md#redact-after-fetch-protocol); the receipt-of-confirmation draft assembly follows the [reveal-before-send protocol](../../tools/privacy-llm/wiring.md#reveal-before-send-protocol) when (and only when) the draft references a third-party identifier. 5. **Disclosure governance from `<project-config>/security-intake-config.md`.** If the file exists, read the `disclosure_governance` block and load these two keys into the observed-state bag for use in Step 7: - `reporter_acknowledgement_model` — `manual` | `auto` | `none`. Controls whether and how the receipt-of-confirmation reply is drafted (Step 7.4). - `window_days` — integer; the CVD window in calendar days, used as the disclosure deadline hint when composing the acknowledgement draft. If the file does not exist or the `disclosure_governance` block is absent, silently default to `reporter_acknowledgement_model: manual` and `window_days: 90`. A missing file is **not** a stop condition — adopters who have not yet created this config receive the same ASF defaults the skill has always applied. If a `mandatory: yes` mail-source backend or the `gh` check fails, do **not** proceed — the skill would fail mid-flow otherwise, leaving half-built state (a draft on the wrong thread, or a tracker with no receipt reply). Fail fast instead. `mandatory: no` backends degrade quietly per the contract's resolution rule. A privacy-llm pre-flight failure is also a hard stop — the redactor's mapping store and the collaborator-source lookup are both load-bearing for every subsequent body read. --- ## Inputs Before running, resolve the user's selector into a concrete set of 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 <tracker> issue and has not already been answered-and-closed on-thread |
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub