trivy-db, oras-go, the three version comparators and robfig/cron were
recorded as indirect with an incomplete go.sum, which builds locally
against a warm module cache but fails in CI with "updates to go.mod
needed". trivy-db pulls testify into the build graph, and its hashes
were missing entirely.
Completes tasks 10-15 and fixes what was outstanding:
- vulndb.Pull implemented with oras-go, streaming the ~50MB layer and
staging both files before replacing either, so a failed pull leaves the
previous database intact rather than a half-written one.
- db.go: Vulnerability.Severity is a string, not trivy Severity, so the
int conversion did not compile. Severity now resolves vendor (highest
when vendors disagree) then NVD then unknown, and CVSS is read too.
- findings.go: added sweepFixedFindings plus the fleet query, severity
counts, rescan flag and accept/unaccept the API needs.
- vulnrules.go: added rule CRUD and the digest builder. ResolveTargets
returns []models.Server, not []string, so filterByServers was wrong.
- api/vulnerabilities.go was an empty file while handlers.go registered
twelve routes against it; written, grouped by CVE.
- shared/mail: added the missing sender. The templates were orphaned and
the HTML one was a copy of the text one, defining "subject" (which
html/template would escape) and emitting no markup. render.go parses
every template in init(), so a bad one panics server, admin and sitesvc
at boot — go build never runs init(), which is why nothing complained.
- notify: digests dispatch through their own path so SMTP gets the digest
template rather than arriving dressed as a monitor alert.
The 1.26.4 floor meant a base toolchain of 1.26.2 could not load the
workspace at all: the terminal worked only because GOTOOLCHAIN=auto
silently swapped in a downloaded 1.26.4, and gopls -- which does not get
that switch -- failed every packages.Load with
go: go.work requires go >= 1.26.4 (running go 1.26.2)
Nothing needed the patch-level floor. agent/go.mod already declared plain
go 1.26, so this makes the workspace uniform rather than introducing a new
convention, and CI is unaffected because golang:1.26 is already newer.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
go build inside the Docker image runs outside the workspace, so server/go.sum
needed the hyperboloide/lk entry that GOWORK resolution was supplying locally.
Caught by the image build, not by go build.
Also pins the explicit shared require in both go.mod files. `go mod tidy`
in workspace mode drops it, which breaks the Docker build where no
workspace exists.