From 4bc49c90b3c20525e194070748fbf69a31d42ecf Mon Sep 17 00:00:00 2001 From: GlyphRunner System Date: Wed, 20 May 2026 17:41:47 -0400 Subject: [PATCH] =?UTF-8?q?Implement=20LAIN=20=E2=86=94=20Supercharged=20G?= =?UTF-8?q?lyph=20Bridge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New module: - gx_lain/lain_glyph_bridge.py: Bridge connecting LedoGlyph600 to LAIN cognition Functions: - load_glyph_context(manifest, context): Load relevant glyph from registry - inject_glyph_metadata_into_lane(lane_result, glyph_context): Add glyph fields to lane - compute_glyph_resonance(glyph_context): Calculate glyph resonance metrics - augment_fused_symbol_with_glyphs(fused_symbol, glyph_context): Add glyph to final output Modified: - gx_lain/runtime.py: Integrate glyph bridge into execute_with_lain() * Load glyph context as step 1 of cognition * Inject glyph metadata into each lane result * Augment fused symbol with glyph context * Add glyph_resonance to diagnostics * Track glyph loading in cognition_trace Tests: - tests/test_lain_glyph_bridge.py: 10 comprehensive tests * Context loading (with/without glyph) * Metadata injection (preserves existing fields) * Resonance computation (4-component metric) * Symbol augmentation * Full integration test Features: - Glyph metadata: id, name, category, score, period, band - Frequency signatures: praw (P, R, A, W) - Activation envelopes: mode, score - Lineage: signature, inheritance weight - Symbolic anatomy: power, complexity, resonance, stability, connectivity, affinity - Resonance profile: activation + frequency + symbolic metrics (0.0-1.0) All 18 integration tests still passing (no regressions). --- gx_lain/lain_glyph_bridge.py | 292 +++++++++++++++++++++++++ gx_lain/runtime.py | 39 +++- tests/test_lain_glyph_bridge.py | 369 ++++++++++++++++++++++++++++++++ 3 files changed, 697 insertions(+), 3 deletions(-) create mode 100644 gx_lain/lain_glyph_bridge.py create mode 100644 tests/test_lain_glyph_bridge.py diff --git a/gx_lain/lain_glyph_bridge.py b/gx_lain/lain_glyph_bridge.py new file mode 100644 index 0000000..fef4197 --- /dev/null +++ b/gx_lain/lain_glyph_bridge.py @@ -0,0 +1,292 @@ +"""LAIN ↔ Supercharged Glyph Bridge + +Connects the Supercharged Glyph Registry (LedoGlyph600) to the LAIN cognition +engine, injecting glyph metadata, frequency signatures, lineage, activation +envelopes, and resonance profiles into the cognition process. +""" + +from typing import Optional, Dict, Any, List +from glyphs.super_registry import get_super, search_super, list_super_ids + + +def load_glyph_context(manifest: dict, context: dict) -> dict: + """Load glyph context relevant to the GX file. + + Determines which glyph(s) are relevant by: + 1. Checking manifest["glyph_id"] if present + 2. Searching glyphs by manifest["glyphs"] if present + 3. Searching glyphs by manifest["tags"] if present + 4. Falling back to default context if no glyph found + + Args: + manifest: GX manifest dict + context: Execution context dict + + Returns: + Dict with glyph metadata and context fields: + { + "id": str, + "name": str, + "category": str, + "score": int, + "praw": dict, + "originalMetrics": dict, + "activation": dict, + "lineage": dict, + "found": bool, + "_raw": dict, + } + """ + # Try to find glyph by explicit ID + glyph_id = manifest.get("glyph_id") + if glyph_id: + glyph = get_super(glyph_id) + if glyph: + return _build_glyph_context(glyph, found=True) + + # Try to find by "glyphs" field in manifest + glyphs_list = manifest.get("glyphs") + if glyphs_list and isinstance(glyphs_list, list) and glyphs_list: + glyph_id = glyphs_list[0] + glyph = get_super(glyph_id) + if glyph: + return _build_glyph_context(glyph, found=True) + + # Try to find by tags + tags = manifest.get("tags", []) + if tags: + for tag in tags: + results = search_super(tag, limit=1) + if results: + return _build_glyph_context(results[0], found=True) + + # Return default context if no glyph found + return _build_glyph_context(None, found=False) + + +def _build_glyph_context(glyph: Optional[dict], found: bool) -> dict: + """Build a normalized glyph context dict. + + Args: + glyph: Glyph dict from registry, or None + found: Whether a glyph was found + + Returns: + Normalized glyph context dict + """ + if glyph and found: + return { + "id": glyph.get("id", "unknown"), + "name": glyph.get("name", "unknown"), + "category": glyph.get("category", "unknown"), + "score": glyph.get("score", 0), + "praw": glyph.get("praw", {}), + "originalMetrics": glyph.get("originalMetrics", {}), + "activation": glyph.get("activation", {}), + "lineage": glyph.get("lineage", {}), + "routing": glyph.get("routing", {}), + "storage": glyph.get("storage", {}), + "governance": glyph.get("governance", {}), + "period": glyph.get("period"), + "band": glyph.get("band"), + "found": True, + "_raw": glyph, + } + else: + return { + "id": "none", + "name": "none", + "category": "none", + "score": 0, + "praw": {}, + "originalMetrics": {}, + "activation": {}, + "lineage": {}, + "routing": {}, + "storage": {}, + "governance": {}, + "period": None, + "band": None, + "found": False, + "_raw": None, + } + + +def inject_glyph_metadata_into_lane( + lane_result: dict, + glyph_context: dict, +) -> dict: + """Inject glyph metadata into a lane result. + + Adds glyph fields to the lane result without overwriting existing fields. + Extends lane_result with: + - glyph_id + - glyph_name + - glyph_category + - glyph_frequency_signature (praw) + - glyph_activation_mode + - glyph_lineage_signature + - glyph_symbolic_anatomy (originalMetrics) + + Args: + lane_result: Lane result dict from lane processor + glyph_context: Glyph context from load_glyph_context() + + Returns: + Extended lane_result dict with glyph metadata + """ + if not glyph_context.get("found"): + # No glyph context, return unchanged + return lane_result + + # Create extended result + extended = dict(lane_result) + + # Add glyph metadata + extended["glyph_id"] = glyph_context["id"] + extended["glyph_name"] = glyph_context["name"] + extended["glyph_category"] = glyph_context["category"] + extended["glyph_score"] = glyph_context["score"] + + # Add frequency signature + praw = glyph_context.get("praw", {}) + if praw: + extended["glyph_frequency_signature"] = praw + + # Add activation mode and score + activation = glyph_context.get("activation", {}) + if activation: + extended["glyph_activation_mode"] = activation.get("currentMode", "unknown") + extended["glyph_activation_score"] = activation.get("score", 0) + + # Add lineage signature + lineage = glyph_context.get("lineage", {}) + if lineage: + extended["glyph_lineage_signature"] = lineage.get("signature", "unknown") + extended["glyph_inheritance_weight"] = lineage.get("inheritanceWeight", 0) + + # Add symbolic anatomy + metrics = glyph_context.get("originalMetrics", {}) + if metrics: + extended["glyph_symbolic_anatomy"] = metrics + + return extended + + +def compute_glyph_resonance(glyph_context: dict) -> dict: + """Compute glyph-level resonance metrics. + + Combines multiple glyph measurements into unified resonance metrics: + - activation_resonance: from activation.score + - frequency_resonance: from praw vector magnitude + - symbolic_resonance: from originalMetrics resonance field + - overall_resonance: combined normalized value + + Args: + glyph_context: Glyph context from load_glyph_context() + + Returns: + Dict with resonance metrics + """ + if not glyph_context.get("found"): + return { + "activation_resonance": 0.0, + "frequency_resonance": 0.0, + "symbolic_resonance": 0.0, + "overall_resonance": 0.0, + "glyph_found": False, + } + + # Activation resonance from activation.score (0-100 scale) + activation = glyph_context.get("activation", {}) + activation_score = activation.get("score", 0) + activation_resonance = min(1.0, activation_score / 100.0) + + # Frequency resonance from praw vector magnitude + praw = glyph_context.get("praw", {}) + praw_values = [float(praw.get(k, 0)) for k in ["P", "R", "A", "W"]] + praw_magnitude = (sum(v * v for v in praw_values) ** 0.5) / 100.0 + frequency_resonance = min(1.0, praw_magnitude) + + # Symbolic resonance from originalMetrics + metrics = glyph_context.get("originalMetrics", {}) + symbolic_resonance_val = metrics.get("resonance", 50) + symbolic_resonance = min(1.0, symbolic_resonance_val / 100.0) + + # Combined overall resonance + overall_resonance = ( + activation_resonance * 0.4 + + frequency_resonance * 0.3 + + symbolic_resonance * 0.3 + ) + + return { + "activation_resonance": round(activation_resonance, 4), + "frequency_resonance": round(frequency_resonance, 4), + "symbolic_resonance": round(symbolic_resonance, 4), + "overall_resonance": round(overall_resonance, 4), + "glyph_found": True, + "glyph_id": glyph_context["id"], + "glyph_score": glyph_context["score"], + } + + +def augment_fused_symbol_with_glyphs( + fused_symbol: dict, + glyph_context: dict, +) -> dict: + """Augment fused symbol with glyph metadata. + + Adds glyph context fields to the final fused symbol: + - glyph_id + - glyph_name + - glyph_category + - glyph_score + - glyph_activation_mode + - glyph_resonance + - glyph_lineage_signature + + Args: + fused_symbol: Fused symbol from fuse_lanes() + glyph_context: Glyph context from load_glyph_context() + + Returns: + Augmented fused_symbol dict + """ + # Create extended symbol + augmented = dict(fused_symbol) + + if glyph_context.get("found"): + # Add glyph metadata + augmented["glyph_id"] = glyph_context["id"] + augmented["glyph_name"] = glyph_context["name"] + augmented["glyph_category"] = glyph_context["category"] + augmented["glyph_score"] = glyph_context["score"] + + # Add activation mode + activation = glyph_context.get("activation", {}) + if activation: + augmented["glyph_activation_mode"] = activation.get("currentMode", "unknown") + + # Add lineage signature + lineage = glyph_context.get("lineage", {}) + if lineage: + augmented["glyph_lineage_signature"] = lineage.get("signature", "unknown") + + # Add key glyph points to key_points + if "key_points" in augmented: + glyph_key_points = [ + f"glyph:{glyph_context['id']}", + f"category:{glyph_context['category']}", + ] + augmented["key_points"] = augmented.get("key_points", []) + glyph_key_points + + else: + # Mark that no glyph was found + augmented["glyph_id"] = "none" + augmented["glyph_name"] = "none" + augmented["glyph_category"] = "none" + augmented["glyph_score"] = 0 + augmented["glyph_found"] = False + + return augmented diff --git a/gx_lain/runtime.py b/gx_lain/runtime.py index 9965e6d..a3c3007 100644 --- a/gx_lain/runtime.py +++ b/gx_lain/runtime.py @@ -376,7 +376,7 @@ def execute_with_lain(envelope: dict) -> dict: """Execute ExecutionEnvelope through LAIN cognition engine. Real implementation: iterate through lanes, process each via lane processors, - fuse results, and return full ExecutionResult. + fuse results, integrate glyph metadata, and return full ExecutionResult. Contract: - Does not mutate input envelope @@ -390,6 +390,12 @@ def execute_with_lain(envelope: dict) -> dict: ExecutionResult dict with cognition_trace, fused_symbol, output_text, diagnostics """ from .lane_processors import process_lane + from .lain_glyph_bridge import ( + load_glyph_context, + inject_glyph_metadata_into_lane, + compute_glyph_resonance, + augment_fused_symbol_with_glyphs, + ) start_time = time.time() @@ -419,8 +425,24 @@ def execute_with_lain(envelope: dict) -> dict: "note": "Loaded ExecutionEnvelope into LAIN cognition engine.", }) + # Step 1: Load glyph context + glyph_context = load_glyph_context(manifest, context) + cognition_trace.append({ + "step": 1, + "lane": -1, + "segment_id": None, + "operation": "glyph_context_loaded", + "input": {"glyph_found": glyph_context.get("found", False)}, + "output": { + "glyph_id": glyph_context.get("id"), + "glyph_name": glyph_context.get("name"), + "glyph_score": glyph_context.get("score"), + }, + "note": f"Loaded glyph context: {glyph_context.get('name')}", + }) + # Process each lane - step_num = 1 + step_num = 2 for lane_id in sorted(lanes.keys()): lane_start = time.time() lane_segments = lanes.get(lane_id, []) @@ -433,6 +455,10 @@ def execute_with_lain(envelope: dict) -> dict: context, manifest, ) + + # Inject glyph metadata into lane result + lane_result = inject_glyph_metadata_into_lane(lane_result, glyph_context) + lane_results[lane_id] = lane_result # Record timing @@ -487,9 +513,15 @@ def execute_with_lain(envelope: dict) -> dict: # Fuse lane results fused_symbol = fuse_lanes(lane_results) - # Compute resonance + # Augment fused symbol with glyph metadata + fused_symbol = augment_fused_symbol_with_glyphs(fused_symbol, glyph_context) + + # Compute lane resonance resonance = compute_resonance(lane_results, context) + # Compute glyph resonance + glyph_resonance = compute_glyph_resonance(glyph_context) + # Render output text output_text = render_output_text(fused_symbol, context) @@ -500,6 +532,7 @@ def execute_with_lain(envelope: dict) -> dict: "lane_timings": lane_timings, "errors": errors, "resonance": resonance, + "glyph_resonance": glyph_resonance, "interface_version": INTERFACE_VERSION, "elapsed": elapsed, } diff --git a/tests/test_lain_glyph_bridge.py b/tests/test_lain_glyph_bridge.py new file mode 100644 index 0000000..0735df4 --- /dev/null +++ b/tests/test_lain_glyph_bridge.py @@ -0,0 +1,369 @@ +#!/usr/bin/env python3 +"""Tests for LAIN ↔ Supercharged Glyph Bridge + +Tests verify: +- load_glyph_context loads correct glyphs from registry +- inject_glyph_metadata_into_lane adds glyph fields +- compute_glyph_resonance returns numeric values +- augment_fused_symbol_with_glyphs adds glyph metadata +- execute_with_lain integrates glyph bridge into cognition +- Glyph metadata appears in lane results, fused symbol, and diagnostics +""" + +import sys +from pathlib import Path + +sys.path.insert(0, str(Path.cwd())) + +from gx_lain.lain_glyph_bridge import ( + load_glyph_context, + inject_glyph_metadata_into_lane, + compute_glyph_resonance, + augment_fused_symbol_with_glyphs, +) +from gx_lain.runtime import execute_gx_path + + +def test_load_glyph_context_no_glyph(): + """Test loading glyph context when no glyph is specified.""" + manifest = { + "source_file": "test.py", + "version": "1.0.0", + } + context = {} + + glyph_context = load_glyph_context(manifest, context) + + if not isinstance(glyph_context, dict): + print("FAIL: glyph_context is not a dict") + return False + + if glyph_context["found"] != False: + print("FAIL: Should return found=False when no glyph specified") + return False + + if glyph_context["id"] != "none": + print("FAIL: Should return id='none' when no glyph found") + return False + + print("PASS: load_glyph_context handles missing glyph") + return True + + +def test_load_glyph_context_by_id(): + """Test loading glyph context by explicit glyph_id.""" + manifest = { + "source_file": "test.py", + "glyph_id": "G001", + } + context = {} + + glyph_context = load_glyph_context(manifest, context) + + if glyph_context["found"] != True: + print("FAIL: Should find glyph G001") + return False + + if glyph_context["id"] != "G001": + print(f"FAIL: Expected G001, got {glyph_context['id']}") + return False + + if glyph_context["name"] == "none": + print("FAIL: Glyph name should not be 'none'") + return False + + if glyph_context["score"] <= 0: + print("FAIL: Glyph score should be positive") + return False + + print(f"PASS: load_glyph_context found G001 ({glyph_context['name']})") + return True + + +def test_load_glyph_context_fields(): + """Test that glyph context includes all required fields.""" + manifest = {"glyph_id": "G001"} + context = {} + + glyph_context = load_glyph_context(manifest, context) + + required_fields = [ + "id", "name", "category", "score", "praw", "originalMetrics", + "activation", "lineage", "found" + ] + + for field in required_fields: + if field not in glyph_context: + print(f"FAIL: Missing field: {field}") + return False + + print("PASS: glyph_context includes all required fields") + return True + + +def test_inject_glyph_metadata_into_lane(): + """Test injecting glyph metadata into lane result.""" + lane_result = { + "summary": "Test summary", + "key_points": ["point1"], + "constraints": [], + "open_questions": [], + } + + manifest = {"glyph_id": "G001"} + glyph_context = load_glyph_context(manifest, {}) + + augmented = inject_glyph_metadata_into_lane(lane_result, glyph_context) + + # Check that original fields are preserved + if augmented["summary"] != "Test summary": + print("FAIL: Original summary was overwritten") + return False + + # Check that glyph fields were added + if "glyph_id" not in augmented: + print("FAIL: glyph_id not added") + return False + + if augmented["glyph_id"] != "G001": + print(f"FAIL: glyph_id mismatch") + return False + + if "glyph_name" not in augmented: + print("FAIL: glyph_name not added") + return False + + if "glyph_frequency_signature" not in augmented: + print("FAIL: glyph_frequency_signature not added") + return False + + print("PASS: inject_glyph_metadata_into_lane works correctly") + return True + + +def test_inject_no_glyph(): + """Test inject when no glyph is found.""" + lane_result = { + "summary": "Test", + "key_points": [], + "constraints": [], + "open_questions": [], + } + + glyph_context = load_glyph_context({}, {}) # No glyph + + augmented = inject_glyph_metadata_into_lane(lane_result, glyph_context) + + # Should return unchanged + if augmented != lane_result: + print("FAIL: Should return unchanged when no glyph") + return False + + print("PASS: inject handles missing glyph correctly") + return True + + +def test_compute_glyph_resonance_no_glyph(): + """Test computing resonance when no glyph is found.""" + glyph_context = load_glyph_context({}, {}) + + resonance = compute_glyph_resonance(glyph_context) + + if not isinstance(resonance, dict): + print("FAIL: resonance is not a dict") + return False + + if resonance["glyph_found"] != False: + print("FAIL: Should indicate glyph not found") + return False + + if resonance["overall_resonance"] != 0.0: + print("FAIL: Should return 0.0 when no glyph") + return False + + print("PASS: compute_glyph_resonance handles missing glyph") + return True + + +def test_compute_glyph_resonance_with_glyph(): + """Test computing resonance with valid glyph.""" + glyph_context = load_glyph_context({"glyph_id": "G001"}, {}) + + resonance = compute_glyph_resonance(glyph_context) + + if not isinstance(resonance, dict): + print("FAIL: resonance is not a dict") + return False + + if resonance["glyph_found"] != True: + print("FAIL: Should indicate glyph found") + return False + + # Check resonance metrics are numeric + for metric in [ + "activation_resonance", + "frequency_resonance", + "symbolic_resonance", + "overall_resonance", + ]: + if metric not in resonance: + print(f"FAIL: Missing metric {metric}") + return False + + if not isinstance(resonance[metric], float): + print(f"FAIL: {metric} is not a float") + return False + + if not (0.0 <= resonance[metric] <= 1.0): + print(f"FAIL: {metric} out of range [0,1]") + return False + + if resonance["glyph_id"] != "G001": + print("FAIL: glyph_id mismatch") + return False + + print(f"PASS: compute_glyph_resonance returned valid metrics") + return True + + +def test_augment_fused_symbol_no_glyph(): + """Test augmenting fused symbol when no glyph.""" + fused_symbol = { + "summary": "Fused summary", + "key_points": ["p1", "p2"], + "constraints": [], + "open_questions": [], + } + + glyph_context = load_glyph_context({}, {}) + + augmented = augment_fused_symbol_with_glyphs(fused_symbol, glyph_context) + + if augmented["glyph_id"] != "none": + print("FAIL: Should set glyph_id to 'none'") + return False + + if augmented["glyph_found"] != False: + print("FAIL: Should mark glyph_found as False") + return False + + print("PASS: augment_fused_symbol handles missing glyph") + return True + + +def test_augment_fused_symbol_with_glyph(): + """Test augmenting fused symbol with valid glyph.""" + fused_symbol = { + "summary": "Fused summary", + "key_points": ["p1", "p2"], + "constraints": [], + "open_questions": [], + } + + glyph_context = load_glyph_context({"glyph_id": "G001"}, {}) + + augmented = augment_fused_symbol_with_glyphs(fused_symbol, glyph_context) + + # Check original fields preserved + if augmented["summary"] != "Fused summary": + print("FAIL: Original summary overwritten") + return False + + # Check glyph fields added + glyph_fields = [ + "glyph_id", "glyph_name", "glyph_category", "glyph_score" + ] + + for field in glyph_fields: + if field not in augmented: + print(f"FAIL: Missing field {field}") + return False + + if augmented["glyph_id"] != "G001": + print("FAIL: glyph_id mismatch") + return False + + # Check key_points were extended + if not any("glyph:" in str(kp) for kp in augmented["key_points"]): + print("FAIL: Glyph key points not added") + return False + + print("PASS: augment_fused_symbol adds glyph metadata correctly") + return True + + +def test_execute_with_lain_includes_glyph(): + """Test that execute_with_lain includes glyph metadata in result.""" + # Execute a .gx file and verify glyph integration + try: + result = execute_gx_path("/home/dave/sample_code.gx") + except Exception as e: + print(f"FAIL: execute_gx_path failed: {e}") + return False + + # Check cognition_trace includes glyph loading + glyph_load_step = None + for step in result.get("cognition_trace", []): + if step.get("operation") == "glyph_context_loaded": + glyph_load_step = step + break + + if glyph_load_step is None: + print("FAIL: glyph_context_loaded not in trace") + return False + + # Check fused_symbol has glyph fields + fused = result.get("fused_symbol", {}) + if "glyph_id" not in fused: + print("FAIL: glyph_id not in fused_symbol") + return False + + # Check diagnostics has glyph resonance + diags = result.get("diagnostics", {}) + if "glyph_resonance" not in diags: + print("FAIL: glyph_resonance not in diagnostics") + return False + + print("PASS: execute_with_lain integrates glyph bridge") + return True + + +def main_test(): + print("[TEST SUITE] test_lain_glyph_bridge.py") + print() + + tests = [ + ("Load glyph context (no glyph)", test_load_glyph_context_no_glyph), + ("Load glyph context (by ID)", test_load_glyph_context_by_id), + ("Glyph context fields", test_load_glyph_context_fields), + ("Inject glyph metadata", test_inject_glyph_metadata_into_lane), + ("Inject without glyph", test_inject_no_glyph), + ("Compute resonance (no glyph)", test_compute_glyph_resonance_no_glyph), + ("Compute resonance (with glyph)", test_compute_glyph_resonance_with_glyph), + ("Augment symbol (no glyph)", test_augment_fused_symbol_no_glyph), + ("Augment symbol (with glyph)", test_augment_fused_symbol_with_glyph), + ("Execute with glyph integration", test_execute_with_lain_includes_glyph), + ] + + passed = 0 + failed = 0 + + for name, test_func in tests: + print(f"Running: {name}...", end=" ") + try: + if test_func(): + passed += 1 + else: + failed += 1 + except Exception as e: + print(f"FAIL: {e}") + failed += 1 + + print() + print(f"Results: {passed} passed, {failed} failed") + + return 0 if failed == 0 else 1 + + +if __name__ == "__main__": + sys.exit(main_test())