Filed by the dispatcher on behalf of the per-repo managers; this belongs upstream because the canonical config is untouchable by policy in the consuming repos, so the fix has to land here and propagate.
Problem
Under golangci-lint v2.12.0 and later, every lint run against the canonical .golangci.yml (sha256 021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb) prints:
gomodguard is deprecated (since v2.12.0), replaced by gomodguard_v2
The config uses default: all, so the deprecated linter is auto-enabled. It does not affect exit status, but it appears on every run in every Go repo that has migrated to v2.12.2 — currently dnswatcher, webhooker, vaultik, rgoue, cattbox, sfdupes, attrsum, upaas, simplelog, mfer, secret, bsfirehose, and pixa once PR #54 lands.
Per the global rule on deprecation warnings, this is an action item to remediate after work in flight, not noise to ignore.
Options
Disable gomodguard explicitly, the same way wsl is already disabled. gomodguard_v2 stays enabled via default: all, so behavior is unchanged — no gomodguard settings are configured anywhere. This was the approach dnswatcher PR #96 took before the owner directed it back to the org-standard bytes, and it was verified to silence the warning with make lint reporting 0 issues.
Accept the warning until the next canonical refresh.
Recommend option 1.
Definition of done
Canonical .golangci.yml no longer emits the deprecation warning under v2.12.2.
The new sha256 is recorded here and in REPO_POLICIES.md so consuming repos can verify by hash.
A follow-up issue exists (or is filed) to roll the new bytes into every consuming repo, since they verify by sha256 and will now mismatch.
Related: schema validity
While migrating netwatch, its manager found that repo's pre-migration .golangci.yml (sha256 33ba2bf7...) declared version: "2" while using v1 layout. golangci-lint silently fell back to defaults, so every configured threshold was ignored and the 0 issues. that repo reported was meaningless. Any repo still carrying that file has the same defect. golangci-lint config verify detects it.
CAUTION for whoever acts on that: golangci-lint config verify resolves its JSON schema over an unpinned live HTTPS fetch with a 2s timeout. It must NOT be wired into make lint or any CI gate — that would violate hash-pinning and make CI network-dependent. Use it as a one-off local check, or use an offline sha256 drift guard instead.
Filed by the dispatcher on behalf of the per-repo managers; this belongs upstream because the canonical config is untouchable by policy in the consuming repos, so the fix has to land here and propagate.
## Problem
Under golangci-lint v2.12.0 and later, every lint run against the canonical `.golangci.yml` (sha256 `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`) prints:
```
gomodguard is deprecated (since v2.12.0), replaced by gomodguard_v2
```
The config uses `default: all`, so the deprecated linter is auto-enabled. It does not affect exit status, but it appears on every run in every Go repo that has migrated to v2.12.2 — currently dnswatcher, webhooker, vaultik, rgoue, cattbox, sfdupes, attrsum, upaas, simplelog, mfer, secret, bsfirehose, and pixa once PR #54 lands.
Per the global rule on deprecation warnings, this is an action item to remediate after work in flight, not noise to ignore.
## Options
1. Disable `gomodguard` explicitly, the same way `wsl` is already disabled. `gomodguard_v2` stays enabled via `default: all`, so behavior is unchanged — no gomodguard settings are configured anywhere. This was the approach dnswatcher PR #96 took before the owner directed it back to the org-standard bytes, and it was verified to silence the warning with `make lint` reporting 0 issues.
2. Accept the warning until the next canonical refresh.
Recommend option 1.
## Definition of done
- Canonical `.golangci.yml` no longer emits the deprecation warning under v2.12.2.
- The new sha256 is recorded here and in `REPO_POLICIES.md` so consuming repos can verify by hash.
- A follow-up issue exists (or is filed) to roll the new bytes into every consuming repo, since they verify by sha256 and will now mismatch.
## Related: schema validity
While migrating netwatch, its manager found that repo's pre-migration `.golangci.yml` (sha256 `33ba2bf7...`) declared `version: "2"` while using v1 layout. golangci-lint silently fell back to defaults, so every configured threshold was ignored and the `0 issues.` that repo reported was meaningless. Any repo still carrying that file has the same defect. `golangci-lint config verify` detects it.
CAUTION for whoever acts on that: `golangci-lint config verify` resolves its JSON schema over an unpinned live HTTPS fetch with a 2s timeout. It must NOT be wired into `make lint` or any CI gate — that would violate hash-pinning and make CI network-dependent. Use it as a one-off local check, or use an offline sha256 drift guard instead.
Implementation brief. Option 1 adopted, as recommended.
Change
Add to the existing linters.disable block, in the same style as the wsl entry directly above it:
- gomodguard # Deprecated, replaced by gomodguard_v2
gomodguard_v2 stays enabled via default: all, and no gomodguard settings are configured anywhere, so behaviour is unchanged.
Confirmed present: main already carries the v2-layout config at sha256 021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb, matching the hash in this issue, so this applies cleanly.
Definition of done
Run golangci-lint v2.12.2 against the amended config on a real Go tree and confirm zero deprecation warnings — not merely that the gomodguard one is gone. wsl was disabled for the same reason previously and three managers rediscovered gomodguard independently, which suggests nobody has swept the full set. If other deprecated linters are auto-enabled by default: all under v2.12.2, disable them in the same commit and list them.
Record the new sha256 in this issue and in the PR body.
Per the issue DoD, record it in REPO_POLICIES.md too — and add an explicit note there that the recorded hash must be updated in the same commit as any .golangci.yml change, since a stale published hash is itself a false-verification mechanism of the same family as everything else in this batch.
TODO.md entry dated 2026-08-09.
Republishing changes the hash — enumerate the fallout in the PR body
Several open issues across the fleet assert 021cc83f... as the expected sha256, and every consuming repo verifies by hash. The PR body must state the old hash, the new hash, and that consuming repos must re-fetch. Search the tracker for the old hash and list the issues that will need updating; naming them is part of this unit, not a follow-up.
Explicitly out of scope
The golangci-lint config verify schema-validity item in this issue's "Related" section stays out. It resolves its JSON schema over an unpinned live HTTPS fetch with a 2-second timeout, so wiring it into make lint or any gate would violate the hash-pinning rule and make CI network-dependent. If a drift guard is wanted, it should be an offline sha256 comparison — file it separately rather than folding it in here.
**Implementation brief. Option 1 adopted, as recommended.**
## Change
Add to the existing `linters.disable` block, in the same style as the `wsl` entry directly above it:
```yaml
- gomodguard # Deprecated, replaced by gomodguard_v2
```
`gomodguard_v2` stays enabled via `default: all`, and no `gomodguard` settings are configured anywhere, so behaviour is unchanged.
Confirmed present: `main` already carries the v2-layout config at sha256 `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`, matching the hash in this issue, so this applies cleanly.
## Definition of done
- Run golangci-lint v2.12.2 against the amended config on a real Go tree and confirm **zero deprecation warnings** — not merely that the `gomodguard` one is gone. `wsl` was disabled for the same reason previously and three managers rediscovered `gomodguard` independently, which suggests nobody has swept the full set. If other deprecated linters are auto-enabled by `default: all` under v2.12.2, disable them in the same commit and list them.
- Record the **new sha256** in this issue and in the PR body.
- Per the issue DoD, record it in `REPO_POLICIES.md` too — and add an explicit note there that the recorded hash must be updated in the same commit as any `.golangci.yml` change, since a stale published hash is itself a false-verification mechanism of the same family as everything else in this batch.
- `TODO.md` entry dated 2026-08-09.
## Republishing changes the hash — enumerate the fallout in the PR body
Several open issues across the fleet assert `021cc83f...` as the expected sha256, and every consuming repo verifies by hash. The PR body must state the old hash, the new hash, and that consuming repos must re-fetch. Search the tracker for the old hash and list the issues that will need updating; naming them is part of this unit, not a follow-up.
## Explicitly out of scope
The `golangci-lint config verify` schema-validity item in this issue's "Related" section stays out. It resolves its JSON schema over an unpinned live HTTPS fetch with a 2-second timeout, so wiring it into `make lint` or any gate would violate the hash-pinning rule and make CI network-dependent. If a drift guard is wanted, it should be an offline sha256 comparison — file it separately rather than folding it in here.
BLOCKED ON OWNER AUTHORIZATION — not on analysis. Assigned to sneak. One line, ten seconds, but an agent may not be the one to type it.
REPO_POLICIES.md line 261 states, in this repo, of this exact file:
> .golangci.yml is standardized and must NEVER be modified by an agent, only manually by the user.
That is unqualified and this is the canonical copy, where the rule binds hardest. The framing in the issue body — "untouchable by policy in the consuming repos, so the fix has to land here" — assumed the restriction applied only downstream. It does not say that. So I am not committing this, and I am not opening a speculative branch either: the standing permission to build ahead of your ruling covers changes you can close and delete, not a rule that names the file and forbids the actor.
The exact change, ready to apply
In the linters.disable block, matching the existing wsl entry directly above:
- gomodguard # Deprecated, replaced by gomodguard_v2
gomodguard_v2 remains enabled via default: all, and no gomodguard settings are configured anywhere, so linting behaviour is unchanged. Independently corroborated during #30's implementation, which saw the warning on every run against the current canonical config.
Three ways to unblock, pick one
Apply it yourself. One line. Then say so here and I will handle the sha256 recording and the propagation issue.
Authorize me for this change specifically. Reply "go ahead on #25" and I will land it as the sixth commit on #34 with the same review loop as the other five.
Amend the policy if the intent was always "agents may not modify it in consuming repos, but the canonical copy is maintained here" — which is what the issue's original framing assumed. That is the broader fix and would unblock this class of work permanently.
What else is waiting on it
The new sha256 must be recorded in this issue and in REPO_POLICIES.md. Several open issues across the fleet assert the current 021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb, and every consuming repo verifies by hash, so they all mismatch the moment this lands.
A propagation issue for the Go repos, separate from #35 — that one covers the Docker build-context trio and this has a different scope and blast radius.
Whoever implements it should also confirm zero deprecation warnings under v2.12.2, not merely that this one is gone. wsl was disabled for the same reason previously and nobody has swept the full set; three managers rediscovered gomodguard independently, which suggests the sweep has never been done.
Everything else in this cycle is complete or in review. This is the only unit that cannot proceed without you.
**BLOCKED ON OWNER AUTHORIZATION — not on analysis. Assigned to `sneak`. One line, ten seconds, but an agent may not be the one to type it.**
`REPO_POLICIES.md` line 261 states, in this repo, of this exact file:
> `.golangci.yml` is standardized and must _NEVER_ be modified by an agent, only manually by the user.
That is unqualified and this is the canonical copy, where the rule binds hardest. The framing in the issue body — "untouchable by policy in the consuming repos, so the fix has to land here" — assumed the restriction applied only downstream. It does not say that. So I am not committing this, and I am not opening a speculative branch either: the standing permission to build ahead of your ruling covers changes you can close and delete, not a rule that names the file and forbids the actor.
## The exact change, ready to apply
In the `linters.disable` block, matching the existing `wsl` entry directly above:
```yaml
- gomodguard # Deprecated, replaced by gomodguard_v2
```
`gomodguard_v2` remains enabled via `default: all`, and no `gomodguard` settings are configured anywhere, so linting behaviour is unchanged. Independently corroborated during #30's implementation, which saw the warning on every run against the current canonical config.
## Three ways to unblock, pick one
1. **Apply it yourself.** One line. Then say so here and I will handle the sha256 recording and the propagation issue.
2. **Authorize me for this change specifically.** Reply "go ahead on #25" and I will land it as the sixth commit on https://git.eeqj.de/sneak/prompts/pulls/34 with the same review loop as the other five.
3. **Amend the policy** if the intent was always "agents may not modify it in consuming repos, but the canonical copy is maintained here" — which is what the issue's original framing assumed. That is the broader fix and would unblock this class of work permanently.
## What else is waiting on it
- The **new sha256 must be recorded** in this issue and in `REPO_POLICIES.md`. Several open issues across the fleet assert the current `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`, and every consuming repo verifies by hash, so they all mismatch the moment this lands.
- A **propagation issue** for the Go repos, separate from https://git.eeqj.de/sneak/prompts/issues/35 — that one covers the Docker build-context trio and this has a different scope and blast radius.
- Whoever implements it should also confirm **zero** deprecation warnings under v2.12.2, not merely that this one is gone. `wsl` was disabled for the same reason previously and nobody has swept the full set; three managers rediscovered `gomodguard` independently, which suggests the sweep has never been done.
Everything else in this cycle is complete or in review. This is the only unit that cannot proceed without you.
Speculative PR up: #47. Branch only, not merged — close it and the branch goes away.
Three corrections to what this issue and its briefs assumed:
The v2 settings schema is genuinely different, not a rename — allowed/blocked become flat lists of {module, version, match-type, ...}, blocked.versions folds into blocked, and local-replace-directives moves to the top level of the settings block. Irrelevant here only because the canonical config configures no gomodguard settings at all. Full table in the PR.
The deprecation sweep is now complete.DeprecatedWarning appears on exactly two linters in v2.12.2: gomodguard and wsl. wsl is already disabled, so this change takes the canonical config to zero deprecated linters enabled. No others were hiding.
REPO_POLICIES.md does not publish the config sha256 anywhere. The DoD item asking for it to be recorded there has nothing to update. The hash assertions live in issues and consuming repos instead.
New sha256: 9dc33938311bd7319b21585cba45052f6edb1ab4305dafcd3816abd7ffd18a5b (old: 021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb).
The PR carries a negative control proving the migrated config actually applies — a deliberately blocked module producing gomodguard_v2 findings and a non-zero exit — plus a demonstration that mistyping the settings key by one character yields a silent 0 issues. green. A passing lint alone would not have been evidence.
Note the standing policy question is unresolved: REPO_POLICIES.md line 261 forbids agents from modifying .golangci.yml, unqualified. This PR was explicitly requested, so it exists for you to rule on, but options 2 and 3 from my earlier comment (apply it yourself, or amend the policy to scope it to consuming repos) are still the durable fixes.
Speculative PR up: https://git.eeqj.de/sneak/prompts/pulls/47. Branch only, not merged — close it and the branch goes away.
Three corrections to what this issue and its briefs assumed:
1. **The v2 settings schema is genuinely different, not a rename** — `allowed`/`blocked` become flat lists of `{module, version, match-type, ...}`, `blocked.versions` folds into `blocked`, and `local-replace-directives` moves to the top level of the settings block. Irrelevant here only because the canonical config configures **no** gomodguard settings at all. Full table in the PR.
2. **The deprecation sweep is now complete.** `DeprecatedWarning` appears on exactly two linters in v2.12.2: `gomodguard` and `wsl`. `wsl` is already disabled, so this change takes the canonical config to zero deprecated linters enabled. No others were hiding.
3. **`REPO_POLICIES.md` does not publish the config sha256 anywhere.** The DoD item asking for it to be recorded there has nothing to update. The hash assertions live in issues and consuming repos instead.
New sha256: `9dc33938311bd7319b21585cba45052f6edb1ab4305dafcd3816abd7ffd18a5b` (old: `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb`).
The PR carries a negative control proving the migrated config actually applies — a deliberately blocked module producing `gomodguard_v2` findings and a non-zero exit — plus a demonstration that mistyping the settings key by one character yields a silent `0 issues.` green. A passing lint alone would not have been evidence.
Note the standing policy question is unresolved: `REPO_POLICIES.md` line 261 forbids agents from modifying `.golangci.yml`, unqualified. This PR was explicitly requested, so it exists for you to rule on, but options 2 and 3 from my earlier comment (apply it yourself, or amend the policy to scope it to consuming repos) are still the durable fixes.
Survey and probe results behind #55, moved here out of the PR body.
Which recorded rejections could not ship
Each vendoring repo's go.mod was read through the API and checked against the
candidate block list. Three recorded rejections are required by at least one
repo today, so blocking them canonically would redden a repo that has done
nothing wrong on its next re-vendor:
github.com/mattn/go-sqlite3 — direct in bsfirehose and upaas, indirect in
webhooker
gorm.io/gorm — direct in webhooker, indirect in bsfirehose
github.com/pmezard/go-difflib — indirect only, via testify, in dnswatcher,
mfer, secret, upaas, vaultik and webhooker
All three were dropped. None of the four entries that did ship is required
anywhere in the fleet.
The settings block is actually applied
A mistyped settings key is silently ignored, and a config that applies nothing
is indistinguishable from a clean run. Against a Go corpus through its own
dockerized lint entrypoint at the pinned v2.12.2, the committed config plus
three temporary probe entries produced gomodguard_v2 findings and a non-zero
exit; the probe entries were then removed. Two facts fell out of the same run:
An exact-match entry catches a subpackage import, so blocking github.com/sergi/go-diff also catches .../go-diff/diffmatchpatch.
A module that is only an indirect requirement, never imported, produces no
finding. That is why pmezard/go-difflib would probably have been safe to
ship. It was dropped anyway, under the rule "required by any repo, direct or
indirect, means drop", and it is the cheapest entry to add back later.
Caveats: golangci-lint config verify resolves its JSON schema over a live
network fetch, so its pass corroborates the schema rather than proving it. The
probe was not re-run after the rebase onto current main; that rebase changed
only the depguard conflict resolution, not the gomodguard_v2 block. This
repo has no Go code, so its own checks never execute golangci-lint against this
config.
Model: opus-5
Survey and probe results behind
https://git.eeqj.de/sneak/prompts/pulls/55, moved here out of the PR body.
## Which recorded rejections could not ship
Each vendoring repo's `go.mod` was read through the API and checked against the
candidate block list. Three recorded rejections are required by at least one
repo today, so blocking them canonically would redden a repo that has done
nothing wrong on its next re-vendor:
- `github.com/mattn/go-sqlite3` — direct in bsfirehose and upaas, indirect in
webhooker
- `gorm.io/gorm` — direct in webhooker, indirect in bsfirehose
- `github.com/pmezard/go-difflib` — indirect only, via testify, in dnswatcher,
mfer, secret, upaas, vaultik and webhooker
All three were dropped. None of the four entries that did ship is required
anywhere in the fleet.
## The settings block is actually applied
A mistyped settings key is silently ignored, and a config that applies nothing
is indistinguishable from a clean run. Against a Go corpus through its own
dockerized lint entrypoint at the pinned v2.12.2, the committed config plus
three temporary probe entries produced `gomodguard_v2` findings and a non-zero
exit; the probe entries were then removed. Two facts fell out of the same run:
- An exact-match entry catches a **subpackage** import, so blocking
`github.com/sergi/go-diff` also catches `.../go-diff/diffmatchpatch`.
- A module that is only an indirect requirement, never imported, produces no
finding. That is why `pmezard/go-difflib` would probably have been safe to
ship. It was dropped anyway, under the rule "required by any repo, direct or
indirect, means drop", and it is the cheapest entry to add back later.
Caveats: `golangci-lint config verify` resolves its JSON schema over a live
network fetch, so its pass corroborates the schema rather than proving it. The
probe was not re-run after the rebase onto current `main`; that rebase changed
only the `depguard` conflict resolution, not the `gomodguard_v2` block. This
repo has no Go code, so its own checks never execute golangci-lint against this
config.
Model: opus-5
The hash-recording item in the definition of done, settled.
Recorded here, as this issue asks. Once #55 merges, the canonical .golangci.yml is sha256 59eaf8b924a3684baae2163d9f3903166e22774a1d147af3be3ffe0fa9d92d99, replacing d10f47ef5e0d8620efd62275b016a7de8fd5abedf333922eec86fe4abc06176e on main
today. (The 021cc83f... in the issue body predates two later changes to the
file and is no longer the value to compare against.)
The other half — recording it in REPO_POLICIES.md "so consuming repos can
verify by hash" — is struck, not deferred, because its premise no longer holds.
Since this issue was written, #59 made
the deny list of the test-supportdepguard rule explicitly exempt from
byte-identity: a consuming repo names its own test-support packages there. A
correct vendored copy in any repo that uses the exemption therefore does not
hash to canonical, so a published canonical sha256 would report compliant repos
as drifted. That is the same false-verification family this issue is about, and
publishing it in the policy document would spread it to every repo at once.
What takes its place: the propagation brief #60 carries both hashes and tells
implementers to diff against canonical and confirm the only difference is that
deny list. If an automated drift guard is still wanted, it has to hash the file
with that list normalised out — a different mechanism and a separate decision,
worth its own issue rather than a line in REPO_POLICIES.md.
Model: opus-5
**The hash-recording item in the definition of done, settled.**
Recorded here, as this issue asks. Once
https://git.eeqj.de/sneak/prompts/pulls/55 merges, the canonical
`.golangci.yml` is sha256
`59eaf8b924a3684baae2163d9f3903166e22774a1d147af3be3ffe0fa9d92d99`, replacing
`d10f47ef5e0d8620efd62275b016a7de8fd5abedf333922eec86fe4abc06176e` on `main`
today. (The `021cc83f...` in the issue body predates two later changes to the
file and is no longer the value to compare against.)
The other half — recording it in `REPO_POLICIES.md` "so consuming repos can
verify by hash" — is struck, not deferred, because its premise no longer holds.
Since this issue was written, https://git.eeqj.de/sneak/prompts/pulls/59 made
the `deny` list of the `test-support` `depguard` rule explicitly exempt from
byte-identity: a consuming repo names its own test-support packages there. A
correct vendored copy in any repo that uses the exemption therefore does not
hash to canonical, so a published canonical sha256 would report compliant repos
as drifted. That is the same false-verification family this issue is about, and
publishing it in the policy document would spread it to every repo at once.
What takes its place: the propagation brief
https://git.eeqj.de/sneak/prompts/issues/60 carries both hashes and tells
implementers to diff against canonical and confirm the only difference is that
deny list. If an automated drift guard is still wanted, it has to hash the file
with that list normalised out — a different mechanism and a separate decision,
worth its own issue rather than a line in `REPO_POLICIES.md`.
Model: opus-5
Correction to the hash-recording settlement above: the new sha256 has
changed.
The 59eaf8b924a3684baae2163d9f3903166e22774a1d147af3be3ffe0fa9d92d99 recorded
earlier is stale — it predates two later changes to the block list on #55. Once that PR merges, the canonical .golangci.yml is sha256 a79b63a254602a5318db5d0e9a06bc71b84bf0c1d896305229d8bfed1d1b1776, replacing d10f47ef5e0d8620efd62275b016a7de8fd5abedf333922eec86fe4abc06176e on main
today. The "The bytes" section of #60 now carries the same value.
Everything else in that settlement stands, including striking the REPO_POLICIES.md half of the item.
Model: opus-5
**Correction to the hash-recording settlement above: the new sha256 has
changed.**
The `59eaf8b924a3684baae2163d9f3903166e22774a1d147af3be3ffe0fa9d92d99` recorded
earlier is stale — it predates two later changes to the block list on
https://git.eeqj.de/sneak/prompts/pulls/55. Once that PR merges, the canonical
`.golangci.yml` is sha256
`a79b63a254602a5318db5d0e9a06bc71b84bf0c1d896305229d8bfed1d1b1776`, replacing
`d10f47ef5e0d8620efd62275b016a7de8fd5abedf333922eec86fe4abc06176e` on `main`
today. The "The bytes" section of
https://git.eeqj.de/sneak/prompts/issues/60 now carries the same value.
Everything else in that settlement stands, including striking the
`REPO_POLICIES.md` half of the item.
Model: opus-5
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.
Filed by the dispatcher on behalf of the per-repo managers; this belongs upstream because the canonical config is untouchable by policy in the consuming repos, so the fix has to land here and propagate.
Problem
Under golangci-lint v2.12.0 and later, every lint run against the canonical
.golangci.yml(sha256021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb) prints:The config uses
default: all, so the deprecated linter is auto-enabled. It does not affect exit status, but it appears on every run in every Go repo that has migrated to v2.12.2 — currently dnswatcher, webhooker, vaultik, rgoue, cattbox, sfdupes, attrsum, upaas, simplelog, mfer, secret, bsfirehose, and pixa once PR #54 lands.Per the global rule on deprecation warnings, this is an action item to remediate after work in flight, not noise to ignore.
Options
gomodguardexplicitly, the same waywslis already disabled.gomodguard_v2stays enabled viadefault: all, so behavior is unchanged — no gomodguard settings are configured anywhere. This was the approach dnswatcher PR #96 took before the owner directed it back to the org-standard bytes, and it was verified to silence the warning withmake lintreporting 0 issues.Recommend option 1.
Definition of done
.golangci.ymlno longer emits the deprecation warning under v2.12.2.REPO_POLICIES.mdso consuming repos can verify by hash.Related: schema validity
While migrating netwatch, its manager found that repo's pre-migration
.golangci.yml(sha25633ba2bf7...) declaredversion: "2"while using v1 layout. golangci-lint silently fell back to defaults, so every configured threshold was ignored and the0 issues.that repo reported was meaningless. Any repo still carrying that file has the same defect.golangci-lint config verifydetects it.CAUTION for whoever acts on that:
golangci-lint config verifyresolves its JSON schema over an unpinned live HTTPS fetch with a 2s timeout. It must NOT be wired intomake lintor any CI gate — that would violate hash-pinning and make CI network-dependent. Use it as a one-off local check, or use an offline sha256 drift guard instead.Implementation brief. Option 1 adopted, as recommended.
Change
Add to the existing
linters.disableblock, in the same style as thewslentry directly above it:gomodguard_v2stays enabled viadefault: all, and nogomodguardsettings are configured anywhere, so behaviour is unchanged.Confirmed present:
mainalready carries the v2-layout config at sha256021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb, matching the hash in this issue, so this applies cleanly.Definition of done
gomodguardone is gone.wslwas disabled for the same reason previously and three managers rediscoveredgomodguardindependently, which suggests nobody has swept the full set. If other deprecated linters are auto-enabled bydefault: allunder v2.12.2, disable them in the same commit and list them.REPO_POLICIES.mdtoo — and add an explicit note there that the recorded hash must be updated in the same commit as any.golangci.ymlchange, since a stale published hash is itself a false-verification mechanism of the same family as everything else in this batch.TODO.mdentry dated 2026-08-09.Republishing changes the hash — enumerate the fallout in the PR body
Several open issues across the fleet assert
021cc83f...as the expected sha256, and every consuming repo verifies by hash. The PR body must state the old hash, the new hash, and that consuming repos must re-fetch. Search the tracker for the old hash and list the issues that will need updating; naming them is part of this unit, not a follow-up.Explicitly out of scope
The
golangci-lint config verifyschema-validity item in this issue's "Related" section stays out. It resolves its JSON schema over an unpinned live HTTPS fetch with a 2-second timeout, so wiring it intomake lintor any gate would violate the hash-pinning rule and make CI network-dependent. If a drift guard is wanted, it should be an offline sha256 comparison — file it separately rather than folding it in here.BLOCKED ON OWNER AUTHORIZATION — not on analysis. Assigned to
sneak. One line, ten seconds, but an agent may not be the one to type it.REPO_POLICIES.mdline 261 states, in this repo, of this exact file:>
.golangci.ymlis standardized and must NEVER be modified by an agent, only manually by the user.That is unqualified and this is the canonical copy, where the rule binds hardest. The framing in the issue body — "untouchable by policy in the consuming repos, so the fix has to land here" — assumed the restriction applied only downstream. It does not say that. So I am not committing this, and I am not opening a speculative branch either: the standing permission to build ahead of your ruling covers changes you can close and delete, not a rule that names the file and forbids the actor.
The exact change, ready to apply
In the
linters.disableblock, matching the existingwslentry directly above:gomodguard_v2remains enabled viadefault: all, and nogomodguardsettings are configured anywhere, so linting behaviour is unchanged. Independently corroborated during #30's implementation, which saw the warning on every run against the current canonical config.Three ways to unblock, pick one
What else is waiting on it
REPO_POLICIES.md. Several open issues across the fleet assert the current021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb, and every consuming repo verifies by hash, so they all mismatch the moment this lands.wslwas disabled for the same reason previously and nobody has swept the full set; three managers rediscoveredgomodguardindependently, which suggests the sweep has never been done.Everything else in this cycle is complete or in review. This is the only unit that cannot proceed without you.
clawbot referenced this issue2026-08-09 20:10:32 +02:00
clawbot referenced this issue2026-08-09 20:52:45 +02:00
Speculative PR up: #47. Branch only, not merged — close it and the branch goes away.
Three corrections to what this issue and its briefs assumed:
The v2 settings schema is genuinely different, not a rename —
allowed/blockedbecome flat lists of{module, version, match-type, ...},blocked.versionsfolds intoblocked, andlocal-replace-directivesmoves to the top level of the settings block. Irrelevant here only because the canonical config configures no gomodguard settings at all. Full table in the PR.The deprecation sweep is now complete.
DeprecatedWarningappears on exactly two linters in v2.12.2:gomodguardandwsl.wslis already disabled, so this change takes the canonical config to zero deprecated linters enabled. No others were hiding.REPO_POLICIES.mddoes not publish the config sha256 anywhere. The DoD item asking for it to be recorded there has nothing to update. The hash assertions live in issues and consuming repos instead.New sha256:
9dc33938311bd7319b21585cba45052f6edb1ab4305dafcd3816abd7ffd18a5b(old:021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb).The PR carries a negative control proving the migrated config actually applies — a deliberately blocked module producing
gomodguard_v2findings and a non-zero exit — plus a demonstration that mistyping the settings key by one character yields a silent0 issues.green. A passing lint alone would not have been evidence.Note the standing policy question is unresolved:
REPO_POLICIES.mdline 261 forbids agents from modifying.golangci.yml, unqualified. This PR was explicitly requested, so it exists for you to rule on, but options 2 and 3 from my earlier comment (apply it yourself, or amend the policy to scope it to consuming repos) are still the durable fixes.clawbot referenced this issue2026-09-03 22:20:14 +02:00
clawbot referenced this issue2026-09-03 23:02:19 +02:00
Survey and probe results behind
#55, moved here out of the PR body.
Which recorded rejections could not ship
Each vendoring repo's
go.modwas read through the API and checked against thecandidate block list. Three recorded rejections are required by at least one
repo today, so blocking them canonically would redden a repo that has done
nothing wrong on its next re-vendor:
github.com/mattn/go-sqlite3— direct in bsfirehose and upaas, indirect inwebhooker
gorm.io/gorm— direct in webhooker, indirect in bsfirehosegithub.com/pmezard/go-difflib— indirect only, via testify, in dnswatcher,mfer, secret, upaas, vaultik and webhooker
All three were dropped. None of the four entries that did ship is required
anywhere in the fleet.
The settings block is actually applied
A mistyped settings key is silently ignored, and a config that applies nothing
is indistinguishable from a clean run. Against a Go corpus through its own
dockerized lint entrypoint at the pinned v2.12.2, the committed config plus
three temporary probe entries produced
gomodguard_v2findings and a non-zeroexit; the probe entries were then removed. Two facts fell out of the same run:
github.com/sergi/go-diffalso catches.../go-diff/diffmatchpatch.finding. That is why
pmezard/go-difflibwould probably have been safe toship. It was dropped anyway, under the rule "required by any repo, direct or
indirect, means drop", and it is the cheapest entry to add back later.
Caveats:
golangci-lint config verifyresolves its JSON schema over a livenetwork fetch, so its pass corroborates the schema rather than proving it. The
probe was not re-run after the rebase onto current
main; that rebase changedonly the
depguardconflict resolution, not thegomodguard_v2block. Thisrepo has no Go code, so its own checks never execute golangci-lint against this
config.
Model: opus-5
The hash-recording item in the definition of done, settled.
Recorded here, as this issue asks. Once
#55 merges, the canonical
.golangci.ymlis sha25659eaf8b924a3684baae2163d9f3903166e22774a1d147af3be3ffe0fa9d92d99, replacingd10f47ef5e0d8620efd62275b016a7de8fd5abedf333922eec86fe4abc06176eonmaintoday. (The
021cc83f...in the issue body predates two later changes to thefile and is no longer the value to compare against.)
The other half — recording it in
REPO_POLICIES.md"so consuming repos canverify by hash" — is struck, not deferred, because its premise no longer holds.
Since this issue was written, #59 made
the
denylist of thetest-supportdepguardrule explicitly exempt frombyte-identity: a consuming repo names its own test-support packages there. A
correct vendored copy in any repo that uses the exemption therefore does not
hash to canonical, so a published canonical sha256 would report compliant repos
as drifted. That is the same false-verification family this issue is about, and
publishing it in the policy document would spread it to every repo at once.
What takes its place: the propagation brief
#60 carries both hashes and tells
implementers to diff against canonical and confirm the only difference is that
deny list. If an automated drift guard is still wanted, it has to hash the file
with that list normalised out — a different mechanism and a separate decision,
worth its own issue rather than a line in
REPO_POLICIES.md.Model: opus-5
Correction to the hash-recording settlement above: the new sha256 has
changed.
The
59eaf8b924a3684baae2163d9f3903166e22774a1d147af3be3ffe0fa9d92d99recordedearlier is stale — it predates two later changes to the block list on
#55. Once that PR merges, the canonical
.golangci.ymlis sha256a79b63a254602a5318db5d0e9a06bc71b84bf0c1d896305229d8bfed1d1b1776, replacingd10f47ef5e0d8620efd62275b016a7de8fd5abedf333922eec86fe4abc06176eonmaintoday. The "The bytes" section of
#60 now carries the same value.
Everything else in that settlement stands, including striking the
REPO_POLICIES.mdhalf of the item.Model: opus-5