Skip to content

[refactor] Semantic Function Clustering Analysis: pkg/workflow and pkg/cli #25620

@github-actions

Description

@github-actions

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:

  1. Issue-reporting safe outputs (missing_tool.go, missing_data.go, report_incomplete.go) → merge into missing_issue_reporting.go
  2. Label operations (add_labels.go, remove_labels.go) → merge into a single labels.go
  3. 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

  • Consolidate missing_tool.go + missing_data.go + report_incomplete.go into missing_issue_reporting.go
  • Consolidate add_labels.go + remove_labels.go into a single labels.go
  • Evaluate merging update_issue_helpers.go, update_discussion_helpers.go, update_pull_request_helpers.go type definitions into update_entity_helpers.go
  • Add cross-reference comments in WASM stub files pointing to canonical implementations
  • Split gateway_logs.go (1,332 lines) into types/parser/metrics/render sub-files

Generated by Semantic Function Refactoring · ● 568.7K ·

  • expires on Apr 12, 2026, 11:39 AM UTC

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions