FalkorDB Architecture Review

Status: working memory Date: 2026-05-23

Question

Are semantic_nodes, semantic_edges, and semantic_backing accidentally rebuilding FalkorDB inside D1?

Short answer: they will, if we let them become the canonical graph read model. They are still useful if we constrain them to an API-side semantic claim ledger: typed node identity, typed edge claims, backing/evidence pointers, sync state, and integrity checks. FalkorDB should own graph traversal and graph search.

What FalkorDB Actually Gives Us

The previous "Falkor is just a rebuildable cache" wording is too small. FalkorDB is a property graph database with OpenCypher, directed relationships, node labels, relationship types, range indexes, full-text indexes, relationship indexes, vector indexes, read-only query commands, atomic single-query writes, serialized writes per graph, and Redis durability options.

That makes FalkorDB a graph-query index and graph projection engine, not a UI badge and not merely a dump target.

Useful source points:

Current CareerVector Reality

The repo already has two different Falkor paths:

  • wiki/scripts/sync-falkor-graph.ts builds a Wiki graph projection from Markdown and graph annotations, emits schema statements plus node/edge MERGE Cypher, and can apply them to FalkorDB.
  • lib/knowledge-hub/src/runtime.ts exposes the header/control-plane actions for Git checkpoint and Falkor verify/sync, but its runtime Falkor sync only writes a tiny Hub status graph. It is not the whole nine-hub graph pipeline.

The new Ops semantic_* API gives agents and APIs a writeable way to express canonical node/edge/backing claims. That is valuable, but only if it remains a ledger and source registry. If UI/API graph reads mostly query D1 semantic_edges, we have duplicated the graph database and Falkor becomes ornamental.

Use three layers:

  1. Domain source stores own payload. Wiki Markdown, QA D1 tables, Ops events/anomalies/infra rows, provider snapshots, and generated file claims own their domain facts.

  2. D1 semantic claim ledger owns API writes and evidence. D1 records that a hub node or edge exists, why it exists, who/source wrote it, which file/row/provider object backs it, and whether it has been synced. It supports cheap API/MCP CRUD, idempotency, auditability, fallback reads, and Git checkpoint coordination.

  3. FalkorDB owns graph projection and graph questions. Falkor gets materialized nodes and relationships from the claim ledger and domain sources. Traversal, neighborhood, path queries, graph full-text, and future vector similarity should read from Falkor first, with D1 fallback only when Falkor is unavailable or unsynced.

Practical Rule

D1 may answer "what claims exist and what backs them?"

FalkorDB should answer "what is connected to this, why, through which paths, which neighborhoods are hot, and what nearby nodes match this text/vector query?"

Git should answer "what file-backed truth can rebuild this?"

Providers should answer "what external raw fact was observed?"

Consequence For Current semantic_*

The table names are acceptable if the product meaning is "semantic claim ledger". They become wrong if we add graph-neighborhood APIs on top of D1 and never project/query through Falkor.

The next implementation step should not be another D1 graph endpoint. It should be a semantic-to-Falkor projection service that:

  • creates Falkor indexes and constraints for hub ids and relationship ids;
  • projects all semantic_nodes, semantic_edges, and source/backing metadata;
  • records sync status back to D1;
  • exposes read APIs that prefer GRAPH.RO_QUERY;
  • keeps D1 fallback paths narrow and explicit;
  • uses parameterized Cypher through a real Redis/Falkor client where the runtime supports it, instead of growing the hand-rolled RESP bridge for complex reads.

This preserves API-first and MCP-second while giving FalkorDB the role it is actually good at.

Outage And Keepalive Rule

FalkorDB outage must not block API writes. D1 remains the write ledger and backing index; graph-specific reads degrade, report stale/error state, and catch up when projection resumes.

The Ops API worker owns the keepalive so Wiki, QA, and Ops do not all ping the same database. Its scheduled trigger runs every 12 hours and sends only Redis PING through the existing RESP bridge. It does not run graph counts, graph queries, sync statements, or UI polling. The only durable write is a tiny D1 audit row when D1 is available, so operators can see whether the scheduled keepalive succeeded.

Source: wiki/content/working-memory/falkordb-architecture-review.md