chore(deps): Go modules — sqlite 1.56.0 (corruption fix) + libc 1.74.4 lockstep, goose 3.27.3 unblocked, advisories GO-2026-5970 + GO-2025-3553 [schedule: Daily agent update check] #250

Open
opened 2026-07-31 04:09:30 +02:00 by dominik.polakovics · 6 comments

Goal

Bring the stale Go module pins in go.mod up to current. Two of them close security advisories that our pinned versions are inside; one of them (modernc.org/sqlite) closes a SQLite data-corruption bug; the rest are routine. None of the reviewed changelog entries touches an API this repo calls — but modernc.org/sqlite has a hard libc lockstep requirement that will silently break the build if missed.

Body rewritten 2026-08-04. modernc.org/sqlite v1.56.0 published to the Go module proxy on 2026-08-03T14:31:47Z — hours after the 2026-08-03 sweep checked and found it absent for the third time. It changes three of this issue's conclusions: the sqlite target, the libc target, and goose is no longer blocked. Two "do not move" indirects are now expected to move. See the 2026-08-04 comment for the diff.

Everything below was checked against the upstream changelogs and proxy.golang.org on 2026-08-04; the "does it break us" verdicts are stated per module with the reasoning, so you can re-check rather than take them on faith.

Evidence — what is behind

Module go.mod Target Kind
modernc.org/sqlite v1.53.0 v1.56.0 data-corruption fix + minor ×3
modernc.org/libc (indirect) v1.73.4 v1.74.4 lockstep with sqlite
golang.org/x/text (indirect) v0.38.0 v0.40.0 advisory GO-2026-5970
github.com/golang-jwt/jwt/v5 (indirect) v5.2.1 v5.3.1 advisory GO-2025-3553
github.com/pressly/goose/v3 v3.27.2 v3.27.3 unblocked 2026-08-04 — see below
github.com/prometheus/client_golang v1.23.2 v1.24.1 minor + patch
github.com/prometheus/common (indirect) v0.66.1 v0.70.1 rides client_golang
github.com/prometheus/procfs (indirect) v0.20.1 v0.21.1 rides client_golang
go.yaml.in/yaml/v2 v2.4.2 v2.4.4 patch ×2
golang.org/x/crypto v0.52.0 v0.54.0 hygiene — explicit go get
golang.org/x/sync (indirect) v0.21.0 v0.22.0 carried by goose v3.27.3
github.com/mattn/go-isatty (indirect) v0.0.21 v0.0.24 now expected — carried by sqlite v1.56.0
github.com/sethvargo/go-retry (indirect) v0.3.0 v0.4.0 now expected — carried by goose v3.27.3

Only golang.org/x/crypto needs an explicit go get. Everything else is carried by minimum-version selection once you bump modernc.org/sqlite, github.com/pressly/goose/v3 and github.com/prometheus/client_golang — see "What MVS carries for free". Verify the resulting versions against this table either way.

Already current, do not touch: github.com/jackc/pgx/v5 v5.10.0, github.com/SherClockHolmes/webpush-go v1.4.0, github.com/prometheus/client_model v0.6.2, golang.org/x/sys v0.47.0, golang.org/x/term v0.45.0, google.golang.org/protobuf v1.36.11, modernc.org/mathutil v1.7.1, modernc.org/memory v1.11.0, github.com/google/uuid v1.6.0, github.com/cespare/xxhash/v2 v2.3.0, github.com/dustin/go-humanize v1.0.1, github.com/ncruces/go-strftime v1.0.0, github.com/jackc/puddle/v2 v2.2.2, github.com/mfridman/interpolate v0.0.2, go.uber.org/multierr v1.11.0 — all confirmed at upstream @latest on 2026-08-04.

Security

Two advisories reach versions we pin, plus one data-corruption bug.

1. GO-2026-5970golang.org/x/text

GO-2026-5970  Infinite loop on invalid input in golang.org/x/text   (CVE-2026-56852)
  golang.org/x/text  introduced: 0  fixed: 0.39.0
  affected package: golang.org/x/text/unicode/norm
  affected symbols: Form.Append, Form.Bytes, Form.String, Form.Transform,
                    Iter.Next, normReader.Read, normWriter.Write, ... (24 total)

We pin golang.org/x/text v0.38.0 (go.mod, indirect block) — inside the affected range. Reachability was not verified (this investigation ran without a Go toolchain, so no govulncheck). x/text arrives only transitively; nothing under internal/ or cmd/ imports it directly. So this may well be unreachable in practice — but the fix is a one-line pin move, so bump it and let govulncheck say so definitively.

2. GO-2025-3553github.com/golang-jwt/jwt/v5

GO-2025-3553  Excessive memory allocation during header parsing in github.com/golang-jwt/jwt
              (CVE-2025-30204, GHSA-mh63-6h87-95cp)
  github.com/golang-jwt/jwt/v5  introduced: 5.0.0-rc.1  fixed: 5.2.2
  affected symbol: Parser.ParseUnverified

go.mod pins github.com/golang-jwt/jwt/v5 v5.2.1 in the indirect block — inside the affected range. It arrives via github.com/SherClockHolmes/webpush-go v1.4.0, whose own go.mod requires exactly v5.2.1.

Expected reachability: none, but bump anyway. The advisory's affected symbol is Parser.ParseUnverified. webpush-go only signs — its sole jwt call site is vapid.go:80, jwt.NewWithClaims(jwt.SigningMethodES256, …) for the VAPID Authorization header, which internal/push/sender.go:196 drives through webpush.SendNotificationWithContext. Nothing in this repo or in webpush-go parses a JWT, so govulncheck's symbol analysis should report it unreachable. Bump regardless: it is free (see below), and a version-range scanner will keep flagging v5.2.1 forever otherwise. Confirm with govulncheck rather than trusting this paragraph.

3. Not a CVE, but the strongest reason on this issue — the SQLite 3.53.3 journal-rollback corruption

Not in any advisory database (it is an upstream SQLite bug, patched downstream by modernc.org/libsqlite3), but it is a silent database-corruption bug and it is the reason the sqlite target moved from v1.55.0 to v1.56.0. Full analysis in the modernc.org/sqlite section below. The short version:

  • Our current v1.53.0 embeds SQLite 3.53.2 — not affected.
  • v1.54.0 upgraded the engine to SQLite 3.53.3, which introduced the bug. v1.55.0 still carries it.
  • v1.56.0 patches the amalgamation before transpiling — fixed.

So the previously-specified target v1.55.0 would have moved us from a correct engine onto a knowingly-corrupting one, for no benefit. Take v1.56.0.

Deliberately not a reason to bump — stated so nobody re-derives it: golang.org/x/crypto looks alarming in the vulnerability database (29 advisories, 14 of them in 2026: GO-2026-5005, 5006, 50135021, 5023, 5033). Every one of them is fixed in v0.52.0, which is what we already pin, and every one is in golang.org/x/crypto/ssh*. This repo imports exactly one x/crypto package — golang.org/x/crypto/argon2 (internal/httpapi/password.go:11). The one still-open advisory, GO-2026-5932, covers x/crypto/openpgp, which we do not import. The x/crypto row in the table above is hygiene, not security. Same story for golang.org/x/sys (GO-2026-5024, fixed v0.44.0, we are on v0.47.0), pgx/v5 (GO-2026-5004 fixed 5.9.2; GO-2026-4771/4772 fixed 5.9.0; we are on v5.10.0), google.golang.org/protobuf (GO-2024-2611 fixed 1.33.0, we are on v1.36.11) and prometheus/client_golang (GO-2022-0322 fixed 1.11.1).

Full sweep, 2026-08-03, re-confirmed 2026-08-04: every one of the 34 modules in go.mod was checked against the complete vuln.go.dev module index (not just the direct ones — that narrower check is what missed GO-2025-3553 on the earlier passes). Only the seven modules listed above appear in the index at all, and only x/text and golang-jwt/jwt/v5 have an advisory whose affected range contains the version we pin.

What MVS carries for free

Verified from the upstream .mod files on 2026-08-04.

