1 #!/usr/bin/env python3 2 """ 3 Graph-Weighted Memory Engine for Distributed Cognitive Cluster 4 Implements Dynamic Edge Reinforcement, Decay, and Spreading Activation 5 """ 6 import sqlite3 7 import datetime 8 import math 9 import sys 10 import os 11 import json 12 13 DB_PATH = os.environ.get( 14 'GRAPH_MEMORY_DB', 15 '/var/neural_memory/data/graph_memory.db' if os.path.exists('/var/neural_memory/data/graph_memory.db') 16 else os.path.join(os.path.dirname(os.path.abspath(__file__)), '.graph_memory_cache.db') 17 ) 18 19 def get_db(): 20 conn = sqlite3.connect(DB_PATH) 21 conn.execute('PRAGMA journal_mode = WAL;') 22 conn.execute('PRAGMA foreign_keys = ON;') 23 conn.row_factory = sqlite3.Row 24 return conn 25 26 def init_db(): 27 conn = get_db() 28 c = conn.cursor() 29 c.executescript(''' 30 CREATE TABLE IF NOT EXISTS graph_nodes ( 31 id TEXT PRIMARY KEY, 32 label TEXT NOT NULL, 33 entity_type TEXT NOT NULL, 34 content TEXT NOT NULL, 35 embedding BLOB, 36 importance_score REAL DEFAULT 0.50, 37 access_count INTEGER DEFAULT 1, 38 created_at TEXT NOT NULL, 39 last_accessed_at TEXT NOT NULL 40 ); 41 42 CREATE TABLE IF NOT EXISTS graph_edges ( 43 source_id TEXT NOT NULL, 44 target_id TEXT NOT NULL, 45 relation TEXT NOT NULL, 46 weight REAL DEFAULT 0.80, 47 confidence REAL DEFAULT 1.00, 48 last_reinforced_at TEXT NOT NULL, 49 decay_rate REAL DEFAULT 0.005, 50 PRIMARY KEY (source_id, target_id, relation), 51 FOREIGN KEY (source_id) REFERENCES graph_nodes(id) ON DELETE CASCADE, 52 FOREIGN KEY (target_id) REFERENCES graph_nodes(id) ON DELETE CASCADE 53 ); 54 55 CREATE TABLE IF NOT EXISTS graph_episodes ( 56 id INTEGER PRIMARY KEY AUTOINCREMENT, 57 title TEXT NOT NULL, 58 context TEXT NOT NULL, 59 actions TEXT NOT NULL, 60 outcome TEXT NOT NULL, 61 root_node_id TEXT, 62 timestamp TEXT NOT NULL, 63 FOREIGN KEY (root_node_id) REFERENCES graph_nodes(id) ON DELETE SET NULL 64 ); 65 66 CREATE TABLE IF NOT EXISTS graph_skills ( 67 name TEXT PRIMARY KEY, 68 trigger_pattern TEXT NOT NULL, 69 command_template TEXT NOT NULL, 70 description TEXT NOT NULL, 71 associated_node_id TEXT, 72 FOREIGN KEY (associated_node_id) REFERENCES graph_nodes(id) ON DELETE SET NULL 73 ); 74 75 CREATE INDEX IF NOT EXISTS idx_nodes_type ON graph_nodes(entity_type); 76 CREATE INDEX IF NOT EXISTS idx_edges_source ON graph_edges(source_id); 77 CREATE INDEX IF NOT EXISTS idx_edges_target ON graph_edges(target_id); 78 ''') 79 conn.commit() 80 conn.close() 81 82 def now_iso(): 83 return datetime.datetime.now(datetime.timezone.utc).isoformat() 84 85 def add_node(node_id, label, entity_type, content, importance=0.5): 86 conn = get_db() 87 c = conn.cursor() 88 t = now_iso() 89 c.execute(''' 90 INSERT INTO graph_nodes (id, label, entity_type, content, importance_score, access_count, created_at, last_accessed_at) 91 VALUES (?, ?, ?, ?, ?, 1, ?, ?) 92 ON CONFLICT(id) DO UPDATE SET 93 label=excluded.label, 94 entity_type=excluded.entity_type, 95 content=excluded.content, 96 importance_score=excluded.importance_score, 97 access_count=access_count+1, 98 last_accessed_at=excluded.last_accessed_at; 99 ''', (node_id, label, entity_type, content, importance, t, t)) 100 conn.commit() 101 conn.close() 102 103 def add_edge(source_id, target_id, relation, weight=0.8, confidence=1.0): 104 conn = get_db() 105 c = conn.cursor() 106 t = now_iso() 107 c.execute(''' 108 INSERT INTO graph_edges (source_id, target_id, relation, weight, confidence, last_reinforced_at) 109 VALUES (?, ?, ?, ?, ?, ?) 110 ON CONFLICT(source_id, target_id, relation) DO UPDATE SET 111 weight=MIN(1.0, weight + 0.15), 112 last_reinforced_at=excluded.last_reinforced_at; 113 ''', (source_id, target_id, relation, weight, confidence, t)) 114 conn.commit() 115 conn.close() 116 117 def spread_activation(seed_id, max_depth=2, decay=0.75, threshold=0.25): 118 conn = get_db() 119 c = conn.cursor() 120 121 visited_nodes = {} 122 visited_edges = [] 123 queue = [(seed_id, 1.0, 0)] # (node_id, energy, depth) 124 125 while queue: 126 curr_id, energy, depth = queue.pop(0) 127 if curr_id in visited_nodes and visited_nodes[curr_id] >= energy: 128 continue 129 visited_nodes[curr_id] = energy 130 131 # Update last accessed 132 c.execute('UPDATE graph_nodes SET access_count=access_count+1, last_accessed_at=? WHERE id=?', (now_iso(), curr_id)) 133 134 if depth >= max_depth: 135 continue 136 137 c.execute('SELECT target_id, relation, weight FROM graph_edges WHERE source_id=?', (curr_id,)) 138 for target_id, rel, weight in c.fetchall(): 139 next_energy = energy * weight * decay 140 if next_energy >= threshold: 141 visited_edges.append({'from': curr_id, 'rel': rel, 'to': target_id, 'weight': round(weight, 3)}) 142 queue.append((target_id, next_energy, depth + 1)) 143 # Reinforce edge on traversal 144 c.execute('UPDATE graph_edges SET weight=MIN(1.0, weight+0.05), last_reinforced_at=? WHERE source_id=? AND target_id=? AND relation=?', 145 (now_iso(), curr_id, target_id, rel)) 146 147 conn.commit() 148 149 # Fetch node details 150 nodes_data = [] 151 for nid, energy in sorted(visited_nodes.items(), key=lambda x: x[1], reverse=True): 152 c.execute('SELECT id, label, entity_type, content, importance_score FROM graph_nodes WHERE id=?', (nid,)) 153 row = c.fetchone() 154 if row: 155 d = dict(row) 156 d['activation_energy'] = round(energy, 3) 157 nodes_data.append(d) 158 159 conn.close() 160 return {'nodes': nodes_data, 'edges': visited_edges} 161 162 def seed_baseline(): 163 init_db() 164 # 1. Physical nodes 165 nodes = [ 166 ("node_master", "Apple Silicon Mac (Master)", "host", "Primary cognitive controller, runs DeepSeek-R1 inference on Metal GPU.", 1.0), 167 ("node_dell", "Dell Inspiron 3521 (Tactical Body)", "host", "24/7 headless execution worker, persistent memory anchor, mass storage server.", 1.0), 168 ("vol_ssd", "Internal ADATA SSD (/dev/sda3)", "storage", "146 GB ext4, root OS volume and L1 hot memory graph anchor.", 0.95), 169 ("vol_d_drive", "Protected Personal Drive D (/dev/sda5)", "storage", "77.1 GB NTFS, contains critical non-recoverable operator data. ROE-01 Enforced.", 1.0), 170 ("vol_hdd1", "Mass Storage HDD 1 (/dev/sdb1)", "storage", "931.5 GB NTFS mounted at /mnt/hdd1 (L2 warm semantic vector store).", 0.90), 171 ("vol_hdd2", "Mass Storage HDD 2 (/dev/sdc1)", "storage", "931.5 GB Mass storage mounted at /mnt/hdd2 (L3 cold archival vault).", 0.90), 172 ("hw_gpu_amd", "AMD Radeon HD 8730M", "hardware", "Discrete GPU with 2GB VRAM, driver amdgpu, render node /dev/dri/renderD129.", 0.85), 173 ("hw_gpu_intel", "Intel HD Graphics 4000", "hardware", "Integrated display core, driver i915, render node /dev/dri/renderD128.", 0.70), 174 ("hw_cpu", "Intel Core i5-3337U", "hardware", "Ivy Bridge, 2C/4T, 1.80-2.70GHz, AVX, VT-x active.", 0.85), 175 ("rule_roe01", "ROE-01: Sanctity of Drive D", "policy", "Under no circumstances may /dev/sda5 be modified, partitioned, or written to. Read-only only.", 1.0), 176 ("rule_caffeine", "Power: Permanent Caffeinate Policy", "policy", "Systemd sleep, suspend, and hibernate targets masked to /dev/null; wifi powersave disabled.", 0.95), 177 ("skill_caffeinate", "caffeinate", "skill", "sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target", 0.90), 178 ("skill_test_gpu", "test_gpu", "skill", "cat /sys/class/drm/card1/device/mem_info_vram_total", 0.80), 179 ("picoclaw_daemon", "PicoClaw Gateway", "agent", "Ultra-lightweight Go agent daemon running 24/7 in under 10MB RAM on Dell.", 0.95) 180 ] 181 for nid, lbl, etype, cnt, imp in nodes: 182 add_node(nid, lbl, etype, cnt, imp) 183 184 # 2. Directed weighted edges 185 edges = [ 186 ("node_master", "node_dell", "COMMANDS", 1.0), 187 ("node_dell", "vol_ssd", "CONTAINS", 1.0), 188 ("node_dell", "vol_d_drive", "PROTECTS", 1.0), 189 ("node_dell", "vol_hdd1", "MOUNTS", 0.95), 190 ("node_dell", "vol_hdd2", "MOUNTS", 0.95), 191 ("node_dell", "hw_gpu_amd", "CONTAINS", 0.95), 192 ("node_dell", "hw_gpu_intel", "CONTAINS", 0.80), 193 ("node_dell", "hw_cpu", "CONTAINS", 0.95), 194 ("node_dell", "picoclaw_daemon", "HOSTS", 1.0), 195 ("rule_roe01", "vol_d_drive", "GOVERNS", 1.0), 196 ("rule_caffeine", "node_dell", "PROTECTS", 1.0), 197 ("skill_caffeinate", "rule_caffeine", "IMPLEMENTS", 0.95), 198 ("skill_test_gpu", "hw_gpu_amd", "AUDITS", 0.90) 199 ] 200 for s, t, r, w in edges: 201 add_edge(s, t, r, w) 202 203 if __name__ == '__main__': 204 if len(sys.argv) > 1 and sys.argv[1] == 'seed': 205 seed_baseline() 206 print('GRAPH_MEMORY_INITIALIZED_AND_SEEDED') 207 elif len(sys.argv) > 2 and sys.argv[1] == 'query': 208 subgraph = spread_activation(sys.argv[2]) 209 print(json.dumps(subgraph, indent=2)) 210 elif len(sys.argv) > 1 and sys.argv[1] == 'status': 211 conn = get_db() 212 c = conn.cursor() 213 c.execute('SELECT COUNT(*) FROM graph_nodes;') 214 nn = c.fetchone()[0] 215 c.execute('SELECT COUNT(*) FROM graph_edges;') 216 ne = c.fetchone()[0] 217 conn.close() 218 print(f"Graph Status: {nn} Nodes, {ne} Edges") 219 else: 220 init_db() 221 print('GRAPH_DB_VERIFIED') 222