Automated semantic function clustering analysis of 666 non-test Go source files across 20 packages. The analysis used naming patterns, file structure, and call-graph inspection to identify refactoring opportunities.
Executive Summary
- Files analyzed: 666 Go source files (no test files)
- Total functions cataloged: ~2,500 across all packages
- Packages inspected: 20 (
workflow, cli, parser, console, stringutil, and 15 utility packages)
- Key findings: 3 categories of actionable refactoring opportunities identified
Finding 1: Redundant Single-Function Wrapper Files in pkg/workflow/
Severity: Medium | Effort: Low
Three minimal files exist solely to call the shared parseIssueReportingConfig helper in missing_issue_reporting.go:
| File |
Lines |
Function |
pkg/workflow/missing_tool.go |
11 |
parseMissingToolConfig() |
pkg/workflow/missing_data.go |
11 |
parseMissingDataConfig() |
pkg/workflow/report_incomplete.go |
27 |
parseReportIncompleteConfig() |
Both missing_tool.go and missing_data.go are structurally identical — each declares a logger variable and one function that forwards to parseIssueReportingConfig with different string arguments:
// missing_tool.go
func (c *Compiler) parseMissingToolConfig(outputMap map[string]any) *MissingToolConfig {
return c.parseIssueReportingConfig(outputMap, "missing-tool", "[missing tool]", missingToolLog)
}
// missing_data.go
func (c *Compiler) parseMissingDataConfig(outputMap map[string]any) *MissingDataConfig {
return c.parseIssueReportingConfig(outputMap, "missing-data", "[missing data]", missingDataLog)
}
The backing type definitions (MissingDataConfig, MissingToolConfig) are already type aliases in missing_issue_reporting.go. These two functions (and the report_incomplete.go function) could live there directly, eliminating 2–3 small files without any functional change.
Recommendation: Consolidate parseMissingToolConfig, parseMissingDataConfig, and parseReportIncompleteConfig into missing_issue_reporting.go.
Finding 2: High File Fragmentation in pkg/workflow/ — 40+ Single-Function Files
Severity: Medium | Effort: Medium
The pkg/workflow/ package contains 322 files for ~1,607 functions (avg ~5 per file). Approximately 40 files contain a single exported or unexported function with ≤40 lines — a ratio indicating excessive fragmentation for a non-public internal package.
Sample of single-function thin files (≤40 lines)
| File |
Lines |
Purpose |
missing_data.go |
11 |
Wraps parseIssueReportingConfig |
missing_tool.go |
11 |
Wraps parseIssueReportingConfig |
label_command_parser.go |
19 |
Single parse function |
gemini_mcp.go |
21 |
Single MCP config function |
scripts.go |
22 |
Single script helper |
update_release.go |
24 |
Single update function |
secrets_validation.go |
26 |
Single validation |
set_issue_type.go |
26 |
Single config parser |
report_incomplete.go |
27 |
Wraps parseIssueReportingConfig |
add_labels.go |
29 |
Single config parser |
remove_labels.go |
29 |
Single config parser |
assign_milestone.go |
30 |
Single config parser |
update_issue_helpers.go |
36 |
Type + 1 function |
update_discussion_helpers.go |
~36 |
Type + 1 function |
update_pull_request_helpers.go |
~36 |
Type + 1 function |
Many of these files represent safe-output action parsers that follow an identical pattern: declare a logger, define a config type, and parse it with a generic base function. They are semantically related but live in separate files.
Potential consolidation groups:
- Issue-reporting safe outputs (
missing_tool.go, missing_data.go, report_incomplete.go) → merge into missing_issue_reporting.go
- Label operations (
add_labels.go, remove_labels.go) → merge into a single labels.go
- Update entity typed wrappers (
update_issue_helpers.go, update_discussion_helpers.go, update_pull_request_helpers.go) → merge types into a single update_entity_types.go, keeping the parser functions in update_entity_helpers.go
Note: The existing safe_outputs_*.go prefix cluster (20+ files) already applies a consistent naming convention — this is good organization and should be extended to the outlier action files.
Finding 3: Platform-Specific Function Stub Duplication (WASM Build Tags)
Severity: Low (Intentional Pattern) | Effort: Documentation
Seven file pairs use Go build tags to provide WASM stubs for platform-incompatible functions:
| Non-WASM file |
WASM stub file |
Duplicated signatures |
npm_validation.go |
npm_validation_wasm.go |
validateNpxPackages, isErrNpmNotAvailable |
pip_validation.go |
pip_validation_wasm.go |
validatePipPackages, validateUvPackages, validatePythonPackagesWithPip, validateUvPackagesWithPip |
docker_validation.go |
docker_validation_wasm.go |
(docker validation functions) |
repository_features_validation.go |
repository_features_validation_wasm.go |
validateRepositoryFeatures |
git_helpers.go |
git_helpers_wasm.go |
git helper functions |
github_cli.go |
github_cli_wasm.go |
GitHub CLI functions |
dependabot.go* |
dependabot_wasm.go |
dependabot functions |
This is intentional — Go's standard platform build tag pattern is correct here. However, the 4 pip validation functions duplicated in the WASM stub represent the highest maintenance surface. If any of these function signatures change, both files must be updated.
Recommendation: Add a code comment in each WASM stub file referencing the canonical non-WASM implementation, to reduce the risk of signature drift during refactoring.
Finding 4: Mixed Responsibilities in Large pkg/cli/gateway_logs.go
Severity: Low–Medium | Effort: Medium
pkg/cli/gateway_logs.go (1,332 lines) conflates four distinct responsibilities:
- Type definitions (lines 38–232):
GatewayLogEntry, GatewayMetrics, RPCMessageEntry, etc.
- Log parsing (lines 233–530):
parseRPCMessages, parseGatewayLogs
- Metrics computation (lines 531–875):
processGatewayLogEntry, calculateGatewayAggregates, getOrCreateServer
- Rendering (lines 699–1332):
renderGatewayMetricsTable, displayAggregatedGatewayMetrics, buildGuardPolicySummary
Existing neighboring files (gateway_*.go pattern is not used — files are prefixed audit_* and logs_*) suggest there's room for consistent decomposition.
Recommendation: Split into gateway_logs_types.go, gateway_logs_parser.go, gateway_logs_metrics.go, and gateway_logs_render.go, following the pattern already used for audit_*.go and logs_*.go files in the same package.
Analysis Metadata
- Total Go files analyzed: 666 (non-test)
- Packages inspected: 20
- Total functions cataloged: ~2,500 (
pkg/workflow: 1,607, pkg/cli: ~850, utilities: ~100)
- Single-function files in
pkg/workflow: ~40
- WASM stub file pairs: 7
- Detection method: Serena LSP semantic analysis + naming pattern analysis +
grep-based function inventory
- Workflow run: §24240825012
- Analysis date: 2026-04-10
Implementation Checklist
Generated by Semantic Function Refactoring · ● 568.7K · ◷
Automated semantic function clustering analysis of 666 non-test Go source files across 20 packages. The analysis used naming patterns, file structure, and call-graph inspection to identify refactoring opportunities.
Executive Summary
workflow,cli,parser,console,stringutil, and 15 utility packages)Finding 1: Redundant Single-Function Wrapper Files in
pkg/workflow/Severity: Medium | Effort: Low
Three minimal files exist solely to call the shared
parseIssueReportingConfighelper inmissing_issue_reporting.go:pkg/workflow/missing_tool.goparseMissingToolConfig()pkg/workflow/missing_data.goparseMissingDataConfig()pkg/workflow/report_incomplete.goparseReportIncompleteConfig()Both
missing_tool.goandmissing_data.goare structurally identical — each declares a logger variable and one function that forwards toparseIssueReportingConfigwith different string arguments:The backing type definitions (
MissingDataConfig,MissingToolConfig) are already type aliases inmissing_issue_reporting.go. These two functions (and thereport_incomplete.gofunction) could live there directly, eliminating 2–3 small files without any functional change.Recommendation: Consolidate
parseMissingToolConfig,parseMissingDataConfig, andparseReportIncompleteConfigintomissing_issue_reporting.go.Finding 2: High File Fragmentation in
pkg/workflow/— 40+ Single-Function FilesSeverity: Medium | Effort: Medium
The
pkg/workflow/package contains 322 files for ~1,607 functions (avg ~5 per file). Approximately 40 files contain a single exported or unexported function with ≤40 lines — a ratio indicating excessive fragmentation for a non-public internal package.Sample of single-function thin files (≤40 lines)
missing_data.goparseIssueReportingConfigmissing_tool.goparseIssueReportingConfiglabel_command_parser.gogemini_mcp.goscripts.goupdate_release.gosecrets_validation.goset_issue_type.goreport_incomplete.goparseIssueReportingConfigadd_labels.goremove_labels.goassign_milestone.goupdate_issue_helpers.goupdate_discussion_helpers.goupdate_pull_request_helpers.goMany of these files represent safe-output action parsers that follow an identical pattern: declare a logger, define a config type, and parse it with a generic base function. They are semantically related but live in separate files.
Potential consolidation groups:
missing_tool.go,missing_data.go,report_incomplete.go) → merge intomissing_issue_reporting.goadd_labels.go,remove_labels.go) → merge into a singlelabels.goupdate_issue_helpers.go,update_discussion_helpers.go,update_pull_request_helpers.go) → merge types into a singleupdate_entity_types.go, keeping the parser functions inupdate_entity_helpers.goNote: The existing
safe_outputs_*.goprefix cluster (20+ files) already applies a consistent naming convention — this is good organization and should be extended to the outlier action files.Finding 3: Platform-Specific Function Stub Duplication (WASM Build Tags)
Severity: Low (Intentional Pattern) | Effort: Documentation
Seven file pairs use Go build tags to provide WASM stubs for platform-incompatible functions:
npm_validation.gonpm_validation_wasm.govalidateNpxPackages,isErrNpmNotAvailablepip_validation.gopip_validation_wasm.govalidatePipPackages,validateUvPackages,validatePythonPackagesWithPip,validateUvPackagesWithPipdocker_validation.godocker_validation_wasm.gorepository_features_validation.gorepository_features_validation_wasm.govalidateRepositoryFeaturesgit_helpers.gogit_helpers_wasm.gogithub_cli.gogithub_cli_wasm.godependabot.go*dependabot_wasm.goThis is intentional — Go's standard platform build tag pattern is correct here. However, the 4 pip validation functions duplicated in the WASM stub represent the highest maintenance surface. If any of these function signatures change, both files must be updated.
Recommendation: Add a code comment in each WASM stub file referencing the canonical non-WASM implementation, to reduce the risk of signature drift during refactoring.
Finding 4: Mixed Responsibilities in Large
pkg/cli/gateway_logs.goSeverity: Low–Medium | Effort: Medium
pkg/cli/gateway_logs.go(1,332 lines) conflates four distinct responsibilities:GatewayLogEntry,GatewayMetrics,RPCMessageEntry, etc.parseRPCMessages,parseGatewayLogsprocessGatewayLogEntry,calculateGatewayAggregates,getOrCreateServerrenderGatewayMetricsTable,displayAggregatedGatewayMetrics,buildGuardPolicySummaryExisting neighboring files (
gateway_*.gopattern is not used — files are prefixedaudit_*andlogs_*) suggest there's room for consistent decomposition.Recommendation: Split into
gateway_logs_types.go,gateway_logs_parser.go,gateway_logs_metrics.go, andgateway_logs_render.go, following the pattern already used foraudit_*.goandlogs_*.gofiles in the same package.Analysis Metadata
pkg/workflow: 1,607,pkg/cli: ~850, utilities: ~100)pkg/workflow: ~40grep-based function inventoryImplementation Checklist
missing_tool.go+missing_data.go+report_incomplete.gointomissing_issue_reporting.goadd_labels.go+remove_labels.gointo a singlelabels.goupdate_issue_helpers.go,update_discussion_helpers.go,update_pull_request_helpers.gotype definitions intoupdate_entity_helpers.gogateway_logs.go(1,332 lines) into types/parser/metrics/render sub-files