Repository navigation
Sergo - Serena Go Expert #287
sergo.lock.yml
on: schedule
Annotations
9 errors, 3 warnings, and 2 notices
|
agent
TypeAssertExpr nodeFilter flagging single-value pointer-type assertions without ok-check; correctly defers x,_:=v.(T) (ok discarded via blank) to sibling typeassertionokdiscarded, confirmed via reading that linters isTwoValueBlankOkAssertion which flags any discarded-ok regardless of pointer-ness - not a gap, intentional division of labor, testdatas own goodTwoValueUnderscore comment is accurate. FOUND BUG: analyzeTypeAssert(62-75) does `typeAssert.Type.(*ast.StarExpr)` as a syntactic gate and returns early BEFORE pass.TypesInfo is ever consulted, so (a) a type alias to a pointer (type P = *T; v.(P)) is invisible despite go/types resolving P to *types.Pointer transparently, and (b) parenthesized pointer-type syntax v.((*T)) (valid per the assertion grammar Type=TypeLit|(Type)) is invisible since typeAssert.Type becomes *ast.ParenExpr - no UnwrapParenExpr call exists anywhere in the file. This is the FIRST instance of the established paren_unwrap_gap class applying to a Type position instead of a value expression. Zero testdata coverage for either shape, no live pointer-type-alias found via grep in pkg/ (latent), typeassertionnil absent from cgo.yml LINTER_FLAGS (not CI-enforced). gh api search/issues confirmed zero prior coverage before filing. Filed sg84a1. 1 issue this run (chose a single high-confidence new-linter finding over padding, consistent with the many prior single-issue runs when only one finding was strong). Serena 24 tools stable, activate_project OK go/typescript/bash, no approval prompts for Read/Grep/Glob/Edit/gh api/safeoutputs/serena CLI; raw Bash grep -c/wc -c/find on repo-memory path blocked outright (reconfirms Glob/Read/Edit-only access to /tmp/gh-aw/repo-memory, consistent with all prior runs). safeoutputs create_issue via single JSON-object-argument CLI form worked in ONE shot (~3.6KB body), zero apostrophes, bold headers, fenced go block, no approval prompt, no retry. NEXT R85: verify sg84a1 landed; re-tally 17 opens (16 above + sg84a1); if registry grows (76th) audit fresh, and treat a first-pass paren_unwrap_gap probe (bare *ast.BasicLit/*ast.Ident/*ast.CallExpr/*ast.StarExpr assertions without UnwrapParenExpr) as a standing day-one check for any newly-registered linter, since it has now independently recurred in 3 consecutive new-linter audits (R82 closeerrorunchecked, R84 typeassertionnil, plus the originally-discovered instances); check whether closeerrorunchecked(74th) or typeassertionnil(75th) land in cgo.yml LINTER_FLAGS.\"}\n{\"date\": \"2026-10-03\", \"strategy\": \"DELTA-75to76-newlinter-audit(fprintferrorunchecked:node_filter_too_narrow-at-938-occurrence-scale)+reconcile-reverse-phantom-refile(63342-main-guard-4th,63343-nilctxpassed-3rd)\", \"findings\": 5, \"tasks_created\": 3, \"success_score\": 9, \"notes\": \"R85: registry DELTA 75->76 (grep -c Analyzer,$ registry.go=76). 76th=fprintferrorunchecked (PR #65073, added 2026-10-02, first-ever audit, ALREADY CI-enforced natively+wasm from day one per cgo.yml:1487/1490). AssignStmt-only nodeFilter (fprintferrorunchecked.go:40) means a bare ExprStmt call like fmt.Fprintf(w,...) with no assignment at all completely escapes detection - this is in fact the single most common way these calls are written in this codebase: grep found 938 bare fmt.Fprintf/Fprintln/Fprint statement calls across 193 files in pkg/ alone, vs the explicit `_, _ = ` form the linter actually catches. Two concrete sites cited: pkg/console/confirm.go:53-56 (writes to an io.Writer parameter, e.g. os.Stdout in real callers) and pkg/workflow/workflow_errors.go:99. This is the node_filter_too_narrow class (previously filed against globwalkignorederror/strconvparseignorederror, #61265/#63094) but at an unprecedented scale - prior instances affected a handful of sites, this affects nearly a thousand. Filed sg85a1. gh api reconcile: fresh state=open+labels=sergo query returned only 14 opens vs the 17 memory expected after R84 - diffed via a separate state=closed query sorted by updated and found 3 issues auto-expired within the prior 24h: 63342(4-linter main-guard gap, lineag
|
|
agent
analyzeFuncBody ast.Inspect visits every BlockStmt/CaseClause/CommClause independently (line 52-63) and analyzeBlockStatements(line 72) only searches hasScannerErrCheck(stmts[i+1:]) within THAT SAME stmts slice (line 98) - a scanner.Err() check placed in an ENCLOSING block after an if/for/switch wrapping the scan loop lives in a different stmts slice and is invisible; matches the block_scope_state_reset class already catalogued from bufferresetbeforereuse one linter later. testdata badNestedBlock/goodNestedBlock only cover Err() check INSIDE the same if-block as the loop, never the enclosing-block case. Grepped every scanner.Scan()/scanner.Err() prod site in pkg/ (excl _test.go, ~20 sites across pkg/cli+pkg/parser+pkg/workflow) - ALL place loop+errcheck as direct top-level-function siblings, so 0 live FPs today (latent, same latency profile as sg61a1). receiverKey (line 227-250) recurses through arbitrarily-deep SelectorExpr chains keeping the ROOT idents types.Object fixed while accumulating path - CORRECTLY avoids the nested_selector_key_collapse class (sg62a1/#41376) that manualmutexunlock still has; audited-clean on that vein, better design than its predecessor. doc.go already documents 70th linter (no doc-sync gap); not yet in cgo.yml LINTER_FLAGS (not CI-enforced, pure diagnostic no SuggestedFix). Filed sg66a1=#aw_sg66a1 (block-scope Err()-check gap). Serena 24 tools STABLE. NEXT R67: verify sg66a1 landed; re-check the 5+1=6 opens (60367,60170,59875,59627,59122,+sg66a1); if registry grows again (71st) audit fresh; low-priority idea: probe bufioscannererunchecked isBufioScanner for wrapper-struct-embedding-bufio.Scanner blind spot (likely intentional scope limit, not filed).\"}"," {\"date\": \"2026-09-15\", \"strategy\": \"DELTA-70to71-newlinter-audit(blankassigncomma)+reconcile-reverse-phantom-refile(59122-closed-not_planned-bug-still-present)\", \"findings\": 5, \"tasks_created\": 2, \"success_score\": 9, \"notes\": \"R67: registry DELTA 70->71. 71st=blankassigncomma (PR #60893, 2026-09-14, no SuggestedFix, first-ever audit). gh api reconcile: #60557(sg65a1) confirmed CLOSED-COMPLETED (already fixed by R66). #59122 (nolint space-prefix, was open at R66) flipped to closed/not_planned (auto-expired) this run - re-read pkg/linters/internal/nolint/nolint.go:59-60 (strings.TrimPrefix(comment.Text,\\\"//\\\") then HasPrefix(text,\\\"nolint:\\\")) and confirmed the bug is STILL 100% present: a `// nolint:x` (single space) comment leaves a leading space after TrimPrefix and fails HasPrefix, silently dropping the directive from the index. This is the SECOND reverse-phantom-reconcile instance (closed but unfixed) after #58376/#60557 - re-filed as sg67a1. Full audit of blankassigncomma.go (stateless single-nodeFilter AssignStmt check, all-Lhs-blank with len>=2, properly wired to filecheck.ShouldSkipFilename + nolint.HasDirectiveForLinter, no scope-boundary/double-traversal/selector-collapse bug classes apply since it holds no state and does no ancestor walk): grepped every `_, _ = ` site in pkg/ (excl testdata/_test.go) and found 14 production matches, ALL deliberate idiomatic discards - pkg/console/spinner.go:208, pkg/workflow/maintenance_cron.go:46, pkg/workflow/compiler_yaml_main_job.go:37 (the PRs own cited motivating example), pkg/workflow/strings.go:174-175 (one line below an explicit comment: hash.Hash.Write never returns an error in practice, but check to satisfy gosec G104 - direct proof the pattern exists ONLY to satisfy a different linter), pkg/cli/outcome_eval_review.go:311, graders_run.go:365, update_extension_check.go:161, deps_outdated.go:181, deps_security.go:164, trial_repository.go:183 (explicit Ignore error comment), codemod_steps_run_secrets_env.go:450, docker_images.go:354, bootstrap_profile_github_app.go:284. Cross-referenced .golangci.yml:37 which disables errcheck repo-wide (exclude-functions broken in v2) - meaning `_, _ =` is this codebases MANUAL SUBSTITUTE for a broken exclude-list mechanism, and blankassigncomma (no allow-list of its own) directly re-flags the same pattern. NEW PATTERN CLASS adde
|
|
agent
isInsideLoop(69-83) classifies loop membership purely by AST node kind (ForStmt/RangeStmt/FuncLit via cur.Enclosing), never consulting pass.TypesInfo or rangeStmt.X's type. Since Go 1.23, ranging over a func value (iter.Seq-shaped) compiles the loop body to an implicit per-iteration function literal, so a defer inside it genuinely runs at the end of each iteration - the opposite of every other RangeStmt case and of this linter's own diagnostic text. Distinct from every other class in this file: those are about losing/merging/misreading STATE within an already-correctly-identified loop or branch; this one is about MISCLASSIFYING THE LOOP KIND ITSELF for want of type info, producing a false positive on a loop that was never the bug pattern at all. go.mod pins go 1.26.9 (fully capable); no live call site found yet (latent/forward-looking, same filing bar as sg90a1/sg91a1). PROBE any other AST-shape-only loop/scope classifier (ForStmt/RangeStmt treated as interchangeable) for the same blind spot if range-over-func adoption grows in this repo.\","," \"presnapshot_position_blind\": \"R79 #63768 lenstringzero: collectLenStringAliases builds ONE alias lookup map via a single whole-package ast.Inspect BEFORE run() analyzes any comparison, so the map holds only the FINAL state of each variable after all its later DEFINE/ASSIGN/IncDec/Range events have already been processed - not the state at each comparison's actual source position. Every comparison queries the same static post-collection map regardless of where it sits relative to a later mutation, so a variable aliased to len(s), used validly in an early comparison, and reassigned later in the same function has that early valid comparison retroactively blinded (false negative) even though it was correct at the time. Distinct from block_scope_state_reset (that class loses state too EARLY by resetting per nested block; this class keeps ONE state for too LONG - a single global snapshot with no per-position query at all) and from branch_state_merge (that class conflates sibling if/else branches within one flat map; this class conflates EARLIER and LATER source positions within a single linear scope). R80 #sg80a2 tolowerequalfold: collectCaseConvAliases (line 147) is structurally identical - one whole-file alias map built at line 41 before the separate BinaryExpr walk at line 47, with ASSIGN/IncDec/range-assign all deleting entries during the same collect pass, so an early valid ToLower/ToUpper alias comparison is blinded by a later same-scope reassignment. Confirms this is a recurring design flaw, not a one-off. R81: SWEEP COMPLETE on the remaining 4 candidates, ALL CLEAN. collectKnownPathConsts(hardcodedfilepath) collects package-scope CONSTANTS (fixed identity, immutable, immune by construction). collectPackageLevelSliceMapVars collects package-level VAR DECLARATIONS (fixed identity for the whole run, immune). seenmapbool's collectSeenMapCandidates/findNonSetMaps intentionally scans the whole function regardless of position since set-ness is a whole-lifetime property, not per-comparison-site - correct design. sprintfbool.collectSprintfBoolCandidates does a direct single-pass TypesInfo.TypeOf check, no alias pre-collection at all - immune. VEIN NOW EXHAUSTED at 2 confirmed instances (lenstringzero, tolowerequalfold); do not re-probe unless a new collect-then-query helper is added.\""," },"," \"ci_enforce_14\": \"cgo.yml LINTER_FLAGS -test=false (test-skip moot in CI): errstringmatch panicinlibrarycode manualmutexunlock osexitinlibrary rawloginlib regexpcompileinfunction fprintlnsprintf strconvparseignorederror jsonmarshalignoredeerror uncheckedtypeassertion fmterrorfnoverbs tolowerequalfold httpnoctx timeafterleak. NOT-enforced probe-targets: sprintferrdot fileclose contextcancel sprintferrorsnew lenstringzero seenmapbool ossetenvlibrary errorfwrapv excessivefuncparams largefunc deferinloop errormessage.\","]}],"userModified":false,"replaceAll":false}}
|
|
agent
isInsideLoop(69-83) classifies loop membership purely by AST node kind (ForStmt/RangeStmt/FuncLit via cur.Enclosing), never consulting pass.TypesInfo or rangeStmt.X's type. Since Go 1.23, ranging over a func value (iter.Seq-shaped) compiles the loop body to an implicit per-iteration function literal, so a defer inside it genuinely runs at the end of each iteration - the opposite of every other RangeStmt case and of this linter's own diagnostic text. Distinct from every other class in this file: those are about losing/merging/misreading STATE within an already-correctly-identified loop or branch; this one is about MISCLASSIFYING THE LOOP KIND ITSELF for want of type info, producing a false positive on a loop that was never the bug pattern at all. go.mod pins go 1.26.9 (fully capable); no live call site found yet (latent/forward-looking, same filing bar as sg90a1/sg91a1). PROBE any other AST-shape-only loop/scope classifier (ForStmt/RangeStmt treated as interchangeable) for the same blind spot if range-over-func adoption grows in this repo.\",\n \"presnapshot_position_blind\":"},"caller":{"type":"direct"}}],"container":null,"stop_reason":null,"stop_sequence":null,"stop_details":null,"usage":{"input_tokens":2,"cache_creation_input_tokens":1300,"cache_read_input_tokens":156382,"cache_creation":{"ephemeral_5m_input_tokens":1300,"ephemeral_1h_input_tokens":0},"output_tokens":3,"service_tier":"standard","inference_geo":"global"},"diagnostics":null,"context_management":null},"parent_tool_use_id":null,"session_id":"3d6176ab-a541-4240-a209-0724b22514a2","uuid":"10bb7d71-9fcf-4c09-9765-50530addae07","timestamp":"2026-10-10T04:01:15.454Z","request_id":"req_011CfstYtLJsFkg14Z3Nv6cP"}
|
|
agent
TypeAssertExpr nodeFilter flagging single-value pointer-type assertions without ok-check; correctly defers x,_:=v.(T) (ok discarded via blank) to sibling typeassertionokdiscarded, confirmed via reading that linters isTwoValueBlankOkAssertion which flags any discarded-ok regardless of pointer-ness - not a gap, intentional division of labor, testdatas own goodTwoValueUnderscore comment is accurate. FOUND BUG: analyzeTypeAssert(62-75) does `typeAssert.Type.(*ast.StarExpr)` as a syntactic gate and returns early BEFORE pass.TypesInfo is ever consulted, so (a) a type alias to a pointer (type P = *T; v.(P)) is invisible despite go/types resolving P to *types.Pointer transparently, and (b) parenthesized pointer-type syntax v.((*T)) (valid per the assertion grammar Type=TypeLit|(Type)) is invisible since typeAssert.Type becomes *ast.ParenExpr - no UnwrapParenExpr call exists anywhere in the file. This is the FIRST instance of the established paren_unwrap_gap class applying to a Type position instead of a value expression. Zero testdata coverage for either shape, no live pointer-type-alias found via grep in pkg/ (latent), typeassertionnil absent from cgo.yml LINTER_FLAGS (not CI-enforced). gh api search/issues confirmed zero prior coverage before filing. Filed sg84a1. 1 issue this run (chose a single high-confidence new-linter finding over padding, consistent with the many prior single-issue runs when only one finding was strong). Serena 24 tools stable, activate_project OK go/typescript/bash, no approval prompts for Read/Grep/Glob/Edit/gh api/safeoutputs/serena CLI; raw Bash grep -c/wc -c/find on repo-memory path blocked outright (reconfirms Glob/Read/Edit-only access to /tmp/gh-aw/repo-memory, consistent with all prior runs). safeoutputs create_issue via single JSON-object-argument CLI form worked in ONE shot (~3.6KB body), zero apostrophes, bold headers, fenced go block, no approval prompt, no retry. NEXT R85: verify sg84a1 landed; re-tally 17 opens (16 above + sg84a1); if registry grows (76th) audit fresh, and treat a first-pass paren_unwrap_gap probe (bare *ast.BasicLit/*ast.Ident/*ast.CallExpr/*ast.StarExpr assertions without UnwrapParenExpr) as a standing day-one check for any newly-registered linter, since it has now independently recurred in 3 consecutive new-linter audits (R82 closeerrorunchecked, R84 typeassertionnil, plus the originally-discovered instances); check whether closeerrorunchecked(74th) or typeassertionnil(75th) land in cgo.yml LINTER_FLAGS.\"}\n{\"date\": \"2026-10-03\", \"strategy\": \"DELTA-75to76-newlinter-audit(fprintferrorunchecked:node_filter_too_narrow-at-938-occurrence-scale)+reconcile-reverse-phantom-refile(63342-main-guard-4th,63343-nilctxpassed-3rd)\", \"findings\": 5, \"tasks_created\": 3, \"success_score\": 9, \"notes\": \"R85: registry DELTA 75->76 (grep -c Analyzer,$ registry.go=76). 76th=fprintferrorunchecked (PR #65073, added 2026-10-02, first-ever audit, ALREADY CI-enforced natively+wasm from day one per cgo.yml:1487/1490). AssignStmt-only nodeFilter (fprintferrorunchecked.go:40) means a bare ExprStmt call like fmt.Fprintf(w,...) with no assignment at all completely escapes detection - this is in fact the single most common way these calls are written in this codebase: grep found 938 bare fmt.Fprintf/Fprintln/Fprint statement calls across 193 files in pkg/ alone, vs the explicit `_, _ = ` form the linter actually catches. Two concrete sites cited: pkg/console/confirm.go:53-56 (writes to an io.Writer parameter, e.g. os.Stdout in real callers) and pkg/workflow/workflow_errors.go:99. This is the node_filter_too_narrow class (previously filed against globwalkignorederror/strconvparseignorederror, #61265/#63094) but at an unprecedented scale - prior instances affected a handful of sites, this affects nearly a thousand. Filed sg85a1. gh api reconcile: fresh state=open+labels=sergo query returned only 14 opens vs the 17 memory expected after R84 - diffed via a separate state=closed query sorted by updated and found 3 issues auto-expired within the prior 24h: 63342(4-linter main-guard gap, lineag
|
|
agent
analyzeFuncBody ast.Inspect visits every BlockStmt/CaseClause/CommClause independently (line 52-63) and analyzeBlockStatements(line 72) only searches hasScannerErrCheck(stmts[i+1:]) within THAT SAME stmts slice (line 98) - a scanner.Err() check placed in an ENCLOSING block after an if/for/switch wrapping the scan loop lives in a different stmts slice and is invisible; matches the block_scope_state_reset class already catalogued from bufferresetbeforereuse one linter later. testdata badNestedBlock/goodNestedBlock only cover Err() check INSIDE the same if-block as the loop, never the enclosing-block case. Grepped every scanner.Scan()/scanner.Err() prod site in pkg/ (excl _test.go, ~20 sites across pkg/cli+pkg/parser+pkg/workflow) - ALL place loop+errcheck as direct top-level-function siblings, so 0 live FPs today (latent, same latency profile as sg61a1). receiverKey (line 227-250) recurses through arbitrarily-deep SelectorExpr chains keeping the ROOT idents types.Object fixed while accumulating path - CORRECTLY avoids the nested_selector_key_collapse class (sg62a1/#41376) that manualmutexunlock still has; audited-clean on that vein, better design than its predecessor. doc.go already documents 70th linter (no doc-sync gap); not yet in cgo.yml LINTER_FLAGS (not CI-enforced, pure diagnostic no SuggestedFix). Filed sg66a1=#aw_sg66a1 (block-scope Err()-check gap). Serena 24 tools STABLE. NEXT R67: verify sg66a1 landed; re-check the 5+1=6 opens (60367,60170,59875,59627,59122,+sg66a1); if registry grows again (71st) audit fresh; low-priority idea: probe bufioscannererunchecked isBufioScanner for wrapper-struct-embedding-bufio.Scanner blind spot (likely intentional scope limit, not filed).\"}"]}],"userModified":false,"replaceAll":false,"contentNotInModelContext":true}}
|
|
detection
Process completed with exit code 1.
|
|
detection
ERR_SYSTEM: ❌ Detection result file not found at: /tmp/gh-aw/threat-detection/detection_result.json
|
|
detection
Process completed with exit code 2.
|
|
agent
Removed symbolic link before artifact upload: /tmp/gh-aw/latest
|
|
conclusion
Failed to post comment to detection runs issue: Commenting is disabled on issues with more than 2500 comments - https://docs.github.com/rest/issues/comments#create-an-issue-comment
|
|
conclusion
Threat detection produced no security verdict. Review the detection job logs before trusting the agent outputs.
|
|
agent
"The ubuntu-latest label will migrate to Ubuntu 26 beginning October 19, 2026. For more information, see https://github.com/actions/runner-images/issues/14748"
|
|
detection
"The ubuntu-latest label will migrate to Ubuntu 26 beginning October 19, 2026. For more information, see https://github.com/actions/runner-images/issues/14748"
|
Artifacts
Produced during runtime
| Name | Size | Digest | |
|---|---|---|---|
|
agent
|
1.2 MB |
sha256:fd378f5d1bfd4c12dce175ec1e23dac9be3cbdc44faa79f1e9dcba1a254dce32
|
|
|
agent-output-fallback
|
13.2 KB |
sha256:6c78281fd736952e9d807ad4282c9fdd9b015ef65899c45ffcb18c1bdb4ecfd6
|
|
|
detection
|
18 KB |
sha256:30a248879e906c1899bcd0607ef52f9d286c5c6ad03011f8812a13fe5bdf17a6
|
|
|
info
|
615 Bytes |
sha256:009adcb1102de525048a1381798b9449e5c064f1e1153d1a4d8eb5a90dd020d4
|
|
|
safe-outputs-items
|
631 Bytes |
sha256:5cf442a8a52d84d7c4988d210411774d257f2d86e249fb7e3c59512994d1301d
|
|
|
usage
|
117 KB |
sha256:6fe5621d05c7ee432a94ad6d2d02c7bd3b37d9a49111a7399f979b12d2c7e03a
|
|