Skip to content

Implement incremental graph updates via git hooks and file watcher #69

Description

@sshaaf

Summary

rgctl currently requires manual rgctl discover to build or rebuild the code graph. Nothing automatically triggers re-extraction when source files change. This issue proposes two complementary approaches — git hooks (phase 1) and a file watcher (phase 2) — to keep the graph fresh automatically.

Existing infrastructure

~90% of the plumbing already exists:

Component Location Status
IncrementalUpdater crates/rgctl-incremental/src/updater.rs:72-148 Implemented — update() and update_files()
FileTracker crates/rgctl-incremental/src/file_tracker.rs Implemented — blake3 hash-based change detection
ChangeDetector crates/rgctl-incremental/src/changes/mod.rs:54-135 Implemented — blast-radius risk classification
HooksConfig crates/rgctl-project-config/src/project.rs:38-76 Implemented — pre_commit, post_commit, post_checkout, block_on_risk, blast_radius_threshold
WatchConfig crates/rgctl-project-config/src/project.rs:78-96 Implemented — debounce_ms (default 500ms)
git_changed_files() crates/rgctl-incremental/src/file_tracker.rs:301 Implemented — git diff --name-only
pipeline_watch_loop src/cli/http_serve.rs:310-320 Implemented — polls graph digest every 400ms, hot-reloads snapshot

What is missing is the end-to-end wiring: CLI subcommands, hook scripts, and the OS-level file watcher.


Phase 1: Git Hooks

Approach

Shell scripts in .git/hooks/ invoke rgctl at git lifecycle points:

  • pre-commit — runs rgctl check --staged, blocks if risk exceeds threshold (exit 1)
  • post-commit — runs rgctl update --since HEAD~1 in background
  • post-checkout — runs rgctl update --since <prev-HEAD> on branch switch
  • post-merge — runs rgctl update after merge

Tasks

  • Add rgctl update CLI subcommand wrapping IncrementalUpdater::update() / update_files()
  • Add rgctl check --staged flag to wire ChangeDetector against git diff --cached --name-only
  • Add rgctl install --hooks to generate and install hook scripts in .git/hooks/
  • Respect HooksConfig from rgctl.toml for which hooks to install and risk thresholds
  • Add rgctl uninstall --hooks to remove installed hooks
  • Document in docs/guides/git-hooks.md

Why hooks first

  1. More infrastructure already exists (HooksConfig, ChangeDetector, RiskLevel)
  2. Risk gating (blocking risky commits) is a unique capability only hooks provide
  3. No new crate dependencies needed
  4. CI parity — same rgctl check works in hooks and pipelines

Phase 2: File Watcher

Approach

A background watcher using the notify crate detects file writes/renames/deletes, debounces events, filters to language-supported extensions, and invokes IncrementalUpdater::update_files().

Tasks

  • Add notify crate dependency
  • Add --watch flag to rgctl serve (both HTTP and MCP modes)
  • Implement debounced watcher with extension filtering via LanguageRegistry
  • Connect watcher events to IncrementalUpdater::update_files()
  • Respect WatchConfig.debounce_ms from rgctl.toml
  • Add .gitignore-aware path filtering to avoid indexing build artifacts
  • Document in docs/guides/watch-mode.md

Comparison

Dimension Git Hooks File Watcher
Latency Seconds (on git op) Sub-second
Trigger commit, checkout, merge Any file write
Resource cost Zero between operations Continuous (watcher thread)
Risk gating Yes (pre-commit) No
CI integration Direct (rgctl check) N/A
Setup rgctl install --hooks Automatic with serve --watch
Git dependency Yes No
New dependencies None notify crate
Unstaged files Invisible Visible

Phase 3 (optional): Hybrid

  • rgctl serve --watch for real-time freshness + git hooks for risk gating
  • Coordination lock to prevent watcher and hook from racing
  • Dashboard indicator showing last-update source

References

Full analysis: .scratch/todo/FILE_WATCHER_VS_GIT_HOOKS.md

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions