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 7320484 refactor(security-issue-sync): verify advisory-shipped from
the users@ archive, not the tracker body (#431)
7320484 is described below
commit 7320484b4bc3dd59f09a43bf5a20f865d935542d
Author: Jarek Potiuk <[email protected]>
AuthorDate: Mon Jun 1 18:33:02 2026 +0200
refactor(security-issue-sync): verify advisory-shipped from the users@
archive, not the tracker body (#431)
Bulk-mode gather subagents could conclude "advisory not yet sent /
parked" from the tracker body's empty *Public advisory URL* field and
missing `announced` label, even when the advisory had already shipped
to users@ and the CVE was already live on cve.org. That false negative
strands announced trackers open on their milestone (observed on two
real trackers whose advisories shipped but whose body fields lagged a
sync behind).
Make the users@ archive search + cve.org publication state the
authoritative advisory-shipped signal in the bulk-mode subagent
contract, and add advisory_shipped / advisory_url / cve_published to
the subagent report shape so the orchestrator buckets such trackers
into the Step 14->15 close-out regardless of body-field lag.
Generated-by: Claude Code (Opus 4.8)
---
.claude/skills/security-issue-sync/bulk-mode.md | 31 ++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/.claude/skills/security-issue-sync/bulk-mode.md
b/.claude/skills/security-issue-sync/bulk-mode.md
index e3104a4..e4572f7 100644
--- a/.claude/skills/security-issue-sync/bulk-mode.md
+++ b/.claude/skills/security-issue-sync/bulk-mode.md
@@ -202,6 +202,27 @@ concurrently, which is exactly what the sync needs.
- Read the issue, its closing-PR references, the fixing PR state
and milestone, the originating Gmail thread, and mine comments
and mail for the signals in the table in Step 1d.
+ - **Determine advisory-shipped state from the authoritative
+ source, never the tracker body.** For any tracker carrying
+ `cve allocated`, search the public `<users-list>` archive for
+ the CVE ID (PonyMail `search_list` on the users list, per
+ [`tools/ponymail/`](../../../tools/ponymail/); Gmail fallback)
+ and cross-check the cve.org publication state (per
+ [`tools/cve-org/`](../../../tools/cve-org/)). A `<users-list>`
+ archive hit authored by the release manager **is** the
+ advisory-shipped signal, and its `lists.apache.org/thread/<id>`
+ permalink is the *Public advisory URL*. The tracker body's
+ *Public advisory URL* field and `announced` label are a
+ **lagging mirror**: once populated they confirm shipment, but an
+ empty value is **never** proof the advisory did not ship — those
+ fields are only written on the *next* sync, after the release
+ manager sends the advisory out-of-band. A tracker still at
+ `fix released` with an empty *Public advisory URL* whose CVE is
+ already live on cve.org is a **Step 14→15 close-out**, not a
+ parked tracker; report it as such (see the `advisory_shipped` /
+ `advisory_url` fields below) so the orchestrator buckets it into
+ the close-out batch rather than leaving it stranded open on its
+ milestone.
- Return a **compact structured report** — not a freeform
narrative. The exact shape is below.
@@ -331,6 +352,9 @@ fix_pr:
merged_at: <ISO8601 or null>
milestone: <PR milestone title or null>
release_shipped: true | false | unknown
+advisory_shipped: true | false | unknown # from the <users-list> archive
search for the CVE ID — NOT derived from the tracker body
+advisory_url: <lists.apache.org/thread/... permalink, or null> # the archive
permalink when advisory_shipped is true
+cve_published: true | false | unknown # cve.org publication state (MITRE
API), independent of the tracker body
reporter:
name: <name or null>
email: <email or null>
@@ -353,7 +377,12 @@ notes: <free-form one-to-three sentences, only if
something does not fit above>
The orchestrator uses the structured fields to produce the merged
proposal table and relies on `blockers` to flag issues that cannot
be resolved without user input (for example a missing Gmail thread
-or an ambiguous credit line).
+or an ambiguous credit line). When `advisory_shipped` (or
+`cve_published`) is true while the tracker is still labelled
+`fix released`, the orchestrator buckets the tracker into the Step
+14→15 close-out **regardless** of whether the body's *Public advisory
+URL* field is still empty — the archive/cve.org signal is
+authoritative and the empty body field is just sync lag.
### Hard rules for bulk mode