docs: incremental vs full rebuild guide with staleness check#919
docs: incremental vs full rebuild guide with staleness check#919carlos-alm merged 6 commits intomainfrom
Conversation
… check - Add "What incremental rebuilds refresh" section to README with comparison table and guidance on when to run full rebuilds - Create docs/guides/incremental-builds.md with detailed guide covering three-tier change detection, what gets skipped, recommended schedules, configuration, and Claude Code hook integration - Update recommended-practices.md with periodic full rebuild section (husky post-merge example) and watch mode freshness note - Update hooks example README with incremental build freshness section documenting the automatic staleness detection mechanism - Upgrade post-git-ops.sh to run --no-incremental after merge/rebase/pull (both our hooks and example hooks) with staleness marker update - Add 24h staleness check to update-graph.sh: first edit of a stale session auto-upgrades to full rebuild via .codegraph/last-full-build marker, subsequent edits stay incremental
|
Claude finished @carlos-alm's task —— View job PR Review: Incremental vs Full Rebuild GuideConducting comprehensive review following the 5-phase process: Todo List
Root Cause AnalysisProblem Being Solved: Users relying on analysis queries (complexity, dataflow, CFG, directory cohesion) had no documentation about when or why incremental builds skip recomputing this data for unchanged files. The staleness check addresses the automation gap — the first edit after >24h triggers a one-time full rebuild automatically. Why This Approach: Sound approach. Documentation addresses the knowledge gap while the automatic staleness detection provides a practical solution that balances performance (incremental for active sessions) with accuracy (full rebuild after staleness). The 24h threshold and marker file system are simple and reliable. Risk Assessment: Very low risk. This is purely additive documentation and hook improvements with sensible defaults. No core functionality changes. Backlog Compliance
Code Quality AssessmentDocumentation Quality ⭐⭐⭐⭐⭐
Hook Implementation ⭐⭐⭐⭐
Technical Implementation
Minor Enhancement Opportunities (not blocking):
No Critical Issues Found: No security concerns, no malicious code patterns, no test weakening, no configuration rule relaxation. Final Recommendation
The automatic staleness check is particularly valuable - it solves the "I don't know when to run |
Greptile SummaryThis PR adds documentation explaining incremental vs full rebuild semantics and wires up automatic staleness detection in both hook files:
Confidence Score: 4/5Safe to merge after fixing the two broken One P1 doc regression: docs/guides/recommended-practices.md lines 36 and 50 — both diff-impact examples use the invalid Important Files Changed
Reviews (3): Last reviewed commit: "Merge branch 'main' into docs/incrementa..." | Re-trigger Greptile |
.claude/hooks/update-graph.sh
Outdated
| codegraph build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null || true | ||
| else | ||
| node "${CLAUDE_PROJECT_DIR:-$WORK_ROOT}/src/cli.js" build "$WORK_ROOT" -d "$DB_PATH" 2>/dev/null || true | ||
| node "${CLAUDE_PROJECT_DIR}/src/cli.js" build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null || true |
There was a problem hiding this comment.
Regression: node fallback path drops
:-$PROJECT_DIR guard
${CLAUDE_PROJECT_DIR} is referenced without a default value. With set -euo pipefail active (line 8), if CLAUDE_PROJECT_DIR is unset the script exits non-zero with "unbound variable" before the || true can save it. The original code had ${CLAUDE_PROJECT_DIR:-$WORK_ROOT} to handle this, and post-git-ops.sh (line 46) still retains the equivalent ${CLAUDE_PROJECT_DIR:-$PROJECT_DIR} form. This inconsistency looks like an oversight.
| node "${CLAUDE_PROJECT_DIR}/src/cli.js" build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null || true | |
| node "${CLAUDE_PROJECT_DIR:-$PROJECT_DIR}/src/cli.js" build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null || true |
There was a problem hiding this comment.
Fixed. Restored the ${CLAUDE_PROJECT_DIR:-$PROJECT_DIR} fallback guard on line 80, matching the pattern already used in post-git-ops.sh.
.claude/hooks/update-graph.sh
Outdated
| # Update marker if we did a full rebuild | ||
| if [ -n "$BUILD_FLAGS" ]; then | ||
| mkdir -p "$(dirname "$MARKER")" | ||
| touch "$MARKER" | ||
| fi |
There was a problem hiding this comment.
Staleness marker updated even when build silently fails
Because the build commands use || true, a failed --no-incremental run still advances the staleness clock. The next edit within 24 hours will see a fresh marker and run only an incremental build — so a single silent build failure silently defers the next full refresh by up to 24 hours. The same pattern exists in post-git-ops.sh (line 50). This is a design trade-off consistent with the "never block" philosophy, but worth mitigating by only touching the marker when the build exits 0.
There was a problem hiding this comment.
Fixed. Introduced a BUILD_OK flag — the marker is now only touched when the build command exits 0. Applied consistently across all four hook files (.claude/hooks/ and docs/examples/ versions of both update-graph.sh and post-git-ops.sh).
docs/guides/incremental-builds.md
Outdated
| - You edited a few files and want to check impact — incremental handles this perfectly | ||
| - You're querying callers, paths, or dependencies — edge data is always current for changed files | ||
| - `codegraph watch` is running — it maintains a change journal for efficient incremental updates | ||
| - You just ran `git pull` with a post-checkout hook that triggers `codegraph build` — incremental is sufficient for routine pulls |
There was a problem hiding this comment.
Contradicts actual hook behavior
This bullet says "incremental is sufficient for routine pulls," but post-git-ops.sh unconditionally runs --no-incremental after every git pull/merge/rebase. A reader using the Claude Code hooks will experience a full rebuild after every pull — not incremental. The bullet should reflect that the hooks handle this with a full rebuild, or be reworded to apply only to users without the hooks.
| - You just ran `git pull` with a post-checkout hook that triggers `codegraph build` — incremental is sufficient for routine pulls | |
| - You just ran `git pull` and the `post-git-ops.sh` hook is active — it already ran a full rebuild for you |
There was a problem hiding this comment.
Fixed. Updated to: "You just ran git pull and the post-git-ops.sh hook is active — it already ran a full rebuild for you." This now accurately reflects that the hook runs --no-incremental after every pull.
- Restore :-$PROJECT_DIR default in node fallback path (update-graph.sh) to prevent unbound variable exit under set -euo pipefail - Only update staleness marker when build exits 0, so a silent failure doesn't defer the next full rebuild by up to 24 hours - Apply both fixes consistently across .claude/hooks/ and docs/examples/
…919) The post-git-ops.sh hook unconditionally runs --no-incremental after every pull/merge/rebase. Updated the guide to reflect actual behavior.
Summary
--no-incremental, automatic triggers, recommended schedules, configuration, and Claude Code hook integrationpost-mergeexample) and watch mode freshness note.claude/hooks/anddocs/examples/claude-code-hooks/):post-git-ops.sh→ upgraded to--no-incrementalafter merge/rebase/pull, writes.codegraph/last-full-buildmarkerupdate-graph.sh→ added 24h staleness check: first edit of a stale session auto-upgrades to full rebuild via marker file, subsequent edits stay incrementalWhy
Incremental builds keep edges and symbols current but skip recomputing complexity, dataflow, CFG, and directory cohesion for files not directly edited. Users relying on these analysis queries had no documentation telling them when or why to run a full rebuild. The staleness check in
update-graph.shcloses the gap automatically — the first edit after >24h triggers a one-time full rebuild (~3.5s overhead), then everything stays incremental.Test plan
update-graph.shtriggers full rebuild when.codegraph/last-full-buildis missingupdate-graph.shtriggers full rebuild when marker is >24h oldupdate-graph.shstays incremental when marker is freshpost-git-ops.shwrites the marker after full rebuild