modernc.org/sqlite v1.56.0 (https://proxy.golang.org/modernc.org/sqlite/@v/v1.56.0.mod) requires:

github.com/google/pprof   v0.0.0-20260802141513-ef3492d7dac3
golang.org/x/sys          v0.47.0
modernc.org/fileutil      v1.4.0
modernc.org/libc          v1.74.4
modernc.org/mathutil      v1.7.1
github.com/mattn/go-isatty v0.0.24 // indirect

github.com/pressly/goose/v3 v3.27.3 (https://proxy.golang.org/github.com/pressly/goose/v3/@v/v3.27.3.mod) requires (relevant lines only):

modernc.org/sqlite          v1.54.0
modernc.org/libc            v1.74.3 // indirect
github.com/sethvargo/go-retry v0.4.0
github.com/mattn/go-isatty  v0.0.23 // indirect
golang.org/x/sync           v0.22.0
github.com/jackc/pgx/v5     v5.10.0

github.com/prometheus/client_golang v1.24.1 requires:

github.com/prometheus/common  v0.70.1
github.com/prometheus/procfs  v0.21.1
golang.org/x/text             v0.40.0
go.yaml.in/yaml/v2            v2.4.4
golang.org/x/sys              v0.47.0
google.golang.org/protobuf    v1.36.11
github.com/golang-jwt/jwt/v5  v5.3.1 // indirect

So the three bumps carry everything else in the target table — both advisories close as a side effect. Do not fight it, and do not assume it: check the resulting go.mod against the target table.

Expect new // indirect lines. From sqlite v1.56.0: github.com/google/pprof, modernc.org/fileutil. From client_golang v1.24.1 / prometheus/common v0.70.1: github.com/json-iterator/go, github.com/klauspost/compress, github.com/modern-go/concurrent, github.com/modern-go/reflect2, github.com/jpillora/backoff, github.com/mwitkow/go-conntrack, golang.org/x/net, golang.org/x/oauth2. Whichever of those go mod tidy decides our build actually needs will appear in the indirect block. That is normal and is not a finding — but it enlarges the go.sum diff, which is the vendorHash trap below.

What changed, per module, and whether it breaks us

modernc.org/sqlite v1.53.0 → v1.56.0 — read this one carefully

Hard requirement, stated by upstream in its own changelog: "downstream modules must pin the exact same modernc.org/libc version this module's go.mod pins" (GitLab issue #177). sqlite v1.56.0 pins modernc.org/libc v1.74.4 (verified from the .mod above). We currently carry modernc.org/libc v1.73.4. Both lines must move together. v1.74.4 also happens to be libc's own @latest, so for this bump — unlike the previous target — the two coincide. Verify the resulting go.mod line reads modernc.org/libc v1.74.4.

  • v1.54.0 — upgrades the embedded engine to SQLite 3.53.3. Adds an opt-in _texttotime DSN parameter; without it, behavior is byte-for-byte unchanged. This release also introduced the corruption bug below.

  • v1.55.0 — adds mattn/go-sqlite3-compatible shorthand DSN keys (_busy_timeout, _fk, _journal_mode, _synchronous, _auto_vacuum, _query_only). Upstream flags this as a real behavior change: those keys were previously ignored, and now they take effect, and an unrecognized value now fails the connection. Also: every DSN query parameter is now validated before any of them is applied, so a DSN with a bad later parameter no longer leaves the file half-converted.

  • v1.56.0 — the data-corruption fix. Quoting upstream's changelog:

    Re-vendor the transpiled SQLite sources, picking up modernc.org/libsqlite3's fix for an upstream data-corruption bug in SQLite 3.53.3's journal rollback. The SQLite version is unchanged at 3.53.3; what changes is that the amalgamation is now patched before it is transpiled. 3.53.3 reworked readSuperJournal() to return the super-journal name through a char** out-parameter, and pager_playback() now tests that pointer where it used to test zSuper[0]. A crash during the commit of a multi-database (ATTACH) transaction can leave the super-journal name and its checksum zeroed while the name length and the trailing magic survive; the checksum is a plain byte sum, so an all-zero name still validates and readSuperJournal() hands back a non-NULL pointer to an empty string. pager_playback() then calls sqlite3OsAccess(pVfs, "", SQLITE_ACCESS_EXISTS), gets ENOENT, and deletes the hot journal without playing it back — leaving the database corrupted. This is not a transpilation artifact: a plain gcc build of the stock 3.53.3 amalgamation fails on the same bytes while 3.53.2 recovers them, and it is what has been making upstream's own test/crash.test fail intermittently, in roughly 2% of runs, on every platform.

    v1.56.0 also adds NewConnector (additive; we do not use it) and regenerates the linux/s390x and linux/riscv64 transpiles. Every other target's generated code is byte-identical to v1.55.0 apart from the journal-rollback patch.

  • Does the corruption bug reach lab's own store? Expected: no — but verify this reasoning rather than take it on faith. Two independent conditions have to hold for the bug to fire, and neither does here:

    1. It needs a super-journal, which only exists for a multi-database (ATTACH) transaction. grep -rn 'ATTACH' internal/ migrations/ finds zero hits (the only matches are the word "attach" in tmux-attach prose). Lab opens one database.
    2. It needs a hot rollback journal to replay. Lab pins journal_mode(WAL) in its DSN, and SQLite decides whether a commit needs a super-journal from a per-journal-mode table (aMJNeeded[] in vdbeaux.c) in which WAL is marked as not needing one.

    So the fix is not urgent for us. It is still the right target, because the alternative — the v1.55.0 this issue previously specified — moves us onto the buggy 3.53.3 engine and buys nothing over v1.56.0.

  • Does the DSN change break us? No — and here is the check. Our DSN recipe is pinned at internal/store/store.go:84-86:

    sqliteDSN := "file:" + path +
        "?_pragma=foreign_keys(1)&_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_txlock=immediate"
    

    We use the _pragma=name(value) form and _txlock, not the mattn shorthand keys, so none of the newly-honored v1.55.0 keys appear in our DSN. The "validate every parameter first" change does cover the pre-existing _txlock, but immediate remains a valid value. Re-read store.go when you do this and confirm the DSN recipe has not drifted from the quote above.

github.com/pressly/goose/v3 v3.27.2 → v3.27.3 — UNBLOCKED as of 2026-08-04

This issue previously said, in bold, "BLOCKED at v3.27.2, do not bump." That is no longer true, and the thing that changed is the publication of sqlite v1.56.0. Re-derive it yourself; here is the arithmetic:

  • goose v3.27.3 requires modernc.org/sqlite v1.54.0 and modernc.org/libc v1.74.3 // indirect.
  • modernc.org/libc v1.74.2 and v1.74.3 are retracted upstream ("freeaddrinfo leaks a locked ___lock entry; deadlocks name resolution, fixed in v1.74.4" — the retraction directives are in libc v1.74.4's own go.mod).
  • modernc.org/sqlite v1.56.0 lockstep-pins modernc.org/libc v1.74.4 exactly.

Under MVS the selected versions are the maxima across the graph:

libc   = max(v1.74.4 [sqlite v1.56.0], v1.74.3 [goose v3.27.3])  = v1.74.4   ✅ == sqlite's lockstep pin
sqlite = max(v1.56.0 [ours],           v1.54.0 [goose v3.27.3])  = v1.56.0   ✅

The retracted v1.74.3 is never selected — it is only required, and a higher version wins. So the lockstep holds and goose moves. This only works if you take sqlite v1.56.0. With the old v1.55.0 target (libc v1.74.1) the arithmetic gives libc = v1.74.3, which is both retracted and a lockstep violation — that was the original block, and it is why the two bumps must land together.

goose v3.27.3's release notes read, in full: "### Changed — Various dependency upgrades". No API change, no advisory. Lab's only goose surface is internal/store/store.go (goose.DialectSQLite3 / the pgx dialect and the embedded migrations.SQLite FS) — none of it touched.

github.com/mattn/go-isatty v0.0.21 → v0.0.24 and github.com/sethvargo/go-retry v0.3.0 → v0.4.0 — now expected to move

This issue previously said to leave both alone and treat any movement as a tripwire. That instruction is now inverted, because their floor came from goose v3.27.2 and both movers raise it:

  • go-isattyv0.0.24 is required by sqlite v1.56.0 (indirect).
  • go-retryv0.4.0 is required by goose v3.27.3 (direct in goose).

Both are indirect for us, neither has an advisory, and nothing in internal/ or cmd/ imports either. Let go mod tidy place them. If either lands on a version other than the one above, that is worth a second look before proceeding.

github.com/prometheus/client_golang v1.23.2 → v1.24.1

  • v1.24.0 [CHANGE] minimum Go is now 1.25. We declare go 1.26 (go.mod:3) — fine.
  • v1.24.0 [CHANGE] name validation always uses the UTF-8 scheme; code that set model.NameValidationScheme = LegacyValidation loses legacy enforcement. We never set it (no match for NameValidationScheme anywhere under internal/) — fine.
  • v1.24.0 [CHANGE] api/prometheus/v1 signature changes (Rules, LabelNames) and exp/api/remote reshaping. We import none of those packages — we use prometheus, promhttp, and collectors only (internal/metrics/metrics.go, internal/metrics/lab.go) — fine.
  • v1.24.0 [FEATURE] new Go 1.26 runtime metrics, WithUnit option, Desc.Err(). Additive.
  • v1.24.1 [BUGFIX] promhttp: fix panic on requests with a nil URL (#2065). We serve promhttp — a straight robustness win.
  • internal/metrics/metrics_test.go:170 asserts the presence of lab_http_requests_total, lab_http_request_duration_seconds, and go_goroutines. All three survive; if that assertion fails, treat it as a real finding and report it rather than loosening the test.

golang.org/x/text v0.38.0 → v0.40.0 — the advisory fix (see Security §1). Indirect only; rides client_golang.

github.com/golang-jwt/jwt/v5 v5.2.1 → v5.3.1 — the advisory fix (see Security §2). Indirect only; rides client_golang. Between v5.2.1 and v5.3.1 upstream added ParseWithClaims validator options and a ClockSkew option, and fixed the ParseUnverified allocation bug that is CVE-2025-30204. We call none of it directly — webpush-go's signing path is the only consumer.

go.yaml.in/yaml/v2 v2.4.2 → v2.4.4 — patch releases on the drop-in gopkg.in/yaml.v2 replacement. Single call site: internal/seeder/skillsindex.go:8. Rides client_golang.

golang.org/x/crypto v0.52.0 → v0.54.0 — hygiene, and this is the issue's single answer on it

Earlier comments on this issue disagreed about whether to move it. The answer is: move it. Nothing in the module graph requires more than v0.52.0, so go mod tidy will not raise it on its own — it needs an explicit go get golang.org/x/crypto@v0.54.0.

Between v0.52.0 and v0.54.0 (golang/crypto commit log, 2026-06-02 .. 2026-07-23) there are ~35 commits, all but two under ssh/, ssh/agent, ssh/knownhosts, ssh/test, acme/, x509roots/fallback, ocsp/, pkcs12/ or openpgp/. We import exactly one x/crypto package, golang.org/x/crypto/argon2 (internal/httpapi/password.go:11). The only argon2 commit in the window is:

0b316e7ee409  2026-06-18  argon2: update RFC 9106 parameter recommendations
  "Update the IDKey example to use RFC 9106's first recommended Argon2id
   option and clarify the relationship between the first and second
   recommended options."   (golang/go#79823)

A doc-comment change only — no exported signature, no default, no behavior. internal/httpapi/password.go:23-29 pins the RFC 9106 second recommended set (time=3, memory=64MiB, threads=4, keyLen=32, saltLen=16) as explicit constants, so the revised example in upstream's docs does not reach us. Do not touch defaultArgonParams — it is a design §12 decision, not a copy of upstream's example. Expected code impact: zero.

golang.org/x/sync v0.21.0 → v0.22.0 — hygiene, indirect

Previously needed an explicit go get (it was pinned at v0.21.0 by goose v3.27.2). goose v3.27.3 requires v0.22.0, so MVS now carries it — no explicit go get needed. No advisory, no API this repo calls.

Scope

  • go.mod, go.sum — the moving lines above, plus whatever go mod tidy pulls behind them.
  • nix/package.nix:56vendorHash. This is the trap. Both Go derivations share one goModules fetch (nix/package.nix:55), and the hash is hard-coded:
    vendorHash = "sha256-hOPrF9pvuxt4r29yoUo/Uy6G7FbCOyxmFPqDDXuEbnA=";
    
    Any go.sum change invalidates it and the hermetic nix gate (.forgejo/workflows/ci-nix.yml) fails with a fixed-output-derivation hash mismatch. Set it to lib.fakeHash, run the build, and paste the got: hash from the error. This must land in the same commit as the go.mod change. The go.sum diff is larger than on previous passes (goose v3.27.3 drags a wide module graph), so this is more likely to bite, not less.
  • No production code changes are expected. If you need one, that is a finding — report it here.

How to verify

go get modernc.org/sqlite@v1.56.0
go get github.com/pressly/goose/v3@v3.27.3
go get github.com/prometheus/client_golang@v1.24.1
go get golang.org/x/crypto@v0.54.0
go mod tidy

grep -E 'modernc.org/(sqlite|libc)|golang.org/x/(text|crypto|sync)|golang-jwt|pressly/goose|prometheus/(common|procfs|client_golang)|yaml/v2|go-isatty|go-retry' go.mod
#   want: sqlite v1.56.0, libc v1.74.4, goose v3.27.3, text v0.40.0, crypto v0.54.0,
#         sync v0.22.0, golang-jwt/jwt/v5 v5.3.1, client_golang v1.24.1,
#         common v0.70.1, procfs v0.21.1, yaml/v2 v2.4.4,
#         mattn/go-isatty v0.0.24, sethvargo/go-retry v0.4.0

go build ./...
go test ./...                       # the store suite exercises the pinned SQLite DSN recipe
golangci-lint run                   # `make lint`
go run golang.org/x/vuln/cmd/govulncheck@latest ./...   # must be clean; specifically confirms
                                    # GO-2026-5970 and GO-2025-3553 are gone
nix flake check                     # the hermetic gate — this is what catches a stale vendorHash

make test and make lint are the Makefile equivalents of the middle two.

If go mod tidy reports a retracted modernc.org/libc selection, stop — that means sqlite v1.56.0 did not land and the lockstep arithmetic above did not hold. Report it here rather than forcing it.

Done means

  • The target table's versions are what go.mod reads after go mod tidy, checked line by line.
  • modernc.org/sqlite is at v1.56.0 — not v1.55.0, which carries the SQLite 3.53.3 journal-rollback corruption bug.
  • modernc.org/libc is exactly the version modernc.org/sqlite v1.56.0 pins (v1.74.4), and is not the retracted v1.74.2/v1.74.3.
  • github.com/pressly/goose/v3 is at v3.27.3.
  • github.com/golang-jwt/jwt/v5 is at v5.3.1 (or anything >= v5.2.2) — the advisory fix. It should arrive for free via client_golang; if it did not, raise it explicitly and find out why.
  • github.com/mattn/go-isatty is at v0.0.24 and github.com/sethvargo/go-retry is at v0.4.0 — both carried by MVS, neither forced.
  • nix/package.nix vendorHash regenerated in the same commit.
  • go build ./..., go test ./..., golangci-lint run all green.
  • govulncheck ./... reports no findings — in particular no GO-2026-5970 and no GO-2025-3553.
  • nix flake check passes (proves the vendorHash is right).
  • The store suite passes unchanged — the pinned SQLite DSN recipe in internal/store/store.go is not edited as part of this.
  • internal/httpapi/password.go is not edited — in particular defaultArgonParams is untouched.
  • PR body says Closes #250.

Out of scope

  • golang.org/x/sys, golang.org/x/term, pgx/v5, webpush-go, client_model, protobuf — already current, leave them alone.
  • The Go language pin (go 1.26) and the nixpkgs flake input. flake.lock is current — nixpkgs 148bab9c, locked 2026-08-01, one day behind nixos-unstable HEAD (643809054d65, 2026-08-02) as of this sweep. Nothing to chase and no separate issue is owed.
  • Agent-tools CLI pins (containers/agent-tools/versions.env) — those are their own issues: codex on #249, Claude Code on #235 and the 2.1.221 issue.
  • Web/npm dependencies. Re-investigated 2026-08-04: still nothing actionable, no issue filed. Both remaining upgrades are majors blocked by upstream peer ranges — see the 2026-08-03 comment for the full evidence, and the 2026-08-04 comment for the (nil) delta.
  • CI action pins — actions/checkout@v7, actions/setup-node@v7, actions/setup-go@v7, actions/cache@v6 across all four workflows; all current.

Filed by the Daily agent update check schedule, 2026-07-31; body corrected 2026-08-02 (goose moved from "bump" to "blocked"), 2026-08-03 (second advisory GO-2025-3553 added, MVS analysis added, x/crypto and x/sync folded in from comments, indirect block swept) and 2026-08-04 (sqlite v1.56.0 published — retargets sqlite/libc, unblocks goose, inverts the two held indirects). Versions from proxy.golang.org/<module>/@latest; advisory data from vuln.go.dev; changelogs from each project's own release notes.

## Goal Bring the stale Go module pins in `go.mod` up to current. **Two** of them close security advisories that our pinned versions are inside; **one** of them (`modernc.org/sqlite`) closes a SQLite **data-corruption** bug; the rest are routine. None of the reviewed changelog entries touches an API this repo calls — but `modernc.org/sqlite` has a hard **libc lockstep** requirement that will silently break the build if missed. > **Body rewritten 2026-08-04.** `modernc.org/sqlite v1.56.0` published to the Go module proxy on **2026-08-03T14:31:47Z** — hours *after* the 2026-08-03 sweep checked and found it absent for the third time. It changes three of this issue's conclusions: the sqlite target, the libc target, and **`goose` is no longer blocked**. Two "do not move" indirects are now *expected* to move. See the 2026-08-04 comment for the diff. Everything below was checked against the upstream changelogs and `proxy.golang.org` on 2026-08-04; the "does it break us" verdicts are stated per module with the reasoning, so you can re-check rather than take them on faith. ## Evidence — what is behind | Module | `go.mod` | Target | Kind | |---|---|---|---| | `modernc.org/sqlite` | `v1.53.0` | **`v1.56.0`** | **data-corruption fix** + minor ×3 | | `modernc.org/libc` (indirect) | `v1.73.4` | **`v1.74.4`** | **lockstep with sqlite** | | `golang.org/x/text` (indirect) | `v0.38.0` | `v0.40.0` | **advisory GO-2026-5970** | | `github.com/golang-jwt/jwt/v5` (indirect) | `v5.2.1` | `v5.3.1` | **advisory GO-2025-3553** | | `github.com/pressly/goose/v3` | `v3.27.2` | **`v3.27.3`** | **unblocked 2026-08-04** — see below | | `github.com/prometheus/client_golang` | `v1.23.2` | `v1.24.1` | minor + patch | | `github.com/prometheus/common` (indirect) | `v0.66.1` | `v0.70.1` | rides client_golang | | `github.com/prometheus/procfs` (indirect) | `v0.20.1` | `v0.21.1` | rides client_golang | | `go.yaml.in/yaml/v2` | `v2.4.2` | `v2.4.4` | patch ×2 | | `golang.org/x/crypto` | `v0.52.0` | `v0.54.0` | hygiene — explicit `go get` | | `golang.org/x/sync` (indirect) | `v0.21.0` | `v0.22.0` | carried by goose v3.27.3 | | `github.com/mattn/go-isatty` (indirect) | `v0.0.21` | **`v0.0.24`** | **now expected** — carried by sqlite v1.56.0 | | `github.com/sethvargo/go-retry` (indirect) | `v0.3.0` | **`v0.4.0`** | **now expected** — carried by goose v3.27.3 | **Only `golang.org/x/crypto` needs an explicit `go get`.** Everything else is carried by minimum-version selection once you bump `modernc.org/sqlite`, `github.com/pressly/goose/v3` and `github.com/prometheus/client_golang` — see "What MVS carries for free". Verify the resulting versions against this table either way. Already current, do **not** touch: `github.com/jackc/pgx/v5 v5.10.0`, `github.com/SherClockHolmes/webpush-go v1.4.0`, `github.com/prometheus/client_model v0.6.2`, `golang.org/x/sys v0.47.0`, `golang.org/x/term v0.45.0`, `google.golang.org/protobuf v1.36.11`, `modernc.org/mathutil v1.7.1`, `modernc.org/memory v1.11.0`, `github.com/google/uuid v1.6.0`, `github.com/cespare/xxhash/v2 v2.3.0`, `github.com/dustin/go-humanize v1.0.1`, `github.com/ncruces/go-strftime v1.0.0`, `github.com/jackc/puddle/v2 v2.2.2`, `github.com/mfridman/interpolate v0.0.2`, `go.uber.org/multierr v1.11.0` — all confirmed at upstream `@latest` on 2026-08-04. ## Security **Two advisories reach versions we pin, plus one data-corruption bug.** ### 1. `GO-2026-5970` — `golang.org/x/text` ``` GO-2026-5970 Infinite loop on invalid input in golang.org/x/text (CVE-2026-56852) golang.org/x/text introduced: 0 fixed: 0.39.0 affected package: golang.org/x/text/unicode/norm affected symbols: Form.Append, Form.Bytes, Form.String, Form.Transform, Iter.Next, normReader.Read, normWriter.Write, ... (24 total) ``` We pin `golang.org/x/text v0.38.0` (`go.mod`, indirect block) — inside the affected range. **Reachability was not verified** (this investigation ran without a Go toolchain, so no `govulncheck`). `x/text` arrives only transitively; nothing under `internal/` or `cmd/` imports it directly. So this may well be unreachable in practice — but the fix is a one-line pin move, so bump it and let `govulncheck` say so definitively. ### 2. `GO-2025-3553` — `github.com/golang-jwt/jwt/v5` ``` GO-2025-3553 Excessive memory allocation during header parsing in github.com/golang-jwt/jwt (CVE-2025-30204, GHSA-mh63-6h87-95cp) github.com/golang-jwt/jwt/v5 introduced: 5.0.0-rc.1 fixed: 5.2.2 affected symbol: Parser.ParseUnverified ``` `go.mod` pins `github.com/golang-jwt/jwt/v5 v5.2.1` in the indirect block — inside the affected range. It arrives via `github.com/SherClockHolmes/webpush-go v1.4.0`, whose own `go.mod` requires exactly `v5.2.1`. **Expected reachability: none, but bump anyway.** The advisory's affected symbol is `Parser.ParseUnverified`. webpush-go only *signs* — its sole jwt call site is `vapid.go:80`, `jwt.NewWithClaims(jwt.SigningMethodES256, …)` for the VAPID `Authorization` header, which `internal/push/sender.go:196` drives through `webpush.SendNotificationWithContext`. Nothing in this repo or in webpush-go parses a JWT, so `govulncheck`'s symbol analysis should report it unreachable. Bump regardless: it is free (see below), and a version-range scanner will keep flagging `v5.2.1` forever otherwise. **Confirm with `govulncheck` rather than trusting this paragraph.** ### 3. Not a CVE, but the strongest reason on this issue — the SQLite 3.53.3 journal-rollback corruption Not in any advisory database (it is an upstream SQLite bug, patched downstream by `modernc.org/libsqlite3`), but it is a **silent database-corruption** bug and it is the reason the sqlite target moved from `v1.55.0` to `v1.56.0`. Full analysis in the `modernc.org/sqlite` section below. The short version: - Our current `v1.53.0` embeds SQLite **3.53.2** — not affected. - `v1.54.0` upgraded the engine to SQLite **3.53.3**, which introduced the bug. `v1.55.0` still carries it. - `v1.56.0` patches the amalgamation before transpiling — fixed. **So the previously-specified target `v1.55.0` would have moved us from a correct engine onto a knowingly-corrupting one, for no benefit.** Take `v1.56.0`. **Deliberately not a reason to bump — stated so nobody re-derives it:** `golang.org/x/crypto` looks alarming in the vulnerability database (29 advisories, 14 of them in 2026: `GO-2026-5005`, `5006`, `5013`–`5021`, `5023`, `5033`). Every one of them is **fixed in `v0.52.0`, which is what we already pin**, and every one is in `golang.org/x/crypto/ssh*`. This repo imports exactly one `x/crypto` package — `golang.org/x/crypto/argon2` (`internal/httpapi/password.go:11`). The one still-open advisory, `GO-2026-5932`, covers `x/crypto/openpgp`, which we do not import. The `x/crypto` row in the table above is **hygiene, not security**. Same story for `golang.org/x/sys` (`GO-2026-5024`, fixed `v0.44.0`, we are on `v0.47.0`), `pgx/v5` (`GO-2026-5004` fixed `5.9.2`; `GO-2026-4771`/`4772` fixed `5.9.0`; we are on `v5.10.0`), `google.golang.org/protobuf` (`GO-2024-2611` fixed `1.33.0`, we are on `v1.36.11`) and `prometheus/client_golang` (`GO-2022-0322` fixed `1.11.1`). **Full sweep, 2026-08-03, re-confirmed 2026-08-04:** every one of the 34 modules in `go.mod` was checked against the complete `vuln.go.dev` module index (not just the direct ones — that narrower check is what missed `GO-2025-3553` on the earlier passes). Only the seven modules listed above appear in the index at all, and only `x/text` and `golang-jwt/jwt/v5` have an advisory whose affected range contains the version we pin. ## What MVS carries for free Verified from the upstream `.mod` files on 2026-08-04. `modernc.org/sqlite v1.56.0` (`https://proxy.golang.org/modernc.org/sqlite/@v/v1.56.0.mod`) requires: ``` github.com/google/pprof v0.0.0-20260802141513-ef3492d7dac3 golang.org/x/sys v0.47.0 modernc.org/fileutil v1.4.0 modernc.org/libc v1.74.4 modernc.org/mathutil v1.7.1 github.com/mattn/go-isatty v0.0.24 // indirect ``` `github.com/pressly/goose/v3 v3.27.3` (`https://proxy.golang.org/github.com/pressly/goose/v3/@v/v3.27.3.mod`) requires (relevant lines only): ``` modernc.org/sqlite v1.54.0 modernc.org/libc v1.74.3 // indirect github.com/sethvargo/go-retry v0.4.0 github.com/mattn/go-isatty v0.0.23 // indirect golang.org/x/sync v0.22.0 github.com/jackc/pgx/v5 v5.10.0 ``` `github.com/prometheus/client_golang v1.24.1` requires: ``` github.com/prometheus/common v0.70.1 github.com/prometheus/procfs v0.21.1 golang.org/x/text v0.40.0 go.yaml.in/yaml/v2 v2.4.4 golang.org/x/sys v0.47.0 google.golang.org/protobuf v1.36.11 github.com/golang-jwt/jwt/v5 v5.3.1 // indirect ``` So the three bumps carry everything else in the target table — **both advisories close as a side effect**. Do not fight it, and do not assume it: check the resulting `go.mod` against the target table. **Expect new `// indirect` lines.** From sqlite v1.56.0: `github.com/google/pprof`, `modernc.org/fileutil`. From `client_golang v1.24.1` / `prometheus/common v0.70.1`: `github.com/json-iterator/go`, `github.com/klauspost/compress`, `github.com/modern-go/concurrent`, `github.com/modern-go/reflect2`, `github.com/jpillora/backoff`, `github.com/mwitkow/go-conntrack`, `golang.org/x/net`, `golang.org/x/oauth2`. Whichever of those `go mod tidy` decides our build actually needs will appear in the indirect block. That is normal and is not a finding — but it enlarges the `go.sum` diff, which is the `vendorHash` trap below. ## What changed, per module, and whether it breaks us ### `modernc.org/sqlite` v1.53.0 → v1.56.0 — **read this one carefully** **Hard requirement, stated by upstream in its own changelog:** *"downstream modules must pin the exact same `modernc.org/libc` version this module's `go.mod` pins"* ([GitLab issue #177](https://gitlab.com/cznic/sqlite/-/issues/177)). `sqlite v1.56.0` pins `modernc.org/libc v1.74.4` (verified from the `.mod` above). We currently carry `modernc.org/libc v1.73.4`. **Both lines must move together.** `v1.74.4` also happens to be `libc`'s own `@latest`, so for this bump — unlike the previous target — the two coincide. Verify the resulting `go.mod` line reads `modernc.org/libc v1.74.4`. - **v1.54.0** — upgrades the embedded engine to SQLite 3.53.3. Adds an opt-in `_texttotime` DSN parameter; without it, behavior is byte-for-byte unchanged. **This release also introduced the corruption bug below.** - **v1.55.0** — adds `mattn/go-sqlite3`-compatible shorthand DSN keys (`_busy_timeout`, `_fk`, `_journal_mode`, `_synchronous`, `_auto_vacuum`, `_query_only`). Upstream flags this as a real behavior change: those keys were previously *ignored*, and now they take effect, and an unrecognized value now **fails the connection**. Also: every DSN query parameter is now validated *before* any of them is applied, so a DSN with a bad later parameter no longer leaves the file half-converted. - **v1.56.0 — the data-corruption fix.** Quoting upstream's changelog: > Re-vendor the transpiled SQLite sources, picking up `modernc.org/libsqlite3`'s fix for an upstream **data-corruption bug in SQLite 3.53.3's journal rollback**. The SQLite version is unchanged at 3.53.3; what changes is that the amalgamation is now patched before it is transpiled. 3.53.3 reworked `readSuperJournal()` to return the super-journal name through a `char**` out-parameter, and `pager_playback()` now tests that pointer where it used to test `zSuper[0]`. A crash during the commit of a multi-database (ATTACH) transaction can leave the super-journal name and its checksum zeroed while the name length and the trailing magic survive; the checksum is a plain byte sum, so an all-zero name still validates and `readSuperJournal()` hands back a non-NULL pointer to an empty string. `pager_playback()` then calls `sqlite3OsAccess(pVfs, "", SQLITE_ACCESS_EXISTS)`, gets ENOENT, and **deletes the hot journal without playing it back — leaving the database corrupted.** This is not a transpilation artifact: a plain gcc build of the stock 3.53.3 amalgamation fails on the same bytes while 3.53.2 recovers them, and it is what has been making upstream's own `test/crash.test` fail intermittently, in roughly 2% of runs, on every platform. v1.56.0 also adds `NewConnector` (additive; we do not use it) and regenerates the `linux/s390x` and `linux/riscv64` transpiles. Every other target's generated code is byte-identical to v1.55.0 apart from the journal-rollback patch. - **Does the corruption bug reach lab's own store? Expected: no — but verify this reasoning rather than take it on faith.** Two independent conditions have to hold for the bug to fire, and neither does here: 1. **It needs a super-journal**, which only exists for a multi-database (`ATTACH`) transaction. `grep -rn 'ATTACH' internal/ migrations/` finds **zero** hits (the only matches are the word "attach" in tmux-attach prose). Lab opens one database. 2. **It needs a hot rollback journal to replay.** Lab pins `journal_mode(WAL)` in its DSN, and SQLite decides whether a commit needs a super-journal from a per-journal-mode table (`aMJNeeded[]` in `vdbeaux.c`) in which WAL is marked as not needing one. So the fix is not urgent for us. **It is still the right target**, because the alternative — the `v1.55.0` this issue previously specified — moves us onto the buggy 3.53.3 engine and buys nothing over `v1.56.0`. - **Does the DSN change break us? No — and here is the check.** Our DSN recipe is pinned at `internal/store/store.go:84-86`: ```go sqliteDSN := "file:" + path + "?_pragma=foreign_keys(1)&_pragma=busy_timeout(5000)&_pragma=journal_mode(WAL)&_txlock=immediate" ``` We use the `_pragma=name(value)` form and `_txlock`, **not** the mattn shorthand keys, so none of the newly-honored v1.55.0 keys appear in our DSN. The "validate every parameter first" change does cover the pre-existing `_txlock`, but `immediate` remains a valid value. Re-read `store.go` when you do this and confirm the DSN recipe has not drifted from the quote above. ### `github.com/pressly/goose/v3` v3.27.2 → v3.27.3 — **UNBLOCKED as of 2026-08-04** This issue previously said, in bold, *"BLOCKED at v3.27.2, do not bump."* **That is no longer true**, and the thing that changed is the publication of `sqlite v1.56.0`. Re-derive it yourself; here is the arithmetic: - `goose v3.27.3` requires `modernc.org/sqlite v1.54.0` and `modernc.org/libc v1.74.3 // indirect`. - `modernc.org/libc v1.74.2` and `v1.74.3` are **retracted** upstream (*"freeaddrinfo leaks a locked `___lock` entry; deadlocks name resolution, fixed in v1.74.4"* — the retraction directives are in `libc v1.74.4`'s own `go.mod`). - `modernc.org/sqlite v1.56.0` lockstep-pins `modernc.org/libc v1.74.4` **exactly**. Under MVS the selected versions are the maxima across the graph: ``` libc = max(v1.74.4 [sqlite v1.56.0], v1.74.3 [goose v3.27.3]) = v1.74.4 ✅ == sqlite's lockstep pin sqlite = max(v1.56.0 [ours], v1.54.0 [goose v3.27.3]) = v1.56.0 ✅ ``` The retracted `v1.74.3` is never *selected* — it is only *required*, and a higher version wins. So the lockstep holds and goose moves. **This only works if you take `sqlite v1.56.0`.** With the old `v1.55.0` target (libc `v1.74.1`) the arithmetic gives `libc = v1.74.3`, which is both retracted and a lockstep violation — that was the original block, and it is why the two bumps must land together. `goose v3.27.3`'s release notes read, in full: *"### Changed — Various dependency upgrades"*. No API change, no advisory. Lab's only goose surface is `internal/store/store.go` (`goose.DialectSQLite3` / the pgx dialect and the embedded `migrations.SQLite` FS) — none of it touched. ### `github.com/mattn/go-isatty` v0.0.21 → v0.0.24 and `github.com/sethvargo/go-retry` v0.3.0 → v0.4.0 — **now expected to move** This issue previously said to leave both alone and treat any movement as a tripwire. **That instruction is now inverted**, because their floor came from `goose v3.27.2` and both movers raise it: - `go-isatty` → `v0.0.24` is required by `sqlite v1.56.0` (indirect). - `go-retry` → `v0.4.0` is required by `goose v3.27.3` (direct in goose). Both are indirect for us, neither has an advisory, and nothing in `internal/` or `cmd/` imports either. Let `go mod tidy` place them. If either lands on a version *other* than the one above, that is worth a second look before proceeding. ### `github.com/prometheus/client_golang` v1.23.2 → v1.24.1 - **v1.24.0 [CHANGE]** minimum Go is now 1.25. We declare `go 1.26` (`go.mod:3`) — fine. - **v1.24.0 [CHANGE]** name validation always uses the UTF-8 scheme; code that set `model.NameValidationScheme = LegacyValidation` loses legacy enforcement. **We never set it** (no match for `NameValidationScheme` anywhere under `internal/`) — fine. - **v1.24.0 [CHANGE]** `api/prometheus/v1` signature changes (`Rules`, `LabelNames`) and `exp/api/remote` reshaping. **We import none of those packages** — we use `prometheus`, `promhttp`, and `collectors` only (`internal/metrics/metrics.go`, `internal/metrics/lab.go`) — fine. - **v1.24.0 [FEATURE]** new Go 1.26 runtime metrics, `WithUnit` option, `Desc.Err()`. Additive. - **v1.24.1 [BUGFIX]** `promhttp`: fix panic on requests with a nil URL (#2065). We serve `promhttp` — a straight robustness win. - `internal/metrics/metrics_test.go:170` asserts the presence of `lab_http_requests_total`, `lab_http_request_duration_seconds`, and `go_goroutines`. All three survive; if that assertion fails, treat it as a real finding and report it rather than loosening the test. ### `golang.org/x/text` v0.38.0 → v0.40.0 — the advisory fix (see Security §1). Indirect only; rides `client_golang`. ### `github.com/golang-jwt/jwt/v5` v5.2.1 → v5.3.1 — the advisory fix (see Security §2). Indirect only; rides `client_golang`. Between `v5.2.1` and `v5.3.1` upstream added `ParseWithClaims` validator options and a `ClockSkew` option, and fixed the `ParseUnverified` allocation bug that is CVE-2025-30204. We call none of it directly — webpush-go's signing path is the only consumer. ### `go.yaml.in/yaml/v2` v2.4.2 → v2.4.4 — patch releases on the drop-in `gopkg.in/yaml.v2` replacement. Single call site: `internal/seeder/skillsindex.go:8`. Rides `client_golang`. ### `golang.org/x/crypto` v0.52.0 → v0.54.0 — hygiene, and this is the issue's single answer on it Earlier comments on this issue disagreed about whether to move it. **The answer is: move it.** Nothing in the module graph requires more than `v0.52.0`, so `go mod tidy` will not raise it on its own — it needs an explicit `go get golang.org/x/crypto@v0.54.0`. Between `v0.52.0` and `v0.54.0` (`golang/crypto` commit log, 2026-06-02 .. 2026-07-23) there are ~35 commits, all but two under `ssh/`, `ssh/agent`, `ssh/knownhosts`, `ssh/test`, `acme/`, `x509roots/fallback`, `ocsp/`, `pkcs12/` or `openpgp/`. **We import exactly one `x/crypto` package, `golang.org/x/crypto/argon2`** (`internal/httpapi/password.go:11`). The only `argon2` commit in the window is: ``` 0b316e7ee409 2026-06-18 argon2: update RFC 9106 parameter recommendations "Update the IDKey example to use RFC 9106's first recommended Argon2id option and clarify the relationship between the first and second recommended options." (golang/go#79823) ``` A **doc-comment change only** — no exported signature, no default, no behavior. `internal/httpapi/password.go:23-29` pins the RFC 9106 *second* recommended set (`time=3, memory=64MiB, threads=4, keyLen=32, saltLen=16`) as explicit constants, so the revised example in upstream's docs does not reach us. **Do not touch `defaultArgonParams`** — it is a design §12 decision, not a copy of upstream's example. Expected code impact: zero. ### `golang.org/x/sync` v0.21.0 → v0.22.0 — hygiene, indirect Previously needed an explicit `go get` (it was pinned at `v0.21.0` by `goose v3.27.2`). **`goose v3.27.3` requires `v0.22.0`, so MVS now carries it** — no explicit `go get` needed. No advisory, no API this repo calls. ## Scope - `go.mod`, `go.sum` — the moving lines above, plus whatever `go mod tidy` pulls behind them. - **`nix/package.nix:56` — `vendorHash`.** This is the trap. Both Go derivations share one `goModules` fetch (`nix/package.nix:55`), and the hash is hard-coded: ```nix vendorHash = "sha256-hOPrF9pvuxt4r29yoUo/Uy6G7FbCOyxmFPqDDXuEbnA="; ``` Any `go.sum` change invalidates it and the hermetic nix gate (`.forgejo/workflows/ci-nix.yml`) fails with a fixed-output-derivation hash mismatch. Set it to `lib.fakeHash`, run the build, and paste the `got:` hash from the error. **This must land in the same commit as the `go.mod` change.** The `go.sum` diff is larger than on previous passes (goose v3.27.3 drags a wide module graph), so this is more likely to bite, not less. - No production code changes are expected. If you need one, that is a finding — report it here. ## How to verify ```sh go get modernc.org/sqlite@v1.56.0 go get github.com/pressly/goose/v3@v3.27.3 go get github.com/prometheus/client_golang@v1.24.1 go get golang.org/x/crypto@v0.54.0 go mod tidy grep -E 'modernc.org/(sqlite|libc)|golang.org/x/(text|crypto|sync)|golang-jwt|pressly/goose|prometheus/(common|procfs|client_golang)|yaml/v2|go-isatty|go-retry' go.mod # want: sqlite v1.56.0, libc v1.74.4, goose v3.27.3, text v0.40.0, crypto v0.54.0, # sync v0.22.0, golang-jwt/jwt/v5 v5.3.1, client_golang v1.24.1, # common v0.70.1, procfs v0.21.1, yaml/v2 v2.4.4, # mattn/go-isatty v0.0.24, sethvargo/go-retry v0.4.0 go build ./... go test ./... # the store suite exercises the pinned SQLite DSN recipe golangci-lint run # `make lint` go run golang.org/x/vuln/cmd/govulncheck@latest ./... # must be clean; specifically confirms # GO-2026-5970 and GO-2025-3553 are gone nix flake check # the hermetic gate — this is what catches a stale vendorHash ``` `make test` and `make lint` are the Makefile equivalents of the middle two. If `go mod tidy` reports a **retracted** `modernc.org/libc` selection, stop — that means `sqlite v1.56.0` did not land and the lockstep arithmetic above did not hold. Report it here rather than forcing it. ## Done means - [ ] The target table's versions are what `go.mod` reads after `go mod tidy`, checked line by line. - [ ] `modernc.org/sqlite` is at **`v1.56.0`** — not `v1.55.0`, which carries the SQLite 3.53.3 journal-rollback corruption bug. - [ ] `modernc.org/libc` is exactly the version `modernc.org/sqlite v1.56.0` pins (**`v1.74.4`**), and is **not** the retracted `v1.74.2`/`v1.74.3`. - [ ] `github.com/pressly/goose/v3` is at **`v3.27.3`**. - [ ] **`github.com/golang-jwt/jwt/v5` is at `v5.3.1`** (or anything `>= v5.2.2`) — the advisory fix. It should arrive for free via `client_golang`; if it did not, raise it explicitly and find out why. - [ ] `github.com/mattn/go-isatty` is at `v0.0.24` and `github.com/sethvargo/go-retry` is at `v0.4.0` — both carried by MVS, neither forced. - [ ] `nix/package.nix` `vendorHash` regenerated in the same commit. - [ ] `go build ./...`, `go test ./...`, `golangci-lint run` all green. - [ ] `govulncheck ./...` reports no findings — in particular no `GO-2026-5970` and no `GO-2025-3553`. - [ ] `nix flake check` passes (proves the vendorHash is right). - [ ] The store suite passes unchanged — the pinned SQLite DSN recipe in `internal/store/store.go` is **not** edited as part of this. - [ ] `internal/httpapi/password.go` is **not** edited — in particular `defaultArgonParams` is untouched. - [ ] PR body says `Closes #250`. ## Out of scope - `golang.org/x/sys`, `golang.org/x/term`, `pgx/v5`, `webpush-go`, `client_model`, `protobuf` — already current, leave them alone. - The Go language pin (`go 1.26`) and the nixpkgs flake input. **`flake.lock` is current** — nixpkgs `148bab9c`, locked 2026-08-01, one day behind `nixos-unstable` HEAD (`643809054d65`, 2026-08-02) as of this sweep. Nothing to chase and no separate issue is owed. - Agent-tools CLI pins (`containers/agent-tools/versions.env`) — those are their own issues: codex on #249, Claude Code on #235 and the 2.1.221 issue. - Web/npm dependencies. **Re-investigated 2026-08-04: still nothing actionable, no issue filed.** Both remaining upgrades are majors blocked by upstream peer ranges — see the 2026-08-03 comment for the full evidence, and the 2026-08-04 comment for the (nil) delta. - CI action pins — `actions/checkout@v7`, `actions/setup-node@v7`, `actions/setup-go@v7`, `actions/cache@v6` across all four workflows; all current. --- *Filed by the Daily agent update check schedule, 2026-07-31; body corrected 2026-08-02 (goose moved from "bump" to "blocked"), 2026-08-03 (second advisory `GO-2025-3553` added, MVS analysis added, x/crypto and x/sync folded in from comments, indirect block swept) and 2026-08-04 (sqlite v1.56.0 published — retargets sqlite/libc, unblocks goose, inverts the two held indirects). Versions from `proxy.golang.org/<module>/@latest`; advisory data from `vuln.go.dev`; changelogs from each project's own release notes.*
Author
Owner

Finding: goose/v3 cannot move to v3.27.3 — blocked by the sqlite/libc lockstep. Left at v3.27.2.

Evidence (verified against proxy.golang.org during the run):

  • goose v3.27.3's own go.mod requires modernc.org/libc v1.74.3 // indirect (its v3.27.3 release — release notes: "Various dependency upgrades" — bumped its own sqlite to v1.54.0 and libc to v1.74.3).
  • modernc.org/libc v1.74.3 (and v1.74.2) are retracted upstream: "freeaddrinfo leaks a locked ___lock entry; deadlocks name resolution, fixed in v1.74.4".
  • modernc.org/sqlite v1.55.0 lockstep-pins libc v1.74.1 exactly.

So under MVS the six targets are mutually unsatisfiable: taking goose v3.27.3 forces libc to v1.74.3 (retracted, deadlock bug) or — if bumped past the retraction — v1.74.4, which violates the lockstep requirement this issue rightly flags as hard. go get confirms: goose/v3@v3.27.3 requires modernc.org/libc@v1.74.3, not modernc.org/libc@v1.74.1.

Decision: honor the lockstep (libc v1.74.1, sqlite v1.55.0) and keep goose at v3.27.2. goose v3.27.3 has no code changes, only the dependency bumps that create this very conflict, so nothing is lost. The goose bump unblocks when either (a) sqlite ships a release pinning libc ≥ v1.74.4 (the changelog's unpublished v1.56.0 is a candidate — re-check its libc pin), or (b) a later goose release lands on a lockstep-compatible libc. Suggest the daily schedule will simply pick it up then.

One more scope note: go get opportunistically moved golang.org/x/crypto v0.52.0 → v0.54.0 (v0.54.0 is now upstream latest, so the issue's "already current" table entry was stale by a hair). Nothing in the module graph requires > v0.52.0 and the issue says leave it alone, so it was reverted to v0.52.0. All 2026 x/crypto advisories remain fixed at that version; govulncheck is clean either way.

**Finding: `goose/v3` cannot move to v3.27.3 — blocked by the sqlite/libc lockstep. Left at v3.27.2.** Evidence (verified against proxy.golang.org during the run): - `goose v3.27.3`'s own go.mod requires `modernc.org/libc v1.74.3 // indirect` (its v3.27.3 release — release notes: *"Various dependency upgrades"* — bumped its own sqlite to v1.54.0 and libc to v1.74.3). - `modernc.org/libc v1.74.3` (and v1.74.2) are **retracted** upstream: *"freeaddrinfo leaks a locked ___lock entry; deadlocks name resolution, fixed in v1.74.4"*. - `modernc.org/sqlite v1.55.0` lockstep-pins `libc v1.74.1` exactly. So under MVS the six targets are mutually unsatisfiable: taking goose v3.27.3 forces libc to v1.74.3 (retracted, deadlock bug) or — if bumped past the retraction — v1.74.4, which violates the lockstep requirement this issue rightly flags as hard. `go get` confirms: `goose/v3@v3.27.3 requires modernc.org/libc@v1.74.3, not modernc.org/libc@v1.74.1`. Decision: honor the lockstep (libc **v1.74.1**, sqlite **v1.55.0**) and keep goose at **v3.27.2**. goose v3.27.3 has no code changes, only the dependency bumps that create this very conflict, so nothing is lost. The goose bump unblocks when either (a) sqlite ships a release pinning libc ≥ v1.74.4 (the changelog's unpublished v1.56.0 is a candidate — re-check its libc pin), or (b) a later goose release lands on a lockstep-compatible libc. Suggest the daily schedule will simply pick it up then. One more scope note: `go get` opportunistically moved `golang.org/x/crypto` v0.52.0 → v0.54.0 (v0.54.0 is now upstream latest, so the issue's "already current" table entry was stale by a hair). Nothing in the module graph requires > v0.52.0 and the issue says leave it alone, so it was reverted to **v0.52.0**. All 2026 x/crypto advisories remain fixed at that version; govulncheck is clean either way.
Author
Owner

Re-verified 2026-08-01 (Daily agent update check). The advisory driver and the sqlite/libc lockstep both stand unchanged — but the "already current, do not touch" list has two errors. Two more pins are stale.

Correction 1 — golang.org/x/crypto is NOT current

The body lists golang.org/x/crypto v0.52.0 under "Already current, do not touch". It is not:

$ curl -s https://proxy.golang.org/golang.org/x/crypto/@v/list | sort -V | tail -5
v0.50.0 v0.51.0 v0.52.0 v0.53.0 v0.54.0
$ curl -s https://proxy.golang.org/golang.org/x/crypto/@latest
v0.54.0   (2026-07-08)

go.mod:12 pins v0.52.0, so we are two releases behind. The security reasoning in the body is still correct and needs no revision — every advisory listed there is fixed in v0.52.0, and nothing new has landed (see re-check below). Only the "already current" claim is wrong.

What is in v0.52.0 → v0.54.0 (from the golang/crypto commit log, 2026-06-02 .. 2026-07-23): ~35 commits, of which all but two are under ssh/, ssh/agent, ssh/knownhosts, ssh/test, acme/, x509roots/fallback, ocsp/, pkcs12/, or openpgp/. This repo imports exactly one x/crypto package — golang.org/x/crypto/argon2 (internal/httpapi/password.go:11). The only argon2 commit in the window is:

0b316e7ee409  2026-06-18  argon2: update RFC 9106 parameter recommendations
  "Update the IDKey example to use RFC 9106's first recommended Argon2id
   option and clarify the relationship between the first and second
   recommended options."   (golang/go#79823)

That is a doc-comment change only — no exported signature, no default, no behavior. internal/httpapi/password.go:23-29 pins the RFC 9106 second recommended set (time=3, memory=64MiB, threads=4, keyLen=32, saltLen=16) as explicit constants, so the revised example in upstream's docs does not reach us. Do not touch defaultArgonParams — it is a design §12 decision, not a copy of upstream's example.

So: bump golang.org/x/crypto v0.52.0 → v0.54.0 as routine hygiene, expect zero code impact, and leave password.go alone.

Correction 2 — golang.org/x/sync is stale and was omitted entirely

go.mod:38 pins golang.org/x/sync v0.21.0 // indirect; latest is v0.22.0. Not mentioned anywhere in the body. Indirect, low-risk, let go mod tidy carry it.

Re-confirmed, no change needed

  • GO-2026-5970 (x/text, fixed 0.39.0) is still the only advisory reaching any pin we carry. Checked the full vuln.go.dev module index for all 13 modules in our graph on 2026-08-01: no new advisory since this issue was filed. x/crypto's newest entries (GO-2026-5005/5006/50135021/5023/5033) are all fixed: 0.52.0; the one unfixed entry GO-2026-5932 is x/crypto/openpgp, which we do not import. x/sys GO-2026-5024 is fixed: 0.44.0 (we are on v0.47.0). The body's security section is accurate as written.
  • modernc.org/sqlite v1.56.0 is still NOT on the Go module proxy — the body flagged this as a thing to re-check:
    $ curl -s https://proxy.golang.org/modernc.org/sqlite/@v/list | sort -V | tail -3
    v1.53.0 v1.54.0 v1.55.0
    
    v1.55.0 remains the target. The lockstep requirement is unchanged: it pins modernc.org/libc v1.74.1 exactly.
  • modernc.org/libc @latest is now v1.74.4 — consistent with the retraction note in the earlier comment (v1.74.2/v1.74.3 retracted). Do not take v1.74.4; take the v1.74.1 that sqlite v1.55.0 pins, exactly as the body says.
  • golang.org/x/term v0.45.0 and golang.org/x/sys v0.47.0 really are current — those two entries in the "do not touch" list are correct.
  • goose/v3 stays at v3.27.2, blocked by the libc lockstep for the reason given in the earlier comment. Unchanged.

Updated target table

Module go.mod Target Note
golang.org/x/text (indirect) v0.38.0 v0.40.0 advisory GO-2026-5970
modernc.org/sqlite v1.53.0 v1.55.0 libc lockstep
modernc.org/libc (indirect) v1.73.4 v1.74.1 exactly what sqlite v1.55.0 pins
github.com/prometheus/client_golang v1.23.2 v1.24.1
go.yaml.in/yaml/v2 v2.4.2 v2.4.4
golang.org/x/crypto v0.52.0 v0.54.0 new — see Correction 1
golang.org/x/sync (indirect) v0.21.0 v0.22.0 new — see Correction 2
github.com/pressly/goose/v3 v3.27.2 stays blocked, see earlier comment

Everything else in the body — the vendorHash trap at nix/package.nix:56, the DSN check at internal/store/store.go:83-86, the client_golang analysis, the verification commands, and the done-list — stands as written.

**Re-verified 2026-08-01 (Daily agent update check). The advisory driver and the sqlite/libc lockstep both stand unchanged — but the "already current, do not touch" list has two errors. Two more pins are stale.** ### Correction 1 — `golang.org/x/crypto` is NOT current The body lists `golang.org/x/crypto v0.52.0` under *"Already current, do not touch"*. It is not: ``` $ curl -s https://proxy.golang.org/golang.org/x/crypto/@v/list | sort -V | tail -5 v0.50.0 v0.51.0 v0.52.0 v0.53.0 v0.54.0 $ curl -s https://proxy.golang.org/golang.org/x/crypto/@latest v0.54.0 (2026-07-08) ``` `go.mod:12` pins `v0.52.0`, so we are two releases behind. **The security reasoning in the body is still correct and needs no revision** — every advisory listed there is fixed in v0.52.0, and nothing new has landed (see re-check below). Only the "already current" *claim* is wrong. What is in v0.52.0 → v0.54.0 (from the `golang/crypto` commit log, 2026-06-02 .. 2026-07-23): ~35 commits, of which all but two are under `ssh/`, `ssh/agent`, `ssh/knownhosts`, `ssh/test`, `acme/`, `x509roots/fallback`, `ocsp/`, `pkcs12/`, or `openpgp/`. **This repo imports exactly one `x/crypto` package — `golang.org/x/crypto/argon2` (`internal/httpapi/password.go:11`).** The only `argon2` commit in the window is: ``` 0b316e7ee409 2026-06-18 argon2: update RFC 9106 parameter recommendations "Update the IDKey example to use RFC 9106's first recommended Argon2id option and clarify the relationship between the first and second recommended options." (golang/go#79823) ``` That is a **doc-comment change only** — no exported signature, no default, no behavior. `internal/httpapi/password.go:23-29` pins the RFC 9106 *second* recommended set (`time=3, memory=64MiB, threads=4, keyLen=32, saltLen=16`) as explicit constants, so the revised example in upstream's docs does not reach us. **Do not touch `defaultArgonParams`** — it is a design §12 decision, not a copy of upstream's example. So: bump `golang.org/x/crypto v0.52.0 → v0.54.0` as routine hygiene, expect zero code impact, and leave `password.go` alone. ### Correction 2 — `golang.org/x/sync` is stale and was omitted entirely `go.mod:38` pins `golang.org/x/sync v0.21.0 // indirect`; latest is **v0.22.0**. Not mentioned anywhere in the body. Indirect, low-risk, let `go mod tidy` carry it. ### Re-confirmed, no change needed - **`GO-2026-5970` (x/text, fixed 0.39.0) is still the only advisory reaching any pin we carry.** Checked the full `vuln.go.dev` module index for all 13 modules in our graph on 2026-08-01: no new advisory since this issue was filed. `x/crypto`'s newest entries (`GO-2026-5005`/`5006`/`5013`–`5021`/`5023`/`5033`) are all `fixed: 0.52.0`; the one unfixed entry `GO-2026-5932` is `x/crypto/openpgp`, which we do not import. `x/sys` `GO-2026-5024` is `fixed: 0.44.0` (we are on v0.47.0). The body's security section is accurate as written. - **`modernc.org/sqlite v1.56.0` is still NOT on the Go module proxy** — the body flagged this as a thing to re-check: ``` $ curl -s https://proxy.golang.org/modernc.org/sqlite/@v/list | sort -V | tail -3 v1.53.0 v1.54.0 v1.55.0 ``` **`v1.55.0` remains the target.** The lockstep requirement is unchanged: it pins `modernc.org/libc v1.74.1` exactly. - `modernc.org/libc @latest` is now **v1.74.4** — consistent with the retraction note in the earlier comment (v1.74.2/v1.74.3 retracted). Do **not** take v1.74.4; take the `v1.74.1` that `sqlite v1.55.0` pins, exactly as the body says. - `golang.org/x/term v0.45.0` and `golang.org/x/sys v0.47.0` really are current — those two entries in the "do not touch" list are correct. - `goose/v3` stays at **v3.27.2**, blocked by the libc lockstep for the reason given in the earlier comment. Unchanged. ### Updated target table | Module | `go.mod` | Target | Note | |---|---|---|---| | `golang.org/x/text` (indirect) | v0.38.0 | **v0.40.0** | advisory GO-2026-5970 | | `modernc.org/sqlite` | v1.53.0 | **v1.55.0** | libc lockstep | | `modernc.org/libc` (indirect) | v1.73.4 | **v1.74.1** | exactly what sqlite v1.55.0 pins | | `github.com/prometheus/client_golang` | v1.23.2 | **v1.24.1** | | | `go.yaml.in/yaml/v2` | v2.4.2 | **v2.4.4** | | | `golang.org/x/crypto` | v0.52.0 | **v0.54.0** | *new — see Correction 1* | | `golang.org/x/sync` (indirect) | v0.21.0 | **v0.22.0** | *new — see Correction 2* | | `github.com/pressly/goose/v3` | v3.27.2 | *stays* | blocked, see earlier comment | Everything else in the body — the `vendorHash` trap at `nix/package.nix:56`, the DSN check at `internal/store/store.go:83-86`, the `client_golang` analysis, the verification commands, and the done-list — stands as written.
Author
Owner

Re-verified 2026-08-02 (Daily agent update check). Targets unchanged; the body has been corrected to fold in the goose block.

What changed on the issue since it was filed:

  • The goose finding from the 2026-07-31 comment is now in the body itself, not just a comment underneath it. It had been sitting in the evidence table as v3.27.2 → v3.27.3, in the scope list as "six lines", and in the Done checklist as "all six pins moved" — all three contradicted the comment. An implementing agent reading top-down would have bumped goose and broken the sqlite lockstep. The table row now reads stays v3.27.2, the module section spells out the MVS reasoning, and the checklist has an explicit goose is still v3.27.2 box plus a tripwire (libc above v1.74.1 means something pulled goose up).
  • Also corrected: golang.org/x/crypto was listed under "already current, do not touch". It is not current — v0.54.0 is out and we pin v0.52.0. The conclusion is unchanged (no bump needed: every 2026 advisory is in x/crypto/ssh*, we import only argon2), but the stated reason was wrong and is now stated correctly.
  • The "out of scope" note on the nixpkgs flake input now points at its own issue rather than describing it as untracked.

Nothing moved upstream in the two days since filing:

proxy.golang.org/@latest, 2026-08-02
  golang.org/x/text                    v0.40.0  (target, unchanged)
  modernc.org/sqlite                   v1.55.0  (target, unchanged)
  github.com/prometheus/client_golang  v1.24.1  (target, unchanged)
  go.yaml.in/yaml/v2                   v2.4.4   (target, unchanged)
  github.com/pressly/goose/v3          v3.27.3  (blocked, unchanged)
  modernc.org/libc                     v1.74.4  (NOT the target — v1.74.1 is)

proxy.golang.org/modernc.org/sqlite/@v/list | tail -1  →  v1.55.0

modernc.org/sqlite v1.56.0 is documented on upstream's master changelog but still has not published to the module proxy — the list still tops out at v1.55.0. v1.55.0 remains the target.

**Re-verified 2026-08-02 (Daily agent update check). Targets unchanged; the body has been corrected to fold in the `goose` block.** What changed on the issue since it was filed: - The `goose` finding from the 2026-07-31 comment is now **in the body itself**, not just a comment underneath it. It had been sitting in the evidence table as `v3.27.2 → v3.27.3`, in the scope list as "six lines", and in the Done checklist as "all six pins moved" — all three contradicted the comment. An implementing agent reading top-down would have bumped goose and broken the sqlite lockstep. The table row now reads **stays `v3.27.2`**, the module section spells out the MVS reasoning, and the checklist has an explicit *goose is still v3.27.2* box plus a tripwire (`libc` above `v1.74.1` means something pulled goose up). - Also corrected: `golang.org/x/crypto` was listed under "already current, do not touch". It is not current — `v0.54.0` is out and we pin `v0.52.0`. The *conclusion* is unchanged (no bump needed: every 2026 advisory is in `x/crypto/ssh*`, we import only `argon2`), but the stated reason was wrong and is now stated correctly. - The "out of scope" note on the nixpkgs flake input now points at its own issue rather than describing it as untracked. Nothing moved upstream in the two days since filing: ``` proxy.golang.org/@latest, 2026-08-02 golang.org/x/text v0.40.0 (target, unchanged) modernc.org/sqlite v1.55.0 (target, unchanged) github.com/prometheus/client_golang v1.24.1 (target, unchanged) go.yaml.in/yaml/v2 v2.4.4 (target, unchanged) github.com/pressly/goose/v3 v3.27.3 (blocked, unchanged) modernc.org/libc v1.74.4 (NOT the target — v1.74.1 is) proxy.golang.org/modernc.org/sqlite/@v/list | tail -1 → v1.55.0 ``` `modernc.org/sqlite v1.56.0` is documented on upstream's `master` changelog but **still has not published to the module proxy** — the list still tops out at `v1.55.0`. `v1.55.0` remains the target.
dominik.polakovics changed title from chore(deps): Go module updates — x/text advisory GO-2026-5970, sqlite 1.55.0 (+libc lockstep), client_golang 1.24.1, yaml 2.4.4, goose 3.27.3 [schedule: Daily agent update check] to chore(deps): Go module updates — x/text advisory GO-2026-5970, sqlite 1.55.0 (+libc lockstep), client_golang 1.24.1, yaml 2.4.4 (goose blocked) [schedule: Daily agent update check] 2026-08-02 04:13:48 +02:00
dominik.polakovics changed title from chore(deps): Go module updates — x/text advisory GO-2026-5970, sqlite 1.55.0 (+libc lockstep), client_golang 1.24.1, yaml 2.4.4 (goose blocked) [schedule: Daily agent update check] to chore(deps): Go module updates — advisories GO-2026-5970 (x/text) + GO-2025-3553 (golang-jwt), sqlite 1.55.0 (+libc lockstep), client_golang 1.24.1, x/crypto 0.54.0 (goose blocked) [schedule: Daily agent update check] 2026-08-03 04:15:09 +02:00
Author
Owner

Re-verified 2026-08-03 (Daily agent update check). Every previously-stated target is unchanged — but the sweep found a second security advisory this issue was missing, and the body has been rewritten around it.

New finding — GO-2025-3553 also reaches us

The body claimed, in bold, "One advisory reaches a version we pin: GO-2026-5970." That was wrong. go.mod:22 pins github.com/golang-jwt/jwt/v5 v5.2.1, which is inside:

GO-2025-3553  Excessive memory allocation during header parsing in github.com/golang-jwt/jwt
              (CVE-2025-30204, GHSA-mh63-6h87-95cp)
  github.com/golang-jwt/jwt/v5   introduced: 5.0.0-rc.1   fixed: 5.2.2
  affected symbol: Parser.ParseUnverified

Why the earlier passes missed it. The 2026-08-01 comment says it "Checked the full vuln.go.dev module index for all 13 modules in our graph." go.mod declares 34 modules — 10 direct and 24 indirect. Thirteen is the direct block plus a few; the indirect block was never swept. This pass checked all 34 against the complete vuln.go.dev module index. Seven modules appear in the index at all; of those, exactly two have an advisory whose affected range contains the version we pin — x/text (already known) and golang-jwt/jwt/v5 (new).

Expected reachability: none. jwt/v5 arrives via webpush-go v1.4.0, whose go.mod requires exactly v5.2.1. Its only jwt call site is vapid.go:80jwt.NewWithClaims(jwt.SigningMethodES256, …), the VAPID signing path that internal/push/sender.go:196 drives. The advisory's affected symbol is Parser.ParseUnverified; nothing here parses a JWT. govulncheck should report it unreachable. Bumping is still right — it costs nothing (below) and a range-based scanner will flag v5.2.1 indefinitely.

It costs nothing because MVS already carries it. client_golang v1.24.1's own go.mod — the bump this issue already specified — requires github.com/golang-jwt/jwt/v5 v5.3.1 // indirect:

$ curl -s https://proxy.golang.org/github.com/prometheus/client_golang/@v/v1.24.1.mod
  github.com/prometheus/common  v0.70.1
  github.com/prometheus/procfs  v0.21.1
  golang.org/x/text             v0.40.0
  go.yaml.in/yaml/v2            v2.4.4
  github.com/golang-jwt/jwt/v5  v5.3.1 // indirect

So one bump closes both advisories and carries four other targets. The risk was never that the fix was hard — it was that the done-list never told an implementing agent to check jwt landed, so a partial bump could have shipped looking complete. The Done section now has an explicit box for it.

Also folded into the body (were contradictions or omissions)

  • golang.org/x/crypto had two conflicting answers across the comments. The 2026-07-31 implementation comment says it was reverted to v0.52.0 because the body said leave it alone; the 2026-08-01 comment says "bump it as routine hygiene." An agent reading top-down got whichever it read last. The body now gives one answer — bump to v0.54.0 — with the argon2 analysis (only two of ~35 commits are outside ssh*/acme/openpgp; the single argon2 commit 0b316e7ee409 is a doc-comment change) and an explicit do not touch defaultArgonParams. It also notes MVS will not raise it, so it needs an explicit go get.
  • golang.org/x/sync v0.21.0 → v0.22.0 existed only in a comment. Now in the body table, marked hygiene, with the same "needs an explicit go get" note.
  • prometheus/common v0.66.1 → v0.70.1 and prometheus/procfs v0.20.1 → v0.21.1 were stale and unlisted anywhere. Both ride client_golang; now in the table.
  • Two stale indirects we are deliberately NOT moving, stated so the next sweep does not re-file them: mattn/go-isatty v0.0.21 (latest v0.0.24) and sethvargo/go-retry v0.3.0 (latest v0.4.0). Both are pinned at exactly our versions by goose v3.27.2, nothing else asks for more, neither has an advisory, so MVS will not raise them and forcing it buys nothing. There are now Done boxes asserting they stayed put.
  • New // indirect lines are expected. client_golang v1.24.1 + common v0.70.1 bring graph entries we do not carry (json-iterator/go, klauspost/compress, modern-go/*, jpillora/backoff, mwitkow/go-conntrack, x/net, x/oauth2). Whichever ones go mod tidy keeps will show up. Normal, not a finding — but it enlarges the go.sum diff, which is the vendorHash trap.
  • The nixpkgs out-of-scope note was stale. It said the flake input was "tracked on its own issue." flake.lock was actually moved on 2026-08-02 (commit bbc7f99, nixpkgs d407951148bab9c, go_1_26 1.26.4 → 1.26.5), so it is current and nothing is owed.

Re-confirmed unchanged (nothing moved upstream)

proxy.golang.org/@latest, 2026-08-03
  golang.org/x/text                    v0.40.0  (target, unchanged)
  modernc.org/sqlite                   v1.55.0  (target, unchanged)
  github.com/prometheus/client_golang  v1.24.1  (target, unchanged)
  go.yaml.in/yaml/v2                   v2.4.4   (target, unchanged)
  golang.org/x/crypto                  v0.54.0  (target, unchanged)
  github.com/pressly/goose/v3          v3.27.3  (blocked, unchanged)
  modernc.org/libc                     v1.74.4  (NOT the target — v1.74.1 is)

proxy.golang.org/modernc.org/sqlite/@v/list | tail -1  →  v1.55.0
  • modernc.org/sqlite v1.56.0 still has not published to the module proxy — third sweep in a row it is documented on upstream master but absent from the proxy. v1.55.0 remains the target, still lockstep-pinning libc v1.74.1.
  • goose stays blocked at v3.27.2 for the reason in the 2026-07-31 comment. v3.27.3 still requires the retracted libc v1.74.3.
  • The whole "already current, do not touch" list was re-checked against @latest and expanded to name every module that really is current, so a future sweep does not have to re-derive which is which.

Web/npm: investigated 2026-08-03, nothing actionable — no issue filed

The old out-of-scope line promised "Web/npm dependencies — separate issue." This closes that out. There is no issue to file, and the evidence is here so the next sweep skips it.

Zero advisories. All 270 packages in web/package-lock.json were submitted to the npm bulk advisory endpoint (registry.npmjs.org/-/npm/v1/security/advisories/bulk) at their locked versions. Empty response — no advisory against any installed version.

Twelve of fifteen declared dependencies are already at upstream latest, because the caret ranges float and package-lock.json has kept up: @solidjs/router 1.0.0, solid-js 1.9.14, @playwright/test 1.62.1, @typescript-eslint/{eslint-plugin,parser} 8.65.0, typescript-eslint 8.65.0, eslint-plugin-solid 0.14.5, jsdom 30.0.1, prettier 3.9.6, vite 8.2.0, vite-plugin-solid 2.11.14, vitest 4.1.10.

The three that are behind are all majors, and both upgrades are blocked upstream:

  1. typescript 6.0.3 → 7.0.2 (TS 7 is the native port). Blocked: typescript-eslint@8.65.0 declares peerDependencies.typescript: ">=4.8.4 <6.1.0", which excludes 7.x, and no stable typescript-eslint supports TS 7 yet (latest is 8.65.0; only alpha/canary tags exist beyond). web/package.json runs tsc --noEmit in npm run build, so this is not optional tooling. Also worth recording: TypeScript published no 6.1 — the 6.x line ends at 6.0.3 (2026-04-16) — so the ^6.0.3 range cannot drift into the excluded <6.1.0 boundary on its own. Nothing to do, and nothing latent.

  2. eslint 9.39.5 → 10.8.0 (and @eslint/js 9.39.5 → 10.0.1). Blocked on eslint-plugin-solid@0.14.5, which declares peerDependencies.eslint: "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" — no ^10 — and has not published since 2024-12-11. There is no maintained successor (npm search turns up only @ssen/eslint-plugin-solid@2.0.0-next.5, a third-party prerelease fork). The plugin is used at web/eslint.config.js:3.

    Worth recording precisely, because the obvious next question has already been answered: the plugin's code is forward-compatible; only its declared peer range is not. ESLint 10 removed the deprecated rule-context methods (fix!: Remove deprecated rule context methods, #20086), and eslint-plugin-solid does call context.getScope / context.getSourceCode / context.markVariableAsUsed — but all three go through a src/compat.ts shim that tries the modern API first:

    function getSourceCode(context) {
      if (typeof context.getSourceCode === "function") { return context.getSourceCode(); }
      return context.sourceCode;
    }
    function getScope(context, node) {
      const sourceCode = getSourceCode(context);
      if (typeof sourceCode.getScope === "function") { return sourceCode.getScope(node); }
      ...
    }
    

    So ESLint 10 would probably work if the peer range were forced with an npm overrides entry. That is not worth doing: it buys a version number, permanently installs an override hack against an abandoned plugin, and ESLint 10's other breaking changes (feat!: update eslint:recommended configuration, feat!: enable JSX reference tracking — which directly touches Solid's JSX and no-unused-vars) would likely churn source files. ESLint 9.39.5 is still upstream's maintenance dist-tag and carries no advisory.

Node runtime is fine either way. jsdom@30.0.1 has the strictest engines in the tree (^22.22.2 || ^24.15.0 || >=26.0.0); CI uses actions/setup-node with node-version: "24" (.forgejo/workflows/ci.yml:49-53) and nixpkgs at 148bab9c has nodejs = nodejs_24, so both build paths satisfy it.

**Re-verified 2026-08-03 (Daily agent update check). Every previously-stated target is unchanged — but the sweep found a second security advisory this issue was missing, and the body has been rewritten around it.** ## New finding — `GO-2025-3553` also reaches us The body claimed, in bold, *"One advisory reaches a version we pin: GO-2026-5970."* That was wrong. `go.mod:22` pins `github.com/golang-jwt/jwt/v5 v5.2.1`, which is inside: ``` GO-2025-3553 Excessive memory allocation during header parsing in github.com/golang-jwt/jwt (CVE-2025-30204, GHSA-mh63-6h87-95cp) github.com/golang-jwt/jwt/v5 introduced: 5.0.0-rc.1 fixed: 5.2.2 affected symbol: Parser.ParseUnverified ``` **Why the earlier passes missed it.** The 2026-08-01 comment says it *"Checked the full vuln.go.dev module index for all 13 modules in our graph."* `go.mod` declares **34** modules — 10 direct and 24 indirect. Thirteen is the direct block plus a few; the indirect block was never swept. This pass checked all 34 against the complete `vuln.go.dev` module index. Seven modules appear in the index at all; of those, exactly two have an advisory whose affected range contains the version we pin — `x/text` (already known) and `golang-jwt/jwt/v5` (new). **Expected reachability: none.** `jwt/v5` arrives via `webpush-go v1.4.0`, whose `go.mod` requires exactly `v5.2.1`. Its only jwt call site is `vapid.go:80` — `jwt.NewWithClaims(jwt.SigningMethodES256, …)`, the VAPID signing path that `internal/push/sender.go:196` drives. The advisory's affected symbol is `Parser.ParseUnverified`; nothing here parses a JWT. `govulncheck` should report it unreachable. Bumping is still right — it costs nothing (below) and a range-based scanner will flag `v5.2.1` indefinitely. **It costs nothing because MVS already carries it.** `client_golang v1.24.1`'s own `go.mod` — the bump this issue *already specified* — requires `github.com/golang-jwt/jwt/v5 v5.3.1 // indirect`: ``` $ curl -s https://proxy.golang.org/github.com/prometheus/client_golang/@v/v1.24.1.mod github.com/prometheus/common v0.70.1 github.com/prometheus/procfs v0.21.1 golang.org/x/text v0.40.0 go.yaml.in/yaml/v2 v2.4.4 github.com/golang-jwt/jwt/v5 v5.3.1 // indirect ``` So one bump closes **both** advisories and carries four other targets. The risk was never that the fix was hard — it was that the done-list never told an implementing agent to *check* jwt landed, so a partial bump could have shipped looking complete. The Done section now has an explicit box for it. ## Also folded into the body (were contradictions or omissions) - **`golang.org/x/crypto` had two conflicting answers across the comments.** The 2026-07-31 implementation comment says it was *reverted* to `v0.52.0` because the body said leave it alone; the 2026-08-01 comment says *"bump it as routine hygiene."* An agent reading top-down got whichever it read last. The body now gives one answer — **bump to `v0.54.0`** — with the argon2 analysis (only two of ~35 commits are outside `ssh*`/`acme`/`openpgp`; the single `argon2` commit `0b316e7ee409` is a doc-comment change) and an explicit *do not touch `defaultArgonParams`*. It also notes MVS will **not** raise it, so it needs an explicit `go get`. - **`golang.org/x/sync v0.21.0 → v0.22.0`** existed only in a comment. Now in the body table, marked hygiene, with the same "needs an explicit `go get`" note. - **`prometheus/common v0.66.1 → v0.70.1` and `prometheus/procfs v0.20.1 → v0.21.1`** were stale and unlisted anywhere. Both ride `client_golang`; now in the table. - **Two stale indirects we are deliberately NOT moving**, stated so the next sweep does not re-file them: `mattn/go-isatty v0.0.21` (latest `v0.0.24`) and `sethvargo/go-retry v0.3.0` (latest `v0.4.0`). Both are pinned at exactly our versions by `goose v3.27.2`, nothing else asks for more, neither has an advisory, so MVS will not raise them and forcing it buys nothing. There are now Done boxes asserting they stayed put. - **New `// indirect` lines are expected.** `client_golang v1.24.1` + `common v0.70.1` bring graph entries we do not carry (`json-iterator/go`, `klauspost/compress`, `modern-go/*`, `jpillora/backoff`, `mwitkow/go-conntrack`, `x/net`, `x/oauth2`). Whichever ones `go mod tidy` keeps will show up. Normal, not a finding — but it enlarges the `go.sum` diff, which is the `vendorHash` trap. - **The nixpkgs out-of-scope note was stale.** It said the flake input was *"tracked on its own issue."* `flake.lock` was actually moved on 2026-08-02 (commit `bbc7f99`, nixpkgs `d407951` → `148bab9c`, `go_1_26` 1.26.4 → 1.26.5), so it is current and nothing is owed. ## Re-confirmed unchanged (nothing moved upstream) ``` proxy.golang.org/@latest, 2026-08-03 golang.org/x/text v0.40.0 (target, unchanged) modernc.org/sqlite v1.55.0 (target, unchanged) github.com/prometheus/client_golang v1.24.1 (target, unchanged) go.yaml.in/yaml/v2 v2.4.4 (target, unchanged) golang.org/x/crypto v0.54.0 (target, unchanged) github.com/pressly/goose/v3 v3.27.3 (blocked, unchanged) modernc.org/libc v1.74.4 (NOT the target — v1.74.1 is) proxy.golang.org/modernc.org/sqlite/@v/list | tail -1 → v1.55.0 ``` - **`modernc.org/sqlite v1.56.0` still has not published to the module proxy** — third sweep in a row it is documented on upstream `master` but absent from the proxy. `v1.55.0` remains the target, still lockstep-pinning `libc v1.74.1`. - **`goose` stays blocked** at `v3.27.2` for the reason in the 2026-07-31 comment. `v3.27.3` still requires the retracted `libc v1.74.3`. - The whole "already current, do not touch" list was re-checked against `@latest` and expanded to name every module that really is current, so a future sweep does not have to re-derive which is which. --- ## Web/npm: investigated 2026-08-03, nothing actionable — no issue filed The old out-of-scope line promised *"Web/npm dependencies — separate issue."* This closes that out. There is no issue to file, and the evidence is here so the next sweep skips it. **Zero advisories.** All 270 packages in `web/package-lock.json` were submitted to the npm bulk advisory endpoint (`registry.npmjs.org/-/npm/v1/security/advisories/bulk`) at their locked versions. Empty response — no advisory against any installed version. **Twelve of fifteen declared dependencies are already at upstream `latest`**, because the caret ranges float and `package-lock.json` has kept up: `@solidjs/router 1.0.0`, `solid-js 1.9.14`, `@playwright/test 1.62.1`, `@typescript-eslint/{eslint-plugin,parser} 8.65.0`, `typescript-eslint 8.65.0`, `eslint-plugin-solid 0.14.5`, `jsdom 30.0.1`, `prettier 3.9.6`, `vite 8.2.0`, `vite-plugin-solid 2.11.14`, `vitest 4.1.10`. **The three that are behind are all majors, and both upgrades are blocked upstream:** 1. **`typescript` 6.0.3 → 7.0.2** (TS 7 is the native port). Blocked: `typescript-eslint@8.65.0` declares `peerDependencies.typescript: ">=4.8.4 <6.1.0"`, which excludes 7.x, and no stable typescript-eslint supports TS 7 yet (`latest` is 8.65.0; only alpha/canary tags exist beyond). `web/package.json` runs `tsc --noEmit` in `npm run build`, so this is not optional tooling. Also worth recording: TypeScript published **no 6.1** — the 6.x line ends at `6.0.3` (2026-04-16) — so the `^6.0.3` range cannot drift into the excluded `<6.1.0` boundary on its own. Nothing to do, and nothing latent. 2. **`eslint` 9.39.5 → 10.8.0** (and `@eslint/js` 9.39.5 → 10.0.1). Blocked on `eslint-plugin-solid@0.14.5`, which declares `peerDependencies.eslint: "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"` — no `^10` — and has not published since **2024-12-11**. There is no maintained successor (npm search turns up only `@ssen/eslint-plugin-solid@2.0.0-next.5`, a third-party prerelease fork). The plugin is used at `web/eslint.config.js:3`. Worth recording precisely, because the obvious next question has already been answered: **the plugin's code is forward-compatible; only its declared peer range is not.** ESLint 10 removed the deprecated rule-context methods (`fix!: Remove deprecated rule context methods`, #20086), and `eslint-plugin-solid` does call `context.getScope` / `context.getSourceCode` / `context.markVariableAsUsed` — but all three go through a `src/compat.ts` shim that tries the modern API first: ```js function getSourceCode(context) { if (typeof context.getSourceCode === "function") { return context.getSourceCode(); } return context.sourceCode; } function getScope(context, node) { const sourceCode = getSourceCode(context); if (typeof sourceCode.getScope === "function") { return sourceCode.getScope(node); } ... } ``` So ESLint 10 would probably work if the peer range were forced with an npm `overrides` entry. **That is not worth doing:** it buys a version number, permanently installs an override hack against an abandoned plugin, and ESLint 10's other breaking changes (`feat!: update eslint:recommended configuration`, `feat!: enable JSX reference tracking` — which directly touches Solid's JSX and `no-unused-vars`) would likely churn source files. ESLint 9.39.5 is still upstream's `maintenance` dist-tag and carries no advisory. **Node runtime is fine either way.** `jsdom@30.0.1` has the strictest `engines` in the tree (`^22.22.2 || ^24.15.0 || >=26.0.0`); CI uses `actions/setup-node` with `node-version: "24"` (`.forgejo/workflows/ci.yml:49-53`) and nixpkgs at `148bab9c` has `nodejs = nodejs_24`, so both build paths satisfy it.
dominik.polakovics changed title from chore(deps): Go module updates — advisories GO-2026-5970 (x/text) + GO-2025-3553 (golang-jwt), sqlite 1.55.0 (+libc lockstep), client_golang 1.24.1, x/crypto 0.54.0 (goose blocked) [schedule: Daily agent update check] to chore(deps): Go module updates — sqlite 1.56.0 (SQLite journal-rollback corruption fix, +libc 1.74.4 lockstep), goose 3.27.3 UNBLOCKED, advisories GO-2026-5970 (x/text) + GO-2025-3553 (golang-jwt), client_golang 1.24.1 [schedule: Daily agent update c… 2026-08-04 04:11:19 +02:00
Author
Owner

Re-verified 2026-08-04 (Daily agent update check). modernc.org/sqlite v1.56.0 finally published — and it changes three of this issue's conclusions. The body has been rewritten around it.

The previous three sweeps (2026-08-01, -02, -03) each checked and reported the same thing: "modernc.org/sqlite v1.56.0 is documented on upstream master but still has not published to the module proxy." It published 2026-08-03T14:31:47Z — roughly twelve hours after the 2026-08-03 sweep ran:

$ curl -s https://proxy.golang.org/modernc.org/sqlite/@v/list | sort -V | tail -3
v1.54.0
v1.55.0
v1.56.0
$ curl -s https://proxy.golang.org/modernc.org/sqlite/@v/v1.56.0.info
{"Version":"v1.56.0","Time":"2026-08-03T14:31:47Z", ...}

Change 1 — the sqlite target moves to v1.56.0, and the reason is data corruption

This is the substantive finding. v1.56.0's changelog entry, quoted in the body, describes a silent database-corruption bug in SQLite 3.53.3's journal rollback that v1.54.0 introduced and v1.55.0 still carries:

A crash during the commit of a multi-database (ATTACH) transaction can leave the super-journal name and its checksum zeroed while the name length and the trailing magic survive; the checksum is a plain byte sum, so an all-zero name still validates … pager_playback() then calls sqlite3OsAccess(pVfs, "", SQLITE_ACCESS_EXISTS), gets ENOENT, and deletes the hot journal without playing it back — leaving the database corrupted.

Upstream is explicit that this is not a transpilation artifact: "a plain gcc build of the stock 3.53.3 amalgamation fails on the same bytes while 3.53.2 recovers them," and it is what makes upstream's own test/crash.test fail in ~2% of runs on every platform.

Our current v1.53.0 embeds SQLite 3.53.2 — the version that recovers correctly. So the v1.55.0 this issue specified for four days would have moved us off a correct engine onto a knowingly-corrupting one. Nobody implemented it, so nothing shipped, but the target was wrong and is now v1.56.0.

Reachability for lab's own store: expected none — stated in the body with the reasoning so it can be checked rather than believed. Two conditions must both hold and neither does: the bug needs a super-journal, which only exists for an ATTACH transaction (grep -rn 'ATTACH' internal/ migrations/ → zero hits), and it needs a hot rollback journal to replay, while internal/store/store.go:84-86 pins journal_mode(WAL). The fix is therefore not urgent — but v1.56.0 costs nothing over v1.55.0 and is strictly better.

Change 2 — goose/v3 is UNBLOCKED

The body said, in bold, "BLOCKED at v3.27.2, do not bump", with a Done box and a tripwire built around it. That is no longer true, and the only thing that changed is which sqlite version we take.

sqlite v1.55.0 lockstep-pins libc v1.74.1     ← old target
sqlite v1.56.0 lockstep-pins libc v1.74.4     ← new target   (verified from the .mod)
goose  v3.27.3 requires      libc v1.74.3, sqlite v1.54.0

MVS with the OLD target:  libc = max(1.74.1, 1.74.3) = 1.74.3  ✗ retracted, and ≠ sqlite's pin
MVS with the NEW target:  libc = max(1.74.4, 1.74.3) = 1.74.4  ✓ == sqlite's pin

The retracted v1.74.3 is only ever required, never selected, once a higher version is in the graph — and v1.74.4 is the release that fixes the very freeaddrinfo deadlock the retraction cites (its retraction directives are in libc v1.74.4's own go.mod, which I read to confirm v1.74.4 is not itself retracted).

So goose v3.27.3 lands, the lockstep holds, and the "if libc goes above the pin, something pulled goose up" tripwire has been rewritten (it now trips on a retracted selection instead). This only works if the sqlite bump goes to v1.56.0 — the two must land together, which the body now says explicitly.

Change 3 — the two "do not move" indirects are now expected to move

The body told an implementing agent that github.com/mattn/go-isatty and github.com/sethvargo/go-retry must stay put, with Done boxes asserting it and an instruction to stop and investigate if go mod tidy moved either. That was correct only while goose was held at v3.27.2, which is what pinned their floor. With the movers above:

  • mattn/go-isatty v0.0.21v0.0.24 — required by sqlite v1.56.0 (indirect).
  • sethvargo/go-retry v0.3.0v0.4.0 — required by goose v3.27.3 (direct in goose).

Both instructions are inverted in the body, and the Done boxes now assert the new versions. Left as-is, they would have sent an agent chasing a phantom regression on a correct go mod tidy result.

Knock-on: golang.org/x/sync v0.22.0 no longer needs an explicit go get either — goose v3.27.3 requires it, so MVS carries it. golang.org/x/crypto is now the only target needing an explicit go get.

Also expect two new indirects from sqlite v1.56.0 that no previous sweep anticipated: github.com/google/pprof and modernc.org/fileutil v1.4.0. Combined with the goose graph this makes the go.sum diff considerably larger than previously estimated — which raises, not lowers, the odds of the nix/package.nix:56 vendorHash trap biting. That warning is unchanged and still the most likely way this PR fails CI.

Unchanged — re-confirmed against proxy.golang.org/@latest, 2026-08-04

golang.org/x/text                    v0.40.0  (target, unchanged)
github.com/golang-jwt/jwt/v5         v5.3.1   (target, unchanged)
github.com/prometheus/client_golang  v1.24.1  (target, unchanged)
github.com/prometheus/common         v0.70.1  (target, unchanged)
github.com/prometheus/procfs         v0.21.1  (target, unchanged)
go.yaml.in/yaml/v2                   v2.4.4   (target, unchanged)
golang.org/x/crypto                  v0.54.0  (target, unchanged)
golang.org/x/sync                    v0.22.0  (target, now carried by goose)
modernc.org/libc                     v1.74.4  (NOW the target — was v1.74.1)
modernc.org/sqlite                   v1.56.0  (NOW the target — was v1.55.0)
github.com/pressly/goose/v3          v3.27.3  (NOW the target — was "blocked")

Both advisories (GO-2026-5970 x/text, GO-2025-3553 golang-jwt) still reach the versions we pin; the full 34-module vuln.go.dev sweep from 2026-08-03 was re-run and turned up nothing new. Everything on the "already current, do not touch" list is still at @latest. The client_golang, x/crypto/argon2 and DSN analyses stand as written.

Adjacent surfaces re-checked this sweep — nothing to file

  • flake.lock — nixpkgs 148bab9c, locked 2026-08-01; nixos-unstable HEAD is 643809054d65 (2026-08-02). One day behind. Nothing owed.
  • Web/npm — re-ran the whole check independently of the 2026-08-03 comment and reached the same conclusion, so that comment's evidence stands. Deltas since: typescript-eslint (and @typescript-eslint/*) 8.65.08.66.0, and eslint 10.7.x10.8.0. Neither changes anything. typescript-eslint@8.66.0 still declares peerDependencies.typescript: ">=4.8.4 <6.1.0", so TypeScript 7.0.2 stays blocked and there is still no stable typescript-eslint v9. eslint-plugin-solid is still 0.14.5 (last published 2024-12-11) with peerDependencies.eslint: "^6 || ^7 || ^8 || ^9", so ESLint 10.8.0 stays blocked. The lockfile is otherwise at latest on every floating range (vite 8.2.0, vitest 4.1.10, prettier 3.9.6, @playwright/test 1.62.1, vite-plugin-solid 2.11.14, solid-js 1.9.14, jsdom 30.0.1). A lone typescript-eslint 8.65→8.66 bump is not worth an agent run.
  • CI action pinsactions/checkout@v7, actions/setup-node@v7, actions/setup-go@v7, actions/cache/{restore,save}@v6 across ci.yml, ci-nix.yml, deploy.yml, agent-tools.yml. All current.
  • Container base imagescontainers/agent-tools/Containerfile.claude uses golang:1.26-alpine (floating; currently resolves to 1.26.5) and alpine:3.22 (floating within 3.22.x; upstream latest line is 3.24). Both are build stages only — the shipped image is FROM scratch — and alpine:3.22 still receives security patches, which the floating tag picks up automatically. Not worth an issue.
  • Agent-tools CLI pins — codex on #249 (0.146.0 still the newest stable), Claude Code on #235 plus a new issue for 2.1.221, which published 2026-08-03 and carries a Bash-tool permission-check fix.
**Re-verified 2026-08-04 (Daily agent update check). `modernc.org/sqlite v1.56.0` finally published — and it changes three of this issue's conclusions. The body has been rewritten around it.** The previous three sweeps (2026-08-01, -02, -03) each checked and reported the same thing: *"`modernc.org/sqlite v1.56.0` is documented on upstream `master` but still has not published to the module proxy."* It published **2026-08-03T14:31:47Z** — roughly twelve hours *after* the 2026-08-03 sweep ran: ``` $ curl -s https://proxy.golang.org/modernc.org/sqlite/@v/list | sort -V | tail -3 v1.54.0 v1.55.0 v1.56.0 $ curl -s https://proxy.golang.org/modernc.org/sqlite/@v/v1.56.0.info {"Version":"v1.56.0","Time":"2026-08-03T14:31:47Z", ...} ``` ## Change 1 — the sqlite target moves to v1.56.0, and the reason is data corruption This is the substantive finding. `v1.56.0`'s changelog entry, quoted in the body, describes a **silent database-corruption bug in SQLite 3.53.3's journal rollback** that `v1.54.0` introduced and `v1.55.0` still carries: > A crash during the commit of a multi-database (ATTACH) transaction can leave the super-journal name and its checksum zeroed while the name length and the trailing magic survive; the checksum is a plain byte sum, so an all-zero name still validates … `pager_playback()` then calls `sqlite3OsAccess(pVfs, "", SQLITE_ACCESS_EXISTS)`, gets ENOENT, and **deletes the hot journal without playing it back — leaving the database corrupted.** Upstream is explicit that this is not a transpilation artifact: *"a plain gcc build of the stock 3.53.3 amalgamation fails on the same bytes while 3.53.2 recovers them,"* and it is what makes upstream's own `test/crash.test` fail in ~2% of runs on every platform. Our current `v1.53.0` embeds SQLite **3.53.2** — the version that recovers correctly. **So the `v1.55.0` this issue specified for four days would have moved us off a correct engine onto a knowingly-corrupting one.** Nobody implemented it, so nothing shipped, but the target was wrong and is now `v1.56.0`. **Reachability for lab's own store: expected none** — stated in the body with the reasoning so it can be checked rather than believed. Two conditions must both hold and neither does: the bug needs a super-journal, which only exists for an `ATTACH` transaction (`grep -rn 'ATTACH' internal/ migrations/` → zero hits), and it needs a hot *rollback* journal to replay, while `internal/store/store.go:84-86` pins `journal_mode(WAL)`. The fix is therefore not urgent — but `v1.56.0` costs nothing over `v1.55.0` and is strictly better. ## Change 2 — `goose/v3` is UNBLOCKED The body said, in bold, **"BLOCKED at v3.27.2, do not bump"**, with a Done box and a tripwire built around it. That is no longer true, and the *only* thing that changed is which sqlite version we take. ``` sqlite v1.55.0 lockstep-pins libc v1.74.1 ← old target sqlite v1.56.0 lockstep-pins libc v1.74.4 ← new target (verified from the .mod) goose v3.27.3 requires libc v1.74.3, sqlite v1.54.0 MVS with the OLD target: libc = max(1.74.1, 1.74.3) = 1.74.3 ✗ retracted, and ≠ sqlite's pin MVS with the NEW target: libc = max(1.74.4, 1.74.3) = 1.74.4 ✓ == sqlite's pin ``` The retracted `v1.74.3` is only ever *required*, never *selected*, once a higher version is in the graph — and `v1.74.4` is the release that fixes the very `freeaddrinfo` deadlock the retraction cites (its retraction directives are in `libc v1.74.4`'s own `go.mod`, which I read to confirm `v1.74.4` is not itself retracted). So `goose v3.27.3` lands, the lockstep holds, and the "if `libc` goes above the pin, something pulled goose up" tripwire has been rewritten (it now trips on a *retracted* selection instead). **This only works if the sqlite bump goes to v1.56.0** — the two must land together, which the body now says explicitly. ## Change 3 — the two "do not move" indirects are now expected to move The body told an implementing agent that `github.com/mattn/go-isatty` and `github.com/sethvargo/go-retry` must stay put, with Done boxes asserting it and an instruction to stop and investigate if `go mod tidy` moved either. That was correct **only while goose was held at v3.27.2**, which is what pinned their floor. With the movers above: - `mattn/go-isatty` `v0.0.21` → **`v0.0.24`** — required by `sqlite v1.56.0` (indirect). - `sethvargo/go-retry` `v0.3.0` → **`v0.4.0`** — required by `goose v3.27.3` (direct in goose). Both instructions are inverted in the body, and the Done boxes now assert the new versions. Left as-is, they would have sent an agent chasing a phantom regression on a correct `go mod tidy` result. Knock-on: `golang.org/x/sync v0.22.0` no longer needs an explicit `go get` either — `goose v3.27.3` requires it, so MVS carries it. `golang.org/x/crypto` is now the **only** target needing an explicit `go get`. Also expect two new indirects from sqlite v1.56.0 that no previous sweep anticipated: `github.com/google/pprof` and `modernc.org/fileutil v1.4.0`. Combined with the goose graph this makes the `go.sum` diff considerably larger than previously estimated — which raises, not lowers, the odds of the `nix/package.nix:56` `vendorHash` trap biting. That warning is unchanged and still the most likely way this PR fails CI. ## Unchanged — re-confirmed against `proxy.golang.org/@latest`, 2026-08-04 ``` golang.org/x/text v0.40.0 (target, unchanged) github.com/golang-jwt/jwt/v5 v5.3.1 (target, unchanged) github.com/prometheus/client_golang v1.24.1 (target, unchanged) github.com/prometheus/common v0.70.1 (target, unchanged) github.com/prometheus/procfs v0.21.1 (target, unchanged) go.yaml.in/yaml/v2 v2.4.4 (target, unchanged) golang.org/x/crypto v0.54.0 (target, unchanged) golang.org/x/sync v0.22.0 (target, now carried by goose) modernc.org/libc v1.74.4 (NOW the target — was v1.74.1) modernc.org/sqlite v1.56.0 (NOW the target — was v1.55.0) github.com/pressly/goose/v3 v3.27.3 (NOW the target — was "blocked") ``` Both advisories (`GO-2026-5970` x/text, `GO-2025-3553` golang-jwt) still reach the versions we pin; the full 34-module `vuln.go.dev` sweep from 2026-08-03 was re-run and turned up nothing new. Everything on the "already current, do not touch" list is still at `@latest`. The `client_golang`, `x/crypto`/argon2 and DSN analyses stand as written. ## Adjacent surfaces re-checked this sweep — nothing to file - **`flake.lock`** — nixpkgs `148bab9c`, locked 2026-08-01; `nixos-unstable` HEAD is `643809054d65` (2026-08-02). One day behind. Nothing owed. - **Web/npm** — re-ran the whole check independently of the 2026-08-03 comment and reached the same conclusion, so that comment's evidence stands. Deltas since: `typescript-eslint` (and `@typescript-eslint/*`) `8.65.0` → `8.66.0`, and `eslint` `10.7.x` → `10.8.0`. Neither changes anything. `typescript-eslint@8.66.0` still declares `peerDependencies.typescript: ">=4.8.4 <6.1.0"`, so **TypeScript 7.0.2 stays blocked** and there is still no stable typescript-eslint v9. `eslint-plugin-solid` is still `0.14.5` (last published 2024-12-11) with `peerDependencies.eslint: "^6 || ^7 || ^8 || ^9"`, so **ESLint 10.8.0 stays blocked**. The lockfile is otherwise at `latest` on every floating range (vite 8.2.0, vitest 4.1.10, prettier 3.9.6, @playwright/test 1.62.1, vite-plugin-solid 2.11.14, solid-js 1.9.14, jsdom 30.0.1). A lone `typescript-eslint` 8.65→8.66 bump is not worth an agent run. - **CI action pins** — `actions/checkout@v7`, `actions/setup-node@v7`, `actions/setup-go@v7`, `actions/cache/{restore,save}@v6` across `ci.yml`, `ci-nix.yml`, `deploy.yml`, `agent-tools.yml`. All current. - **Container base images** — `containers/agent-tools/Containerfile.claude` uses `golang:1.26-alpine` (floating; currently resolves to 1.26.5) and `alpine:3.22` (floating within 3.22.x; upstream latest line is 3.24). Both are **build stages only** — the shipped image is `FROM scratch` — and `alpine:3.22` still receives security patches, which the floating tag picks up automatically. Not worth an issue. - **Agent-tools CLI pins** — codex on #249 (`0.146.0` still the newest stable), Claude Code on #235 plus a new issue for `2.1.221`, which published 2026-08-03 and carries a Bash-tool permission-check fix.
dominik.polakovics changed title from chore(deps): Go module updates — sqlite 1.56.0 (SQLite journal-rollback corruption fix, +libc 1.74.4 lockstep), goose 3.27.3 UNBLOCKED, advisories GO-2026-5970 (x/text) + GO-2025-3553 (golang-jwt), client_golang 1.24.1 [schedule: Daily agent update c… to chore(deps): Go modules — sqlite 1.56.0 (corruption fix) + libc 1.74.4 lockstep, goose 3.27.3 unblocked, advisories GO-2026-5970 + GO-2025-3553 [schedule: Daily agent update check] 2026-08-04 04:13:29 +02:00
Author
Owner

Re-verified 2026-08-05 (Daily agent update check). Every target version in the rewritten body is still upstream @latest — no edits needed. The body stands exactly as rewritten on 2026-08-04.

Full proxy.golang.org/<module>/@latest sweep of all 29 modules in go.mod, today:

MODULE                                  go.mod      @latest     PUBLISHED
modernc.org/sqlite                      v1.53.0     v1.56.0     2026-08-03   <== BEHIND
modernc.org/libc            (indirect)  v1.73.4     v1.74.4     2026-07-27   <== BEHIND
golang.org/x/text           (indirect)  v0.38.0     v0.40.0     2026-07-08   <== BEHIND
github.com/golang-jwt/jwt/v5(indirect)  v5.2.1      v5.3.1      2026-01-28   <== BEHIND
github.com/pressly/goose/v3             v3.27.2     v3.27.3     2026-07-22   <== BEHIND
github.com/prometheus/client_golang     v1.23.2     v1.24.1     2026-07-24   <== BEHIND
github.com/prometheus/common (indirect) v0.66.1     v0.70.1     2026-07-22   <== BEHIND
github.com/prometheus/procfs (indirect) v0.20.1     v0.21.1     2026-06-30   <== BEHIND
golang.org/x/crypto                     v0.52.0     v0.54.0     2026-07-08   <== BEHIND
golang.org/x/sync           (indirect)  v0.21.0     v0.22.0     2026-07-01   <== BEHIND
go.yaml.in/yaml/v2                      v2.4.2      v2.4.4      2026-03-06   <== BEHIND
github.com/mattn/go-isatty  (indirect)  v0.0.21     v0.0.24     2026-07-23   <== BEHIND
github.com/sethvargo/go-retry(indirect) v0.3.0      v0.4.0      2026-07-17   <== BEHIND

That is exactly the body's table — same 13 modules, same targets, nothing added, nothing moved. In particular modernc.org/sqlite is still v1.56.0 (no v1.57.x since the 2026-08-03 publish that triggered the rewrite) and modernc.org/libc is still v1.74.4, so the lockstep pair is unchanged and goose v3.27.3 stays unblocked.

The remaining 16 modules re-confirmed at @latest, matching the body's "already current, do not touch" list: pgx/v5 v5.10.0, webpush-go v1.4.0, client_model v0.6.2, x/sys v0.47.0, x/term v0.45.0, protobuf v1.36.11, mathutil v1.7.1, memory v1.11.0, uuid v1.6.0, xxhash/v2 v2.3.0, go-humanize v1.0.1, go-strftime v1.0.0, puddle/v2 v2.2.2, interpolate v0.0.2, multierr v1.11.0, perks v1.0.1.

Advisory re-check — no new advisory reaches any pin, and the body's x/crypto reasoning is confirmed

Queried api.osv.dev/v1/querybatch for all 18 non-trivial modules at their currently pinned versions. Exactly three hits, all already in the body:

golang.org/x/crypto        v0.52.0  ->  GO-2026-5932
golang.org/x/text          v0.38.0  ->  GO-2026-5970
github.com/golang-jwt/jwt/v5 v5.2.1 ->  GO-2025-3553, GHSA-mh63-6h87-95cp

GO-2026-5932 is the one the body dismisses, and the dismissal is correct — confirmed against the advisory's own affected-imports list this run:

$ curl -s https://vuln.go.dev/ID/GO-2026-5932.json
summary: The golang.org/x/crypto/openpgp package is unmaintained, unsafe by
         design, and has known security issues
affected imports: golang.org/x/crypto/openpgp{,/packet,/armor,/clearsign,
                  /errors,/elgamal,/s2k}
ranges: introduced 0   (no fixed version — the package is simply unmaintained)

Every affected import is under openpgp/. This repo imports exactly one x/crypto package, golang.org/x/crypto/argon2 (internal/httpapi/password.go:11), so the advisory does not reach us and — note for the implementer — it will still be "open" against v0.54.0 after the bump, because it has no fixed version. That is expected and is not a reason to hold the bump: govulncheck reports on the call graph, so it will stay clean. The x/crypto row remains hygiene, exactly as the body says.

So the security section is unchanged: GO-2026-5970 (x/text, fixed 0.39.0) and GO-2025-3553 (jwt/v5, fixed 5.3.0) remain the only two advisories that reach a pin we carry, and both are closed by the targets already in the table.

Nothing to correct. This comment exists so the next sweep can see the full graph was re-swept rather than assumed.

Companion sweeps this run, for cross-reference: codex on #249 (re-verified, no change), and a new issue #290 — Claude Code 2.1.2212.1.222. Also swept and found clean, so nobody re-derives them: the web/ npm dependency tree (everything at @latest except typescript-eslint 8.65.0 → 8.66.0; ESLint 10 and TypeScript 7 are both blocked by upstream peer ranges, see #290's sibling note), the buildpack-deps:stable-scm digest in nix/module.nix (byte-identical to the tag's current digest), and the Forgejo workflow action pins (checkout@v7, setup-node@v7, setup-go@v7, cache@v6 — all current majors).

**Re-verified 2026-08-05 (Daily agent update check). Every target version in the rewritten body is still upstream `@latest` — no edits needed. The body stands exactly as rewritten on 2026-08-04.** Full `proxy.golang.org/<module>/@latest` sweep of all 29 modules in `go.mod`, today: ``` MODULE go.mod @latest PUBLISHED modernc.org/sqlite v1.53.0 v1.56.0 2026-08-03 <== BEHIND modernc.org/libc (indirect) v1.73.4 v1.74.4 2026-07-27 <== BEHIND golang.org/x/text (indirect) v0.38.0 v0.40.0 2026-07-08 <== BEHIND github.com/golang-jwt/jwt/v5(indirect) v5.2.1 v5.3.1 2026-01-28 <== BEHIND github.com/pressly/goose/v3 v3.27.2 v3.27.3 2026-07-22 <== BEHIND github.com/prometheus/client_golang v1.23.2 v1.24.1 2026-07-24 <== BEHIND github.com/prometheus/common (indirect) v0.66.1 v0.70.1 2026-07-22 <== BEHIND github.com/prometheus/procfs (indirect) v0.20.1 v0.21.1 2026-06-30 <== BEHIND golang.org/x/crypto v0.52.0 v0.54.0 2026-07-08 <== BEHIND golang.org/x/sync (indirect) v0.21.0 v0.22.0 2026-07-01 <== BEHIND go.yaml.in/yaml/v2 v2.4.2 v2.4.4 2026-03-06 <== BEHIND github.com/mattn/go-isatty (indirect) v0.0.21 v0.0.24 2026-07-23 <== BEHIND github.com/sethvargo/go-retry(indirect) v0.3.0 v0.4.0 2026-07-17 <== BEHIND ``` That is **exactly** the body's table — same 13 modules, same targets, nothing added, nothing moved. In particular `modernc.org/sqlite` is still `v1.56.0` (no `v1.57.x` since the 2026-08-03 publish that triggered the rewrite) and `modernc.org/libc` is still `v1.74.4`, so the **lockstep pair is unchanged** and `goose v3.27.3` stays unblocked. The remaining 16 modules re-confirmed at `@latest`, matching the body's "already current, do not touch" list: `pgx/v5 v5.10.0`, `webpush-go v1.4.0`, `client_model v0.6.2`, `x/sys v0.47.0`, `x/term v0.45.0`, `protobuf v1.36.11`, `mathutil v1.7.1`, `memory v1.11.0`, `uuid v1.6.0`, `xxhash/v2 v2.3.0`, `go-humanize v1.0.1`, `go-strftime v1.0.0`, `puddle/v2 v2.2.2`, `interpolate v0.0.2`, `multierr v1.11.0`, `perks v1.0.1`. ## Advisory re-check — no new advisory reaches any pin, and the body's `x/crypto` reasoning is confirmed Queried `api.osv.dev/v1/querybatch` for all 18 non-trivial modules at their **currently pinned** versions. Exactly three hits, all already in the body: ``` golang.org/x/crypto v0.52.0 -> GO-2026-5932 golang.org/x/text v0.38.0 -> GO-2026-5970 github.com/golang-jwt/jwt/v5 v5.2.1 -> GO-2025-3553, GHSA-mh63-6h87-95cp ``` `GO-2026-5932` is the one the body dismisses, and the dismissal is **correct** — confirmed against the advisory's own affected-imports list this run: ``` $ curl -s https://vuln.go.dev/ID/GO-2026-5932.json summary: The golang.org/x/crypto/openpgp package is unmaintained, unsafe by design, and has known security issues affected imports: golang.org/x/crypto/openpgp{,/packet,/armor,/clearsign, /errors,/elgamal,/s2k} ranges: introduced 0 (no fixed version — the package is simply unmaintained) ``` Every affected import is under `openpgp/`. This repo imports exactly one `x/crypto` package, `golang.org/x/crypto/argon2` (`internal/httpapi/password.go:11`), so the advisory does not reach us and — note for the implementer — **it will still be "open" against `v0.54.0` after the bump**, because it has no fixed version. That is expected and is not a reason to hold the bump: `govulncheck` reports on the *call graph*, so it will stay clean. The `x/crypto` row remains hygiene, exactly as the body says. So the security section is unchanged: `GO-2026-5970` (x/text, fixed 0.39.0) and `GO-2025-3553` (jwt/v5, fixed 5.3.0) remain the only two advisories that reach a pin we carry, and both are closed by the targets already in the table. Nothing to correct. This comment exists so the next sweep can see the full graph was re-swept rather than assumed. **Companion sweeps this run, for cross-reference:** codex on #249 (re-verified, no change), and a **new** issue **#290** — Claude Code `2.1.221` → `2.1.222`. Also swept and found clean, so nobody re-derives them: the `web/` npm dependency tree (everything at `@latest` except `typescript-eslint` 8.65.0 → 8.66.0; ESLint 10 and TypeScript 7 are both blocked by upstream peer ranges, see #290's sibling note), the `buildpack-deps:stable-scm` digest in `nix/module.nix` (byte-identical to the tag's current digest), and the Forgejo workflow action pins (`checkout@v7`, `setup-node@v7`, `setup-go@v7`, `cache@v6` — all current majors).
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Cloonar/coding-lab#250
No description provided.