Bumps golangci-lint from v2.11.3 to v2.12.2 and adopts the canonical lint config.
Version pins
Dockerfile: golangci/golangci-lint:v2.12.2 Debian image, pinned by digest, dated 2026-08-07
script/bootstrap: GOLANGCI_LINT_VERSION=2.12.2 with updated sha256 pins for the linux-amd64 and linux-arm64 release archives
Config
.golangci.yml replaced with the canonical config. The previous file kept lll/funlen/cyclop/dupl settings under the top-level linters-settings key, which the v2 schema ignores; the canonical config nests them under linters.settings, so those thresholds now actually apply. The unsupported issues.exclude-use-default key was dropped.
Lint fixes (32 findings)
lll (7): wrapped or shortened over-length lines (struct tag comments moved above fields, test logger construction split, session.NewForTest signature wrapped, shortened a #nosec comment)
goconst (17): replaced repeated "POST"/"PUT" literals with http.MethodPost/http.MethodPut, added shared test constants for webhooker-test/test/application/json, and added tmplKeyError/tmplKeyWebhook constants for template data keys in internal/handlers
dupl (8): merged buildHTTPTargetConfig and buildSlackTargetConfig into a parameterized buildURLTargetConfig; removed the duplicate iWebhookDB test helper in favor of testWebhookDB; extracted shared helpers in middleware and session tests
No //nolint directives were added and behavior is unchanged. make check (fmt-check, tests, lint) passes.
Note: golangci-lint v2.12 deprecates the gomodguard linter in favor of gomodguard_v2; the canonical config change for that is left for a future coordinated update.
Bumps golangci-lint from v2.11.3 to v2.12.2 and adopts the canonical lint config.
## Version pins
- `Dockerfile`: `golangci/golangci-lint:v2.12.2` Debian image, pinned by digest, dated `2026-08-07`
- `script/bootstrap`: `GOLANGCI_LINT_VERSION=2.12.2` with updated sha256 pins for the `linux-amd64` and `linux-arm64` release archives
## Config
`.golangci.yml` replaced with the canonical config. The previous file kept `lll`/`funlen`/`cyclop`/`dupl` settings under the top-level `linters-settings` key, which the v2 schema ignores; the canonical config nests them under `linters.settings`, so those thresholds now actually apply. The unsupported `issues.exclude-use-default` key was dropped.
## Lint fixes (32 findings)
- `lll` (7): wrapped or shortened over-length lines (struct tag comments moved above fields, test logger construction split, `session.NewForTest` signature wrapped, shortened a `#nosec` comment)
- `goconst` (17): replaced repeated `"POST"`/`"PUT"` literals with `http.MethodPost`/`http.MethodPut`, added shared test constants for `webhooker-test`/`test`/`application/json`, and added `tmplKeyError`/`tmplKeyWebhook` constants for template data keys in `internal/handlers`
- `dupl` (8): merged `buildHTTPTargetConfig` and `buildSlackTargetConfig` into a parameterized `buildURLTargetConfig`; removed the duplicate `iWebhookDB` test helper in favor of `testWebhookDB`; extracted shared helpers in middleware and session tests
No `//nolint` directives were added and behavior is unchanged. `make check` (fmt-check, tests, lint) passes.
Note: golangci-lint v2.12 deprecates the `gomodguard` linter in favor of `gomodguard_v2`; the canonical config change for that is left for a future coordinated update.
Bump the golangci-lint Docker image pin in Dockerfile and the
release-archive sha256 pins in script/bootstrap from 2.11.3 to
2.12.2, and replace .golangci.yml with the canonical config. The
canonical config moves lll/funlen/cyclop/dupl settings from the
top-level linters-settings key (ignored by the v2 schema) to
linters.settings, so those thresholds now actually apply.
Fix all findings the newly applied thresholds surfaced:
- lll: wrap or shorten seven over-length lines (struct tag
comments, test logger construction, a func signature, and a
nosec comment)
- goconst: use http.MethodPost/http.MethodPut and new shared
constants for repeated test strings; add tmplKeyError and
tmplKeyWebhook constants for template data keys in handlers
- dupl: merge buildHTTPTargetConfig and buildSlackTargetConfig
into a parameterized buildURLTargetConfig; drop the duplicate
iWebhookDB test helper in favor of testWebhookDB; extract
shared helpers in middleware and session tests
clawbot
self-assigned this 2026-08-07 22:54:18 +02:00
Manager note: PR #84 (database archiving) merged to main at ee7c626 after this PR was opened; Gitea reports this PR as not mergeable, and the new archiving code (internal/delivery/target_database*.go, internal/handlers/source_management.go, tests) has never been linted under the v2.12.2 canonical config this PR introduces. Label set to needs-rebase; dispatching a rework agent to rebase onto current main, resolve conflicts (the goconst/dupl/lll fixes overlap files #84 touched), fix any new findings the stricter config surfaces in the merged archiving code, and re-run the full docker lint gate. A fresh adversarial review follows the rebase.
Manager note: PR #84 (database archiving) merged to `main` at ee7c626 after this PR was opened; Gitea reports this PR as not mergeable, and the new archiving code (`internal/delivery/target_database*.go`, `internal/handlers/source_management.go`, tests) has never been linted under the v2.12.2 canonical config this PR introduces. Label set to `needs-rebase`; dispatching a rework agent to rebase onto current `main`, resolve conflicts (the goconst/dupl/lll fixes overlap files #84 touched), fix any new findings the stricter config surfaces in the merged archiving code, and re-run the full docker lint gate. A fresh adversarial review follows the rebase.
Rebased onto current main (ee7c626, the database archiving target from #84). New head: 36a1bacf11 (force-pushed with lease; the branch is a single rebased commit as before).
Conflict resolution
One conflict, in internal/handlers/source_management.go, in buildTargetConfig:
main (#84) routed Slack through buildSlackTargetConfig and added buildDatabaseTargetConfig(w, expiry) for database targets.
This branch's dupl fix had merged the HTTP/Slack builders into the parameterized buildURLTargetConfig and previously returned "" for database targets (correct before #84 existed).
Resolved by keeping both sides' intent: Slack now goes through buildURLTargetConfig(w, r, targetURL, "webhookUrl", ...) (the dedup), and database targets go through #84's buildDatabaseTargetConfig(w, expiry) (the archiving behavior). main's buildSlackTargetConfig was behaviorally identical to buildURLTargetConfig with key webhookUrl (empty check, SSRF validation, JSON marshal), so no validation was lost in the dedup. The buildDatabaseTargetConfig helper and all other #84 code are untouched. The other overlapping files (internal/delivery/engine_test.go, internal/handlers/export_test.go) auto-merged cleanly.
Ran the full v2.12.2 canonical-config lint over the rebased tree, including the code merged in #84 that had never been linted under it (internal/delivery/target_database.go, target_database_archive.go, their tests, the internal/handlers changes, templates). Result: 0 new findings — the archiving code is clean under the new config, so no additional fix commits were needed and the finding counts in the PR body remain accurate (32 findings, all pre-existing).
Note: the host-installed golangci-lint (2.10.1, older than the new pin) reports one gosec G704 in internal/delivery/client_ssrf_test.go that the pinned v2.12.2 image does not report; the docker gate is authoritative, so no change was made for that.
Gates
script/cibuild (docker build with the newly pinned golangci/golangci-lint:v2.12.2 image): exit 0; lint stage prints 0 issues., make fmt-check and make test stages green, final image builds.
Host make test: all packages pass.
Host make fmt-check: clean.
The v2.12.2 linter emits a deprecation warning that gomodguard is replaced by gomodguard_v2 (warning only, does not fail the build); as noted in the PR body, that config migration is left for a future coordinated canonical-config update.
Rebased onto current `main` (ee7c626, the database archiving target from #84). New head: 36a1bacf11a2ba4d185fb5d5b448143c1978bc2d (force-pushed with lease; the branch is a single rebased commit as before).
## Conflict resolution
One conflict, in `internal/handlers/source_management.go`, in `buildTargetConfig`:
- `main` (#84) routed Slack through `buildSlackTargetConfig` and added `buildDatabaseTargetConfig(w, expiry)` for database targets.
- This branch's `dupl` fix had merged the HTTP/Slack builders into the parameterized `buildURLTargetConfig` and previously returned `""` for database targets (correct before #84 existed).
Resolved by keeping both sides' intent: Slack now goes through `buildURLTargetConfig(w, r, targetURL, "webhookUrl", ...)` (the dedup), and database targets go through #84's `buildDatabaseTargetConfig(w, expiry)` (the archiving behavior). `main`'s `buildSlackTargetConfig` was behaviorally identical to `buildURLTargetConfig` with key `webhookUrl` (empty check, SSRF validation, JSON marshal), so no validation was lost in the dedup. The `buildDatabaseTargetConfig` helper and all other #84 code are untouched. The other overlapping files (`internal/delivery/engine_test.go`, `internal/handlers/export_test.go`) auto-merged cleanly.
## Lint pass over the #84 archiving code
Ran the full v2.12.2 canonical-config lint over the rebased tree, including the code merged in #84 that had never been linted under it (`internal/delivery/target_database.go`, `target_database_archive.go`, their tests, the `internal/handlers` changes, templates). Result: **0 new findings** — the archiving code is clean under the new config, so no additional fix commits were needed and the finding counts in the PR body remain accurate (32 findings, all pre-existing).
Note: the host-installed golangci-lint (2.10.1, older than the new pin) reports one `gosec` G704 in `internal/delivery/client_ssrf_test.go` that the pinned v2.12.2 image does not report; the docker gate is authoritative, so no change was made for that.
## Gates
- `script/cibuild` (docker build with the newly pinned `golangci/golangci-lint:v2.12.2` image): exit 0; lint stage prints `0 issues.`, `make fmt-check` and `make test` stages green, final image builds.
- Host `make test`: all packages pass.
- Host `make fmt-check`: clean.
The v2.12.2 linter emits a deprecation warning that `gomodguard` is replaced by `gomodguard_v2` (warning only, does not fail the build); as noted in the PR body, that config migration is left for a future coordinated canonical-config update.
Fresh adversarial review of head 36a1bacf11, a single commit rebased onto current main (ee7c626, which includes the #84 database archiving target).
Blocking findings
None.
Policy status of the .golangci.yml change
Agent modification of .golangci.yml is owner-authorized for this org-wide golangci v2.12.2 campaign (sneak, 2026-08-07, recorded on dnswatcher PR #96: comments 44012, 44023, and directive 44100 naming the org-standard config to ship everywhere). This review therefore verifies fidelity instead of failing on the standing iron rule. Verified: the file at head hashes to sha256 021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb — byte-identical to the org-standard config the owner directed for all repos (and to prompts PR #24). Base main's copy was byte-identical to the currently published prompts canonical (33ba2bf7...), whose linters-settings block the v2 schema ignores; the new file moves those settings under linters.settings, so the lll/funlen/cyclop/dupl thresholds are now active. The dropped issues.exclude-use-default: false is a v1-only key that was inert under v2; its intent (no default exclusion presets) is preserved because the new config declares no linters.exclusions.presets. Nothing was silently lost; the config only got stricter.
Rebase conflict resolution (internal/handlers/source_management.go)
Verified no validation or behavior dropped from either side:
On base, buildHTTPTargetConfig and buildSlackTargetConfig were line-for-line identical except the missing-URL message and the config key (url vs webhookUrl). The merged buildURLTargetConfig parameterizes exactly those two strings; the empty-URL 400 + errMissingURL, the delivery.ValidateTargetURL SSRF check with warn log and 400 (the #68/#73 behavior — base's Slack builder had no other validation), and the JSON marshal with 500 fallback are all intact, and buildTargetConfig passes the same literals the dedicated builders used.
#84's buildDatabaseTargetConfig (creation-time expiry validation) is untouched and still routed for database.TargetTypeDatabase; internal/delivery/target_database*.go and its tests do not appear in the diff at all.
goconst: every introduced constant has a value byte-identical to the literal it replaces (http.MethodPost/http.MethodPut == "POST"/"PUT"; testAppname/testVersion/testContentType; tmplKeyError = "Error", tmplKeyWebhook = "Webhook" — template data keys unchanged, so template rendering is unaffected).
lll: pure rewraps. Struct-tag reflow in model_entrypoint.go/model_webhook.go/model_target.go changes only inter-tag whitespace and comment placement — gorm/json tag values identical. The #nosec G704 directive in target_http.go:498 is retained; only its justification comment was shortened and it remains accurate (URL validated at config-parse time, SSRF-safe transport).
dupl: iWebhookDB was a byte-level duplicate of testWebhookDB in the same delivery_test package (same DSN, same migrated models, same cleanup); both call sites now use testWebhookDB — no coverage change. The middleware runMetricsAuthRequest helper preserves both tests' distinct assertions (valid: called + 200; invalid: not-called + 401). The session testSessionGetter helper preserves the before/after-SetUser assertions for both GetUserID and GetUsername paths with their distinct expected values.
No //nolint directives added anywhere in the diff (grepped git log -p ee7c626..36a1bac).
Version pins
Dockerfile: golangci/golangci-lint:v2.12.2@sha256:5cceeef0... — digest-pinned, comment carries version + 2026-08-07 date per policy; digest resolves and pulls (verified by the docker builds below).
script/bootstrap: GOLANGCI_LINT_VERSION=2.12.2; I independently downloaded both release archives from GitHub and hashed them: golangci-lint-2.12.2-linux-amd64.tar.gz = 8df580d2...a553 and linux-arm64 = 44cd40a8...df3a, both matching the pinned values exactly. Version string 2.12.2 consistent everywhere; no other external reference changed.
Gates (run by this reviewer)
script/cibuild: exit 0.
Forced uncached rebuild of the Dockerfile lint stage (--no-cache --target lint), so the result is from a fresh run of the pinned v2.12.2 image against this exact tree, not layer cache: make fmt-check clean, make lint prints 0 issues., exit 0 — the #84 archiving code is confirmed clean under the now-active thresholds.
Host make test: exit 0, all packages pass, no verbose rerun triggered. Host make fmt-check: exit 0.
CI green on head: check / check (push) success on 36a1bac (actions run 92, 2m48s).
Mergeable: Gitea reports mergeable, base sha ee7c626 is the current main head, single clean commit.
Hygiene
No Claude/Anthropic references or attribution trailers in the commit message, diff, or PR body (grepped case-insensitively).
TODO.md Completed Steps updated in the same commit; markdown formatting passes make fmt-check.
Commit message accurately describes the change; PR body claims verified against the diff (32 findings: 7 lll, 17 goconst, 8 dupl — file-by-file counts consistent with the hunks reviewed).
Non-blocking observations
No (closes #N) on the landing commit: there is no linked tracker issue for this org-wide campaign (the earlier #55 was a PR, already closed by the v2.11.3 pin), and the manager accepted the no-issue status for this campaign on the record (dnswatcher #96 comment 43974). Plain title is correct here.
The PR body's phrase "the canonical config" is slightly ahead of reality: the prompts repo's published canonical is still the old file until prompts PR #24 lands the 021cc83f bytes. The shipped file matches the owner-directed org standard, so this is terminology, not a defect.
The v2.12.2 linter emits an informational gomodguard deprecation warning sourced from the org config (exit status unaffected); disclosed in the PR body and owner-accepted for a future coordinated config update.
internal/handlers/export_test.go re-specifies the Slack parameters (webhookUrl, missing-URL message) instead of sharing them with buildTargetConfig; if the production literals ever change, the test wrapper could drift. Cosmetic.
How verified
Isolated worktree at head 36a1bac; full git diff ee7c626..36a1bac reviewed file by file; base-vs-head comparison of the target-config builders; sha256 verification of the config against the org standard and of both bootstrap archive pins against freshly downloaded GitHub release archives; script/cibuild, uncached lint-stage docker build, make test, make fmt-check (make/script entrypoints only); CI status and mergeability via the Gitea API.
## Independent review of PR #86 (head 36a1bac)
**VERDICT: PASS**
Fresh adversarial review of head 36a1bacf11a2ba4d185fb5d5b448143c1978bc2d, a single commit rebased onto current `main` (ee7c626, which includes the #84 database archiving target).
### Blocking findings
None.
### Policy status of the `.golangci.yml` change
Agent modification of `.golangci.yml` is owner-authorized for this org-wide golangci v2.12.2 campaign (sneak, 2026-08-07, recorded on dnswatcher PR #96: comments 44012, 44023, and directive 44100 naming the org-standard config to ship everywhere). This review therefore verifies fidelity instead of failing on the standing iron rule. Verified: the file at head hashes to sha256 `021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb` — byte-identical to the org-standard config the owner directed for all repos (and to prompts PR #24). Base `main`'s copy was byte-identical to the currently published prompts canonical (`33ba2bf7...`), whose `linters-settings` block the v2 schema ignores; the new file moves those settings under `linters.settings`, so the `lll`/`funlen`/`cyclop`/`dupl` thresholds are now active. The dropped `issues.exclude-use-default: false` is a v1-only key that was inert under v2; its intent (no default exclusion presets) is preserved because the new config declares no `linters.exclusions.presets`. Nothing was silently lost; the config only got stricter.
### Rebase conflict resolution (`internal/handlers/source_management.go`)
Verified no validation or behavior dropped from either side:
- On base, `buildHTTPTargetConfig` and `buildSlackTargetConfig` were line-for-line identical except the missing-URL message and the config key (`url` vs `webhookUrl`). The merged `buildURLTargetConfig` parameterizes exactly those two strings; the empty-URL 400 + `errMissingURL`, the `delivery.ValidateTargetURL` SSRF check with warn log and 400 (the #68/#73 behavior — base's Slack builder had no other validation), and the JSON marshal with 500 fallback are all intact, and `buildTargetConfig` passes the same literals the dedicated builders used.
- #84's `buildDatabaseTargetConfig` (creation-time expiry validation) is untouched and still routed for `database.TargetTypeDatabase`; `internal/delivery/target_database*.go` and its tests do not appear in the diff at all.
### Lint-fix behavior neutrality (all 32 claimed fixes checked)
- goconst: every introduced constant has a value byte-identical to the literal it replaces (`http.MethodPost`/`http.MethodPut` == `"POST"`/`"PUT"`; `testAppname`/`testVersion`/`testContentType`; `tmplKeyError` = `"Error"`, `tmplKeyWebhook` = `"Webhook"` — template data keys unchanged, so template rendering is unaffected).
- lll: pure rewraps. Struct-tag reflow in `model_entrypoint.go`/`model_webhook.go`/`model_target.go` changes only inter-tag whitespace and comment placement — gorm/json tag values identical. The `#nosec G704` directive in `target_http.go:498` is retained; only its justification comment was shortened and it remains accurate (URL validated at config-parse time, SSRF-safe transport).
- dupl: `iWebhookDB` was a byte-level duplicate of `testWebhookDB` in the same `delivery_test` package (same DSN, same migrated models, same cleanup); both call sites now use `testWebhookDB` — no coverage change. The middleware `runMetricsAuthRequest` helper preserves both tests' distinct assertions (valid: called + 200; invalid: not-called + 401). The session `testSessionGetter` helper preserves the before/after-SetUser assertions for both `GetUserID` and `GetUsername` paths with their distinct expected values.
- No `//nolint` directives added anywhere in the diff (grepped `git log -p ee7c626..36a1bac`).
### Version pins
- `Dockerfile`: `golangci/golangci-lint:v2.12.2@sha256:5cceeef0...` — digest-pinned, comment carries version + 2026-08-07 date per policy; digest resolves and pulls (verified by the docker builds below).
- `script/bootstrap`: `GOLANGCI_LINT_VERSION=2.12.2`; I independently downloaded both release archives from GitHub and hashed them: `golangci-lint-2.12.2-linux-amd64.tar.gz` = `8df580d2...a553` and `linux-arm64` = `44cd40a8...df3a`, both matching the pinned values exactly. Version string 2.12.2 consistent everywhere; no other external reference changed.
### Gates (run by this reviewer)
- `script/cibuild`: exit 0.
- Forced **uncached** rebuild of the Dockerfile lint stage (`--no-cache --target lint`), so the result is from a fresh run of the pinned v2.12.2 image against this exact tree, not layer cache: `make fmt-check` clean, `make lint` prints `0 issues.`, exit 0 — the #84 archiving code is confirmed clean under the now-active thresholds.
- Host `make test`: exit 0, all packages pass, no verbose rerun triggered. Host `make fmt-check`: exit 0.
- CI green on head: `check / check (push)` success on 36a1bac (actions run 92, 2m48s).
- Mergeable: Gitea reports mergeable, base sha ee7c626 is the current `main` head, single clean commit.
### Hygiene
- No Claude/Anthropic references or attribution trailers in the commit message, diff, or PR body (grepped case-insensitively).
- `TODO.md` Completed Steps updated in the same commit; markdown formatting passes `make fmt-check`.
- Commit message accurately describes the change; PR body claims verified against the diff (32 findings: 7 lll, 17 goconst, 8 dupl — file-by-file counts consistent with the hunks reviewed).
### Non-blocking observations
- No `(closes #N)` on the landing commit: there is no linked tracker issue for this org-wide campaign (the earlier #55 was a PR, already closed by the v2.11.3 pin), and the manager accepted the no-issue status for this campaign on the record (dnswatcher #96 comment 43974). Plain title is correct here.
- The PR body's phrase "the canonical config" is slightly ahead of reality: the prompts repo's published canonical is still the old file until prompts PR #24 lands the `021cc83f` bytes. The shipped file matches the owner-directed org standard, so this is terminology, not a defect.
- The v2.12.2 linter emits an informational `gomodguard` deprecation warning sourced from the org config (exit status unaffected); disclosed in the PR body and owner-accepted for a future coordinated config update.
- `internal/handlers/export_test.go` re-specifies the Slack parameters (`webhookUrl`, missing-URL message) instead of sharing them with `buildTargetConfig`; if the production literals ever change, the test wrapper could drift. Cosmetic.
### How verified
Isolated worktree at head 36a1bac; full `git diff ee7c626..36a1bac` reviewed file by file; base-vs-head comparison of the target-config builders; sha256 verification of the config against the org standard and of both bootstrap archive pins against freshly downloaded GitHub release archives; `script/cibuild`, uncached lint-stage docker build, `make test`, `make fmt-check` (make/script entrypoints only); CI status and mergeability via the Gitea API.
clawbot
removed their assignment 2026-08-07 23:06:14 +02:00
sneak
was assigned by clawbot2026-08-07 23:06:14 +02:00
Manager note: independent review above (comment 44174) PASSED the rebased head 36a1bac with no blocking findings — conflict resolution verified lossless on both sides (#86 dedup and #84 archiving config), all 32 lint fixes verified behavior-neutral, the shipped .golangci.yml verified byte-identical to the owner-directed org-standard config, both release-archive sha256 pins independently re-derived, and an uncached lint-stage rebuild under the pinned v2.12.2 image confirmed 0 issues. on the full tree including the #84 code. CI green, mergeable. Setting merge-ready and assigning to sneak for merge (protected main).
Manager note: independent review above (comment 44174) PASSED the rebased head 36a1bac with no blocking findings — conflict resolution verified lossless on both sides (#86 dedup and #84 archiving config), all 32 lint fixes verified behavior-neutral, the shipped `.golangci.yml` verified byte-identical to the owner-directed org-standard config, both release-archive sha256 pins independently re-derived, and an uncached lint-stage rebuild under the pinned v2.12.2 image confirmed `0 issues.` on the full tree including the #84 code. CI green, mergeable. Setting `merge-ready` and assigning to sneak for merge (protected `main`).
sneak
merged commit 734606b7af into main2026-08-07 23:18:49 +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.
Bumps golangci-lint from v2.11.3 to v2.12.2 and adopts the canonical lint config.
Version pins
Dockerfile:golangci/golangci-lint:v2.12.2Debian image, pinned by digest, dated2026-08-07script/bootstrap:GOLANGCI_LINT_VERSION=2.12.2with updated sha256 pins for thelinux-amd64andlinux-arm64release archivesConfig
.golangci.ymlreplaced with the canonical config. The previous file keptlll/funlen/cyclop/duplsettings under the top-levellinters-settingskey, which the v2 schema ignores; the canonical config nests them underlinters.settings, so those thresholds now actually apply. The unsupportedissues.exclude-use-defaultkey was dropped.Lint fixes (32 findings)
lll(7): wrapped or shortened over-length lines (struct tag comments moved above fields, test logger construction split,session.NewForTestsignature wrapped, shortened a#noseccomment)goconst(17): replaced repeated"POST"/"PUT"literals withhttp.MethodPost/http.MethodPut, added shared test constants forwebhooker-test/test/application/json, and addedtmplKeyError/tmplKeyWebhookconstants for template data keys ininternal/handlersdupl(8): mergedbuildHTTPTargetConfigandbuildSlackTargetConfiginto a parameterizedbuildURLTargetConfig; removed the duplicateiWebhookDBtest helper in favor oftestWebhookDB; extracted shared helpers in middleware and session testsNo
//nolintdirectives were added and behavior is unchanged.make check(fmt-check, tests, lint) passes.Note: golangci-lint v2.12 deprecates the
gomodguardlinter in favor ofgomodguard_v2; the canonical config change for that is left for a future coordinated update.Manager note: PR #84 (database archiving) merged to
mainatee7c626after this PR was opened; Gitea reports this PR as not mergeable, and the new archiving code (internal/delivery/target_database*.go,internal/handlers/source_management.go, tests) has never been linted under the v2.12.2 canonical config this PR introduces. Label set toneeds-rebase; dispatching a rework agent to rebase onto currentmain, resolve conflicts (the goconst/dupl/lll fixes overlap files #84 touched), fix any new findings the stricter config surfaces in the merged archiving code, and re-run the full docker lint gate. A fresh adversarial review follows the rebase.641a8ebd66to36a1bacf11Rebased onto current
main(ee7c626, the database archiving target from #84). New head:36a1bacf11(force-pushed with lease; the branch is a single rebased commit as before).Conflict resolution
One conflict, in
internal/handlers/source_management.go, inbuildTargetConfig:main(#84) routed Slack throughbuildSlackTargetConfigand addedbuildDatabaseTargetConfig(w, expiry)for database targets.duplfix had merged the HTTP/Slack builders into the parameterizedbuildURLTargetConfigand previously returned""for database targets (correct before #84 existed).Resolved by keeping both sides' intent: Slack now goes through
buildURLTargetConfig(w, r, targetURL, "webhookUrl", ...)(the dedup), and database targets go through #84'sbuildDatabaseTargetConfig(w, expiry)(the archiving behavior).main'sbuildSlackTargetConfigwas behaviorally identical tobuildURLTargetConfigwith keywebhookUrl(empty check, SSRF validation, JSON marshal), so no validation was lost in the dedup. ThebuildDatabaseTargetConfighelper and all other #84 code are untouched. The other overlapping files (internal/delivery/engine_test.go,internal/handlers/export_test.go) auto-merged cleanly.Lint pass over the #84 archiving code
Ran the full v2.12.2 canonical-config lint over the rebased tree, including the code merged in #84 that had never been linted under it (
internal/delivery/target_database.go,target_database_archive.go, their tests, theinternal/handlerschanges, templates). Result: 0 new findings — the archiving code is clean under the new config, so no additional fix commits were needed and the finding counts in the PR body remain accurate (32 findings, all pre-existing).Note: the host-installed golangci-lint (2.10.1, older than the new pin) reports one
gosecG704 ininternal/delivery/client_ssrf_test.gothat the pinned v2.12.2 image does not report; the docker gate is authoritative, so no change was made for that.Gates
script/cibuild(docker build with the newly pinnedgolangci/golangci-lint:v2.12.2image): exit 0; lint stage prints0 issues.,make fmt-checkandmake teststages green, final image builds.make test: all packages pass.make fmt-check: clean.The v2.12.2 linter emits a deprecation warning that
gomodguardis replaced bygomodguard_v2(warning only, does not fail the build); as noted in the PR body, that config migration is left for a future coordinated canonical-config update.Independent review of PR #86 (head
36a1bac)VERDICT: PASS
Fresh adversarial review of head
36a1bacf11, a single commit rebased onto currentmain(ee7c626, which includes the #84 database archiving target).Blocking findings
None.
Policy status of the
.golangci.ymlchangeAgent modification of
.golangci.ymlis owner-authorized for this org-wide golangci v2.12.2 campaign (sneak, 2026-08-07, recorded on dnswatcher PR #96: comments 44012, 44023, and directive 44100 naming the org-standard config to ship everywhere). This review therefore verifies fidelity instead of failing on the standing iron rule. Verified: the file at head hashes to sha256021cc83f4e6fc7c31b95b34b846723dfcf20b66b7baeea1dc40406e643346bcb— byte-identical to the org-standard config the owner directed for all repos (and to prompts PR #24). Basemain's copy was byte-identical to the currently published prompts canonical (33ba2bf7...), whoselinters-settingsblock the v2 schema ignores; the new file moves those settings underlinters.settings, so thelll/funlen/cyclop/duplthresholds are now active. The droppedissues.exclude-use-default: falseis a v1-only key that was inert under v2; its intent (no default exclusion presets) is preserved because the new config declares nolinters.exclusions.presets. Nothing was silently lost; the config only got stricter.Rebase conflict resolution (
internal/handlers/source_management.go)Verified no validation or behavior dropped from either side:
buildHTTPTargetConfigandbuildSlackTargetConfigwere line-for-line identical except the missing-URL message and the config key (urlvswebhookUrl). The mergedbuildURLTargetConfigparameterizes exactly those two strings; the empty-URL 400 +errMissingURL, thedelivery.ValidateTargetURLSSRF check with warn log and 400 (the #68/#73 behavior — base's Slack builder had no other validation), and the JSON marshal with 500 fallback are all intact, andbuildTargetConfigpasses the same literals the dedicated builders used.buildDatabaseTargetConfig(creation-time expiry validation) is untouched and still routed fordatabase.TargetTypeDatabase;internal/delivery/target_database*.goand its tests do not appear in the diff at all.Lint-fix behavior neutrality (all 32 claimed fixes checked)
http.MethodPost/http.MethodPut=="POST"/"PUT";testAppname/testVersion/testContentType;tmplKeyError="Error",tmplKeyWebhook="Webhook"— template data keys unchanged, so template rendering is unaffected).model_entrypoint.go/model_webhook.go/model_target.gochanges only inter-tag whitespace and comment placement — gorm/json tag values identical. The#nosec G704directive intarget_http.go:498is retained; only its justification comment was shortened and it remains accurate (URL validated at config-parse time, SSRF-safe transport).iWebhookDBwas a byte-level duplicate oftestWebhookDBin the samedelivery_testpackage (same DSN, same migrated models, same cleanup); both call sites now usetestWebhookDB— no coverage change. The middlewarerunMetricsAuthRequesthelper preserves both tests' distinct assertions (valid: called + 200; invalid: not-called + 401). The sessiontestSessionGetterhelper preserves the before/after-SetUser assertions for bothGetUserIDandGetUsernamepaths with their distinct expected values.//nolintdirectives added anywhere in the diff (greppedgit log -p ee7c626..36a1bac).Version pins
Dockerfile:golangci/golangci-lint:v2.12.2@sha256:5cceeef0...— digest-pinned, comment carries version + 2026-08-07 date per policy; digest resolves and pulls (verified by the docker builds below).script/bootstrap:GOLANGCI_LINT_VERSION=2.12.2; I independently downloaded both release archives from GitHub and hashed them:golangci-lint-2.12.2-linux-amd64.tar.gz=8df580d2...a553andlinux-arm64=44cd40a8...df3a, both matching the pinned values exactly. Version string 2.12.2 consistent everywhere; no other external reference changed.Gates (run by this reviewer)
script/cibuild: exit 0.--no-cache --target lint), so the result is from a fresh run of the pinned v2.12.2 image against this exact tree, not layer cache:make fmt-checkclean,make lintprints0 issues., exit 0 — the #84 archiving code is confirmed clean under the now-active thresholds.make test: exit 0, all packages pass, no verbose rerun triggered. Hostmake fmt-check: exit 0.check / check (push)success on36a1bac(actions run 92, 2m48s).ee7c626is the currentmainhead, single clean commit.Hygiene
TODO.mdCompleted Steps updated in the same commit; markdown formatting passesmake fmt-check.Non-blocking observations
(closes #N)on the landing commit: there is no linked tracker issue for this org-wide campaign (the earlier #55 was a PR, already closed by the v2.11.3 pin), and the manager accepted the no-issue status for this campaign on the record (dnswatcher #96 comment 43974). Plain title is correct here.021cc83fbytes. The shipped file matches the owner-directed org standard, so this is terminology, not a defect.gomodguarddeprecation warning sourced from the org config (exit status unaffected); disclosed in the PR body and owner-accepted for a future coordinated config update.internal/handlers/export_test.gore-specifies the Slack parameters (webhookUrl, missing-URL message) instead of sharing them withbuildTargetConfig; if the production literals ever change, the test wrapper could drift. Cosmetic.How verified
Isolated worktree at head 36a1bac; full
git diff ee7c626..36a1bacreviewed file by file; base-vs-head comparison of the target-config builders; sha256 verification of the config against the org standard and of both bootstrap archive pins against freshly downloaded GitHub release archives;script/cibuild, uncached lint-stage docker build,make test,make fmt-check(make/script entrypoints only); CI status and mergeability via the Gitea API.Manager note: independent review above (comment 44174) PASSED the rebased head
36a1bacwith no blocking findings — conflict resolution verified lossless on both sides (#86 dedup and #84 archiving config), all 32 lint fixes verified behavior-neutral, the shipped.golangci.ymlverified byte-identical to the owner-directed org-standard config, both release-archive sha256 pins independently re-derived, and an uncached lint-stage rebuild under the pinned v2.12.2 image confirmed0 issues.on the full tree including the #84 code. CI green, mergeable. Settingmerge-readyand assigning to sneak for merge (protectedmain).