Vulnerability process
What happens to a vulnerability report after it arrives. How to report one, what counts as one and
which releases are supported is SECURITY.md; this page does not repeat it. Adopted in Q1,
2026-10-08, for the 1.x line.
1. Intake
A report arrives by the private channel SECURITY.md names. It is acknowledged, and given an
identifier NZSEC-<year>-<n> used in every later record. Nothing about it is written to a public
issue, commit message, branch name or test name until disclosure (§6).
Publication blocker. Today the repository is private, so GitHub’s private vulnerability
reporting cannot be enabled and the email fallback is the only channel. Before the first public
release: make the repository public, enable private vulnerability reporting, confirm the fallback
address receives mail, and record both checks in the release record (docs/releases/).
2. Triage
Reproduce it on the latest 1.x release and on main. Classify it by docs/quality-model.md:
technical severity, programme disposition, taxonomy tag. Decide whether it is a vulnerability at
all — SECURITY.md, What counts, and What the security features are not. A report that is not
one is answered with the reason and, where it is still a defect, filed as an ordinary one.
3. Private fix
The fix is prepared out of public view: a local branch, not pushed to a public remote, or a GitHub
security advisory’s private fork once one exists. It follows the ordinary rules
(CONTRIBUTING.md): the regression test that fails before the fix, a focused mutation, the
authority documents, and a semantic-epoch bump when the fix changes what a program means. A fix
that must refuse a previously accepted program refuses it with a diagnostic naming the rule.
4. Advisory and CVE
Every fixed vulnerability gets an advisory: the identifier, affected and fixed versions, severity, what an attacker controls, the workaround if any, and credit if the reporter wants it. A CVE is requested through the GitHub advisory once the repository is public, for every HIGH or CRITICAL finding and for any other a user is likely to scan for. Before then, no CVE is requested.
5. Patch release
The fix ships as the next patch release of the latest 1.x minor (SECURITY.md, Supported
releases), assembled and verified through the ordinary release path (docs/runbook.md,
scripts/release-candidate.sh) — the full contained gate, not a shortcut. Its release record names
the advisory.
6. Disclosure
The advisory and the fix are published together. The target is 90 days from acknowledgement, or sooner when a fix is ready; the reporter is told the date in advance and may agree a different one. A vulnerability already exploited or already public is fixed and disclosed as fast as the release path allows.
7. The supported line
Only the latest 1.x minor receives fixes. No maintenance branch is kept for an older minor, and
none is promised (SECURITY.md). The process promises what the project’s maintainers can keep,
and no more.