Documentation
¶
Overview ¶
Package analysis provides code analysis tools for Trace.
Description ¶
This package implements analysis tools for understanding code impact, including blast radius analysis which calculates the effect of changing a function or type on the rest of the codebase.
Thread Safety ¶
All analyzer types are safe for concurrent use.
Index ¶
- Constants
- Variables
- func GetChurnLevel(changesLast30Days int) string
- func IsHighConfidence(score ConfidenceScore) bool
- func IsLowConfidence(score ConfidenceScore) bool
- func IsMediumConfidence(score ConfidenceScore) bool
- type APIContract
- type APIDepEnricher
- type APIDepTracker
- func (t *APIDepTracker) AllDependencies() []APIDependency
- func (t *APIDepTracker) Contracts() []APIContract
- func (t *APIDepTracker) FindEndpointUsages(endpoint string) ([]APIDependency, error)
- func (t *APIDepTracker) FindSymbolDependencies(symbolID string) ([]APIDependency, error)
- func (t *APIDepTracker) Scan(ctx context.Context) error
- type APIDependency
- type APIType
- type AnalyzeOptions
- type BlastRadius
- type BlastRadiusAnalyzer
- type Caller
- type ChangeClassifier
- func (c *ChangeClassifier) ClassifyChangeType(oldSymbol, newSymbol *ast.Symbol) (changeType string, impact string)
- func (c *ChangeClassifier) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
- func (c *ChangeClassifier) Name() string
- func (c *ChangeClassifier) Priority() int
- type ChangeImpact
- type ChurnAnalyzer
- type ChurnScore
- type CodeOwnerRule
- type ConfidenceCalculator
- type ConfidenceScore
- type ConfigDepEnricher
- type ConfigDepTracker
- func (t *ConfigDepTracker) AllDependencies() []ConfigDependency
- func (t *ConfigDepTracker) ConfigKeys() []string
- func (t *ConfigDepTracker) FindConfigUsages(key string) ([]ConfigDependency, error)
- func (t *ConfigDepTracker) FindSymbolDependencies(symbolID string) ([]ConfigDependency, error)
- func (t *ConfigDepTracker) Scan(ctx context.Context) error
- type ConfigDependency
- type ConfigType
- type ContractEndpoint
- type CoverageCorrelator
- func (c *CoverageCorrelator) CalculateCoverageRisk(br *EnhancedBlastRadius) CoverageRisk
- func (c *CoverageCorrelator) GetCoverage(symbolID string) (*CoverageInfo, error)
- func (c *CoverageCorrelator) GetUntestedBlastRadius(br *BlastRadius) []string
- func (c *CoverageCorrelator) GetUntestedEnhancedBlastRadius(br *EnhancedBlastRadius) []Caller
- func (c *CoverageCorrelator) Stats() CoverageStats
- type CoverageEnricher
- type CoverageInfo
- type CoverageRisk
- type CoverageStats
- type DeadCodeDetector
- type DeadCodeDetectorOption
- type DeadCodeEnricher
- type DeadCodeInfo
- type DeadCodeResult
- type DeadSymbol
- type EnhancedAnalyzer
- func (a *EnhancedAnalyzer) Analyze(ctx context.Context, targetID string, opts *AnalyzeOptions) (*EnhancedBlastRadius, error)
- func (a *EnhancedAnalyzer) GetBaseAnalyzer() *BlastRadiusAnalyzer
- func (a *EnhancedAnalyzer) GetGraph() *graph.Graph
- func (a *EnhancedAnalyzer) GetIndex() *index.SymbolIndex
- func (a *EnhancedAnalyzer) GetRegistry() *EnricherRegistry
- func (a *EnhancedAnalyzer) GetRepoPath() string
- func (a *EnhancedAnalyzer) GetTimeout() time.Duration
- func (a *EnhancedAnalyzer) SetTimeout(d time.Duration)
- type EnhancedAnalyzerOption
- func WithEnrichmentTimeout(d time.Duration) EnhancedAnalyzerOption
- func WithGraph(g *graph.Graph) EnhancedAnalyzerOption
- func WithIndex(idx *index.SymbolIndex) EnhancedAnalyzerOption
- func WithInputValidator(v *validation.InputValidator) EnhancedAnalyzerOption
- func WithRepoPath(path string) EnhancedAnalyzerOption
- type EnhancedBlastRadius
- type Enricher
- type EnricherRegistry
- type EnricherResult
- type EnrichmentTarget
- type Implementer
- type IrreversibleChange
- type IrreversibleChangeType
- type Ownership
- type OwnershipResolver
- type PredictiveEnricher
- type PredictiveRisk
- type PredictiveRiskFactor
- type PredictiveRiskLevel
- type PredictiveRiskScorer
- func (p *PredictiveRiskScorer) CalculateRisk(ctx context.Context, symbolID string) (*PredictiveRisk, error)
- func (p *PredictiveRiskScorer) LoadBugHistory(history map[string]int)
- func (p *PredictiveRiskScorer) LoadChurnScores(scores map[string]float64)
- func (p *PredictiveRiskScorer) RegisterBug(symbolID string)
- func (p *PredictiveRiskScorer) UpdateChurnScore(symbolID string, rate float64)
- type RiskConfig
- type RiskFactor
- type RiskLevel
- type RollbackEnricher
- type RollbackRisk
- type RollbackRiskAssessor
- type RollbackRiskLevel
- type SQLOperation
- type SchemaDepEnricher
- type SchemaDepTracker
- func (t *SchemaDepTracker) AllDependencies() []SchemaDependency
- func (t *SchemaDepTracker) FindSymbolDependencies(symbolID string) ([]SchemaDependency, error)
- func (t *SchemaDepTracker) FindTableUsages(tableName string) ([]SchemaDependency, error)
- func (t *SchemaDepTracker) Scan(ctx context.Context) error
- func (t *SchemaDepTracker) Tables() []string
- type SchemaDependency
- type SecurityPath
- type SecurityPathDetector
- func (d *SecurityPathDetector) AddPattern(pathType, pattern string) error
- func (d *SecurityPathDetector) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
- func (d *SecurityPathDetector) GetPatterns() map[string][]string
- func (d *SecurityPathDetector) Name() string
- func (d *SecurityPathDetector) Priority() int
- type SharedDep
Constants ¶
const ( DeadReasonNoCallers = "no_callers" DeadReasonNoReferences = "no_references" DeadReasonTestOnly = "test_only" DeadReasonUnreachable = "unreachable" )
DeadCodeReason constants explain why code is considered dead.
const ( // ImpactBreaking means callers/implementers must be updated. ImpactBreaking = "BREAKING" // ImpactCompatible means existing code continues to work. ImpactCompatible = "COMPATIBLE" // ImpactSafe means no external changes needed. ImpactSafe = "SAFE" )
Change impact severity constants.
const ( // ConfidenceHigh means >= 90% confidence. ConfidenceHigh = "HIGH" // ConfidenceMedium means 70-89% confidence. ConfidenceMedium = "MEDIUM" // ConfidenceLow means < 70% confidence. ConfidenceLow = "LOW" )
Confidence level constants.
const ( // SecurityPathAuth is for authentication code. SecurityPathAuth = "AUTH" // SecurityPathAuthz is for authorization code. SecurityPathAuthz = "AUTHZ" // SecurityPathPII is for PII handling code. SecurityPathPII = "PII" // SecurityPathCrypto is for cryptographic code. SecurityPathCrypto = "CRYPTO" // SecurityPathSecrets is for secret/credential handling. SecurityPathSecrets = "SECRETS" )
SecurityPathType constants.
const ( // ChurnLevelLow is < 3 changes in 30 days. ChurnLevelLow = "LOW" // ChurnLevelModerate is 3-9 changes in 30 days. ChurnLevelModerate = "MODERATE" // ChurnLevelHigh is 10+ changes in 30 days. ChurnLevelHigh = "HIGH" )
ChurnLevel constants.
const MaxCoverageFileSize = 50 * 1024 * 1024 // 50MB
MaxCoverageFileSize is the maximum size of coverage files to parse.
Variables ¶
var ( // ErrNilContext is returned when a nil context is passed to an analysis function. ErrNilContext = errors.New("context must not be nil") // ErrSymbolNotFound is returned when a symbol cannot be found in the graph. ErrSymbolNotFound = errors.New("symbol not found in graph") // ErrGraphNotReady is returned when the graph is not in a frozen state. ErrGraphNotReady = errors.New("graph is not frozen") // ErrAnalysisTimeout is returned when analysis exceeds the time limit. ErrAnalysisTimeout = errors.New("analysis timeout") // ErrInvalidSymbolID is returned when a symbol ID is invalid. ErrInvalidSymbolID = errors.New("invalid symbol ID") )
Analysis errors.
var ConfidenceThresholds = struct { High int Medium int }{ High: 90, Medium: 70, }
ConfidenceThresholds defines threshold values for confidence levels.
var DefaultSecurityPatterns = map[string][]string{
SecurityPathAuth: {
"(?i)login",
"(?i)logout",
"(?i)authenticate",
"(?i)validatetoken",
"(?i)verifytoken",
"(?i)session",
"(?i)signin",
"(?i)signout",
"(?i)oauth",
"(?i)oidc",
"(?i)saml",
"(?i)jwt",
"(?i)refreshtoken",
"(?i)accesstoken",
},
SecurityPathAuthz: {
"(?i)authorize",
"(?i)permission",
"(?i)role",
"(?i)access",
"(?i)canuser",
"(?i)isallowed",
"(?i)hasperm",
"(?i)checkaccess",
"(?i)acl",
"(?i)rbac",
"(?i)policy",
},
SecurityPathPII: {
"(?i)email",
"(?i)phone",
"(?i)address",
"(?i)ssn",
"(?i)creditcard",
"(?i)password",
"(?i)secret",
"(?i)birthdate",
"(?i)socialsecurity",
"(?i)personalinfo",
"(?i)userdata",
"(?i)pii",
},
SecurityPathCrypto: {
"(?i)encrypt",
"(?i)decrypt",
"(?i)hash",
"(?i)sign",
"(?i)verify",
"(?i)hmac",
"(?i)aes",
"(?i)rsa",
"(?i)sha256",
"(?i)sha512",
"(?i)bcrypt",
"(?i)argon",
"(?i)pbkdf",
"(?i)cipher",
},
SecurityPathSecrets: {
"(?i)apikey",
"(?i)token",
"(?i)credential",
"(?i)secret",
"(?i)private",
"(?i)privatekey",
"(?i)secretkey",
"(?i)masterkey",
"(?i)passphrase",
"(?i)vault",
},
}
DefaultSecurityPatterns provides standard patterns for security detection.
Pattern Categories ¶
- AUTH: Authentication (login, logout, token validation, sessions)
- AUTHZ: Authorization (permissions, roles, access control)
- PII: Personal identifiable information handling
- CRYPTO: Cryptographic operations
- SECRETS: Secret and credential handling
Functions ¶
func GetChurnLevel ¶
GetChurnLevel returns the churn level for a given change count.
func IsHighConfidence ¶
func IsHighConfidence(score ConfidenceScore) bool
IsHighConfidence returns true if confidence is >= 90%.
func IsLowConfidence ¶
func IsLowConfidence(score ConfidenceScore) bool
IsLowConfidence returns true if confidence is < 70%.
func IsMediumConfidence ¶
func IsMediumConfidence(score ConfidenceScore) bool
IsMediumConfidence returns true if confidence is 70-89%.
Types ¶
type APIContract ¶
type APIContract struct {
// Path is the file path of the contract.
Path string `json:"path"`
// Type is the contract type (openapi, graphql, protobuf).
Type string `json:"type"`
// Version is the API version (if specified).
Version string `json:"version,omitempty"`
// Endpoints are the defined endpoints.
Endpoints []ContractEndpoint `json:"endpoints"`
}
APIContract represents a parsed API contract file.
type APIDepEnricher ¶
type APIDepEnricher struct {
// contains filtered or unexported fields
}
APIDepEnricher implements Enricher for API dependency tracking.
func NewAPIDepEnricher ¶
func NewAPIDepEnricher(projectRoot string, g *graph.Graph, idx *index.SymbolIndex) *APIDepEnricher
NewAPIDepEnricher creates an enricher for API dependencies.
func (*APIDepEnricher) Enrich ¶
func (e *APIDepEnricher) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
Enrich adds API dependency information to the blast radius.
func (*APIDepEnricher) Invalidate ¶
func (e *APIDepEnricher) Invalidate()
Invalidate forces a rescan on next enrichment.
func (*APIDepEnricher) Name ¶
func (e *APIDepEnricher) Name() string
Name returns the enricher name.
func (*APIDepEnricher) Priority ¶
func (e *APIDepEnricher) Priority() int
Priority returns execution priority.
type APIDepTracker ¶
type APIDepTracker struct {
// contains filtered or unexported fields
}
APIDepTracker tracks external API dependencies in code.
Description ¶
Detects HTTP client calls, OpenAPI/Swagger references, GraphQL operations, and gRPC service calls. Maps these to symbols to understand the external API blast radius of changes.
Thread Safety ¶
Safe for concurrent use after construction.
func NewAPIDepTracker ¶
func NewAPIDepTracker(projectRoot string, g *graph.Graph, idx *index.SymbolIndex) *APIDepTracker
NewAPIDepTracker creates a new API dependency tracker.
Inputs ¶
- projectRoot: Root directory of the project.
- g: The dependency graph.
- idx: The symbol index.
Outputs ¶
- *APIDepTracker: Ready-to-use tracker.
func (*APIDepTracker) AllDependencies ¶
func (t *APIDepTracker) AllDependencies() []APIDependency
AllDependencies returns all detected API dependencies.
func (*APIDepTracker) Contracts ¶
func (t *APIDepTracker) Contracts() []APIContract
Contracts returns all parsed API contracts.
func (*APIDepTracker) FindEndpointUsages ¶
func (t *APIDepTracker) FindEndpointUsages(endpoint string) ([]APIDependency, error)
FindEndpointUsages returns all code locations that call an endpoint.
func (*APIDepTracker) FindSymbolDependencies ¶
func (t *APIDepTracker) FindSymbolDependencies(symbolID string) ([]APIDependency, error)
FindSymbolDependencies returns all API dependencies for a symbol.
type APIDependency ¶
type APIDependency struct {
// Endpoint is the API endpoint (URL path or service method).
Endpoint string `json:"endpoint"`
// Method is the HTTP method (GET, POST, etc.) or RPC method.
Method string `json:"method"`
// Type is the API type (REST, GraphQL, gRPC).
Type APIType `json:"type"`
// SourceSymbol is the symbol containing this dependency.
SourceSymbol string `json:"source_symbol"`
// FilePath is the file containing the dependency.
FilePath string `json:"file_path"`
// Line is the line number of the dependency.
Line int `json:"line"`
// ServiceName is the external service name (if detectable).
ServiceName string `json:"service_name,omitempty"`
// Contract is the API contract reference (if any).
Contract string `json:"contract,omitempty"`
// Confidence is how confident we are in this detection (0-100).
Confidence int `json:"confidence"`
}
APIDependency represents an external API dependency from code.
type AnalyzeOptions ¶
type AnalyzeOptions struct {
MaxDirectCallers int `json:"max_direct_callers"`
MaxIndirectCallers int `json:"max_indirect_callers"`
MaxHops int `json:"max_hops"`
Timeout time.Duration `json:"timeout"`
TestPatterns []string `json:"test_patterns"`
TestDirs []string `json:"test_dirs"`
}
AnalyzeOptions configures the blast radius analysis.
Fields ¶
- MaxDirectCallers: Stop expanding direct callers after this limit.
- MaxIndirectCallers: Total indirect caller limit.
- MaxHops: How far to trace indirect callers (default 3).
- Timeout: Maximum analysis time.
- TestPatterns: Glob patterns for test files (default ["*_test.go"]).
- TestDirs: Additional directories to search for tests.
func DefaultAnalyzeOptions ¶
func DefaultAnalyzeOptions() AnalyzeOptions
DefaultAnalyzeOptions returns options with sensible defaults.
type BlastRadius ¶
type BlastRadius struct {
Target string `json:"target"`
RiskLevel RiskLevel `json:"risk_level"`
DirectCallers []Caller `json:"direct_callers"`
IndirectCallers []Caller `json:"indirect_callers"`
Implementers []Implementer `json:"implementers,omitempty"`
FilesAffected []string `json:"files_affected"`
TestFiles []string `json:"test_files"`
Summary string `json:"summary"`
Recommendation string `json:"recommendation"`
Truncated bool `json:"truncated,omitempty"`
TruncatedReason string `json:"truncated_reason,omitempty"`
}
BlastRadius contains the analysis results for a potential change.
Description ¶
Provides comprehensive information about what would be affected if the target symbol is modified. Used by agents to make informed decisions before generating patches.
Fields ¶
- Target: The symbol being analyzed (function, type, etc.).
- RiskLevel: Overall risk assessment.
- DirectCallers: Functions that directly call the target.
- IndirectCallers: Functions that call functions that call the target.
- Implementers: Types implementing an interface (if target is interface).
- SharedDeps: Dependencies shared by target and its callers.
- FilesAffected: Unique files that may need changes.
- TestFiles: Test files that should be run.
- Summary: Human-readable summary.
- Recommendation: Actionable advice.
type BlastRadiusAnalyzer ¶
type BlastRadiusAnalyzer struct {
// contains filtered or unexported fields
}
BlastRadiusAnalyzer calculates the impact of changing code.
Description ¶
Analyzes a target symbol to determine what would be affected if it were modified. Provides risk assessment, caller analysis, and actionable recommendations.
Thread Safety ¶
All methods are safe for concurrent use.
func NewBlastRadiusAnalyzer ¶
func NewBlastRadiusAnalyzer(g *graph.Graph, idx *index.SymbolIndex, riskConfig *RiskConfig) *BlastRadiusAnalyzer
NewBlastRadiusAnalyzer creates an analyzer with the given graph and index.
Description ¶
Creates an analyzer that will use the provided graph for relationship queries and the index for symbol lookups.
Inputs ¶
- g: Code graph with call relationships.
- idx: Symbol index for lookups.
- riskConfig: Optional risk thresholds (nil uses defaults).
Outputs ¶
- *BlastRadiusAnalyzer: Ready-to-use analyzer.
func (*BlastRadiusAnalyzer) Analyze ¶
func (a *BlastRadiusAnalyzer) Analyze(ctx context.Context, targetID string, opts *AnalyzeOptions) (*BlastRadius, error)
Analyze calculates the blast radius for a target symbol.
Description ¶
Performs comprehensive analysis of what would be affected if the target symbol were modified. Respects timeout and limits specified in options.
Inputs ¶
- ctx: Context for timeout and cancellation.
- targetID: Symbol ID to analyze (e.g., "pkg/auth.go:10:ValidateToken").
- opts: Analysis options (nil uses defaults).
Outputs ¶
- *BlastRadius: Analysis results.
- error: Non-nil on failure.
Example ¶
analyzer := analysis.NewBlastRadiusAnalyzer(graph, index, nil)
result, err := analyzer.Analyze(ctx, "pkg/auth.go:10:ValidateToken", nil)
if err != nil {
return err
}
fmt.Printf("Risk: %s\n", result.RiskLevel)
fmt.Printf("Direct callers: %d\n", len(result.DirectCallers))
type Caller ¶
type Caller struct {
ID string `json:"id"`
Name string `json:"name"`
FilePath string `json:"file_path"`
Line int `json:"line"`
Hops int `json:"hops"`
}
Caller represents a function that calls the target.
Fields ¶
- ID: Unique symbol identifier.
- Name: Human-readable function name.
- FilePath: File containing the caller.
- Line: Line number of the call.
- Hops: Distance from target (1 = direct, 2+ = indirect).
type ChangeClassifier ¶
type ChangeClassifier struct{}
ChangeClassifier classifies potential change impacts.
Description ¶
Analyzes the target symbol to determine what kinds of changes would be breaking vs compatible. Helps agents understand the consequences of different modification strategies.
Change Classifications ¶
For Functions:
- add_param: BREAKING (all callers must update)
- remove_param: BREAKING (all callers must update)
- change_return_type: BREAKING (all callers must update)
- add_return_value: COMPATIBLE (callers can ignore in Go)
- internal_logic: SAFE (no signature change)
For Types:
- add_field: COMPATIBLE (existing code works)
- remove_field: BREAKING (code using field breaks)
- change_field_type: BREAKING
- rename_field: BREAKING
For Interfaces:
- add_method: BREAKING (all implementers must add)
- remove_method: BREAKING (callers of method break)
- change_signature: BREAKING (all implementers + callers)
Thread Safety ¶
Safe for concurrent use (stateless).
func NewChangeClassifier ¶
func NewChangeClassifier() *ChangeClassifier
NewChangeClassifier creates a new change classifier.
func (*ChangeClassifier) ClassifyChangeType ¶
func (c *ChangeClassifier) ClassifyChangeType(oldSymbol, newSymbol *ast.Symbol) (changeType string, impact string)
ClassifyChangeType analyzes a before/after diff to classify the change.
Description ¶
Given the old and new versions of a symbol, determines what kind of change was made. This is used by patch validation to automatically detect the impact of proposed changes.
Inputs ¶
- oldSymbol: The symbol before changes (nil if new).
- newSymbol: The symbol after changes (nil if deleted).
Outputs ¶
- string: The change type (e.g., "add_param", "internal_logic").
- string: The impact level (BREAKING, COMPATIBLE, SAFE).
Limitations ¶
This is heuristic-based and may not catch all breaking changes, especially semantic changes that don't affect the signature.
func (*ChangeClassifier) Enrich ¶
func (c *ChangeClassifier) Enrich( ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius, ) error
Enrich classifies potential change impacts for the target.
Description ¶
Analyzes the target symbol and generates a list of potential change types with their impact classifications. This helps agents understand what kinds of modifications are safe vs breaking.
Inputs ¶
- ctx: Context for cancellation.
- target: The symbol to analyze.
- result: The result to enrich.
Outputs ¶
- error: Non-nil on context cancellation.
func (*ChangeClassifier) Name ¶
func (c *ChangeClassifier) Name() string
Name returns the enricher identifier.
func (*ChangeClassifier) Priority ¶
func (c *ChangeClassifier) Priority() int
Priority returns 2 (secondary analysis).
type ChangeImpact ¶
type ChangeImpact struct {
// ChangeType identifies what kind of change this describes.
ChangeType string `json:"change_type"`
// Impact is the severity of the change.
// One of: "BREAKING", "COMPATIBLE", "SAFE".
Impact string `json:"impact"`
// AffectedSites is the count of locations that would need updates.
// For BREAKING changes, this is the number of callers/implementers.
AffectedSites int `json:"affected_sites"`
// Description explains the impact in human-readable terms.
Description string `json:"description"`
// Example provides a code example if applicable.
Example string `json:"example,omitempty"`
}
ChangeImpact describes the potential impact of a change type.
Description ¶
Classifies different types of changes and their impact on callers. Helps agents understand whether they can make internal changes safely or need to update all callers.
Change Types for Functions ¶
- add_param: Adding a parameter (BREAKING)
- remove_param: Removing a parameter (BREAKING)
- change_return_type: Changing return type (BREAKING)
- add_return_value: Adding return value (COMPATIBLE for Go)
- internal_logic: Changing implementation (SAFE)
Change Types for Types ¶
- add_field: Adding struct field (COMPATIBLE)
- remove_field: Removing struct field (BREAKING)
- change_field_type: Changing field type (BREAKING)
- rename_field: Renaming field (BREAKING)
Change Types for Interfaces ¶
- add_method: Adding interface method (BREAKING for implementers)
- remove_method: Removing interface method (BREAKING for callers)
- change_signature: Changing method signature (BREAKING)
Thread Safety ¶
Read-only after construction.
type ChurnAnalyzer ¶
type ChurnAnalyzer struct {
// contains filtered or unexported fields
}
ChurnAnalyzer analyzes git history for code churn.
Description ¶
Examines git history to determine how often code changes, which can indicate instability or active development. High churn code may need extra attention during modifications.
Security ¶
Uses exec.Command with explicit arguments (no shell). Validates all file paths before passing to git. Enforces timeouts and output limits.
Thread Safety ¶
Safe for concurrent use. Git log results are cached with TTL.
func NewChurnAnalyzer ¶
func NewChurnAnalyzer(repoPath string, validator *validation.InputValidator) *ChurnAnalyzer
NewChurnAnalyzer creates a churn analyzer for the given repository.
Description ¶
Creates a ChurnAnalyzer that queries git history for code churn metrics. If git is not available or the path is not a git repository, the analyzer will return gracefully with nil ChurnScore.
Inputs ¶
- repoPath: Absolute path to the repository root.
- validator: Input validator. If nil, a default is created.
Outputs ¶
- *ChurnAnalyzer: Ready-to-use analyzer.
Example ¶
analyzer := NewChurnAnalyzer("/path/to/repo", validator)
func (*ChurnAnalyzer) ClearCache ¶
func (a *ChurnAnalyzer) ClearCache()
ClearCache clears all cached git log results.
func (*ChurnAnalyzer) Enrich ¶
func (a *ChurnAnalyzer) Enrich( ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius, ) error
Enrich analyzes git history for the target symbol's file.
Description ¶
Queries git log to count commits, identify bug fixes, and determine code stability. Populates result.ChurnScore with findings.
Graceful Degradation ¶
Returns nil ChurnScore (no error) if:
- Git is not available
- Path is not in a git repository
- Git command fails for any reason
Inputs ¶
- ctx: Context for cancellation.
- target: The symbol to analyze.
- result: The result to enrich.
Outputs ¶
- error: Non-nil only on context cancellation.
func (*ChurnAnalyzer) Name ¶
func (a *ChurnAnalyzer) Name() string
Name returns the enricher identifier.
func (*ChurnAnalyzer) Priority ¶
func (a *ChurnAnalyzer) Priority() int
Priority returns 2 (secondary analysis).
func (*ChurnAnalyzer) SetCacheTTL ¶
func (a *ChurnAnalyzer) SetCacheTTL(ttl time.Duration)
SetCacheTTL sets the cache time-to-live.
type ChurnScore ¶
type ChurnScore struct {
// ChangesLast30Days is the number of commits affecting this file
// in the last 30 days.
ChangesLast30Days int `json:"changes_last_30_days"`
// ChangesLast90Days is the number of commits affecting this file
// in the last 90 days.
ChangesLast90Days int `json:"changes_last_90_days"`
// BugReportsLinked is the count of commits with "fix", "bug", or
// issue references (e.g., "#123") in the last 90 days.
BugReportsLinked int `json:"bug_reports_linked"`
// LastModified is when the file was last changed (Unix milliseconds UTC).
LastModified int64 `json:"last_modified"`
// ChurnLevel categorizes the churn rate.
// One of: "LOW", "MODERATE", "HIGH".
ChurnLevel string `json:"churn_level"`
// Contributors lists unique authors who modified this file recently.
Contributors []string `json:"contributors,omitempty"`
}
ChurnScore describes historical code churn.
Description ¶
Analyzes git history to determine how often this code changes. High churn code is more likely to have bugs and may need extra attention during changes.
Churn Levels ¶
- LOW: < 3 changes in 30 days (stable code)
- MODERATE: 3-9 changes in 30 days (active development)
- HIGH: 10+ changes in 30 days (hot code, potential instability)
Thread Safety ¶
Read-only after construction.
type CodeOwnerRule ¶
type CodeOwnerRule struct {
Pattern string // Glob pattern (e.g., "*.go", "/src/auth/**")
Owners []string // List of owners (e.g., "@team", "user@example.com")
Line int // Line number in CODEOWNERS file (for debugging)
}
CodeOwnerRule represents a single CODEOWNERS rule.
type ConfidenceCalculator ¶
type ConfidenceCalculator struct{}
ConfidenceCalculator calculates analysis confidence scores.
Description ¶
Evaluates how reliable the blast radius analysis is based on factors that can cause incomplete or inaccurate results. Lower confidence indicates the agent should be extra careful with changes.
Confidence Reducers ¶
- Reflection usage in callers (-20%)
- Interface with external implementers (-15%)
- Dynamic dispatch patterns (-10%)
- Plugin/callback patterns (-10%)
- Truncated results (-10% per truncation)
- Enricher failures (-5% each)
Thread Safety ¶
Safe for concurrent use (stateless).
func NewConfidenceCalculator ¶
func NewConfidenceCalculator() *ConfidenceCalculator
NewConfidenceCalculator creates a new confidence calculator.
func (*ConfidenceCalculator) Enrich ¶
func (c *ConfidenceCalculator) Enrich( ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius, ) error
Enrich calculates the confidence score for the analysis.
Description ¶
Examines the analysis results to determine confidence level. Starts at 100% and reduces based on detected uncertainty factors.
Inputs ¶
- ctx: Context for cancellation.
- target: The symbol to analyze.
- result: The result to enrich.
Outputs ¶
- error: Non-nil on context cancellation.
func (*ConfidenceCalculator) Name ¶
func (c *ConfidenceCalculator) Name() string
Name returns the enricher identifier.
func (*ConfidenceCalculator) Priority ¶
func (c *ConfidenceCalculator) Priority() int
Priority returns 3 (runs last, aggregates other results).
type ConfidenceScore ¶
type ConfidenceScore struct {
// Score is a percentage (0-100) indicating confidence.
Score int `json:"score"`
// Level categorizes the score.
// One of: "HIGH", "MEDIUM", "LOW".
Level string `json:"level"`
// UncertaintyReasons explains why confidence was reduced.
// Empty if confidence is HIGH.
UncertaintyReasons []string `json:"uncertainty_reasons,omitempty"`
}
ConfidenceScore indicates analysis reliability.
Description ¶
Confidence is reduced when the analysis may be incomplete due to:
- Reflection/dynamic dispatch (can't trace all calls)
- Interface with external implementers
- Plugin/callback patterns
- Analysis truncation
- Enricher failures
Score Interpretation ¶
- 90-100: HIGH confidence, complete analysis
- 70-89: MEDIUM confidence, some uncertainty
- 0-69: LOW confidence, significant gaps
Thread Safety ¶
Read-only after construction.
func NewConfidenceScore ¶
func NewConfidenceScore(score int, reasons []string) ConfidenceScore
NewConfidenceScore creates a ConfidenceScore with the appropriate level.
type ConfigDepEnricher ¶
type ConfigDepEnricher struct {
// contains filtered or unexported fields
}
ConfigDepEnricher implements Enricher for config dependency tracking.
func NewConfigDepEnricher ¶
func NewConfigDepEnricher(projectRoot string, g *graph.Graph, idx *index.SymbolIndex) *ConfigDepEnricher
NewConfigDepEnricher creates an enricher for config dependencies.
func (*ConfigDepEnricher) Enrich ¶
func (e *ConfigDepEnricher) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
Enrich adds config dependency information to the blast radius.
func (*ConfigDepEnricher) Invalidate ¶
func (e *ConfigDepEnricher) Invalidate()
Invalidate forces a rescan on next enrichment.
func (*ConfigDepEnricher) Name ¶
func (e *ConfigDepEnricher) Name() string
Name returns the enricher name.
func (*ConfigDepEnricher) Priority ¶
func (e *ConfigDepEnricher) Priority() int
Priority returns execution priority.
type ConfigDepTracker ¶
type ConfigDepTracker struct {
// contains filtered or unexported fields
}
ConfigDepTracker tracks configuration dependencies in code.
Description ¶
Detects environment variable usage, Viper config references, and struct tag-based configuration. Maps these to symbols to understand which code depends on which configuration values.
Thread Safety ¶
Safe for concurrent use after construction.
func NewConfigDepTracker ¶
func NewConfigDepTracker(projectRoot string, g *graph.Graph, idx *index.SymbolIndex) *ConfigDepTracker
NewConfigDepTracker creates a new configuration dependency tracker.
Inputs ¶
- projectRoot: Root directory of the project.
- g: The dependency graph.
- idx: The symbol index.
Outputs ¶
- *ConfigDepTracker: Ready-to-use tracker.
func (*ConfigDepTracker) AllDependencies ¶
func (t *ConfigDepTracker) AllDependencies() []ConfigDependency
AllDependencies returns all detected config dependencies.
func (*ConfigDepTracker) ConfigKeys ¶
func (t *ConfigDepTracker) ConfigKeys() []string
ConfigKeys returns all config keys that have dependencies.
func (*ConfigDepTracker) FindConfigUsages ¶
func (t *ConfigDepTracker) FindConfigUsages(key string) ([]ConfigDependency, error)
FindConfigUsages returns all code locations that use a config key.
func (*ConfigDepTracker) FindSymbolDependencies ¶
func (t *ConfigDepTracker) FindSymbolDependencies(symbolID string) ([]ConfigDependency, error)
FindSymbolDependencies returns all config dependencies for a symbol.
type ConfigDependency ¶
type ConfigDependency struct {
// Key is the configuration key name.
Key string `json:"key"`
// Type is the type of configuration (env, viper, flag, file).
Type ConfigType `json:"type"`
// DefaultValue is the default value (if detectable).
DefaultValue string `json:"default_value,omitempty"`
// Required indicates if this config is required.
Required bool `json:"required"`
// SourceSymbol is the symbol containing this dependency.
SourceSymbol string `json:"source_symbol"`
// FilePath is the file containing the dependency.
FilePath string `json:"file_path"`
// Line is the line number of the dependency.
Line int `json:"line"`
// Confidence is how confident we are in this detection (0-100).
Confidence int `json:"confidence"`
}
ConfigDependency represents a configuration dependency from code.
type ConfigType ¶
type ConfigType string
ConfigType represents the type of configuration source.
const ( ConfigTypeEnv ConfigType = "ENV" ConfigTypeViper ConfigType = "VIPER" ConfigTypeFlag ConfigType = "FLAG" ConfigTypeFile ConfigType = "FILE" ConfigTypeStruct ConfigType = "STRUCT_TAG" )
type ContractEndpoint ¶
type ContractEndpoint struct {
Path string `json:"path"`
Method string `json:"method,omitempty"`
OperationID string `json:"operation_id,omitempty"`
Summary string `json:"summary,omitempty"`
Parameters []string `json:"parameters,omitempty"`
}
ContractEndpoint represents an endpoint defined in a contract.
type CoverageCorrelator ¶
type CoverageCorrelator struct {
// contains filtered or unexported fields
}
CoverageCorrelator parses coverage files and maps coverage to symbols.
Description ¶
Parses lcov and cobertura format coverage files and correlates the line coverage data with symbols from the index. Provides methods to query coverage for specific symbols and find untested code paths.
Thread Safety ¶
Safe for concurrent use after construction.
func NewCoverageCorrelator ¶
func NewCoverageCorrelator(coveragePath string, idx *index.SymbolIndex) (*CoverageCorrelator, error)
NewCoverageCorrelator creates a new correlator from a coverage file.
Description ¶
Parses the coverage file and creates an internal representation for fast symbol lookup. Supports lcov (.info) and cobertura (.xml) formats.
Inputs ¶
- coveragePath: Path to the coverage file. Must be < 50MB.
- idx: Symbol index for mapping lines to symbols.
Outputs ¶
- *CoverageCorrelator: Ready-to-use correlator.
- error: Non-nil if parsing failed.
func (*CoverageCorrelator) CalculateCoverageRisk ¶
func (c *CoverageCorrelator) CalculateCoverageRisk(br *EnhancedBlastRadius) CoverageRisk
CalculateCoverageRisk determines the coverage risk level.
func (*CoverageCorrelator) GetCoverage ¶
func (c *CoverageCorrelator) GetCoverage(symbolID string) (*CoverageInfo, error)
GetCoverage returns coverage info for a specific symbol.
Inputs ¶
- symbolID: The symbol to get coverage for.
Outputs ¶
- *CoverageInfo: Coverage data for the symbol.
- error: Non-nil if symbol not found or no coverage data.
func (*CoverageCorrelator) GetUntestedBlastRadius ¶
func (c *CoverageCorrelator) GetUntestedBlastRadius(br *BlastRadius) []string
GetUntestedBlastRadius returns symbols in the blast radius that lack coverage.
Inputs ¶
- br: The blast radius to analyze.
Outputs ¶
- []string: Symbol IDs that are untested.
func (*CoverageCorrelator) GetUntestedEnhancedBlastRadius ¶
func (c *CoverageCorrelator) GetUntestedEnhancedBlastRadius(br *EnhancedBlastRadius) []Caller
GetUntestedEnhancedBlastRadius returns untested symbols from enhanced result.
func (*CoverageCorrelator) Stats ¶
func (c *CoverageCorrelator) Stats() CoverageStats
Stats returns overall coverage statistics.
type CoverageEnricher ¶
type CoverageEnricher struct {
// contains filtered or unexported fields
}
CoverageEnricher implements Enricher for test coverage correlation.
func NewCoverageEnricher ¶
func NewCoverageEnricher(coveragePath string, idx *index.SymbolIndex) (*CoverageEnricher, error)
NewCoverageEnricher creates an enricher for coverage correlation.
func (*CoverageEnricher) Enrich ¶
func (e *CoverageEnricher) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
Enrich adds coverage information to the blast radius.
func (*CoverageEnricher) Name ¶
func (e *CoverageEnricher) Name() string
Name returns the enricher name.
func (*CoverageEnricher) Priority ¶
func (e *CoverageEnricher) Priority() int
Priority returns execution priority.
type CoverageInfo ¶
type CoverageInfo struct {
// SymbolID is the symbol this coverage applies to.
SymbolID string `json:"symbol_id"`
// LineCoverage is the percentage of lines covered (0.0-1.0).
LineCoverage float64 `json:"line_coverage"`
// BranchCoverage is the percentage of branches covered (0.0-1.0).
BranchCoverage float64 `json:"branch_coverage"`
// CoveredLines is the number of lines with coverage.
CoveredLines int `json:"covered_lines"`
// TotalLines is the total number of lines.
TotalLines int `json:"total_lines"`
// CoveredBy is the list of test functions that cover this symbol.
CoveredBy []string `json:"covered_by,omitempty"`
}
CoverageInfo contains coverage data for a symbol.
type CoverageRisk ¶
type CoverageRisk string
CoverageRisk indicates the coverage risk level.
const ( // CoverageRiskHighUntested indicates most code is untested. CoverageRiskHighUntested CoverageRisk = "HIGH_UNTESTED" // CoverageRiskPartial indicates partial test coverage. CoverageRiskPartial CoverageRisk = "PARTIAL" // CoverageRiskCovered indicates good test coverage. CoverageRiskCovered CoverageRisk = "COVERED" )
type CoverageStats ¶
type CoverageStats struct {
TotalFiles int `json:"total_files"`
TotalLines int `json:"total_lines"`
CoveredLines int `json:"covered_lines"`
Coverage float64 `json:"coverage"`
}
Stats returns coverage statistics.
type DeadCodeDetector ¶
type DeadCodeDetector struct {
// contains filtered or unexported fields
}
DeadCodeDetector finds unused code in the codebase.
Description ¶
Analyzes the dependency graph to find functions, types, and constants that have no callers or references. Uses confidence scoring to account for reflection, exports, and other uncertainty sources.
Thread Safety ¶
Safe for concurrent use after construction.
func NewDeadCodeDetector ¶
func NewDeadCodeDetector(g *graph.Graph, idx *index.SymbolIndex) *DeadCodeDetector
NewDeadCodeDetector creates a new detector.
Inputs ¶
- g: The dependency graph to analyze.
- idx: The symbol index for lookups.
Outputs ¶
- *DeadCodeDetector: Ready-to-use detector.
func (*DeadCodeDetector) Detect ¶
func (d *DeadCodeDetector) Detect(ctx context.Context) (*DeadCodeResult, error)
Detect finds dead code in the codebase.
Description ¶
Scans all symbols in the graph and identifies those with no incoming edges (callers/references). Special handling for:
- main() and init() functions (never dead)
- Test functions (can be dead only if no test references them)
- Exported symbols (lower confidence since may be used externally)
- Reflection-prone code (lower confidence)
Inputs ¶
- ctx: Context for cancellation.
Outputs ¶
- *DeadCodeResult: Detected dead code.
- error: Non-nil on failure.
type DeadCodeDetectorOption ¶
type DeadCodeDetectorOption func(*deadCodeOptions)
DeadCodeDetectorOption configures the detector.
func WithExcludePatterns ¶
func WithExcludePatterns(patterns []string) DeadCodeDetectorOption
WithExcludePatterns sets patterns to exclude from detection.
func WithMinConfidence ¶
func WithMinConfidence(min int) DeadCodeDetectorOption
WithMinConfidence sets the minimum confidence threshold.
type DeadCodeEnricher ¶
type DeadCodeEnricher struct {
// contains filtered or unexported fields
}
DeadCodeEnricher implements Enricher for dead code detection.
func NewDeadCodeEnricher ¶
func NewDeadCodeEnricher(g *graph.Graph, idx *index.SymbolIndex) *DeadCodeEnricher
NewDeadCodeEnricher creates an enricher for dead code detection.
func (*DeadCodeEnricher) Enrich ¶
func (e *DeadCodeEnricher) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
Enrich adds dead code information to the blast radius.
func (*DeadCodeEnricher) Invalidate ¶
func (e *DeadCodeEnricher) Invalidate()
Invalidate clears the cached dead code result.
func (*DeadCodeEnricher) Name ¶
func (e *DeadCodeEnricher) Name() string
Name returns the enricher name.
func (*DeadCodeEnricher) Priority ¶
func (e *DeadCodeEnricher) Priority() int
Priority returns execution priority (run after basic analysis).
type DeadCodeInfo ¶
type DeadCodeInfo struct {
// IsDead indicates if the target symbol is dead.
IsDead bool `json:"is_dead"`
// Reason for being dead (if IsDead is true).
Reason string `json:"reason,omitempty"`
// Confidence in the dead code detection (0-100).
Confidence int `json:"confidence,omitempty"`
// DeadCallerCount is how many callers are themselves dead.
DeadCallerCount int `json:"dead_caller_count,omitempty"`
// TotalDeadLines is total dead lines in the codebase.
TotalDeadLines int `json:"total_dead_lines,omitempty"`
// DeadFunctionCount is total dead functions.
DeadFunctionCount int `json:"dead_function_count,omitempty"`
// DeadTypeCount is total dead types.
DeadTypeCount int `json:"dead_type_count,omitempty"`
}
DeadCodeInfo contains dead code analysis for a symbol.
type DeadCodeResult ¶
type DeadCodeResult struct {
// UnusedFunctions are functions with no callers.
UnusedFunctions []DeadSymbol `json:"unused_functions"`
// UnusedTypes are types with no usages.
UnusedTypes []DeadSymbol `json:"unused_types"`
// UnusedConstants are constants with no references.
UnusedConstants []DeadSymbol `json:"unused_constants"`
// TotalDeadLines is the estimated total lines of dead code.
TotalDeadLines int `json:"total_dead_lines"`
}
DeadCodeResult contains the results of dead code detection.
type DeadSymbol ¶
type DeadSymbol struct {
// ID is the unique symbol identifier.
ID string `json:"id"`
// Name is the symbol's name.
Name string `json:"name"`
// FilePath is the file containing the symbol.
FilePath string `json:"file_path"`
// Line is the starting line number.
Line int `json:"line"`
// EndLine is the ending line number (for line count estimation).
EndLine int `json:"end_line,omitempty"`
// Reason explains why this is considered dead.
Reason string `json:"reason"`
// Confidence is how confident we are (0-100).
// Lower for exported symbols, reflection-heavy code, etc.
Confidence int `json:"confidence"`
}
DeadSymbol represents a potentially dead symbol.
type EnhancedAnalyzer ¶
type EnhancedAnalyzer struct {
// contains filtered or unexported fields
}
EnhancedAnalyzer orchestrates multiple enrichers with parallel execution.
Description ¶
EnhancedAnalyzer extends BlastRadiusAnalyzer by running additional enrichers that add security, churn, ownership, change classification, and confidence analysis. Enrichers run in parallel within priority groups for optimal latency.
Execution Model ¶
- Run base BlastRadiusAnalyzer.Analyze() to get CB-17 result
- Group enrichers by priority
- For each priority group (in order): run enrichers in parallel via errgroup
- Aggregate results; slow enrichers don't block response (partial results OK)
Thread Safety ¶
Safe for concurrent use. Multiple goroutines may call Analyze simultaneously.
func NewEnhancedAnalyzer ¶
func NewEnhancedAnalyzer( base *BlastRadiusAnalyzer, g *graph.Graph, idx *index.SymbolIndex, registry *EnricherRegistry, opts ...EnhancedAnalyzerOption, ) *EnhancedAnalyzer
NewEnhancedAnalyzer creates an analyzer that orchestrates enrichers.
Description ¶
Creates an EnhancedAnalyzer that wraps a base BlastRadiusAnalyzer and adds enrichment capabilities. The graph and index must be provided for enrichment context (they can be the same as those used by the base analyzer).
Inputs ¶
- base: The CB-17 BlastRadiusAnalyzer. Must not be nil.
- g: The code graph. Must not be nil.
- idx: The symbol index. Must not be nil.
- registry: Registry of enrichers to run. Must not be nil.
- opts: Optional configuration.
Outputs ¶
- *EnhancedAnalyzer: Ready-to-use analyzer.
Panics ¶
Panics if base, graph, index, or registry is nil.
Example ¶
registry := NewEnricherRegistry()
registry.Register(NewSecurityPathDetector(patterns))
registry.Register(NewChurnAnalyzer(repoPath, validator))
registry.Register(NewOwnershipResolver(repoPath, validator))
registry.Register(NewChangeClassifier())
registry.Register(NewConfidenceCalculator())
analyzer := NewEnhancedAnalyzer(baseAnalyzer, graph, index, registry,
WithEnrichmentTimeout(150*time.Millisecond),
WithRepoPath("/path/to/repo"),
)
func (*EnhancedAnalyzer) Analyze ¶
func (a *EnhancedAnalyzer) Analyze( ctx context.Context, targetID string, opts *AnalyzeOptions, ) (*EnhancedBlastRadius, error)
Analyze runs base analysis then enriches with all registered enrichers.
Description ¶
Performs a complete enhanced blast radius analysis:
- Validates input
- Runs CB-17 base analysis
- Runs enrichers grouped by priority
- Returns combined result with partial enrichment if timeout
Execution Model ¶
Enrichers are grouped by priority and run in parallel within each group. If the total enrichment timeout is reached, remaining enrichers are skipped. This ensures the response is always returned within the timeout budget.
Inputs ¶
- ctx: Context for cancellation/timeout. Must not be nil.
- targetID: The symbol ID to analyze.
- opts: Analysis options (may be nil for defaults).
Outputs ¶
- *EnhancedBlastRadius: Analysis result. Never nil on success.
- error: Non-nil on complete failure (validation, base analysis failed). Partial enrichment failures are captured in EnricherResults, not here.
Example ¶
result, err := analyzer.Analyze(ctx, "pkg/auth.go:42:ValidateToken", nil)
if err != nil {
return fmt.Errorf("analysis failed: %w", err)
}
if result.SecurityPath != nil && result.SecurityPath.RequiresReview {
log.Warn("Security review required")
}
func (*EnhancedAnalyzer) GetBaseAnalyzer ¶
func (a *EnhancedAnalyzer) GetBaseAnalyzer() *BlastRadiusAnalyzer
GetBaseAnalyzer returns the underlying BlastRadiusAnalyzer.
func (*EnhancedAnalyzer) GetGraph ¶
func (a *EnhancedAnalyzer) GetGraph() *graph.Graph
GetGraph returns the code graph.
func (*EnhancedAnalyzer) GetIndex ¶
func (a *EnhancedAnalyzer) GetIndex() *index.SymbolIndex
GetIndex returns the symbol index.
func (*EnhancedAnalyzer) GetRegistry ¶
func (a *EnhancedAnalyzer) GetRegistry() *EnricherRegistry
GetRegistry returns the enricher registry.
func (*EnhancedAnalyzer) GetRepoPath ¶
func (a *EnhancedAnalyzer) GetRepoPath() string
GetRepoPath returns the repository root path.
func (*EnhancedAnalyzer) GetTimeout ¶
func (a *EnhancedAnalyzer) GetTimeout() time.Duration
GetTimeout returns the enrichment timeout.
func (*EnhancedAnalyzer) SetTimeout ¶
func (a *EnhancedAnalyzer) SetTimeout(d time.Duration)
SetTimeout updates the enrichment timeout. Thread-safe.
type EnhancedAnalyzerOption ¶
type EnhancedAnalyzerOption func(*EnhancedAnalyzer)
EnhancedAnalyzerOption configures EnhancedAnalyzer.
func WithEnrichmentTimeout ¶
func WithEnrichmentTimeout(d time.Duration) EnhancedAnalyzerOption
WithEnrichmentTimeout sets the total time budget for enrichment. Default: 150ms.
func WithGraph ¶
func WithGraph(g *graph.Graph) EnhancedAnalyzerOption
WithGraph sets an explicit graph (overrides base analyzer's graph).
func WithIndex ¶
func WithIndex(idx *index.SymbolIndex) EnhancedAnalyzerOption
WithIndex sets an explicit index (overrides base analyzer's index).
func WithInputValidator ¶
func WithInputValidator(v *validation.InputValidator) EnhancedAnalyzerOption
WithInputValidator sets the input validator.
func WithRepoPath ¶
func WithRepoPath(path string) EnhancedAnalyzerOption
WithRepoPath sets the repository root path.
type EnhancedBlastRadius ¶
type EnhancedBlastRadius struct {
// BlastRadius embeds the core CB-17 result.
// This includes: Target, RiskLevel, DirectCallers, IndirectCallers,
// Implementers, SharedDeps, FilesAffected, TestFiles, Summary, Recommendation.
BlastRadius
// SecurityPath contains security analysis results (single primary path).
// Nil if security analysis didn't run or found nothing.
SecurityPath *SecurityPath `json:"security_path,omitempty"`
// SecurityPaths contains all detected security paths.
// Used by CB-17c for multiple path detection.
SecurityPaths []SecurityPath `json:"security_paths,omitempty"`
// ChurnScore contains historical churn analysis (single primary).
// Nil if git is unavailable or analysis failed.
ChurnScore *ChurnScore `json:"churn_score,omitempty"`
// ChurnScores contains all churn scores for affected files.
// Used by CB-17c for comprehensive churn analysis.
ChurnScores []ChurnScore `json:"churn_scores,omitempty"`
// Ownership contains code ownership information.
// Nil if CODEOWNERS is missing or analysis failed.
Ownership *Ownership `json:"ownership,omitempty"`
// ChangeImpacts describes potential impacts of different change types.
// Empty if classification couldn't be performed.
ChangeImpacts []ChangeImpact `json:"change_impacts"`
// Confidence indicates analysis reliability.
// Always populated (defaults to HIGH if no issues detected).
Confidence *ConfidenceScore `json:"confidence,omitempty"`
// EnricherResults tracks which enrichers ran successfully.
// Useful for debugging partial results.
EnricherResults []EnricherResult `json:"enricher_results,omitempty"`
// AnalyzedAt is when this analysis was performed (Unix milliseconds UTC).
AnalyzedAt int64 `json:"analyzed_at"`
// GraphGeneration is the graph version used for analysis.
// Used for cache invalidation.
GraphGeneration uint64 `json:"graph_generation"`
// TransitiveCount is the total number of transitive callers.
TransitiveCount int `json:"transitive_count,omitempty"`
// DeadCode contains dead code analysis for this symbol.
DeadCode *DeadCodeInfo `json:"dead_code,omitempty"`
// Coverage contains test coverage information for this symbol.
Coverage *CoverageInfo `json:"coverage,omitempty"`
// UntestedCallers are callers that lack test coverage.
UntestedCallers []Caller `json:"untested_callers,omitempty"`
// CoverageRisk indicates the coverage risk level.
// One of: "HIGH_UNTESTED", "PARTIAL", "COVERED".
CoverageRisk string `json:"coverage_risk,omitempty"`
// SchemaDependencies are database schema dependencies.
SchemaDependencies []SchemaDependency `json:"schema_dependencies,omitempty"`
// APIDependencies are external API dependencies.
APIDependencies []APIDependency `json:"api_dependencies,omitempty"`
// ConfigDependencies are configuration dependencies.
ConfigDependencies []ConfigDependency `json:"config_dependencies,omitempty"`
// RollbackRisk assesses the difficulty of rolling back changes.
RollbackRisk *RollbackRisk `json:"rollback_risk,omitempty"`
// PredictiveRisk contains predictive risk scoring based on history.
PredictiveRisk *PredictiveRisk `json:"predictive_risk,omitempty"`
}
EnhancedBlastRadius extends BlastRadius with additional analysis dimensions.
Description ¶
Combines the core CB-17 blast radius result with enhanced analysis from CB-17b enrichers: security path detection, historical churn, ownership, change impact classification, and confidence scoring.
JSON Serialization ¶
All fields use omitempty where appropriate to minimize response size. Optional enricher fields are nil when the enricher didn't run or failed.
Thread Safety ¶
Not safe for concurrent modification. Create a new instance for each analysis result.
type Enricher ¶
type Enricher interface {
// Name returns a unique identifier for logging and metrics.
//
// # Description
//
// The name should be a short, lowercase, underscore-separated string
// that identifies this enricher (e.g., "security_path", "churn").
//
// # Outputs
//
// - string: Unique identifier for this enricher.
Name() string
// Priority determines execution order (lower = earlier).
//
// # Description
//
// Enrichers with the same priority run in parallel using errgroup.
// Priority groups execute sequentially.
//
// # Priority Guidelines
//
// - 1: Critical analysis that other enrichers may depend on
// - 2: Independent secondary analysis
// - 3: Derived analysis that aggregates other results
//
// # Range
//
// Valid range: 1-10 (1 = first, 10 = last).
//
// # Outputs
//
// - int: Priority level (1-10).
Priority() int
// Enrich adds analysis data to the result.
//
// # Description
//
// Performs the enricher's analysis and modifies the result in place.
// The result is pre-populated with base BlastRadius data from CB-17.
//
// # Inputs
//
// - ctx: Context for cancellation/timeout. Must be checked frequently.
// Implementations should check ctx.Err() at least every 10ms of work.
// - target: The symbol and context being analyzed.
// - result: The result to enrich. Modify appropriate fields in place.
//
// # Outputs
//
// - error: Non-nil on failure. Partial enrichment is acceptable.
// Errors do not fail the overall analysis; they're logged and
// the enricher's contribution is marked as missing.
//
// # Behavior Requirements
//
// - Must be idempotent (calling twice produces same result)
// - Must respect context cancellation (return ctx.Err())
// - Should complete within 50ms for good UX
// - May return partial results if timeout is imminent
// - Must not modify fields owned by other enrichers
//
// # Example
//
// func (e *MyEnricher) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error {
// // Check cancellation at start
// if ctx.Err() != nil {
// return ctx.Err()
// }
//
// // Do analysis...
// data := e.analyze(target)
//
// // Check cancellation after work
// if ctx.Err() != nil {
// return ctx.Err()
// }
//
// // Enrich result
// result.MyData = data
// return nil
// }
Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
}
Enricher adds analysis dimensions to a blast radius result.
Description ¶
Enrichers are composable sub-analyzers that add specific dimensions to blast radius results. They run in parallel (grouped by priority) to minimize latency. Each enricher focuses on one aspect: security paths, code churn, ownership, etc.
Priority Groups ¶
Enrichers are grouped by priority (lower number = higher priority):
- Priority 1: Critical analysis (security, ownership) - must complete
- Priority 2: Secondary analysis (churn, change classification)
- Priority 3: Derived analysis (confidence) - depends on earlier results
Within each priority group, enrichers run in parallel.
Implementation Requirements ¶
- Must be idempotent (safe to retry)
- Must check context for cancellation frequently
- Should complete within 50ms for good UX
- Must be thread-safe for concurrent use
- May return partial results on timeout
- Must not panic (return errors instead)
Thread Safety ¶
Implementations must be safe for concurrent use. Multiple goroutines may call Enrich simultaneously with different targets.
type EnricherRegistry ¶
type EnricherRegistry struct {
// contains filtered or unexported fields
}
EnricherRegistry manages a collection of enrichers.
Description ¶
Provides a way to register, unregister, and retrieve enrichers. Enrichers are stored in priority order for efficient iteration.
Thread Safety ¶
Safe for concurrent use after construction. Modifications during analysis are not supported.
func DefaultEnricherRegistry ¶
func DefaultEnricherRegistry(repoPath string, validator *validation.InputValidator) (*EnricherRegistry, error)
DefaultEnricherRegistry creates a registry with standard enrichers.
Description ¶
Creates a registry pre-populated with the standard CB-17b enrichers:
- SecurityPathDetector (priority 1)
- OwnershipResolver (priority 1)
- ChurnAnalyzer (priority 2)
- ChangeClassifier (priority 2)
- ConfidenceCalculator (priority 3)
Inputs ¶
- repoPath: Absolute path to the repository root.
- validator: Input validator (may be nil for default).
Outputs ¶
- *EnricherRegistry: Registry with standard enrichers.
- error: Non-nil if critical enrichers failed to initialize.
Example ¶
registry, err := DefaultEnricherRegistry("/path/to/repo", nil)
if err != nil {
return fmt.Errorf("failed to create registry: %w", err)
}
func NewEnricherRegistry ¶
func NewEnricherRegistry() *EnricherRegistry
NewEnricherRegistry creates a new empty registry.
func (*EnricherRegistry) All ¶
func (r *EnricherRegistry) All() []Enricher
All returns all registered enrichers.
Description ¶
Returns a copy of the enricher slice. The caller may modify the returned slice without affecting the registry.
Outputs ¶
- []Enricher: Copy of all registered enrichers.
func (*EnricherRegistry) ByPriority ¶
func (r *EnricherRegistry) ByPriority() map[int][]Enricher
ByPriority groups enrichers by their priority level.
Description ¶
Returns a map of priority -> enrichers. Used by EnhancedAnalyzer to run enrichers in parallel within each priority group.
Outputs ¶
- map[int][]Enricher: Enrichers grouped by priority.
func (*EnricherRegistry) Register ¶
func (r *EnricherRegistry) Register(enricher Enricher)
Register adds an enricher to the registry.
Description ¶
Adds the enricher to the registry. Enrichers are stored in registration order; they will be sorted by priority when retrieved.
Inputs ¶
- enricher: The enricher to register. Must not be nil.
Panics ¶
Panics if enricher is nil.
func (*EnricherRegistry) SortedPriorities ¶
func (r *EnricherRegistry) SortedPriorities() []int
SortedPriorities returns priority levels in ascending order.
Description ¶
Returns the unique priority levels in ascending order. Used by EnhancedAnalyzer to process priority groups sequentially.
Outputs ¶
- []int: Priority levels sorted ascending.
type EnricherResult ¶
type EnricherResult struct {
// Name is the enricher's unique identifier.
Name string
// Success indicates whether the enricher completed without error.
Success bool
// Error contains the error message if Success is false.
// Empty string if no error.
Error string
// DurationMs is how long the enricher took in milliseconds.
DurationMs int64
// Skipped indicates the enricher was skipped (e.g., due to timeout).
Skipped bool
// SkipReason explains why the enricher was skipped.
SkipReason string
}
EnricherResult captures the outcome of running an enricher.
Description ¶
Used by EnhancedAnalyzer to track which enrichers succeeded, failed, or were skipped. Enables partial results and debugging.
type EnrichmentTarget ¶
type EnrichmentTarget struct {
// SymbolID is the unique identifier of the target symbol.
// Format: "path/to/file.go:line:name"
SymbolID string
// Symbol is the resolved AST symbol. May be nil if the symbol
// could not be found (e.g., it was deleted or is dynamically generated).
Symbol *ast.Symbol
// Graph is the frozen code graph. Must be read-only at this point.
// Use graph.Query methods to find relationships.
Graph *graph.Graph
// Index is the symbol index for O(1) lookups by ID, name, file, or kind.
Index *index.SymbolIndex
// RepoPath is the absolute path to the repository root.
// Used by enrichers that need to access files (e.g., CODEOWNERS, git).
RepoPath string
// BaseResult is the CB-17 blast radius result.
// Enrichers use this to access callers, implementers, etc.
BaseResult *BlastRadius
}
EnrichmentTarget provides context for enrichment.
Description ¶
Contains all the context an enricher needs to analyze a symbol, including the symbol itself, the graph, the index, and the base blast radius result from CB-17.
Thread Safety ¶
Read-only after construction. Safe for concurrent access.
Fields ¶
- SymbolID: The unique identifier of the target symbol.
- Symbol: The resolved AST symbol (nil if not found).
- Graph: The frozen code graph for querying relationships.
- Index: The symbol index for lookups.
- RepoPath: Absolute path to the repository root.
- BaseResult: The CB-17 blast radius result to enrich.
type Implementer ¶
type Implementer struct {
TypeID string `json:"type_id"`
TypeName string `json:"type_name"`
MethodID string `json:"method_id,omitempty"`
MethodName string `json:"method_name,omitempty"`
FilePath string `json:"file_path"`
Line int `json:"line"`
}
Implementer represents a type that implements an interface.
Fields ¶
- TypeID: Unique identifier of the implementing type.
- TypeName: Human-readable type name.
- MethodID: If target is interface method, the implementing method.
- MethodName: Human-readable method name.
- FilePath: File containing the implementation.
- Line: Line number of the implementation.
type IrreversibleChange ¶
type IrreversibleChange struct {
// Type is the type of irreversible change.
Type IrreversibleChangeType `json:"type"`
// Description describes what was changed.
Description string `json:"description"`
// Location is where the change occurs.
Location string `json:"location"`
// Impact describes the impact of this change.
Impact string `json:"impact"`
}
IrreversibleChange represents a change that cannot be easily undone.
type IrreversibleChangeType ¶
type IrreversibleChangeType string
IrreversibleChangeType represents types of irreversible changes.
const ( IrreversibleColumnDrop IrreversibleChangeType = "COLUMN_DROP" IrreversibleTableDrop IrreversibleChangeType = "TABLE_DROP" IrreversibleDataDelete IrreversibleChangeType = "DATA_DELETE" IrreversibleAPIRemoval IrreversibleChangeType = "API_REMOVAL" IrreversibleFieldRemoval IrreversibleChangeType = "FIELD_REMOVAL" IrreversibleTypeChange IrreversibleChangeType = "TYPE_CHANGE" )
type Ownership ¶
type Ownership struct {
// PrimaryOwner is the team/person from CODEOWNERS matching the target file.
// Format: "@team-name" or "@username" or "email@example.com".
// Empty if no CODEOWNERS match.
PrimaryOwner string `json:"primary_owner,omitempty"`
// SecondaryOwners are owners of files in the blast radius.
// These teams should be notified of changes.
SecondaryOwners []string `json:"secondary_owners,omitempty"`
// ReviewerHint suggests who should review based on recent activity.
// May be a specific person who recently worked on this code.
ReviewerHint string `json:"reviewer_hint,omitempty"`
// OwnershipSource indicates where ownership was determined from.
// One of: "CODEOWNERS", "git_blame", "fallback".
OwnershipSource string `json:"ownership_source,omitempty"`
}
Ownership describes code ownership from CODEOWNERS.
Description ¶
Parses CODEOWNERS file to determine who owns the code and should review changes. Also identifies secondary owners from affected files.
Thread Safety ¶
Read-only after construction.
type OwnershipResolver ¶
type OwnershipResolver struct {
// contains filtered or unexported fields
}
OwnershipResolver resolves code ownership from CODEOWNERS file.
Description ¶
Parses GitHub/GitLab CODEOWNERS format to determine who owns the code and should review changes. Also aggregates owners from all affected files in the blast radius.
CODEOWNERS Format ¶
Standard GitHub/GitLab format:
# Comment *.go @backend-team /docs/ @docs-team @writers src/auth/ @security-team @backend-team
Thread Safety ¶
Safe for concurrent use. Rules are loaded once at construction.
func NewOwnershipResolver ¶
func NewOwnershipResolver(repoPath string, validator *validation.InputValidator) (*OwnershipResolver, error)
NewOwnershipResolver creates an ownership resolver for the repository.
Description ¶
Creates an OwnershipResolver by loading and parsing the CODEOWNERS file. Looks for CODEOWNERS in standard locations:
- CODEOWNERS
- .github/CODEOWNERS
- docs/CODEOWNERS
Inputs ¶
- repoPath: Absolute path to the repository root.
- validator: Input validator. If nil, a default is created.
Outputs ¶
- *OwnershipResolver: Ready-to-use resolver.
- error: Non-nil if CODEOWNERS cannot be found or parsed.
Example ¶
resolver, err := NewOwnershipResolver("/path/to/repo", validator)
if err != nil {
// CODEOWNERS not found - ownership will be nil
}
func (*OwnershipResolver) Enrich ¶
func (r *OwnershipResolver) Enrich( ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius, ) error
Enrich resolves ownership for the target and affected files.
Description ¶
Determines the primary owner for the target file and aggregates secondary owners from all files in the blast radius.
Inputs ¶
- ctx: Context for cancellation.
- target: The symbol to analyze.
- result: The result to enrich.
Outputs ¶
- error: Non-nil on context cancellation.
func (*OwnershipResolver) GetRules ¶
func (r *OwnershipResolver) GetRules() []CodeOwnerRule
GetRules returns the parsed CODEOWNERS rules for inspection.
func (*OwnershipResolver) Name ¶
func (r *OwnershipResolver) Name() string
Name returns the enricher identifier.
func (*OwnershipResolver) Priority ¶
func (r *OwnershipResolver) Priority() int
Priority returns 1 (critical analysis).
type PredictiveEnricher ¶
type PredictiveEnricher struct {
// contains filtered or unexported fields
}
PredictiveEnricher implements Enricher for predictive risk scoring.
func NewPredictiveEnricher ¶
func NewPredictiveEnricher(g *graph.Graph, idx *index.SymbolIndex, store *history.HistoryStore) *PredictiveEnricher
NewPredictiveEnricher creates a predictive risk enricher.
func (*PredictiveEnricher) Enrich ¶
func (e *PredictiveEnricher) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
Enrich adds predictive risk information to the blast radius.
func (*PredictiveEnricher) Name ¶
func (e *PredictiveEnricher) Name() string
Name returns the enricher name.
func (*PredictiveEnricher) Priority ¶
func (e *PredictiveEnricher) Priority() int
Priority returns execution priority (runs last).
func (*PredictiveEnricher) Scorer ¶
func (e *PredictiveEnricher) Scorer() *PredictiveRiskScorer
Scorer returns the underlying scorer for configuration.
type PredictiveRisk ¶
type PredictiveRisk struct {
// Score is the overall risk score (0-100, higher = riskier).
Score int `json:"score"`
// Level is the risk level category.
Level PredictiveRiskLevel `json:"level"`
// Factors are the factors contributing to the score.
Factors []PredictiveRiskFactor `json:"factors"`
// HistoricalBugCount is the number of past bugs in this area.
HistoricalBugCount int `json:"historical_bug_count"`
// ChurnRate is the change frequency (changes per week).
ChurnRate float64 `json:"churn_rate"`
// ComplexityScore is the estimated complexity (if available).
ComplexityScore int `json:"complexity_score,omitempty"`
// FailureProbability is the estimated probability of failure (0.0-1.0).
FailureProbability float64 `json:"failure_probability"`
// Recommendations are suggested risk mitigation steps.
Recommendations []string `json:"recommendations,omitempty"`
}
PredictiveRisk represents a predictive risk score.
type PredictiveRiskFactor ¶
type PredictiveRiskFactor struct {
// Name is the factor name.
Name string `json:"name"`
// Description explains the factor.
Description string `json:"description"`
// Contribution is the score contribution (0-100).
Contribution int `json:"contribution"`
// Evidence provides supporting data.
Evidence string `json:"evidence,omitempty"`
}
PredictiveRiskFactor is a factor contributing to predictive risk.
type PredictiveRiskLevel ¶
type PredictiveRiskLevel string
PredictiveRiskLevel categorizes predictive risk.
const ( PredictiveRiskLow PredictiveRiskLevel = "LOW" PredictiveRiskMedium PredictiveRiskLevel = "MEDIUM" PredictiveRiskHigh PredictiveRiskLevel = "HIGH" PredictiveRiskCritical PredictiveRiskLevel = "CRITICAL" )
type PredictiveRiskScorer ¶
type PredictiveRiskScorer struct {
// contains filtered or unexported fields
}
PredictiveRiskScorer calculates predictive risk scores based on historical data.
Description ¶
Uses historical bug correlation, churn rate, and complexity metrics to predict the risk of changes. Symbols with past bugs or high churn are considered higher risk.
Thread Safety ¶
Safe for concurrent use after construction.
func NewPredictiveRiskScorer ¶
func NewPredictiveRiskScorer(g *graph.Graph, idx *index.SymbolIndex, store *history.HistoryStore) *PredictiveRiskScorer
NewPredictiveRiskScorer creates a new scorer.
func (*PredictiveRiskScorer) CalculateRisk ¶
func (p *PredictiveRiskScorer) CalculateRisk(ctx context.Context, symbolID string) (*PredictiveRisk, error)
CalculateRisk computes the predictive risk for a symbol.
Inputs ¶
- ctx: Context for cancellation.
- symbolID: The symbol to analyze.
Outputs ¶
- *PredictiveRisk: The calculated risk.
- error: Non-nil on failure.
func (*PredictiveRiskScorer) LoadBugHistory ¶
func (p *PredictiveRiskScorer) LoadBugHistory(history map[string]int)
LoadBugHistory loads bug history from a map.
func (*PredictiveRiskScorer) LoadChurnScores ¶
func (p *PredictiveRiskScorer) LoadChurnScores(scores map[string]float64)
LoadChurnScores loads churn scores from a map.
func (*PredictiveRiskScorer) RegisterBug ¶
func (p *PredictiveRiskScorer) RegisterBug(symbolID string)
RegisterBug records a bug for a symbol.
func (*PredictiveRiskScorer) UpdateChurnScore ¶
func (p *PredictiveRiskScorer) UpdateChurnScore(symbolID string, rate float64)
UpdateChurnScore updates the churn rate for a symbol.
type RiskConfig ¶
type RiskConfig struct {
CriticalThreshold int `json:"critical_threshold"`
HighThreshold int `json:"high_threshold"`
MediumThreshold int `json:"medium_threshold"`
}
RiskConfig allows customizing risk level thresholds.
Description ¶
Default thresholds work for typical projects but can be adjusted for utility libraries where functions commonly have many callers.
Fields ¶
- CriticalThreshold: Direct callers >= this is CRITICAL (default 20).
- HighThreshold: Direct callers >= this is HIGH (default 10).
- MediumThreshold: Direct callers >= this is MEDIUM (default 4).
func DefaultRiskConfig ¶
func DefaultRiskConfig() RiskConfig
DefaultRiskConfig returns risk thresholds with sensible defaults.
type RiskFactor ¶
type RiskFactor struct {
// Factor is the risk factor name.
Factor string `json:"factor"`
// Description explains the risk.
Description string `json:"description"`
// Weight is the contribution to the overall score (0-100).
Weight int `json:"weight"`
}
RiskFactor represents a factor contributing to rollback risk.
type RiskLevel ¶
type RiskLevel string
RiskLevel indicates the risk associated with a change.
const ( // RiskCritical means the change affects many callers or interfaces. // Examples: 20+ direct callers, changing an interface, shared utility. RiskCritical RiskLevel = "CRITICAL" // RiskHigh means significant impact but manageable. // Examples: 10-19 direct callers, exported public API. RiskHigh RiskLevel = "HIGH" // RiskMedium means moderate impact. // Examples: 4-9 direct callers, same package. RiskMedium RiskLevel = "MEDIUM" // RiskLow means minimal impact. // Examples: 0-3 direct callers, unexported. RiskLow RiskLevel = "LOW" )
type RollbackEnricher ¶
type RollbackEnricher struct {
// contains filtered or unexported fields
}
RollbackEnricher implements Enricher for rollback risk assessment.
func NewRollbackEnricher ¶
func NewRollbackEnricher(g *graph.Graph, idx *index.SymbolIndex) *RollbackEnricher
NewRollbackEnricher creates a rollback risk enricher.
func (*RollbackEnricher) Enrich ¶
func (e *RollbackEnricher) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
Enrich adds rollback risk information to the blast radius.
func (*RollbackEnricher) Name ¶
func (e *RollbackEnricher) Name() string
Name returns the enricher name.
func (*RollbackEnricher) Priority ¶
func (e *RollbackEnricher) Priority() int
Priority returns execution priority.
type RollbackRisk ¶
type RollbackRisk struct {
// Level is the overall risk level.
Level RollbackRiskLevel `json:"level"`
// Score is a numeric score (0-100, higher = harder to rollback).
Score int `json:"score"`
// IrreversibleChanges are changes that cannot be undone.
IrreversibleChanges []IrreversibleChange `json:"irreversible_changes,omitempty"`
// HighRiskFactors are factors contributing to rollback difficulty.
HighRiskFactors []RiskFactor `json:"high_risk_factors,omitempty"`
// MitigationSteps are suggested steps to enable safe rollback.
MitigationSteps []string `json:"mitigation_steps,omitempty"`
// RequiresDataMigration indicates if data migration is needed.
RequiresDataMigration bool `json:"requires_data_migration"`
// RequiresAPIVersioning indicates if API versioning is needed.
RequiresAPIVersioning bool `json:"requires_api_versioning"`
// EstimatedRecoveryComplexity estimates rollback complexity.
EstimatedRecoveryComplexity string `json:"estimated_recovery_complexity"`
}
RollbackRisk represents the risk assessment for rolling back a change.
type RollbackRiskAssessor ¶
type RollbackRiskAssessor struct {
// contains filtered or unexported fields
}
RollbackRiskAssessor assesses the risk and difficulty of rolling back changes.
Description ¶
Analyzes changes to identify irreversible or hard-to-rollback modifications such as database schema changes, API removals, and data migrations.
Thread Safety ¶
Safe for concurrent use after construction.
func NewRollbackRiskAssessor ¶
func NewRollbackRiskAssessor(g *graph.Graph, idx *index.SymbolIndex) *RollbackRiskAssessor
NewRollbackRiskAssessor creates a new assessor.
func (*RollbackRiskAssessor) AnalyzeDiff ¶
func (r *RollbackRiskAssessor) AnalyzeDiff(ctx context.Context, diff string) (*RollbackRisk, error)
AnalyzeDiff analyzes a diff for rollback risks.
func (*RollbackRiskAssessor) AssessChange ¶
func (r *RollbackRiskAssessor) AssessChange( ctx context.Context, changeType string, symbolID string, details map[string]string, ) (*RollbackRisk, error)
AssessChange assesses the rollback risk for a change.
Inputs ¶
- ctx: Context for cancellation.
- changeType: Type of change (e.g., "function_removed", "field_added").
- symbolID: The symbol being changed.
- details: Additional details about the change.
Outputs ¶
- *RollbackRisk: The risk assessment.
- error: Non-nil on failure.
type RollbackRiskLevel ¶
type RollbackRiskLevel string
RollbackRiskLevel represents the risk level for rollback.
const ( RollbackRiskLow RollbackRiskLevel = "LOW" RollbackRiskMedium RollbackRiskLevel = "MEDIUM" RollbackRiskHigh RollbackRiskLevel = "HIGH" RollbackRiskCritical RollbackRiskLevel = "CRITICAL" )
type SQLOperation ¶
type SQLOperation string
SQLOperation represents a type of SQL operation.
const ( SQLSelect SQLOperation = "SELECT" SQLInsert SQLOperation = "INSERT" SQLUpdate SQLOperation = "UPDATE" SQLDelete SQLOperation = "DELETE" SQLCreate SQLOperation = "CREATE" SQLAlter SQLOperation = "ALTER" SQLDrop SQLOperation = "DROP" )
type SchemaDepEnricher ¶
type SchemaDepEnricher struct {
// contains filtered or unexported fields
}
SchemaDepEnricher implements Enricher for schema dependency tracking.
func NewSchemaDepEnricher ¶
func NewSchemaDepEnricher(projectRoot string, g *graph.Graph, idx *index.SymbolIndex) *SchemaDepEnricher
NewSchemaDepEnricher creates an enricher for schema dependencies.
func (*SchemaDepEnricher) Enrich ¶
func (e *SchemaDepEnricher) Enrich(ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius) error
Enrich adds schema dependency information to the blast radius.
func (*SchemaDepEnricher) Invalidate ¶
func (e *SchemaDepEnricher) Invalidate()
Invalidate forces a rescan on next enrichment.
func (*SchemaDepEnricher) Name ¶
func (e *SchemaDepEnricher) Name() string
Name returns the enricher name.
func (*SchemaDepEnricher) Priority ¶
func (e *SchemaDepEnricher) Priority() int
Priority returns execution priority.
type SchemaDepTracker ¶
type SchemaDepTracker struct {
// contains filtered or unexported fields
}
SchemaDepTracker tracks database schema dependencies in code.
Description ¶
Detects SQL queries, ORM operations, and schema references in source code. Maps these to symbols to understand the database blast radius of changes.
Limitations ¶
SQL detection via regex has false-negative risk for:
- Dynamic SQL construction
- Heavily templated queries
- Non-standard SQL dialects
Thread Safety ¶
Safe for concurrent use after construction.
func NewSchemaDepTracker ¶
func NewSchemaDepTracker(projectRoot string, g *graph.Graph, idx *index.SymbolIndex) *SchemaDepTracker
NewSchemaDepTracker creates a new schema dependency tracker.
Inputs ¶
- projectRoot: Root directory of the project.
- g: The dependency graph.
- idx: The symbol index.
Outputs ¶
- *SchemaDepTracker: Ready-to-use tracker.
func (*SchemaDepTracker) AllDependencies ¶
func (t *SchemaDepTracker) AllDependencies() []SchemaDependency
AllDependencies returns all detected schema dependencies.
func (*SchemaDepTracker) FindSymbolDependencies ¶
func (t *SchemaDepTracker) FindSymbolDependencies(symbolID string) ([]SchemaDependency, error)
FindSymbolDependencies returns all schema dependencies for a symbol.
Inputs ¶
- symbolID: The symbol to get dependencies for.
Outputs ¶
- []SchemaDependency: All schema dependencies.
- error: Non-nil on failure.
func (*SchemaDepTracker) FindTableUsages ¶
func (t *SchemaDepTracker) FindTableUsages(tableName string) ([]SchemaDependency, error)
FindTableUsages returns all code locations that use a table.
Inputs ¶
- tableName: The table to search for.
Outputs ¶
- []SchemaDependency: All usages of the table.
- error: Non-nil on failure.
func (*SchemaDepTracker) Scan ¶
func (t *SchemaDepTracker) Scan(ctx context.Context) error
Scan analyzes the codebase for database dependencies.
Inputs ¶
- ctx: Context for cancellation.
Outputs ¶
- error: Non-nil on failure.
func (*SchemaDepTracker) Tables ¶
func (t *SchemaDepTracker) Tables() []string
Tables returns all tables that have dependencies.
type SchemaDependency ¶
type SchemaDependency struct {
// Table is the database table name.
Table string `json:"table"`
// Columns are specific columns referenced (if detectable).
Columns []string `json:"columns,omitempty"`
// Operation is the SQL operation type.
Operation SQLOperation `json:"operation"`
// SourceSymbol is the symbol containing this dependency.
SourceSymbol string `json:"source_symbol"`
// FilePath is the file containing the dependency.
FilePath string `json:"file_path"`
// Line is the line number of the dependency.
Line int `json:"line"`
// RawQuery is the detected SQL snippet (truncated for safety).
RawQuery string `json:"raw_query,omitempty"`
// ORM is the ORM framework detected (if any).
ORM string `json:"orm,omitempty"`
// Confidence is how confident we are in this detection (0-100).
Confidence int `json:"confidence"`
}
SchemaDependency represents a database dependency from code.
type SecurityPath ¶
type SecurityPath struct {
// IsSecuritySensitive indicates the symbol is in a security path.
IsSecuritySensitive bool `json:"is_security_sensitive"`
// PathType identifies the type of security path.
// One of: "AUTH", "AUTHZ", "PII", "CRYPTO", "SECRETS".
// Empty string if not security sensitive.
PathType string `json:"path_type,omitempty"`
// Reason explains why this was classified as security-sensitive.
// Human-readable explanation for agents.
Reason string `json:"reason,omitempty"`
// RequiresReview indicates whether changes need security review.
RequiresReview bool `json:"requires_review"`
// MatchedPatterns lists which patterns triggered detection.
// Useful for debugging false positives.
MatchedPatterns []string `json:"matched_patterns,omitempty"`
// CallChainSecurity indicates the symbol is called BY security code.
// A function may not look security-sensitive itself but is in the
// security call chain.
CallChainSecurity bool `json:"call_chain_security,omitempty"`
}
SecurityPath describes security-sensitive code paths.
Description ¶
Identifies whether the target symbol is in a security-sensitive path such as authentication, authorization, cryptography, or PII handling. When a symbol is in a security path, changes require extra scrutiny.
Path Types ¶
- AUTH: Authentication (login, logout, token validation)
- AUTHZ: Authorization (permissions, roles, access control)
- PII: Personal identifiable information handling
- CRYPTO: Cryptographic operations
- SECRETS: Secret/credential handling
Thread Safety ¶
Read-only after construction.
type SecurityPathDetector ¶
type SecurityPathDetector struct {
// contains filtered or unexported fields
}
SecurityPathDetector identifies security-sensitive code paths.
Description ¶
Analyzes symbol names and call chains to detect security-sensitive paths such as authentication, authorization, cryptography, and PII handling. Uses pre-compiled regex patterns for performance.
Detection Methods ¶
- Pattern matching on symbol name
- Call chain analysis (if target is called BY security code)
Thread Safety ¶
Safe for concurrent use. Patterns are pre-compiled at construction.
func NewSecurityPathDetector ¶
func NewSecurityPathDetector(patterns map[string][]string) (*SecurityPathDetector, error)
NewSecurityPathDetector creates a detector with the given patterns.
Description ¶
Creates a SecurityPathDetector with pre-compiled regex patterns. Invalid patterns are logged but don't cause construction to fail.
Inputs ¶
- patterns: Map of PathType -> regex patterns. Use DefaultSecurityPatterns for standard patterns, or provide custom patterns.
Outputs ¶
- *SecurityPathDetector: Ready-to-use detector.
- error: Non-nil if no valid patterns could be compiled.
Example ¶
detector, err := NewSecurityPathDetector(DefaultSecurityPatterns)
if err != nil {
return fmt.Errorf("failed to create detector: %w", err)
}
func (*SecurityPathDetector) AddPattern ¶
func (d *SecurityPathDetector) AddPattern(pathType, pattern string) error
AddPattern adds a pattern to an existing detector. Note: This creates a new compiled pattern; the detector is NOT fully thread-safe for pattern modification during use.
func (*SecurityPathDetector) Enrich ¶
func (d *SecurityPathDetector) Enrich( ctx context.Context, target *EnrichmentTarget, result *EnhancedBlastRadius, ) error
Enrich analyzes the target for security sensitivity.
Description ¶
Checks whether the target symbol or its callers are security-sensitive. Populates result.SecurityPath with findings.
Detection Logic ¶
- Check target symbol name against patterns
- Check target file path against patterns
- Check if any direct callers match security patterns (call chain)
Inputs ¶
- ctx: Context for cancellation.
- target: The symbol to analyze.
- result: The result to enrich.
Outputs ¶
- error: Non-nil on failure (should be rare for this enricher).
func (*SecurityPathDetector) GetPatterns ¶
func (d *SecurityPathDetector) GetPatterns() map[string][]string
GetPatterns returns the raw patterns for inspection/debugging.
func (*SecurityPathDetector) Name ¶
func (d *SecurityPathDetector) Name() string
Name returns the enricher identifier.
func (*SecurityPathDetector) Priority ¶
func (d *SecurityPathDetector) Priority() int
Priority returns 1 (critical analysis).
type SharedDep ¶
type SharedDep struct {
}
SharedDep represents a dependency shared between target and callers.
Description ¶
A shared dependency creates a "diamond" pattern where both the target and its callers depend on the same symbol. Changes to shared deps can have cascading effects.
Fields ¶
- ID: Unique symbol identifier.
- Name: Human-readable name.
- UsedBy: Callers that also use this dependency.
- UsageType: Type of shared usage ("diamond", "common_utility").
- Warning: Human-readable warning message.