Skip to content

refactor(kuzu): Reflect KuzuDB deprecation and provide users with an exit route (migrating to another DB) - #1302

Open
macunha1 wants to merge 7 commits into
CodeGraphContext:mainfrom
macunha1:main
Open

refactor(kuzu): Reflect KuzuDB deprecation and provide users with an exit route (migrating to another DB)#1302
macunha1 wants to merge 7 commits into
CodeGraphContext:mainfrom
macunha1:main

Conversation

@macunha1

Copy link
Copy Markdown

Why this is worth considering?

CGC currently treats KuzuDB as a normal runtime backend, but KuzuDB is deprecated: it was archived upstream and its Python package no longer installs cleanly on newer Python versions such as Python 3.14. As archived repos are read-only, we can't fix that. That turns Kuzu into an adoption blocker: a user can hit a packaging failure before they ever get to the value of CGC itself.

This exit path is, unfortunately, inevitable. The practical question is whether we make that path explicit and supported, or whether users discover it through broken installs. This PR proposes the cleaner route: keep KuzuDB data reachable through migration, but stop depending on KuzuDB as an active runtime backend.

The product story becomes cleaner for new users:

  • FalkorDB Lite remains the fast local default where it is available.
  • LadybugDB covers cross-platform embedded installs.
  • FalkorDB Remote, Neo4j, and Nornic cover shared or managed graph deployments.
  • Existing KuzuDB users get a documented migration route instead of an unexplained hard cutoff.

That direction lets us keep the "works locally, works with agents, works with teams" message without carrying an archived database dependency in the main install path.

What changed

This branch moves KuzuDB from "supported backend" to "deprecated legacy migration source":

  • Removes the active KuzuDB runtime backend and Kuzu-specific code paths.
  • Updates backend selection so supported choices are falkordb, ladybugdb, falkordb-remote, neo4j, and nornic.
  • Uses LadybugDB as the cross-platform embedded fallback when FalkorDB Lite is not available.
  • Adds automatic legacy KuzuDB migration into the configured supported backend.
  • Adds a dedicated KuzuDB migration guide for users who still have an existing Kuzu store.
  • Updates README, CLI docs, setup docs, troubleshooting docs, VS Code extension copy, and backend comparison docs so the public story matches the supported runtime surface.
  • Fixes the FalkorDB worker path for redis-py 8 Unix socket behavior.
  • Adds unit and integration coverage around migration behavior and backend selection.

Why this route

The alternative is to keep treating KuzuDB as an equal backend and try to work around its already limited state. That may buy short-term compatibility, but it leaves CGC tied to an archived upstream dependency and makes future Python support difficult. Since the deprecation pressure already exists, delaying KuzuDB migration does not avoid the exit.

This route keeps the useful part of KuzuDB support (protecting existing user data) while removing the part that creates ongoing install risk. It also makes the backend matrix easier to communicate:

  • New local users get FalkorDB Lite first, with LadybugDB as the cross-platform embedded option.
  • Teams can use FalkorDB Remote, Neo4j, or Nornic when they want shared infrastructure.
  • Existing KuzuDB users get a migration bridge instead of being left behind.

That feels like the right product tradeoff: less dependency risk for new adoption, without leaving behind existing data and users.

User-facing impact

For new users, installation and setup should be more predictable because the default path no longer depends on an archived package. They will never have to worry about KuzuDB

For existing KuzuDB users, the recommended path is migration. CGC detects legacy KuzuDB stores, exports them through the bundle flow, and imports them into the configured supported backend when the target is empty. The docs also explain the Docker-based migration path for environments where KuzuDB only works under an older Python image. This makes the deprecation visible and gives users a controlled exit path before newer Python environments make that decision for them.

Validation

The branch adds and updates tests for:

  • Legacy KuzuDB migration behavior.
  • Backend selection after removing KuzuDB as a runtime backend.
  • FalkorDB remote/session handling.
  • CLI configuration behavior.

Scope

Try and deprecate KuzuDB as a production runtime backend, with a narrow intent: acknowledge that KuzuDB was archived, won't be supported anymore, and consequently should also be deprecated in CGC's supported runtime surface. Reduce CGC installation and maintenance risk, and give existing KuzuDB data a clear exit path into supported backends.

@vercel

vercel Bot commented Jun 21, 2026

