Skip to content

[refactor] Semantic Function Clustering Analysis — Refactoring Opportunities #4645

Description

@github-actions

Overview

Automated semantic function clustering analysis of 109 non-test Go source files covering 746 functions across internal/. Three meaningful refactoring opportunities were identified: (1) a very large mcp/connection.go mixing multiple concerns, (2) JSON response-transform helpers embedded in proxy/handler.go, and (3) GitHub-specific utilities mixed into the generic httputil package. The rest of the codebase is well-organised with clear single-purpose files.


Function Inventory

Package Files Primary purpose
internal/auth 1 Auth header parsing
internal/cmd 8 CLI (Cobra flags, run logic)
internal/config 10 TOML/JSON config + validation
internal/difc 8 Information-flow labels + evaluator
internal/envutil 3 Environment variable helpers
internal/guard 6 Security guards (AllowOnly, WASM, etc.)
internal/httputil 1 HTTP utilities (mixed concerns — see below)
internal/launcher 4 Backend process management
internal/logger 13 Debug + file + RPC logging
internal/mcp 7 MCP protocol (connection + types)
internal/middleware 1 jq-schema middleware
internal/oidc 1 OIDC provider
internal/proxy 6 Reverse-proxy + DIFC filter
internal/server 12 HTTP server (routed/unified)
internal/strutil 4 String utilities
internal/syncutil 1 Generic sync cache
internal/sys 2 Docker / container detection
internal/testutil 4 Test helpers
internal/tracing 2 OpenTelemetry provider
internal/tty 1 TTY detection
internal/version 1 Version string

Identified Issues

1. mcp/connection.go — Oversized file with mixed concerns (HIGH)

File: internal/mcp/connection.go
Size: 749 lines, 34 functions

The file handles four distinct responsibilities:

Responsibility Example functions
Connection lifecycle NewConnection, NewHTTPConnection, Close, reconnectPlainJSON, reconnectSDKTransport
RPC method dispatch listTools, callTool, listResources, readResource, listPrompts, getPrompt
RPC logging logOutboundRPCRequest, logInboundRPCResponse, logInboundRPCResponseFromResult
Generic helpers paginateAll, listMCPItems, unmarshalParams, marshalToResponse, callParamMethod

Recommendation: Extract into three focused files:

internal/mcp/connection.go          ← lifecycle only (New*, reconnect*, Close, requireSession)
internal/mcp/connection_methods.go  ← listTools, callTool, listResources, etc.
internal/mcp/connection_logging.go  ← logOutboundRPCRequest, logInboundRPC*, logReconnect*

The generic pagination helpers (paginateAll, listMCPItems) could also move to a dedicated internal/mcp/pagination.go.

Estimated effort: 1–2 hours (mechanical file split, no logic changes)
Impact: Easier navigation and code review; each file has one reason to change


2. proxy/handler.go — JSON transform utilities mixed with HTTP handler (MEDIUM)

File: internal/proxy/handler.go
Size: 618 lines

The following functions are data-transformation utilities, not HTTP handlers:

// proxy/handler.go — candidates for extraction
func deepCloneJSON(v interface{}) interface{}
func rewrapSearchResponse(originalData interface{}, filteredItems interface{}) interface{}
func unwrapSingleObject(originalData interface{}, filteredData interface{}) interface{}
func replaceNodesArray(v interface{}, items []interface{}) bool
func rebuildGraphQLResponse(originalData interface{}, filtered *difc.FilteredCollectionLabeledData) interface{}

These five functions (~80 lines total) perform JSON deep-copy and response envelope reshaping for DIFC-filtered results. They are purely data-manipulation utilities embedded in the HTTP layer.

Recommendation: Move to a new file:

internal/proxy/response_transform.go  ← deepCloneJSON, rewrap*, unwrap*, replaceNodes*, rebuild*

deepCloneJSON is already called from proxy/proxy_test.go, and centralising all response-shaping helpers in one file makes the HTTP handler focused exclusively on request routing and forwarding.

Estimated effort: 30–60 minutes
Impact: handler.go becomes focused on HTTP dispatch; JSON helpers are discoverable and testable in isolation


3. httputil/httputil.go — GitHub-specific helpers mixed into generic HTTP utilities (MEDIUM)

File: internal/httputil/httputil.go (81 lines)

The file contains two distinct categories:

Generic HTTP GitHub-specific
WriteJSONResponse ApplyGitHubAPIHeaders
IsTransientHTTPError ParseRateLimitResetHeader

ApplyGitHubAPIHeaders sets Accept and Authorization headers following the GitHub API convention.
ParseRateLimitResetHeader parses the x-ratelimit-reset header used by the GitHub API.

Both belong conceptually with GitHub-specific HTTP logic (compare: internal/envutil/github.go which holds GitHub URL/token env helpers).

Recommendation: Split into two files:

internal/httputil/httputil.go        ← WriteJSONResponse, IsTransientHTTPError
internal/httputil/github_http.go     ← ApplyGitHubAPIHeaders, ParseRateLimitResetHeader

Estimated effort: 20–30 minutes
Impact: Clearer separation of generic and GitHub-specific HTTP utilities; follows existing envutil/github.go pattern in the project


What Looks Well-Organised ✓

  • internal/config/ — clearly split by concern (config_core, config_stdin, expand, validation, validation_schema, validation_env, guard_policy, rules/)
  • internal/difc/ — one file per concept (labels, evaluator, agent, capabilities, resource, tags, path_labels, pipeline_decisions)
  • internal/launcher/launcher.go (core) + log_helpers.go (logging methods) is a good pattern
  • internal/logger/ — well-stratified: file_logger, jsonl_logger, markdown_logger, rpc_logger, rpc_formatter, rpc_helpers, server_file_logger, tools_logger, session_helpers, global_helpers
  • internal/strutil/ and internal/syncutil/ — each file is a single focused utility
  • internal/guard/ — one file per guard type

Refactoring Recommendations

Priority Action Files Effort
1 🔴 Split mcp/connection.go by responsibility connection.go, new connection_methods.go, connection_logging.go 1–2 h
2 🟡 Extract JSON helpers from proxy/handler.go handler.go → new response_transform.go 30–60 min
3 🟡 Split GitHub-specific helpers out of httputil/httputil.go httputil.go → new github_http.go 20–30 min

Implementation Checklist

  • Split internal/mcp/connection.go into connection.go / connection_methods.go / connection_logging.go
  • Move JSON transform helpers from proxy/handler.go to new proxy/response_transform.go
  • Move ApplyGitHubAPIHeaders and ParseRateLimitResetHeader from httputil/httputil.go to new httputil/github_http.go
  • Run make agent-finished after each change to verify build + tests pass

Analysis Metadata

Total Go files analysed 109
Total functions catalogued 746
Function clusters identified 21 packages
Outlier files found 3
Exact duplicates detected 0
Detection method Naming-pattern clustering + call-scope analysis
Analysis date 2026-04-27

Generated by Semantic Function Refactoring · ● 800.3K ·

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions