fix(risk): normalize the git_metadata target path in get_risk - #1849
fix(risk): normalize the git_metadata target path in get_risk#1849sloemo01 wants to merge 1 commit into
Conversation
…n get_risk get_risk matches git_metadata.file_path by exact string equality, but callers hand the path over in many forms — backslashes (Windows), a leading ./, a trailing separator, or a repo-absolute path — while file_path is stored POSIX-relative. Any of those made the row lookup miss, and _assess_one_target then reported the indistinguishable "no git metadata available" card (hotspot_score=0, primary_owner=None, empty co_change_partners) even though the row exists (issue repowise-dev#1279). Normalize the target once in _assess_one_target and key every file-path lookup (git_metadata, graph edges/nodes, test gap, security signals) on the normalized form, while keeping the response keyed by the caller's exact string. Add a regression test covering backslash, ./, trailing-slash, duplicate-slash, and repo-absolute forms.
|
✅ Health of changed files: 2.9 → 3.2 (+0.3) 📋 At a glance Files & modules (2)
✅ Health gate: passed 📌 Before you merge
🔎 More signals (2)🗺️ Change map flowchart LR
subgraph PR ["Changed in this PR (1 with dependents)"]
f_packages_server_src_repowise_server_mcp_server_tool_risk_assessment_py[".../tool_risk/assessment.py 🔥"]:::changed
end
f_packages_server_src_repowise_server_mcp_server_tool_context_targets_py[".../tool_context/targets.py"]
f_packages_server_src_repowise_server_mcp_server_tool_risk_assessment_py --> f_packages_server_src_repowise_server_mcp_server_tool_context_targets_py
f_packages_server_src_repowise_server_mcp_server_tool_risk___init___py[".../tool_risk/__init__.py"]
f_packages_server_src_repowise_server_mcp_server_tool_risk_assessment_py --> f_packages_server_src_repowise_server_mcp_server_tool_risk___init___py
f_packages_server_src_repowise_server_mcp_server_tool_risk_get_risk_py[".../tool_risk/get_risk.py"]
f_packages_server_src_repowise_server_mcp_server_tool_risk_assessment_py --> f_packages_server_src_repowise_server_mcp_server_tool_risk_get_risk_py
t_tests_unit_persistence_test_test_gap_graph_floor_py(["✅ .../persistence/test_test_gap_graph_floor.py"]):::guard
t_tests_unit_persistence_test_test_gap_graph_floor_py -.-> f_packages_server_src_repowise_server_mcp_server_tool_risk_assessment_py
classDef changed fill:#dbeafe,stroke:#1d4ed8,color:#1e3a5f
classDef warn fill:#fef3c7,stroke:#b45309,color:#78350f
classDef guard fill:#dcfce7,stroke:#15803d,color:#14532d
Solid arrows: code that imports the changed files (3 direct dependents, from the last indexed snapshot). Dashed: history/tests. 🔥 Hotspots touched (2)
👀 Suggested reviewers @RaghavChamadiya 📊 See the full report for this PR |
Ayush7614
left a comment
There was a problem hiding this comment.
Verified: packages/server/src/repowise/server/mcp_server/tool_risk/assessment.py:1 adds normalize_target_path handling backslash, ./, trailing slash, repo-absolute → POSIX-relative, fixing #1279 where exact-string lookup returned hotspot_score=0. All lookups now use normalized path while response keeps raw target. Parametrized tests in test_risk.py cover forms. Correct fix — LGTM.
|
Thanks @sloemo01. The framing is right: a caller-side path that misses the row produces the One line in normalized = normalized.lstrip("/").lstrip(".")
Every dot-directory loses its dot, so A prefix strip is what you want: if normalized.startswith("./"):
normalized = normalized[2:]
normalized = normalized.lstrip("/")Two smaller things in the same function, both non-blocking: The The rest of the PR is good and the trailing-separator and duplicate-slash handling is worth having. Push the prefix strip and I will take it. |
Summary
Fixes #1279:
get_riskreturnedhotspot_score=0,primary_owner=null,co_change_partners=[], and a"no git metadata available"summary for files that do have richgit_metadatarows.Root cause
_assess_one_targetlooked up theGitMetadatarow by exact string equality onfile_pathagainst the caller's raw target. The index storesfile_pathPOSIX-relative (src/auth/service.py), but callers reachget_riskthrough git tools, shell completion, or editors that hand over:src\auth\service.py, common on Windows),./,/abs/repo/src/auth/service.py).Any of these made the lookup miss, so
metawasNoneand_assess_one_targetemitted the indistinguishable "no git metadata available" card — the exact payload the reporter saw. (The v0.37 column names were already correct; the lookup simply never found the row.)Change
normalize_target_path(target, repo_root)inassessment.py: converts backslashes to/, strips a leading./and any leading slash, collapses duplicate/trailing separators, and makes a repo-absolute path relative torepository.local_path._assess_one_target, normalize the target once and key every file-path lookup (git_metadata, graph edges/nodes, test gap, security signals) on the normalized form, while keeping the response keyed by the caller's exact string.Tests
Added regression tests in
tests/unit/server/mcp/test_risk.py:test_get_risk_normalizes_target_path— backslash,./, trailing-slash forms now populatehotspot_score/primary_owner/co_change_partners.test_get_risk_repo_absolute_target_path— repo-absolute form resolves.test_normalize_target_path— parametrized unit coverage of the helper.Ruff + all
test_risk.py/test_risk_dependency_edges.pytests pass.