You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This report analyzes all 155 non-test Go source files across 26 packages in internal/, cataloging 966 top-level function and method declarations. The codebase is generally well-organized, with clear package-level separation of concerns. Most findings are refinement opportunities rather than significant problems. Three clusters of interest emerged: scattered but thin format-helper patterns, a composable logging architecture that works correctly but has visible structural layering, and a few functions that could be consolidated or co-located more naturally.
Overlap: The regex-based ${VAR} substitution pattern is config-specific (fail-on-undefined semantics), so it is intentionally different from envutil's defaults. This is acceptable but worth documenting.
Recommendation: Add a package-level comment in config/expand.go explaining why it doesn't reuse envutil (different error semantics: undefined vars are fatal in config context). This prevents future contributors from questioning the apparent duplication.
2. Near-Duplicate: truncateAndSanitize in logger/rpc_format.go Is a Thin Wrapper
This is a two-line composition of sanitize.SanitizeString + util.Truncate. It is called within rpc_format.go only.
File: internal/logger/rpc_format.go (line 28)
Issue: Private wrapper adds an indirection layer with no additional logic. Callers could inline the two calls.
Recommendation: Inline the two calls at each usage site, or if the combination is needed elsewhere, promote it to internal/sanitize as sanitize.TruncateAndSanitize(s string, maxLen int) string.
Estimated Impact: Minor — reduces one private function, improves clarity.
3. Structural Pattern: Three Parallel logWithLevel* Dispatcher Functions
Observation: The logger package has three parallel dispatcher functions following the same structural pattern:
Function
File
Pattern
logWithLevel(level, category, format, args)
file_logger.go
dispatches to FileLogger.Log
logWithLevelAndServer(serverID, level, category, format, args)
server_file_logger.go
dispatches to ServerFileLogger.Log + unified log
logWithMarkdown(level, category, format, args)
markdown_logger.go
dispatches to logFuncs[level] + MarkdownLogger.Log
All three are used to build per-level exported functions (LogInfo, LogWarn, LogError, LogDebug and their variants) via newLevelLoggerFuncs / newServerLevelLoggerFuncs. The global_state.go comment notes this pattern explicitly.
Status: ✅ Already partially refactored — the shared newLogFuncSet generic eliminates structural duplication. The three dispatcher functions themselves are intentionally distinct (different signatures and side effects).
Recommendation: No immediate refactoring needed. Consider adding a single comment in global_state.go cross-referencing all three dispatchers to help future maintainers navigate the architecture.
Both ultimately call httputil.WriteErrorResponse, but with different signatures and side-effect responsibilities (server logs to markdown + runtime error; proxy also records a span). They are not consolidation candidates — the divergence is intentional and both are package-private.
Status: Acceptable divergence.
Recommendation: None required. The shared httputil.WriteErrorResponse already captures the common denominator.
5. Observation: internal/config/config_env.go Gateway Accessors Are Co-located with Parsing Logic
Observation: config_env.go contains both low-level env-parsing (parseAndValidateIntEnv) and high-level gateway config accessors (GetGatewayPortFromEnv, GetGatewayDomainFromEnv, etc.).
File: internal/config/config_env.go
Issue: The private parsing helper parseAndValidateIntEnv is used only by the public GetGateway* functions in the same file — this is fine. However, the mix of low-level parsing and high-level accessors in one file may confuse new contributors.
Recommendation: Consider renaming the file gateway_env.go to better reflect that it contains gateway-specific env var accessors, separating it conceptually from expand.go which handles JSON config expansion.
Status: ✅ Well-organized. Each file is cohesive within its package — httputil/tls.go has reusable builders, server/gateway_tls.go has the gateway-specific loader, proxy/tls.go has proxy-specific cert generation. No consolidation needed.
Recommendation: None required.
7. Cluster: Format Functions in difc/labels.go
Observation: internal/difc/labels.go (31 functions — the largest file) contains two private formatting helpers:
These are used only within FormatViolationError in the same file. They are reasonably placed.
Status: ✅ Acceptable. The functions are cohesive with their only caller.
Recommendation: If labels.go continues to grow, consider extracting FormatViolationError and its helpers into a dedicated violation_error.go file. Not urgent at current size.
Refactoring Recommendations
Priority 1: Low-effort, High-clarity
Add explanatory comment to config/expand.go explaining the intentional separation from envutil (different undefined-variable semantics). Prevents future confusion.
Effort: ~5 minutes
Consider renaming config/config_env.go → config/gateway_env.go to better signal that this file contains gateway-specific environment variable accessors.
Effort: ~10 minutes (rename + update any references)
Priority 2: Medium-term
Inline or promote truncateAndSanitize in logger/rpc_format.go. Either inline the two calls or move the composite to internal/sanitize if it becomes reused.
Effort: ~15 minutes
Add navigation comment in global_state.go cross-referencing the three logWith* dispatcher functions so maintainers can quickly find the trio.
Effort: ~5 minutes
Priority 3: Future Consideration
Extract FormatViolationError + helpers from difc/labels.go into difc/violation_error.go if the file continues to grow beyond its current 31 functions.
🔧 Semantic Function Clustering Analysis
Analysis of repository: github/gh-aw-mcpg
Overview
This report analyzes all 155 non-test Go source files across 26 packages in
internal/, cataloging 966 top-level function and method declarations. The codebase is generally well-organized, with clear package-level separation of concerns. Most findings are refinement opportunities rather than significant problems. Three clusters of interest emerged: scattered but thin format-helper patterns, a composable logging architecture that works correctly but has visible structural layering, and a few functions that could be consolidated or co-located more naturally.Function Inventory
Packages by File Count
internal/serverinternal/configinternal/loggerinternal/cmdinternal/mcpinternal/difcinternal/guardinternal/proxyinternal/tracinginternal/envutilinternal/githubhttpinternal/httputilinternal/launcherinternal/testutilinternal/utilIdentified Issues
1. Outlier:
config/expand.go— Env Expansion DuplicatesenvutilPatternsObservation:
internal/config/expand.goimplements its own${VAR_NAME}environment variable expansion usingos.LookupEnvdirectly. Meanwhile,internal/envutil/already provides a general-purpose env-var toolkit (GetEnvString,HasEnvVar, etc.).internal/config/expand.goexpandVariablesCore,expandVariables,ExpandRawJSONVariables,expandEnvVariables,expandMapInPlace,expandTracingVariables${VAR}substitution pattern is config-specific (fail-on-undefined semantics), so it is intentionally different from envutil's defaults. This is acceptable but worth documenting.config/expand.goexplaining why it doesn't reuseenvutil(different error semantics: undefined vars are fatal in config context). This prevents future contributors from questioning the apparent duplication.2. Near-Duplicate:
truncateAndSanitizeinlogger/rpc_format.goIs a Thin WrapperObservation:
internal/logger/rpc_format.godefines:This is a two-line composition of
sanitize.SanitizeString+util.Truncate. It is called withinrpc_format.goonly.internal/logger/rpc_format.go(line 28)internal/sanitizeassanitize.TruncateAndSanitize(s string, maxLen int) string.3. Structural Pattern: Three Parallel
logWithLevel*Dispatcher FunctionsObservation: The logger package has three parallel dispatcher functions following the same structural pattern:
logWithLevel(level, category, format, args)file_logger.goFileLogger.LoglogWithLevelAndServer(serverID, level, category, format, args)server_file_logger.goServerFileLogger.Log+ unified loglogWithMarkdown(level, category, format, args)markdown_logger.gologFuncs[level]+MarkdownLogger.LogAll three are used to build per-level exported functions (
LogInfo,LogWarn,LogError,LogDebugand their variants) vianewLevelLoggerFuncs/newServerLevelLoggerFuncs. Theglobal_state.gocomment notes this pattern explicitly.newLogFuncSetgeneric eliminates structural duplication. The three dispatcher functions themselves are intentionally distinct (different signatures and side effects).global_state.gocross-referencing all three dispatchers to help future maintainers navigate the architecture.4. Outlier:
rejectRequest(server) andrejectProxyRequest(proxy) — Parallel Rejection PatternsObservation: Two similar rejection helper functions exist in separate packages:
Both ultimately call
httputil.WriteErrorResponse, but with different signatures and side-effect responsibilities (server logs to markdown + runtime error; proxy also records a span). They are not consolidation candidates — the divergence is intentional and both are package-private.httputil.WriteErrorResponsealready captures the common denominator.5. Observation:
internal/config/config_env.goGateway Accessors Are Co-located with Parsing LogicObservation:
config_env.gocontains both low-level env-parsing (parseAndValidateIntEnv) and high-level gateway config accessors (GetGatewayPortFromEnv,GetGatewayDomainFromEnv, etc.).internal/config/config_env.goparseAndValidateIntEnvis used only by the publicGetGateway*functions in the same file — this is fine. However, the mix of low-level parsing and high-level accessors in one file may confuse new contributors.gateway_env.goto better reflect that it contains gateway-specific env var accessors, separating it conceptually fromexpand.gowhich handles JSON config expansion.6. Cluster: Three TLS Files Across Packages
Observation: TLS-related functions are spread across three files in different packages:
internal/httputil/tls.goTLSTrustEnvKeys,NewServerTLSConfig,NewClientTLSConfig,ConfigureTLSTrustEnvironmentinternal/server/gateway_tls.goLoadGatewayTLSinternal/proxy/tls.goGenerateSelfSignedTLS,randomSerial,writePEMhttputil/tls.gohas reusable builders,server/gateway_tls.gohas the gateway-specific loader,proxy/tls.gohas proxy-specific cert generation. No consolidation needed.7. Cluster: Format Functions in
difc/labels.goObservation:
internal/difc/labels.go(31 functions — the largest file) contains two private formatting helpers:formatIntegrityLevel(tags []Tag) string(line 435)formatSecrecyLevel(tags []Tag) string(line 468)These are used only within
FormatViolationErrorin the same file. They are reasonably placed.labels.gocontinues to grow, consider extractingFormatViolationErrorand its helpers into a dedicatedviolation_error.gofile. Not urgent at current size.Refactoring Recommendations
Priority 1: Low-effort, High-clarity
Add explanatory comment to
config/expand.goexplaining the intentional separation fromenvutil(different undefined-variable semantics). Prevents future confusion.Consider renaming
config/config_env.go→config/gateway_env.goto better signal that this file contains gateway-specific environment variable accessors.Priority 2: Medium-term
Inline or promote
truncateAndSanitizeinlogger/rpc_format.go. Either inline the two calls or move the composite tointernal/sanitizeif it becomes reused.Add navigation comment in
global_state.gocross-referencing the threelogWith*dispatcher functions so maintainers can quickly find the trio.Priority 3: Future Consideration
FormatViolationError+ helpers fromdifc/labels.gointodifc/violation_error.goif the file continues to grow beyond its current 31 functions.Analysis Metadata
truncateAndSanitizethin wrapper)References: §29285489446
Warning
Firewall blocked 1 domain
The following domain was blocked by the firewall during workflow execution:
awmgmcpgSee Network Configuration for more information.