Copy link
Copy Markdown

@macunha1 is attempting to deploy a commit to the shashankss1205's projects Team on Vercel.

A member of the Team first needs to authorize it.

@Shashankss1205

Copy link
Copy Markdown
Collaborator

👋 Thanks for contributing to CodeGraphContext! Since this PR was opened, main has moved forward significantly (we just shipped v0.5.2 and merged ~50 PRs), so this one now has merge conflicts. Could you please rebase onto the latest main and resolve the conflicts? Once it is conflict-free and CI is green, we will review and merge it. Really appreciate your work — thank you! 🙏

@Shashankss1205

Copy link
Copy Markdown
Collaborator

Triage update: thank you for the thorough work here, @macunha1 — upstream KuzuDB's status is a real concern and this deserves a proper decision rather than a drive-by review. Flagging for @Shashankss1205: this PR proposes deprecating the Kùzu backend and giving users a migration path. Main currently still ships Kùzu as a first-class backend (with Ladybug as the successor lineage), so the call on direction needs to come from the project. Leaving open until that decision is made.

…ckets

redis-py 8 defaults to RESP3, which triggers a maintenance-notifications
handshake on every connection. The handshake requires a TCP host
attribute to determine the endpoint type. Unix-socket connections set
host=None, which passes hasattr(conn, "host") but then raises inside
_enable_maintenance_notifications when it checks the value.

Fix: pass protocol=2 to FalkorDB(...) to force RESP2. The guard at
connection.py checks get_protocol() != 2 before attempting the
handshake, so RESP2 skips it entirely. FalkorDB graph operations are
RESP2-compatible and unaffected.
KuzuDB is deprecated and can't be installed on Python 3.14+. The
repository was archived and can't/won't get updates to fix that, so
let's KuzuDB deprecate as a runtime backend and implement a migration
path for users running on KuzuDB.

Add a legacy migration helper that detects old KuzuDB stores, exports
them into a temporary CGC bundle, and imports that bundle into the
backend the user selected. If no backend is configured, migration
follows the resolved default backend.

Document the Docker-based migration path for installing KuzuDB in an
older temporary Python environment, and update docs so KuzuDB is
described as migration-only.

Add unit coverage for source discovery, missing Kuzu installs, non-empty
target guards, bundle creation, row normalization, configured target
selection, and the runtime backend deprecation path.
- Add factory-level migration tests for LadybugDB, FalkorDB, remote
  FalkorDB, Neo4j, and Nornic so legacy Kuzu data follows the resolved
  backend instead of an accidental hard-coded target.
- Cover the FalkorDB-to-Ladybug fallback path so a broken embedded
  FalkorDB setup still migrates into the adjusted LadybugDB store path.
- Cover the zero-config LadybugDB path after KuzuDB removal so the
  default replacement backend keeps migration behavior visible in tests.
- Add `bundle merge` to the canonical CLI command matrix because the
  command exists in the source inventory and was missing from executable
  CLI coverage.
- Enable `ALLOW_DB_DELETION` in the CLI test fixture so the stubbed
  delete command remains testable without changing production deletion
  safeguards.
- Modified config directory resolution to honor CGC_CONFIG_DIR and
  XDG_CONFIG_HOME, because MCP clients should not depend on the legacy
  ~/.codegraphcontext path.
- Added separate data and cache roots so embedded databases and logs can
  live under XDG_DATA_HOME and XDG_CACHE_HOME.
- Routed CLI configuration output to stderr so MCP startup logs do not
  compete with JSON-RPC stdout.
- Modified FalkorDB backend selection to fail loudly instead of falling
  back to LadybugDB, because an explicit local database choice should
  not create a second embedded store.
- Updated service initialization so FalkorDB startup failures preserve
  the selected backend contract and surface the real worker error.
- Fixed bundle import handling for LadybugDB internal IDs and properties
  so cross-backend migrations can load into FalkorDB without
  non-primitive property failures.
- restore explicit Kuzu backend selection
- align tests after rebase
- preserve upstream README during rebase
@macunha1

macunha1 commented Aug 2, 2026

Copy link
Copy Markdown
Author

Triage update: thank you for the thorough work here, @macunha1 — upstream KuzuDB's status is a real concern and this deserves a proper decision rather than a drive-by review. Flagging for @Shashankss1205: this PR proposes deprecating the Kùzu backend and giving users a migration path. Main currently still ships Kùzu as a first-class backend (with Ladybug as the successor lineage), so the call on direction needs to come from the project. Leaving open until that decision is made.

