Files
exo/db/migrations/002_knowledge_graph.sql
Kyle Isom 051a85d846 Add Phase 4 knowledge graph: nodes, cells, facts, edges, gRPC service
Build the knowledge graph pillar with the kg package:
- Node: hierarchical notes with parent/children, C2 wiki-style naming,
  shared tag/category pool with artifacts
- Cell: content units (markdown, code, plain) with ordinal ordering
- Fact: EAV tuples with transaction timestamps and retraction support
- Edge: directed graph links (child, parent, related, artifact_link)

Includes schema migration (002_knowledge_graph.sql), protobuf definitions
(kg.proto), full gRPC KnowledgeGraphService implementation, CLI commands
(node create/get), and comprehensive test coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:05:43 -07:00

83 lines
3.2 KiB
SQL

-- Migration 002: Knowledge graph tables
-- Adds nodes, cells, facts, and graph edges to the unified database.
-- Nodes are entities in the knowledge graph.
-- A node is either a note or an artifact link.
CREATE TABLE IF NOT EXISTS nodes
(
id TEXT PRIMARY KEY,
parent_id TEXT, -- parent node ID (C2 wiki style hierarchy)
name TEXT NOT NULL, -- human-readable name
type TEXT NOT NULL DEFAULT 'note', -- 'note' or 'artifact_link'
created TEXT NOT NULL, -- ISO 8601 UTC
modified TEXT NOT NULL, -- ISO 8601 UTC
FOREIGN KEY (parent_id) REFERENCES nodes (id)
);
CREATE INDEX IF NOT EXISTS idx_nodes_parent ON nodes (parent_id);
CREATE INDEX IF NOT EXISTS idx_nodes_name ON nodes (name);
-- Many-to-many junction: nodes <-> tags.
CREATE TABLE IF NOT EXISTS node_tags
(
node_id TEXT NOT NULL,
tag_id TEXT NOT NULL,
FOREIGN KEY (node_id) REFERENCES nodes (id),
FOREIGN KEY (tag_id) REFERENCES tags (id)
);
-- Many-to-many junction: nodes <-> categories.
CREATE TABLE IF NOT EXISTS node_categories
(
node_id TEXT NOT NULL,
category_id TEXT NOT NULL,
FOREIGN KEY (node_id) REFERENCES nodes (id),
FOREIGN KEY (category_id) REFERENCES categories (id)
);
-- Cells are content units within a note.
-- Inspired by Quiver's cell-based structure.
CREATE TABLE IF NOT EXISTS cells
(
id TEXT PRIMARY KEY,
node_id TEXT NOT NULL,
type TEXT NOT NULL DEFAULT 'markdown', -- 'markdown', 'code', etc.
contents BLOB,
ordinal INTEGER NOT NULL DEFAULT 0, -- display order within the node
created TEXT NOT NULL,
modified TEXT NOT NULL,
FOREIGN KEY (node_id) REFERENCES nodes (id)
);
CREATE INDEX IF NOT EXISTS idx_cells_node ON cells (node_id);
-- Facts record EAV relationships with transactional history.
-- entity + attribute + transaction form the natural key.
CREATE TABLE IF NOT EXISTS facts
(
id TEXT PRIMARY KEY,
entity_id TEXT NOT NULL, -- the subject (node or artifact UUID)
entity_name TEXT NOT NULL, -- human-readable entity name
attribute_id TEXT NOT NULL, -- attribute UUID
attribute_name TEXT NOT NULL, -- human-readable attribute name
value_contents TEXT NOT NULL,
value_type TEXT NOT NULL,
tx_timestamp INTEGER NOT NULL, -- Unix epoch of the transaction
retraction INTEGER NOT NULL DEFAULT 0 -- 1 = this fact is retracted
);
CREATE INDEX IF NOT EXISTS idx_facts_entity ON facts (entity_id);
CREATE INDEX IF NOT EXISTS idx_facts_attribute ON facts (attribute_id);
-- Graph edges link nodes to other nodes or artifacts.
CREATE TABLE IF NOT EXISTS edges
(
id TEXT PRIMARY KEY,
source_id TEXT NOT NULL, -- source node UUID
target_id TEXT NOT NULL, -- target node or artifact UUID
relation TEXT NOT NULL, -- 'child', 'parent', 'related', 'artifact_link', etc.
created TEXT NOT NULL,
FOREIGN KEY (source_id) REFERENCES nodes (id)
);
CREATE INDEX IF NOT EXISTS idx_edges_source ON edges (source_id);
CREATE INDEX IF NOT EXISTS idx_edges_target ON edges (target_id);
INSERT INTO schema_version (version, applied) VALUES (2, datetime('now'));