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>
This commit is contained in:
82
db/migrations/002_knowledge_graph.sql
Normal file
82
db/migrations/002_knowledge_graph.sql
Normal file
@@ -0,0 +1,82 @@
|
||||
-- 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'));
|
||||
Reference in New Issue
Block a user