mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
* chore(claude): session-start and pre-bash hooks, deny .env reads scripts/claude-hook.mjs, wired in .claude/settings.json: - SessionStart warns when core.hooksPath is not .githooks, so a clone or a new machine cannot silently run without the repo git hooks. - PreToolUse on Bash refuses a top-level cd: the tool's shell is persistent, so a cd leaks into every later command and a gate can report green from the wrong directory. Subshells, git -C and root-relative paths pass. permissions.deny gains Read(**/.env): the gitignored env files never enter the model's context. Server/.env.example stays readable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jwaz4CHGAz85Rpypjvto5a * chore(lint): durationcheck on the server, noImplicitOverride on the client Both measured at zero hits on dev, so they cost nothing today and only block regressions: a Duration multiplied by a Duration-typed value, and an override left behind when its base method is renamed. rowserrcheck and sqlclosecheck were measured too and rejected: their six production hits are all correct code (rows.Err is checked inside scanEventRows behind the rowsScanner interface; the three Close sites close on every path by hand). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jwaz4CHGAz85Rpypjvto5a --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
127 lines
5.8 KiB
YAML
127 lines
5.8 KiB
YAML
version: "2"
|
|
|
|
linters:
|
|
enable:
|
|
- gocritic # opinionated checks for bugs, performance, style
|
|
- gosec # security-focused static analysis (SQL injection, hardcoded creds, weak crypto)
|
|
- errcheck # ensures all errors are checked
|
|
- bodyclose # detects unclosed HTTP response bodies
|
|
- contextcheck # verifies context.Context propagation
|
|
- nilerr # detects returning nil when err is not nil
|
|
- prealloc # suggests pre-allocating slices for performance
|
|
- unconvert # removes unnecessary type conversions
|
|
- unparam # finds unused function parameters
|
|
- wastedassign # finds wasted assignments
|
|
- staticcheck # advanced static analysis (correctness, performance, deprecation)
|
|
- modernize # flags outdated idioms (slices/maps/min/max, range-over-int, any, fmt.Appendf)
|
|
|
|
# Complexity budgets. These are a RATCHET, not a standard: each threshold sits
|
|
# just above today's worst offender, so the build is green now and the budget
|
|
# only blocks regression past the current extreme. Tighten them over time — each
|
|
# step is a one-line edit here plus the refactor it forces. Measured values and
|
|
# the work each budget is waiting on are in the settings block below.
|
|
- funlen # function length (lines and statements)
|
|
- cyclop # cyclomatic complexity per function
|
|
- nestif # deeply nested if-blocks
|
|
- dupl # verbatim duplicated blocks
|
|
|
|
# Silent-drop and sentinel-error classes (added 2026-08-30).
|
|
- exhaustive # a switch over an enum-like type with no default that misses a member
|
|
- errorlint # errors.Is/As instead of == and type assertions on wrapped errors; %w in Errorf
|
|
- durationcheck # time.Duration multiplied by a Duration-typed value, e.g. d*time.Second where d is already a Duration
|
|
|
|
settings:
|
|
exhaustive:
|
|
# An explicit default branch is a deliberate catch-all; only switches without
|
|
# one, which fall through in silence, must list every member.
|
|
default-signifies-exhaustive: true
|
|
staticcheck:
|
|
checks:
|
|
- "all"
|
|
- "-SA1019" # suppress deprecated usage warnings (websocket library migration tracked separately)
|
|
gocritic:
|
|
enabled-tags:
|
|
- diagnostic
|
|
- performance
|
|
disabled-checks:
|
|
- hugeParam # too noisy for struct-heavy code
|
|
# Complexity budgets set to a TARGET, not to whatever passes today. Existing
|
|
# offenders are deliberately left failing rather than excluded: an exclusion
|
|
# list goes stale and quietly becomes permanent, whereas a failing check is a
|
|
# backlog you can see. Measured 2026-08-16 over 1446 production functions,
|
|
# tests excluded.
|
|
#
|
|
# These are not the tool defaults (60/40, 10, 4). The defaults descend from
|
|
# 1976-era cyclomatic-complexity work that predates Go's explicit error
|
|
# handling: every `if err != nil` costs a branch, so idiomatic Go scores high
|
|
# for no real complexity. That is why golangci-lint's other cyclomatic linter,
|
|
# gocyclo, defaults to 30 rather than 10. The values below are chosen for a Go
|
|
# server rather than copied from C-era literature.
|
|
funlen:
|
|
# funlen counts in its own units — it ignores blank lines and comments, so
|
|
# main.go run() is 311 here and 422 by raw line span. Worst today: 311 lines,
|
|
# 131 statements.
|
|
lines: 100
|
|
statements: 50
|
|
cyclop:
|
|
# Worst today: ws/voice_join.go handleVoiceJoin at 59, main.go run at 57,
|
|
# plugin/registry.go InstallFromZip at 44.
|
|
max-complexity: 20
|
|
nestif:
|
|
# Worst today: 17.
|
|
min-complexity: 8
|
|
dupl:
|
|
# The conventional value. Flags three real duplicate pairs, all adjacent
|
|
# near-identical siblings worth collapsing:
|
|
# db/mention_queries.go:322-357 vs :364-399
|
|
# ws/voice_controls.go:13-42 vs :45-73
|
|
# ws/voice_controls.go:76-121 vs :124-171
|
|
threshold: 150
|
|
gosec:
|
|
excludes:
|
|
- G104 # unhandled errors — errcheck covers this better
|
|
- G304 # file path from variable — expected in file storage code
|
|
- G306 # WriteFile perms ≤0600 — our only hits are generated source files (cmd/genprotocol), which must stay world-readable or multi-stage container builds break
|
|
- G706 # log injection — false positive with slog structured logging (values are typed key-value pairs, not interpolated)
|
|
|
|
exclusions:
|
|
# Suppress noisy linters in test files
|
|
rules:
|
|
- linters: [unparam]
|
|
path: _test\.go
|
|
- linters: [gosec]
|
|
path: _test\.go
|
|
- linters: [errcheck]
|
|
path: _test\.go
|
|
# Complexity budgets apply to production code only. Table-driven tests are
|
|
# legitimately long, and duplicated setup between test cases is clearer than
|
|
# a shared helper that hides what each case is doing.
|
|
- linters: [funlen, cyclop, nestif, dupl]
|
|
path: _test\.go
|
|
|
|
# gofmt is the required Go formatting gate (S-05). It lives here rather than as a
|
|
# standalone CI step because `gofmt -l` prints offenders and still exits 0, so a
|
|
# `gofmt -l` step cannot fail a build. Running it as a formatter inside
|
|
# golangci-lint means it reports through the already-pinned Lint check.
|
|
#
|
|
# In v2 the formatters moved out of `linters.enable` into their own section, and
|
|
# they carry their own exclusion list.
|
|
formatters:
|
|
enable:
|
|
- gofmt
|
|
exclusions:
|
|
paths:
|
|
# sqlc output, verified by `git diff --exit-code db/dbgen` after regeneration.
|
|
- db/dbgen
|
|
|
|
# Report every finding. The defaults hide work three separate ways, which is fine
|
|
# when the list is meant to be empty and actively misleading when it is a backlog:
|
|
# "fixed everything shown" would leave more behind. uniq-by-line is the sharp one —
|
|
# it keeps a single issue per line, and since cyclop and funlen both anchor at the
|
|
# function declaration, enabling cyclop silently swallowed 16 of funlen's 21
|
|
# findings here.
|
|
issues:
|
|
max-issues-per-linter: 0
|
|
max-same-issues: 0
|
|
uniq-by-line: false
|