Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion fix_test.sh

This file was deleted.

47 changes: 38 additions & 9 deletions internal/campaign/edge_case_detector.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ func (d *EdgeCaseDetector) AnalyzeFiles(ctx context.Context, paths []string, int
decisions := make([]FileDecision, 0, len(paths))

for _, path := range paths {
if path == "" {
decisions = append(decisions, FileDecision{Path: path, RecommendedAction: ActionSkip, Reasoning: "Empty path", Language: "unknown"})
continue
}
select {
case <-ctx.Done():
logging.Campaign("Edge case analysis interrupted: %d/%d files analyzed before timeout", len(decisions), len(paths))
Expand Down Expand Up @@ -282,7 +286,9 @@ func (d *EdgeCaseDetector) analyzeFile(ctx context.Context, path string, intel *
}

// Gather metrics from intelligence report
d.gatherMetrics(&decision, path, intel)
if err := d.gatherMetrics(ctx, &decision, path, intel); err != nil {
return FileDecision{Path: path, RecommendedAction: ActionSkip, Reasoning: "Analysis cancelled"}
}

// Apply decision logic
decision.RecommendedAction, decision.Reasoning = d.determineAction(decision)
Expand All @@ -294,9 +300,13 @@ func (d *EdgeCaseDetector) analyzeFile(ctx context.Context, path string, intel *
}

// gatherMetrics populates decision metrics from intelligence data.
func (d *EdgeCaseDetector) gatherMetrics(decision *FileDecision, path string, intel *IntelligenceReport) {
func (d *EdgeCaseDetector) gatherMetrics(ctx context.Context, decision *FileDecision, path string, intel *IntelligenceReport) error {
if intel == nil {
return
return nil
}

if err := ctx.Err(); err != nil {
return err
}

// Get churn rate from git history
Expand Down Expand Up @@ -327,20 +337,31 @@ func (d *EdgeCaseDetector) gatherMetrics(decision *FileDecision, path string, in

// Query kernel for dependencies
if d.kernel != nil {
d.queryDependencies(decision, path)
d.queryComplexity(decision, path)
if err := d.queryDependencies(ctx, decision, path); err != nil {
return err
}
if err := d.queryComplexity(ctx, decision, path); err != nil {
return err
}
}
return nil
}

// queryDependencies gets file dependencies from the kernel.
func (d *EdgeCaseDetector) queryDependencies(decision *FileDecision, path string) {
func (d *EdgeCaseDetector) queryDependencies(ctx context.Context, decision *FileDecision, path string) error {
if err := ctx.Err(); err != nil {
return err
}
// Query dependency_link for dependencies
facts, err := d.kernel.Query("dependency_link")
if err != nil {
return
return nil
}

for _, fact := range facts {
if err := ctx.Err(); err != nil {
return err
}
if len(fact.Args) >= 3 {
file := d.parseArg(fact.Args[0])
imported := d.parseArg(fact.Args[2])
Expand All @@ -356,21 +377,28 @@ func (d *EdgeCaseDetector) queryDependencies(decision *FileDecision, path string

// Calculate impact score based on dependents
decision.ImpactScore = len(decision.Dependents)
return nil
}

// queryComplexity estimates complexity from kernel facts.
func (d *EdgeCaseDetector) queryComplexity(decision *FileDecision, path string) {
func (d *EdgeCaseDetector) queryComplexity(ctx context.Context, decision *FileDecision, path string) error {
if err := ctx.Err(); err != nil {
return err
}
// Query for complexity-related facts
facts, err := d.kernel.Query("cyclomatic_complexity")
if err != nil {
return
return nil
}

var (
maxComplexity float64
hasComplexity bool
)
for _, fact := range facts {
if err := ctx.Err(); err != nil {
return err
}
if len(fact.Args) >= 3 {
file := d.parseArg(fact.Args[0])
if d.matchesPath(file, path) {
Expand All @@ -391,6 +419,7 @@ func (d *EdgeCaseDetector) queryComplexity(decision *FileDecision, path string)
// Rough heuristic: 1 complexity point per 50 lines
decision.Complexity = float64(decision.LineCount) / 50.0
}
return nil
}

// determineAction decides what action to take based on gathered metrics.
Expand Down