Commit 67a76de
feat: incremental graph rebuild (3-PR sequence: G1+G2+G3) (#284)
* feat: add source_file to edge schemas and FileHashTracker for incremental graph rebuild (PR-G1)
This commit implements PR-G1 of the incremental graph rebuild plan:
- Bump ONTOLOGY_VERSION to 17 (requires re-index)
- Add source_file STRING column to all 12 edge DDL constants
- Update _write_edges() to pass source_file for EXTENDS, IMPLEMENTS, INJECTS, DECLARES, OVERRIDES, CALLS, UNRESOLVED_AT
- Update _write_routes_and_exposes() to pass source_file for EXPOSES, DECLARES_CLIENT, DECLARES_PRODUCER, HTTP_CALLS, ASYNC_CALLS
- Add FileHashTracker class for detecting file changes (added, changed, removed)
- Add 9 tests for FileHashTracker and edge schema validation
Scope: PR-G1 (Hash tracker + source_file edge schema)
Plan: plans/active/PLAN-INCREMENTAL-GRAPH.md
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: pass2_edges in test setup and crash marker cleanup in fallback path
Tests that verify EXTENDS edge dependent expansion were missing pass2_edges()
calls in their setup, resulting in no EXTENDS edges being written to the graph.
Also fixed crash marker not being cleaned up in the _fallback_to_full code path
and invalid Kuzu SHOW_TABLES syntax in test_incremental_pass5_6_always_global.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: restructure _delete_file_scope to handle cross-file edge deletion
Process edge deletions across all scope files before deleting any nodes.
The previous per-file loop could fail when file B has an EXTENDS edge
to file A — deleting A's nodes first left dangling edges that Kuzu
refused to drop.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: add run_incremental_graph() wrapper for incremental rebuild (PR-G2)
Add subprocess wrapper that passes --incremental flag to build_ast_graph.py.
Part of incremental graph rebuild implementation.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* feat: CLI integration for incremental graph rebuild (PR-G3)
- Update increment command to run both CocoIndex catch-up and incremental Kuzu graph update
- Add --vectors-only flag to preserve old Lance-only behavior
- Update CLI help texts and documentation
- Emit JSON output from incremental_rebuild for mode detection
- Add/update tests for new increment behavior
Increment now updates both Lance and Kuzu by default. The old stale
warning is only emitted when --vectors-only is used.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: correct Cypher parameter names and close db on fallback in incremental rebuild
- Fix _write_clients_producers_and_calls: use correct parameter names
($sid/$cid/$pid/$rid) matching Cypher templates, add missing fields
(strategy, method_call, raw_uri, match, direction, raw_topic)
- Use dict lookup instead of O(n) list scan for client/producer source_file
- Use keyword args for MemberEntry placeholder construction
- Delete db+conn before fallback to avoid file lock
- Remove redundant import json inside main()
- Remove stale duplicate comment in pass1_parse
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: critical runtime bugs in incremental rebuild found by code review
- Fix _write_clients_producers_and_calls: use asdict(row) for Client/Producer
nodes instead of manually constructed dicts with wrong field names
(kind vs client_kind, target vs target_service, missing 10+ fields)
- Fix _delete_file_scope: add ALL edge tables to Phase 1 deletion
(was missing EXPOSES, DECLARES_CLIENT, DECLARES_PRODUCER, HTTP_CALLS,
ASYNC_CALLS — would crash on any Spring codebase with controllers)
- Use DETACH DELETE for Route/Client/Producer nodes as safety net
- Fix N+1 query in dependent expansion: single IN-query instead of per-file
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* refactor: deduplicate incremental rebuild code per code review
- Merge _load_existing_types/_load_existing_types_filtered into single
function with optional exclude_files parameter (same for members)
- Simplify _find_dependents: loop over edge type strings instead of
six identical if/elif branches
- Factor _write_nodes and _write_nodes_merge to shared _write_nodes_impl
accepting the query template as parameter (~70 lines deduplicated)
- Extract _build_file_by_node_id and share between _write_edges and
_write_routes_and_exposes (was built twice independently)
- Extract _init_hash_tracker helper for duplicated hash-init logic
in _fallback_to_full and no-DB branch of incremental_rebuild
- Add warning log in FileHashTracker.save() instead of silent OSError
- Update AGENTS.md ontology_version references from 15 to 17
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix: phantom route writes, duplicate members, and minor issues from review round 2
- Write phantom Route nodes in _write_clients_producers_and_calls using MERGE
(pass5 creates phantom routes for cross-service calls that were never
persisted to Kuzu, silently dropping HTTP_CALLS/ASYNC_CALLS edges)
- Remove redundant _load_existing_members before full pass1_parse in global
pass 5-6 step (was creating duplicate stub members alongside full entries)
- Use conn.close() + del instead of bare del for Kuzu handle cleanup on
fallback (avoids relying on CPython ref-counting for file lock release)
- Add FileNotFoundError handling in FileHashTracker.detect_changes for files
that vanish between listing and hashing
- Remove redundant inline import json in cli.py _cmd_increment
- Update stale _delete_file_scope docstring to match implementation
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>1 parent 263935f commit 67a76de
9 files changed
Lines changed: 1866 additions & 79 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
46 | | - | |
| 46 | + | |
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
| |||
190 | 190 | | |
191 | 191 | | |
192 | 192 | | |
193 | | - | |
| 193 | + | |
194 | 194 | | |
195 | 195 | | |
196 | 196 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
168 | 168 | | |
169 | 169 | | |
170 | 170 | | |
171 | | - | |
| 171 | + | |
172 | 172 | | |
173 | 173 | | |
174 | 174 | | |
| |||
212 | 212 | | |
213 | 213 | | |
214 | 214 | | |
215 | | - | |
216 | 215 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
83 | 83 | | |
84 | 84 | | |
85 | 85 | | |
86 | | - | |
| 86 | + | |
87 | 87 | | |
88 | 88 | | |
89 | 89 | | |
| |||
0 commit comments