diff --git a/.github/workflows/post-release.yml b/.github/workflows/post-release.yml
index 2878a059..d59d666a 100644
--- a/.github/workflows/post-release.yml
+++ b/.github/workflows/post-release.yml
@@ -1,4 +1,4 @@
-name: "Publish release documentation"
+name: "Post release"
 on:
   release:
     types:
@@ -44,7 +44,7 @@ jobs:
           delete-branch: true
 
   update-assets:
-    name: "Update GitHub Action assets"
+    name: "Update assets"
     runs-on: ubuntu-latest
     env:
       GITHUB_TOKEN: ${{ secrets.GOLANGCI_LINT_TOKEN }}
@@ -62,12 +62,18 @@ jobs:
       - name: Update GitHub action config
         run: make assets/github-action-config.json
 
+      - name: Update reference files
+        run: cp .golangci.next.reference.yml .golangci.reference.yml
+
+      - name: Update information
+        run: make website_dump_info
+
       - name: Create Pull Request
         uses: peter-evans/create-pull-request@v6
         with:
           base: master
           token: ${{ secrets.GOLANGCI_LINT_TOKEN }}
           branch-suffix: timestamp
-          title: "docs: update GitHub Action assets"
+          title: "docs: update assets"
           team-reviewers: golangci/team
           delete-branch: true
