From b42683185ac9ec58e4b6392c4959af387aae7f11 Mon Sep 17 00:00:00 2001 From: Wolfvin Date: Sun, 12 Jul 2026 01:38:05 +0700 Subject: [PATCH] fix(impact,history): tests field false-flagged all files + circular_deps_count always 0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. impact_engine.py: test_patterns included f.replace('.rs','_test.rs').replace('.py','_test.py') unconditionally. For any non-Rust/Python file (e.g. .ts), neither replace matches, so this candidate degenerates into the original filename f itself — which trivially exists on disk, so EVERY affected file got misclassified as its own test file. Found via real validation: impact --name signInWithGoogle listed calculator_widget.ts, errors.ts, sidepanel.ts as 'tests', none of which are test files. Fixed by gating the Rust/Python candidates on actual extension match. 2. history_engine.py: circular_deps_count read circ.get('cycle_count', 0), but detect_circular() returns 'total_cycles', never 'cycle_count' — so this metric silently stayed 0 regardless of how many cycles existed. Found via real validation: circular_deps_count read 0 while the circular_deps list (populated from the same detect_circular() call, right below) had 5 entries. dashboard_engine.py reads this same field from the snapshot metrics dict, so it inherits the fix automatically. --- scripts/history_engine.py | 7 ++++++- scripts/impact_engine.py | 13 ++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/scripts/history_engine.py b/scripts/history_engine.py index e9bd71d7..01204dfb 100644 --- a/scripts/history_engine.py +++ b/scripts/history_engine.py @@ -151,7 +151,12 @@ def collect_metrics(workspace: str, scan_result: Dict[str, Any]) -> Dict[str, An try: from circular_engine import detect_circular circ = detect_circular(workspace) - metrics["circular_deps_count"] = circ.get("cycle_count", 0) + # Bug: detect_circular() returns "total_cycles", never "cycle_count" — + # this always silently fell back to the 0 default regardless of how + # many cycles were actually found (found via real-codebase validation: + # circular_deps_count read 0 while the circular_deps list right below + # had 5 entries populated from the same detect_circular() call). + metrics["circular_deps_count"] = circ.get("total_cycles", 0) metrics["circular_deps"] = [] cycles = circ.get("cycles", circ.get("chains", {})) if isinstance(cycles, dict): diff --git a/scripts/impact_engine.py b/scripts/impact_engine.py index 5538cb87..cafa7647 100755 --- a/scripts/impact_engine.py +++ b/scripts/impact_engine.py @@ -296,8 +296,19 @@ def analyze_impact( test_patterns = [ f"{base}.test.ts", f"{base}.test.js", f"{base}.spec.ts", f"{base}.spec.js", f"{base}.test.tsx", f"{base}.spec.tsx", - f.replace(".rs", "_test.rs").replace(".py", "_test.py"), ] + # Rust/Python "_test" suffix convention — only applicable to files of + # that extension. Bug: str.replace() is a no-op when the extension + # doesn't match (e.g. a .ts file has no ".rs"/".py" substring), so the + # "pattern" silently degenerated into the original filename `f` itself + # — which trivially exists on disk, causing EVERY affected file to be + # misclassified as its own test file (found via real-codebase + # validation: impact --name signInWithGoogle listed calculator_widget.ts, + # errors.ts, sidepanel.ts as "tests", none of which are test files). + if f.endswith(".rs"): + test_patterns.append(f[:-3] + "_test.rs") + elif f.endswith(".py"): + test_patterns.append(f[:-3] + "_test.py") for tf in test_patterns: full_path = os.path.join(workspace, tf) if os.path.exists(full_path):