Skip to content

[refactor] Semantic Function Clustering Analysis: Refactoring Opportunities #19876

@github-actions

Description

@github-actions

Automated semantic analysis of 552 non-test Go source files across pkg/ identified several refactoring opportunities ranging from critical file sprawl to minor consolidation wins.

Analysis Metadata

  • Total Go Files Analyzed: 552 non-test files
  • Packages Scanned: pkg/workflow/, pkg/cli/, pkg/stringutil/, pkg/constants/, pkg/console/, pkg/repoutil/, pkg/fileutil/, and 11 other utility packages
  • Detection Method: Serena semantic code analysis + naming pattern analysis
  • Workflow Run: §22773821538

Critical Findings

1. safe_outputs File Sprawl in pkg/workflow/

The safe_outputs subsystem is fragmented across 14 separate files with no clear ownership boundaries:

File Responsibility
safe_outputs.go Doc file only (8 lines)
safe_outputs_app.go GitHub App config parsing
safe_outputs_config.go Schema documentation (583 lines)
safe_outputs_config_generation.go Tool definition generation (599 lines)
safe_outputs_config_generation_helpers.go 12+ generation helper functions
safe_outputs_config_helpers.go Reflection-based field mapping (28 entries)
safe_outputs_config_messages.go Message config parsing
safe_outputs_domains_validation.go Domain validation
safe_outputs_env.go Environment variable helpers
safe_outputs_jobs.go Job configuration builder
safe_outputs_permissions.go Permission computation
safe_outputs_steps.go Step builders
safe_outputs_target_validation.go Target validation
safe_outputs_tools_generation.go Tool schema generation (572 lines)

Issue: Validation logic is split across safe_outputs_domains_validation.go and safe_outputs_target_validation.go. Config parsing is split across safe_outputs_config.go, safe_outputs_app.go, and safe_outputs_config_messages.go. Two overlapping helper files exist (safe_outputs_config_helpers.go and safe_outputs_config_generation_helpers.go).

Recommendation: Consolidate into 4–5 cohesive modules following the data-flow pattern:

safe_outputs_config.go       ← All config parsing (app + messages + target)
safe_outputs_validation.go   ← All validation (domains + target)
safe_outputs_generation.go   ← All generation + helpers (merge both helper files)
safe_outputs_jobs.go         ← Job building + permissions + steps + env

Estimated Impact: 14 files → 4–5 files, eliminates 3 redundant helper files.


2. Duplicated Logger Initialization Pattern Across 32+ Validation Files

Every *_validation.go file in pkg/workflow/ duplicates the same initialization line:

var engineValidationLog = logger.New("workflow:engine_validation")
var firewallValidationLog = logger.New("workflow:firewall_validation")
var dockerValidationLog = logger.New("workflow:docker_validation")
// ... repeated 30+ times

Recommendation: Extract a helper into validation_helpers.go:

func newValidationLogger(domain string) *logger.Logger {
    return logger.New("workflow:" + domain + "_validation")
}

Then each file becomes:

var engineValidationLog = newValidationLogger("engine")

Estimated Impact: ~30 lines of boilerplate removed; standardized logger naming.


3. codemod_permissions.go Violates Single-Responsibility Pattern

pkg/cli/codemod_permissions.go contains two independent codemods (getPermissionsReadCodemod() and getWritePermissionsCodemod()), while all 50+ other codemod files follow a strict one-codemod-per-file rule.

Recommendation: Split into codemod_permissions_read.go and codemod_permissions_write.go.

Estimated Impact: Low effort, improves consistency with the established codemod pattern.


Medium-Priority Findings

4. Duplicate String() and IsValid() Methods on Semantic Type Aliases in pkg/constants/

Five type aliases (Version, JobName, StepID, CommandPrefix, DocURL) each define identical method bodies:

func (v Version) String() string  { return string(v) }
func (v Version) IsValid() bool   { return v != "" }

func (j JobName) String() string  { return string(j) }
func (j JobName) IsValid() bool   { return j != "" }
// ... repeated 5 times

Recommendation: Consider using go:generate with a code generation approach, or document the intentional duplication with a comment. Alternatively, since Go doesn't support shared method sets for type aliases, add a comment to each grouping noting this is intentional boilerplate.

Estimated Impact: Clarity improvement; reduces confusion about whether these are truly distinct.


5. repoutil.SanitizeForFilename Misplaced

pkg/repoutil/repoutil.go contains SanitizeForFilename(slug string) string which converts / to - in repo slugs. This is a string transformation utility with no dependency on repository logic.

Recommendation: Move to pkg/stringutil/sanitize.go alongside SanitizeParameterName, SanitizePythonVariableName, and SanitizeToolID.

Estimated Impact: Better discoverability; repoutil becomes a pure slug-splitting utility.


6. Inconsistent Naming Convention in pkg/console/

The console package uses two different naming prefixes for its output functions with no clear semantic distinction:

  • Format* functions: FormatError, FormatSuccessMessage, FormatWarningMessage, FormatInfoMessage, FormatCommandMessage, FormatProgressMessage, FormatBanner
  • Render* functions: RenderStruct, RenderTable, RenderTitleBox, RenderErrorBox, RenderInfoSection, RenderTree

Recommendation: Establish a convention: Format* for functions that return strings, Render* for functions that write to output, or standardize on one prefix. Document the distinction in doc.go.


7. Scattered Error Type Definitions in pkg/workflow/

Error-related types and logic are spread across four files:

  • error_helpers.goWorkflowValidationError struct
  • error_aggregation.goErrorCollector multi-error type
  • shared_workflow_error.goSharedWorkflowError with custom message
  • frontmatter_error.go — YAML-specific error formatting with regex parsers

Recommendation: Consolidate error_helpers.go + error_aggregation.go + shared_workflow_error.go into a single workflow_errors.go. Keep frontmatter_error.go separate as it has domain-specific YAML parsing logic.

Estimated Impact: 3 files → 1 file; single place for error type definitions.


Low-Priority Observations

8. Large Flat MCP File Clusters (pkg/cli/)

The pkg/cli/ directory contains 64+ mcp_*.go files and 53+ logs_*.go files all in a flat directory structure. While naming conventions are consistent, the volume makes navigation difficult.

Observation: Consider whether Go subpackages (pkg/cli/mcp/, pkg/cli/logs/) would improve discoverability, weighing this against the refactoring cost and import changes required.


Refactoring Checklist

  • Consolidate 14 safe_outputs_* files into 4–5 cohesive modules
  • Extract newValidationLogger() helper to validation_helpers.go
  • Split codemod_permissions.go into codemod_permissions_read.go and codemod_permissions_write.go
  • Move repoutil.SanitizeForFilename to stringutil package
  • Consolidate error_helpers.go + error_aggregation.go + shared_workflow_error.go into workflow_errors.go
  • Establish and document Format* vs Render* naming convention in console package
  • Document intentional String()/IsValid() duplication in constants package

References:

Generated by Semantic Function Refactoring ·

  • expires on Mar 8, 2026, 5:17 PM UTC

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions