Found in a read-only audit of v2.3.8. Verified against current main.
Three smaller defects around the watcher and the root guard, grouped because they share a cause: state that is decided once and then trusted.
1. Ignore patterns are snapshotted at startup
The supervisor and the event handler both capture _load_ignore_patterns(repo_root) when the watcher starts (code_review_graph/incremental.py:2163). A Maven module that first builds after that point has its target/ indexed, and because watch-mode updates run with reconcile_stale=False, those rows survive even after the nested-ignore cache refreshes.
2. The root guard accepts partial overlap
_assert_graph_matches_root passes when any stored marker sits below the requested root (:1120). A graph holding both /repo and /repo/nested paths therefore passes a run anchored at /repo/nested, which then purges everything outside it. Narrower than the total mismatch #889 fixed, but the same shape.
3. Qoder skills are never installed from a wheel
install_qoder_skills copies <target repo>/skills (code_review_graph/skills.py:2025), but skills/ ships only in the sdist — the wheel packages code_review_graph alone (pyproject.toml). A real installed-wheel run writes .qoder/mcp.json correctly and then prints No skills/ directory found, installing zero skills. MCP configuration and hooks are unaffected.
The fix is to ship the skills inside the package and read them through importlib.resources, rather than looking for them in the user's repository.
Found in a read-only audit of v2.3.8. Verified against current
main.Three smaller defects around the watcher and the root guard, grouped because they share a cause: state that is decided once and then trusted.
1. Ignore patterns are snapshotted at startup
The supervisor and the event handler both capture
_load_ignore_patterns(repo_root)when the watcher starts (code_review_graph/incremental.py:2163). A Maven module that first builds after that point has itstarget/indexed, and because watch-mode updates run withreconcile_stale=False, those rows survive even after the nested-ignore cache refreshes.2. The root guard accepts partial overlap
_assert_graph_matches_rootpasses when any stored marker sits below the requested root (:1120). A graph holding both/repoand/repo/nestedpaths therefore passes a run anchored at/repo/nested, which then purges everything outside it. Narrower than the total mismatch #889 fixed, but the same shape.3. Qoder skills are never installed from a wheel
install_qoder_skillscopies<target repo>/skills(code_review_graph/skills.py:2025), butskills/ships only in the sdist — the wheel packagescode_review_graphalone (pyproject.toml). A real installed-wheel run writes.qoder/mcp.jsoncorrectly and then printsNo skills/ directory found, installing zero skills. MCP configuration and hooks are unaffected.The fix is to ship the skills inside the package and read them through
importlib.resources, rather than looking for them in the user's repository.