Skip to content

fix: global concurrency cap for hook-triggered indexers - #160

Merged
rajkumarsakthivel merged 5 commits into
mainfrom
fix/hook-concurrency-cap
Aug 23, 2026
Merged

fix: global concurrency cap for hook-triggered indexers#160
rajkumarsakthivel merged 5 commits into
mainfrom
fix/hook-concurrency-cap

Conversation

@rajkumarsakthivel

Copy link
Copy Markdown
Member

Summary

Fixes #159. Git hooks fire in all worktrees (shared .git/hooks/), and the old hook spawned unbounded background indexers. With N worktrees this produced N detached cce index processes.

  • Global machine-wide lock via mkdir (POSIX portable, works on macOS without flock). At most one hook-triggered indexer runs at a time. Stale locks are reclaimed when the owner PID is dead.
  • Skip ephemeral worktree paths (/tmp/*, .claude/worktrees/*) since agent-created throwaway trees are deleted minutes later.
  • nice -n 10 so indexing never competes with foreground work.
  • Worktree-aware hook install: install_hooks() resolves through git rev-parse --git-common-dir so hooks install correctly from inside a worktree.
  • Upgrade path: cce init replaces old single-line hook blocks with the new guarded version instead of silently skipping when the marker is present.
  • Uninstall: handles multi-line hook blocks via start/end markers, backward-compatible with old single-line format.

Warm zinc-black palette, indigo accents, Inter+Outfit typography.
Massive 94% number as hero focal point, trust-strip with editor logos,
vertical numbered capabilities, horizontal benchmark stats, and
comparison table with green "Best" pill.
Git hooks installed by CCE fire in all worktrees (shared .git/hooks/),
and the old hook spawned unbounded background indexers. With N worktrees
this produced N detached cce-index processes (observed: 36 at ~1.85GB
each, ~66GB total on a 96GB machine).

Three changes:
- Global machine-wide lock via mkdir (POSIX portable, works on macOS
  without flock). At most one hook-triggered indexer runs at a time.
- Skip ephemeral worktree paths (/tmp/*, .claude/worktrees/*) since
  those trees are deleted minutes later.
- nice -n 10 so indexing never competes with foreground work.

Also fixes:
- install_hooks() now resolves through git common dir so hooks install
  correctly from inside a worktree.
- cce init/upgrade replaces old hook blocks with the new guarded version
  instead of silently skipping when the marker is present.
- Uninstall handles multi-line hook blocks (start/end markers).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR addresses runaway resource usage from hook-triggered cce index when Git worktrees share a common hooks directory, by making hook installation worktree-aware and adding guardrails to the generated hook script.

Changes:

  • Adds a guarded, background hook script that attempts to serialize hook-triggered indexing via a global lock and deprioritizes indexing with nice.
  • Resolves hooks installation through git rev-parse --git-common-dir so installing from within a worktree writes to the effective hooks directory.
  • Updates hook-uninstall stripping logic to support the new multi-line hook block format (marker + end-marker), while remaining backward-compatible with the legacy single-line format.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/context_engine/indexer/git_hooks.py Generates new guarded hook script and installs hooks into the correct common hooks dir for worktrees; adds upgrade behavior when an existing marker is found.
src/context_engine/cli.py Updates uninstall hook-block stripping to handle the new multi-line hook block format.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/context_engine/indexer/git_hooks.py
Comment thread src/context_engine/indexer/git_hooks.py Outdated
Comment thread src/context_engine/cli.py Outdated
Comment thread src/context_engine/indexer/git_hooks.py
- Remove shlex.quote from case glob patterns (broke ephemeral path matching)
- Remove unused _MAX_CONCURRENT_INDEXERS constant
- Fix _strip_cce_git_hook_block to detect end marker only after start marker
- Fix reinstall to preserve user content after the CCE block
@rajkumarsakthivel
rajkumarsakthivel merged commit 7507115 into main Aug 23, 2026
19 checks passed
@rajkumarsakthivel
rajkumarsakthivel deleted the fix/hook-concurrency-cap branch August 23, 2026 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Git hooks fire for every worktree with no concurrency cap — 36 detached indexers, ~66GB RAM, host unusable

2 participants