diff --git a/.golangci.next.reference.yml b/.golangci.next.reference.yml
new file mode 100644
index 00000000..4fbbe8fa
--- /dev/null
+++ b/.golangci.next.reference.yml
@@ -0,0 +1,2904 @@
+# This file contains all available configuration options
+# with their default values (in comments).
+#
+# This file is not a configuration example,
+# it contains the exhaustive configuration with explanations of the options.
+
+# Options for analysis running.
+run:
+  # Number of operating system threads  (`GOMAXPROCS`) that can execute golangci-lint simultaneously.
+  # If it is explicitly set to 0 (i.e. not the default) then golangci-lint will automatically set the value to match Linux container CPU quota.
+  # Default: the number of logical CPUs in the machine
+  concurrency: 4
+
+  # Timeout for analysis, e.g. 30s, 5m.
+  # Default: 1m
+  timeout: 5m
+
+  # Exit code when at least one issue was found.
+  # Default: 1
+  issues-exit-code: 2
+
+  # Include test files or not.
+  # Default: true
+  tests: false
+
+  # List of build tags, all linters use it.
+  # Default: []
+  build-tags:
+    - mytag
+
+  # Which dirs to skip: issues from them won't be reported.
+  # Can use regexp here: `generated.*`, regexp is applied on full path,
+  # including the path prefix if one is set.
+  # Default dirs are skipped independently of this option's value (see skip-dirs-use-default).
+  # "/" will be replaced by current OS file path separator to properly work on Windows.
+  # Default: []
+  skip-dirs:
+    - src/external_libs
+    - autogenerated_by_my_lib
+
+  # Enables skipping of directories:
+  # - vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
+  # Default: true
+  skip-dirs-use-default: false
+
+  # Which files to skip: they will be analyzed, but issues from them won't be reported.
+  # There is no need to include all autogenerated files,
+  # we confidently recognize autogenerated files.
+  # If it's not, please let us know.
+  # "/" will be replaced by current OS file path separator to properly work on Windows.
+  # Default: []
+  skip-files:
+    - ".*\\.my\\.go$"
+    - lib/bad.go
+
+  # If set, we pass it to "go list -mod={option}". From "go help modules":
+  # If invoked with -mod=readonly, the go command is disallowed from the implicit
+  # automatic updating of go.mod described above. Instead, it fails when any changes
+  # to go.mod are needed. This setting is most useful to check that go.mod does
+  # not need updates, such as in a continuous integration and testing system.
+  # If invoked with -mod=vendor, the go command assumes that the vendor
+  # directory holds the correct copies of dependencies and ignores
+  # the dependency descriptions in go.mod.
+  #
+  # Allowed values: readonly|vendor|mod
+  # Default: ""
+  modules-download-mode: readonly
+
+  # Allow multiple parallel golangci-lint instances running.
+  # If false, golangci-lint acquires file lock on start.
+  # Default: false
+  allow-parallel-runners: true
+
+  # Allow multiple golangci-lint instances running, but serialize them around a lock.
+  # If false, golangci-lint exits with an error if it fails to acquire file lock on start.
+  # Default: false
+  allow-serial-runners: true
+
+  # Define the Go version limit.
+  # Mainly related to generics support since go1.18.
+  # Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.17
+  go: '1.19'
+
+
+# output configuration options
+output:
+  # Format: colored-line-number|line-number|json|colored-tab|tab|checkstyle|code-climate|junit-xml|github-actions|teamcity
+  #
+  # Multiple can be specified by separating them by comma, output can be provided
+  # for each of them by separating format name and path by colon symbol.
+  # Output path can be either `stdout`, `stderr` or path to the file to write to.
+  # Example: "checkstyle:report.xml,json:stdout,colored-line-number"
+  #
+  # Default: colored-line-number
+  format: json
+
+  # Print lines of code with issue.
+  # Default: true
+  print-issued-lines: false
+
+  # Print linter name in the end of issue text.
+  # Default: true
+  print-linter-name: false
+
+  # Make issues output unique by line.
+  # Default: true
+  uniq-by-line: false
+
+  # Add a prefix to the output file references.
+  # Default: ""
+  path-prefix: ""
+
+  # Sort results by the order defined in `sort-order`.
+  # Default: false
+  sort-results: true
+
+  # Order to use when sorting results.
+  # Require `sort-results` to `true`.
+  # Possible values: `file`, `linter`, and `severity`.
+  #
+  # If the severity values are inside the following list, they are ordered in this order:
+  #   1. error
+  #   2. warning
+  #   3. high
+  #   4. medium
+  #   5. low
+  # Either they are sorted alphabetically.
+  #
+  # Default: ["file"]
+  sort-order:
+    - linter
+    - severity
+    - file # filepath, line, and column.
+
+  # Show statistics per linter.
+  # Default: false
+  show-stats: true
+
+
+# All available settings of specific linters.
+linters-settings:
+  asasalint:
+    # To specify a set of function names to exclude.
+    # The values are merged with the builtin exclusions.
+    # The builtin exclusions can be disabled by setting `use-builtin-exclusions` to `false`.
+    # Default: ["^(fmt|log|logger|t|)\.(Print|Fprint|Sprint|Fatal|Panic|Error|Warn|Warning|Info|Debug|Log)(|f|ln)$"]
+    exclude:
+      - Append
+      - \.Wrapf
+    # To enable/disable the asasalint builtin exclusions of function names.
+    # See the default value of `exclude` to get the builtin exclusions.
+    # Default: true
+    use-builtin-exclusions: false
+    # Ignore *_test.go files.
+    # Default: false
+    ignore-test: true
+
+  bidichk:
+    # The following configurations check for all mentioned invisible unicode runes.
+    # All runes are enabled by default.
+    left-to-right-embedding: false
+    right-to-left-embedding: false
+    pop-directional-formatting: false
+    left-to-right-override: false
+    right-to-left-override: false
+    left-to-right-isolate: false
+    right-to-left-isolate: false
+    first-strong-isolate: false
+    pop-directional-isolate: false
+
+  copyloopvar:
+    # If true, ignore aliasing of loop variables.
+    # Default: false
+    ignore-alias: true
+
+  cyclop:
+    # The maximal code complexity to report.
+    # Default: 10
+    max-complexity: 10
+    # The maximal average package complexity.
+    # If it's higher than 0.0 (float) the check is enabled
+    # Default: 0.0
+    package-average: 0.5
+    # Should ignore tests.
+    # Default: false
+    skip-tests: true
+
+  decorder:
+    # Required order of `type`, `const`, `var` and `func` declarations inside a file.
+    # Default: types before constants before variables before functions.
+    dec-order:
+      - type
+      - const
+      - var
+      - func
+
+    # If true, underscore vars (vars with "_" as the name) will be ignored at all checks
+    # Default: false (underscore vars are not ignored)
+    ignore-underscore-vars: false
+
+    # If true, order of declarations is not checked at all.
+    # Default: true (disabled)
+    disable-dec-order-check: false
+
+    # If true, `init` func can be anywhere in file (does not have to be declared before all other functions).
+    # Default: true (disabled)
+    disable-init-func-first-check: false
+
+    # If true, multiple global `type`, `const` and `var` declarations are allowed.
+    # Default: true (disabled)
+    disable-dec-num-check: false
+
+    # If true, type declarations will be ignored for dec num check
+    # Default: false (type statements are not ignored)
+    disable-type-dec-num-check: false
+
+    # If true, const declarations will be ignored for dec num check
+    # Default: false (const statements are not ignored)
+    disable-const-dec-num-check: false
+
+    # If true, var declarations will be ignored for dec num check
+    # Default: false (var statements are not ignored)
+    disable-var-dec-num-check: false
+
+  depguard:
+    # Rules to apply.
+    #
+    # Variables:
+    # - File Variables
+    #   you can still use and exclamation mark ! in front of a variable to say not to use it.
+    #   Example !$test will match any file that is not a go test file.
+    #
+    #   `$all` - matches all go files
+    #   `$test` - matches all go test files
+    #
+    # - Package Variables
+    #
+    #  `$gostd` - matches all of go's standard library (Pulled from `GOROOT`)
+    #
+    # Default: Only allow $gostd in all files.
+    rules:
+      # Name of a rule.
+      main:
+        # Used to determine the package matching priority.
+        # There are three different modes: `original`, `strict`, and `lax`.
+        # Default: "original"
+        list-mode: lax
+        # List of file globs that will match this list of settings to compare against.
+        # Default: $all
+        files:
+          - "!**/*_a _file.go"
+        # List of allowed packages.
+        allow:
+          - $gostd
+          - github.com/OpenPeeDeeP
+        # Packages that are not allowed where the value is a suggestion.
+        deny:
+          - pkg: "github.com/sirupsen/logrus"
+            desc: not allowed
+          - pkg: "github.com/pkg/errors"
+            desc: Should be replaced by standard lib errors package
+
+  dogsled:
+    # Checks assignments with too many blank identifiers.
+    # Default: 2
+    max-blank-identifiers: 3
+
+  dupl:
+    # Tokens count to trigger issue.
+    # Default: 150
+    threshold: 100
+
+  dupword:
+    # Keywords for detecting duplicate words.
+    # If this list is not empty, only the words defined in this list will be detected.
+    # Default: []
+    keywords:
+      - "the"
+      - "and"
+      - "a"
+    # Keywords used to ignore detection.
+    # Default: []
+    ignore:
+      - "0C0C"
+
+  errcheck:
+    # Report about not checking of errors in type assertions: `a := b.(MyStruct)`.
+    # Such cases aren't reported by default.
+    # Default: false
+    check-type-assertions: true
+
+    # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`.
+    # Such cases aren't reported by default.
+    # Default: false
+    check-blank: true
+
+    # DEPRECATED comma-separated list of pairs of the form pkg:regex
+    #
+    # the regex is used to ignore names within pkg. (default "fmt:.*").
+    # see https://github.com/kisielk/errcheck#the-deprecated-method for details
+    ignore: fmt:.*,io/ioutil:^Read.*
+
+    # To disable the errcheck built-in exclude list.
+    # See `-excludeonly` option in https://github.com/kisielk/errcheck#excluding-functions for details.
+    # Default: false
+    disable-default-exclusions: true
+
+    # DEPRECATED use exclude-functions instead.
+    #
+    # Path to a file containing a list of functions to exclude from checking.
+    # See https://github.com/kisielk/errcheck#excluding-functions for details.
+    exclude: /path/to/file.txt
+
+    # List of functions to exclude from checking, where each entry is a single function to exclude.
+    # See https://github.com/kisielk/errcheck#excluding-functions for details.
+    exclude-functions:
+      - io/ioutil.ReadFile
+      - io.Copy(*bytes.Buffer)
+      - io.Copy(os.Stdout)
+
+  errchkjson:
+    # With check-error-free-encoding set to true, errchkjson does warn about errors
+    # from json encoding functions that are safe to be ignored,
+    # because they are not possible to happen.
+    #
+    # if check-error-free-encoding is set to true and errcheck linter is enabled,
+    # it is recommended to add the following exceptions to prevent from false positives:
+    #
+    #     linters-settings:
+    #       errcheck:
+    #         exclude-functions:
+    #           - encoding/json.Marshal
+    #           - encoding/json.MarshalIndent
+    #
+    # Default: false
+    check-error-free-encoding: true
+
+    # Issue on struct encoding that doesn't have exported fields.
+    # Default: false
+    report-no-exported: false
+
+  errorlint:
+    # Check whether fmt.Errorf uses the %w verb for formatting errors.
+    # See the https://github.com/polyfloyd/go-errorlint for caveats.
+    # Default: true
+    errorf: false
+    # Permit more than 1 %w verb, valid per Go 1.20 (Requires errorf:true)
+    # Default: true
+    errorf-multi: false
+    # Check for plain type assertions and type switches.
+    # Default: true
+    asserts: false
+    # Check for plain error comparisons.
+    # Default: true
+    comparison: false
+
+  exhaustive:
+    # Program elements to check for exhaustiveness.
+    # Default: [ switch ]
+    check:
+      - switch
+      - map
+    # Check switch statements in generated files also.
+    # Default: false
+    check-generated: true
+    # Presence of "default" case in switch statements satisfies exhaustiveness,
+    # even if all enum members are not listed.
+    # Default: false
+    default-signifies-exhaustive: true
+    # Enum members matching the supplied regex do not have to be listed in
+    # switch statements to satisfy exhaustiveness.
+    # Default: ""
+    ignore-enum-members: "Example.+"
+    # Enum types matching the supplied regex do not have to be listed in
+    # switch statements to satisfy exhaustiveness.
+    # Default: ""
+    ignore-enum-types: "Example.+"
+    # Consider enums only in package scopes, not in inner scopes.
+    # Default: false
+    package-scope-only: true
+    # Only run exhaustive check on switches with "//exhaustive:enforce" comment.
+    # Default: false
+    explicit-exhaustive-switch: true
+    # Only run exhaustive check on map literals with "//exhaustive:enforce" comment.
+    # Default: false
+    explicit-exhaustive-map: true
+    # Switch statement requires default case even if exhaustive.
+    # Default: false
+    default-case-required: true
+
+  exhaustruct:
+    # List of regular expressions to match struct packages and their names.
+    # Regular expressions must match complete canonical struct package/name/structname.
+    # If this list is empty, all structs are tested.
+    # Default: []
+    include:
+      - '.+\.Test'
+      - 'example\.com/package\.ExampleStruct[\d]{1,2}'
+    # List of regular expressions to exclude struct packages and their names from checks.
+    # Regular expressions must match complete canonical struct package/name/structname.
+    # Default: []
+    exclude:
+      - '.+/cobra\.Command$'
+
+  forbidigo:
+    # Forbid the following identifiers (list of regexp).
+    # Default: ["^(fmt\\.Print(|f|ln)|print|println)$"]
+    forbid:
+      # Builtin function:
+      - ^print.*$
+      # Optional message that gets included in error reports.
+      - p: ^fmt\.Print.*$
+        msg: Do not commit print statements.
+      # Alternatively, put messages at the end of the regex, surrounded by `(# )?`
+      # Escape any special characters. Those messages get included in error reports.
+      - 'fmt\.Print.*(# Do not commit print statements\.)?'
+      # Forbid spew Dump, whether it is called as function or method.
+      # Depends on analyze-types below.
+      - ^spew\.(ConfigState\.)?Dump$
+      # The package name might be ambiguous.
+      # The full import path can be used as additional criteria.
+      # Depends on analyze-types below.
+      - p: ^v1.Dump$
+        pkg: ^example.com/pkg/api/v1$
+    # Exclude godoc examples from forbidigo checks.
+    # Default: true
+    exclude-godoc-examples: false
+    # Instead of matching the literal source code,
+    # use type information to replace expressions with strings that contain the package name
+    # and (for methods and fields) the type name.
+    # This makes it possible to handle import renaming and forbid struct fields and methods.
+    # Default: false
+    analyze-types: true
+
+  funlen:
+    # Checks the number of lines in a function.
+    # If lower than 0, disable the check.
+    # Default: 60
+    lines: -1
+    # Checks the number of statements in a function.
+    # If lower than 0, disable the check.
+    # Default: 40
+    statements: -1
+    # Ignore comments when counting lines.
+    # Default false
+    ignore-comments: true
+
+  gci:
+    # DEPRECATED: use `sections` and `prefix(github.com/org/project)` instead.
+    local-prefixes: github.com/org/project
+
+    # Section configuration to compare against.
+    # Section names are case-insensitive and may contain parameters in ().
+    # The default order of sections is `standard > default > custom > blank > dot > alias`,
+    # If `custom-order` is `true`, it follows the order of `sections` option.
+    # Default: ["standard", "default"]
+    sections:
+      - standard                       # Standard section: captures all standard packages.
+      - default                        # Default section: contains all imports that could not be matched to another section type.
+      - prefix(github.com/org/project) # Custom section: groups all imports with the specified Prefix.
+      - blank                          # Blank section: contains all blank imports. This section is not present unless explicitly enabled.
+      - dot                            # Dot section: contains all dot imports. This section is not present unless explicitly enabled.
+      - alias                          # Alias section: contains all alias imports. This section is not present unless explicitly enabled.
+
+    # Skip generated files.
+    # Default: true
+    skip-generated: false
+
+    # Enable custom order of sections.
+    # If `true`, make the section order the same as the order of `sections`.
+    # Default: false
+    custom-order: true
+
+  ginkgolinter:
+    # Suppress the wrong length assertion warning.
+    # Default: false
+    suppress-len-assertion: true
+
+    # Suppress the wrong nil assertion warning.
+    # Default: false
+    suppress-nil-assertion: true
+
+    # Suppress the wrong error assertion warning.
+    # Default: false
+    suppress-err-assertion: true
+
+    # Suppress the wrong comparison assertion warning.
+    # Default: false
+    suppress-compare-assertion: true
+
+    # Suppress the function all in async assertion warning.
+    # Default: false
+    suppress-async-assertion: true
+
+    # Suppress warning for comparing values from different types, like int32 and uint32
+    # Default: false
+    suppress-type-compare-assertion: true
+
+    # Trigger warning for ginkgo focus containers like FDescribe, FContext, FWhen or FIt
+    # Default: false
+    forbid-focus-container: true
+
+    # Don't trigger warnings for HaveLen(0)
+    # Default: false
+    allow-havelen-zero: true
+
+  gocognit:
+    # Minimal code complexity to report.
+    # Default: 30 (but we recommend 10-20)
+    min-complexity: 10
+
+  goconst:
+    # Minimal length of string constant.
+    # Default: 3
+    min-len: 2
+    # Minimum occurrences of constant string count to trigger issue.
+    # Default: 3
+    min-occurrences: 2
+    # Ignore test files.
+    # Default: false
+    ignore-tests: true
+    # Look for existing constants matching the values.
+    # Default: true
+    match-constant: false
+    # Search also for duplicated numbers.
+    # Default: false
+    numbers: true
+    # Minimum value, only works with goconst.numbers
+    # Default: 3
+    min: 2
+    # Maximum value, only works with goconst.numbers
+    # Default: 3
+    max: 2
+    # Ignore when constant is not used as function argument.
+    # Default: true
+    ignore-calls: false
+    # Exclude strings matching the given regular expression.
+    # Default: ""
+    ignore-strings: 'foo.+'
+
+  gocritic:
+    # Disable all checks.
+    # Default: false
+    disable-all: true
+    # Which checks should be enabled in addition to default checks; can't be combined with 'disabled-checks'.
+    # By default, list of stable checks is used (https://go-critic.github.io/overview#checks-overview):
+    #   appendAssign, argOrder, assignOp, badCall, badCond, captLocal, caseOrder, codegenComment, commentFormatting,
+    #   defaultCaseOrder, deprecatedComment, dupArg, dupBranchBody, dupCase, dupSubExpr, elseif, exitAfterDefer,
+    #   flagDeref, flagName, ifElseChain, mapKey, newDeref, offBy1, regexpMust, singleCaseSwitch, sloppyLen,
+    #   sloppyTypeAssert, switchTrue, typeSwitchVar, underef, unlambda, unslice, valSwap, wrapperFunc
+    # To see which checks are enabled run `GL_DEBUG=gocritic golangci-lint run --enable=gocritic`.
+    enabled-checks:
+      - nestingReduce
+      - unnamedResult
+      - ruleguard
+      - truncateCmp
+
+    # Enable all checks.
+    # Default: false
+    enable-all: true
+    # Which checks should be disabled; can't be combined with 'enabled-checks'.
+    # Default: []
+    disabled-checks:
+      - regexpMust
+
+    # Enable multiple checks by tags in addition to default checks.
+    # Run `GL_DEBUG=gocritic golangci-lint run --enable=gocritic` to see all tags and checks.
+    # See https://github.com/go-critic/go-critic#usage -> section "Tags".
+    # Default: []
+    enabled-tags:
+      - diagnostic
+      - style
+      - performance
+      - experimental
+      - opinionated
+    disabled-tags:
+      - diagnostic
+      - style
+      - performance
+      - experimental
+      - opinionated
+
+    # Settings passed to gocritic.
+    # The settings key is the name of a supported gocritic checker.
+    # The list of supported checkers can be find in https://go-critic.github.io/overview.
+    settings:
+      # Must be valid enabled check name.
+      captLocal:
+        # Whether to restrict checker to params only.
+        # Default: true
+        paramsOnly: false
+      commentedOutCode:
+        # Min length of the comment that triggers a warning.
+        # Default: 15
+        minLength: 50
+      elseif:
+        # Whether to skip balanced if-else pairs.
+        # Default: true
+        skipBalanced: false
+      hugeParam:
+        # Size in bytes that makes the warning trigger.
+        # Default: 80
+        sizeThreshold: 70
+      ifElseChain:
+        # Min number of if-else blocks that makes the warning trigger.
+        # Default: 2
+        minThreshold: 4
+      nestingReduce:
+        # Min number of statements inside a branch to trigger a warning.
+        # Default: 5
+        bodyWidth: 4
+      rangeExprCopy:
+        # Size in bytes that makes the warning trigger.
+        # Default: 512
+        sizeThreshold: 516
+        # Whether to check test functions
+        # Default: true
+        skipTestFuncs: false
+      rangeValCopy:
+        # Size in bytes that makes the warning trigger.
+        # Default: 128
+        sizeThreshold: 32
+        # Whether to check test functions.
+        # Default: true
+        skipTestFuncs: false
+      ruleguard:
+        # Enable debug to identify which 'Where' condition was rejected.
+        # The value of the parameter is the name of a function in a ruleguard file.
+        #
+        # When a rule is evaluated:
+        # If:
+        #   The Match() clause is accepted; and
+        #   One of the conditions in the Where() clause is rejected,
+        # Then:
+        #   ruleguard prints the specific Where() condition that was rejected.
+        #
+        # The option is passed to the ruleguard 'debug-group' argument.
+        # Default: ""
+        debug: 'emptyDecl'
+        # Deprecated, use 'failOn' param.
+        # If set to true, identical to failOn='all', otherwise failOn=''
+        failOnError: false
+        # Determines the behavior when an error occurs while parsing ruleguard files.
+        # If flag is not set, log error and skip rule files that contain an error.
+        # If flag is set, the value must be a comma-separated list of error conditions.
+        # - 'all':    fail on all errors.
+        # - 'import': ruleguard rule imports a package that cannot be found.
+        # - 'dsl':    gorule file does not comply with the ruleguard DSL.
+        # Default: ""
+        failOn: dsl
+        # Comma-separated list of file paths containing ruleguard rules.
+        # If a path is relative, it is relative to the directory where the golangci-lint command is executed.
+        # The special '${configDir}' variable is substituted with the absolute directory containing the golangci config file.
+        # Glob patterns such as 'rules-*.go' may be specified.
+        # Default: ""
+        rules: '${configDir}/ruleguard/rules-*.go,${configDir}/myrule1.go'
+        # Comma-separated list of enabled groups or skip empty to enable everything.
+        # Tags can be defined with # character prefix.
+        # Default: "<all>"
+        enable: "myGroupName,#myTagName"
+        # Comma-separated list of disabled groups or skip empty to enable everything.
+        # Tags can be defined with # character prefix.
+        # Default: ""
+        disable: "myGroupName,#myTagName"
+      tooManyResultsChecker:
+        # Maximum number of results.
+        # Default: 5
+        maxResults: 10
+      truncateCmp:
+        # Whether to skip int/uint/uintptr types.
+        # Default: true
+        skipArchDependent: false
+      underef:
+        # Whether to skip (*x).method() calls where x is a pointer receiver.
+        # Default: true
+        skipRecvDeref: false
+      unnamedResult:
+        # Whether to check exported functions.
+        # Default: false
+        checkExported: true
+
+  gocyclo:
+    # Minimal code complexity to report.
+    # Default: 30 (but we recommend 10-20)
+    min-complexity: 10
+
+  godot:
+    # Comments to be checked: `declarations`, `toplevel`, or `all`.
+    # Default: declarations
+    scope: toplevel
+    # List of regexps for excluding particular comment lines from check.
+    # Default: []
+    exclude:
+      # Exclude todo and fixme comments.
+      - "^fixme:"
+      - "^todo:"
+    # Check that each sentence ends with a period.
+    # Default: true
+    period: false
+    # Check that each sentence starts with a capital letter.
+    # Default: false
+    capital: true
+
+  godox:
+    # Report any comments starting with keywords, this is useful for TODO or FIXME comments that
+    # might be left in the code accidentally and should be resolved before merging.
+    # Default: ["TODO", "BUG", "FIXME"]
+    keywords:
+      - NOTE
+      - OPTIMIZE # marks code that should be optimized before merging
+      - HACK # marks hack-around that should be removed before merging
+
+  gofmt:
+    # Simplify code: gofmt with `-s` option.
+    # Default: true
+    simplify: false
+    # Apply the rewrite rules to the source before reformatting.
+    # https://pkg.go.dev/cmd/gofmt
+    # Default: []
+    rewrite-rules:
+      - pattern: 'interface{}'
+        replacement: 'any'
+      - pattern: 'a[b:len(a)]'
+        replacement: 'a[b:]'
+
+  gofumpt:
+    # Deprecated: use the global `run.go` instead.
+    lang-version: "1.17"
+
+    # Module path which contains the source code being formatted.
+    # Default: ""
+    module-path: github.com/org/project
+
+    # Choose whether to use the extra rules.
+    # Default: false
+    extra-rules: true
+
+  goheader:
+    # Supports two types 'const` and `regexp`.
+    # Values can be used recursively.
+    # Default: {}
+    values:
+      const:
+        # Define here const type values in format k:v.
+        # For example:
+        COMPANY: MY COMPANY
+      regexp:
+        # Define here regexp type values.
+        # for example:
+        AUTHOR: .*@mycompany\.com
+    # The template use for checking.
+    # Default: ""
+    template: |-
+      # Put here copyright header template for source code files
+      # For example:
+      # Note: {{ YEAR }} is a builtin value that returns the year relative to the current machine time.
+      #
+      # {{ AUTHOR }} {{ COMPANY }} {{ YEAR }}
+      # SPDX-License-Identifier: Apache-2.0
+
+      # Licensed under the Apache License, Version 2.0 (the "License");
+      # you may not use this file except in compliance with the License.
+      # You may obtain a copy of the License at:
+
+      #   http://www.apache.org/licenses/LICENSE-2.0
+
+      # Unless required by applicable law or agreed to in writing, software
+      # distributed under the License is distributed on an "AS IS" BASIS,
+      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+      # See the License for the specific language governing permissions and
+      # limitations under the License.
+    # As alternative of directive 'template', you may put the path to file with the template source.
+    # Useful if you need to load the template from a specific file.
+    # Default: ""
+    template-path: /path/to/my/template.tmpl
+
+  goimports:
+    # A comma-separated list of prefixes, which, if set, checks import paths
+    # with the given prefixes are grouped after 3rd-party packages.
+    # Default: ""
+    local-prefixes: github.com/org/project
+
+  gomnd:
+    # List of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
+    # Default: ["argument", "case", "condition", "operation", "return", "assign"]
+    checks:
+      - argument
+      - case
+      - condition
+      - operation
+      - return
+      - assign
+    # List of numbers to exclude from analysis.
+    # The numbers should be written as string.
+    # Values always ignored: "1", "1.0", "0" and "0.0"
+    # Default: []
+    ignored-numbers:
+      - '0666'
+      - '0755'
+      - '42'
+    # List of file patterns to exclude from analysis.
+    # Values always ignored: `.+_test.go`
+    # Default: []
+    ignored-files:
+      - 'magic1_.+\.go$'
+    # List of function patterns to exclude from analysis.
+    # Following functions are always ignored: `time.Date`,
+    # `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`,
+    # `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`.
+    # Default: []
+    ignored-functions:
+      - '^math\.'
+      - '^http\.StatusText$'
+
+  gomoddirectives:
+    # Allow local `replace` directives.
+    # Default: false
+    replace-local: false
+    # List of allowed `replace` directives.
+    # Default: []
+    replace-allow-list:
+      - launchpad.net/gocheck
+    # Allow to not explain why the version has been retracted in the `retract` directives.
+    # Default: false
+    retract-allow-no-explanation: false
+    # Forbid the use of the `exclude` directives.
+    # Default: false
+    exclude-forbidden: false
+
+  gomodguard:
+    allowed:
+      # List of allowed modules.
+      # Default: []
+      modules:
+        - gopkg.in/yaml.v2
+      # List of allowed module domains.
+      # Default: []
+      domains:
+        - golang.org
+    blocked:
+      # List of blocked modules.
+      # Default: []
+      modules:
+        # Blocked module.
+        - github.com/uudashr/go-module:
+            # Recommended modules that should be used instead. (Optional)
+            recommendations:
+              - golang.org/x/mod
+            # Reason why the recommended module should be used. (Optional)
+            reason: "`mod` is the official go.mod parser library."
+      # List of blocked module version constraints.
+      # Default: []
+      versions:
+        # Blocked module with version constraint.
+        - github.com/mitchellh/go-homedir:
+            # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons.
+            version: "< 1.1.0"
+            # Reason why the version constraint exists. (Optional)
+            reason: "testing if blocked version constraint works."
+      # Set to true to raise lint issues for packages that are loaded from a local path via replace directive.
+      # Default: false
+      local_replace_directives: false
+
+  gosimple:
+    # Deprecated: use the global `run.go` instead.
+    go: "1.15"
+    # Sxxxx checks in https://staticcheck.io/docs/configuration/options/#checks
+    # Default: ["*"]
+    checks: [ "all" ]
+
+  gosec:
+    # To select a subset of rules to run.
+    # Available rules: https://github.com/securego/gosec#available-rules
+    # Default: [] - means include all rules
+    includes:
+      - G101 # Look for hard coded credentials
+      - G102 # Bind to all interfaces
+      - G103 # Audit the use of unsafe block
+      - G104 # Audit errors not checked
+      - G106 # Audit the use of ssh.InsecureIgnoreHostKey
+      - G107 # Url provided to HTTP request as taint input
+      - G108 # Profiling endpoint automatically exposed on /debug/pprof
+      - G109 # Potential Integer overflow made by strconv.Atoi result conversion to int16/32
+      - G110 # Potential DoS vulnerability via decompression bomb
+      - G111 # Potential directory traversal
+      - G112 # Potential slowloris attack
+      - G113 # Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772)
+      - G114 # Use of net/http serve function that has no support for setting timeouts
+      - G201 # SQL query construction using format string
+      - G202 # SQL query construction using string concatenation
+      - G203 # Use of unescaped data in HTML templates
+      - G204 # Audit use of command execution
+      - G301 # Poor file permissions used when creating a directory
+      - G302 # Poor file permissions used with chmod
+      - G303 # Creating tempfile using a predictable path
+      - G304 # File path provided as taint input
+      - G305 # File traversal when extracting zip/tar archive
+      - G306 # Poor file permissions used when writing to a new file
+      - G307 # Poor file permissions used when creating a file with os.Create
+      - G401 # Detect the usage of DES, RC4, MD5 or SHA1
+      - G402 # Look for bad TLS connection settings
+      - G403 # Ensure minimum RSA key length of 2048 bits
+      - G404 # Insecure random number source (rand)
+      - G501 # Import blocklist: crypto/md5
+      - G502 # Import blocklist: crypto/des
+      - G503 # Import blocklist: crypto/rc4
+      - G504 # Import blocklist: net/http/cgi
+      - G505 # Import blocklist: crypto/sha1
+      - G601 # Implicit memory aliasing of items from a range statement
+      - G602 # Slice access out of bounds
+
+    # To specify a set of rules to explicitly exclude.
+    # Available rules: https://github.com/securego/gosec#available-rules
+    # Default: []
+    excludes:
+      - G101 # Look for hard coded credentials
+      - G102 # Bind to all interfaces
+      - G103 # Audit the use of unsafe block
+      - G104 # Audit errors not checked
+      - G106 # Audit the use of ssh.InsecureIgnoreHostKey
+      - G107 # Url provided to HTTP request as taint input
+      - G108 # Profiling endpoint automatically exposed on /debug/pprof
+      - G109 # Potential Integer overflow made by strconv.Atoi result conversion to int16/32
+      - G110 # Potential DoS vulnerability via decompression bomb
+      - G111 # Potential directory traversal
+      - G112 # Potential slowloris attack
+      - G113 # Usage of Rat.SetString in math/big with an overflow (CVE-2022-23772)
+      - G114 # Use of net/http serve function that has no support for setting timeouts
+      - G201 # SQL query construction using format string
+      - G202 # SQL query construction using string concatenation
+      - G203 # Use of unescaped data in HTML templates
+      - G204 # Audit use of command execution
+      - G301 # Poor file permissions used when creating a directory
+      - G302 # Poor file permissions used with chmod
+      - G303 # Creating tempfile using a predictable path
+      - G304 # File path provided as taint input
+      - G305 # File traversal when extracting zip/tar archive
+      - G306 # Poor file permissions used when writing to a new file
+      - G307 # Poor file permissions used when creating a file with os.Create
+      - G401 # Detect the usage of DES, RC4, MD5 or SHA1
+      - G402 # Look for bad TLS connection settings
+      - G403 # Ensure minimum RSA key length of 2048 bits
+      - G404 # Insecure random number source (rand)
+      - G501 # Import blocklist: crypto/md5
+      - G502 # Import blocklist: crypto/des
+      - G503 # Import blocklist: crypto/rc4
+      - G504 # Import blocklist: net/http/cgi
+      - G505 # Import blocklist: crypto/sha1
+      - G601 # Implicit memory aliasing of items from a range statement
+      - G602 # Slice access out of bounds
+
+    # Exclude generated files
+    # Default: false
+    exclude-generated: true
+
+    # Filter out the issues with a lower severity than the given value.
+    # Valid options are: low, medium, high.
+    # Default: low
+    severity: medium
+
+    # Filter out the issues with a lower confidence than the given value.
+    # Valid options are: low, medium, high.
+    # Default: low
+    confidence: medium
+
+    # Concurrency value.
+    # Default: the number of logical CPUs usable by the current process.
+    concurrency: 12
+
+    # To specify the configuration of rules.
+    config:
+      # Globals are applicable to all rules.
+      global:
+        # If true, ignore #nosec in comments (and an alternative as well).
+        # Default: false
+        nosec: true
+        # Add an alternative comment prefix to #nosec (both will work at the same time).
+        # Default: ""
+        "#nosec": "#my-custom-nosec"
+        # Define whether nosec issues are counted as finding or not.
+        # Default: false
+        show-ignored: true
+        # Audit mode enables addition checks that for normal code analysis might be too nosy.
+        # Default: false
+        audit: true
+      G101:
+        # Regexp pattern for variables and constants to find.
+        # Default: "(?i)passwd|pass|password|pwd|secret|token|pw|apiKey|bearer|cred"
+        pattern: "(?i)example"
+        # If true, complain about all cases (even with low entropy).
+        # Default: false
+        ignore_entropy: false
+        # Maximum allowed entropy of the string.
+        # Default: "80.0"
+        entropy_threshold: "80.0"
+        # Maximum allowed value of entropy/string length.
+        # Is taken into account if entropy >= entropy_threshold/2.
+        # Default: "3.0"
+        per_char_threshold: "3.0"
+        # Calculate entropy for first N chars of the string.
+        # Default: "16"
+        truncate: "32"
+      # Additional functions to ignore while checking unhandled errors.
+      # Following functions always ignored:
+      #   bytes.Buffer:
+      #     - Write
+      #     - WriteByte
+      #     - WriteRune
+      #     - WriteString
+      #   fmt:
+      #     - Print
+      #     - Printf
+      #     - Println
+      #     - Fprint
+      #     - Fprintf
+      #     - Fprintln
+      #   strings.Builder:
+      #     - Write
+      #     - WriteByte
+      #     - WriteRune
+      #     - WriteString
+      #   io.PipeWriter:
+      #     - CloseWithError
+      #   hash.Hash:
+      #     - Write
+      #   os:
+      #     - Unsetenv
+      # Default: {}
+      G104:
+        fmt:
+          - Fscanf
+      G111:
+        # Regexp pattern to find potential directory traversal.
+        # Default: "http\\.Dir\\(\"\\/\"\\)|http\\.Dir\\('\\/'\\)"
+        pattern: "custom\\.Dir\\(\\)"
+      # Maximum allowed permissions mode for os.Mkdir and os.MkdirAll
+      # Default: "0750"
+      G301: "0750"
+      # Maximum allowed permissions mode for os.OpenFile and os.Chmod
+      # Default: "0600"
+      G302: "0600"
+      # Maximum allowed permissions mode for os.WriteFile and ioutil.WriteFile
+      # Default: "0600"
+      G306: "0600"
+
+  gosmopolitan:
+    # Allow and ignore `time.Local` usages.
+    #
+    # Default: false
+    allow-time-local: true
+    # List of fully qualified names in the `full/pkg/path.name` form, to act as "i18n escape hatches".
+    # String literals inside call-like expressions to, or struct literals of those names,
+    # are exempt from the writing system check.
+    #
+    # Default: []
+    escape-hatches:
+      - 'github.com/nicksnyder/go-i18n/v2/i18n.Message'
+      - 'example.com/your/project/i18n/markers.Raw'
+      - 'example.com/your/project/i18n/markers.OK'
+      - 'example.com/your/project/i18n/markers.TODO'
+      - 'command-line-arguments.Simple'
+    # Ignore test files.
+    #
+    # Default: true
+    ignore-tests: false
+    # List of Unicode scripts to watch for any usage in string literals.
+    # https://pkg.go.dev/unicode#pkg-variables
+    #
+    # Default: ["Han"]
+    watch-for-scripts:
+      - Devanagari
+      - Han
+      - Hangul
+      - Hiragana
+      - Katakana
+
+  govet:
+    # Report about shadowed variables.
+    # Default: false
+    check-shadowing: true
+
+    # Settings per analyzer.
+    settings:
+      # Analyzer name, run `go tool vet help` to see all analyzers.
+      printf:
+        # Comma-separated list of print function names to check (in addition to default, see `go tool vet help printf`).
+        # Default: []
+        funcs:
+          - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
+          - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
+          - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
+          - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
+      shadow:
+        # Whether to be strict about shadowing; can be noisy.
+        # Default: false
+        strict: true
+      unusedresult:
+        # Comma-separated list of functions whose results must be used
+        # (in addition to default:
+        #   context.WithCancel, context.WithDeadline, context.WithTimeout, context.WithValue, errors.New, fmt.Errorf,
+        #   fmt.Sprint, fmt.Sprintf, sort.Reverse
+        # ).
+        # Default: []
+        funcs:
+          - pkg.MyFunc
+        # Comma-separated list of names of methods of type func() string whose results must be used
+        # (in addition to default Error,String)
+        # Default: []
+        stringmethods:
+          - MyMethod
+
+    # Disable all analyzers.
+    # Default: false
+    disable-all: true
+    # Enable analyzers by name.
+    # (in addition to default:
+    #   appends, asmdecl, assign, atomic, bools, buildtag, cgocall, composites, copylocks, defers, directive, errorsas,
+    #   framepointer, httpresponse, ifaceassert, loopclosure, lostcancel, nilfunc, printf, shift, sigchanyzer, slog,
+    #   stdmethods, stringintconv, structtag, testinggoroutine, tests, timeformat, unmarshal, unreachable, unsafeptr,
+    #   unusedresult
+    # ).
+    # Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers.
+    # Default: []
+    enable:
+      - appends
+      - asmdecl
+      - assign
+      - atomic
+      - atomicalign
+      - bools
+      - buildtag
+      - cgocall
+      - composites
+      - copylocks
+      - deepequalerrors
+      - defers
+      - directive
+      - errorsas
+      - fieldalignment
+      - findcall
+      - framepointer
+      - httpresponse
+      - ifaceassert
+      - loopclosure
+      - lostcancel
+      - nilfunc
+      - nilness
+      - printf
+      - reflectvaluecompare
+      - shadow
+      - shift
+      - sigchanyzer
+      - slog
+      - sortslice
+      - stdmethods
+      - stringintconv
+      - structtag
+      - testinggoroutine
+      - tests
+      - unmarshal
+      - unreachable
+      - unsafeptr
+      - unusedresult
+      - unusedwrite
+
+    # Enable all analyzers.
+    # Default: false
+    enable-all: true
+    # Disable analyzers by name.
+    # (in addition to default
+    #   atomicalign, deepequalerrors, fieldalignment, findcall, nilness, reflectvaluecompare, shadow, sortslice,
+    #   timeformat, unusedwrite
+    # ).
+    # Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers.
+    # Default: []
+    disable:
+      - appends
+      - asmdecl
+      - assign
+      - atomic
+      - atomicalign
+      - bools
+      - buildtag
+      - cgocall
+      - composites
+      - copylocks
+      - deepequalerrors
+      - defers
+      - directive
+      - errorsas
+      - fieldalignment
+      - findcall
+      - framepointer
+      - httpresponse
+      - ifaceassert
+      - loopclosure
+      - lostcancel
+      - nilfunc
+      - nilness
+      - printf
+      - reflectvaluecompare
+      - shadow
+      - shift
+      - sigchanyzer
+      - slog
+      - sortslice
+      - stdmethods
+      - stringintconv
+      - structtag
+      - testinggoroutine
+      - tests
+      - unmarshal
+      - unreachable
+      - unsafeptr
+      - unusedresult
+      - unusedwrite
+
+  grouper:
+    # Require the use of a single global 'const' declaration only.
+    # Default: false
+    const-require-single-const: true
+    # Require the use of grouped global 'const' declarations.
+    # Default: false
+    const-require-grouping: true
+
+    # Require the use of a single 'import' declaration only.
+    # Default: false
+    import-require-single-import: true
+    # Require the use of grouped 'import' declarations.
+    # Default: false
+    import-require-grouping: true
+
+    # Require the use of a single global 'type' declaration only.
+    # Default: false
+    type-require-single-type: true
+    # Require the use of grouped global 'type' declarations.
+    # Default: false
+    type-require-grouping: true
+
+    # Require the use of a single global 'var' declaration only.
+    # Default: false
+    var-require-single-var: true
+    # Require the use of grouped global 'var' declarations.
+    # Default: false
+    var-require-grouping: true
+
+  importas:
+    # Do not allow unaliased imports of aliased packages.
+    # Default: false
+    no-unaliased: true
+    # Do not allow non-required aliases.
+    # Default: false
+    no-extra-aliases: true
+    # List of aliases
+    # Default: []
+    alias:
+      # Using `servingv1` alias for `knative.dev/serving/pkg/apis/serving/v1` package.
+      - pkg: knative.dev/serving/pkg/apis/serving/v1
+        alias: servingv1
+      # Using `autoscalingv1alpha1` alias for `knative.dev/serving/pkg/apis/autoscaling/v1alpha1` package.
+      - pkg: knative.dev/serving/pkg/apis/autoscaling/v1alpha1
+        alias: autoscalingv1alpha1
+      # You can specify the package path by regular expression,
+      # and alias by regular expression expansion syntax like below.
+      # see https://github.com/julz/importas#use-regular-expression for details
+      - pkg: knative.dev/serving/pkg/apis/(\w+)/(v[\w\d]+)
+        alias: $1$2
+
+  inamedparam:
+    # Skips check for interface methods with only a single parameter.
+    # Default: false
+    skip-single-param: true
+
+  interfacebloat:
+    # The maximum number of methods allowed for an interface.
+    # Default: 10
+    max: 5
+
+  ireturn:
+    # ireturn does not allow using `allow` and `reject` settings at the same time.
+    # Both settings are lists of the keywords and regular expressions matched to interface or package names.
+    # keywords:
+    # - `empty` for `interface{}`
+    # - `error` for errors
+    # - `stdlib` for standard library
+    # - `anon` for anonymous interfaces
+    # - `generic` for generic interfaces added in go 1.18
+
+    # By default, it allows using errors, empty interfaces, anonymous interfaces,
+    # and interfaces provided by the standard library.
+    allow:
+      - anon
+      - error
+      - empty
+      - stdlib
+      # You can specify idiomatic endings for interface
+      - (or|er)$
+
+    # reject-list of interfaces
+    reject:
+      - github.com\/user\/package\/v4\.Type
+
+  lll:
+    # Max line length, lines longer will be reported.
+    # '\t' is counted as 1 character by default, and can be changed with the tab-width option.
+    # Default: 120.
+    line-length: 120
+    # Tab width in spaces.
+    # Default: 1
+    tab-width: 1
+
+  loggercheck:
+    # Allow check for the github.com/go-kit/log library.
+    # Default: true
+    kitlog: false
+    # Allow check for the k8s.io/klog/v2 library.
+    # Default: true
+    klog: false
+    # Allow check for the github.com/go-logr/logr library.
+    # Default: true
+    logr: false
+    # Allow check for the "sugar logger" from go.uber.org/zap library.
+    # Default: true
+    zap: false
+    # Require all logging keys to be inlined constant strings.
+    # Default: false
+    require-string-key: true
+    # Require printf-like format specifier (%s, %d for example) not present.
+    # Default: false
+    no-printf-like: true
+    # List of custom rules to check against, where each rule is a single logger pattern, useful for wrapped loggers.
+    # For example: https://github.com/timonwong/loggercheck/blob/7395ab86595781e33f7afba27ad7b55e6956ebcd/testdata/custom-rules.txt
+    # Default: empty
+    rules:
+      - k8s.io/klog/v2.InfoS   # package level exported functions
+      - (github.com/go-logr/logr.Logger).Error  # "Methods"
+      - (*go.uber.org/zap.SugaredLogger).With  # Also "Methods", but with a pointer receiver
+
+  maintidx:
+    # Show functions with maintainability index lower than N.
+    # A high index indicates better maintainability (it's kind of the opposite of complexity).
+    # Default: 20
+    under: 100
+
+  makezero:
+    # Allow only slices initialized with a length of zero.
+    # Default: false
+    always: true
+
+  misspell:
+    # Correct spellings using locale preferences for US or UK.
+    # Setting locale to US will correct the British spelling of 'colour' to 'color'.
+    # Default is to use a neutral variety of English.
+    locale: US
+    # Typos to ignore.
+    # Should be in lower case.
+    # Default: []
+    ignore-words:
+      - someword
+    # Extra word corrections.
+    # `typo` and `correction` should only contain letters.
+    # The words are case-insensitive.
+    # Default: []
+    extra-words:
+      - typo: "iff"
+        correction: "if"
+      - typo: "cancelation"
+        correction: "cancellation"
+    # Mode of the analysis:
+    # - default: checks all the file content.
+    # - restricted: checks only comments.
+    # Default: ""
+    mode: restricted
+
+  musttag:
+    # A set of custom functions to check in addition to the builtin ones.
+    # Default: json, xml, gopkg.in/yaml.v3, BurntSushi/toml, mitchellh/mapstructure, jmoiron/sqlx
+    functions:
+      # The full name of the function, including the package.
+      - name: github.com/hashicorp/hcl/v2/hclsimple.DecodeFile
+        # The struct tag whose presence should be ensured.
+        tag: hcl
+        # The position of the argument to check.
+        arg-pos: 2
+
+  nakedret:
+    # Make an issue if func has more lines of code than this setting, and it has naked returns.
+    # Default: 30
+    max-func-lines: 31
+
+  nestif:
+    # Minimal complexity of if statements to report.
+    # Default: 5
+    min-complexity: 4
+
+  nilnil:
+    # Checks that there is no simultaneous return of `nil` error and an invalid value.
+    # Default: ["ptr", "func", "iface", "map", "chan"]
+    checked-types:
+      - ptr
+      - func
+      - iface
+      - map
+      - chan
+
+  nlreturn:
+    # Size of the block (including return statement that is still "OK")
+    # so no return split required.
+    # Default: 1
+    block-size: 2
+
+  nolintlint:
+    # Disable to ensure that all nolint directives actually have an effect.
+    # Default: false
+    allow-unused: true
+    # Exclude following linters from requiring an explanation.
+    # Default: []
+    allow-no-explanation: [ ]
+    # Enable to require an explanation of nonzero length after each nolint directive.
+    # Default: false
+    require-explanation: true
+    # Enable to require nolint directives to mention the specific linter being suppressed.
+    # Default: false
+    require-specific: true
+
+  nonamedreturns:
+    # Report named error if it is assigned inside defer.
+    # Default: false
+    report-error-in-defer: true
+
+  paralleltest:
+    # Ignore missing calls to `t.Parallel()` and only report incorrect uses of it.
+    # Default: false
+    ignore-missing: true
+    # Ignore missing calls to `t.Parallel()` in subtests. Top-level tests are
+    # still required to have `t.Parallel`, but subtests are allowed to skip it.
+    # Default: false
+    ignore-missing-subtests: true
+
+  perfsprint:
+    # Optimizes even if it requires an int or uint type cast.
+    # Default: true
+    int-conversion: false
+    # Optimizes into `err.Error()` even if it is only equivalent for non-nil errors.
+    # Default: false
+    err-error: true
+    # Optimizes `fmt.Errorf`.
+    # Default: true
+    errorf: false
+    # Optimizes `fmt.Sprintf` with only one argument.
+    # Default: true
+    sprintf1: false
+    # Optimizes into strings concatenation.
+    # Default: true
+    strconcat: false
+
+  prealloc:
+    # IMPORTANT: we don't recommend using this linter before doing performance profiling.
+    # For most programs usage of prealloc will be a premature optimization.
+
+    # Report pre-allocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
+    # Default: true
+    simple: false
+    # Report pre-allocation suggestions on range loops.
+    # Default: true
+    range-loops: false
+    # Report pre-allocation suggestions on for loops.
+    # Default: false
+    for-loops: true
+
+  predeclared:
+    # Comma-separated list of predeclared identifiers to not report on.
+    # Default: ""
+    ignore: "new,int"
+    # Include method names and field names (i.e., qualified names) in checks.
+    # Default: false
+    q: true
+
+  promlinter:
+    # Promlinter cannot infer all metrics name in static analysis.
+    # Enable strict mode will also include the errors caused by failing to parse the args.
+    # Default: false
+    strict: true
+    # Please refer to https://github.com/yeya24/promlinter#usage for detailed usage.
+    # Default: []
+    disabled-linters:
+      - Help
+      - MetricUnits
+      - Counter
+      - HistogramSummaryReserved
+      - MetricTypeInName
+      - ReservedChars
+      - CamelCase
+      - UnitAbbreviations
+
+  protogetter:
+    # Skip files generated by specified generators from the checking.
+    # Checks only the file's initial comment, which must follow the format: "// Code generated by <generator-name>".
+    # Files generated by protoc-gen-go, protoc-gen-go-grpc, and protoc-gen-grpc-gateway are always excluded automatically.
+    # Default: []
+    skip-generated-by: ["protoc-gen-go-my-own-generator"]
+    # Skip files matching the specified glob pattern from the checking.
+    # Default: []
+    skip-files:
+      - "*.pb.go"
+      - "*/vendor/*"
+      - "/full/path/to/file.go"
+    # Skip any generated files from the checking.
+    # Default: false
+    skip-any-generated: true
+    # Skip first argument of append function.
+    # Default: false
+    replace-first-arg-in-append: true
+
+  reassign:
+    # Patterns for global variable names that are checked for reassignment.
+    # See https://github.com/curioswitch/go-reassign#usage
+    # Default: ["EOF", "Err.*"]
+    patterns:
+      - ".*"
+
+  revive:
+    # Maximum number of open files at the same time.
+    # See https://github.com/mgechev/revive#command-line-flags
+    # Defaults to unlimited.
+    max-open-files: 2048
+
+    # When set to false, ignores files with "GENERATED" header, similar to golint.
+    # See https://github.com/mgechev/revive#available-rules for details.
+    # Default: false
+    ignore-generated-header: true
+
+    # Sets the default severity.
+    # See https://github.com/mgechev/revive#configuration
+    # Default: warning
+    severity: error
+
+    # Enable all available rules.
+    # Default: false
+    enable-all-rules: true
+
+    # Sets the default failure confidence.
+    # This means that linting errors with less than 0.8 confidence will be ignored.
+    # Default: 0.8
+    confidence: 0.1
+
+    rules:
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#add-constant
+      - name: add-constant
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - maxLitCount: "3"
+            allowStrs: '""'
+            allowInts: "0,1,2"
+            allowFloats: "0.0,0.,1.0,1.,2.0,2."
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#argument-limit
+      - name: argument-limit
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ 4 ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#atomic
+      - name: atomic
+        severity: warning
+        exclude: [""]
+        disabled: false
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#banned-characters
+      - name: banned-characters
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ "Ω","Σ","σ", "7" ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bare-return
+      - name: bare-return
+        severity: warning
+        exclude: [""]
+        disabled: false
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#blank-imports
+      - name: blank-imports
+        severity: warning
+        exclude: [""]
+        disabled: false
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bool-literal-in-expr
+      - name: bool-literal-in-expr
+        severity: warning
+        exclude: [""]
+        disabled: false
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#call-to-gc
+      - name: call-to-gc
+        severity: warning
+        exclude: [""]
+        disabled: false
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cognitive-complexity
+      - name: cognitive-complexity
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ 7 ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#comment-spacings
+      - name: comment-spacings
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - mypragma
+          - otherpragma
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-naming
+      - name: confusing-naming
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-results
+      - name: confusing-results
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#constant-logical-expr
+      - name: constant-logical-expr
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-as-argument
+      - name: context-as-argument
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - allowTypesBefore: "*testing.T,*github.com/user/repo/testing.Harness"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-keys-type
+      - name: context-keys-type
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cyclomatic
+      - name: cyclomatic
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ 3 ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#datarace
+      - name: datarace
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#deep-exit
+      - name: deep-exit
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#defer
+      - name: defer
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - [ "call-chain", "loop" ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#dot-imports
+      - name: dot-imports
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#duplicated-imports
+      - name: duplicated-imports
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#early-return
+      - name: early-return
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "preserveScope"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-block
+      - name: empty-block
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines
+      - name: empty-lines
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-map-style
+      - name: enforce-map-style
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "make"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-repeated-arg-type-style
+      - name: enforce-repeated-arg-type-style
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "short"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-slice-style
+      - name: enforce-slice-style
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "make"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-naming
+      - name: error-naming
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-return
+      - name: error-return
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-strings
+      - name: error-strings
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#errorf
+      - name: errorf
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#exported
+      - name: exported
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "preserveScope"
+          - "checkPrivateReceivers"
+          - "sayRepetitiveInsteadOfStutters"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#file-header
+      - name: file-header
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - This is the text that must appear at the top of source files.
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#flag-parameter
+      - name: flag-parameter
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-result-limit
+      - name: function-result-limit
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ 2 ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-length
+      - name: function-length
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ 10, 0 ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#get-return
+      - name: get-return
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#identical-branches
+      - name: identical-branches
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#if-return
+      - name: if-return
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#increment-decrement
+      - name: increment-decrement
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow
+      - name: indent-error-flow
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "preserveScope"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-alias-naming
+      - name: import-alias-naming
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "^[a-z][a-z0-9]{0,}$"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#imports-blocklist
+      - name: imports-blocklist
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "crypto/md5"
+          - "crypto/sha1"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-shadowing
+      - name: import-shadowing
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#line-length-limit
+      - name: line-length-limit
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ 80 ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#max-control-nesting
+      - name: max-control-nesting
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ 3 ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#max-public-structs
+      - name: max-public-structs
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments: [ 3 ]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-parameter
+      - name: modifies-parameter
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-value-receiver
+      - name: modifies-value-receiver
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#nested-structs
+      - name: nested-structs
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#optimize-operands-order
+      - name: optimize-operands-order
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments
+      - name: package-comments
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range
+      - name: range
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-in-closure
+      - name: range-val-in-closure
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-address
+      - name: range-val-address
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#receiver-naming
+      - name: receiver-naming
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redundant-import-alias
+      - name: redundant-import-alias
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redefines-builtin-id
+      - name: redefines-builtin-id
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-of-int
+      - name: string-of-int
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-format
+      - name: string-format
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - - 'core.WriteError[1].Message'
+            - '/^([^A-Z]|$)/'
+            - must not start with a capital letter
+          - - 'fmt.Errorf[0]'
+            - '/(^|[^\.!?])$/'
+            - must not end in punctuation
+          - - panic
+            - '/^[^\n]*$/'
+            - must not contain line breaks
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#struct-tag
+      - name: struct-tag
+        arguments:
+          - "json,inline"
+          - "bson,outline,gnu"
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#superfluous-else
+      - name: superfluous-else
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "preserveScope"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-equal
+      - name: time-equal
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-naming
+      - name: time-naming
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-naming
+      - name: var-naming
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - [ "ID" ] # AllowList
+          - [ "VM" ] # DenyList
+          - - upperCaseConst: true
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-declaration
+      - name: var-declaration
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unconditional-recursion
+      - name: unconditional-recursion
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-naming
+      - name: unexported-naming
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-return
+      - name: unexported-return
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unhandled-error
+      - name: unhandled-error
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - "fmt.Printf"
+          - "myFunction"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unnecessary-stmt
+      - name: unnecessary-stmt
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unreachable-code
+      - name: unreachable-code
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter
+      - name: unused-parameter
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - allowRegex: "^_"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-receiver
+      - name: unused-receiver
+        severity: warning
+        disabled: false
+        exclude: [""]
+        arguments:
+          - allowRegex: "^_"
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#useless-break
+      - name: useless-break
+        severity: warning
+        disabled: false
+        exclude: [""]
+      # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#waitgroup-by-value
+      - name: waitgroup-by-value
+        severity: warning
+        disabled: false
+        exclude: [""]
+
+  rowserrcheck:
+    # database/sql is always checked
+    # Default: []
+    packages:
+      - github.com/jmoiron/sqlx
+
+  sloglint:
+    # Enforce not mixing key-value pairs and attributes.
+    # Default: true
+    no-mixed-args: false
+    # Enforce using key-value pairs only (overrides no-mixed-args, incompatible with attr-only).
+    # Default: false
+    kv-only: true
+    # Enforce using attributes only (overrides no-mixed-args, incompatible with kv-only).
+    # Default: false
+    attr-only: true
+    # Enforce using methods that accept a context.
+    # Default: false
+    context-only: true
+    # Enforce using static values for log messages.
+    # Default: false
+    static-msg: true
+    # Enforce using constants instead of raw keys.
+    # Default: false
+    no-raw-keys: true
+    # Enforce a single key naming convention.
+    # Values: snake, kebab, camel, pascal
+    # Default: ""
+    key-naming-case: snake
+    # Enforce putting arguments on separate lines.
+    # Default: false
+    args-on-sep-lines: true
+
+  spancheck:
+    # Checks to enable.
+    # Options include:
+    # - `end`: check that `span.End()` is called
+    # - `record-error`: check that `span.RecordError(err)` is called when an error is returned
+    # - `set-status`: check that `span.SetStatus(codes.Error, msg)` is called when an error is returned
+    # Default: ["end"]
+    checks:
+      - end
+      - record-error
+      - set-status
+    # A list of regexes for function signatures that silence `record-error` and `set-status` reports
+    # if found in the call path to a returned error.
+    # https://github.com/jjti/go-spancheck#ignore-check-signatures
+    # Default: []
+    ignore-check-signatures:
+      - "telemetry.RecordError"
+
+  staticcheck:
+    # Deprecated: use the global `run.go` instead.
+    go: "1.15"
+    # SAxxxx checks in https://staticcheck.io/docs/configuration/options/#checks
+    # Default: ["*"]
+    checks: [ "all" ]
+
+  stylecheck:
+    # Deprecated: use the global `run.go` instead.
+    go: "1.15"
+    # STxxxx checks in https://staticcheck.io/docs/configuration/options/#checks
+    # Default: ["*"]
+    checks: [ "all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022" ]
+    # https://staticcheck.io/docs/configuration/options/#dot_import_whitelist
+    # Default: ["github.com/mmcloughlin/avo/build", "github.com/mmcloughlin/avo/operand", "github.com/mmcloughlin/avo/reg"]
+    dot-import-whitelist:
+      - fmt
+    # https://staticcheck.io/docs/configuration/options/#initialisms
+    # Default: ["ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS"]
+    initialisms: [ "ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "QPS", "RAM", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "GID", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS", "SIP", "RTP", "AMQP", "DB", "TS" ]
+    # https://staticcheck.io/docs/configuration/options/#http_status_code_whitelist
+    # Default: ["200", "400", "404", "500"]
+    http-status-code-whitelist: [ "200", "400", "404", "500" ]
+
+  tagalign:
+    # Align and sort can be used together or separately.
+    #
+    # Whether enable align. If true, the struct tags will be aligned.
+    # e.g.:
+    # type FooBar struct {
+    #     Bar    string `json:"bar" validate:"required"`
+    #     FooFoo int8   `json:"foo_foo" validate:"required"`
+    # }
+    # will be formatted to:
+    # type FooBar struct {
+    #     Bar    string `json:"bar"     validate:"required"`
+    #     FooFoo int8   `json:"foo_foo" validate:"required"`
+    # }
+    # Default: true.
+    align: false
+    # Whether enable tags sort.
+    # If true, the tags will be sorted by name in ascending order.
+    # e.g.: `xml:"bar" json:"bar" validate:"required"` -> `json:"bar" validate:"required" xml:"bar"`
+    # Default: true
+    sort: false
+    # Specify the order of tags, the other tags will be sorted by name.
+    # This option will be ignored if `sort` is false.
+    # Default: []
+    order:
+      - json
+      - yaml
+      - yml
+      - toml
+      - mapstructure
+      - binding
+      - validate
+    # Whether enable strict style.
+    # In this style, the tags will be sorted and aligned in the dictionary order,
+    # and the tags with the same name will be aligned together.
+    # Note: This option will be ignored if 'align' or 'sort' is false.
+    # Default: false
+    strict: true
+
+  tagliatelle:
+    # Check the struct tag name case.
+    case:
+      # Use the struct field name to check the name of the struct tag.
+      # Default: false
+      use-field-name: true
+      # `camel` is used for `json` and `yaml`, and `header` is used for `header` (can be overridden)
+      # Default: {}
+      rules:
+        # Any struct tag type can be used.
+        # Support string case: `camel`, `pascal`, `kebab`, `snake`, `upperSnake`, `goCamel`, `goPascal`, `goKebab`, `goSnake`, `upper`, `lower`, `header`
+        json: camel
+        yaml: camel
+        xml: camel
+        bson: camel
+        avro: snake
+        mapstructure: kebab
+        env: upperSnake
+        envconfig: upperSnake
+
+  tenv:
+    # The option `all` will run against whole test files (`_test.go`) regardless of method/function signatures.
+    # Otherwise, only methods that take `*testing.T`, `*testing.B`, and `testing.TB` as arguments are checked.
+    # Default: false
+    all: false
+
+  testifylint:
+    # Enable all checkers (https://github.com/Antonboom/testifylint#checkers).
+    # Default: false
+    enable-all: true
+    # Disable checkers by name
+    # (in addition to default
+    #   suite-thelper
+    # ).
+    disable:
+      - blank-import
+      - bool-compare
+      - compares
+      - empty
+      - error-is-as
+      - error-nil
+      - expected-actual
+      - go-require
+      - float-compare
+      - len
+      - nil-compare
+      - require-error
+      - suite-dont-use-pkg
+      - suite-extra-assert-call
+      - suite-thelper
+      - useless-assert
+
+    # Disable all checkers (https://github.com/Antonboom/testifylint#checkers).
+    # Default: false
+    disable-all: true
+    # Enable checkers by name
+    # (in addition to default
+    #   blank-import, bool-compare, compares, empty, error-is-as, error-nil, expected-actual, go-require, float-compare,
+    #   len, nil-compare, require-error, suite-dont-use-pkg, suite-extra-assert-call, useless-assert
+    # ).
+    enable:
+      - blank-import
+      - bool-compare
+      - compares
+      - empty
+      - error-is-as
+      - error-nil
+      - expected-actual
+      - go-require
+      - float-compare
+      - len
+      - nil-compare
+      - require-error
+      - suite-dont-use-pkg
+      - suite-extra-assert-call
+      - suite-thelper
+      - useless-assert
+
+    bool-compare:
+      # To ignore user defined types (over builtin bool).
+      # Default: false
+      ignore-custom-types: true
+    expected-actual:
+      # Regexp for expected variable name.
+      # Default: (^(exp(ected)?|want(ed)?)([A-Z]\w*)?$)|(^(\w*[a-z])?(Exp(ected)?|Want(ed)?)$)
+      pattern: ^expected
+    require-error:
+      # Regexp for assertions to analyze. If defined, then only matched error assertions will be reported.
+      # Default: ""
+      fn-pattern: ^(Errorf?|NoErrorf?)$
+    suite-extra-assert-call:
+      # To require or remove extra Assert() call?
+      # Default: remove
+      mode: require
+
+  testpackage:
+    # Regexp pattern to skip files.
+    # Default: "(export|internal)_test\\.go"
+    skip-regexp: (export|internal)_test\.go
+    # List of packages that don't end with _test that tests are allowed to be in.
+    # Default: "main"
+    allow-packages:
+      - example
+      - main
+
+  thelper:
+    test:
+      # Check *testing.T is first param (or after context.Context) of helper function.
+      # Default: true
+      first: false
+      # Check *testing.T param has name t.
+      # Default: true
+      name: false
+      # Check t.Helper() begins helper function.
+      # Default: true
+      begin: false
+    benchmark:
+      # Check *testing.B is first param (or after context.Context) of helper function.
+      # Default: true
+      first: false
+      # Check *testing.B param has name b.
+      # Default: true
+      name: false
+      # Check b.Helper() begins helper function.
+      # Default: true
+      begin: false
+    tb:
+      # Check *testing.TB is first param (or after context.Context) of helper function.
+      # Default: true
+      first: false
+      # Check *testing.TB param has name tb.
+      # Default: true
+      name: false
+      # Check tb.Helper() begins helper function.
+      # Default: true
+      begin: false
+    fuzz:
+      # Check *testing.F is first param (or after context.Context) of helper function.
+      # Default: true
+      first: false
+      # Check *testing.F param has name f.
+      # Default: true
+      name: false
+      # Check f.Helper() begins helper function.
+      # Default: true
+      begin: false
+
+  usestdlibvars:
+    # Suggest the use of http.MethodXX.
+    # Default: true
+    http-method: false
+    # Suggest the use of http.StatusXX.
+    # Default: true
+    http-status-code: false
+    # Suggest the use of time.Weekday.String().
+    # Default: true
+    time-weekday: true
+    # Suggest the use of time.Month.String().
+    # Default: false
+    time-month: true
+    # Suggest the use of time.Layout.
+    # Default: false
+    time-layout: true
+    # Suggest the use of crypto.Hash.String().
+    # Default: false
+    crypto-hash: true
+    # Suggest the use of rpc.DefaultXXPath.
+    # Default: false
+    default-rpc-path: true
+    # DEPRECATED Suggest the use of os.DevNull.
+    # Default: false
+    os-dev-null: true
+    # Suggest the use of sql.LevelXX.String().
+    # Default: false
+    sql-isolation-level: true
+    # Suggest the use of tls.SignatureScheme.String().
+    # Default: false
+    tls-signature-scheme: true
+    # Suggest the use of constant.Kind.String().
+    # Default: false
+    constant-kind: true
+    # DEPRECATED Suggest the use of syslog.Priority.
+    # Default: false
+    syslog-priority: true
+
+  unconvert:
+    # Remove conversions that force intermediate rounding.
+    # Default: false
+    fast-math: true
+    # Be more conservative (experimental).
+    # Default: false
+    safe: true
+
+  unparam:
+    # Inspect exported functions.
+    #
+    # Set to true if no external program/library imports your code.
+    # XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
+    # if it's called for subdir of a project it can't find external interfaces. All text editor integrations
+    # with golangci-lint call it on a directory with the changed file.
+    #
+    # Default: false
+    check-exported: true
+
+  unused:
+    # Mark all struct fields that have been written to as used.
+    # Default: true
+    field-writes-are-uses: false
+    # Treat IncDec statement (e.g. `i++` or `i--`) as both read and write operation instead of just write.
+    # Default: false
+    post-statements-are-reads: true
+    # Mark all exported identifiers as used.
+    # Default: true
+    exported-is-used: false
+    # Mark all exported fields as used.
+    # default: true
+    exported-fields-are-used: false
+    # Mark all function parameters as used.
+    # default: true
+    parameters-are-used: false
+    # Mark all local variables as used.
+    # default: true
+    local-variables-are-used: false
+    # Mark all identifiers inside generated files as used.
+    # Default: true
+    generated-is-used: false
+
+  varnamelen:
+    # The longest distance, in source lines, that is being considered a "small scope".
+    # Variables used in at most this many lines will be ignored.
+    # Default: 5
+    max-distance: 6
+    # The minimum length of a variable's name that is considered "long".
+    # Variable names that are at least this long will be ignored.
+    # Default: 3
+    min-name-length: 2
+    # Check method receivers.
+    # Default: false
+    check-receiver: true
+    # Check named return values.
+    # Default: false
+    check-return: true
+    # Check type parameters.
+    # Default: false
+    check-type-param: true
+    # Ignore "ok" variables that hold the bool return value of a type assertion.
+    # Default: false
+    ignore-type-assert-ok: true
+    # Ignore "ok" variables that hold the bool return value of a map index.
+    # Default: false
+    ignore-map-index-ok: true
+    # Ignore "ok" variables that hold the bool return value of a channel receive.
+    # Default: false
+    ignore-chan-recv-ok: true
+    # Optional list of variable names that should be ignored completely.
+    # Default: []
+    ignore-names:
+      - err
+    # Optional list of variable declarations that should be ignored completely.
+    # Entries must be in one of the following forms (see below for examples):
+    # - for variables, parameters, named return values, method receivers, or type parameters:
+    #   <name> <type>  (<type> can also be a pointer/slice/map/chan/...)
+    # - for constants: const <name>
+    #
+    # Default: []
+    ignore-decls:
+      - c echo.Context
+      - t testing.T
+      - f *foo.Bar
+      - e error
+      - i int
+      - const C
+      - T any
+      - m map[string]int
+
+  whitespace:
+    # Enforces newlines (or comments) after every multi-line if statement.
+    # Default: false
+    multi-if: true
+    # Enforces newlines (or comments) after every multi-line function signature.
+    # Default: false
+    multi-func: true
+
+  wrapcheck:
+    # An array of strings that specify substrings of signatures to ignore.
+    # If this set, it will override the default set of ignored signatures.
+    # See https://github.com/tomarrell/wrapcheck#configuration for more information.
+    # Default: [".Errorf(", "errors.New(", "errors.Unwrap(", "errors.Join(", ".Wrap(", ".Wrapf(", ".WithMessage(", ".WithMessagef(", ".WithStack("]
+    ignoreSigs:
+      - .Errorf(
+      - errors.New(
+      - errors.Unwrap(
+      - errors.Join(
+      - .Wrap(
+      - .Wrapf(
+      - .WithMessage(
+      - .WithMessagef(
+      - .WithStack(
+    # An array of strings that specify regular expressions of signatures to ignore.
+    # Default: []
+    ignoreSigRegexps:
+      - \.New.*Error\(
+    # An array of strings that specify globs of packages to ignore.
+    # Default: []
+    ignorePackageGlobs:
+      - encoding/*
+      - github.com/pkg/*
+    # An array of strings that specify regular expressions of interfaces to ignore.
+    # Default: []
+    ignoreInterfaceRegexps:
+      - ^(?i)c(?-i)ach(ing|e)
+
+  wsl:
+    # See https://github.com/bombsimon/wsl/blob/master/doc/configuration.md for documentation of available settings.
+    # These are the defaults for `golangci-lint`.
+
+    # Do strict checking when assigning from append (x = append(x, y)). If
+    # this is set to true - the append call must append either a variable
+    # assigned, called or used on the line above.
+    strict-append: true
+
+    # Allows assignments to be cuddled with variables used in calls on
+    # line above and calls to be cuddled with assignments of variables
+    # used in call on line above.
+    allow-assign-and-call: true
+
+    # Allows assignments to be cuddled with anything.
+    allow-assign-and-anything: false
+
+    # Allows cuddling to assignments even if they span over multiple lines.
+    allow-multiline-assign: true
+
+    # If the number of lines in a case block is equal to or lager than this
+    # number, the case *must* end white a newline.
+    force-case-trailing-whitespace: 0
+
+    # Allow blocks to end with comments.
+    allow-trailing-comment: false
+
+    # Allow multiple comments in the beginning of a block separated with newline.
+    allow-separated-leading-comment: false
+
+    # Allow multiple var/declaration statements to be cuddled.
+    allow-cuddle-declarations: false
+
+    # A list of call idents that everything can be cuddled with.
+    # Defaults to calls looking like locks.
+    allow-cuddle-with-calls: [ "Lock", "RLock" ]
+
+    # AllowCuddleWithRHS is a list of right hand side variables that is allowed
+    # to be cuddled with anything. Defaults to assignments or calls looking
+    # like unlocks.
+    allow-cuddle-with-rhs: [ "Unlock", "RUnlock" ]
+
+    # Causes an error when an If statement that checks an error variable doesn't
+    # cuddle with the assignment of that variable.
+    force-err-cuddling: false
+
+    # When force-err-cuddling is enabled this is a list of names
+    # used for error variables to check for in the conditional.
+    error-variable-names: [ "err" ]
+
+    # Causes an error if a short declaration (:=) cuddles with anything other than
+    # another short declaration.
+    # This logic overrides force-err-cuddling among others.
+    force-short-decl-cuddling: false
+
+  # The custom section can be used to define linter plugins to be loaded at runtime.
+  # See README documentation for more info.
+  custom:
+    # Each custom linter should have a unique name.
+    example:
+      # The plugin type.
+      # It can be `goplugin` or `module`.
+      # Default: goplugin
+      type: module
+      # The path to the plugin *.so. Can be absolute or local.
+      # Required for each custom linter.
+      path: /path/to/example.so
+      # The description of the linter.
+      # Optional.
+      description: This is an example usage of a plugin linter.
+      # Intended to point to the repo location of the linter.
+      # Optional.
+      original-url: github.com/golangci/example-linter
+      # Plugins settings/configuration.
+      # Only work with plugin based on `linterdb.PluginConstructor`.
+      # Optional.
+      settings:
+        foo: bar
+
+
+linters:
+  # Disable all linters.
+  # Default: false
+  disable-all: true
+  # Enable specific linter
+  # https://golangci-lint.run/usage/linters/#enabled-by-default
+  enable:
+    - asasalint
+    - asciicheck
+    - bidichk
+    - bodyclose
+    - containedctx
+    - contextcheck
+    - copyloopvar
+    - cyclop
+    - decorder
+    - depguard
+    - dogsled
+    - dupl
+    - dupword
+    - durationcheck
+    - errcheck
+    - errchkjson
+    - errname
+    - errorlint
+    - execinquery
+    - exhaustive
+    - exhaustruct
+    - exportloopref
+    - forbidigo
+    - forcetypeassert
+    - funlen
+    - gci
+    - ginkgolinter
+    - gocheckcompilerdirectives
+    - gochecknoglobals
+    - gochecknoinits
+    - gochecksumtype
+    - gocognit
+    - goconst
+    - gocritic
+    - gocyclo
+    - godot
+    - godox
+    - goerr113
+    - gofmt
+    - gofumpt
+    - goheader
+    - goimports
+    - gomnd
+    - gomoddirectives
+    - gomodguard
+    - goprintffuncname
+    - gosec
+    - gosimple
+    - gosmopolitan
+    - govet
+    - grouper
+    - importas
+    - inamedparam
+    - ineffassign
+    - interfacebloat
+    - intrange
+    - ireturn
+    - lll
+    - loggercheck
+    - maintidx
+    - makezero
+    - mirror
+    - misspell
+    - musttag
+    - nakedret
+    - nestif
+    - nilerr
+    - nilnil
+    - nlreturn
+    - noctx
+    - nolintlint
+    - nonamedreturns
+    - nosprintfhostport
+    - paralleltest
+    - perfsprint
+    - prealloc
+    - predeclared
+    - promlinter
+    - protogetter
+    - reassign
+    - revive
+    - rowserrcheck
+    - sloglint
+    - spancheck
+    - sqlclosecheck
+    - staticcheck
+    - stylecheck
+    - tagalign
+    - tagliatelle
+    - tenv
+    - testableexamples
+    - testifylint
+    - testpackage
+    - thelper
+    - tparallel
+    - typecheck
+    - unconvert
+    - unparam
+    - unused
+    - usestdlibvars
+    - varnamelen
+    - wastedassign
+    - whitespace
+    - wrapcheck
+    - wsl
+    - zerologlint
+
+  # Enable all available linters.
+  # Default: false
+  enable-all: true
+  # Disable specific linter
+  # https://golangci-lint.run/usage/linters/#disabled-by-default
+  disable:
+    - asasalint
+    - asciicheck
+    - bidichk
+    - bodyclose
+    - containedctx
+    - contextcheck
+    - copyloopvar
+    - cyclop
+    - decorder
+    - depguard
+    - dogsled
+    - dupl
+    - dupword
+    - durationcheck
+    - errcheck
+    - errchkjson
+    - errname
+    - errorlint
+    - execinquery
+    - exhaustive
+    - exhaustruct
+    - exportloopref
+    - forbidigo
+    - forcetypeassert
+    - funlen
+    - gci
+    - ginkgolinter
+    - gocheckcompilerdirectives
+    - gochecknoglobals
+    - gochecknoinits
+    - gochecksumtype
+    - gocognit
+    - goconst
+    - gocritic
+    - gocyclo
+    - godot
+    - godox
+    - goerr113
+    - gofmt
+    - gofumpt
+    - goheader
+    - goimports
+    - gomnd
+    - gomoddirectives
+    - gomodguard
+    - goprintffuncname
+    - gosec
+    - gosimple
+    - gosmopolitan
+    - govet
+    - grouper
+    - importas
+    - inamedparam
+    - ineffassign
+    - interfacebloat
+    - intrange
+    - ireturn
+    - lll
+    - loggercheck
+    - maintidx
+    - makezero
+    - mirror
+    - misspell
+    - musttag
+    - nakedret
+    - nestif
+    - nilerr
+    - nilnil
+    - nlreturn
+    - noctx
+    - nolintlint
+    - nonamedreturns
+    - nosprintfhostport
+    - paralleltest
+    - perfsprint
+    - prealloc
+    - predeclared
+    - promlinter
+    - protogetter
+    - reassign
+    - revive
+    - rowserrcheck
+    - sloglint
+    - spancheck
+    - sqlclosecheck
+    - staticcheck
+    - stylecheck
+    - tagalign
+    - tagliatelle
+    - tenv
+    - testableexamples
+    - testifylint
+    - testpackage
+    - thelper
+    - tparallel
+    - typecheck
+    - unconvert
+    - unparam
+    - unused
+    - usestdlibvars
+    - varnamelen
+    - wastedassign
+    - whitespace
+    - wrapcheck
+    - wsl
+    - zerologlint
+    - deadcode # Deprecated
+    - exhaustivestruct # Deprecated
+    - golint # Deprecated
+    - ifshort # Deprecated
+    - interfacer # Deprecated
+    - maligned # Deprecated
+    - nosnakecase # Deprecated
+    - scopelint # Deprecated
+    - structcheck # Deprecated
+    - varcheck # Deprecated
+
+  # Enable presets.
+  # https://golangci-lint.run/usage/linters
+  # Default: []
+  presets:
+    - bugs
+    - comment
+    - complexity
+    - error
+    - format
+    - import
+    - metalinter
+    - module
+    - performance
+    - sql
+    - style
+    - test
+    - unused
+
+  # Enable only fast linters from enabled linters set (first run won't be fast)
+  # Default: false
+  fast: true
+
+
+issues:
+  # List of regexps of issue texts to exclude.
+  #
+  # But independently of this option we use default exclude patterns,
+  # it can be disabled by `exclude-use-default: false`.
+  # To list all excluded by default patterns execute `golangci-lint run --help`
+  #
+  # Default: https://golangci-lint.run/usage/false-positives/#default-exclusions
+  exclude:
+    - abcdef
+
+  # Excluding configuration per-path, per-linter, per-text and per-source
+  exclude-rules:
+    # Exclude some linters from running on tests files.
+    - path: _test\.go
+      linters:
+        - gocyclo
+        - errcheck
+        - dupl
+        - gosec
+
+    # Run some linter only for test files by excluding its issues for everything else.
+    - path-except: _test\.go
+      linters:
+        - forbidigo
+
+    # Exclude known linters from partially hard-vendored code,
+    # which is impossible to exclude via `nolint` comments.
+    # `/` will be replaced by current OS file path separator to properly work on Windows.
+    - path: internal/hmac/
+      text: "weak cryptographic primitive"
+      linters:
+        - gosec
+
+    # Exclude some `staticcheck` messages.
+    - linters:
+        - staticcheck
+      text: "SA9003:"
+
+    # Exclude `lll` issues for long lines with `go:generate`.
+    - linters:
+        - lll
+      source: "^//go:generate "
+
+  # Independently of option `exclude` we use default exclude patterns,
+  # it can be disabled by this option.
+  # To list all excluded by default patterns execute `golangci-lint run --help`.
+  # Default: true
+  exclude-use-default: false
+
+  # If set to true exclude and exclude-rules regular expressions become case-sensitive.
+  # Default: false
+  exclude-case-sensitive: false
+
+  # The list of ids of default excludes to include or disable.
+  # https://golangci-lint.run/usage/false-positives/#default-exclusions
+  # Default: []
+  include:
+    - EXC0001
+    - EXC0002
+    - EXC0003
+    - EXC0004
+    - EXC0005
+    - EXC0006
+    - EXC0007
+    - EXC0008
+    - EXC0009
+    - EXC0010
+    - EXC0011
+    - EXC0012
+    - EXC0013
+    - EXC0014
+    - EXC0015
+
+  # Maximum issues count per one linter.
+  # Set to 0 to disable.
+  # Default: 50
+  max-issues-per-linter: 0
+
+  # Maximum count of issues with the same text.
+  # Set to 0 to disable.
+  # Default: 3
+  max-same-issues: 0
+
+  # Show only new issues: if there are unstaged changes or untracked files,
+  # only those changes are analyzed, else only changes in HEAD~ are analyzed.
+  # It's a super-useful option for integration of golangci-lint into existing large codebase.
+  # It's not practical to fix all existing issues at the moment of integration:
+  # much better don't allow issues in new code.
+  #
+  # Default: false
+  new: true
+
+  # Show only new issues created after git revision `REV`.
+  # Default: ""
+  new-from-rev: HEAD
+
+  # Show only new issues created in git patch with set file path.
+  # Default: ""
+  new-from-patch: path/to/patch/file
+
+  # Fix found issues (if it's supported by the linter).
+  # Default: false
+  fix: true
+
+  # Show issues in any part of update files (requires new-from-rev or new-from-patch).
+  # Default: false
+  whole-files: true
+
+severity:
+  # Set the default severity for issues.
+  #
+  # If severity rules are defined and the issues do not match or no severity is provided to the rule
+  # this will be the default severity applied.
+  # Severities should match the supported severity names of the selected out format.
+  # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity
+  # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#SeverityLevel
+  # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
+  # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance
+  #
+  # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
+  #
+  # Default: ""
+  default-severity: error
+
+  # If set to true `severity-rules` regular expressions become case-sensitive.
+  # Default: false
+  case-sensitive: true
+
+  # When a list of severity rules are provided, severity information will be added to lint issues.
+  # Severity rules have the same filtering capability as exclude rules
+  # except you are allowed to specify one matcher per severity rule.
+  #
+  # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
+  #
+  # Only affects out formats that support setting severity information.
+  #
+  # Default: []
+  rules:
+    - linters:
+        - dupl
+      severity: info
diff --git a/.golangci.reference.yml b/.golangci.reference.yml
index 4fbbe8fa..03e6fa40 100644
--- a/.golangci.reference.yml
+++ b/.golangci.reference.yml
@@ -6,8 +6,7 @@
 
 # Options for analysis running.
 run:
-  # Number of operating system threads  (`GOMAXPROCS`) that can execute golangci-lint simultaneously.
-  # If it is explicitly set to 0 (i.e. not the default) then golangci-lint will automatically set the value to match Linux container CPU quota.
+  # Number of CPUs to use when running golangci-lint.
   # Default: the number of logical CPUs in the machine
   concurrency: 4
 
@@ -81,6 +80,10 @@ run:
   # Default: use Go version from the go.mod file, fallback on the env var `GOVERSION`, fallback on 1.17
   go: '1.19'
 
+  # Show statistics per linter.
+  # Default: false
+  show-stats: true
+
 
 # output configuration options
 output:
@@ -110,32 +113,10 @@ output:
   # Default: ""
   path-prefix: ""
 
-  # Sort results by the order defined in `sort-order`.
+  # Sort results by: filepath, line and column.
   # Default: false
   sort-results: true
 
-  # Order to use when sorting results.
-  # Require `sort-results` to `true`.
-  # Possible values: `file`, `linter`, and `severity`.
-  #
-  # If the severity values are inside the following list, they are ordered in this order:
-  #   1. error
-  #   2. warning
-  #   3. high
-  #   4. medium
-  #   5. low
-  # Either they are sorted alphabetically.
-  #
-  # Default: ["file"]
-  sort-order:
-    - linter
-    - severity
-    - file # filepath, line, and column.
-
-  # Show statistics per linter.
-  # Default: false
-  show-stats: true
-
 
 # All available settings of specific linters.
 linters-settings:
@@ -168,11 +149,6 @@ linters-settings:
     first-strong-isolate: false
     pop-directional-isolate: false
 
-  copyloopvar:
-    # If true, ignore aliasing of loop variables.
-    # Default: false
-    ignore-alias: true
-
   cyclop:
     # The maximal code complexity to report.
     # Default: 10
@@ -388,6 +364,16 @@ linters-settings:
     # Default: false
     default-case-required: true
 
+  exhaustivestruct:
+    # Struct Patterns is list of expressions to match struct packages and names.
+    # The struct packages have the form `example.com/package.ExampleStruct`.
+    # The matching patterns can use matching syntax from https://pkg.go.dev/path#Match.
+    # If this list is empty, all structs are tested.
+    # Default: []
+    struct-patterns:
+      - '*.Test'
+      - 'example.com/package.ExampleStruct'
+
   exhaustruct:
     # List of regular expressions to match struct packages and their names.
     # Regular expressions must match complete canonical struct package/name/structname.
@@ -555,9 +541,6 @@ linters-settings:
       - ruleguard
       - truncateCmp
 
-    # Enable all checks.
-    # Default: false
-    enable-all: true
     # Which checks should be disabled; can't be combined with 'enabled-checks'.
     # Default: []
     disabled-checks:
@@ -780,6 +763,11 @@ linters-settings:
     # Default: ""
     local-prefixes: github.com/org/project
 
+  golint:
+    # Minimal confidence for issues.
+    # Default: 0.8
+    min-confidence: 0.7
+
   gomnd:
     # List of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description.
     # Default: ["argument", "case", "condition", "operation", "return", "assign"]
@@ -1119,7 +1107,7 @@ linters-settings:
     #   stdmethods, stringintconv, structtag, testinggoroutine, tests, timeformat, unmarshal, unreachable, unsafeptr,
     #   unusedresult
     # ).
-    # Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers.
+    # Run `go tool vet help` to see all analyzers.
     # Default: []
     enable:
       - appends
@@ -1171,7 +1159,7 @@ linters-settings:
     #   atomicalign, deepequalerrors, fieldalignment, findcall, nilness, reflectvaluecompare, shadow, sortslice,
     #   timeformat, unusedwrite
     # ).
-    # Run `GL_DEBUG=govet golangci-lint run --enable=govet` to see default, all available analyzers, and enabled analyzers.
+    # Run `go tool vet help` to see all analyzers.
     # Default: []
     disable:
       - appends
@@ -1244,6 +1232,15 @@ linters-settings:
     # Default: false
     var-require-grouping: true
 
+  ifshort:
+    # Maximum length of variable declaration measured in number of lines, after which linter won't suggest using short syntax.
+    # Has higher priority than max-decl-chars.
+    # Default: 1
+    max-decl-lines: 2
+    # Maximum length of variable declaration measured in number of characters, after which linter won't suggest using short syntax.
+    # Default: 30
+    max-decl-chars: 40
+
   importas:
     # Do not allow unaliased imports of aliased packages.
     # Default: false
@@ -1347,25 +1344,19 @@ linters-settings:
     # Default: false
     always: true
 
+  maligned:
+    # Print struct with more effective memory layout or not.
+    # Default: false
+    suggest-new: true
+
   misspell:
     # Correct spellings using locale preferences for US or UK.
     # Setting locale to US will correct the British spelling of 'colour' to 'color'.
     # Default is to use a neutral variety of English.
     locale: US
-    # Typos to ignore.
-    # Should be in lower case.
     # Default: []
     ignore-words:
       - someword
-    # Extra word corrections.
-    # `typo` and `correction` should only contain letters.
-    # The words are case-insensitive.
-    # Default: []
-    extra-words:
-      - typo: "iff"
-        correction: "if"
-      - typo: "cancelation"
-        correction: "cancellation"
     # Mode of the analysis:
     # - default: checks all the file content.
     # - restricted: checks only comments.
@@ -1450,9 +1441,6 @@ linters-settings:
     # Optimizes `fmt.Sprintf` with only one argument.
     # Default: true
     sprintf1: false
-    # Optimizes into strings concatenation.
-    # Default: true
-    strconcat: false
 
   prealloc:
     # IMPORTANT: we don't recommend using this linter before doing performance profiling.
@@ -1549,7 +1537,6 @@ linters-settings:
       - name: add-constant
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - maxLitCount: "3"
             allowStrs: '""'
@@ -1559,50 +1546,41 @@ linters-settings:
       - name: argument-limit
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ 4 ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#atomic
       - name: atomic
         severity: warning
-        exclude: [""]
         disabled: false
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#banned-characters
       - name: banned-characters
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ "Ω","Σ","σ", "7" ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bare-return
       - name: bare-return
         severity: warning
-        exclude: [""]
         disabled: false
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#blank-imports
       - name: blank-imports
         severity: warning
-        exclude: [""]
         disabled: false
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#bool-literal-in-expr
       - name: bool-literal-in-expr
         severity: warning
-        exclude: [""]
         disabled: false
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#call-to-gc
       - name: call-to-gc
         severity: warning
-        exclude: [""]
         disabled: false
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cognitive-complexity
       - name: cognitive-complexity
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ 7 ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#comment-spacings
       - name: comment-spacings
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - mypragma
           - otherpragma
@@ -1610,125 +1588,103 @@ linters-settings:
       - name: confusing-naming
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#confusing-results
       - name: confusing-results
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#constant-logical-expr
       - name: constant-logical-expr
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-as-argument
       - name: context-as-argument
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - allowTypesBefore: "*testing.T,*github.com/user/repo/testing.Harness"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#context-keys-type
       - name: context-keys-type
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#cyclomatic
       - name: cyclomatic
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ 3 ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#datarace
       - name: datarace
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#deep-exit
       - name: deep-exit
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#defer
       - name: defer
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - [ "call-chain", "loop" ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#dot-imports
       - name: dot-imports
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#duplicated-imports
       - name: duplicated-imports
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#early-return
       - name: early-return
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "preserveScope"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-block
       - name: empty-block
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#empty-lines
       - name: empty-lines
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-map-style
       - name: enforce-map-style
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "make"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-repeated-arg-type-style
       - name: enforce-repeated-arg-type-style
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "short"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#enforce-slice-style
       - name: enforce-slice-style
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "make"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-naming
       - name: error-naming
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-return
       - name: error-return
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#error-strings
       - name: error-strings
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#errorf
       - name: errorf
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#exported
       - name: exported
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "preserveScope"
           - "checkPrivateReceivers"
@@ -1737,65 +1693,54 @@ linters-settings:
       - name: file-header
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - This is the text that must appear at the top of source files.
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#flag-parameter
       - name: flag-parameter
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-result-limit
       - name: function-result-limit
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ 2 ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#function-length
       - name: function-length
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ 10, 0 ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#get-return
       - name: get-return
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#identical-branches
       - name: identical-branches
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#if-return
       - name: if-return
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#increment-decrement
       - name: increment-decrement
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#indent-error-flow
       - name: indent-error-flow
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "preserveScope"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#import-alias-naming
       - name: import-alias-naming
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "^[a-z][a-z0-9]{0,}$"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#imports-blocklist
       - name: imports-blocklist
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "crypto/md5"
           - "crypto/sha1"
@@ -1803,90 +1748,73 @@ linters-settings:
       - name: import-shadowing
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#line-length-limit
       - name: line-length-limit
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ 80 ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#max-control-nesting
       - name: max-control-nesting
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ 3 ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#max-public-structs
       - name: max-public-structs
         severity: warning
         disabled: false
-        exclude: [""]
         arguments: [ 3 ]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-parameter
       - name: modifies-parameter
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#modifies-value-receiver
       - name: modifies-value-receiver
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#nested-structs
       - name: nested-structs
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#optimize-operands-order
       - name: optimize-operands-order
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#package-comments
       - name: package-comments
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range
       - name: range
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-in-closure
       - name: range-val-in-closure
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#range-val-address
       - name: range-val-address
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#receiver-naming
       - name: receiver-naming
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redundant-import-alias
       - name: redundant-import-alias
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#redefines-builtin-id
       - name: redefines-builtin-id
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-of-int
       - name: string-of-int
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#string-format
       - name: string-format
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - - 'core.WriteError[1].Message'
             - '/^([^A-Z]|$)/'
@@ -1904,29 +1832,24 @@ linters-settings:
           - "bson,outline,gnu"
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#superfluous-else
       - name: superfluous-else
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "preserveScope"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-equal
       - name: time-equal
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#time-naming
       - name: time-naming
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#var-naming
       - name: var-naming
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - [ "ID" ] # AllowList
           - [ "VM" ] # DenyList
@@ -1935,27 +1858,22 @@ linters-settings:
       - name: var-declaration
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unconditional-recursion
       - name: unconditional-recursion
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-naming
       - name: unexported-naming
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unexported-return
       - name: unexported-return
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unhandled-error
       - name: unhandled-error
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - "fmt.Printf"
           - "myFunction"
@@ -1963,36 +1881,30 @@ linters-settings:
       - name: unnecessary-stmt
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unreachable-code
       - name: unreachable-code
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-parameter
       - name: unused-parameter
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - allowRegex: "^_"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#unused-receiver
       - name: unused-receiver
         severity: warning
         disabled: false
-        exclude: [""]
         arguments:
           - allowRegex: "^_"
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#useless-break
       - name: useless-break
         severity: warning
         disabled: false
-        exclude: [""]
       # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#waitgroup-by-value
       - name: waitgroup-by-value
         severity: warning
         disabled: false
-        exclude: [""]
 
   rowserrcheck:
     # database/sql is always checked
@@ -2186,10 +2098,6 @@ linters-settings:
       - suite-thelper
       - useless-assert
 
-    bool-compare:
-      # To ignore user defined types (over builtin bool).
-      # Default: false
-      ignore-custom-types: true
     expected-actual:
       # Regexp for expected variable name.
       # Default: (^(exp(ected)?|want(ed)?)([A-Z]\w*)?$)|(^(\w*[a-z])?(Exp(ected)?|Want(ed)?)$)
@@ -2293,14 +2201,6 @@ linters-settings:
     # Default: false
     syslog-priority: true
 
-  unconvert:
-    # Remove conversions that force intermediate rounding.
-    # Default: false
-    fast-math: true
-    # Be more conservative (experimental).
-    # Default: false
-    safe: true
-
   unparam:
     # Inspect exported functions.
     #
@@ -2335,6 +2235,11 @@ linters-settings:
     # Default: true
     generated-is-used: false
 
+  varcheck:
+    # Check usage of exported fields and variables.
+    # Default: false
+    exported-fields: true
+
   varnamelen:
     # The longest distance, in source lines, that is being considered a "small scope".
     # Variables used in at most this many lines will be ignored.
@@ -2480,10 +2385,6 @@ linters-settings:
   custom:
     # Each custom linter should have a unique name.
     example:
-      # The plugin type.
-      # It can be `goplugin` or `module`.
-      # Default: goplugin
-      type: module
       # The path to the plugin *.so. Can be absolute or local.
       # Required for each custom linter.
       path: /path/to/example.so
@@ -2493,11 +2394,6 @@ linters-settings:
       # Intended to point to the repo location of the linter.
       # Optional.
       original-url: github.com/golangci/example-linter
-      # Plugins settings/configuration.
-      # Only work with plugin based on `linterdb.PluginConstructor`.
-      # Optional.
-      settings:
-        foo: bar
 
 
 linters:
@@ -2513,8 +2409,8 @@ linters:
     - bodyclose
     - containedctx
     - contextcheck
-    - copyloopvar
     - cyclop
+    - deadcode
     - decorder
     - depguard
     - dogsled
@@ -2527,6 +2423,7 @@ linters:
     - errorlint
     - execinquery
     - exhaustive
+    - exhaustivestruct
     - exhaustruct
     - exportloopref
     - forbidigo
@@ -2549,6 +2446,7 @@ linters:
     - gofumpt
     - goheader
     - goimports
+    - golint
     - gomnd
     - gomoddirectives
     - gomodguard
@@ -2558,16 +2456,18 @@ linters:
     - gosmopolitan
     - govet
     - grouper
+    - ifshort
     - importas
     - inamedparam
     - ineffassign
     - interfacebloat
-    - intrange
+    - interfacer
     - ireturn
     - lll
     - loggercheck
     - maintidx
     - makezero
+    - maligned
     - mirror
     - misspell
     - musttag
@@ -2579,6 +2479,7 @@ linters:
     - noctx
     - nolintlint
     - nonamedreturns
+    - nosnakecase
     - nosprintfhostport
     - paralleltest
     - perfsprint
@@ -2589,10 +2490,12 @@ linters:
     - reassign
     - revive
     - rowserrcheck
+    - scopelint
     - sloglint
     - spancheck
     - sqlclosecheck
     - staticcheck
+    - structcheck
     - stylecheck
     - tagalign
     - tagliatelle
@@ -2607,6 +2510,7 @@ linters:
     - unparam
     - unused
     - usestdlibvars
+    - varcheck
     - varnamelen
     - wastedassign
     - whitespace
@@ -2626,8 +2530,8 @@ linters:
     - bodyclose
     - containedctx
     - contextcheck
-    - copyloopvar
     - cyclop
+    - deadcode
     - decorder
     - depguard
     - dogsled
@@ -2640,6 +2544,7 @@ linters:
     - errorlint
     - execinquery
     - exhaustive
+    - exhaustivestruct
     - exhaustruct
     - exportloopref
     - forbidigo
@@ -2662,6 +2567,7 @@ linters:
     - gofumpt
     - goheader
     - goimports
+    - golint
     - gomnd
     - gomoddirectives
     - gomodguard
@@ -2671,16 +2577,18 @@ linters:
     - gosmopolitan
     - govet
     - grouper
+    - ifshort
     - importas
     - inamedparam
     - ineffassign
     - interfacebloat
-    - intrange
+    - interfacer
     - ireturn
     - lll
     - loggercheck
     - maintidx
     - makezero
+    - maligned
     - mirror
     - misspell
     - musttag
@@ -2692,6 +2600,7 @@ linters:
     - noctx
     - nolintlint
     - nonamedreturns
+    - nosnakecase
     - nosprintfhostport
     - paralleltest
     - perfsprint
@@ -2702,10 +2611,12 @@ linters:
     - reassign
     - revive
     - rowserrcheck
+    - scopelint
     - sloglint
     - spancheck
     - sqlclosecheck
     - staticcheck
+    - structcheck
     - stylecheck
     - tagalign
     - tagliatelle
@@ -2720,22 +2631,13 @@ linters:
     - unparam
     - unused
     - usestdlibvars
+    - varcheck
     - varnamelen
     - wastedassign
     - whitespace
     - wrapcheck
     - wsl
     - zerologlint
-    - deadcode # Deprecated
-    - exhaustivestruct # Deprecated
-    - golint # Deprecated
-    - ifshort # Deprecated
-    - interfacer # Deprecated
-    - maligned # Deprecated
-    - nosnakecase # Deprecated
-    - scopelint # Deprecated
-    - structcheck # Deprecated
-    - varcheck # Deprecated
 
   # Enable presets.
   # https://golangci-lint.run/usage/linters
@@ -2880,8 +2782,6 @@ severity:
   # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message
   # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance
   #
-  # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
-  #
   # Default: ""
   default-severity: error
 
@@ -2892,9 +2792,6 @@ severity:
   # When a list of severity rules are provided, severity information will be added to lint issues.
   # Severity rules have the same filtering capability as exclude rules
   # except you are allowed to specify one matcher per severity rule.
-  #
-  # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...)
-  #
   # Only affects out formats that support setting severity information.
   #
   # Default: []
diff --git a/Makefile b/Makefile
index 57a12590..f7d3e13c 100644
--- a/Makefile
+++ b/Makefile
@@ -88,9 +88,13 @@ go.mod: FORCE
 	go mod verify
 go.sum: go.mod
 
-expand_website_templates:
-	go run ./scripts/expand_website_templates/main.go
-.PHONY: expand_website_templates
+website_expand_templates:
+	go run ./scripts/website/expand_templates/
+.PHONY: website_expand_templates
+
+website_dump_info:
+	go run ./scripts/website/dump_info/
+.PHONY: dump_info
 
 update_contributors_list:
 	cd .github/contributors && npm run all
diff --git a/assets/cli-help.json b/assets/cli-help.json
new file mode 100644
index 00000000..55d66d5e
--- /dev/null
+++ b/assets/cli-help.json
@@ -0,0 +1,5 @@
+{
+  "enable": "Enabled by default linters:\nerrcheck: errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases [fast: false, auto-fix: false]\ngosimple (megacheck): Linter for Go source code that specializes in simplifying code [fast: false, auto-fix: false]\ngovet (vet, vetshadow): Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string [fast: false, auto-fix: false]\nineffassign: Detects when assignments to existing variables are not used [fast: true, auto-fix: false]\nstaticcheck (megacheck): It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint. [fast: false, auto-fix: false]\nunused (megacheck): Checks Go code for unused constants, variables, functions and types [fast: false, auto-fix: false]",
+  "disable": "Disabled by default linters:\nasasalint: check for pass []any as any in variadic func(...any) [fast: false, auto-fix: false]\nasciicheck: checks that all code identifiers does not have non-ASCII symbols in the name [fast: true, auto-fix: false]\nbidichk: Checks for dangerous unicode character sequences [fast: true, auto-fix: false]\nbodyclose: checks whether HTTP response body is closed successfully [fast: false, auto-fix: false]\ncontainedctx: containedctx is a linter that detects struct contained context.Context field [fast: false, auto-fix: false]\ncontextcheck: check whether the function uses a non-inherited context [fast: false, auto-fix: false]\ncyclop: checks function and package cyclomatic complexity [fast: false, auto-fix: false]\ndeadcode [deprecated]: Finds unused code [fast: false, auto-fix: false]\ndecorder: check declaration order and count of types, constants, variables and functions [fast: true, auto-fix: false]\ndepguard: Go linter that checks if package imports are in a list of acceptable packages [fast: true, auto-fix: false]\ndogsled: Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f()) [fast: true, auto-fix: false]\ndupl: Tool for code clone detection [fast: true, auto-fix: false]\ndupword: checks for duplicate words in the source code [fast: true, auto-fix: true]\ndurationcheck: check for two durations multiplied together [fast: false, auto-fix: false]\nerrchkjson: Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omitted. [fast: false, auto-fix: false]\nerrname: Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`. [fast: false, auto-fix: false]\nerrorlint: errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13. [fast: false, auto-fix: false]\nexecinquery: execinquery is a linter about query string checker in Query function which reads your Go src files and warning it finds [fast: false, auto-fix: false]\nexhaustive: check exhaustiveness of enum switch statements [fast: false, auto-fix: false]\nexhaustivestruct [deprecated]: Checks if all struct's fields are initialized [fast: false, auto-fix: false]\nexhaustruct: Checks if all structure fields are initialized [fast: false, auto-fix: false]\nexportloopref: checks for pointers to enclosing loop variables [fast: false, auto-fix: false]\nforbidigo: Forbids identifiers [fast: false, auto-fix: false]\nforcetypeassert: finds forced type assertions [fast: true, auto-fix: false]\nfunlen: Tool for detection of long functions [fast: true, auto-fix: false]\ngci: Gci controls Go package import order and makes it always deterministic. [fast: true, auto-fix: false]\nginkgolinter: enforces standards of using ginkgo and gomega [fast: false, auto-fix: false]\ngocheckcompilerdirectives: Checks that go compiler directive comments (//go:) are valid. [fast: true, auto-fix: false]\ngochecknoglobals: check that no global variables exist [fast: false, auto-fix: false]\ngochecknoinits: Checks that no init functions are present in Go code [fast: true, auto-fix: false]\ngochecksumtype: Run exhaustiveness checks on Go \"sum types\" [fast: false, auto-fix: false]\ngocognit: Computes and checks the cognitive complexity of functions [fast: true, auto-fix: false]\ngoconst: Finds repeated strings that could be replaced by a constant [fast: true, auto-fix: false]\ngocritic: Provides diagnostics that check for bugs, performance and style issues. [fast: false, auto-fix: false]\ngocyclo: Computes and checks the cyclomatic complexity of functions [fast: true, auto-fix: false]\ngodot: Check if comments end in a period [fast: true, auto-fix: true]\ngodox: Tool for detection of FIXME, TODO and other comment keywords [fast: true, auto-fix: false]\ngoerr113: Go linter to check the errors handling expressions [fast: false, auto-fix: false]\ngofmt: Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification [fast: true, auto-fix: true]\ngofumpt: Gofumpt checks whether code was gofumpt-ed. [fast: true, auto-fix: true]\ngoheader: Checks is file header matches to pattern [fast: true, auto-fix: false]\ngoimports: Check import statements are formatted according to the 'goimport' command. Reformat imports in autofix mode. [fast: true, auto-fix: true]\ngolint [deprecated]: Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes [fast: false, auto-fix: false]\ngomnd: An analyzer to detect magic numbers. [fast: true, auto-fix: false]\ngomoddirectives: Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod. [fast: true, auto-fix: false]\ngomodguard: Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations. [fast: true, auto-fix: false]\ngoprintffuncname: Checks that printf-like functions are named with `f` at the end. [fast: true, auto-fix: false]\ngosec (gas): Inspects source code for security problems [fast: false, auto-fix: false]\ngosmopolitan: Report certain i18n/l10n anti-patterns in your Go codebase [fast: false, auto-fix: false]\ngrouper: Analyze expression groups. [fast: true, auto-fix: false]\nifshort [deprecated]: Checks that your code uses short syntax for if-statements whenever possible. [fast: true, auto-fix: false]\nimportas: Enforces consistent import aliases [fast: false, auto-fix: false]\ninamedparam: reports interfaces with unnamed method parameters [fast: true, auto-fix: false]\ninterfacebloat: A linter that checks the number of methods inside an interface. [fast: true, auto-fix: false]\ninterfacer [deprecated]: Linter that suggests narrower interface types [fast: false, auto-fix: false]\nireturn: Accept Interfaces, Return Concrete Types [fast: false, auto-fix: false]\nlll: Reports long lines [fast: true, auto-fix: false]\nloggercheck (logrlint): Checks key value pairs for common logger libraries (kitlog,klog,logr,zap). [fast: false, auto-fix: false]\nmaintidx: maintidx measures the maintainability index of each function. [fast: true, auto-fix: false]\nmakezero: Finds slice declarations with non-zero initial length [fast: false, auto-fix: false]\nmaligned [deprecated]: Tool to detect Go structs that would take less memory if their fields were sorted [fast: false, auto-fix: false]\nmirror: reports wrong mirror patterns of bytes/strings usage [fast: false, auto-fix: false]\nmisspell: Finds commonly misspelled English words [fast: true, auto-fix: true]\nmusttag: enforce field tags in (un)marshaled structs [fast: false, auto-fix: false]\nnakedret: Checks that functions with naked returns are not longer than a maximum size (can be zero). [fast: true, auto-fix: false]\nnestif: Reports deeply nested if statements [fast: true, auto-fix: false]\nnilerr: Finds the code that returns nil even if it checks that the error is not nil. [fast: false, auto-fix: false]\nnilnil: Checks that there is no simultaneous return of `nil` error and an invalid value. [fast: false, auto-fix: false]\nnlreturn: nlreturn checks for a new line before return and branch statements to increase code clarity [fast: true, auto-fix: false]\nnoctx: Finds sending http request without context.Context [fast: false, auto-fix: false]\nnolintlint: Reports ill-formed or insufficient nolint directives [fast: true, auto-fix: false]\nnonamedreturns: Reports all named returns [fast: false, auto-fix: false]\nnosnakecase [deprecated]: nosnakecase is a linter that detects snake case of variable naming and function name. [fast: true, auto-fix: false]\nnosprintfhostport: Checks for misuse of Sprintf to construct a host with port in a URL. [fast: true, auto-fix: false]\nparalleltest: Detects missing usage of t.Parallel() method in your Go test [fast: false, auto-fix: false]\nperfsprint: Checks that fmt.Sprintf can be replaced with a faster alternative. [fast: false, auto-fix: false]\nprealloc: Finds slice declarations that could potentially be pre-allocated [fast: true, auto-fix: false]\npredeclared: find code that shadows one of Go's predeclared identifiers [fast: true, auto-fix: false]\npromlinter: Check Prometheus metrics naming via promlint [fast: true, auto-fix: false]\nprotogetter: Reports direct reads from proto message fields when getters should be used [fast: false, auto-fix: true]\nreassign: Checks that package variables are not reassigned [fast: false, auto-fix: false]\nrevive: Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. [fast: false, auto-fix: false]\nrowserrcheck: checks whether Rows.Err of rows is checked successfully [fast: false, auto-fix: false]\nscopelint [deprecated]: Scopelint checks for unpinned variables in go programs [fast: true, auto-fix: false]\nsloglint: ensure consistent code style when using log/slog [fast: false, auto-fix: false]\nspancheck: Checks for mistakes with OpenTelemetry/Census spans. [fast: false, auto-fix: false]\nsqlclosecheck: Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed. [fast: false, auto-fix: false]\nstructcheck [deprecated]: Finds unused struct fields [fast: false, auto-fix: false]\nstylecheck: Stylecheck is a replacement for golint [fast: false, auto-fix: false]\ntagalign: check that struct tags are well aligned [fast: true, auto-fix: true]\ntagliatelle: Checks the struct tags. [fast: true, auto-fix: false]\ntenv: tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17 [fast: false, auto-fix: false]\ntestableexamples: linter checks if examples are testable (have an expected output) [fast: true, auto-fix: false]\ntestifylint: Checks usage of github.com/stretchr/testify. [fast: false, auto-fix: false]\ntestpackage: linter that makes you use a separate _test package [fast: true, auto-fix: false]\nthelper: thelper detects tests helpers which is not start with t.Helper() method. [fast: false, auto-fix: false]\ntparallel: tparallel detects inappropriate usage of t.Parallel() method in your Go test codes. [fast: false, auto-fix: false]\nunconvert: Remove unnecessary type conversions [fast: false, auto-fix: false]\nunparam: Reports unused function parameters [fast: false, auto-fix: false]\nusestdlibvars: A linter that detect the possibility to use variables/constants from the Go standard library. [fast: true, auto-fix: false]\nvarcheck [deprecated]: Finds unused global variables and constants [fast: false, auto-fix: false]\nvarnamelen: checks that the length of a variable's name matches its scope [fast: false, auto-fix: false]\nwastedassign: Finds wasted assignment statements [fast: false, auto-fix: false]\nwhitespace: Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc. [fast: true, auto-fix: true]\nwrapcheck: Checks that errors returned from external packages are wrapped [fast: false, auto-fix: false]\nwsl: add or remove empty lines [fast: true, auto-fix: false]\nzerologlint: Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg` [fast: false, auto-fix: false]",
+  "help": "Usage:\n  golangci-lint run [flags]\n\nFlags:\n  -c, --config PATH                    Read config from file path PATH\n      --no-config                      Don't read config file\n      --out-format string              Format of output: colored-line-number|line-number|json|tab|checkstyle|code-climate|html|junit-xml|github-actions|teamcity (default \"colored-line-number\")\n      --print-issued-lines             Print lines of code with issue (default true)\n      --print-linter-name              Print linter name in issue line (default true)\n      --uniq-by-line                   Make issues output unique by line (default true)\n      --sort-results                   Sort linter results\n      --path-prefix string             Path prefix to add to output\n      --modules-download-mode string   Modules download mode. If not empty, passed as -mod=\u003cmode\u003e to go tools\n      --issues-exit-code int           Exit code when issues were found (default 1)\n      --go string                      Targeted Go version\n      --build-tags strings             Build tags\n      --timeout duration               Timeout for total work (default 1m0s)\n      --tests                          Analyze tests (*_test.go) (default true)\n      --print-resources-usage          Print avg and max memory usage of golangci-lint and total time\n      --skip-dirs strings              Regexps of directories to skip\n      --skip-dirs-use-default          Use or not use default excluded directories:\n                                         - (^|/)vendor($|/)\n                                         - (^|/)third_party($|/)\n                                         - (^|/)testdata($|/)\n                                         - (^|/)examples($|/)\n                                         - (^|/)Godeps($|/)\n                                         - (^|/)builtin($|/)\n                                        (default true)\n      --skip-files strings             Regexps of files to skip\n      --allow-parallel-runners         Allow multiple parallel golangci-lint instances running. If false (default) - golangci-lint acquires file lock on start.\n      --allow-serial-runners           Allow multiple golangci-lint instances running, but serialize them around a lock. If false (default) - golangci-lint exits with an error if it fails to acquire file lock on start.\n      --show-stats                     Show statistics per linter\n  -D, --disable strings                Disable specific linter\n      --disable-all                    Disable all linters\n  -E, --enable strings                 Enable specific linter\n      --enable-all                     Enable all linters\n      --fast                           Enable only fast linters from enabled linters set (first run won't be fast)\n  -p, --presets strings                Enable presets (bugs|comment|complexity|error|format|import|metalinter|module|performance|sql|style|test|unused) of linters. Run 'golangci-lint help linters' to see them. This option implies option --disable-all\n  -e, --exclude strings                Exclude issue by regexp\n      --exclude-use-default            Use or not use default excludes:\n                                         # EXC0001 errcheck: Almost all programs ignore errors on these functions and in most cases it's ok\n                                         - Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked\n                                       \n                                         # EXC0002 golint: Annoying issue about not having a comment. The rare codebase has such comments\n                                         - (comment on exported (method|function|type|const)|should have( a package)? comment|comment should be of the form)\n                                       \n                                         # EXC0003 golint: False positive when tests are defined in package 'test'\n                                         - func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this\n                                       \n                                         # EXC0004 govet: Common false positives\n                                         - (possible misuse of unsafe.Pointer|should have signature)\n                                       \n                                         # EXC0005 staticcheck: Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore\n                                         - ineffective break statement. Did you mean to break out of the outer loop\n                                       \n                                         # EXC0006 gosec: Too many false-positives on 'unsafe' usage\n                                         - Use of unsafe calls should be audited\n                                       \n                                         # EXC0007 gosec: Too many false-positives for parametrized shell calls\n                                         - Subprocess launch(ed with variable|ing should be audited)\n                                       \n                                         # EXC0008 gosec: Duplicated errcheck checks\n                                         - (G104)\n                                       \n                                         # EXC0009 gosec: Too many issues in popular repos\n                                         - (Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)\n                                       \n                                         # EXC0010 gosec: False positive is triggered by 'src, err := ioutil.ReadFile(filename)'\n                                         - Potential file inclusion via variable\n                                       \n                                         # EXC0011 stylecheck: Annoying issue about not having a comment. The rare codebase has such comments\n                                         - (comment on exported (method|function|type|const)|should have( a package)? comment|comment should be of the form)\n                                       \n                                         # EXC0012 revive: Annoying issue about not having a comment. The rare codebase has such comments\n                                         - exported (.+) should have comment( \\(or a comment on this block\\))? or be unexported\n                                       \n                                         # EXC0013 revive: Annoying issue about not having a comment. The rare codebase has such comments\n                                         - package comment should be of the form \"(.+)...\n                                       \n                                         # EXC0014 revive: Annoying issue about not having a comment. The rare codebase has such comments\n                                         - comment on exported (.+) should be of the form \"(.+)...\"\n                                       \n                                         # EXC0015 revive: Annoying issue about not having a comment. The rare codebase has such comments\n                                         - should have a package comment\n                                        (default true)\n      --exclude-case-sensitive         If set to true exclude and exclude rules regular expressions are case sensitive\n      --max-issues-per-linter int      Maximum issues count per one linter. Set to 0 to disable (default 50)\n      --max-same-issues int            Maximum count of issues with the same text. Set to 0 to disable (default 3)\n  -n, --new                            Show only new issues: if there are unstaged changes or untracked files, only those changes are analyzed, else only changes in HEAD~ are analyzed.\n                                       It's a super-useful option for integration of golangci-lint into existing large codebase.\n                                       It's not practical to fix all existing issues at the moment of integration: much better to not allow issues in new code.\n                                       For CI setups, prefer --new-from-rev=HEAD~, as --new can skip linting the current patch if any scripts generate unstaged files before golangci-lint runs.\n      --new-from-rev REV               Show only new issues created after git revision REV\n      --new-from-patch PATH            Show only new issues created in git patch with file path PATH\n      --whole-files                    Show issues in any part of update files (requires new-from-rev or new-from-patch)\n      --fix                            Fix found issues (if it's supported by the linter)\n  -h, --help                           help for run\n\nGlobal Flags:\n      --color string              Use color when printing; can be 'always', 'auto', or 'never' (default \"auto\")\n  -j, --concurrency int           Number of CPUs to use (Default: number of logical CPUs) (default 8)\n      --cpu-profile-path string   Path to CPU profile output file\n      --mem-profile-path string   Path to memory profile output file\n      --trace-path string         Path to trace output file\n  -v, --verbose                   Verbose output\n      --version                   Print version\n"
+}
diff --git a/assets/default-exclusions.json b/assets/default-exclusions.json
new file mode 100644
index 00000000..93f096dd
--- /dev/null
+++ b/assets/default-exclusions.json
@@ -0,0 +1,92 @@
+[
+  {
+    "id": "EXC0001",
+    "pattern": "Error return value of .((os\\.)?std(out|err)\\..*|.*Close|.*Flush|os\\.Remove(All)?|.*print(f|ln)?|os\\.(Un)?Setenv). is not checked",
+    "linter": "errcheck",
+    "why": "Almost all programs ignore errors on these functions and in most cases it's ok"
+  },
+  {
+    "id": "EXC0002",
+    "pattern": "(comment on exported (method|function|type|const)|should have( a package)? comment|comment should be of the form)",
+    "linter": "golint",
+    "why": "Annoying issue about not having a comment. The rare codebase has such comments"
+  },
+  {
+    "id": "EXC0003",
+    "pattern": "func name will be used as test\\.Test.* by other packages, and that stutters; consider calling this",
+    "linter": "golint",
+    "why": "False positive when tests are defined in package 'test'"
+  },
+  {
+    "id": "EXC0004",
+    "pattern": "(possible misuse of unsafe.Pointer|should have signature)",
+    "linter": "govet",
+    "why": "Common false positives"
+  },
+  {
+    "id": "EXC0005",
+    "pattern": "ineffective break statement. Did you mean to break out of the outer loop",
+    "linter": "staticcheck",
+    "why": "Developers tend to write in C-style with an explicit 'break' in a 'switch', so it's ok to ignore"
+  },
+  {
+    "id": "EXC0006",
+    "pattern": "Use of unsafe calls should be audited",
+    "linter": "gosec",
+    "why": "Too many false-positives on 'unsafe' usage"
+  },
+  {
+    "id": "EXC0007",
+    "pattern": "Subprocess launch(ed with variable|ing should be audited)",
+    "linter": "gosec",
+    "why": "Too many false-positives for parametrized shell calls"
+  },
+  {
+    "id": "EXC0008",
+    "pattern": "(G104)",
+    "linter": "gosec",
+    "why": "Duplicated errcheck checks"
+  },
+  {
+    "id": "EXC0009",
+    "pattern": "(Expect directory permissions to be 0750 or less|Expect file permissions to be 0600 or less)",
+    "linter": "gosec",
+    "why": "Too many issues in popular repos"
+  },
+  {
+    "id": "EXC0010",
+    "pattern": "Potential file inclusion via variable",
+    "linter": "gosec",
+    "why": "False positive is triggered by 'src, err := ioutil.ReadFile(filename)'"
+  },
+  {
+    "id": "EXC0011",
+    "pattern": "(comment on exported (method|function|type|const)|should have( a package)? comment|comment should be of the form)",
+    "linter": "stylecheck",
+    "why": "Annoying issue about not having a comment. The rare codebase has such comments"
+  },
+  {
+    "id": "EXC0012",
+    "pattern": "exported (.+) should have comment( \\(or a comment on this block\\))? or be unexported",
+    "linter": "revive",
+    "why": "Annoying issue about not having a comment. The rare codebase has such comments"
+  },
+  {
+    "id": "EXC0013",
+    "pattern": "package comment should be of the form \"(.+)...",
+    "linter": "revive",
+    "why": "Annoying issue about not having a comment. The rare codebase has such comments"
+  },
+  {
+    "id": "EXC0014",
+    "pattern": "comment on exported (.+) should be of the form \"(.+)...\"",
+    "linter": "revive",
+    "why": "Annoying issue about not having a comment. The rare codebase has such comments"
+  },
+  {
+    "id": "EXC0015",
+    "pattern": "should have a package comment",
+    "linter": "revive",
+    "why": "Annoying issue about not having a comment. The rare codebase has such comments"
+  }
+]
diff --git a/assets/linters-info.json b/assets/linters-info.json
new file mode 100644
index 00000000..eab346ce
--- /dev/null
+++ b/assets/linters-info.json
@@ -0,0 +1,1600 @@
+[
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/alingse/asasalint",
+    "internal": false,
+    "isSlow": true,
+    "since": "1.47.0",
+    "name": "asasalint",
+    "desc": "check for pass []any as any in variadic func(...any)"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "bugs",
+      "style"
+    ],
+    "originalURL": "https://github.com/tdakkota/asciicheck",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.26.0",
+    "name": "asciicheck",
+    "desc": "checks that all code identifiers does not have non-ASCII symbols in the name"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/breml/bidichk",
+    "internal": false,
+    "isSlow": false,
+    "since": "1.43.0",
+    "name": "bidichk",
+    "desc": "Checks for dangerous unicode character sequences"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "performance",
+      "bugs"
+    ],
+    "originalURL": "https://github.com/timakin/bodyclose",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.18.0",
+    "name": "bodyclose",
+    "desc": "checks whether HTTP response body is closed successfully"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/sivchari/containedctx",
+    "internal": false,
+    "isSlow": true,
+    "since": "1.44.0",
+    "name": "containedctx",
+    "desc": "containedctx is a linter that detects struct contained context.Context field"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/kkHAIKE/contextcheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.43.0",
+    "name": "contextcheck",
+    "desc": "check whether the function uses a non-inherited context"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "complexity"
+    ],
+    "originalURL": "https://github.com/bkielbasa/cyclop",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.37.0",
+    "name": "cyclop",
+    "desc": "checks function and package cyclomatic complexity"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "format",
+      "style"
+    ],
+    "originalURL": "https://gitlab.com/bosi/decorder",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.44.0",
+    "name": "decorder",
+    "desc": "check declaration order and count of types, constants, variables and functions"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "unused"
+    ],
+    "originalURL": "https://github.com/remyoudompheng/go-misc/tree/master/deadcode",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "deprecation": {
+      "since": "v1.49.0",
+      "message": "The owner seems to have abandoned the linter.",
+      "replacement": "unused"
+    },
+    "name": "deadcode",
+    "desc": "Finds unused code"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "import",
+      "module"
+    ],
+    "originalURL": "https://github.com/OpenPeeDeeP/depguard",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.4.0",
+    "name": "depguard",
+    "desc": "Go linter that checks if package imports are in a list of acceptable packages"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/alexkohler/dogsled",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.19.0",
+    "name": "dogsled",
+    "desc": "Checks assignments with too many blank identifiers (e.g. x, _, _, _, := f())"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/mibk/dupl",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.0.0",
+    "name": "dupl",
+    "desc": "Tool for code clone detection"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "comment"
+    ],
+    "originalURL": "https://github.com/Abirdcfly/dupword",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": false,
+    "since": "1.50.0",
+    "name": "dupword",
+    "desc": "checks for duplicate words in the source code"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/charithe/durationcheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.37.0",
+    "name": "durationcheck",
+    "desc": "check for two durations multiplied together"
+  },
+  {
+    "linter": {},
+    "enabledByDefault": true,
+    "loadMode": 575,
+    "inPresets": [
+      "bugs",
+      "error"
+    ],
+    "originalURL": "https://github.com/kisielk/errcheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "name": "errcheck",
+    "desc": "errcheck is a program for checking for unchecked errors in Go code. These unchecked errors can be critical bugs in some cases"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/breml/errchkjson",
+    "internal": false,
+    "isSlow": true,
+    "since": "1.44.0",
+    "name": "errchkjson",
+    "desc": "Checks types passed to the json encoding functions. Reports unsupported types and reports occations, where the check for the returned error can be omitted."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/Antonboom/errname",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.42.0",
+    "name": "errname",
+    "desc": "Checks that sentinel errors are prefixed with the `Err` and error types are suffixed with the `Error`."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs",
+      "error"
+    ],
+    "originalURL": "https://github.com/polyfloyd/go-errorlint",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.32.0",
+    "name": "errorlint",
+    "desc": "errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "sql"
+    ],
+    "originalURL": "https://github.com/lufeee/execinquery",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.46.0",
+    "name": "execinquery",
+    "desc": "execinquery is a linter about query string checker in Query function which reads your Go src files and warning it finds"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/nishanths/exhaustive",
+    "internal": false,
+    "isSlow": true,
+    "since": " v1.28.0",
+    "name": "exhaustive",
+    "desc": "check exhaustiveness of enum switch statements"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "test"
+    ],
+    "originalURL": "https://github.com/mbilski/exhaustivestruct",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.32.0",
+    "deprecation": {
+      "since": "v1.46.0",
+      "message": "The owner seems to have abandoned the linter.",
+      "replacement": "exhaustruct"
+    },
+    "name": "exhaustivestruct",
+    "desc": "Checks if all struct's fields are initialized"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "test"
+    ],
+    "originalURL": "https://github.com/GaijinEntertainment/go-exhaustruct",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.46.0",
+    "name": "exhaustruct",
+    "desc": "Checks if all structure fields are initialized"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/kyoh86/exportloopref",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.28.0",
+    "name": "exportloopref",
+    "desc": "checks for pointers to enclosing loop variables"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/ashanbrown/forbidigo",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.34.0",
+    "name": "forbidigo",
+    "desc": "Forbids identifiers"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/gostaticanalysis/forcetypeassert",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.38.0",
+    "name": "forcetypeassert",
+    "desc": "finds forced type assertions"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "complexity"
+    ],
+    "originalURL": "https://github.com/ultraware/funlen",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.18.0",
+    "name": "funlen",
+    "desc": "Tool for detection of long functions"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "format",
+      "import"
+    ],
+    "originalURL": "https://github.com/daixiang0/gci",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.30.0",
+    "name": "gci",
+    "desc": "Gci controls Go package import order and makes it always deterministic."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/nunnatsa/ginkgolinter",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.51.0",
+    "name": "ginkgolinter",
+    "desc": "enforces standards of using ginkgo and gomega"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/leighmcculloch/gocheckcompilerdirectives",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.51.0",
+    "name": "gocheckcompilerdirectives",
+    "desc": "Checks that go compiler directive comments (//go:) are valid."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/leighmcculloch/gochecknoglobals",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.12.0",
+    "name": "gochecknoglobals",
+    "desc": "check that no global variables exist\n\nThis analyzer checks for global variables and errors on any found.\n\nA global variable is a variable declared in package scope and that can be read\nand written to by any function within the package. Global variables can cause\nside effects which are difficult to keep track of. A code in one function may\nchange the variables state while another unrelated chunk of code may be\neffected by it."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.12.0",
+    "name": "gochecknoinits",
+    "desc": "Checks that no init functions are present in Go code"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/alecthomas/go-check-sumtype",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.55.0",
+    "name": "gochecksumtype",
+    "desc": "Run exhaustiveness checks on Go \"sum types\""
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "complexity"
+    ],
+    "originalURL": "https://github.com/uudashr/gocognit",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.20.0",
+    "name": "gocognit",
+    "desc": "Computes and checks the cognitive complexity of functions"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/jgautheron/goconst",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.0.0",
+    "name": "goconst",
+    "desc": "Finds repeated strings that could be replaced by a constant"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "metalinter"
+    ],
+    "originalURL": "https://github.com/go-critic/go-critic",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.12.0",
+    "name": "gocritic",
+    "desc": "Provides diagnostics that check for bugs, performance and style issues.\nExtensible without recompilation through dynamic rules.\nDynamic rules are written declaratively with AST patterns, filters, report message and optional suggestion."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "complexity"
+    ],
+    "originalURL": "https://github.com/fzipp/gocyclo",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.0.0",
+    "name": "gocyclo",
+    "desc": "Computes and checks the cyclomatic complexity of functions"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "comment"
+    ],
+    "originalURL": "https://github.com/tetafro/godot",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": false,
+    "since": "v1.25.0",
+    "name": "godot",
+    "desc": "Check if comments end in a period"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "comment"
+    ],
+    "originalURL": "https://github.com/matoous/godox",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.19.0",
+    "name": "godox",
+    "desc": "Tool for detection of FIXME, TODO and other comment keywords"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "error"
+    ],
+    "originalURL": "https://github.com/Djarvur/go-err113",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.26.0",
+    "name": "goerr113",
+    "desc": "Go linter to check the errors handling expressions"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "format"
+    ],
+    "originalURL": "https://pkg.go.dev/cmd/gofmt",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": false,
+    "since": "v1.0.0",
+    "name": "gofmt",
+    "desc": "Gofmt checks whether code was gofmt-ed. By default this tool runs with -s option to check for code simplification"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "format"
+    ],
+    "originalURL": "https://github.com/mvdan/gofumpt",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": false,
+    "since": "v1.28.0",
+    "name": "gofumpt",
+    "desc": "Gofumpt checks whether code was gofumpt-ed."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/denis-tingaikin/go-header",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.28.0",
+    "name": "goheader",
+    "desc": "Checks is file header matches to pattern"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "format",
+      "import"
+    ],
+    "originalURL": "https://pkg.go.dev/golang.org/x/tools/cmd/goimports",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": false,
+    "since": "v1.20.0",
+    "name": "goimports",
+    "desc": "Check import statements are formatted according to the 'goimport' command. Reformat imports in autofix mode."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/golang/lint",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "deprecation": {
+      "since": "v1.41.0",
+      "message": "The repository of the linter has been archived by the owner.",
+      "replacement": "revive"
+    },
+    "name": "golint",
+    "desc": "Golint differs from gofmt. Gofmt reformats Go source code, whereas golint prints out style mistakes"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/tommy-muehle/go-mnd",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.22.0",
+    "name": "gomnd",
+    "desc": "An analyzer to detect magic numbers."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "module"
+    ],
+    "originalURL": "https://github.com/ldez/gomoddirectives",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.39.0",
+    "name": "gomoddirectives",
+    "desc": "Manage the use of 'replace', 'retract', and 'excludes' directives in go.mod."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "import",
+      "module"
+    ],
+    "originalURL": "https://github.com/ryancurrah/gomodguard",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.25.0",
+    "name": "gomodguard",
+    "desc": "Allow and block list linter for direct Go module dependencies. This is different from depguard where there are different block types for example version constraints and module recommendations."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/jirfag/go-printf-func-name",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.23.0",
+    "name": "goprintffuncname",
+    "desc": "Checks that printf-like functions are named with `f` at the end."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "alternativeNames": [
+      "gas"
+    ],
+    "originalURL": "https://github.com/securego/gosec",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "name": "gosec",
+    "desc": "Inspects source code for security problems"
+  },
+  {
+    "linter": {},
+    "enabledByDefault": true,
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "alternativeNames": [
+      "megacheck"
+    ],
+    "originalURL": "https://github.com/dominikh/go-tools/tree/master/simple",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.20.0",
+    "name": "gosimple",
+    "desc": "Linter for Go source code that specializes in simplifying code"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/xen0n/gosmopolitan",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.53.0",
+    "name": "gosmopolitan",
+    "desc": "Report certain i18n/l10n anti-patterns in your Go codebase"
+  },
+  {
+    "linter": {},
+    "enabledByDefault": true,
+    "loadMode": 575,
+    "inPresets": [
+      "bugs",
+      "metalinter"
+    ],
+    "alternativeNames": [
+      "vet",
+      "vetshadow"
+    ],
+    "originalURL": "https://pkg.go.dev/cmd/vet",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "name": "govet",
+    "desc": "Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/leonklingele/grouper",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.44.0",
+    "name": "grouper",
+    "desc": "Analyze expression groups."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/esimonov/ifshort",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.36.0",
+    "deprecation": {
+      "since": "v1.48.0",
+      "message": "The repository of the linter has been deprecated by the owner."
+    },
+    "name": "ifshort",
+    "desc": "Checks that your code uses short syntax for if-statements whenever possible."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/julz/importas",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.38.0",
+    "name": "importas",
+    "desc": "Enforces consistent import aliases"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/macabu/inamedparam",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.55.0",
+    "name": "inamedparam",
+    "desc": "reports interfaces with unnamed method parameters"
+  },
+  {
+    "linter": {},
+    "enabledByDefault": true,
+    "loadMode": 7,
+    "inPresets": [
+      "unused"
+    ],
+    "originalURL": "https://github.com/gordonklaus/ineffassign",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.0.0",
+    "name": "ineffassign",
+    "desc": "Detects when assignments to existing variables are not used"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/sashamelentyev/interfacebloat",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.49.0",
+    "name": "interfacebloat",
+    "desc": "A linter that checks the number of methods inside an interface."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/mvdan/interfacer",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "deprecation": {
+      "since": "v1.38.0",
+      "message": "The repository of the linter has been archived by the owner."
+    },
+    "name": "interfacer",
+    "desc": "Linter that suggests narrower interface types"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/butuzov/ireturn",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.43.0",
+    "name": "ireturn",
+    "desc": "Accept Interfaces, Return Concrete Types"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.8.0",
+    "name": "lll",
+    "desc": "Reports long lines"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "bugs"
+    ],
+    "alternativeNames": [
+      "logrlint"
+    ],
+    "originalURL": "https://github.com/timonwong/loggercheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.49.0",
+    "name": "loggercheck",
+    "desc": "Checks key value pairs for common logger libraries (kitlog,klog,logr,zap)."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "complexity"
+    ],
+    "originalURL": "https://github.com/yagipy/maintidx",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.44.0",
+    "name": "maintidx",
+    "desc": "maintidx measures the maintainability index of each function."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "bugs"
+    ],
+    "originalURL": "https://github.com/ashanbrown/makezero",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.34.0",
+    "name": "makezero",
+    "desc": "Finds slice declarations with non-zero initial length"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "performance"
+    ],
+    "originalURL": "https://github.com/mdempsky/maligned",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "deprecation": {
+      "since": "v1.38.0",
+      "message": "The repository of the linter has been archived by the owner.",
+      "replacement": "govet 'fieldalignment'"
+    },
+    "name": "maligned",
+    "desc": "Tool to detect Go structs that would take less memory if their fields were sorted"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/butuzov/mirror",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.53.0",
+    "name": "mirror",
+    "desc": "reports wrong mirror patterns of bytes/strings usage"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "comment"
+    ],
+    "originalURL": "https://github.com/client9/misspell",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": false,
+    "since": "v1.8.0",
+    "name": "misspell",
+    "desc": "Finds commonly misspelled English words"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "bugs"
+    ],
+    "originalURL": "https://github.com/go-simpler/musttag",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.51.0",
+    "name": "musttag",
+    "desc": "enforce field tags in (un)marshaled structs"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/alexkohler/nakedret",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.19.0",
+    "name": "nakedret",
+    "desc": "Checks that functions with naked returns are not longer than a maximum size (can be zero)."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "complexity"
+    ],
+    "originalURL": "https://github.com/nakabonne/nestif",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.25.0",
+    "name": "nestif",
+    "desc": "Reports deeply nested if statements"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/gostaticanalysis/nilerr",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.38.0",
+    "name": "nilerr",
+    "desc": "Finds the code that returns nil even if it checks that the error is not nil."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/Antonboom/nilnil",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.43.0",
+    "name": "nilnil",
+    "desc": "Checks that there is no simultaneous return of `nil` error and an invalid value."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/ssgreg/nlreturn",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.30.0",
+    "name": "nlreturn",
+    "desc": "nlreturn checks for a new line before return and branch statements to increase code clarity"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "performance",
+      "bugs"
+    ],
+    "originalURL": "https://github.com/sonatard/noctx",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.28.0",
+    "name": "noctx",
+    "desc": "Finds sending http request without context.Context"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/firefart/nonamedreturns",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.46.0",
+    "name": "nonamedreturns",
+    "desc": "Reports all named returns"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/sivchari/nosnakecase",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.47.0",
+    "deprecation": {
+      "since": "v1.48.1",
+      "message": "The repository of the linter has been deprecated by the owner.",
+      "replacement": "revive(var-naming)"
+    },
+    "name": "nosnakecase",
+    "desc": "nosnakecase is a linter that detects snake case of variable naming and function name."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/stbenjam/no-sprintf-host-port",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.46.0",
+    "name": "nosprintfhostport",
+    "desc": "Checks for misuse of Sprintf to construct a host with port in a URL."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "test"
+    ],
+    "originalURL": "https://github.com/kunwardeep/paralleltest",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.33.0",
+    "name": "paralleltest",
+    "desc": "Detects missing usage of t.Parallel() method in your Go test"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "performance"
+    ],
+    "originalURL": "https://github.com/catenacyber/perfsprint",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.55.0",
+    "name": "perfsprint",
+    "desc": "Checks that fmt.Sprintf can be replaced with a faster alternative."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "performance"
+    ],
+    "originalURL": "https://github.com/alexkohler/prealloc",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.19.0",
+    "name": "prealloc",
+    "desc": "Finds slice declarations that could potentially be pre-allocated"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/nishanths/predeclared",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.35.0",
+    "name": "predeclared",
+    "desc": "find code that shadows one of Go's predeclared identifiers"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/yeya24/promlinter",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.40.0",
+    "name": "promlinter",
+    "desc": "Check Prometheus metrics naming via promlint"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/ghostiam/protogetter",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": true,
+    "since": "v1.55.0",
+    "name": "protogetter",
+    "desc": "Reports direct reads from proto message fields when getters should be used"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/curioswitch/go-reassign",
+    "internal": false,
+    "isSlow": true,
+    "since": "1.49.0",
+    "name": "reassign",
+    "desc": "Checks that package variables are not reassigned"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "metalinter"
+    ],
+    "originalURL": "https://github.com/mgechev/revive",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.37.0",
+    "name": "revive",
+    "desc": "Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs",
+      "sql"
+    ],
+    "originalURL": "https://github.com/jingyugao/rowserrcheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.23.0",
+    "name": "rowserrcheck",
+    "desc": "checks whether Rows.Err of rows is checked successfully"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "format"
+    ],
+    "originalURL": "https://github.com/go-simpler/sloglint",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.55.0",
+    "name": "sloglint",
+    "desc": "ensure consistent code style when using log/slog"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/kyoh86/scopelint",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.12.0",
+    "deprecation": {
+      "since": "v1.39.0",
+      "message": "The repository of the linter has been deprecated by the owner.",
+      "replacement": "exportloopref"
+    },
+    "name": "scopelint",
+    "desc": "Scopelint checks for unpinned variables in go programs"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs",
+      "sql"
+    ],
+    "originalURL": "https://github.com/ryanrolds/sqlclosecheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.28.0",
+    "name": "sqlclosecheck",
+    "desc": "Checks that sql.Rows, sql.Stmt, sqlx.NamedStmt, pgx.Query are closed."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/jjti/go-spancheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.56.0",
+    "name": "spancheck",
+    "desc": "Checks for mistakes with OpenTelemetry/Census spans."
+  },
+  {
+    "linter": {},
+    "enabledByDefault": true,
+    "loadMode": 575,
+    "inPresets": [
+      "bugs",
+      "metalinter"
+    ],
+    "alternativeNames": [
+      "megacheck"
+    ],
+    "originalURL": "https://staticcheck.io/",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "name": "staticcheck",
+    "desc": "It's a set of rules from staticcheck. It's not the same thing as the staticcheck binary. The author of staticcheck doesn't support or approve the use of staticcheck as a library inside golangci-lint."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "unused"
+    ],
+    "originalURL": "https://github.com/opennota/check",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "deprecation": {
+      "since": "v1.49.0",
+      "message": "The owner seems to have abandoned the linter.",
+      "replacement": "unused"
+    },
+    "name": "structcheck",
+    "desc": "Finds unused struct fields"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/dominikh/go-tools/tree/master/stylecheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.20.0",
+    "name": "stylecheck",
+    "desc": "Stylecheck is a replacement for golint"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "format"
+    ],
+    "originalURL": "https://github.com/4meepo/tagalign",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": false,
+    "since": "v1.53.0",
+    "name": "tagalign",
+    "desc": "check that struct tags are well aligned"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/ldez/tagliatelle",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.40.0",
+    "name": "tagliatelle",
+    "desc": "Checks the struct tags."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/sivchari/tenv",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.43.0",
+    "name": "tenv",
+    "desc": "tenv is analyzer that detects using os.Setenv instead of t.Setenv since Go1.17"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "test"
+    ],
+    "originalURL": "https://github.com/maratori/testableexamples",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.50.0",
+    "name": "testableexamples",
+    "desc": "linter checks if examples are testable (have an expected output)"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "test",
+      "bugs"
+    ],
+    "originalURL": "https://github.com/Antonboom/testifylint",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.55.0",
+    "name": "testifylint",
+    "desc": "Checks usage of github.com/stretchr/testify."
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style",
+      "test"
+    ],
+    "originalURL": "https://github.com/maratori/testpackage",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.25.0",
+    "name": "testpackage",
+    "desc": "linter that makes you use a separate _test package"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/kulti/thelper",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.34.0",
+    "name": "thelper",
+    "desc": "thelper detects tests helpers which is not start with t.Helper() method."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "test"
+    ],
+    "originalURL": "https://github.com/moricho/tparallel",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.32.0",
+    "name": "tparallel",
+    "desc": "tparallel detects inappropriate usage of t.Parallel() method in your Go test codes."
+  },
+  {
+    "linter": {},
+    "enabledByDefault": true,
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "internal": true,
+    "isSlow": true,
+    "since": "v1.3.0",
+    "name": "typecheck",
+    "desc": "Like the front-end of a Go compiler, parses and type-checks Go code"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/mdempsky/unconvert",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "name": "unconvert",
+    "desc": "Remove unnecessary type conversions"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "unused"
+    ],
+    "originalURL": "https://github.com/mvdan/unparam",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.9.0",
+    "name": "unparam",
+    "desc": "Reports unused function parameters"
+  },
+  {
+    "linter": {},
+    "enabledByDefault": true,
+    "loadMode": 575,
+    "inPresets": [
+      "unused"
+    ],
+    "alternativeNames": [
+      "megacheck"
+    ],
+    "originalURL": "https://github.com/dominikh/go-tools/tree/master/unused",
+    "internal": false,
+    "isSlow": true,
+    "doesChangeTypes": true,
+    "since": "v1.20.0",
+    "name": "unused",
+    "desc": "Checks Go code for unused constants, variables, functions and types"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/sashamelentyev/usestdlibvars",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.48.0",
+    "name": "usestdlibvars",
+    "desc": "A linter that detect the possibility to use variables/constants from the Go standard library."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "unused"
+    ],
+    "originalURL": "https://github.com/opennota/check",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.0.0",
+    "deprecation": {
+      "since": "v1.49.0",
+      "message": "The owner seems to have abandoned the linter.",
+      "replacement": "unused"
+    },
+    "name": "varcheck",
+    "desc": "Finds unused global variables and constants"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/blizzy78/varnamelen",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.43.0",
+    "name": "varnamelen",
+    "desc": "checks that the length of a variable's name matches its scope"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/sanposhiho/wastedassign",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.38.0",
+    "name": "wastedassign",
+    "desc": "Finds wasted assignment statements"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/ultraware/whitespace",
+    "internal": false,
+    "canAutoFix": true,
+    "isSlow": false,
+    "since": "v1.19.0",
+    "name": "whitespace",
+    "desc": "Whitespace is a linter that checks for unnecessary newlines at the start and end of functions, if, for, etc."
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "style",
+      "error"
+    ],
+    "originalURL": "https://github.com/tomarrell/wrapcheck",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.32.0",
+    "name": "wrapcheck",
+    "desc": "Checks that errors returned from external packages are wrapped"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/bombsimon/wsl",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.20.0",
+    "name": "wsl",
+    "desc": "add or remove empty lines"
+  },
+  {
+    "linter": {},
+    "loadMode": 575,
+    "inPresets": [
+      "bugs"
+    ],
+    "originalURL": "https://github.com/ykadowak/zerologlint",
+    "internal": false,
+    "isSlow": true,
+    "since": "v1.53.0",
+    "name": "zerologlint",
+    "desc": "Detects the wrong usage of `zerolog` that a user forgets to dispatch with `Send` or `Msg`"
+  },
+  {
+    "linter": {},
+    "loadMode": 7,
+    "inPresets": [
+      "style"
+    ],
+    "originalURL": "https://github.com/golangci/golangci-lint/blob/master/pkg/golinters/nolintlint/README.md",
+    "internal": false,
+    "isSlow": false,
+    "since": "v1.26.0",
+    "name": "nolintlint",
+    "desc": "Reports ill-formed or insufficient nolint directives"
+  }
+]
diff --git a/docs/package.json b/docs/package.json
index d7d60b1e..5c6fa5eb 100644
--- a/docs/package.json
+++ b/docs/package.json
@@ -51,7 +51,7 @@
     "gatsby-plugin-netlify": "^5.1.0"
   },
   "scripts": {
-    "build": "make -C .. expand_website_templates && gatsby build",
+    "build": "make -C .. website_expand_templates && gatsby build",
     "start": "gatsby develop",
     "serve": "gatsby serve",
     "clean": "gatsby clean"
diff --git a/docs/src/docs/contributing/website.mdx b/docs/src/docs/contributing/website.mdx
index ce9dc7a8..aaf68a2e 100644
--- a/docs/src/docs/contributing/website.mdx
+++ b/docs/src/docs/contributing/website.mdx
@@ -30,8 +30,8 @@ allowing to use `React` components.
 ## Templating
 
 We use templates like `{.SomeField}` inside our `mdx` files.
-There templates are expanded by running `make expand_website_templates` in the root of the repository.
-It runs script `scripts/expand_website_templates/main.go` that rewrites `mdx` files with replaced templates.
+There templates are expanded by running `make website_expand_templates` in the root of the repository.
+It runs script `scripts/website/expand_templates/` that rewrites `mdx` files with replaced templates.
 
 ## Hosting
 
@@ -59,5 +59,5 @@ Also, there is no need to refresh a webpage: hot reload updates changed content
 To do it run:
 
 ```sh
-go run ./scripts/expand_website_templates/main.go
+go run ./scripts/website/expand_templates/
 ```
diff --git a/scripts/expand_website_templates/main.go b/scripts/expand_website_templates/main.go
deleted file mode 100644
index 40564296..00000000
--- a/scripts/expand_website_templates/main.go
+++ /dev/null
@@ -1,572 +0,0 @@
-package main
-
-import (
-	"bytes"
-	"encoding/json"
-	"fmt"
-	"io"
-	"log"
-	"net/http"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"reflect"
-	"sort"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-
-	"golang.org/x/exp/maps"
-	"gopkg.in/yaml.v3"
-
-	"github.com/golangci/golangci-lint/internal/renameio"
-	"github.com/golangci/golangci-lint/pkg/config"
-	"github.com/golangci/golangci-lint/pkg/lint/linter"
-	"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
-)
-
-const listItemPrefix = "list-item-"
-
-func main() {
-	replacements, err := buildTemplateContext()
-	if err != nil {
-		log.Fatalf("Failed to build template context: %s", err)
-	}
-
-	if err := rewriteDocs(replacements); err != nil {
-		log.Fatalf("Failed to rewrite docs: %s", err)
-	}
-
-	log.Print("Successfully expanded templates")
-}
-
-func rewriteDocs(replacements map[string]string) error {
-	madeReplacements := map[string]bool{}
-	err := filepath.Walk(filepath.Join("docs", "src", "docs"),
-		func(path string, info os.FileInfo, err error) error {
-			if err != nil {
-				return err
-			}
-			if info.IsDir() {
-				return nil
-			}
-			return processDoc(path, replacements, madeReplacements)
-		})
-	if err != nil {
-		return fmt.Errorf("failed to walk dir: %w", err)
-	}
-
-	if len(madeReplacements) != len(replacements) {
-		for key := range replacements {
-			if !madeReplacements[key] {
-				log.Printf("Replacement %q wasn't performed", key)
-			}
-		}
-		return fmt.Errorf("%d replacements weren't performed", len(replacements)-len(madeReplacements))
-	}
-	return nil
-}
-
-func processDoc(path string, replacements map[string]string, madeReplacements map[string]bool) error {
-	contentBytes, err := os.ReadFile(path)
-	if err != nil {
-		return fmt.Errorf("failed to read %s: %w", path, err)
-	}
-
-	content := string(contentBytes)
-	hasReplacements := false
-	for key, replacement := range replacements {
-		nextContent := content
-		nextContent = strings.ReplaceAll(nextContent, fmt.Sprintf("{.%s}", key), replacement)
-
-		// Yaml formatter in mdx code section makes extra spaces, need to match them too.
-		nextContent = strings.ReplaceAll(nextContent, fmt.Sprintf("{ .%s }", key), replacement)
-
-		if nextContent != content {
-			hasReplacements = true
-			madeReplacements[key] = true
-			content = nextContent
-		}
-	}
-	if !hasReplacements {
-		return nil
-	}
-
-	log.Printf("Expanded template in %s, saving it", path)
-	if err = renameio.WriteFile(path, []byte(content), os.ModePerm); err != nil {
-		return fmt.Errorf("failed to write changes to file %s: %w", path, err)
-	}
-
-	return nil
-}
-
-type latestRelease struct {
-	TagName string `json:"tag_name"`
-}
-
-func getLatestVersion() (string, error) {
-	req, err := http.NewRequest( //nolint:noctx
-		http.MethodGet,
-		"https://api.github.com/repos/golangci/golangci-lint/releases/latest",
-		http.NoBody,
-	)
-	if err != nil {
-		return "", fmt.Errorf("failed to prepare a http request: %w", err)
-	}
-	req.Header.Add("Accept", "application/vnd.github.v3+json")
-	resp, err := http.DefaultClient.Do(req)
-	if err != nil {
-		return "", fmt.Errorf("failed to get http response for the latest tag: %w", err)
-	}
-	defer resp.Body.Close()
-	body, err := io.ReadAll(resp.Body)
-	if err != nil {
-		return "", fmt.Errorf("failed to read a body for the latest tag: %w", err)
-	}
-	release := latestRelease{}
-	err = json.Unmarshal(body, &release)
-	if err != nil {
-		return "", fmt.Errorf("failed to unmarshal the body for the latest tag: %w", err)
-	}
-	return release.TagName, nil
-}
-
-func buildTemplateContext() (map[string]string, error) {
-	golangciYamlExample, err := os.ReadFile(".golangci.reference.yml")
-	if err != nil {
-		return nil, fmt.Errorf("can't read .golangci.reference.yml: %w", err)
-	}
-
-	snippets, err := extractExampleSnippets(golangciYamlExample)
-	if err != nil {
-		return nil, fmt.Errorf("can't read .golangci.reference.yml: %w", err)
-	}
-
-	if err = exec.Command("make", "build").Run(); err != nil {
-		return nil, fmt.Errorf("can't run go install: %w", err)
-	}
-
-	lintersOut, err := exec.Command("./golangci-lint", "help", "linters").Output()
-	if err != nil {
-		return nil, fmt.Errorf("can't run linters cmd: %w", err)
-	}
-
-	lintersOutParts := bytes.Split(lintersOut, []byte("\n\n"))
-
-	helpCmd := exec.Command("./golangci-lint", "run", "-h")
-	helpCmd.Env = append(helpCmd.Env, os.Environ()...)
-	helpCmd.Env = append(helpCmd.Env, "HELP_RUN=1") // make default concurrency stable: don't depend on machine CPU number
-	help, err := helpCmd.Output()
-	if err != nil {
-		return nil, fmt.Errorf("can't run help cmd: %w", err)
-	}
-
-	helpLines := bytes.Split(help, []byte("\n"))
-	shortHelp := bytes.Join(helpLines[2:], []byte("\n"))
-	changeLog, err := os.ReadFile("CHANGELOG.md")
-	if err != nil {
-		return nil, err
-	}
-
-	latestVersion, err := getLatestVersion()
-	if err != nil {
-		return nil, fmt.Errorf("failed to get the latest version: %w", err)
-	}
-
-	return map[string]string{
-		"LintersExample":                   snippets.LintersSettings,
-		"ConfigurationExample":             snippets.ConfigurationFile,
-		"LintersCommandOutputEnabledOnly":  string(lintersOutParts[0]),
-		"LintersCommandOutputDisabledOnly": string(lintersOutParts[1]),
-		"EnabledByDefaultLinters":          getLintersListMarkdown(true),
-		"DisabledByDefaultLinters":         getLintersListMarkdown(false),
-		"DefaultExclusions":                getDefaultExclusions(),
-		"ThanksList":                       getThanksList(),
-		"RunHelpText":                      string(shortHelp),
-		"ChangeLog":                        string(changeLog),
-		"LatestVersion":                    latestVersion,
-	}, nil
-}
-
-func getDefaultExclusions() string {
-	bufferString := bytes.NewBufferString("")
-
-	for _, pattern := range config.DefaultExcludePatterns {
-		_, _ = fmt.Fprintln(bufferString)
-		_, _ = fmt.Fprintf(bufferString, "### %s\n", pattern.ID)
-		_, _ = fmt.Fprintln(bufferString)
-		_, _ = fmt.Fprintf(bufferString, "- linter: `%s`\n", pattern.Linter)
-		_, _ = fmt.Fprintf(bufferString, "- pattern: `%s`\n", strings.ReplaceAll(pattern.Pattern, "`", "&grave;"))
-		_, _ = fmt.Fprintf(bufferString, "- why: %s\n", pattern.Why)
-	}
-
-	return bufferString.String()
-}
-
-func getLintersListMarkdown(enabled bool) string {
-	dbManager, _ := lintersdb.NewManager(nil, nil, lintersdb.NewLinterBuilder())
-
-	lcs := dbManager.GetAllSupportedLinterConfigs()
-
-	var neededLcs []*linter.Config
-	for _, lc := range lcs {
-		if lc.Internal {
-			continue
-		}
-
-		if lc.EnabledByDefault == enabled {
-			neededLcs = append(neededLcs, lc)
-		}
-	}
-
-	sort.Slice(neededLcs, func(i, j int) bool {
-		return neededLcs[i].Name() < neededLcs[j].Name()
-	})
-
-	lines := []string{
-		"|Name|Description|Presets|AutoFix|Since|",
-		"|---|---|---|---|---|---|",
-	}
-
-	for _, lc := range neededLcs {
-		line := fmt.Sprintf("|%s|%s|%s|%v|%s|",
-			getName(lc),
-			getDesc(lc),
-			strings.Join(lc.InPresets, ", "),
-			check(lc.CanAutoFix, "Auto fix supported"),
-			lc.Since,
-		)
-		lines = append(lines, line)
-	}
-
-	return strings.Join(lines, "\n")
-}
-
-func getName(lc *linter.Config) string {
-	name := lc.Name()
-
-	if lc.OriginalURL != "" {
-		name = fmt.Sprintf("[%s](%s)", name, lc.OriginalURL)
-	}
-
-	if hasSettings(lc.Name()) {
-		name = fmt.Sprintf("%s&nbsp;[%s](#%s)", name, spanWithID(listItemPrefix+lc.Name(), "Configuration", "⚙️"), lc.Name())
-	}
-
-	if !lc.IsDeprecated() {
-		return name
-	}
-
-	title := "deprecated"
-	if lc.Deprecation.Replacement != "" {
-		title += fmt.Sprintf(" since %s", lc.Deprecation.Since)
-	}
-
-	return name + "&nbsp;" + span(title, "⚠")
-}
-
-func getDesc(lc *linter.Config) string {
-	desc := lc.Linter.Desc()
-	if lc.IsDeprecated() {
-		desc = lc.Deprecation.Message
-		if lc.Deprecation.Replacement != "" {
-			desc += fmt.Sprintf(" Replaced by %s.", lc.Deprecation.Replacement)
-		}
-	}
-
-	return formatDesc(desc)
-}
-
-func formatDesc(desc string) string {
-	runes := []rune(desc)
-
-	r, _ := utf8.DecodeRuneInString(desc)
-	runes[0] = unicode.ToUpper(r)
-
-	if runes[len(runes)-1] != '.' {
-		runes = append(runes, '.')
-	}
-
-	return strings.ReplaceAll(string(runes), "\n", "<br/>")
-}
-
-func check(b bool, title string) string {
-	if b {
-		return span(title, "✔")
-	}
-	return ""
-}
-
-func hasSettings(name string) bool {
-	tp := reflect.TypeOf(config.LintersSettings{})
-
-	for i := 0; i < tp.NumField(); i++ {
-		if strings.EqualFold(name, tp.Field(i).Name) {
-			return true
-		}
-	}
-
-	return false
-}
-
-func span(title, icon string) string {
-	return fmt.Sprintf(`<span title=%q>%s</span>`, title, icon)
-}
-
-func spanWithID(id, title, icon string) string {
-	return fmt.Sprintf(`<span id=%q title=%q>%s</span>`, id, title, icon)
-}
-
-type authorDetails struct {
-	Linters []string
-	Profile string
-	Avatar  string
-}
-
-func getThanksList() string {
-	addedAuthors := map[string]*authorDetails{}
-	dbManager, _ := lintersdb.NewManager(nil, nil, lintersdb.NewLinterBuilder())
-
-	for _, lc := range dbManager.GetAllSupportedLinterConfigs() {
-		if lc.Internal {
-			continue
-		}
-
-		if lc.OriginalURL == "" {
-			continue
-		}
-
-		linterURL := lc.OriginalURL
-		if lc.Name() == "staticcheck" {
-			linterURL = "https://github.com/dominikh/go-tools"
-		}
-
-		if author := extractAuthor(linterURL, "https://github.com/"); author != "" && author != "golangci" {
-			if _, ok := addedAuthors[author]; ok {
-				addedAuthors[author].Linters = append(addedAuthors[author].Linters, lc.Name())
-			} else {
-				addedAuthors[author] = &authorDetails{
-					Linters: []string{lc.Name()},
-					Profile: fmt.Sprintf("[%[1]s](https://github.com/sponsors/%[1]s)", author),
-					Avatar:  fmt.Sprintf(`<img src="https://github.com/%[1]s.png" alt="%[1]s" style="max-width: 100%%;" width="20px;" />`, author),
-				}
-			}
-		} else if author := extractAuthor(linterURL, "https://gitlab.com/"); author != "" {
-			if _, ok := addedAuthors[author]; ok {
-				addedAuthors[author].Linters = append(addedAuthors[author].Linters, lc.Name())
-			} else {
-				addedAuthors[author] = &authorDetails{
-					Linters: []string{lc.Name()},
-					Profile: fmt.Sprintf("[%[1]s](https://gitlab.com/%[1]s)", author),
-				}
-			}
-		} else {
-			continue
-		}
-	}
-
-	authors := maps.Keys(addedAuthors)
-	sort.Slice(authors, func(i, j int) bool {
-		return strings.ToLower(authors[i]) < strings.ToLower(authors[j])
-	})
-
-	lines := []string{
-		"|Author|Linter(s)|",
-		"|---|---|",
-	}
-
-	for _, author := range authors {
-		lines = append(lines, fmt.Sprintf("|%s %s|%s|",
-			addedAuthors[author].Avatar, addedAuthors[author].Profile, strings.Join(addedAuthors[author].Linters, ", ")))
-	}
-
-	return strings.Join(lines, "\n")
-}
-
-func extractAuthor(originalURL, prefix string) string {
-	if !strings.HasPrefix(originalURL, prefix) {
-		return ""
-	}
-
-	return strings.SplitN(strings.TrimPrefix(originalURL, prefix), "/", 2)[0]
-}
-
-type SettingSnippets struct {
-	ConfigurationFile string
-	LintersSettings   string
-}
-
-func extractExampleSnippets(example []byte) (*SettingSnippets, error) {
-	var data yaml.Node
-	err := yaml.Unmarshal(example, &data)
-	if err != nil {
-		return nil, err
-	}
-
-	root := data.Content[0]
-
-	globalNode := &yaml.Node{
-		Kind:        root.Kind,
-		Style:       root.Style,
-		Tag:         root.Tag,
-		Value:       root.Value,
-		Anchor:      root.Anchor,
-		Alias:       root.Alias,
-		HeadComment: root.HeadComment,
-		LineComment: root.LineComment,
-		FootComment: root.FootComment,
-		Line:        root.Line,
-		Column:      root.Column,
-	}
-
-	snippets := SettingSnippets{}
-
-	builder := strings.Builder{}
-
-	for j, node := range root.Content {
-		switch node.Value {
-		case "run", "output", "linters", "linters-settings", "issues", "severity":
-		default:
-			continue
-		}
-
-		nextNode := root.Content[j+1]
-
-		newNode := &yaml.Node{
-			Kind: nextNode.Kind,
-			Content: []*yaml.Node{
-				{
-					HeadComment: fmt.Sprintf("See the dedicated %q documentation section.", node.Value),
-					Kind:        node.Kind,
-					Style:       node.Style,
-					Tag:         node.Tag,
-					Value:       "option",
-				},
-				{
-					Kind:  node.Kind,
-					Style: node.Style,
-					Tag:   node.Tag,
-					Value: "value",
-				},
-			},
-		}
-
-		globalNode.Content = append(globalNode.Content, node, newNode)
-
-		if node.Value == "linters-settings" {
-			snippets.LintersSettings, err = getLintersSettingSections(node, nextNode)
-			if err != nil {
-				return nil, err
-			}
-
-			_, _ = builder.WriteString(
-				fmt.Sprintf(
-					"### `%s` configuration\n\nSee the dedicated [linters-settings](/usage/linters) documentation section.\n\n",
-					node.Value,
-				),
-			)
-			continue
-		}
-
-		nodeSection := &yaml.Node{
-			Kind:    root.Kind,
-			Style:   root.Style,
-			Tag:     root.Tag,
-			Value:   root.Value,
-			Content: []*yaml.Node{node, nextNode},
-		}
-
-		snippet, errSnip := marshallSnippet(nodeSection)
-		if errSnip != nil {
-			return nil, errSnip
-		}
-
-		_, _ = builder.WriteString(fmt.Sprintf("### `%s` configuration\n\n%s", node.Value, snippet))
-	}
-
-	overview, err := marshallSnippet(globalNode)
-	if err != nil {
-		return nil, err
-	}
-
-	snippets.ConfigurationFile = overview + builder.String()
-
-	return &snippets, nil
-}
-
-func getLintersSettingSections(node, nextNode *yaml.Node) (string, error) {
-	dbManager, _ := lintersdb.NewManager(nil, nil, lintersdb.NewLinterBuilder())
-	lcs := dbManager.GetAllSupportedLinterConfigs()
-
-	var lintersDesc = make(map[string]string)
-	for _, lc := range lcs {
-		if lc.Internal {
-			continue
-		}
-
-		// it's important to use lc.Name() nor name because name can be alias
-		lintersDesc[lc.Name()] = getDesc(lc)
-	}
-
-	builder := &strings.Builder{}
-
-	for i := 0; i < len(nextNode.Content); i += 2 {
-		r := &yaml.Node{
-			Kind:  nextNode.Kind,
-			Style: nextNode.Style,
-			Tag:   nextNode.Tag,
-			Value: node.Value,
-			Content: []*yaml.Node{
-				{
-					Kind:  node.Kind,
-					Value: node.Value,
-				},
-				{
-					Kind:    nextNode.Kind,
-					Content: []*yaml.Node{nextNode.Content[i], nextNode.Content[i+1]},
-				},
-			},
-		}
-
-		_, _ = fmt.Fprintf(builder, "### %s\n\n", nextNode.Content[i].Value)
-		_, _ = fmt.Fprintf(builder, "%s\n\n", lintersDesc[nextNode.Content[i].Value])
-		_, _ = fmt.Fprintln(builder, "```yaml")
-
-		encoder := yaml.NewEncoder(builder)
-		encoder.SetIndent(2)
-
-		err := encoder.Encode(r)
-		if err != nil {
-			return "", err
-		}
-
-		_, _ = fmt.Fprintln(builder, "```")
-		_, _ = fmt.Fprintln(builder)
-		_, _ = fmt.Fprintf(builder, "[%s](#%s)\n\n", span("Back to the top", "🔼"), listItemPrefix+nextNode.Content[i].Value)
-		_, _ = fmt.Fprintln(builder)
-	}
-
-	return builder.String(), nil
-}
-
-func marshallSnippet(node *yaml.Node) (string, error) {
-	builder := &strings.Builder{}
-
-	if node.Value != "" {
-		_, _ = fmt.Fprintf(builder, "### %s\n\n", node.Value)
-	}
-	_, _ = fmt.Fprintln(builder, "```yaml")
-
-	encoder := yaml.NewEncoder(builder)
-	encoder.SetIndent(2)
-
-	err := encoder.Encode(node)
-	if err != nil {
-		return "", err
-	}
-
-	_, _ = fmt.Fprintln(builder, "```")
-	_, _ = fmt.Fprintln(builder)
-
-	return builder.String(), nil
-}
diff --git a/scripts/website/dump_info/main.go b/scripts/website/dump_info/main.go
new file mode 100644
index 00000000..5f7b8eeb
--- /dev/null
+++ b/scripts/website/dump_info/main.go
@@ -0,0 +1,133 @@
+package main
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"log"
+	"os"
+	"os/exec"
+	"path/filepath"
+
+	"github.com/golangci/golangci-lint/pkg/config"
+	"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
+	"github.com/golangci/golangci-lint/scripts/website/types"
+)
+
+func main() {
+	err := saveLinters()
+	if err != nil {
+		log.Fatalf("Save linters: %v", err)
+	}
+
+	err = saveDefaultExclusions()
+	if err != nil {
+		log.Fatalf("Save default exclusions: %v", err)
+	}
+
+	err = saveCLIHelp(filepath.Join("assets", "cli-help.json"))
+	if err != nil {
+		log.Fatalf("Save CLI help: %v", err)
+	}
+}
+
+func saveLinters() error {
+	linters, _ := lintersdb.NewLinterBuilder().Build(config.NewDefault())
+
+	var wraps []types.LinterWrapper
+	for _, l := range linters {
+		wrapper := types.LinterWrapper{
+			Name:             l.Linter.Name(),
+			Desc:             l.Linter.Desc(),
+			EnabledByDefault: l.EnabledByDefault,
+			LoadMode:         l.LoadMode,
+			InPresets:        l.InPresets,
+			AlternativeNames: l.AlternativeNames,
+			OriginalURL:      l.OriginalURL,
+			Internal:         l.Internal,
+			CanAutoFix:       l.CanAutoFix,
+			IsSlow:           l.IsSlow,
+			DoesChangeTypes:  l.DoesChangeTypes,
+			Since:            l.Since,
+		}
+
+		if l.Deprecation != nil {
+			wrapper.Deprecation = &types.Deprecation{
+				Since:       l.Deprecation.Since,
+				Message:     l.Deprecation.Message,
+				Replacement: l.Deprecation.Replacement,
+			}
+		}
+
+		wraps = append(wraps, wrapper)
+	}
+
+	return saveToJSONFile(filepath.Join("assets", "linters-info.json"), wraps)
+}
+
+func saveDefaultExclusions() error {
+	var excludePatterns []types.ExcludePattern
+
+	for _, pattern := range config.DefaultExcludePatterns {
+		excludePatterns = append(excludePatterns, types.ExcludePattern{
+			ID:      pattern.ID,
+			Pattern: pattern.Pattern,
+			Linter:  pattern.Linter,
+			Why:     pattern.Why,
+		})
+	}
+
+	return saveToJSONFile(filepath.Join("assets", "default-exclusions.json"), excludePatterns)
+}
+
+func saveCLIHelp(dst string) error {
+	err := exec.Command("make", "build").Run()
+	if err != nil {
+		return fmt.Errorf("can't run make build: %w", err)
+	}
+
+	lintersOut, err := exec.Command("./golangci-lint", "help", "linters").Output()
+	if err != nil {
+		return fmt.Errorf("can't run linters cmd: %w", err)
+	}
+
+	lintersOutParts := bytes.Split(lintersOut, []byte("\n\n"))
+
+	helpCmd := exec.Command("./golangci-lint", "run", "-h")
+	helpCmd.Env = append(helpCmd.Env, os.Environ()...)
+	helpCmd.Env = append(helpCmd.Env, "HELP_RUN=1") // make default concurrency stable: don't depend on machine CPU number
+	help, err := helpCmd.Output()
+	if err != nil {
+		return fmt.Errorf("can't run help cmd: %w", err)
+	}
+
+	helpLines := bytes.Split(help, []byte("\n"))
+	shortHelp := bytes.Join(helpLines[2:], []byte("\n"))
+
+	data := types.CLIHelp{
+		Enable:  string(lintersOutParts[0]),
+		Disable: string(lintersOutParts[1]),
+		Help:    string(shortHelp),
+	}
+
+	return saveToJSONFile(dst, data)
+}
+
+func saveToJSONFile(dst string, data any) error {
+	file, err := os.Create(dst)
+	if err != nil {
+		return fmt.Errorf("open file (%s): %w", dst, err)
+	}
+
+	defer func() { _ = file.Close() }()
+
+	encoder := json.NewEncoder(file)
+	encoder.SetIndent("", "  ")
+
+	err = encoder.Encode(data)
+	if err != nil {
+		return fmt.Errorf("encode JSON (%s): %w", dst, err)
+	}
+
+	return nil
+}
diff --git a/scripts/website/expand_templates/exclusions.go b/scripts/website/expand_templates/exclusions.go
new file mode 100644
index 00000000..31678d5b
--- /dev/null
+++ b/scripts/website/expand_templates/exclusions.go
@@ -0,0 +1,48 @@
+package main
+
+import (
+	"bytes"
+	"path/filepath"
+	"strings"
+	"text/template"
+
+	"github.com/golangci/golangci-lint/scripts/website/types"
+)
+
+const exclusionTmpl = `{{ $tick := "` + "`" + `" }}
+### {{ .ID }}
+
+- linter: {{ $tick }}{{ .Linter }}{{ $tick }}
+- pattern: {{ $tick }}{{ .Pattern }}{{ $tick }}
+- why: {{ .Why }}
+`
+
+func getDefaultExclusions() (string, error) {
+	defaultExcludePatterns, err := readJSONFile[[]types.ExcludePattern](filepath.Join("assets", "default-exclusions.json"))
+	if err != nil {
+		return "", err
+	}
+
+	bufferString := bytes.NewBufferString("")
+
+	tmpl, err := template.New("exclusions").Parse(exclusionTmpl)
+	if err != nil {
+		return "", err
+	}
+
+	for _, pattern := range defaultExcludePatterns {
+		data := map[string]any{
+			"ID":      pattern.ID,
+			"Linter":  pattern.Linter,
+			"Pattern": strings.ReplaceAll(pattern.Pattern, "`", "&grave;"),
+			"Why":     pattern.Why,
+		}
+
+		err := tmpl.Execute(bufferString, data)
+		if err != nil {
+			return "", err
+		}
+	}
+
+	return bufferString.String(), nil
+}
diff --git a/scripts/website/expand_templates/linters.go b/scripts/website/expand_templates/linters.go
new file mode 100644
index 00000000..1f216cd3
--- /dev/null
+++ b/scripts/website/expand_templates/linters.go
@@ -0,0 +1,315 @@
+package main
+
+import (
+	"fmt"
+	"path/filepath"
+	"reflect"
+	"sort"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"gopkg.in/yaml.v3"
+
+	"github.com/golangci/golangci-lint/pkg/config"
+	"github.com/golangci/golangci-lint/scripts/website/types"
+)
+
+const listItemPrefix = "list-item-"
+
+func getLintersListMarkdown(enabled bool) string {
+	linters, err := readJSONFile[[]*types.LinterWrapper](filepath.Join("assets", "linters-info.json"))
+	if err != nil {
+		panic(err)
+	}
+
+	var neededLcs []*types.LinterWrapper
+	for _, lc := range linters {
+		if lc.Internal {
+			continue
+		}
+
+		if lc.EnabledByDefault == enabled {
+			neededLcs = append(neededLcs, lc)
+		}
+	}
+
+	sort.Slice(neededLcs, func(i, j int) bool {
+		return neededLcs[i].Name < neededLcs[j].Name
+	})
+
+	lines := []string{
+		"|Name|Description|Presets|AutoFix|Since|",
+		"|---|---|---|---|---|---|",
+	}
+
+	for _, lc := range neededLcs {
+		line := fmt.Sprintf("|%s|%s|%s|%v|%s|",
+			getName(lc),
+			getDesc(lc),
+			strings.Join(lc.InPresets, ", "),
+			check(lc.CanAutoFix, "Auto fix supported"),
+			lc.Since,
+		)
+		lines = append(lines, line)
+	}
+
+	return strings.Join(lines, "\n")
+}
+
+func getName(lc *types.LinterWrapper) string {
+	name := lc.Name
+
+	if lc.OriginalURL != "" {
+		name = fmt.Sprintf("[%s](%s)", name, lc.OriginalURL)
+	}
+
+	if hasSettings(lc.Name) {
+		name = fmt.Sprintf("%s&nbsp;[%s](#%s)", name, spanWithID(listItemPrefix+lc.Name, "Configuration", "⚙️"), lc.Name)
+	}
+
+	if lc.Deprecation == nil {
+		return name
+	}
+
+	title := "deprecated"
+	if lc.Deprecation.Replacement != "" {
+		title += fmt.Sprintf(" since %s", lc.Deprecation.Since)
+	}
+
+	return name + "&nbsp;" + span(title, "⚠")
+}
+
+func check(b bool, title string) string {
+	if b {
+		return span(title, "✔")
+	}
+	return ""
+}
+
+func getDesc(lc *types.LinterWrapper) string {
+	desc := lc.Desc
+	if lc.Deprecation != nil {
+		desc = lc.Deprecation.Message
+		if lc.Deprecation.Replacement != "" {
+			desc += fmt.Sprintf(" Replaced by %s.", lc.Deprecation.Replacement)
+		}
+	}
+
+	return formatDesc(desc)
+}
+
+func formatDesc(desc string) string {
+	runes := []rune(desc)
+
+	r, _ := utf8.DecodeRuneInString(desc)
+	runes[0] = unicode.ToUpper(r)
+
+	if runes[len(runes)-1] != '.' {
+		runes = append(runes, '.')
+	}
+
+	return strings.ReplaceAll(string(runes), "\n", "<br/>")
+}
+
+func hasSettings(name string) bool {
+	tp := reflect.TypeOf(config.LintersSettings{})
+
+	for i := 0; i < tp.NumField(); i++ {
+		if strings.EqualFold(name, tp.Field(i).Name) {
+			return true
+		}
+	}
+
+	return false
+}
+
+func span(title, icon string) string {
+	return fmt.Sprintf(`<span title=%q>%s</span>`, title, icon)
+}
+
+func spanWithID(id, title, icon string) string {
+	return fmt.Sprintf(`<span id=%q title=%q>%s</span>`, id, title, icon)
+}
+
+type SettingSnippets struct {
+	ConfigurationFile string
+	LintersSettings   string
+}
+
+func extractExampleSnippets(example []byte) (*SettingSnippets, error) {
+	var data yaml.Node
+	err := yaml.Unmarshal(example, &data)
+	if err != nil {
+		return nil, err
+	}
+
+	root := data.Content[0]
+
+	globalNode := &yaml.Node{
+		Kind:        root.Kind,
+		Style:       root.Style,
+		Tag:         root.Tag,
+		Value:       root.Value,
+		Anchor:      root.Anchor,
+		Alias:       root.Alias,
+		HeadComment: root.HeadComment,
+		LineComment: root.LineComment,
+		FootComment: root.FootComment,
+		Line:        root.Line,
+		Column:      root.Column,
+	}
+
+	snippets := SettingSnippets{}
+
+	builder := strings.Builder{}
+
+	for j, node := range root.Content {
+		switch node.Value {
+		case "run", "output", "linters", "linters-settings", "issues", "severity":
+		default:
+			continue
+		}
+
+		nextNode := root.Content[j+1]
+
+		newNode := &yaml.Node{
+			Kind: nextNode.Kind,
+			Content: []*yaml.Node{
+				{
+					HeadComment: fmt.Sprintf("See the dedicated %q documentation section.", node.Value),
+					Kind:        node.Kind,
+					Style:       node.Style,
+					Tag:         node.Tag,
+					Value:       "option",
+				},
+				{
+					Kind:  node.Kind,
+					Style: node.Style,
+					Tag:   node.Tag,
+					Value: "value",
+				},
+			},
+		}
+
+		globalNode.Content = append(globalNode.Content, node, newNode)
+
+		if node.Value == "linters-settings" {
+			snippets.LintersSettings, err = getLintersSettingSections(node, nextNode)
+			if err != nil {
+				return nil, err
+			}
+
+			_, _ = builder.WriteString(
+				fmt.Sprintf(
+					"### `%s` configuration\n\nSee the dedicated [linters-settings](/usage/linters) documentation section.\n\n",
+					node.Value,
+				),
+			)
+			continue
+		}
+
+		nodeSection := &yaml.Node{
+			Kind:    root.Kind,
+			Style:   root.Style,
+			Tag:     root.Tag,
+			Value:   root.Value,
+			Content: []*yaml.Node{node, nextNode},
+		}
+
+		snippet, errSnip := marshallSnippet(nodeSection)
+		if errSnip != nil {
+			return nil, errSnip
+		}
+
+		_, _ = builder.WriteString(fmt.Sprintf("### `%s` configuration\n\n%s", node.Value, snippet))
+	}
+
+	overview, err := marshallSnippet(globalNode)
+	if err != nil {
+		return nil, err
+	}
+
+	snippets.ConfigurationFile = overview + builder.String()
+
+	return &snippets, nil
+}
+
+func getLintersSettingSections(node, nextNode *yaml.Node) (string, error) {
+	linters, err := readJSONFile[[]*types.LinterWrapper](filepath.Join("assets", "linters-info.json"))
+	if err != nil {
+		return "", err
+	}
+
+	var lintersDesc = make(map[string]string)
+	for _, lc := range linters {
+		if lc.Internal {
+			continue
+		}
+
+		// it's important to use lc.Name() nor name because name can be alias
+		lintersDesc[lc.Name] = getDesc(lc)
+	}
+
+	builder := &strings.Builder{}
+
+	for i := 0; i < len(nextNode.Content); i += 2 {
+		r := &yaml.Node{
+			Kind:  nextNode.Kind,
+			Style: nextNode.Style,
+			Tag:   nextNode.Tag,
+			Value: node.Value,
+			Content: []*yaml.Node{
+				{
+					Kind:  node.Kind,
+					Value: node.Value,
+				},
+				{
+					Kind:    nextNode.Kind,
+					Content: []*yaml.Node{nextNode.Content[i], nextNode.Content[i+1]},
+				},
+			},
+		}
+
+		_, _ = fmt.Fprintf(builder, "### %s\n\n", nextNode.Content[i].Value)
+		_, _ = fmt.Fprintf(builder, "%s\n\n", lintersDesc[nextNode.Content[i].Value])
+		_, _ = fmt.Fprintln(builder, "```yaml")
+
+		encoder := yaml.NewEncoder(builder)
+		encoder.SetIndent(2)
+
+		err := encoder.Encode(r)
+		if err != nil {
+			return "", err
+		}
+
+		_, _ = fmt.Fprintln(builder, "```")
+		_, _ = fmt.Fprintln(builder)
+		_, _ = fmt.Fprintf(builder, "[%s](#%s)\n\n", span("Back to the top", "🔼"), listItemPrefix+nextNode.Content[i].Value)
+		_, _ = fmt.Fprintln(builder)
+	}
+
+	return builder.String(), nil
+}
+
+func marshallSnippet(node *yaml.Node) (string, error) {
+	builder := &strings.Builder{}
+
+	if node.Value != "" {
+		_, _ = fmt.Fprintf(builder, "### %s\n\n", node.Value)
+	}
+	_, _ = fmt.Fprintln(builder, "```yaml")
+
+	encoder := yaml.NewEncoder(builder)
+	encoder.SetIndent(2)
+
+	err := encoder.Encode(node)
+	if err != nil {
+		return "", err
+	}
+
+	_, _ = fmt.Fprintln(builder, "```")
+	_, _ = fmt.Fprintln(builder)
+
+	return builder.String(), nil
+}
diff --git a/scripts/website/expand_templates/main.go b/scripts/website/expand_templates/main.go
new file mode 100644
index 00000000..df5a254b
--- /dev/null
+++ b/scripts/website/expand_templates/main.go
@@ -0,0 +1,182 @@
+package main
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"log"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"github.com/golangci/golangci-lint/internal/renameio"
+	"github.com/golangci/golangci-lint/scripts/website/types"
+)
+
+func main() {
+	replacements, err := buildTemplateContext()
+	if err != nil {
+		log.Fatalf("Failed to build template context: %s", err)
+	}
+
+	if err := rewriteDocs(replacements); err != nil {
+		log.Fatalf("Failed to rewrite docs: %s", err)
+	}
+
+	log.Print("Successfully expanded templates")
+}
+
+func rewriteDocs(replacements map[string]string) error {
+	madeReplacements := map[string]bool{}
+	err := filepath.Walk(filepath.Join("docs", "src", "docs"),
+		func(path string, info os.FileInfo, err error) error {
+			if err != nil {
+				return err
+			}
+			if info.IsDir() {
+				return nil
+			}
+			return processDoc(path, replacements, madeReplacements)
+		})
+	if err != nil {
+		return fmt.Errorf("failed to walk dir: %w", err)
+	}
+
+	if len(madeReplacements) != len(replacements) {
+		for key := range replacements {
+			if !madeReplacements[key] {
+				log.Printf("Replacement %q wasn't performed", key)
+			}
+		}
+		return fmt.Errorf("%d replacements weren't performed", len(replacements)-len(madeReplacements))
+	}
+	return nil
+}
+
+func processDoc(path string, replacements map[string]string, madeReplacements map[string]bool) error {
+	contentBytes, err := os.ReadFile(path)
+	if err != nil {
+		return fmt.Errorf("failed to read %s: %w", path, err)
+	}
+
+	content := string(contentBytes)
+	hasReplacements := false
+	for key, replacement := range replacements {
+		nextContent := content
+		nextContent = strings.ReplaceAll(nextContent, fmt.Sprintf("{.%s}", key), replacement)
+
+		// Yaml formatter in mdx code section makes extra spaces, need to match them too.
+		nextContent = strings.ReplaceAll(nextContent, fmt.Sprintf("{ .%s }", key), replacement)
+
+		if nextContent != content {
+			hasReplacements = true
+			madeReplacements[key] = true
+			content = nextContent
+		}
+	}
+	if !hasReplacements {
+		return nil
+	}
+
+	log.Printf("Expanded template in %s, saving it", path)
+	if err = renameio.WriteFile(path, []byte(content), os.ModePerm); err != nil {
+		return fmt.Errorf("failed to write changes to file %s: %w", path, err)
+	}
+
+	return nil
+}
+
+type latestRelease struct {
+	TagName string `json:"tag_name"`
+}
+
+func getLatestVersion() (string, error) {
+	req, err := http.NewRequest( //nolint:noctx
+		http.MethodGet,
+		"https://api.github.com/repos/golangci/golangci-lint/releases/latest",
+		http.NoBody,
+	)
+	if err != nil {
+		return "", fmt.Errorf("failed to prepare a http request: %w", err)
+	}
+	req.Header.Add("Accept", "application/vnd.github.v3+json")
+	resp, err := http.DefaultClient.Do(req)
+	if err != nil {
+		return "", fmt.Errorf("failed to get http response for the latest tag: %w", err)
+	}
+	defer resp.Body.Close()
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return "", fmt.Errorf("failed to read a body for the latest tag: %w", err)
+	}
+	release := latestRelease{}
+	err = json.Unmarshal(body, &release)
+	if err != nil {
+		return "", fmt.Errorf("failed to unmarshal the body for the latest tag: %w", err)
+	}
+	return release.TagName, nil
+}
+
+func buildTemplateContext() (map[string]string, error) {
+	golangciYamlExample, err := os.ReadFile(".golangci.reference.yml")
+	if err != nil {
+		return nil, fmt.Errorf("can't read .golangci.reference.yml: %w", err)
+	}
+
+	snippets, err := extractExampleSnippets(golangciYamlExample)
+	if err != nil {
+		return nil, fmt.Errorf("can't read .golangci.reference.yml: %w", err)
+	}
+
+	helps, err := readJSONFile[types.CLIHelp](filepath.Join("assets", "cli-help.json"))
+	if err != nil {
+		return nil, err
+	}
+
+	changeLog, err := os.ReadFile("CHANGELOG.md")
+	if err != nil {
+		return nil, err
+	}
+
+	latestVersion, err := getLatestVersion()
+	if err != nil {
+		return nil, fmt.Errorf("failed to get the latest version: %w", err)
+	}
+
+	exclusions, err := getDefaultExclusions()
+	if err != nil {
+		return nil, fmt.Errorf("default exclusions: %w", err)
+	}
+
+	return map[string]string{
+		"LintersExample":                   snippets.LintersSettings,
+		"ConfigurationExample":             snippets.ConfigurationFile,
+		"LintersCommandOutputEnabledOnly":  helps.Enable,
+		"LintersCommandOutputDisabledOnly": helps.Disable,
+		"EnabledByDefaultLinters":          getLintersListMarkdown(true),
+		"DisabledByDefaultLinters":         getLintersListMarkdown(false),
+		"DefaultExclusions":                exclusions,
+		"ThanksList":                       getThanksList(),
+		"RunHelpText":                      helps.Help,
+		"ChangeLog":                        string(changeLog),
+		"LatestVersion":                    latestVersion,
+	}, nil
+}
+
+func readJSONFile[T any](src string) (T, error) {
+	file, err := os.Open(src)
+	if err != nil {
+		var zero T
+		return zero, err
+	}
+
+	var result T
+	err = json.NewDecoder(file).Decode(&result)
+	if err != nil {
+		var zero T
+		return zero, err
+	}
+
+	return result, nil
+}
diff --git a/scripts/expand_website_templates/main_test.go b/scripts/website/expand_templates/main_test.go
similarity index 100%
rename from scripts/expand_website_templates/main_test.go
rename to scripts/website/expand_templates/main_test.go
diff --git a/scripts/website/expand_templates/thanks.go b/scripts/website/expand_templates/thanks.go
new file mode 100644
index 00000000..d4a548f6
--- /dev/null
+++ b/scripts/website/expand_templates/thanks.go
@@ -0,0 +1,87 @@
+package main
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+
+	"golang.org/x/exp/maps"
+
+	"github.com/golangci/golangci-lint/pkg/config"
+	"github.com/golangci/golangci-lint/pkg/lint/lintersdb"
+)
+
+type authorDetails struct {
+	Linters []string
+	Profile string
+	Avatar  string
+}
+
+func getThanksList() string {
+	addedAuthors := map[string]*authorDetails{}
+
+	linters, _ := lintersdb.NewLinterBuilder().Build(config.NewDefault())
+
+	for _, lc := range linters {
+		if lc.Internal {
+			continue
+		}
+
+		if lc.OriginalURL == "" {
+			continue
+		}
+
+		linterURL := lc.OriginalURL
+		if lc.Name() == "staticcheck" {
+			linterURL = "https://github.com/dominikh/go-tools"
+		}
+
+		if author := extractAuthor(linterURL, "https://github.com/"); author != "" && author != "golangci" {
+			if _, ok := addedAuthors[author]; ok {
+				addedAuthors[author].Linters = append(addedAuthors[author].Linters, lc.Name())
+			} else {
+				addedAuthors[author] = &authorDetails{
+					Linters: []string{lc.Name()},
+					Profile: fmt.Sprintf("[%[1]s](https://github.com/sponsors/%[1]s)", author),
+					Avatar:  fmt.Sprintf(`<img src="https://github.com/%[1]s.png" alt="%[1]s" style="max-width: 100%%;" width="20px;" />`, author),
+				}
+			}
+		} else if author := extractAuthor(linterURL, "https://gitlab.com/"); author != "" {
+			if _, ok := addedAuthors[author]; ok {
+				addedAuthors[author].Linters = append(addedAuthors[author].Linters, lc.Name())
+			} else {
+				addedAuthors[author] = &authorDetails{
+					Linters: []string{lc.Name()},
+					Profile: fmt.Sprintf("[%[1]s](https://gitlab.com/%[1]s)", author),
+				}
+			}
+		} else {
+			continue
+		}
+	}
+
+	authors := maps.Keys(addedAuthors)
+	sort.Slice(authors, func(i, j int) bool {
+		return strings.ToLower(authors[i]) < strings.ToLower(authors[j])
+	})
+
+	lines := []string{
+		"|Author|Linter(s)|",
+		"|---|---|",
+	}
+
+	for _, author := range authors {
+		lines = append(lines, fmt.Sprintf("|%s %s|%s|",
+			addedAuthors[author].Avatar, addedAuthors[author].Profile, strings.Join(addedAuthors[author].Linters, ", ")))
+	}
+
+	return strings.Join(lines, "\n")
+}
+
+func extractAuthor(originalURL, prefix string) string {
+	if !strings.HasPrefix(originalURL, prefix) {
+		return ""
+	}
+
+	return strings.SplitN(strings.TrimPrefix(originalURL, prefix), "/", 2)[0]
+}
diff --git a/scripts/website/types/types.go b/scripts/website/types/types.go
new file mode 100644
index 00000000..2eeabf3f
--- /dev/null
+++ b/scripts/website/types/types.go
@@ -0,0 +1,48 @@
+package types
+
+import (
+	"golang.org/x/tools/go/packages"
+)
+
+type CLIHelp struct {
+	Enable  string `json:"enable"`
+	Disable string `json:"disable"`
+	Help    string `json:"help"`
+}
+
+type ExcludePattern struct {
+	ID      string `json:"id,omitempty"`
+	Pattern string `json:"pattern,omitempty"`
+	Linter  string `json:"linter,omitempty"`
+	Why     string `json:"why,omitempty"`
+}
+
+type Deprecation struct {
+	Since       string `json:"since,omitempty"`
+	Message     string `json:"message,omitempty"`
+	Replacement string `json:"replacement,omitempty"`
+}
+
+// LinterWrapper same fields but with struct tags.
+// The field Name and Desc are added to have the information about the linter.
+// The field Linter is removed (not serializable).
+type LinterWrapper struct {
+	Name string `json:"name"` // From linter.
+	Desc string `json:"desc"` // From linter.
+
+	EnabledByDefault bool `json:"enabledByDefault,omitempty"`
+
+	LoadMode packages.LoadMode `json:"loadMode,omitempty"`
+
+	InPresets        []string `json:"inPresets,omitempty"`
+	AlternativeNames []string `json:"alternativeNames,omitempty"`
+
+	OriginalURL     string `json:"originalURL,omitempty"`
+	Internal        bool   `json:"internal"`
+	CanAutoFix      bool   `json:"canAutoFix,omitempty"`
+	IsSlow          bool   `json:"isSlow"`
+	DoesChangeTypes bool   `json:"doesChangeTypes,omitempty"`
+
+	Since       string       `json:"since,omitempty"`
+	Deprecation *Deprecation `json:"deprecation,omitempty"`
+}