Skip to content

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

@github-actions

Description

@github-actions

Overview

Automated semantic function clustering analysis of 136 non-test Go files across internal/ (889 total functions). The codebase is generally well-organized; this report highlights the most actionable refactoring opportunities found.

Analysis Date: 2026-06-13
Files Analyzed: 136 (excluding *_test.go)
Functions Cataloged: 889
Packages Analyzed: 24 packages


Function Inventory by Package

Package Files Functions Notes
server 18 128 Largest package
config 14 118 Well split by concern
difc 10 116 Good separation
logger 14 102 Many specialized sub-files
mcp 9 71
guard 11 70
proxy 8 52
launcher 4 38
tracing 6 34
mcpresult 1 2 Very small package

Identified Issues

1. Rate-Limit Computation Function in Wrong File

Severity: Medium
Category: Outlier function

The function computeRetryAfter lives in internal/proxy/handler.go but is a pure stateless computation with no dependency on proxy-specific state. It belongs semantically alongside ParseRateLimitResetHeader in internal/httputil/github_http.go.

Current layout:

  • internal/httputil/github_http.go: ParseRateLimitResetHeader(value string) time.Time
  • internal/proxy/handler.go: computeRetryAfter(resetAt time.Time) int ← outlier
  • internal/proxy/handler.go: injectRetryAfterIfRateLimited(w, resp) ← already calls httputil.ParseRateLimitResetHeader

Affected code (internal/proxy/handler.go):

// computeRetryAfter returns the number of seconds to wait before retrying.
func computeRetryAfter(resetAt time.Time) int {
    const (
        defaultDelay = 60
        maxDelay     = 3600
    )
    if resetAt.IsZero() {
        return defaultDelay
    }
    secs := int(time.Until(resetAt).Seconds()) + 1
    if secs < 1 {
        return defaultDelay
    }
    if secs > maxDelay {
        return maxDelay
    }
    return secs
}

Recommendation: Move computeRetryAfter to internal/httputil/github_http.go, export it as ComputeRetryAfter, and update the caller in proxy/handler.go.
Estimated effort: 30 minutes
Benefits: All rate-limit timing utilities in one place; testable independently of proxy handler


2. mcpresult Package Is Very Small (Possible Consolidation)

Severity: Low
Category: Package size / scatter

internal/mcpresult/mcpresult.go is a single-file package with only 2 exported functions. While Go permits small packages, the functions operate on raw map[string]interface{} MCP content and are thematically related to internal/mcp/tool_result.go.

Current:

internal/mcpresult/mcpresult.go
  - NormalizeContentItems(contentVal interface{}) ([]map[string]interface{}, bool)
  - ExtractTextContent(result map[string]interface{}) string

Related in internal/mcp/tool_result.go:

  - ConvertToCallToolResult(data interface{}) (*sdk.CallToolResult, error)
  - convertMapToCallToolResult(m map[string]interface{}) (*sdk.CallToolResult, error)
  - BuildMCPTextResponse(text string) map[string]interface{}

Recommendation: Evaluate whether mcpresult functions can be merged into internal/mcp/ (checking for circular dependency risks first). If the mcp package already imports mcpresult, merging is not safe; if it doesn't, consolidation removes an unnecessary package boundary.
Estimated effort: 1-2 hours (including dependency audit and import updates)
Benefits: Reduced package count; co-located content normalization utilities


3. Logger init.go Contains Mixed Responsibilities

Severity: Low
Category: Function placement

internal/logger/init.go contains orchestration functions (InitGatewayLoggers, InitProxyLoggers) alongside two private helpers (initWithWarning, logFallbackWarnings). The helper logFallbackWarnings is also used by file_logger.go at initialization time, creating cross-file coupling within the same package.

Current init.go contents:

func InitGatewayLoggers(logDir string)        // calls 5 Init* functions
func InitProxyLoggers(logDir string)           // calls 3 Init* functions
func initWithWarning(err error, name string)   // private helper
func logFallbackWarnings(...)                  // private helper, also referenced by file_logger.go

Recommendation: Move initWithWarning and logFallbackWarnings to internal/logger/global_helpers.go (which already houses other shared logger utilities like CloseAllLoggers, withGlobalLogger, withMutexLock). This keeps init.go focused purely on the public orchestration API.
Estimated effort: 30 minutes
Benefits: Cleaner separation; all private helpers in one file


4. Near-Duplicate Rate-Limit Parsing Functions Across Packages

Severity: Low (different sources, different semantics — not true duplicates)
Category: Near-duplicate detection

