The proposal is one environment variable. Set GOCOOLDOWN=15d and the go command stops considering any module version published in the last fifteen days. The interesting part is not whether that works. It is that after eight months nobody had to say.
The idea behind a cooldown is that supply chain attacks get caught quickly. Someone compromises a package, publishes a bad version, and the gap between that version going public and the ecosystem pulling it is usually short. Wait out the gap and you never install it. You inspect nothing. You verify nothing. You wait, and other people’s attention does the work.
The proposal cites one blog post for the empirical half of this. The post carries a table of ten incidents, eight of them with windows under a week, and its author is candid about what that is: “in the very small sample set above.”
The thread that follows is careful work. Whether the module proxy or the go command should enforce it. What happens when an attacker backdates a git tag. Whether your own private modules should be exempt, and whether GOPRIVATE is the right lever for that. What go list -m -u ought to print when a newer version exists but sits inside the window. Go’s security team was in the thread. So was the working group that owns the go command.
rsc’s suggestion was not to specify the policy. It was to move it.
Between the go command and a module’s source sits a proxy. It does two things: lists the versions of a module, and hands one over. It already takes instructions in its URL - point at proxy.golang.org/cached-only/ and it serves only what it has already seen. The suggestion was one more prefix. Point GOPROXY at proxy.golang.org/delay/7d/ and the version list it hands back omits anything younger than a week. The go command needs no change at all. Every Go release already installed can do this today.
He named the benefit plainly. It works with every existing Go release, and it needs “no consensus on what the new go support should look like.”
Four hours later the go command working group posted its own read on the same thread: biased against doing it, and the proposal underspecified in terms of policy. Three months after that, the proposal review group put the proposal on hold. “We’re going to see what it looks like to implement this at the module proxy layer first,” the security team wrote. “If that design ends up making sense, we’ll revisit what it’d look like to add simpler toolchain support.”
That is the right call. A URL prefix that works on every installed Go beats two more years of arguing about defaults. It is cheap, it is reversible, and it lets people find out.
Forty days on, /delay/7d/ returns a 404. /cached-only/ still returns 200.
Find out what, though.
Adoption is what the experiment produces by itself. Some number of people will set GOPROXY and leave it set. That number will move one way or the other, and it will be legible without anyone doing extra work to read it.
Efficacy is a different question and it is the one the thread never settled. Go already has a checksum database that stops a published version from being redefined. It also selects versions in a way that keeps you off the newest release of your transitive dependencies, which is the surface that burned other ecosystems. Whether a cooldown adds anything on top of those was raised early, answered reasonably, and never tested. Testing it means measuring a counterfactual: how many fetches would have pulled a version later found to be malicious. That is computable. The proxy sees which versions get fetched. The vulnerability database records which ones went bad. Someone has to sit down and join the two.
Nothing in the resolution asks anyone to.
A year from now the prefix will be in wide use or it won’t, and whichever it turns out to be will read as a verdict. The ten rows will still be the evidence.
This blog’s .github/dependabot.yml has no cooldown key in it. Updates arrive weekly, grouped, and I merge them by hand whenever I get to them, which is somewhere between a day and a week later. That is a cooldown. I did not choose it as one, and I have not made it one since noticing.
Hold is not a verdict. It is a way of not needing one.
