Pin govulncheck to v1.6.0 instead of @latest. The argument is
reproducibility, not supply chain: golang.org/x/vuln is the Go team's
own module and go install is already checksum-verified via GOSUMDB.
What @latest costs is a new govulncheck release turning CI red on an
unchanged tree. This gate is load-bearing - e6e5da0 bumped the Go image
to fix GO-2026-5856 after govulncheck caught it - so protecting it from
unrelated churn is worth a pin.
Pinning costs nothing in scan freshness: the vulnerability database is
fetched at runtime, independently of the binary version. Verified:
Scanner govulncheck@v1.6.0, DB updated 2026-07-08, no vulnerabilities,
exit 0.
Narrow release.yml's workflow-level permissions from contents: write to
contents: read. Only the build job inherits it, and it only checks out
and uploads artifacts - upload-artifact authenticates with
ACTIONS_RUNTIME_TOKEN, not GITHUB_TOKEN. The release and npm-publish
jobs declare their own job-level permissions, which replace the
inherited set entirely, so both are unaffected.
Verified with actionlint (clean across all workflows) and by confirming
the release.yml still parses as YAML.