|
2 | 2 |
|
3 | 3 | All notable changes to CodeLens will be documented in this file. |
4 | 4 |
|
5 | | -The format is based on [Keep a Changelog](https://keepa.changelog.com/en/1.1.0/), |
| 5 | +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), |
6 | 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0/html). |
7 | 7 |
|
| 8 | +## [8.2.0] — Unreleased |
| 9 | + |
| 10 | +### Graph Data Model (issue #8) |
| 11 | + |
| 12 | +Replaces the ad-hoc flat-registry graph traversal with a true node + edge graph |
| 13 | +backed by SQLite. This unblocks structural queries like "who calls this function |
| 14 | +across the entire codebase", "blast radius if I rename this class", and |
| 15 | +"circular dependency chains" — engines no longer need to reimplement partial |
| 16 | +graph traversal logic. |
| 17 | + |
| 18 | +### Added |
| 19 | + |
| 20 | +- **`scripts/graph_model.py`** — New module implementing the graph data model: |
| 21 | + - `init_graph_schema(conn)` — Creates `graph_nodes` + `graph_edges` tables |
| 22 | + and 6 indexes (idempotent, called during database initialization). |
| 23 | + - `populate_graph_tables(workspace, db_path)` — Reads the flat backend |
| 24 | + registry and bulk-inserts all nodes + edges in a single transaction. |
| 25 | + Clears stale rows first so re-scans don't duplicate. |
| 26 | + - `query_callers(node_id, db_path, max_depth=1)` — BFS over CALLS edges |
| 27 | + in reverse (who calls this node). |
| 28 | + - `query_callees(node_id, db_path, max_depth=1)` — BFS over CALLS edges |
| 29 | + forward (what this node calls). |
| 30 | + - `clear_graph_tables(db_path)` — DELETE FROM both tables. |
| 31 | + - `find_nodes_by_name`, `graph_tables_exist`, `graph_tables_populated`, |
| 32 | + `graph_stats` — introspection helpers for engines and tests. |
| 33 | + |
| 34 | +- **Graph schema** (additive, prefixed `graph_` to avoid collisions): |
| 35 | + ```sql |
| 36 | + graph_nodes(id, node_id UNIQUE, node_type, name, file, line, extra_json) |
| 37 | + graph_edges(id, source_id, target_id, edge_type, file, line, |
| 38 | + confidence, extra_json) |
| 39 | + ``` |
| 40 | + Node types: `function|class|file|module|route|type|interface` |
| 41 | + Edge types: `CALLS|IMPORTS|DEFINES|INHERITS|IMPLEMENTS|USES_TYPE` |
| 42 | + (Only `CALLS` is populated in v8.2; other types are reserved for future |
| 43 | + engine migrations — `impact`, `circular`, `dependents`.) |
| 44 | + |
| 45 | +- **`trace --use-graph` / `--no-graph` flags** — The `trace` command now |
| 46 | + queries the graph tables by default, with the flat-registry path retained |
| 47 | + as fallback. Use `--no-graph` to force the flat path for A/B testing. |
| 48 | + |
| 49 | +- **`tests/test_graph_model.py`** — 20 test cases covering schema init, |
| 50 | + population, query_callers, query_callees, re-population idempotency, and |
| 51 | + the trace pilot A/B comparison. |
| 52 | + |
| 53 | +### Changed |
| 54 | + |
| 55 | +- **`scripts/persistent_registry.py`** — Calls `init_graph_schema(conn)` |
| 56 | + during `_init_schema` so the graph tables always exist by the time any |
| 57 | + engine tries to query them. Additive — existing tables untouched. |
| 58 | +- **`scripts/commands/scan.py`** — After the flat backend registry is built, |
| 59 | + calls `populate_graph_tables(workspace, db_path)` to populate the graph |
| 60 | + tables in a single bulk transaction. Scan output now includes a `graph` |
| 61 | + field with node + edge counts. |
| 62 | +- **`scripts/trace_engine.py`** — Pilot engine migration: `trace_symbol` is |
| 63 | + now a dispatcher that picks between `trace_via_graph` (default) and |
| 64 | + `trace_via_flat` (fallback). Falls back to flat automatically when graph |
| 65 | + tables are empty (pre-8.2 databases). Output shape is identical regardless |
| 66 | + of backend — callers and formatters don't need to know which backend ran. |
| 67 | + |
| 68 | +### Non-Breaking |
| 69 | + |
| 70 | +- All 56 existing CLI commands continue to work unchanged. |
| 71 | +- Existing flat tables (`symbols`, `refs`, `files`, `analysis_cache`, |
| 72 | + `scan_metadata`) and JSON registries (`frontend.json`, `backend.json`) |
| 73 | + are untouched. |
| 74 | +- The graph tables are additive — no existing table or column was modified. |
| 75 | +- Scan performance impact is negligible (single bulk INSERT in one |
| 76 | + transaction; <5ms on the clean_app fixture with 31 nodes + 97 edges). |
| 77 | + |
| 78 | +### Migration Notes for Engine Authors |
| 79 | + |
| 80 | +The flat registry remains the source of truth during scan. The graph tables |
| 81 | +are a derived projection that engines can query for structural traversals. |
| 82 | +To migrate an engine to the graph backend: |
| 83 | + |
| 84 | +1. Check `graph_model.graph_tables_populated(db_path)` — if False, fall back |
| 85 | + to the flat path (don't hard-fail). |
| 86 | +2. Use `graph_model.find_nodes_by_name(name, db_path)` to find start nodes. |
| 87 | +3. Use `graph_model.query_callers` / `query_callees` for BFS traversal. |
| 88 | +4. Preserve the existing flat-path output shape so callers and formatters |
| 89 | + don't break. See `trace_engine.trace_via_graph` for a reference impl. |
| 90 | + |
| 91 | +Future engine migrations (post-v8.2): `impact`, `circular`, `dependents`. |
| 92 | + |
| 93 | +--- |
| 94 | + |
8 | 95 | ## [8.1.0] — 2026-06-13 |
9 | 96 |
|
10 | 97 | ### F1 Benchmark Improvements |
|
0 commit comments