Skip to content

build(deps): close nine advisories in grpc, x/net, and x/text - #111

Merged
jakewan merged 1 commit into
mainfrom
feature/close-go-dependency-advisories
Jul 25, 2026
Merged

build(deps): close nine advisories in grpc, x/net, and x/text#111
jakewan merged 1 commit into
mainfrom
feature/close-go-dependency-advisories

Conversation

@jakewan

@jakewan jakewan commented Jul 25, 2026

Copy link
Copy Markdown
Owner

Overview

Dependabot reported two advisories against the daemon and MCP server. A module-mode govulncheck scan reports eight per module, and the union of the two sources is nine across three packages — so the scope had to come from both. The project's CI rule says exactly that of this pair: neither alone is coverage. Scoping from the push warning alone would have closed six of nine and reported success.

google.golang.org/grpc moves to 1.82.1, golang.org/x/net to 0.57.0, and golang.org/x/text to 0.40.0, in both modules. core requires none of the three.

How it works

Three things a reviewer cannot read off a lockfile diff.

Dependabot's floor for x/net is below what actually clears the package. It reports the fix as 0.55.0, but GO-2026-5942 — a dns/dnsmessage panic — needs 0.56.0. 0.57.0 is the minimum that closes every x/net advisory, and it carries x/text past the 0.39.0 that GO-2026-5970 requires. That x/text advisory has no Dependabot alert at all.

The x/net bump is explicit rather than transitive. grpc v1.82.1 still requires x/net v0.53.0 in its own go.mod, so bumping grpc alone leaves x/net where it was — minimal version selection has no reason to raise it. Confirmed in practice: neither go get on grpc mentioned x/net in its output.

Do not read the green just vuln as evidence this landed. None of the nine advisories is reachable from finch's code, and the gRPC one has no Go vulnerability database entry at all, so govulncheck cannot see it in any mode — the symbol-mode scan was green before this change and is green after. What actually proves the bump is the resolved-version assertion per module (grpc v1.82.1 / x/net v0.57.0 / x/text v0.40.0, identical in daemon and mcp) plus an empty module-mode scan, both run. The changelog entry states the not-reachable fact rather than inheriting the precedent entry's "advisories that finch's own code reached."

Dependabot reported two advisories against the daemon and MCP server. A
module-mode govulncheck scan reports eight per module, and the union of the two
sources is nine across three packages — so the scope had to come from both. The
project's own CI rule says exactly that of this pair: neither alone is coverage.
Deriving scope from the push warning alone would have closed six of nine.

Two specifics the single-source view got wrong. Dependabot names golang.org/x/text
not at all, and it reports x/net as fixed in 0.55.0 when one advisory there
(GO-2026-5942, a dnsmessage panic) needs 0.56.0 — so the advertised floor is below
what actually clears the package. 0.57.0 is the minimum that closes everything,
and it carries x/text from 0.36.0 to 0.40.0, past the 0.39.0 that GO-2026-5970
requires.

The x/net bump is explicit rather than transitive because grpc v1.82.1 still
requires x/net v0.53.0 in its own go.mod. Bumping grpc alone leaves x/net
vulnerable; minimal version selection has no reason to move it.

Ordering matters and is documented in ci-go.yml: buf generate must precede tidy,
because without daemon/gen a tidy run prunes the gRPC and protobuf requirements —
which on this change would have committed a security fix whose go.mod no longer
requires the package being patched.

None of the nine was reachable, which the changelog entry states rather than
inheriting the precedent entry's "advisories that finch's own code reached." The
gRPC advisory in particular has no Go vulnerability database entry at all, so
govulncheck cannot see it in any mode — the checks that actually prove this landed
are the resolved-version assertions per module and an empty module-mode scan, not
the symbol-mode run, which was green before the bump too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jakewan
jakewan marked this pull request as ready for review July 25, 2026 18:50
@jakewan
jakewan merged commit ef1b364 into main Jul 25, 2026
3 checks passed
@jakewan
jakewan deleted the feature/close-go-dependency-advisories branch July 25, 2026 18:50
jakewan added a commit that referenced this pull request Jul 25, 2026
Two facts a Go dependency bump needs in this repo were documented only where an agent does not read while planning — a workflow step comment and a justfile comment. A recent bump (#111) consequently scoped nine advisories as two, and ordered its steps so the reconciliation would have run before the code generation it depends on.

Writing that procedure into the always-loaded layer surfaced that half of it should not be documentation at all. Generated code under daemon/gen/ is not committed, and production and test files in both daemon and mcp import it, so nine recipes require it — building, testing, linting, scanning, reconciling — and only `just all` chained it. Each of those nine now declares proto as a dependency; just runs it once per invocation however many legs ask. The core recipes deliberately do not, so `just test-core` still needs no protobuf toolchain, matching the reason `test-app` is kept out of `test`.

The mechanism every existing description gave was also wrong, established by deleting daemon/gen and running the command rather than by reading the comment asserting it. `go mod tidy` does not prune the gRPC and protobuf requirements: it looks for the missing package as an external module and fails to load. gRPC could not have been pruned regardless, since non-generated main.go imports it directly in both modules. The workflow comment making that claim is corrected here too — it was the source the prose paraphrased and would otherwise contradict it.

That inverts what the documentation says. Prose warning a reader to remember an ordering becomes prose explaining why a recipe carries a prerequisite, and the manual "run just proto first" instructions it made obsolete are retired — including two quick-reference lines that would otherwise have kept asserting a setup step the tooling no longer needs.

What remains as guidance is the half that cannot be enforced: scoping a bump means reading both Dependabot alerts and a module-mode govulncheck scan, because each can be the only surface that sees a given advisory. Both now have a named execution path, since naming only the scanner left the instruction half-unfollowable.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant