analysis

package
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 11, 2026 License: AGPL-3.0 Imports: 22 Imported by: 0

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

View Source
const (
	DeadReasonNoCallers    = "no_callers"
	DeadReasonNoReferences = "no_references"
	DeadReasonTestOnly     = "test_only"
	DeadReasonUnreachable  = "unreachable"
)

DeadCodeReason constants explain why code is considered dead.

View Source
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.

View Source
const (
	// ConfidenceHigh means >= 90% confidence.
	ConfidenceHigh = "HIGH"

	// ConfidenceMedium means 70-89% confidence.
	ConfidenceMedium = "MEDIUM"

	// ConfidenceLow means < 70% confidence.
	ConfidenceLow = "LOW"
)

Confidence level constants.

View Source
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.

View Source
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.

View Source
const MaxCoverageFileSize = 50 * 1024 * 1024 // 50MB

MaxCoverageFileSize is the maximum size of coverage files to parse.

Variables

View Source
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.

View Source
var ConfidenceThresholds = struct {
	High   int
	Medium int
}{
	High:   90,
	Medium: 70,
}

ConfidenceThresholds defines threshold values for confidence levels.

View Source
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

func GetChurnLevel(changesLast30Days int) string

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.

func (*APIDepTracker) Scan

func (t *APIDepTracker) Scan(ctx context.Context) error

Scan analyzes the codebase for API dependencies.

Inputs

  • ctx: Context for cancellation.

Outputs

  • error: Non-nil on failure.

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 APIType

type APIType string

APIType represents the type of API.

const (
	APITypeREST    APIType = "REST"
	APITypeGraphQL APIType = "GRAPHQL"
	APITypeGRPC    APIType = "GRPC"
	APITypeWebhook APIType = "WEBHOOK"
)

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"`
	SharedDeps      []SharedDep   `json:"shared_deps,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

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.

func (*ConfigDepTracker) Scan

func (t *ConfigDepTracker) Scan(ctx context.Context) error

Scan analyzes the codebase for configuration dependencies.

Inputs

  • ctx: Context for cancellation.

Outputs

  • error: Non-nil on failure.

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

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

  1. Run base BlastRadiusAnalyzer.Analyze() to get CB-17 result
  2. Group enrichers by priority
  3. For each priority group (in order): run enrichers in parallel via errgroup
  4. 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:

  1. Validates input
  2. Runs CB-17 base analysis
  3. Runs enrichers grouped by priority
  4. 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

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

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

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

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

  1. Pattern matching on symbol name
  2. 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

  1. Check target symbol name against patterns
  2. Check target file path against patterns
  3. 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 {
	ID        string   `json:"id"`
	Name      string   `json:"name"`
	UsedBy    []string `json:"used_by"`
	UsageType string   `json:"usage_type"`
	Warning   string   `json:"warning"`
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL