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 e40b093  import: consolidated receipt + Report (disposition converged) 
sub-class (#152)
e40b093 is described below

commit e40b093036295fe9380b01de822c43e8b6cbd303
Author: Jarek Potiuk <[email protected]>
AuthorDate: Thu May 14 13:05:02 2026 +0200

    import: consolidated receipt + Report (disposition converged) sub-class 
(#152)
    
    Two related improvements to security-issue-import:
    
    1. Consolidated receipt pattern (Step 5)
       When N>1 trackers are imported from the same reporter or same
       source thread within one skill run, propose a single
       consolidated receipt-of-confirmation reply listing all N
       tracker URLs, instead of N redundant receipts. Reporters get
       one credit-preference question, not N.
    
       Detection: same threadId in tracker provenance / same From:
       address / shared outer thread.
    
    2. Report (disposition converged) sub-class (Step 3)
       New classification row detected when the inbound thread
       already has a team-member substantive technical disposition
       AND the reporter has acknowledged it before the tracker was
       created. The tracker is still created (audit trail) but the
       canned receipt is skipped (it would be tone-deaf) and the
       rollup entry notes the converged state.
    
    Step 7 step 4 (draft creation) updated to skip both cases
    correctly with explicit cross-linking in the rollup entry.
    
    Motivation: both patterns surfaced in the 2026-05-14 import
    sweep against airflow-s/airflow-s:
    
      - Lokhesh Ujhoodha's 4 split-out GHSAs were correctly imported
        but the existing per-tracker receipt pattern would have sent
        him 4 redundant emails asking the credit-preference question
        4 times. We sent a single consolidated reply manually.
      - airflow-s#408 (edge3 worker JWT) had Omkhar Arasaratnam's
        Option-1-or-Option-2 disposition already agreed with Jarek
        on the inbound thread, with the docs PR already open. The
        canned receipt would have been tone-deaf. We skipped the
        draft manually.
    
    Codifying both patterns prevents the next operator from having
    to detect and handle these cases by hand.
    
    Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
---
 .claude/skills/security-issue-import/SKILL.md | 59 ++++++++++++++++++++++++++-
 1 file changed, 58 insertions(+), 1 deletion(-)

diff --git a/.claude/skills/security-issue-import/SKILL.md 
b/.claude/skills/security-issue-import/SKILL.md
index 9bbadba..5b58eb4 100644
--- a/.claude/skills/security-issue-import/SKILL.md
+++ b/.claude/skills/security-issue-import/SKILL.md
@@ -734,6 +734,7 @@ Decide the candidate's class from the root message:
 |---|---|---|
 | **Report**: a reporter describes a vulnerability | The body has a 
description, a PoC / reproduction steps, an impact claim. Sender is an external 
address (not `@apache.org`, not on the security-team roster in 
[`AGENTS.md`](../../../AGENTS.md)). | Proceed to Step 4. |
 | **ASF-security relay**: `[email protected]` forwarded a report from a 
reporter via the Foundation channel | Sender is `[email protected]`. The body 
almost always starts with the ASF forwarding preamble — *"Dear PMC, The 
security vulnerability report has been received by the Apache Security Team and 
is being passed to you for action …"* — and contains the original report 
underneath (often after a `====GHSA-…` separator when the report came in via 
GitHub Security Advisory). The pream [...]
+| **Report (disposition converged)**: a `Report` where the inbound thread has 
a team-member substantive technical disposition AND the reporter has 
acknowledged it | Same body shape as `Report`, but the thread has a team-member 
reply with one of: option-1/option-2 framing, *"we agree, opening fix PR"* 
disposition, a docs-clarification acknowledgement; AND the reporter has replied 
confirming the disposition; AND no further reporter follow-up is needed. 
Detected at Step 3 by reading the thr [...]
 | **CVE-tool bookkeeping**: an automated or human status-change notification 
on the ASF CVE tool | Sender is `[email protected]` (or one of the 
security-team members acting on behalf of the CVE tool). Subject matches one 
of: `"CVE-YYYY-NNNNN reserved for airflow"`, `"Comment added on 
CVE-YYYY-NNNNN"`, `"CVE-YYYY-NNNNN is now READY"`, `"CVE-YYYY-NNNNN is now 
PUBLIC"`, `"CVE-YYYY-NNNNN is now PUBLISHED"`, `"CVE-YYYY-NNNNN REJECTED"`, or 
a verbatim `"<state-change>"` line in the body poin [...]
 | **Automated scanner dump**: SAST/DAST tool output, CodeQL/Dependabot alert 
paste, a string of "issues" with no human PoC | Body is machine-generated, 
contains multiple unrelated findings, no explanation of Security Model 
violation | Surface as a candidate with class `automated-scanner` and **do 
not** propose auto-import. In Step 5 the skill proposes a Gmail draft from the 
*"Automated scanning results"* canned response in 
[`canned-responses.md`](../../../<project-config>/canned-response [...]
 | **Consolidated multi-issue report**: one email bundles ≥3 unrelated 
vulnerabilities | The root message has headings like *"Issue 1"*, *"Issue 2"*, 
each of which would be its own tracker | Surface class 
`consolidated-multi-issue`; do not auto-import. Propose the "Sending multiple 
issues in consolidated report" canned reply. |
@@ -845,6 +846,47 @@ Present all candidates as a single numbered proposal 
grouped by class:
   the user knows the filter is working but is not forced to scroll
   past them.
 
+### Consolidated receipts for multi-tracker imports
+
+When the resolved selector imports **N > 1 trackers from the same
+reporter or same source thread within one skill run**, propose a
+**single consolidated receipt-of-confirmation reply** that lists
+all N tracker URLs, instead of N separate receipts.
+
+**Detection conditions** (any one is sufficient):
+
+1. All N trackers reference the same Gmail `threadId` in their
+   "Split from" / "Imported from" provenance (e.g. one reporter
+   split a consolidated report into N separate GHSAs).
+2. All N trackers' inbound `From:` addresses are identical
+   (same reporter sent N independent reports in the same run).
+3. All N trackers were imported from N distinct threads that
+   *share an outer thread* (one reporter, one root, N
+   sub-threads).
+
+**Consolidated receipt shape**:
+
+- Reply on the **earliest** thread in the set (where the team
+  has an established channel with the reporter — typically the
+  consolidated-pre-split thread).
+- List each tracker URL + GHSA ID / equivalent identifier on
+  its own line, one per tracker.
+- Ask the credit-preference question **once**, applying to all
+  trackers in the set.
+- Use the *"Confirmation of receiving the report"* canned body
+  with a leading paragraph that lists the trackers.
+
+**Skip the per-tracker receipt drafts** when the consolidated
+one is created. Surface the consolidated draft in the proposal
+with explicit *"this reply covers trackers #N1, #N2, …"*
+framing so the user knows what's bundled.
+
+**Coherence check**: the consolidated reply must accurately
+characterise *each* tracker (not just the largest one). If the
+reports differ in subject material to the point where one
+consolidated reply would be confusing, fall back to the
+per-tracker receipt pattern; do not force the bundle.
+
 ### Canned-response discipline for negative-response drafts
 
 When the proposed disposition is a negative response — any of the
@@ -1118,7 +1160,22 @@ For each confirmed `Report` / `ASF-security relay`:
    workflow being correctly configured. The mutation is a no-op when
    the item is already on the board with the same Status.
 
-4. Draft the receipt-of-confirmation reply. **Apply the
+4. Draft the receipt-of-confirmation reply **unless one of**:
+
+   - The candidate class is `Report (disposition converged)` —
+     skip the draft entirely; note the converged disposition in
+     the rollup entry (step 5 below) with the exact prior thread
+     URL / message-id where the disposition was reached. Do not
+     create a Gmail draft for this tracker.
+   - The candidate is part of a **consolidated-receipt bundle**
+     (see Step 5's *"Consolidated receipts for multi-tracker
+     imports"* subsection) — the consolidated draft has already
+     been proposed and confirmed at Step 5; this per-tracker
+     draft is skipped because the bundle covers it. Cross-link
+     the consolidated draft's `<draftId>` in this tracker's
+     rollup entry.
+
+   When a draft is created (the default path), **apply the
    reveal-before-send protocol if (and only if) the rendered
    draft body carries any third-party identifiers** (per the
    Step 4 redact-after-fetch above; the receipt template

Reply via email to