Two functions parse GitHub rate-limit reset timing but from different sources:

Function Location Input Purpose
ParseRateLimitResetHeader httputil/github_http.go HTTP header (Unix timestamp string) Parses X-RateLimit-Reset header
parseRateLimitResetFromText server/rate_limit.go MCP tool result text body Parses "rate reset in Ns" text pattern

Both return time.Time. While they are not true duplicates (different inputs, different parsing logic), their existence in different packages could confuse contributors. Adding cross-reference comments would improve discoverability.

Recommendation: Add // See also: parseRateLimitResetFromText in server/rate_limit.go comments (and vice versa) to help contributors find related functions.
Estimated effort: 10 minutes
Benefits: Improved discoverability, prevents accidental re-implementation


5. httputil/endpoint_helpers.go — Micro-File (2 Functions)

Severity: Low
Category: File organization

internal/httputil/endpoint_helpers.go contains only 2 thin wrapper functions:

func WriteSimpleHealthResponse(w http.ResponseWriter)  // wraps WriteJSONResponse
func WriteReflectResponse(w http.ResponseWriter, ...)  // wraps WriteJSONResponse

While the file is justified by its architectural comment (ensuring consistent health endpoint interface), at 2 functions it adds file-navigation overhead.

Recommendation: Merge into internal/httputil/httputil.go. Keep the existing comments explaining the consistent health endpoint interface.
Estimated effort: 15 minutes
Benefits: Fewer files to navigate; httputil.go already contains the WriteJSONResponse they wrap


Well-Organized Areas (No Action Needed)

These patterns are correctly structured and should not be changed:

  • tty/tty.go + tty/tty_stub.go: Legitimate build-tag conditional compilation — not duplicates
  • server/response_writer.go embeds httputil/BaseResponseWriter: Correct composition pattern; server adds body capture + logging on top of base
  • config/expand.go variable expansion vs envutil/: Config expansion uses config-specific error types and semantics — appropriate separation
  • Logger quad-function pattern (LogInfo, LogWarn, LogError, LogDebug × 3 destinations): Intentional design using newLevelLoggerFuncs/newServerLevelLoggerFuncs generics
  • Guard package WASM split (wasm.go, wasm_parse.go, wasm_payload.go, wasm_validate.go): Each file has a clear single concern
  • server/difc_log.go: Bridge functions between server, DIFC, and logger — appropriate in server package

Refactoring Recommendations (Prioritized)

Priority 1: High Impact / Low Risk

# Action Files Effort
1 Move computeRetryAfterhttputil/github_http.go proxy/handler.go, httputil/github_http.go 30 min

Priority 2: Medium Impact / Low Risk

# Action Files Effort
2 Move initWithWarning/logFallbackWarningsglobal_helpers.go logger/init.go, logger/file_logger.go, logger/global_helpers.go 30 min
3 Merge endpoint_helpers.go functions into httputil.go httputil/endpoint_helpers.go, httputil/httputil.go 15 min

Priority 3: Requires Dependency Analysis

# Action Files Effort
4 Evaluate merging mcpresult/ into mcp/ package mcpresult/mcpresult.go, mcp/*.go 1-2 hours

Priority 4: Discoverability (Documentation Only)

# Action Files Effort
5 Add cross-reference comments for rate-limit parse functions httputil/github_http.go, server/rate_limit.go 10 min

Implementation Checklist

  • Review Priority 1: Move computeRetryAfter to httputil/github_http.go
  • Review Priority 2a: Move logger private helpers to global_helpers.go
  • Review Priority 2b: Merge endpoint_helpers.go into httputil.go
  • Review Priority 3: Audit circular deps before consolidating mcpresult
  • Review Priority 4: Add cross-reference comments for rate-limit parsers
  • Run make agent-finished after any changes to verify build/lint/tests pass

Analysis Metadata

  • Total Go Files Analyzed: 136 (excluding *_test.go)
  • Total Functions Cataloged: 889
  • Packages Analyzed: 24
  • Outliers Found: 1 high-confidence (computeRetryAfter), 3 low-confidence
  • Near-Duplicates Detected: 1 (rate-limit parsers, different semantics — not true duplicates)
  • Detection Method: Static function signature analysis + naming pattern clustering + cross-reference tracing
  • Workflow Run: §27479456845

References:

Generated by Semantic Function Refactoring · 423.4 AIC · ⊞ 36.4K ·

Metadata

Metadata

Assignees

No one assigned

    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