Surfaced while implementing #117, where the implementer noticed script/bootstrap rewriting go.mod and correctly reverted it rather than carrying an unrelated change. The underlying cause is more specific than "bootstrap mutates the tree".
The actual defect
go.mod on main lists the same module twice:
line 16: golang.org/x/sync v0.19.0 (direct require block)
line 43: golang.org/x/sync v0.19.0 // indirect
It is genuinely a direct dependency — internal/portcheck/portcheck.go:15 imports golang.org/x/sync/errgroup. So the // indirect entry is redundant and stale, and go mod tidy would collapse it.
REPO_POLICIES.md is explicit: "Always run go mod tidy before committing." That did not happen for whichever commit introduced this.
Why it is worth fixing rather than ignoring
script/bootstrap ends with go mod download, which updates the main module's requirements and therefore drops the redundant line as a side effect. Consequences:
Running script/bootstrap on a clean checkout leaves git status dirty. Every agent on this repo runs bootstrap in a fresh worktree, so every one of them starts against a modified tracked file.
That is a trap for exactly the mistake this repo has been careful about elsewhere: an implementer staging files by name may still commit a go.mod change they did not make and cannot explain, or waste time investigating a diff that is not theirs.
It is also a small integrity problem in its own right. go.mod is a dependency manifest, and one that does not survive a no-op tooling run is not in a settled state.
This is not a security issue — the module hash is in go.sum either way, so the pinning rule is satisfied.
Definition of done
go.mod is tidy: run go mod tidy and commit the result. Expect the redundant golang.org/x/sync v0.19.0 // indirect line to disappear and the direct requirement at line 16 to remain.
go.sum is consistent afterwards.
A clean checkout stays clean across bootstrap. Verify: fresh worktree, git status --porcelain empty, run script/bootstrap, confirm git status --porcelain is still empty. Run it a second time and confirm the same. This is the check that fails today, so it is a real test rather than a formality.
make check green; TODO.md updated in the same commit.
Confirm no dependency is actually removed — go mod tidy dropping something still imported would break the build, so check make build succeeds and the import in internal/portcheck/portcheck.go still resolves.
Commit title ends with (closes #N).
Constraints
Do not change any dependency version. This is a tidiness fix, not an upgrade. golang.org/x/sync stays at v0.19.0; nothing else moves. If go mod tidy wants to change a version, stop and report rather than committing it.
Do not modify .golangci.yml (sha256 021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb) or the golangci-lint pin.
Do not "fix" this by removing go mod download from script/bootstrap — bootstrap should download dependencies. The manifest is what is wrong.
DNS is never mocked in this repository; nothing here touches test behaviour.
make targets and script/ entrypoints only. go mod tidy is the exception and is expected here — the policy names it directly.
Environment hazards
Lint runs can be VOID (#121): void if output contains parallel golangci-lint is running, or names any path beginning with ../, or any absolute path outside your worktree. Fix is in unmerged PR #128; isolate manually meanwhile.
Independent of the open PRs — touches go.mod/go.sum only, which none of #97, #112, #113, #118, #122, #128 or #131 modifies. Only TODO.md will conflict.
Surfaced while implementing [#117](https://git.eeqj.de/sneak/dnswatcher/issues/117), where the implementer noticed `script/bootstrap` rewriting `go.mod` and correctly reverted it rather than carrying an unrelated change. The underlying cause is more specific than "bootstrap mutates the tree".
## The actual defect
`go.mod` on `main` lists the same module twice:
```
line 16: golang.org/x/sync v0.19.0 (direct require block)
line 43: golang.org/x/sync v0.19.0 // indirect
```
It is genuinely a **direct** dependency — `internal/portcheck/portcheck.go:15` imports `golang.org/x/sync/errgroup`. So the `// indirect` entry is redundant and stale, and `go mod tidy` would collapse it.
`REPO_POLICIES.md` is explicit: "Always run `go mod tidy` before committing." That did not happen for whichever commit introduced this.
## Why it is worth fixing rather than ignoring
`script/bootstrap` ends with `go mod download`, which updates the main module's requirements and therefore **drops the redundant line as a side effect**. Consequences:
- Running `script/bootstrap` on a clean checkout leaves `git status` dirty. Every agent on this repo runs bootstrap in a fresh worktree, so every one of them starts against a modified tracked file.
- That is a trap for exactly the mistake this repo has been careful about elsewhere: an implementer staging files by name may still commit a `go.mod` change they did not make and cannot explain, or waste time investigating a diff that is not theirs.
- It is also a small integrity problem in its own right. `go.mod` is a dependency manifest, and one that does not survive a no-op tooling run is not in a settled state.
This is not a security issue — the module hash is in `go.sum` either way, so the pinning rule is satisfied.
## Definition of done
1. `go.mod` is tidy: run `go mod tidy` and commit the result. Expect the redundant `golang.org/x/sync v0.19.0 // indirect` line to disappear and the direct requirement at line 16 to remain.
2. `go.sum` is consistent afterwards.
3. **A clean checkout stays clean across bootstrap.** Verify: fresh worktree, `git status --porcelain` empty, run `script/bootstrap`, confirm `git status --porcelain` is *still* empty. Run it a second time and confirm the same. This is the check that fails today, so it is a real test rather than a formality.
4. `make check` green; `TODO.md` updated in the same commit.
5. Confirm no dependency is actually removed — `go mod tidy` dropping something still imported would break the build, so check `make build` succeeds and the import in `internal/portcheck/portcheck.go` still resolves.
Commit title ends with ` (closes #N)`.
## Constraints
- **Do not change any dependency version.** This is a tidiness fix, not an upgrade. `golang.org/x/sync` stays at `v0.19.0`; nothing else moves. If `go mod tidy` wants to change a version, stop and report rather than committing it.
- Do not modify `.golangci.yml` (sha256 `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`) or the golangci-lint pin.
- Do not "fix" this by removing `go mod download` from `script/bootstrap` — bootstrap should download dependencies. The manifest is what is wrong.
- DNS is never mocked in this repository; nothing here touches test behaviour.
- `make` targets and `script/` entrypoints only. `go mod tidy` is the exception and is expected here — the policy names it directly.
## Environment hazards
- Lint runs can be VOID ([#121](https://git.eeqj.de/sneak/dnswatcher/issues/121)): void if output contains `parallel golangci-lint is running`, or names any path beginning with `../`, or any absolute path outside your worktree. Fix is in unmerged [PR #128](https://git.eeqj.de/sneak/dnswatcher/pulls/128); isolate manually meanwhile.
- `make hooks` fails in a linked worktree ([#129](https://git.eeqj.de/sneak/dnswatcher/issues/129)).
## Sequencing
Independent of the open PRs — touches `go.mod`/`go.sum` only, which none of [#97](https://git.eeqj.de/sneak/dnswatcher/pulls/97), [#112](https://git.eeqj.de/sneak/dnswatcher/pulls/112), [#113](https://git.eeqj.de/sneak/dnswatcher/pulls/113), [#118](https://git.eeqj.de/sneak/dnswatcher/pulls/118), [#122](https://git.eeqj.de/sneak/dnswatcher/pulls/122), [#128](https://git.eeqj.de/sneak/dnswatcher/pulls/128) or [#131](https://git.eeqj.de/sneak/dnswatcher/pulls/131) modifies. Only `TODO.md` will conflict.
clawbot
added this to the 1.0 milestone 2026-08-09 16:56:48 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Surfaced while implementing #117, where the implementer noticed
script/bootstraprewritinggo.modand correctly reverted it rather than carrying an unrelated change. The underlying cause is more specific than "bootstrap mutates the tree".The actual defect
go.modonmainlists the same module twice:It is genuinely a direct dependency —
internal/portcheck/portcheck.go:15importsgolang.org/x/sync/errgroup. So the// indirectentry is redundant and stale, andgo mod tidywould collapse it.REPO_POLICIES.mdis explicit: "Always rungo mod tidybefore committing." That did not happen for whichever commit introduced this.Why it is worth fixing rather than ignoring
script/bootstrapends withgo mod download, which updates the main module's requirements and therefore drops the redundant line as a side effect. Consequences:script/bootstrapon a clean checkout leavesgit statusdirty. Every agent on this repo runs bootstrap in a fresh worktree, so every one of them starts against a modified tracked file.go.modchange they did not make and cannot explain, or waste time investigating a diff that is not theirs.go.modis a dependency manifest, and one that does not survive a no-op tooling run is not in a settled state.This is not a security issue — the module hash is in
go.sumeither way, so the pinning rule is satisfied.Definition of done
go.modis tidy: rungo mod tidyand commit the result. Expect the redundantgolang.org/x/sync v0.19.0 // indirectline to disappear and the direct requirement at line 16 to remain.go.sumis consistent afterwards.git status --porcelainempty, runscript/bootstrap, confirmgit status --porcelainis still empty. Run it a second time and confirm the same. This is the check that fails today, so it is a real test rather than a formality.make checkgreen;TODO.mdupdated in the same commit.go mod tidydropping something still imported would break the build, so checkmake buildsucceeds and the import ininternal/portcheck/portcheck.gostill resolves.Commit title ends with
(closes #N).Constraints
golang.org/x/syncstays atv0.19.0; nothing else moves. Ifgo mod tidywants to change a version, stop and report rather than committing it..golangci.yml(sha256021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb) or the golangci-lint pin.go mod downloadfromscript/bootstrap— bootstrap should download dependencies. The manifest is what is wrong.maketargets andscript/entrypoints only.go mod tidyis the exception and is expected here — the policy names it directly.Environment hazards
parallel golangci-lint is running, or names any path beginning with../, or any absolute path outside your worktree. Fix is in unmerged PR #128; isolate manually meanwhile.make hooksfails in a linked worktree (#129).Sequencing
Independent of the open PRs — touches
go.mod/go.sumonly, which none of #97, #112, #113, #118, #122, #128 or #131 modifies. OnlyTODO.mdwill conflict.