diff --git a/.claude/hooks/post-git-ops.sh b/.claude/hooks/post-git-ops.sh index 7bb3bf51..62cb24ac 100644 --- a/.claude/hooks/post-git-ops.sh +++ b/.claude/hooks/post-git-ops.sh @@ -2,7 +2,7 @@ # post-git-ops.sh — PostToolUse hook for Bash tool calls # Detects git operations that change file state (rebase, revert, cherry-pick, # merge, pull) and: -# 1. Rebuilds the codegraph incrementally (fixes stale dependency context) +# 1. Runs a full codegraph rebuild (recomputes all analysis data, not just edges) # 2. Logs changed files to session-edits.log (so commit validation works) # Always exits 0 (informational only, never blocks). @@ -33,12 +33,23 @@ fi PROJECT_DIR=$(git rev-parse --show-toplevel 2>/dev/null) || PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}" # --- 1. Rebuild codegraph --- +# Git operations (merge, rebase, pull) can change many files at once, including +# files not directly edited in this session. A full rebuild ensures complexity, +# dataflow, and directory cohesion metrics are recomputed for all affected files +# — not just the ones the incremental pipeline would detect via reverse-deps. +# See docs/guides/incremental-builds.md for what incremental skips. DB_PATH="$PROJECT_DIR/.codegraph/graph.db" if [ -f "$DB_PATH" ]; then + BUILD_OK=0 if command -v codegraph &>/dev/null; then - codegraph build "$PROJECT_DIR" -d "$DB_PATH" 2>/dev/null || true + codegraph build "$PROJECT_DIR" -d "$DB_PATH" --no-incremental 2>/dev/null && BUILD_OK=1 || true else - node "${CLAUDE_PROJECT_DIR:-$PROJECT_DIR}/src/cli.js" build "$PROJECT_DIR" -d "$DB_PATH" 2>/dev/null || true + node "${CLAUDE_PROJECT_DIR:-$PROJECT_DIR}/src/cli.js" build "$PROJECT_DIR" -d "$DB_PATH" --no-incremental 2>/dev/null && BUILD_OK=1 || true + fi + # Update staleness marker only if the full rebuild succeeded + if [ "$BUILD_OK" -eq 1 ]; then + MARKER="$PROJECT_DIR/.codegraph/last-full-build" + touch "$MARKER" fi fi diff --git a/.claude/hooks/update-graph.sh b/.claude/hooks/update-graph.sh index d0be9cf1..ab8a1594 100644 --- a/.claude/hooks/update-graph.sh +++ b/.claude/hooks/update-graph.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash # rebuild-graph.sh — PostToolUse hook for Edit and Write tools # Incrementally updates the codegraph after source file edits. +# On the first edit of a stale session (no full rebuild in >24h), upgrades +# to a full rebuild so complexity/dataflow/cohesion data stays fresh. # Always exits 0 (informational only, never blocks). set -euo pipefail @@ -38,18 +40,51 @@ if echo "$FILE_PATH" | grep -qE '(fixtures|__fixtures__|testdata)/'; then fi # Guard: codegraph DB must exist (project has been built at least once) -# Use git worktree root so each worktree uses its own DB (avoids WAL contention) -WORK_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || WORK_ROOT="${CLAUDE_PROJECT_DIR:-.}" -DB_PATH="$WORK_ROOT/.codegraph/graph.db" +PROJECT_DIR=$(git rev-parse --show-toplevel 2>/dev/null) || PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}" +DB_PATH="$PROJECT_DIR/.codegraph/graph.db" if [ ! -f "$DB_PATH" ]; then exit 0 fi -# Run incremental build (skips unchanged files via hash check) +# --- Staleness check --- +# If no full rebuild has happened in >24h, upgrade this one build to +# --no-incremental so complexity/dataflow/cohesion are recomputed for +# all files. Subsequent edits in the same session stay incremental. +# See docs/guides/incremental-builds.md for what incremental skips. +MARKER="$PROJECT_DIR/.codegraph/last-full-build" +BUILD_FLAGS="" +STALE_SECONDS=86400 # 24 hours + +if [ ! -f "$MARKER" ]; then + # No marker = never had a tracked full rebuild — do one now + BUILD_FLAGS="--no-incremental" +else + # Check marker age (cross-platform: use node for reliable epoch math) + MARKER_AGE=$(node -e " + const fs = require('fs'); + try { + const mtime = fs.statSync('${MARKER//\\/\\\\}').mtimeMs; + console.log(Math.floor((Date.now() - mtime) / 1000)); + } catch { console.log('999999'); } + " 2>/dev/null) || MARKER_AGE=999999 + + if [ "$MARKER_AGE" -gt "$STALE_SECONDS" ]; then + BUILD_FLAGS="--no-incremental" + fi +fi + +# Run the build +BUILD_OK=0 if command -v codegraph &>/dev/null; then - codegraph build "$WORK_ROOT" -d "$DB_PATH" 2>/dev/null || true + codegraph build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null && BUILD_OK=1 || 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:-$PROJECT_DIR}/src/cli.js" build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null && BUILD_OK=1 || true +fi + +# Update marker only if we did a full rebuild AND it succeeded +if [ -n "$BUILD_FLAGS" ] && [ "$BUILD_OK" -eq 1 ]; then + mkdir -p "$(dirname "$MARKER")" + touch "$MARKER" fi exit 0 diff --git a/README.md b/README.md index ea5e993f..d4d2b231 100644 --- a/README.md +++ b/README.md @@ -544,6 +544,35 @@ The graph stays current without re-parsing your entire codebase. Three-tier chan **Result:** change one file in a 3,000-file project and the rebuild completes in under a second. Put it in a commit hook, a file watcher, or let your AI agent trigger it. +#### What incremental rebuilds refresh — and what they don't + +Incremental builds re-parse changed files and rebuild their edges, structure metrics, and role classifications. But some data is **only fully refreshed on a full rebuild:** + +| Data | Incremental | Full rebuild | +|------|:-----------:|:------------:| +| Symbols & edges for changed files | Yes | Yes | +| Reverse-dependency cascade (importers of changed files) | Yes | Yes | +| AST nodes, complexity, CFG, dataflow for changed files | Yes | Yes | +| Directory-level cohesion metrics | Partial (skipped for ≤5 files) | Yes | +| Advisory checks (orphaned embeddings, stale embeddings, unused exports) | Skipped | Yes | +| Build metadata persistence | Skipped for ≤3 files | Yes | +| Incremental drift detection | Skipped | Yes | + +**When to run a full rebuild:** + +```bash +codegraph build --no-incremental # Force full rebuild +``` + +- **After large refactors** (renames, moves, deleted files) — the reverse-dependency cascade handles most cases, but a full rebuild ensures nothing is stale +- **If you suspect stale analysis data** — complexity or dataflow results for files you didn't directly edit won't update incrementally +- **Periodically** — if you rely heavily on `complexity`, `dataflow`, `roles --role dead`, or `communities` queries, run a full rebuild weekly or after major merges +- **After upgrading codegraph** — engine, schema, or version changes trigger an automatic full rebuild, but if you skip versions you may want to force one + +Codegraph auto-detects and forces a full rebuild when the engine, schema version, or codegraph version changes between builds. For everything else, incremental is the safe default — a full rebuild is a correctness guarantee, not a frequent necessity. + +> **Detailed guide:** See [docs/guides/incremental-builds.md](docs/guides/incremental-builds.md) for a complete breakdown of what each build mode refreshes and recommended rebuild schedules. + ### Dual Engine Codegraph ships with two parsing engines: diff --git a/docs/examples/claude-code-hooks/README.md b/docs/examples/claude-code-hooks/README.md index b5ab5bff..c9990d77 100644 --- a/docs/examples/claude-code-hooks/README.md +++ b/docs/examples/claude-code-hooks/README.md @@ -54,8 +54,8 @@ If an instruction matters, make it a blocking hook. If it's in CLAUDE.md but not | Hook | Trigger | What it does | |------|---------|-------------| -| `update-graph.sh` | PostToolUse on Edit/Write | Runs `codegraph build` incrementally after source file edits to keep the graph fresh | -| `post-git-ops.sh` | PostToolUse on Bash | Detects `git rebase/revert/cherry-pick/merge/pull` and rebuilds the graph + logs changed files to the edit log | +| `update-graph.sh` | PostToolUse on Edit/Write | Runs `codegraph build` incrementally after source file edits to keep the graph fresh (see [freshness note](#incremental-build-freshness)) | +| `post-git-ops.sh` | PostToolUse on Bash | Detects `git rebase/revert/cherry-pick/merge/pull`, runs a **full rebuild** (recomputes all analysis data), and logs changed files to the edit log | ## Pre-commit consolidation @@ -80,6 +80,34 @@ All session-local state files (`session-edits.log`) use `git rev-parse --show-to **Branch name validation:** The `guard-git.sh` in this repo's `.claude/hooks/` validates branch names against conventional prefixes (`feat/`, `fix/`, etc.). The example version omits this — add your own validation if needed. +## Incremental build freshness + +The `update-graph.sh` hook runs **incremental** builds — it only re-parses files you directly edited. This keeps symbols, edges, and caller data fresh during a session. However, some analysis data is only recomputed for directly modified files: + +- **Complexity, dataflow, and CFG metrics** for files you didn't edit remain from the last full build +- **Directory-level cohesion metrics** are skipped for small changes (≤5 files) +- **Advisory checks** (orphaned embeddings, unused exports) are skipped entirely + +**This means:** If you edit `utils.ts` and `handler.ts` imports it, the import edges from `handler.ts` are rebuilt, but `handler.ts`'s complexity and dataflow data are not recomputed. + +### Automatic staleness detection + +The hooks handle this automatically via a **staleness marker** (`.codegraph/last-full-build`): + +1. **First edit of a stale session** — `update-graph.sh` checks the marker. If missing or older than 24 hours, it upgrades that one build to `--no-incremental` (~3.5s instead of ~1.5s) and updates the marker. +2. **Subsequent edits** — marker is fresh, so builds stay incremental (fast). +3. **After git merge/rebase/pull** — `post-git-ops.sh` always runs a full rebuild and updates the marker. + +This means you never need to manually run `codegraph build --no-incremental` — the first edit after a stale period triggers it automatically. The 24-hour threshold ensures complexity, dataflow, and cohesion data never drifts more than a day behind. + +Add `.codegraph/last-full-build` to `.gitignore` — it's session-local state: + +``` +.codegraph/ +``` + +For a detailed breakdown of what incremental builds skip, see the [incremental builds guide](../../guides/incremental-builds.md). + ## Requirements - Node.js >= 20 diff --git a/docs/examples/claude-code-hooks/post-git-ops.sh b/docs/examples/claude-code-hooks/post-git-ops.sh index 3a8f0bc8..7310e8e9 100644 --- a/docs/examples/claude-code-hooks/post-git-ops.sh +++ b/docs/examples/claude-code-hooks/post-git-ops.sh @@ -2,7 +2,7 @@ # post-git-ops.sh — PostToolUse hook for Bash tool calls # Detects git operations that change file state (rebase, revert, cherry-pick, # merge, pull) and: -# 1. Rebuilds the codegraph incrementally (fixes stale dependency context) +# 1. Runs a full codegraph rebuild (recomputes all analysis data, not just edges) # 2. Logs changed files to session-edits.log (so commit validation works) # Always exits 0 (informational only, never blocks). @@ -32,13 +32,23 @@ fi # Use git worktree root so each worktree session has its own state PROJECT_DIR=$(git rev-parse --show-toplevel 2>/dev/null) || PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}" -# --- 1. Rebuild codegraph --- +# --- 1. Full rebuild of codegraph --- +# Git operations (merge, rebase, pull) can change many files at once. A full +# rebuild ensures complexity, dataflow, and directory cohesion metrics are +# recomputed for all affected files — not just direct edits. +# See docs/guides/incremental-builds.md for what incremental skips. DB_PATH="$PROJECT_DIR/.codegraph/graph.db" if [ -f "$DB_PATH" ]; then + BUILD_OK=0 if command -v codegraph &>/dev/null; then - codegraph build "$PROJECT_DIR" -d "$DB_PATH" 2>/dev/null || true + codegraph build "$PROJECT_DIR" -d "$DB_PATH" --no-incremental 2>/dev/null && BUILD_OK=1 || true else - npx --yes @optave/codegraph build "$PROJECT_DIR" -d "$DB_PATH" 2>/dev/null || true + npx --yes @optave/codegraph build "$PROJECT_DIR" -d "$DB_PATH" --no-incremental 2>/dev/null && BUILD_OK=1 || true + fi + # Update staleness marker only if the full rebuild succeeded + if [ "$BUILD_OK" -eq 1 ]; then + MARKER="$PROJECT_DIR/.codegraph/last-full-build" + touch "$MARKER" fi fi diff --git a/docs/examples/claude-code-hooks/update-graph.sh b/docs/examples/claude-code-hooks/update-graph.sh index 6b5ee577..2468e641 100644 --- a/docs/examples/claude-code-hooks/update-graph.sh +++ b/docs/examples/claude-code-hooks/update-graph.sh @@ -1,6 +1,8 @@ #!/usr/bin/env bash # update-graph.sh — PostToolUse hook for Edit and Write tools # Incrementally updates the codegraph after source file edits. +# On the first edit of a stale session (no full rebuild in >24h), upgrades +# to a full rebuild so complexity/dataflow/cohesion data stays fresh. # Always exits 0 (informational only, never blocks). set -euo pipefail @@ -38,18 +40,51 @@ if echo "$FILE_PATH" | grep -qE '(fixtures|__fixtures__|testdata)/'; then fi # Guard: codegraph DB must exist (project has been built at least once) -# Use git worktree root so each worktree uses its own DB (avoids WAL contention) -WORK_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || WORK_ROOT="${CLAUDE_PROJECT_DIR:-.}" -DB_PATH="$WORK_ROOT/.codegraph/graph.db" +PROJECT_DIR=$(git rev-parse --show-toplevel 2>/dev/null) || PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}" +DB_PATH="$PROJECT_DIR/.codegraph/graph.db" if [ ! -f "$DB_PATH" ]; then exit 0 fi -# Run incremental build (skips unchanged files via hash check) +# --- Staleness check --- +# If no full rebuild has happened in >24h, upgrade this one build to +# --no-incremental so complexity/dataflow/cohesion are recomputed for +# all files. Subsequent edits in the same session stay incremental. +# See docs/guides/incremental-builds.md for what incremental skips. +MARKER="$PROJECT_DIR/.codegraph/last-full-build" +BUILD_FLAGS="" +STALE_SECONDS=86400 # 24 hours + +if [ ! -f "$MARKER" ]; then + # No marker = never had a tracked full rebuild — do one now + BUILD_FLAGS="--no-incremental" +else + # Check marker age (cross-platform: use node for reliable epoch math) + MARKER_AGE=$(node -e " + const fs = require('fs'); + try { + const mtime = fs.statSync('${MARKER//\\/\\\\}').mtimeMs; + console.log(Math.floor((Date.now() - mtime) / 1000)); + } catch { console.log('999999'); } + " 2>/dev/null) || MARKER_AGE=999999 + + if [ "$MARKER_AGE" -gt "$STALE_SECONDS" ]; then + BUILD_FLAGS="--no-incremental" + fi +fi + +# Run the build +BUILD_OK=0 if command -v codegraph &>/dev/null; then - codegraph build "$WORK_ROOT" -d "$DB_PATH" 2>/dev/null || true + codegraph build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null && BUILD_OK=1 || true else - npx --yes @optave/codegraph build "$WORK_ROOT" -d "$DB_PATH" 2>/dev/null || true + npx --yes @optave/codegraph build "$PROJECT_DIR" -d "$DB_PATH" $BUILD_FLAGS 2>/dev/null && BUILD_OK=1 || true +fi + +# Update marker only if we did a full rebuild AND it succeeded +if [ -n "$BUILD_FLAGS" ] && [ "$BUILD_OK" -eq 1 ]; then + mkdir -p "$(dirname "$MARKER")" + touch "$MARKER" fi exit 0 diff --git a/docs/guides/incremental-builds.md b/docs/guides/incremental-builds.md new file mode 100644 index 00000000..ad7e2730 --- /dev/null +++ b/docs/guides/incremental-builds.md @@ -0,0 +1,161 @@ +# Incremental vs Full Builds + +Codegraph defaults to incremental builds — only re-parsing files whose content has changed. This is fast (sub-second for small changes) and correct for most workflows. But some analysis data is only fully refreshed on a full rebuild, and understanding the difference helps you get accurate results. + +--- + +## How incremental builds work + +Codegraph uses a three-tier change detection strategy: + +1. **Tier 0 — Journal:** If `codegraph watch` was running, a change journal records exactly which files were touched. The next build reads the journal — zero filesystem scanning. +2. **Tier 1 — mtime + size:** Without a journal, codegraph stats every file and compares mtime + size against stored values. Files that match are skipped without reading content. +3. **Tier 2 — Hash:** Files that fail the mtime/size check are read and MD5-hashed. Only files whose hash actually changed get re-parsed. + +After detecting changes, the build pipeline runs these stages on the changed files: + +- **Parse** — re-parse changed files with tree-sitter +- **Insert nodes** — purge old nodes for changed files, insert new definitions +- **Reverse-dependency cascade** — find files that import the changed files, rebuild their outgoing edges +- **Resolve imports** — re-resolve imports for changed files (and related barrel/re-export files) +- **Build edges** — rebuild call edges, scoped to changed files and their targets +- **Structure metrics** — update per-file metrics (fast path for ≤5 changed files) +- **Role classification** — reclassify roles for changed files' symbols +- **Analysis** — recompute AST nodes, complexity, CFG, and dataflow for changed files only + +## What incremental builds skip + +Some operations are **only run on full rebuilds** for performance reasons: + +| Operation | Why it's skipped incrementally | +|-----------|-------------------------------| +| **Advisory checks** (orphaned embeddings, stale embeddings, unused exports) | These scan the entire DB — ~40-60ms cost that isn't worth paying on every small change | +| **Directory-level cohesion metrics** | For ≤5 changed files, directory-level metrics won't meaningfully shift — skipped to save ~8ms | +| **Build metadata persistence** | For ≤3 changed files, skipped to avoid WAL fsync overhead | +| **Incremental drift detection** | Compares node/edge counts vs previous build to detect corruption — only meaningful after a full rebuild | +| **Global repo registry update** | Repo is already registered from the initial full build | + +### The practical impact + +The most important thing to understand: **complexity, dataflow, and CFG data for files you didn't directly edit won't update incrementally.** If you refactor `utils.ts` and that changes the behavior of functions in `handler.ts` (which imports `utils.ts`), the edges from `handler.ts` are rebuilt (via the reverse-dependency cascade), but `handler.ts`'s complexity metrics and dataflow edges are not recomputed. + +For most workflows — querying callers, checking impact, finding dead code — incremental builds are perfectly accurate. The staleness only matters for analysis-heavy queries (`complexity`, `dataflow`, `cfg`) on files that weren't directly modified. + +--- + +## When to run a full rebuild + +```bash +codegraph build --no-incremental +``` + +### You should run a full rebuild when: + +**After large refactors or branch merges.** Moving, renaming, or deleting many files can leave stale edges or orphaned nodes. The reverse-dependency cascade handles most cases correctly, but a full rebuild guarantees a clean slate. + +**If analysis data seems stale.** If `codegraph complexity` or `codegraph dataflow` returns results that don't match the current code, a full rebuild will recompute everything from scratch. + +**After upgrading codegraph.** Engine changes, schema migrations, or major version bumps trigger an automatic full rebuild. But if you skip versions or aren't sure, `--no-incremental` is the safe choice. + +**Periodically, if you rely on analysis queries.** If your workflow heavily uses `complexity`, `dataflow`, `cfg`, `communities --drift`, or `roles --role dead`, schedule a weekly full rebuild (or after major merges to main) to keep the data fresh. + +**Before publishing audit results.** If you're generating reports with `codegraph audit`, `codegraph triage`, or `codegraph check` for CI or stakeholders, run a full rebuild first so the numbers reflect reality. + +### You don't need a full rebuild when: + +- 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` and the `post-git-ops.sh` hook is active — it already ran a full rebuild for you + +--- + +## Automatic full rebuild triggers + +Codegraph forces a full rebuild automatically when it detects: + +1. **Engine change** — switching between `native` and `wasm` (different parsers may produce slightly different node boundaries) +2. **Schema version change** — a DB migration was applied (new tables, columns, or indexes) +3. **Codegraph version change** — a new release may change extraction or resolution logic + +These are detected from build metadata stored in the SQLite database. You don't need to remember to force a rebuild after upgrading — it happens automatically. + +--- + +## Recommended rebuild schedule + +| Workflow | Rebuild strategy | +|----------|-----------------| +| **Solo developer, daily work** | Incremental (default). Full rebuild weekly or after large merges. | +| **CI pipeline** | Full rebuild on main branch builds. Incremental on PR branches (with graph cache). | +| **AI agent sessions** | Incremental via hooks (automatic). Full rebuild at session start if the graph is older than a day. | +| **Before audits or reports** | Always full rebuild. | +| **After codegraph upgrade** | Automatic (version mismatch triggers full rebuild). | + +--- + +## Checking build freshness + +Use `codegraph stats` to see when the graph was last built and what engine was used: + +```bash +codegraph stats +``` + +The output includes the build timestamp, engine, and node/edge counts. If the `built_at` timestamp is old relative to your recent changes, consider a full rebuild. + +--- + +## Configuration + +Disable incremental builds globally via `.codegraphrc.json`: + +```json +{ + "build": { + "incremental": false + } +} +``` + +This forces every `codegraph build` to be a full rebuild. Not recommended for daily use (it's slower), but useful if you want to guarantee freshness in CI or automated pipelines. + +The CLI flag `--no-incremental` overrides the config for a single invocation: + +```bash +codegraph build --no-incremental # Full rebuild this time only +codegraph build # Back to incremental (per config) +``` + +--- + +## Claude Code hooks and incremental builds + +If you use the codegraph Claude Code hooks (see [hooks examples](../examples/claude-code-hooks/)), the hooks automatically manage full vs incremental builds using a **staleness marker** (`.codegraph/last-full-build`): + +### How the staleness check works + +1. **`update-graph.sh`** fires on every Edit/Write. It checks the marker file: + - **Missing or older than 24 hours** → runs `codegraph build --no-incremental` (full rebuild, ~3.5s), then updates the marker + - **Fresh (< 24 hours)** → runs `codegraph build` (incremental, ~1.5s) +2. **`post-git-ops.sh`** fires after `git merge/rebase/pull`. It always runs a full rebuild and updates the marker. + +This means: +- The **first edit** of a new session (or after a long break) triggers a one-time full rebuild — complexity, dataflow, and cohesion data are refreshed for all files +- **Every subsequent edit** in the same session stays incremental (fast) +- **After merging main** into your branch, `post-git-ops.sh` does a full rebuild and resets the staleness clock + +You never need to manually run `codegraph build --no-incremental` — the hooks handle it. The 24-hour threshold ensures analysis data never drifts more than a day behind, while keeping the per-edit overhead minimal. + +### Customizing the staleness threshold + +The default threshold is 86400 seconds (24 hours). To change it, edit the `STALE_SECONDS` variable in `update-graph.sh`: + +```bash +STALE_SECONDS=43200 # 12 hours — more aggressive freshness +STALE_SECONDS=172800 # 48 hours — less frequent full rebuilds +``` + +For projects where you rarely use analysis queries (complexity, dataflow), a longer threshold reduces overhead. For projects where analysis accuracy matters, shorten it. + +You can also add a periodic full rebuild to your git hooks. See [recommended-practices.md](./recommended-practices.md#periodic-full-rebuilds) for examples. diff --git a/docs/guides/recommended-practices.md b/docs/guides/recommended-practices.md index 64ec2815..969fdaf8 100644 --- a/docs/guides/recommended-practices.md +++ b/docs/guides/recommended-practices.md @@ -33,7 +33,7 @@ See what your branch will affect before pushing: ```bash # .husky/pre-push codegraph build -codegraph diff-impact origin/main --no-tests +codegraph diff-impact --ref origin/main --no-tests ``` This prints a summary like: @@ -47,7 +47,7 @@ If you want to **block pushes** that exceed a threshold, add a check: ```bash # .husky/pre-push codegraph build -IMPACT=$(codegraph diff-impact origin/main --no-tests -f json) +IMPACT=$(codegraph diff-impact --ref origin/main --no-tests --json) AFFECTED=$(echo "$IMPACT" | node -e " const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(d.summary?.callersAffected || 0) @@ -58,6 +58,26 @@ if [ "$AFFECTED" -gt 50 ]; then fi ``` +### Periodic full rebuilds + +Incremental builds keep edges and symbols fresh, but some analysis data (complexity, dataflow, directory cohesion) is only recomputed for files you directly edit. Schedule a periodic full rebuild to keep everything accurate: + +**With husky (weekly or post-merge):** + +```bash +# .husky/post-merge — runs after every git pull/merge +codegraph build --no-incremental +``` + +**Manual habit:** + +```bash +# After large merges, before audits, or weekly +codegraph build --no-incremental +``` + +> **When does this matter?** If you rely on `codegraph complexity`, `codegraph dataflow`, `codegraph communities --drift`, or `codegraph roles --role dead` for files you haven't directly edited, those results may be stale after incremental-only builds. A full rebuild recomputes everything from scratch. See [incremental-builds.md](./incremental-builds.md) for the full breakdown. + ### Commit message enrichment Automatically append impact info to commit messages: @@ -98,7 +118,7 @@ Add a threshold check to your CI pipeline: - name: Check impact threshold run: | npx codegraph build - IMPACT=$(npx codegraph diff-impact origin/${{ github.base_ref }} -f json) + IMPACT=$(npx codegraph diff-impact --ref origin/${{ github.base_ref }} --json) AFFECTED=$(echo "$IMPACT" | node -e " const d = JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(d.summary?.callersAffected || 0) @@ -389,6 +409,8 @@ codegraph watch Changes are picked up incrementally — no manual rebuilds needed. +> **Note:** Watch mode runs incremental builds — it keeps symbols, edges, and callers current, but won't recompute complexity, dataflow, or directory cohesion for files you didn't directly edit. If you need fresh analysis data across the entire codebase, run `codegraph build --no-incremental` periodically. See [incremental-builds.md](./incremental-builds.md) for details. + ### Explore before you edit Before touching a function, understand its role and blast radius: