Repository navigation
[sergo] Sergo Report: New-Linter Day-One Audit + Clean Reconcile + Adjacency-Gap Probe - 2026-10-15 #68946
Closed
Replies: 1 comment
|
This discussion was automatically closed because it expired on 2026-10-16T04:02:13.947Z.
|
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Executive Summary
Run R97. Registry grew from 81 to 82 analyzers (
deferrerrorunchecked, PR #68780). Reconcile found all 3 pre-run open issues still accurate with zero reverse-phantoms -- the first fully-clean reconcile in several runs. Two new, independently-verified, non-duplicate issues were filed: a day-one diagnostic-duplication bug in the new 82nd linter, and a structurally distinct false-positive class ingoroutineresourceleak(81st linter) that R96 had flagged but not yet filed.Tool Updates
serena --helpreconfirmed the exact same tool list as prior runs).deferrerrorunchecked(packagepkg/linters/deferred-error-unchecked), introduced via PR [linter-miner] linter: add deferred-error-unchecked to detect unchecked deferred errors #68780 anddocs/adr/68780-add-deferred-error-unchecked-linter.md, authored by the linter-miner agentic workflow.doc.goalready correctly lists 82 active analyzers -- no doc-sync gap this time.Strategy: 50/50 Split
Cached component (50%) -- Reconcile + verify the 3 standing open issues against current code:
#68309(contextcancelnotdeferred wasm CI omission) -- re-checkedcgo.yml, still native-only, still accurate.#68590(resourcetracker Acquisitions-callback paren gap) -- re-readmanualmutexunlock.go:49, still a bareexprStmt.X.(*ast.CallExpr)with noUnwrapParenExpr, still accurate.#68591(goroutineresourceleak paren_unwrap_gap, 6 call sites) -- re-read the file, all 6 sites still unchanged, still accurate.Zero reverse-phantoms this run -- expected outcome was "confirm or refile"; actual outcome was "all 3 confirmed, nothing to refile."
New-exploration component (50%) -- Two angles per the registry delta and R96s own flagged next step:
deferrerrorunchecked, cross-checked against every existing Close()/defer-family linter (not just a syntactic self-audit).goroutineresourceleaks block-adjacency assumption incheckCancelLeak/checkMutexLeak.Target for the run: 1-3 distinct, code-verified findings; 1-3 non-duplicate issues; keep the reconcile pass honest (verify via code read, not just issue-label state).
Findings
Finding 1 --
deferrerroruncheckedfully duplicatesunchecked_deferredclose(new issue, ~50 affected sites)The new 82nd linter flags every bare
defer x.Method()whose last return iserror. This is the identical AST shape the existingunchecked_deferredcloselinter (PR #67481) already targets forClose()specifically. Both linters testdata assert on the exact same code pattern (defer f.Close(),defer c.Close(), etc.), so every matching site now gets two diagnostics with two different messages and needs two different(nolint/redacted)directives. The introducing ADR names this risk qualitatively but does not quantify it. A repo scan (excluding_test.goand lintertestdata/) found roughly 50 production call sites across 40+ files inpkg/cli,pkg/parser,pkg/workflow, andpkg/fileutilthat will double-report.Representative sites
pkg/parser/remote_client.go:102pkg/parser/remote_resolve_sha.go:192pkg/parser/remote_download_file.go:372pkg/fileutil/fileutil.gopkg/cli/audit_threat_detection.gopkg/cli/*.goandpkg/workflow/*.goFinding 2 --
goroutineresourceleakfalse-positives on a non-leaking statement before an eventual defer (new issue)checkCancelLeak/checkMutexLeakrequire the cleanup defer to be the literal next statement after the acquisition. Any intervening, non-control-flow statement (a log line, a bookkeeping call) between the acquisition and a later, still-unconditional defer trips a false leak report -- distinct from the already-correctly-flagged case where an early return genuinely skips the defer. This is latent (the linter is not yet CI-enforced) and absent from the current testdata fixture.Tasks Generated
deferrerroruncheckedvsunchecked_deferredclose-- either exclude the bare-Close() shape from the new linter (keeping only its genuinely new coverage), or retire the older linter now that the new one is a strict superset, with nolint-directive migration. Small effort.checkCancelLeak/checkMutexLeak-- keep scanning the rest of the block for a deferred cleanup instead of stopping at the first non-defer statement, while preserving the existing early-return detection. Small-medium effort.Metrics
Historical Context
This continues a long-running campaign (97 runs) focused on the in-house
pkg/linters/analyzer suite. A recurring theme --paren_unwrap_gap(missingParenExprunwrapping before an AST type assertion) -- has now been found and mostly fixed across more than a dozen linters and shared helpers. A second recurring theme,cross_linter_policy_contradiction, first identified at R93, has now recurred a second time: this run found that the Close()/defer/error semantics family has grown to 4 overlapping linters, with at least one pair now in full diagnostic duplication rather than mere disagreement. A new, third theme was named this run --adjacent_defer_assumption-- for block-scanning cleanup detectors that assume the deferred call is the literal next statement rather than scanning the rest of the block.Recommendations
deferinloop,wgdonenotdeferred,timeafterleak) now that the pattern has a name.Next-Run Focus
Verify both new issues land; re-tally open issues (expect 5 unless bulk-closed); if the registry grows to 83, audit the new linter fresh; otherwise probe
deferinloop/wgdonenotdeferred/timeafterleakfor theadjacent_defer_assumptionclass.References:
All reactions