Skip to content

fix(skills): remove all existing code-review-graph hook entries on reinstall (#558) - #836

Open
Blazehue wants to merge 3 commits into
tirth8205:stagingfrom
Blazehue:fix/hooks-incremental-flow-paths
Open

Blazehue wants to merge 3 commits into
tirth8205:stagingfrom
Blazehue:fix/hooks-incremental-flow-paths

Conversation

@Blazehue

@Blazehue Blazehue commented Aug 8, 2026 •

Copy link
Copy Markdown

I'll update #558 for the same:

Summary

  • Updated _merge_hooks_into_settings in code_review_graph/skills.py to filter out all existing code-review-graph hook entries before appending the new dynamic hook config. This purges stale absolute-path entries and accumulated duplicate hooks on re-installation.
  • Added test_install_hooks_replaces_old_and_duplicate_hooks in tests/test_skills.py seeding an old-style absolute-path hook and duplicate entries, asserting that custom user hooks are preserved while all old CRG entries are replaced by a single dynamic git rev-parse hook.

Verification

  • Tested with pytest tests/test_skills.py (192 passed).

@tirth8205

Copy link
Copy Markdown
Owner

Thanks. Two parts.

The flows change does not fix #569 in the scenario the issue describes. os.path.abspath and Path.resolve at flows.py:489-497 resolve against the process cwd, not the repo root, and incremental_trace_flows never receives the root (tools/build.py:164 has it and does not pass it). Run the MCP server or daemon with cwd outside the repo and the new entry point is still missed. Your test only passes because pytest runs from the repo root. #673 threads repo_root through properly, so I will take that for flows. Please drop the flows.py and test_flows.py hunks.

The hooks dedup is worth keeping, with two changes. Remove all existing code-review-graph entries instead of only the first (skills.py:1041-1046 breaks after one match), otherwise users who already accumulated duplicates keep the stale ones. And the regression test passes on main unchanged, since identical reinstalls were already deduped. Seed an old-style absolute-path hook and assert it is replaced.

#576 is already fixed on main and closed, so drop it from the description.

@Blazehue
Blazehue force-pushed the fix/hooks-incremental-flow-paths branch from 6c733eb to 059f559 Compare August 22, 2026 02:42
@Blazehue Blazehue changed the title fix(hooks,flows): prevent duplicate hooks on reinstall and resolve relative vs absolute path mismatch (#558, #569, #576) fix(skills): remove all existing code-review-graph hook entries on reinstall (#558) Aug 22, 2026
@tirth8205

Copy link
Copy Markdown
Owner

Changes required: the hook migration deletes unrelated user commands within a mixed entry. In .claude/settings.json, place custom-audit --important and code-review-graph update --repo /old/path as sibling commands in one PostToolUse entry, then call code_review_graph.skills.install_hooks(repo_root, platform='claude'); this PR removes the whole entry, including custom-audit. Remove only demonstrably owned inner hooks, and resolve flow paths against the repository root rather than the process working directory.

@tirth8205
tirth8205 changed the base branch from main to staging September 15, 2026 13:12
@tirth8205

tirth8205 commented Sep 15, 2026 •

Copy link
Copy Markdown
Owner

This fails the checks once merged into staging.

pytest (py3.13): "3225 passed, 9 skipped, 2 xpassed, 1 warning in 176.81s". ruff: "E501 Line too long (104 > 100) --> code_review_graph/skills.py:1263:101 ... Found 1 error." (the PR's own new comment line; origin/staging skills.py passes ruff clean, so this is the PR's fault). mypy: "Success: no issues found in 72 source files".

To fix:

  • Fix ruff E501 at code_review_graph/skills.py:1263 (comment line is 104 chars).
  • Test that a user-defined hook whose command contains the substring 'code-review-graph' (but is not a CRG hook) is preserved, or narrow _is_crg_hook to match the actual generated command shapes (e.g. 'code-review-graph update' / 'code-review-graph status').
  • Test for stale CRG hooks under event names the generator no longer emits (legacy 'PreCommit'), which [Bug]: claude-code hooks in settings.json shall not contain absolute paths to the repo #558 asks to be replaced but which this PR leaves in place.
  • Test seeding a stale SessionStart CRG entry and asserting it is replaced.

Merge origin/staging into your branch first to reproduce it.

PRs now target staging, not main. Yours was retargeted already, so nothing to do there.

@tirth8205 tirth8205 added the checks-failing Fails CI when merged into staging label Sep 15, 2026
Blazehue added a commit to Blazehue/code-review-graph that referenced this pull request Sep 16, 2026
…oks (tirth8205#558)

Address staging review on tirth8205#836:

- Fix ruff E501 in skills.py (the merge comment exceeded 100 chars).
- Narrow CRG-hook detection to the command shapes the generator installs
  (`code-review-graph update` / `status` / `detect-changes`) instead of the
  bare `code-review-graph` substring, so a user hook that merely mentions the
  tool is no longer purged.
- Strip only CRG-owned inner hooks from a mixed entry, preserving sibling
  user commands, rather than dropping the whole entry.
- Sweep every existing hook event (not just the ones being re-emitted) so
  stale CRG entries under legacy events the generator no longer emits (e.g.
  `PreCommit`) and orphaned `SessionStart` entries are removed on reinstall;
  already-empty user event lists are left untouched.

Tests: user hook mentioning CRG preserved; sibling command in a mixed entry
preserved; stale legacy PreCommit entry removed; stale SessionStart entry
replaced by the current dynamic hook.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…oks (tirth8205#558)

Address staging review on tirth8205#836:

- Fix ruff E501 in skills.py (the merge comment exceeded 100 chars).
- Narrow CRG-hook detection to the command shapes the generator installs
  (`code-review-graph update` / `status` / `detect-changes`) instead of the
  bare `code-review-graph` substring, so a user hook that merely mentions the
  tool is no longer purged.
- Strip only CRG-owned inner hooks from a mixed entry, preserving sibling
  user commands, rather than dropping the whole entry.
- Sweep every existing hook event (not just the ones being re-emitted) so
  stale CRG entries under legacy events the generator no longer emits (e.g.
  `PreCommit`) and orphaned `SessionStart` entries are removed on reinstall;
  already-empty user event lists are left untouched.

Tests: user hook mentioning CRG preserved; sibling command in a mixed entry
preserved; stale legacy PreCommit entry removed; stale SessionStart entry
replaced by the current dynamic hook.
@Blazehue
Blazehue force-pushed the fix/hooks-incremental-flow-paths branch from 33729af to 9b7e32c Compare September 16, 2026 07:25

@Blazehue Blazehue left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed checklist — all four items are addressed in 9b7e32c.

  1. ruff E501 (skills.py) fixed. The over-length merge comment is gone; ruff check code_review_graph/ is clean.

  2. _is_crg_hook too broad narrowed. Detection now keys off the command shapes the generator actually installs (code-review-graph update / status / detect-changes) via a new _is_crg_command() helper, instead of the bare code-review-graph substring. Added a test seeding a user hook whose command only mentions code-review-graph (an echo) and asserting it survives reinstall.

  3. Stale legacy PreCommit entries — the merge now sweeps every existing hook event, not just the ones being re-emitted, so orphaned CRG entries under events the generator no longer emits are removed. Added a test seeding a stale PreCommit CRG entry and asserting it's purged.

  4. Stale SessionStart entry added a test seeding a stale absolute-path SessionStart CRG entry and asserting it's replaced by the current dynamic (git rev-parse --show-toplevel) hook.

I also carried over your earlier mixed-entry concern: _strip_owned_hooks() removes only the CRG-owned inner hooks from an entry, so a sibling user command (e.g. custom-audit --important) in the same PostToolUse entry is preserved rather than the whole entry being dropped. Already-empty user event lists are left untouched. There's a dedicated test for that case too.

Merged origin/staging locally to reproduce as you suggested. Verified against staging:

ruff check code_review_graph/ — clean
mypy code_review_graph/ — no issues in 72 source files
pytest tests/ — 3232 passed, 9 skipped, 2 xpassed

@tirth8205

Copy link
Copy Markdown
Owner

This no longer merges into staging. The one conflict is code_review_graph/skills.py, and the branch is 228 commits behind.

git fetch origin
git merge origin/staging
# resolve, then
uv run pytest tests/ -q
uv run ruff check code_review_graph/
uv run mypy code_review_graph/ --ignore-missing-imports --no-strict-optional
git push

I have not reviewed the change itself yet. That comes once it merges and the checks run against the merged state, since staging has moved a long way and the result is what matters.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

checks-failing Fails CI when merged into staging

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants