[sergo] Sergo Report: Duplicate-Code Detection — 2026-04-25 #28493
Closed
Replies: 1 comment
-
|
This discussion has been marked as outdated by Sergo - Serena Go Expert. A newer discussion is available at Discussion #28632. |
Beta Was this translation helpful? Give feedback.
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.
-
Date: 2026-04-25
Strategy: Duplicate-Code Detection (new exploration)
Success Score: 7/10
Run ID: §24939819634
Executive Summary
Today's Sergo run performed a deep static analysis of
pkg/workflow/domains.go— the largest and most complex single file in the workflow package — using Serena's symbol search and pattern-matching tools. Two actionable code-quality issues were discovered and tracked as GitHub issues.The first finding is a clear-cut duplication:
extractOpenCodeProviderFromModelandextractCrushProviderFromModelare byte-for-byte identical functions that serve the same purpose for different engine types. The second finding is a systematic anti-pattern: the same 4-line "map-as-set → sorted slice" idiom is repeated 8 times in the same file, even though the idiomatic Go 1.23+ replacement (slices.Sorted(maps.Keys(...))) is already used elsewhere in the codebase.No existing open
sergoissues cover these patterns, so two new tracking issues were created.Serena Tools Update
Tools Snapshot
Tool Capabilities Used Today
activate_projectgh-awGo project for LSP analysisget_symbols_overviewfind_symbolfind_referencing_symbolssearch_for_patternlist_dirStrategy Selection
Cached Reuse Component (50%)
No prior cache — this is run #1. The 50% exploitation slot defaulted to the most universally applicable strategy: symbol-level duplication scan (looking for functions with identical signatures, similar names, or identical bodies).
New Exploration Component (50%)
Novel Approach: Pattern-based idiom detection in the largest file in
pkg/workflow/.search_for_patternwith regex for known Go idioms (make(map[string]bool),sort.Strings(,slices.Sorted(maps.Keys)pkg/workflow/domains.go(the file with the most distinct network-domain functions),pkg/sliceutil/sliceutil.go,pkg/workflow/map_helpers.go,pkg/workflow/agentic_engine.goCombined Strategy Rationale
Symbol-level search catches structural duplication (identical function bodies); pattern search catches syntactic idiom repetition. Together they cover both "two functions doing the same thing" and "the same boilerplate code repeated N times."
Analysis Execution
Codebase Context
pkg/workflow/(~500+ Go files)pkg/cli/,pkg/sliceutil/,pkg/actionpins/mapsandslicespackages fully available)modernize,intrange,exptostd,perfsprint,unconvert, and othersFindings Summary
Detailed Findings
Finding 1 — Duplicate
extractProviderFromModelFunctions (Medium)Location:
pkg/workflow/domains.go:190–199andpkg/workflow/domains.go:224–233extractOpenCodeProviderFromModelandextractCrushProviderFromModelare identical in every respect:Both were likely added independently when OpenCode and Crush engine support was introduced. A single
extractProviderFromModel(model string) stringshould replace both. The testTestExtractProviderFromModelincrush_engine_test.gotests only the Crush variant, leaving the OpenCode function untested for edge cases.Impact: Future changes (e.g., a different default for a new engine type) must be applied twice and can silently diverge.
Fix: See GitHub issue #aw_dup1.
Finding 2 — Repeated Map-to-Sorted-Slice Idiom (Medium)
Location:
pkg/workflow/domains.go, 8 occurrencesThe following 4-line block appears 8 times across different domain-aggregation functions:
The idiomatic Go 1.23+ replacement is already used in this codebase:
pkg/workflow/compiler_main_job.go:99—slices.Sorted(maps.Keys(data.Jobs))pkg/cli/run_workflow_validation.go:240—slices.Sorted(maps.Keys(workflowInputs))The
modernizelinter (enabled in.golangci.yml) targets exactly this kind of modernization.Impact: Verbose boilerplate on every new domain-aggregation function. Inconsistent style within the same module.
Fix: See GitHub issue #28492. Add
"maps"and"slices"todomains.goimports; replace each 4-line block withslices.Sorted(maps.Keys(domainMap)).Affected functions in domains.go
getEcosystemDomainsgetDomainsFromRuntimesGetAllowedDomainsGetBlockedDomainsGetAPITargetDomainsmergeAPITargetDomainsexpandAllowedDomains(×2)Improvement Tasks Generated
Task 1: Unify extractProviderFromModel
Issue Type: Symbol Duplication
Problem:
extractOpenCodeProviderFromModelandextractCrushProviderFromModelindomains.goare identical.Location:
pkg/workflow/domains.go:190–233Severity: Medium | Affected Files: 2 (
domains.go,crush_engine_test.go) | Effort: SmallBefore:
After:
Validation:
go test ./pkg/workflow/...passesgo build ./pkg/workflow/passesTask 2: Replace map-to-sorted-slice with slices.Sorted(maps.Keys(...))
Issue Type: Idiom Modernization
Problem: 8 repeated 4-line blocks in
domains.gothat themodernizelinter targets.Location:
pkg/workflow/domains.go(8 sites)Severity: Medium | Affected Files: 1 | Effort: Small
Before:
After:
Validation:
go test ./pkg/workflow/...passesgolangci-lint run ./pkg/workflow/shows no new warnings"sort"import removed fromdomains.goif no longer usedSuccess Metrics
This Run
Score Reasoning
domains.goand key utilities; did not scanpkg/cli/orpkg/parser/in depth.Cumulative Statistics (Run 1 of N)
Recommendations
Immediate Actions
extractOpenCodeProviderFromModel/extractCrushProviderFromModel→ singleextractProviderFromModel— tracked in issue #aw_dup1domains.gowithslices.Sorted(maps.Keys(...))— tracked in issue Replace repeated map-to-sorted-slice pattern in domains.go with slices.Sorted(maps.Keys(...)) #28492Long-term Improvements
gocriticlinter once golangci-lint v2 bugs are resolved — it would catch similar duplicate/copy-paste patterns automaticallysliceutilpackage'sDeduplicatefunction internally usesmap[T]bool; a future modernization could switch tomap[T]struct{}for zero-size values, though the benefit is minorNext Run Preview
Suggested Focus Areas
pkg/workflow/agentic_engine.go—GetAllAgentManifestFolders/GetAllAgentManifestFilesshare near-identical logic (collect engine files with deduplication); could share a helperpkg/cli/—context.Background()used inside functions that could accept a caller-provided context for better cancellation propagationpkg/workflow/compiler_orchestrator_*.go— phased compilation pipeline; check for error-wrapping consistency across the 5 orchestrator sub-filesStrategy Evolution
pkg/cli/+ new strategy targeting context propagation patterns (50% new exploration)References:
Beta Was this translation helpful? Give feedback.
All reactions