3x-ui is a Go (Gin + GORM) web panel that generates configuration, share links and subscriptions for other programs — Xray-core, mihomo, sing-box, mtg-multi — and is deployed by operators who upgrade in place. Judge findings by what breaks for those consumers and operators, not by style.
Reserve blocking severity for:
internal/web/controller/, session and
middleware code, the PUBLIC internal/sub/ subscription server, and Xray
config generation in internal/xray/.runtime.Runtime
(internal/web/runtime/) and calls internal/xray/api.go directly, or
dispatches from a controller or cron job. It passes every local test and
silently breaks every multi-node deployment.internal/database/db.go, one that behaves differently on SQLite and
PostgreSQL, or one that loses or overwrites operator data on upgrade or
rollback. There are no migration files and no down-migrations.internal/util/link/ + internal/sub/, TS
frontend/src/lib/xray/, TS docs/lib/xray/) diverge from one another..github/workflows/: this repository runs workflows with
secrets against a public fork stream. Untrusted expression interpolation
into run: blocks, broadened permissions, weakened guards, or a job that
executes pull-request code is blocking.Style, naming and refactoring suggestions are nits at most.
g.POST/g.GET in internal/web/controller/ needs the whole chain:
an entry in frontend/src/pages/api-docs/endpoints.ts, regenerated
artefacts (make gen), any new API-boundary struct added to StructAllow
in tools/openapigen/main.go, and frontend/public/openapi.json copied to
docs/public/openapi.json with the docs MDX regenerated
(cd docs && pnpm gen:api). CI checks the first three; the docs copy is
checked by nothing — a missed copy is blocking, not a nit.internal/web/translation/
and is referenced from frontend/src or Go in the same PR.err != nil or len(x) > 0, or was made
green by regenerating golden fixtures or Vitest snapshots is a real finding.npm audit, govulncheck.frontend/src/generated/,
frontend/public/openapi.json, docs/public/openapi.json) or lock files.
Those files being STALE after a source change is reportable; their style
is not.CLAUDE.md rejects such tests outright.file:line citation from this repository,
not an inference from a name.Report at most five nits per review and say "plus N similar" in the summary for the rest. Lead the summary with "No blocking issues" when everything found is a nit. After the first review of a PR, report blocking findings only.