@@ -454,17 +454,16 @@ def _detect_vulns(workspace: str, max_items: int) -> Optional[Dict]:
454454 total = vuln .get ("stats" , {}).get ("total_vulnerabilities" , 0 )
455455 if total == 0 :
456456 return None
457- else :
458- return {
459- "category" : "vulnerabilities" ,
460- "label" : "Known CVEs" ,
461- "total" : total ,
462- "severity" : "critical" ,
463- "by_severity" : vuln .get ("stats" , {}).get ("by_severity" , {}),
464- "top_items" : vuln .get ("vulnerabilities" , [])[:max_items ],
465- "action" : "Update vulnerable dependencies immediately — check npm audit, pip audit, cargo audit, or govulncheck" ,
466- "impact" : "Known vulnerabilities can be exploited by attackers even without source code access" ,
467- }
457+ return {
458+ "category" : "vulnerabilities" ,
459+ "label" : "Known CVEs" ,
460+ "total" : total ,
461+ "severity" : "critical" ,
462+ "by_severity" : vuln .get ("stats" , {}).get ("by_severity" , {}),
463+ "top_items" : vuln .get ("vulnerabilities" , [])[:max_items ],
464+ "action" : "Update vulnerable dependencies immediately — check npm audit, pip audit, cargo audit, or govulncheck" ,
465+ "impact" : "Known vulnerabilities can be exploited by attackers even without source code access" ,
466+ }
468467
469468
470469def _detect_dataflow (workspace : str , max_items : int ) -> Optional [Dict ]:
@@ -473,16 +472,15 @@ def _detect_dataflow(workspace: str, max_items: int) -> Optional[Dict]:
473472 violations = df .get ("stats" , {}).get ("violations" , 0 )
474473 if violations == 0 :
475474 return None
476- else :
477- return {
478- "category" : "dataflow_violations" ,
479- "label" : "Unsafe Data Flows" ,
480- "total" : violations ,
481- "severity" : "high" ,
482- "top_items" : df .get ("violations" , [])[:max_items ],
483- "action" : "Add input sanitization and output encoding at every source→sink boundary" ,
484- "impact" : "Untainted data flows can lead to SQL injection, XSS, and command injection attacks" ,
485- }
475+ return {
476+ "category" : "dataflow_violations" ,
477+ "label" : "Unsafe Data Flows" ,
478+ "total" : violations ,
479+ "severity" : "high" ,
480+ "top_items" : df .get ("violations" , [])[:max_items ],
481+ "action" : "Add input sanitization and output encoding at every source→sink boundary" ,
482+ "impact" : "Untainted data flows can lead to SQL injection, XSS, and command injection attacks" ,
483+ }
486484
487485
488486def _detect_env (workspace : str , max_items : int ) -> Optional [Dict ]:
@@ -495,20 +493,19 @@ def _detect_env(workspace: str, max_items: int) -> Optional[Dict]:
495493 issues = undocumented # Each undocumented var is an issue
496494 if issues == 0 and total_vars == 0 :
497495 return None
498- else :
499- return {
500- "category" : "env_issues" ,
501- "label" : "Environment Issues" ,
502- "total" : issues ,
503- "severity" : "medium" ,
504- "top_items" : [{"name" : v .get ("name" ), "is_required" : v .get ("is_required" ),
505- "has_fallback" : v .get ("has_fallback" ),
506- "documentation" : v .get ("documentation" )}
507- for v in env .get ("variables" , [])[:max_items ]
508- if not v .get ("documentation" )],
509- "action" : "Review .env files, ensure secrets are not committed, add .env to .gitignore" ,
510- "impact" : "Misconfigured environment variables can leak secrets or cause runtime failures" ,
511- }
496+ return {
497+ "category" : "env_issues" ,
498+ "label" : "Environment Issues" ,
499+ "total" : issues ,
500+ "severity" : "medium" ,
501+ "top_items" : [{"name" : v .get ("name" ), "is_required" : v .get ("is_required" ),
502+ "has_fallback" : v .get ("has_fallback" ),
503+ "documentation" : v .get ("documentation" )}
504+ for v in env .get ("variables" , [])[:max_items ]
505+ if not v .get ("documentation" )],
506+ "action" : "Review .env files, ensure secrets are not committed, add .env to .gitignore" ,
507+ "impact" : "Misconfigured environment variables can leak secrets or cause runtime failures" ,
508+ }
512509
513510
514511def _detect_smells (workspace : str , severity_filter : set , max_items : int ) -> Optional [Dict ]:
@@ -561,17 +558,16 @@ def _detect_complexity(workspace: str, max_items: int) -> Optional[Dict]:
561558 hotspots = comp .get ("hotspots" , [])
562559 if not hotspots :
563560 return None
564- else :
565- return {
566- "category" : "complexity" ,
567- "label" : "Complexity Hotspots" ,
568- "total" : len (hotspots ),
569- "severity" : "high" if any (h .get ("cyclomatic" , 0 ) > 20 for h in hotspots ) else "medium" ,
570- "avg_cyclomatic" : comp .get ("stats" , {}).get ("avg_cyclomatic" , 0 ),
571- "top_items" : hotspots [:max_items ],
572- "action" : "Refactor high-complexity functions by extracting helper methods, reducing branches, and simplifying conditionals" ,
573- "impact" : "Complex functions are bug magnets — they're hard to test, understand, and maintain" ,
574- }
561+ return {
562+ "category" : "complexity" ,
563+ "label" : "Complexity Hotspots" ,
564+ "total" : len (hotspots ),
565+ "severity" : "high" if any (h .get ("cyclomatic" , 0 ) > 20 for h in hotspots ) else "medium" ,
566+ "avg_cyclomatic" : comp .get ("stats" , {}).get ("avg_cyclomatic" , 0 ),
567+ "top_items" : hotspots [:max_items ],
568+ "action" : "Refactor high-complexity functions by extracting helper methods, reducing branches, and simplifying conditionals" ,
569+ "impact" : "Complex functions are bug magnets — they're hard to test, understand, and maintain" ,
570+ }
575571
576572
577573def _detect_dead_code (workspace : str , max_items : int ) -> Optional [Dict ]:
@@ -580,17 +576,16 @@ def _detect_dead_code(workspace: str, max_items: int) -> Optional[Dict]:
580576 total = dc .get ("stats" , {}).get ("total_dead_code" , 0 )
581577 if total == 0 :
582578 return None
583- else :
584- return {
585- "category" : "dead_code" ,
586- "label" : "Dead Code" ,
587- "total" : total ,
588- "severity" : "medium" ,
589- "by_category" : dc .get ("stats" , {}).get ("by_category" , {}),
590- "top_items" : dc .get ("results" , {}).get ("unreachable" , [])[:max_items ],
591- "action" : "Remove dead code in batches with testing — start with unreachable code and unused exports" ,
592- "impact" : "Dead code increases maintenance burden, confuses new developers, and bloats the codebase" ,
593- }
579+ return {
580+ "category" : "dead_code" ,
581+ "label" : "Dead Code" ,
582+ "total" : total ,
583+ "severity" : "medium" ,
584+ "by_category" : dc .get ("stats" , {}).get ("by_category" , {}),
585+ "top_items" : dc .get ("results" , {}).get ("unreachable" , [])[:max_items ],
586+ "action" : "Remove dead code in batches with testing — start with unreachable code and unused exports" ,
587+ "impact" : "Dead code increases maintenance burden, confuses new developers, and bloats the codebase" ,
588+ }
594589
595590
596591def _detect_circular (workspace : str , max_items : int ) -> Optional [Dict ]:
@@ -623,17 +618,16 @@ def _detect_perf(workspace: str, max_items: int) -> Optional[Dict]:
623618 total = perf .get ("stats" , {}).get ("total_hints" , 0 )
624619 if total == 0 :
625620 return None
626- else :
627- return {
628- "category" : "perf_hints" ,
629- "label" : "Performance Issues" ,
630- "total" : total ,
631- "severity" : perf .get ("risk" , "low" ),
632- "by_category" : perf .get ("stats" , {}).get ("by_category" , {}),
633- "top_items" : perf .get ("hints" , [])[:max_items ],
634- "action" : "Address N+1 queries first (critical), then sync blocking, then memory leaks" ,
635- "impact" : "Performance issues compound — N+1 queries scale linearly with data size, blocking calls freeze the event loop" ,
636- }
621+ return {
622+ "category" : "perf_hints" ,
623+ "label" : "Performance Issues" ,
624+ "total" : total ,
625+ "severity" : perf .get ("risk" , "low" ),
626+ "by_category" : perf .get ("stats" , {}).get ("by_category" , {}),
627+ "top_items" : perf .get ("hints" , [])[:max_items ],
628+ "action" : "Address N+1 queries first (critical), then sync blocking, then memory leaks" ,
629+ "impact" : "Performance issues compound — N+1 queries scale linearly with data size, blocking calls freeze the event loop" ,
630+ }
637631
638632
639633def _detect_config_drift (workspace : str , max_items : int ) -> Optional [Dict ]:
@@ -642,16 +636,15 @@ def _detect_config_drift(workspace: str, max_items: int) -> Optional[Dict]:
642636 total = drift .get ("stats" , {}).get ("total_drift_items" , 0 )
643637 if total == 0 :
644638 return None
645- else :
646- return {
647- "category" : "config_drift" ,
648- "label" : "Dependency Drift" ,
649- "total" : total ,
650- "severity" : "low" ,
651- "top_items" : drift .get ("drift_items" , [])[:max_items ],
652- "action" : "Update outdated dependencies to reduce security risk and get bug fixes" ,
653- "impact" : "Outdated dependencies may contain unpatched security vulnerabilities" ,
654- }
639+ return {
640+ "category" : "config_drift" ,
641+ "label" : "Dependency Drift" ,
642+ "total" : total ,
643+ "severity" : "low" ,
644+ "top_items" : drift .get ("drift_items" , [])[:max_items ],
645+ "action" : "Update outdated dependencies to reduce security risk and get bug fixes" ,
646+ "impact" : "Outdated dependencies may contain unpatched security vulnerabilities" ,
647+ }
655648
656649
657650def _detect_binaries (workspace : str , max_items : int ) -> Optional [Dict ]:
@@ -660,18 +653,17 @@ def _detect_binaries(workspace: str, max_items: int) -> Optional[Dict]:
660653 total = bins .get ("stats" , {}).get ("total_artifacts" , 0 )
661654 if total == 0 :
662655 return None
663- else :
664- return {
665- "category" : "binary_artifacts" ,
666- "label" : "Binary/Compiled Files" ,
667- "total" : total ,
668- "severity" : "low" ,
669- "by_category" : bins .get ("stats" , {}).get ("by_category" , {}),
670- "top_items" : bins .get ("findings" , [])[:max_items ],
671- "recommendations" : bins .get ("recommendations" , []),
672- "action" : "Add binary files to .gitignore and use build pipelines instead" ,
673- "impact" : "Binary files bloat the repository, make diffs meaningless, and may contain vulnerable code" ,
674- }
656+ return {
657+ "category" : "binary_artifacts" ,
658+ "label" : "Binary/Compiled Files" ,
659+ "total" : total ,
660+ "severity" : "low" ,
661+ "by_category" : bins .get ("stats" , {}).get ("by_category" , {}),
662+ "top_items" : bins .get ("findings" , [])[:max_items ],
663+ "recommendations" : bins .get ("recommendations" , []),
664+ "action" : "Add binary files to .gitignore and use build pipelines instead" ,
665+ "impact" : "Binary files bloat the repository, make diffs meaningless, and may contain vulnerable code" ,
666+ }
675667
676668
677669# ─── Helper Functions ──────────────────────────────────────
0 commit comments