Skip to content

feat(core): backend-neutral federation, mixed Kuzu + DuckDB subrepos#24

Merged
joy-software merged 1 commit into
developfrom
feature/duckdb-federation
Jun 2, 2026
Merged

feat(core): backend-neutral federation, mixed Kuzu + DuckDB subrepos#24
joy-software merged 1 commit into
developfrom
feature/duckdb-federation

Conversation

@joy-software
Copy link
Copy Markdown
Contributor

Summary

Eighth and final step of the Kuzu → DuckDB migration. Federation now opens child read-only connections via the GraphDB protocol, so the same MCP tool can fan out across subrepos using either backend (any mix) without per-tool branching.

What lands

File Change
`analysis/federation.py` `open_kuzu_ro` → `open_graphdb_ro` with backend detection. `for_each_kuzu` family renamed to `_graphdb` variants. Backward-compat aliases preserve existing imports. `ChildStatus` gains `has_duckdb` + `has_graphdb`.

Detection

`_detect_backend_file(repo_root)` looks at `.codegraph/`:

  • `graph.duckdb` exists → DuckDB
  • `graph.db` exists → Kuzu
  • neither → None (subrepo skipped)

DuckDB wins when both are present (handles a half-migrated repo cleanly).

End-to-end verification — mixed backends

```
/tmp/cgh_fed/
child_a/.codegraph/graph.db # Kuzu
child_b/.codegraph/graph.duckdb # DuckDB

open_graphdb_ro(child_a) → KuzuGraphDB, Files=1, Functions=1
open_graphdb_ro(child_b) → DuckDBGraphDB, Files=1, Functions=1
```

Both children answer `count_nodes` / `find_neighbors` / etc. through the same protocol — federated MCP tools work transparently.

Migration complete

File Cypher PR
`indexer.py` 41 → 0 #19
`server/tools_query.py` 13 → 0 #20
`server/tools_arch/docs.py` + `analysis/{dead_code,context_builder}.py` 14 → 0 #21
`server/tools_viz.py` 19 → 0 #22
`cli/commands_monitor.py` 12 → 0 #23
`analysis/federation.py` n/a #24
TOTAL 99 → 0

`CGH_DB=duckdb` now works end-to-end: index, query, viz, stats, and federated subrepo aggregation all return identical results to the Kuzu default.

Next

  • `release/0.5.0`: flip default to DuckDB, mark Kuzu deprecated in the README, lift the Python <3.14 cap
  • `release/0.6.0`: delete the Kuzu code path and dependency entirely

Eighth and final step of the Kuzu -> DuckDB migration. Federation
now opens child read-only connections via the GraphDB protocol so
the same MCP tool can fan out across subrepos using either backend
without any per-tool branching. Parent on Kuzu, children on DuckDB
(or any mix) all work.

What lands:

- codegraph/analysis/federation.py: detection + adapter wiring.
  - new _detect_backend_file(repo_root) inspects .codegraph/ for
    graph.duckdb (wins) or graph.db (fallback). Returns None when
    neither is present.
  - open_kuzu_ro renamed open_graphdb_ro. The detected backend is
    opened via DuckDBGraphDB or KuzuGraphDB; both implement the
    GraphDB protocol so the caller sees the same interface either
    way. Always closes — Kuzu still holds an OS file lock that
    must be released so child owners can keep writing.
  - for_each_kuzu / for_each_child_kuzu / _run_one_kuzu renamed
    for_each_graphdb / for_each_child_graphdb / _run_one_graphdb.
    Signature changed from kuzu.Connection to GraphDB — every
    existing caller already uses the helper methods (find_nodes,
    find_neighbors, count_nodes, ...) introduced in #19-#23, so
    no caller-side changes needed.

  Backward-compat aliases (open_kuzu_ro = open_graphdb_ro, etc.)
  keep existing imports working. The 4 callers in server/tools_*.py
  import the old names — they'll be migrated to the new names
  in 0.6 when the Kuzu code path is removed.

- ChildStatus dataclass gains has_duckdb + has_graphdb. The .ok
  property now uses has_graphdb (either backend counts as "ready").

End-to-end verification on a mixed-backend repo layout:

  /tmp/cgh_fed/
    child_a/.codegraph/graph.db        # Kuzu
    child_b/.codegraph/graph.duckdb    # DuckDB

  open_graphdb_ro(child_a) -> KuzuGraphDB,   Files=1 Functions=1
  open_graphdb_ro(child_b) -> DuckDBGraphDB, Files=1 Functions=1

Both children answer count_nodes / find_neighbors / etc. through
the same protocol — federated MCP tools work transparently.

Migration status:

| File                      | Cypher emit | PR  |
|---------------------------|-------------|-----|
| indexer.py                | 41 -> 0     | #19 |
| server/tools_query.py     | 13 -> 0     | #20 |
| server/tools_arch.py      | 3  -> 0     | #21 |
| server/tools_docs.py      | 6  -> 0     | #21 |
| analysis/dead_code.py     | 2  -> 0     | #21 |
| analysis/context_builder  | 3  -> 0     | #21 |
| server/tools_viz.py       | 19 -> 0     | #22 |
| cli/commands_monitor.py   | 12 -> 0     | #23 |
| analysis/federation.py    | n/a         | #24 |
| TOTAL                     | 99 -> 0     |     |

CGH_DB=duckdb now works end-to-end: index, query, viz, stats, and
federated subrepo aggregation all return identical results to the
Kuzu default backend.

Next: release/0.5.0 flips the default to DuckDB, marks Kuzu deprecated
in the README, lifts the Python <3.14 cap. release/0.6.0 deletes
the Kuzu code path and dependency.
@joy-software joy-software merged commit 3a7f769 into develop Jun 2, 2026
1 check passed
@joy-software joy-software deleted the feature/duckdb-federation branch June 2, 2026 06:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant