Skip to content

feat: the GOMAXPROCS finding rests on a build fact, not on a toolchain version (ADR 0050) - #85

Merged
kfeofantov merged 1 commit into
mainfrom
feat/godebug-defaults-are-build-facts
Aug 29, 2026
Merged

kfeofantov merged 1 commit into
mainfrom
feat/godebug-defaults-are-build-facts

Conversation

@kfeofantov

Copy link
Copy Markdown
Contributor

Go 1.25 made the runtime size GOMAXPROCS from the cgroup CPU quota
(containermaxprocs) and follow a quota that changes under it
(updatemaxprocs). Which behaviour a binary gets follows from the main
module's go directive
, not from the toolchain that compiled it — so
go_build.go_version, which is the toolchain, does not separate a build that
reads the quota from one that counts the node's cores. Today the first-hour
finding fires on both, and the fleet where it is wrong is the fleet that already
did the work. ADR 0047's Context states the pre-1.25 runtime as the runtime;
ADR 0050 corrects it there rather than editing an accepted body.

What ships. The node parses the toolchain's compound DefaultGODEBUG build
setting and keeps those two names, as go_build.godebug. The parse happens
before the node→controller channel, so nothing outside the list crosses the wire.

Why parsed and not allow-listed whole. The compound value carries every
deviating setting — six for a module on go 1.21, mostly TLS, net/http and
go/types. Keeping it whole would ship all of them, then drop the value against
ADR 0019's 128-character bound, which lands on long lists, which are the old go
directives, which are the only builds this field exists to find. The failure mode
would be silence on exactly the population the finding is about.

Ceilings. security.md 930 → 940, backend-requirements.md 460 → 475, with
the reason in prose_test.go: an absent name means the build takes its
toolchain's default, not 0, and that obligation does not fit a table row.

No new RBAC, no new read, no new privilege — DefaultGODEBUG is in build info
the scanner already opens.

Evidence:

go test -race ./...   # green
make lint             # 0 issues

The -update run touched one golden (go-build.golden.json) and no other.

🤖 Generated with Claude Code

https://claude.ai/code/session_011YRKuL97KRndaopfpixrhp

…n version (ADR 0050)

Go 1.25 made the runtime size GOMAXPROCS from the cgroup CPU quota, and the
default follows the main module's `go` directive rather than the toolchain that
compiled the binary. `go_build.go_version` is the toolchain, so nothing shipped
today separates a build that reads the quota from one that counts the node's
cores — and ADR 0047's Context states the old behaviour as universal.

The toolchain records the difference in a compound `DefaultGODEBUG` build
setting. The node parses it and keeps two names, `containermaxprocs` and
`updatemaxprocs`, before the channel; the compound value never crosses the wire.
Allow-listing it whole would have shipped the TLS and net/http switches it also
carries, then dropped the value against ADR 0019's 128-character bound — which
lands on the long lists, which are the old `go` directives, which are the only
builds this field exists to find.

security.md 930 → 940 and backend-requirements.md 460 → 475: an absent name is
the toolchain's own default, not a zero, and that obligation does not fit a
table row.

    go test -race ./... && make lint   # green, 0 issues

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011YRKuL97KRndaopfpixrhp
@kfeofantov
kfeofantov force-pushed the feat/godebug-defaults-are-build-facts branch from b061cc5 to e542ec2 Compare August 29, 2026 07:46
@kfeofantov
kfeofantov merged commit 31885de into main Aug 29, 2026
3 checks passed
@kfeofantov
kfeofantov deleted the feat/godebug-defaults-are-build-facts branch August 29, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant