Table of Contents generated with DocToc
The Vulnogram-side mechanics of maintaining a CVE record from allocation through publication. The generic handling process (steps 13–15 of ../../README.md) describes what has to happen; this file documents the Vulnogram-specific how.
Per-project URL templates live in ../../<project-config>/project.md (cve_tool_record_url_template, cve_tool_source_tab_url_template).
| Purpose | URL |
|---|---|
| Record page (human-readable + edit surface) | https://cveprocess.apache.org/cve5/<CVE-ID> |
#source tab (paste-the-JSON target) | https://cveprocess.apache.org/cve5/<CVE-ID>#source |
#json tab (rendered view of the stored JSON) | https://cveprocess.apache.org/cve5/<CVE-ID>#json |
#email tab (preview the advisory email before sending) | https://cveprocess.apache.org/cve5/<CVE-ID>#email |
The #email tab is the email-preview surface: it renders the advisory exactly as Vulnogram will send it to <users-list> and <announce-list> — same subject, same body, same recipient list. The release-manager checklist in the Release-manager checklist section below calls this out as a load-bearing checkpoint before hitting Send, because the preview surfaces formatting issues (truncation, broken markdown, missing patch links) that the JSON view does not.
The ASF CVE tool requires ASF OAuth; non-security-team members can see a record only after it has moved to PUBLIC (at which point the mirrored record at cve.org/CVERecord?id=<CVE-ID> is the canonical public link per the “Linking CVEs” section of ../../AGENTS.md).
#source paste flowThe generic release-manager workflow is “push the final CVE record and close the issue” (step 15). On Vulnogram that decomposes into:
#source tab at https://cveprocess.apache.org/cve5/<CVE-ID>#source.generate-cve-json tool on every sync — see the “Record-generator round trip” section below).#source form and Save.REVIEW to PUBLIC (or from DRAFT to REVIEW first if the record is still in the pre-review state).PUBLIC is the terminal state — Vulnogram pushes the record to cve.org via the CNA feed once the state lands there.
Vulnogram wraps every record in a CNA_private envelope whose state field drives the visibility + CNA-feed push. The four states the generic skills interact with:
| State | Set by | What it means |
|---|---|---|
DRAFT | Allocation (initial state post-allocation) | Record exists, ID is reserved, but content is still being filled in. Not visible on cve.org. |
REVIEW | Release manager once the content is complete | Ready for CNA review. ASF CNA reviewers may leave reviewer comments at this point (see “Reviewer-comment signal” below). Still not on cve.org. |
READY | Release manager once review feedback is addressed (or immediately after REVIEW if no feedback arrived) | Content is final and the record is staged for the advisory-send step. The advisory emails are dispatched from Vulnogram while in READY. Still not on cve.org. |
PUBLIC | Release manager as the terminal step | Record pushed to cve.org. World-readable. The generic tracking-issue lifecycle terminates at the close action once this state has been reached. |
DRAFT → REVIEW happens when all required fields are populated. The release manager moves the record to REVIEW after the first JSON paste, opening the window for CNA reviewers to leave comments.
REVIEW → READY happens once any reviewer comments have been addressed (via the body-field round-trip described in the Record-generator round trip section below), or immediately after REVIEW when no comments arrive. READY is the state Vulnogram expects when the release manager triggers the advisory email send.
READY → PUBLIC is a human release-manager click in Vulnogram after the advisory archive URL has been captured on the tracker. The generic sync-security-issue skill's Step 2b does not propose this transition — it is a Step 15 release-manager action. The publication-ready notification comment (see Release-manager checklist below) gives the RM the explicit go-ahead.
PUBLISHED is sometimes used as a synonym for PUBLIC in older Vulnogram documentation; the current action is literally labelled PUBLIC in the UI.
The generate-cve-json tool decides REVIEW versus DRAFT for the generated CNA_private.state field by inspecting whether the tracker's public-advisory-url body field is populated and whether a vendor-advisory reference landed in the generated references[]; see the _is_cna_ready_for_review helper in generate-cve-json/src/…/cve_json.py for the exact predicate. The READY state itself is set by hand in Vulnogram after the post-REVIEW body-field stabilisation — the generator does not emit READY directly because it cannot tell, from the tracker body alone, whether reviewer comments are still pending.
ASF CNA reviewers leave comments on REVIEW-state records. Those comments do not surface on the tracking issue directly — Vulnogram notifies by email to the project‘s security_list instead, with the CVE ID in the subject line. The sync-security-issue skill’s Step 1e reads those emails (Gmail search recipe lives in ../gmail/search-queries.md) and surfaces each open reviewer comment in Step 2b as an actionable body-field proposal on the tracker.
The round trip is: reviewer leaves comment in Vulnogram → Vulnogram emails security_list → sync skill reads email → sync skill proposes a tracker body-field update → user confirms → generate-cve-json re-emits the JSON attachment on the next sync → release manager re-pastes the updated JSON into #source → sync detects the comment is resolved on the next run. This indirection keeps the single source of truth on the tracking issue body (which the skills can read + write) rather than inside Vulnogram (which is OAuth-gated and not readable from skill context).
The cveprocess.apache.org/cve5/<CVE-ID>.json endpoint exists but is behind ASF OAuth and is not readable from agent-skill context — the sync-security-issue skill therefore never curls it; Gmail is the load-bearing signal source.
The generate-cve-json tool under generate-cve-json/ reads a tracker issue and emits a paste-ready CVE JSON record in the exact shape Vulnogram‘s #source tab accepts — CNA container, CNA_private envelope, sorted references, deterministic byte output. The tool’s behavioural contract lives in generate-cve-json/SKILL.md; the local-setup / test workflow lives in generate-cve-json/README.md.
Skills that update the tracker body call the tool with --attach so the embedded CVE JSON in the tracker body stays in lock-step with the body fields — every sync, every allocate-CVE wire-back, every dedupe merge regenerates the attachment. The release manager then has one canonical JSON to paste into #source at step 15.
When the <upstream> release containing a fix ships, the sync-security-issue skill swaps the tracker's pr merged label to fix released, reassigns the issue to the release manager, and posts an explicit release-manager hand-off comment on the tracker (the template body lives in release-manager-handoff-comment.md). The numbered checklist below is the standalone authoritative recipe the comment links to — keep them in lock-step when one changes.
The flow has two pastes in the common case (no reviewer comments) and three when reviewer comments arrive:
First paste — DRAFT → REVIEW. Open the #source tab on the CVE record. Copy the CVE JSON embedded in the tracking issue (regenerated by generate-cve-json on every sync — see Record-generator round trip above). Paste, Save. Move the record DRAFT → REVIEW via the Vulnogram UI.
(conditional) Re-paste after reviewer comments. ASF CNA reviewers may leave comments while the record sits in REVIEW (see Reviewer-comment signal above). The sync-security-issue skill detects them automatically and proposes matching body-field updates on the tracker; the security team confirms and the embedded JSON regenerates. Once the body has settled (no more pending reviewer-comment proposals), re-paste the regenerated JSON into #source and Save. Skip this step if no reviewer comments arrived (the common case for well-formed records).
Set READY. Vulnogram UI action — moves the record from REVIEW to READY and stages it for the advisory-send step.
Preview the advisory email on the #email tab. The preview renders the advisory exactly as Vulnogram will send it — same subject, same body, same recipient list. The preview is the load-bearing checkpoint for formatting issues (truncation, broken markdown, missing patch links) that the JSON view does not surface. Always preview before sending. If anything needs to change, edit the corresponding body field on the tracker, wait for the JSON to regenerate, re-paste in #source, and re-preview.
Send the advisory emails. Vulnogram dispatches to <users-list> and <announce-list>. On the tracker, add the announced - emails sent label and remove fix released.
Wait for the publication-ready notification comment. The sync-security-issue skill scans the public users-list archive for the CVE ID on every run. Once it finds the archived advisory, it populates the tracker's Public advisory URL body field, regenerates the CVE JSON to carry the archive URL as a vendor-advisory reference, adds the announced label, and posts a publication-ready notification comment on the tracker (the template body lives in release-manager-publication-comment.md). That comment is the explicit go-ahead for steps 7-8.
Second paste — READY → PUBLIC. Only after the publication-ready notification fires. Re-open #source, paste the now-final JSON (carrying the archive URL in references[]), Save, move the record READY → PUBLIC via the Vulnogram UI. The record propagates to cve.org once the state lands.
Close the tracker. Close as completed; do not update any labels. The sync-security-issue skill's apply step archives the project-board item afterwards (per the archive-from-board recipe in ../github/project-board.md) so the closed tracker leaves the active board.
The “twice paste” framing in the hand-off comment maps to steps 1 and 7 of the checklist above; step 2 is the rare conditional middle paste.