Overview
Static analysis of 117 non-test Go source files containing 756 functions/methods across the internal/ directory. The codebase is generally well-organized with clear single-purpose files. Four concrete refactoring opportunities were identified, ranging from near-duplicate helpers to a structural pattern that could benefit from generics.
Function Inventory
| Package |
Files |
Primary Purpose |
internal/logger |
17 |
Multi-target logging (file, JSONL, markdown, tools, RPC) |
internal/server |
17 |
HTTP server, routing, session, auth, DIFC enforcement |
internal/difc |
9 |
Decentralized Information Flow Control labels/evaluation |
internal/config |
12 |
TOML/JSON config parsing and validation |
internal/cmd |
11 |
CLI commands and flags (Cobra) |
internal/mcp |
10 |
MCP protocol connection and types |
internal/guard |
7 |
Security guard interface, WASM, noop, write-sink |
internal/proxy |
7 |
GitHub API filtering proxy with DIFC |
internal/launcher |
4 |
Backend process management, health monitoring |
internal/testutil/mcptest |
4 |
Test utilities |
| Other packages |
19 |
auth, envutil, httputil, middleware, oidc, strutil, syncutil, sys, tracing, tty, version |
Identified Issues
1. marshalAndSanitizeForLog in Wrong Package
Severity: Low-medium
File: internal/server/tool_registry.go (line 352)
// server/tool_registry.go
func marshalAndSanitizeForLog(value interface{}) string {
resultJSON, _ := json.Marshal(value)
return sanitize.SanitizeString(string(resultJSON))
}
Issue: This unexported helper combines json.Marshal + sanitize.SanitizeString. A related function already lives in the logger package:
// logger/marshal_debug.go
func LogMarshaledForDebug(value interface{}, onMarshalSuccess func(string), onMarshalFailure func(error)) {
resultJSON, err := json.Marshal(value)
// ...only marshals, does NOT sanitize
}
marshalAndSanitizeForLog is used in two places in tool_registry.go for operational logging, but the marshal+sanitize pattern could be promoted to a public function in internal/logger or internal/logger/sanitize so other packages don't re-implement it.
Recommendation: Add MarshalAndSanitize(value interface{}) string to internal/logger/sanitize/sanitize.go and use it from both tool_registry.go and any future callers.
Estimated effort: ~30 min
Files affected: internal/server/tool_registry.go, internal/logger/sanitize/sanitize.go
2. generateRandomID() Duplicates strutil.RandomHex Pattern Without Centralizing Fallback
Severity: Low
File: internal/middleware/jqschema.go (line 116)
// middleware/jqschema.go
func generateRandomID() string {
id, err := strutil.RandomHex(16)
if err != nil {
// Fallback to a process- and time-based ID if random generation fails.
return fmt.Sprintf("fallback-%d-%d", os.Getpid(), time.Now().UnixNano())
}
return id
}
strutil.RandomHex and auth.GenerateRandomAPIKey both call crypto/rand but propagate the error. The middleware wrapper swallows the error with a deterministic fallback — a pattern not available in strutil.
Recommendation: Add RandomHexWithFallback(n int) string to internal/strutil/random_hex.go that encapsulates the fallback logic. The middleware can then remove its local wrapper:
// strutil/random_hex.go (proposed)
func RandomHexWithFallback(n int) string {
s, err := RandomHex(n)
if err != nil {
return fmt.Sprintf("fallback-%d-%d", os.Getpid(), time.Now().UnixNano())
}
return s
}
This makes the fallback pattern reusable and removes the middleware's dependency on os and time just for ID generation.
Estimated effort: ~20 min
Files affected: internal/strutil/random_hex.go, internal/middleware/jqschema.go
3. makeLevelLogger / makeServerLevelLogger Are Near-Identical Structural Patterns
Severity: Low (internal package detail)
File: internal/logger/common.go (lines 232–248)
func makeLevelLogger(
dispatch func(level LogLevel, category, format string, args ...interface{}),
level LogLevel,
) func(category, format string, args ...interface{}) {
return func(category, format string, args ...interface{}) {
dispatch(level, category, format, args...)
}
}
func makeServerLevelLogger(
dispatch func(serverID string, level LogLevel, category, format string, args ...interface{}),
level LogLevel,
) func(serverID, category, format string, args ...interface{}) {
return func(serverID, category, format string, args ...interface{}) {
dispatch(serverID, level, category, format, args...)
}
}
These two functions are structurally identical closures that fix the level parameter — the only difference is the presence of a leading serverID string argument. With Go 1.18+ generics already used elsewhere in the codebase (e.g., syncutil/cache.go, logger/global_helpers.go), this pattern is a candidate for a generic level-binder.
Recommendation: This is low priority because both functions are unexported and only used internally. Consider addressing during a dedicated logger refactor pass.
Estimated effort: ~1 hour (with full test coverage verification)
4. Logger Setup Pattern Repeated Across Four Files
Severity: Low (well-structured but verbose)
Files: internal/logger/file_logger.go, jsonl_logger.go, markdown_logger.go, tools_logger.go
Each logger follows an identical 3-function scaffold:
setup<X>Logger(file *os.File, logDir, fileName string) (*XLogger, error)
handle<X>LoggerError(err error, ...) (*XLogger, error)
Init<X>Logger(logDir, fileName string) error
The generic initLogger[T closableLogger] in common.go already partially unifies this. However, setup* and handle* still contain per-type boilerplate that varies only in the returned concrete type.
Note: This pattern is intentional and correct for separate log targets. The initLogger generic already handles the shared lifecycle. This is more of an observation than a blocker.
Recommendation: Consider defining a LoggerFactory[T closableLogger] interface or using function-value composition to further reduce boilerplate in future logger additions.
Estimated effort: ~2–3 hours
Files affected: All files in internal/logger/
Summary of Recommendations
| Priority |
Issue |
Effort |
Impact |
| 1 |
Promote marshalAndSanitizeForLog to sanitize package |
~30 min |
Prevents future re-implementation in other packages |
| 2 |
Add RandomHexWithFallback to strutil |
~20 min |
Centralizes fallback pattern |
| 3 |
Unify makeLevelLogger/makeServerLevelLogger with generics |
~1 hr |
Reduces internal boilerplate |
| 4 |
Reduce logger-setup boilerplate via factory pattern |
~2–3 hr |
Simplifies adding new log targets |
Implementation Checklist
Analysis Metadata
| Metric |
Value |
| Total Go files analyzed |
117 |
| Total functions/methods cataloged |
756 |
| Packages examined |
22 |
| Outliers (functions in wrong files) |
1 (marshalAndSanitizeForLog) |
| Near-duplicates detected |
2 (generateRandomID wrapping RandomHex; makeLevelLogger/makeServerLevelLogger) |
| Structural patterns flagged |
1 (logger setup boilerplate) |
| Detection method |
Static grep analysis + naming pattern clustering |
| Analysis date |
2026-04-28 |
References: §25048716374
Generated by Semantic Function Refactoring · ● 1.6M · ◷
Overview
Static analysis of 117 non-test Go source files containing 756 functions/methods across the
internal/directory. The codebase is generally well-organized with clear single-purpose files. Four concrete refactoring opportunities were identified, ranging from near-duplicate helpers to a structural pattern that could benefit from generics.Function Inventory
internal/loggerinternal/serverinternal/difcinternal/configinternal/cmdinternal/mcpinternal/guardinternal/proxyinternal/launcherinternal/testutil/mcptestIdentified Issues
1.
marshalAndSanitizeForLogin Wrong PackageSeverity: Low-medium
File:
internal/server/tool_registry.go(line 352)Issue: This unexported helper combines
json.Marshal+sanitize.SanitizeString. A related function already lives in the logger package:marshalAndSanitizeForLogis used in two places intool_registry.gofor operational logging, but the marshal+sanitize pattern could be promoted to a public function ininternal/loggerorinternal/logger/sanitizeso other packages don't re-implement it.Recommendation: Add
MarshalAndSanitize(value interface{}) stringtointernal/logger/sanitize/sanitize.goand use it from bothtool_registry.goand any future callers.Estimated effort: ~30 min
Files affected:
internal/server/tool_registry.go,internal/logger/sanitize/sanitize.go2.
generateRandomID()Duplicatesstrutil.RandomHexPattern Without Centralizing FallbackSeverity: Low
File:
internal/middleware/jqschema.go(line 116)strutil.RandomHexandauth.GenerateRandomAPIKeyboth callcrypto/randbut propagate the error. The middleware wrapper swallows the error with a deterministic fallback — a pattern not available instrutil.Recommendation: Add
RandomHexWithFallback(n int) stringtointernal/strutil/random_hex.gothat encapsulates the fallback logic. The middleware can then remove its local wrapper:This makes the fallback pattern reusable and removes the middleware's dependency on
osandtimejust for ID generation.Estimated effort: ~20 min
Files affected:
internal/strutil/random_hex.go,internal/middleware/jqschema.go3.
makeLevelLogger/makeServerLevelLoggerAre Near-Identical Structural PatternsSeverity: Low (internal package detail)
File:
internal/logger/common.go(lines 232–248)These two functions are structurally identical closures that fix the
levelparameter — the only difference is the presence of a leadingserverID stringargument. With Go 1.18+ generics already used elsewhere in the codebase (e.g.,syncutil/cache.go,logger/global_helpers.go), this pattern is a candidate for a generic level-binder.Recommendation: This is low priority because both functions are unexported and only used internally. Consider addressing during a dedicated logger refactor pass.
Estimated effort: ~1 hour (with full test coverage verification)
4. Logger Setup Pattern Repeated Across Four Files
Severity: Low (well-structured but verbose)
Files:
internal/logger/file_logger.go,jsonl_logger.go,markdown_logger.go,tools_logger.goEach logger follows an identical 3-function scaffold:
setup<X>Logger(file *os.File, logDir, fileName string) (*XLogger, error)handle<X>LoggerError(err error, ...) (*XLogger, error)Init<X>Logger(logDir, fileName string) errorThe generic
initLogger[T closableLogger]incommon.goalready partially unifies this. However,setup*andhandle*still contain per-type boilerplate that varies only in the returned concrete type.Note: This pattern is intentional and correct for separate log targets. The
initLoggergeneric already handles the shared lifecycle. This is more of an observation than a blocker.Recommendation: Consider defining a
LoggerFactory[T closableLogger]interface or using function-value composition to further reduce boilerplate in future logger additions.Estimated effort: ~2–3 hours
Files affected: All files in
internal/logger/Summary of Recommendations
marshalAndSanitizeForLogtosanitizepackageRandomHexWithFallbacktostrutilmakeLevelLogger/makeServerLevelLoggerwith genericsImplementation Checklist
sanitize.MarshalAndSanitize(value interface{}) stringtointernal/logger/sanitize/sanitize.gointernal/server/tool_registry.goto use the new functionstrutil.RandomHexWithFallback(n int) stringtointernal/strutil/random_hex.gointernal/middleware/jqschema.goto usestrutil.RandomHexWithFallbackmakeLevelLogger/makeServerLevelLoggerAnalysis Metadata
marshalAndSanitizeForLog)generateRandomIDwrappingRandomHex;makeLevelLogger/makeServerLevelLogger)References: §25048716374