|
| 1 | +# golangci-lint v2 configuration (schema version "2"). |
| 2 | +# |
| 3 | +# All enabled linters land HARD (CI must be green). This INCLUDES the |
| 4 | +# complexity gates (cyclop / gocognit / nestif): they are ACTIVE and enforcing |
| 5 | +# — new code over budget fails CI. See linters.settings for the thresholds and |
| 6 | +# linters.exclusions for the test-file carve-out. |
| 7 | +# |
| 8 | +# A few pre-existing, *intrinsic* findings are narrowly excluded with a |
| 9 | +# "# TODO(ratchet):" comment (e.g. SHA-1 mandated by the RFC6455 WebSocket |
| 10 | +# handshake, protocol byte encodings, err-shadowing). The only remaining |
| 11 | +# complexity suppressions are narrow inline //nolint:<linter> // TODO(complexity) |
| 12 | +# at the few wasm-tagged (js && wasm) protocol/membrane sites; every other |
| 13 | +# function is decomposed under budget. |
| 14 | +version: "2" |
| 15 | + |
| 16 | +run: |
| 17 | + timeout: 5m |
| 18 | + # Lint test files too. The js/wasm pass (GOOS=js GOARCH=wasm) is invoked |
| 19 | + # separately and is the only pass that covers the //go:build js && wasm |
| 20 | + # files: bridge_js.go / conn_js.go / cmd/wasm-kernel/main.go. |
| 21 | + tests: true |
| 22 | + |
| 23 | +linters: |
| 24 | + # Start from an empty set so the enabled linters are exactly the spec: |
| 25 | + # this guarantees no complexity linter is silently active. |
| 26 | + default: none |
| 27 | + enable: |
| 28 | + - govet |
| 29 | + - staticcheck |
| 30 | + - errcheck |
| 31 | + - ineffassign |
| 32 | + - unused |
| 33 | + - unparam |
| 34 | + - unconvert |
| 35 | + - misspell |
| 36 | + - gosec |
| 37 | + # A.2: complexity gates flipped to HARD error (see settings + exclusions). |
| 38 | + - cyclop |
| 39 | + - gocognit |
| 40 | + - nestif |
| 41 | + |
| 42 | + settings: |
| 43 | + govet: |
| 44 | + # Enable every vet analyzer except fieldalignment (too noisy / churny). |
| 45 | + enable-all: true |
| 46 | + disable: |
| 47 | + - fieldalignment |
| 48 | + # TODO(ratchet): `shadow` flags idiomatic `if _, err := ...` blocks |
| 49 | + # across app and test code. Satisfying it requires renaming variables |
| 50 | + # in application logic, which A.1 must not touch. Re-enable after a |
| 51 | + # dedicated shadow-cleanup pass. Reported as a concern. |
| 52 | + - shadow |
| 53 | + misspell: |
| 54 | + locale: US |
| 55 | + # TODO(ratchet): "cancelled" (British spelling) appears as a local |
| 56 | + # variable in security-membrane code (internal/swhttp/bridge_js.go). |
| 57 | + # A.1 must not reformat/edit the membrane. Ignore the word here rather |
| 58 | + # than rename the variable. Reported as a concern. |
| 59 | + # (v2 schema: misspell uses `ignore-rules`, not the v1 `ignore-words`.) |
| 60 | + ignore-rules: |
| 61 | + - cancelled |
| 62 | + # NOTE: staticcheck is intentionally left at its golangci-lint default |
| 63 | + # check set (which already excludes the ST10xx stylecheck rules). Do NOT |
| 64 | + # add `checks: [all, ...]` here: that switches the entire ST family on and |
| 65 | + # surfaces unrelated structural findings (e.g. ST1000 package comments). |
| 66 | + # QF1003 is deferred via linters.exclusions.rules below instead. |
| 67 | + errcheck: |
| 68 | + # TODO(ratchet): unchecked errors on best-effort write paths. |
| 69 | + # `out` is a *bufio.Writer; WriteString on it can only fail if the |
| 70 | + # underlying writer errors, and an immediate Flush already surfaces that. |
| 71 | + # Fixing the remaining sites edits application logic (forbidden in A.1). |
| 72 | + # Reported as a concern. (Deferred Close/SetDeadline are covered by the |
| 73 | + # std-error-handling preset and the SetDeadline rule below.) |
| 74 | + exclude-functions: |
| 75 | + - (*bufio.Writer).WriteString |
| 76 | + gosec: |
| 77 | + # TODO(ratchet): the findings below are INTRINSIC to a TLS-intercepting |
| 78 | + # proxy / SOCKS5 / WebSocket protocol implementation and cannot be |
| 79 | + # "fixed" without changing security-membrane behavior (forbidden in A.1). |
| 80 | + # Each excluded sub-rule is reported as a concern for the A.2 ratchet: |
| 81 | + # G101 - false positive: "zp-streamiso-v1\x00" is a protocol prefix, |
| 82 | + # not a credential. |
| 83 | + # G114 - http.ListenAndServe in the dev server (server hardening is a |
| 84 | + # separate task). |
| 85 | + # G115 - int->byte/uint16 conversions are deliberate protocol-frame |
| 86 | + # length/port encodings (SOCKS5 / WS). |
| 87 | + # G124 - cookie jar mirrors upstream Set-Cookie attributes verbatim by |
| 88 | + # design; it must not inject Secure/HttpOnly/SameSite. |
| 89 | + # G304/G703 - os.Open of an operator-supplied path (config/asset |
| 90 | + # loading); both fire on the same call site. |
| 91 | + # G401/G505 - SHA-1 is MANDATED by the RFC6455 WebSocket handshake. |
| 92 | + # G710 - http.Redirect target is policy-validated upstream. |
| 93 | + # |
| 94 | + # G104 is a different class: it is gosec's GENERIC unchecked-error rule, |
| 95 | + # fully redundant with errcheck (which stays enabled globally as the |
| 96 | + # authoritative, more configurable unchecked-error linter). Excluding |
| 97 | + # G104 removes double-reporting on lines where errcheck is deliberately |
| 98 | + # excluded; it does NOT reduce unchecked-error coverage. |
| 99 | + excludes: |
| 100 | + - G101 |
| 101 | + - G104 |
| 102 | + - G114 |
| 103 | + - G115 |
| 104 | + - G124 |
| 105 | + - G304 |
| 106 | + - G401 |
| 107 | + - G505 |
| 108 | + - G703 |
| 109 | + - G710 |
| 110 | + |
| 111 | + # ---------------------------------------------------------------------- |
| 112 | + # A.2: complexity gates are now HARD errors. New code over budget fails CI. |
| 113 | + # Pre-existing residuals are handled HONESTLY: _test.go is excluded below |
| 114 | + # (test-function complexity is out of scope), and the remaining wasm-tagged |
| 115 | + # (js && wasm) protocol/membrane functions still over budget carry a narrow |
| 116 | + # inline `//nolint:<linter> // TODO(complexity): ...` at each site. Native |
| 117 | + # offenders have been decomposed under budget. cyclop.package-average is |
| 118 | + # intentionally omitted (fragile). |
| 119 | + cyclop: |
| 120 | + max-complexity: 10 |
| 121 | + gocognit: |
| 122 | + min-complexity: 15 |
| 123 | + nestif: |
| 124 | + min-complexity: 4 |
| 125 | + # ---------------------------------------------------------------------- |
| 126 | + |
| 127 | + exclusions: |
| 128 | + # Be lax on generated files (e.g. files with a generated-code header). |
| 129 | + generated: lax |
| 130 | + # Opt into golangci-lint's built-in "std-error-handling" preset (the old |
| 131 | + # EXC0001): excludes unchecked errors from best-effort cleanup calls such |
| 132 | + # as deferred Close/Flush. v2 ships NO default exclusions, so this is an |
| 133 | + # explicit, narrow opt-in rather than a blanket relaxation. |
| 134 | + presets: |
| 135 | + - std-error-handling |
| 136 | + # Skip vendored / build-output / non-Go trees entirely. |
| 137 | + paths: |
| 138 | + - dist |
| 139 | + - bin |
| 140 | + - rewriter-rs/target |
| 141 | + - node_modules |
| 142 | + rules: |
| 143 | + # Test files: relax rules that are noisy or low-value in tests. |
| 144 | + # A.2: cyclop/gocognit/nestif are excluded here too — test-function |
| 145 | + # complexity is OUT OF SCOPE (e.g. table-driven / scenario bodies like |
| 146 | + # relay_test.go TestBridgeInternalSOCKS, jar_test, transform_*_test). |
| 147 | + # Production complexity stays HARD. |
| 148 | + - path: _test.go |
| 149 | + linters: |
| 150 | + - gosec |
| 151 | + - errcheck |
| 152 | + - unparam |
| 153 | + - cyclop |
| 154 | + - gocognit |
| 155 | + - nestif |
| 156 | + # TODO(ratchet): QF1003 ("use tagged switch") is a stylistic suggestion; |
| 157 | + # acting on it edits application logic. Deferred. Reported as a concern. |
| 158 | + - linters: |
| 159 | + - staticcheck |
| 160 | + text: "QF1003" |
| 161 | + # TODO(ratchet): deferred SetDeadline reset on a connection (best-effort |
| 162 | + # cleanup) in the SOCKS5 client. The receiver is an anonymous interface, |
| 163 | + # so it is excluded by path+text here rather than via |
| 164 | + # errcheck.exclude-functions. Scoped to this one call site. Reported as |
| 165 | + # a concern. |
| 166 | + - path: internal/socks5/client\.go |
| 167 | + linters: |
| 168 | + - errcheck |
| 169 | + text: "c\\.SetDeadline" |
| 170 | + # TODO(ratchet): in-flight scaffolding on the feature branch. These |
| 171 | + # specific symbols/params are wired for the nextgen rewriter and are not |
| 172 | + # safe to delete in a config-only task. Scoped by name so genuinely dead |
| 173 | + # code added later is still caught. Reported as a concern; revisit in A.2. |
| 174 | + - path: internal/htmltx/transform\.go |
| 175 | + linters: |
| 176 | + - unused |
| 177 | + text: "rewriteEventHandler|pathEscape" |
| 178 | + - path: internal/htmltx/transform\.go |
| 179 | + linters: |
| 180 | + - unparam |
| 181 | + text: "wrapAttrURL - nav is unused" |
| 182 | + - path: cmd/zeroproxy-server/main\.go |
| 183 | + text: "workerBootstrap - r is unused" |
| 184 | + linters: |
| 185 | + - unparam |
| 186 | + |
| 187 | +formatters: |
| 188 | + enable: |
| 189 | + - gofumpt |
| 190 | + exclusions: |
| 191 | + paths: |
| 192 | + - dist |
| 193 | + - bin |
| 194 | + - rewriter-rs/target |
| 195 | + - node_modules |
0 commit comments