@Shashankss1205 done ✅

Rebased onto the latest main and resolved all the conflicts, and updated the test suite to cover new cases. The PR is conflict-free now. 👌

Triage update: thank you for the thorough work here, @macunha1 — upstream KuzuDB's status is a real concern and this deserves a proper decision rather than a drive-by review. Flagging for @Shashankss1205: this PR proposes deprecating the Kùzu backend and giving users a migration path. Main currently still ships Kùzu as a first-class backend (with Ladybug as the successor lineage), so the call on direction needs to come from the project. Leaving open until that decision is made.

All good. Please let me know once the project direction is decided, or if you see the need for any more changes to the migration path or implementation in this PR. I can update it accordingly.

- Constrain FastAPI, Starlette, and AnyIO so the workflow resolves a
  compatible TestClient stack across Python 3.12, 3.13, and 3.14.
- Add the matching httpx dev dependency and make the test runner handle
  an unset PYTHONPATH without creating an empty import path.
@Shashankss1205

Copy link
Copy Markdown
Collaborator

Flagging this for a maintainer decision rather than reviewing it as a routine change.

The PR is well-argued and the diff is coherent (24 files, mergeable, no conflicts). But it changes the product's supported-backend story — retiring KùzuDB as a runtime backend and providing a migration path — and that is a direction call for @Shashankss1205, not something to merge on technical correctness alone.

The case you make is real and worth stating plainly for whoever decides:

Against it: KùzuDB is currently the zero-config default on Windows and the FalkorDB fallback, so this touches the default install path for a whole platform, and #1512 shows the simulator is already Kùzu/Ladybug-fragile in ways that would need to move with it.

Two things that would help the decision regardless of outcome:

  1. What happens to a user with an existing Kùzu graph on upgrade — is the migration automatic, prompted, or manual?
  2. Does LadybugDB cover every backend capability Kùzu currently provides? bug(graph): simulator's relationship query uses labels(n1)[0] and a bare pattern predicate, so simulate_metrics always fails on KùzuDB/LadybugDB #1512 suggests at least the simulator's labels(n1)[0] path does not work on either embedded backend today.

Holding rather than merging.

@Shashankss1205

Copy link
Copy Markdown
Collaborator

Thanks for the very thorough write-up — the reasoning about carrying an archived upstream dependency is sound, and the migration guide plus legacy_kuzu_migration.py (with 700 lines of tests) is exactly the right way to protect existing users' data.

Two things before this can land.

1. Three tests fail on a trial-merge onto main:

FAILED tests/unit/core/test_backend_fallback_logging.py::test_falkordb_to_kuzu_fallback_names_kuzu
FAILED tests/unit/core/test_backend_fallback_logging.py::test_kuzu_missing_fallback_names_the_replacement
FAILED tests/unit/core/test_database_falkordb_wrapper.py::test_factory_retries_falkordb_for_a_different_database_path

(1140 pass.) The first two are expected fallout from the deprecation and just need updating to assert the new behaviour. The third points at something bigger — see below.

2. There's a second breaking change bundled in here that isn't in the PR description.
core/__init__.py:190 now makes explicit FalkorDB selection strict:

Database set to 'falkordb' but FalkorDB Lite is not supported or not installed. Explicit FalkorDB selection is strict and will not fall back to LadybugDB.

Today -db falkordb falls back when FalkorDB Lite isn't functional; after this PR it hard-fails. That's a defensible design (explicit beats implicit), but it's an independent behavioural change from the Kuzu deprecation and it's what breaks test_factory_retries_falkordb_for_a_different_database_path. Could you either split it into its own PR or call it out explicitly in the description so it gets its own discussion?

Beyond that, removing a documented backend is a product call rather than a code-review one, so I'm holding this for @Shashankss1205 to weigh in on the direction before merge — the implementation isn't the question here. Worth noting kuzudb is still fully functional on this machine (I used it end-to-end earlier today), so this is a deliberate deprecation rather than a forced one; that makes the timing a judgement call.

Please do fix the three tests in the meantime — that part is unambiguous.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog tasks

Development

Successfully merging this pull request may close these issues.

2 participants