You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
~7 weeks elapsed since the last Sergo run (2026-07-08 → 2026-08-30). The linter registry grew from 43 to 67 analyzers (24 new linters) and the registry's internal structure changed: cmd/linters/main.go is now a thin 24-line entrypoint (no longer a per-analyzer detector), replaced by pkg/linters/registry.go's allAnalyzers slice and a self-documenting header in pkg/linters/doc.go. This run split effort 50/50 between (a) re-validating previously-tracked bug classes against the new registry shape, and (b) exploring never-before-audited linters given the large registry growth. Filed 1 new issue: a coverage gap in manualpathconcat where a common 2-operand path-concatenation shape is never detected. Two historically major bug classes were confirmed permanently closed by new structural guardrails — details below.
Tool & registry updates
Registry detector changed: use pkg/linters/doc.go's // All N active analyzers: header (N=67) or len(allAnalyzers) in pkg/linters/registry.go, notcmd/linters/main.go (now empty of per-analyzer lines).
The syntactic-package-match bug class (ident.Name == "pkg" instead of type-resolved matching) is now fully closed: a repo-wide grep for .Name (==|!=) "<stdpkg>" across pkg/linters returns zero matches. astutil.IsPkgSelector has been adopted universally.
New shared abstraction pkg/linters/internal/resourcetracker centralizes the acquire-then-must-defer-cleanup state machine (nolint suppression, generated-file skip, diagnostic reporting) for contextcancelnotdeferred, manualmutexunlock, and fileclosenotdeferred. This run nearly mis-filed a suppression-gap issue against these three before reading the shared framework and confirming suppression is handled centrally — a false positive avoided.
Strategy split
50% cached reuse — re-applied proven audit methodology: registry-delta detection, gh api issue reconciliation before investigation (avoiding phantom/duplicate findings), and the pattern-set-too-narrow lens that has previously found real bugs in errstringmatch, sprintferrdot, and lenstringzero.
50% new exploration — audited linters with little or no prior Sergo history given the registry's growth to 67: nilctxpassed, bytesbufferstring, ioutildeprecated, globwalkignorederror, walkfuncerrshadow, goroutinemissingrecover. All were read in full and found clean/well-designed.
Success-metric targets set at strategy selection: ≥1 non-duplicate, well-evidenced finding; zero false-positive issues filed; explicit confirmation of the two previously-open bug-class closures.
Findings
manualpathconcat: 2-operand embedded-slash literal is never detected (filed as issue, see below)
matchSlashSeparator (manualpathconcat.go:120-137) only matches the 3-operand chain X + "/" + Y, requiring the middle operand to be the exact literal "/" (isSlashLiteral, line 140). The equally common 2-operand shape dir + "/subpath" — where the slash is embedded in a longer literal — is structurally unreachable: bin.X must itself be a *ast.BinaryExpr, which a bare identifier never is. The same gap exists in the += handler (analyzeAssignStmt, line 94). Testdata confirms zero coverage of this shape: goodSuffixOnly (dir + "/") and goodPrefixOnly ("/" + name) test different, narrower shapes. This is the same pattern_set_too_narrow class previously fixed in errstringmatch (#40244), sprintferrdot, and lenstringzero (#54717).
bytesbufferstring — isBytesBufferValue correctly requires exact value type (not pointer), sound nil-semantics reasoning.
ioutildeprecated — both qualified-selector and dot-import checks use types.Info resolution, not syntactic matching.
globwalkignorederror, walkfuncerrshadow, goroutinemissingrecover — clean on full read.
contextcancelnotdeferred / manualmutexunlock / fileclosenotdeferred — suppression correctly centralized in internal/resourcetracker; initial suppression-gap hypothesis was a false alarm, caught before filing.
Generated tasks / issues
ID
Title
Status
aw_sg61a1
manualpathconcat: 2-operand embedded-slash literal is never detected
Filed this run
Only 1 of the 3 available issue slots was used — the finding is well-evidenced and precise; consistent with this project's established preference for single-file precision over volume.
Success score: 8/10 (solid, well-evidenced, non-duplicate finding; slightly reduced from historical average due to time spent re-deriving registry/tooling context after the 7-week gap rather than pure finding volume)
This run closes out two bug-class categories that have recurred across many prior runs (doc-sync-drift and syntactic-package-match) — both are now structurally guarded by code rather than requiring ongoing manual audits. This mirrors the project's historical trend of previously-manual-audit classes becoming self-enforced over time (e.g. suppression/test-skip parity checks in earlier rounds).
Recommendations
Stop allocating audit time to doc-sync-drift and syntactic-pkg-match classes — they are now structurally guarded.
Prioritize the 24 linters added since the last run for first-time audits, since they carry no prior Sergo history and the registry has nearly grown 60%.
When auditing any linter built on internal/resourcetracker, check the shared framework first — a single fix there would apply to all consumers at once.
Next-run focus (R62)
Re-check pkg/linters/doc.go's header count for further registry growth, then sweep remaining never-audited linters (hardcodedfilepath, sprintfbool, sprintferrdot, sprintferrorsnew, stringscountcontains, stringsindexhasprefix, timenowsub, trimleftright, uncheckedflushreturn, mapdeletecheck, logfatallibrary, httpstatuscode, excessivefuncparams) for pattern-set-too-narrow and autofix-compile-correctness issues, and verify aw_sg61a1 landed correctly.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Executive summary
~7 weeks elapsed since the last Sergo run (2026-07-08 → 2026-08-30). The linter registry grew from 43 to 67 analyzers (24 new linters) and the registry's internal structure changed:
cmd/linters/main.gois now a thin 24-line entrypoint (no longer a per-analyzer detector), replaced bypkg/linters/registry.go'sallAnalyzersslice and a self-documenting header inpkg/linters/doc.go. This run split effort 50/50 between (a) re-validating previously-tracked bug classes against the new registry shape, and (b) exploring never-before-audited linters given the large registry growth. Filed 1 new issue: a coverage gap inmanualpathconcatwhere a common 2-operand path-concatenation shape is never detected. Two historically major bug classes were confirmed permanently closed by new structural guardrails — details below.Tool & registry updates
pkg/linters/doc.go's// All N active analyzers:header (N=67) orlen(allAnalyzers)inpkg/linters/registry.go, notcmd/linters/main.go(now empty of per-analyzer lines).pkg/linters/doc_sync_test.go(4 tests) now cross-checks registry ↔ doc.go ↔ README ↔.github/workflows/cgo.ymlCI-enforcement list automatically. This permanently closes the doc-sync-drift and CI-enforcement-drift bug classes, previously the single most common finding type (e.g. doc-sync guard is incomplete: {registry, spec_test} and {doc.go, README} are two disconnected clusters — a linter present in cod [Content truncated due to length] #47190, doc-sync: pkg/linters/doc.go says "53 active analyzers" but 54 are registered — timenowsub is omitted #46707, trimleftright: the "repeated rune" cutset heuristic is an arbitrary discriminator that misses the most common TrimLeft/TrimRight [Content truncated due to length] #46526, doc-sync: pkg/linters/doc.go says "45 active analyzers" but 51 are registered — 6 newest linters omitted #46131, Registry-CI-enforcement drift: no automated guard ties linters.All() to cgo.yml LINTER_FLAGS #55628). No further probing of this class is warranted.ident.Name == "pkg"instead of type-resolved matching) is now fully closed: a repo-wide grep for.Name (==|!=) "<stdpkg>"acrosspkg/lintersreturns zero matches.astutil.IsPkgSelectorhas been adopted universally.pkg/linters/internal/resourcetrackercentralizes the acquire-then-must-defer-cleanup state machine (nolint suppression, generated-file skip, diagnostic reporting) forcontextcancelnotdeferred,manualmutexunlock, andfileclosenotdeferred. This run nearly mis-filed a suppression-gap issue against these three before reading the shared framework and confirming suppression is handled centrally — a false positive avoided.Strategy split
50% cached reuse — re-applied proven audit methodology: registry-delta detection,
gh apiissue reconciliation before investigation (avoiding phantom/duplicate findings), and the pattern-set-too-narrow lens that has previously found real bugs inerrstringmatch,sprintferrdot, andlenstringzero.50% new exploration — audited linters with little or no prior Sergo history given the registry's growth to 67:
nilctxpassed,bytesbufferstring,ioutildeprecated,globwalkignorederror,walkfuncerrshadow,goroutinemissingrecover. All were read in full and found clean/well-designed.Success-metric targets set at strategy selection: ≥1 non-duplicate, well-evidenced finding; zero false-positive issues filed; explicit confirmation of the two previously-open bug-class closures.
Findings
manualpathconcat: 2-operand embedded-slash literal is never detected (filed as issue, see below)
matchSlashSeparator(manualpathconcat.go:120-137) only matches the 3-operand chainX + "/" + Y, requiring the middle operand to be the exact literal"/"(isSlashLiteral, line 140). The equally common 2-operand shapedir + "/subpath"— where the slash is embedded in a longer literal — is structurally unreachable:bin.Xmust itself be a*ast.BinaryExpr, which a bare identifier never is. The same gap exists in the+=handler (analyzeAssignStmt, line 94). Testdata confirms zero coverage of this shape:goodSuffixOnly(dir + "/") andgoodPrefixOnly("/" + name) test different, narrower shapes. This is the samepattern_set_too_narrowclass previously fixed inerrstringmatch(#40244),sprintferrdot, andlenstringzero(#54717).Audited and confirmed clean (no action needed)
nilctxpassed— variadic/ellipsis-spread parameter handling correctly traced.bytesbufferstring—isBytesBufferValuecorrectly requires exact value type (not pointer), sound nil-semantics reasoning.ioutildeprecated— both qualified-selector and dot-import checks usetypes.Inforesolution, not syntactic matching.globwalkignorederror,walkfuncerrshadow,goroutinemissingrecover— clean on full read.contextcancelnotdeferred/manualmutexunlock/fileclosenotdeferred— suppression correctly centralized ininternal/resourcetracker; initial suppression-gap hypothesis was a false alarm, caught before filing.Generated tasks / issues
manualpathconcat: 2-operand embedded-slash literal is never detectedOnly 1 of the 3 available issue slots was used — the finding is well-evidenced and precise; consistent with this project's established preference for single-file precision over volume.
Metrics
Historical context
This run closes out two bug-class categories that have recurred across many prior runs (doc-sync-drift and syntactic-package-match) — both are now structurally guarded by code rather than requiring ongoing manual audits. This mirrors the project's historical trend of previously-manual-audit classes becoming self-enforced over time (e.g. suppression/test-skip parity checks in earlier rounds).
Recommendations
internal/resourcetracker, check the shared framework first — a single fix there would apply to all consumers at once.Next-run focus (R62)
Re-check
pkg/linters/doc.go's header count for further registry growth, then sweep remaining never-audited linters (hardcodedfilepath,sprintfbool,sprintferrdot,sprintferrorsnew,stringscountcontains,stringsindexhasprefix,timenowsub,trimleftright,uncheckedflushreturn,mapdeletecheck,logfatallibrary,httpstatuscode,excessivefuncparams) for pattern-set-too-narrow and autofix-compile-correctness issues, and verify aw_sg61a1 landed correctly.References:
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
api.anthropic.comTo allow these domains, add them to the
network.allowedlist in your workflow frontmatter:See Network Configuration for more information.
All reactions