Implement LAIN ↔ Supercharged Glyph Bridge
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).
This commit is contained in:
@@ -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
|
||||||
+36
-3
@@ -376,7 +376,7 @@ def execute_with_lain(envelope: dict) -> dict:
|
|||||||
"""Execute ExecutionEnvelope through LAIN cognition engine.
|
"""Execute ExecutionEnvelope through LAIN cognition engine.
|
||||||
|
|
||||||
Real implementation: iterate through lanes, process each via lane processors,
|
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:
|
Contract:
|
||||||
- Does not mutate input envelope
|
- 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
|
ExecutionResult dict with cognition_trace, fused_symbol, output_text, diagnostics
|
||||||
"""
|
"""
|
||||||
from .lane_processors import process_lane
|
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()
|
start_time = time.time()
|
||||||
|
|
||||||
@@ -419,8 +425,24 @@ def execute_with_lain(envelope: dict) -> dict:
|
|||||||
"note": "Loaded ExecutionEnvelope into LAIN cognition engine.",
|
"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
|
# Process each lane
|
||||||
step_num = 1
|
step_num = 2
|
||||||
for lane_id in sorted(lanes.keys()):
|
for lane_id in sorted(lanes.keys()):
|
||||||
lane_start = time.time()
|
lane_start = time.time()
|
||||||
lane_segments = lanes.get(lane_id, [])
|
lane_segments = lanes.get(lane_id, [])
|
||||||
@@ -433,6 +455,10 @@ def execute_with_lain(envelope: dict) -> dict:
|
|||||||
context,
|
context,
|
||||||
manifest,
|
manifest,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Inject glyph metadata into lane result
|
||||||
|
lane_result = inject_glyph_metadata_into_lane(lane_result, glyph_context)
|
||||||
|
|
||||||
lane_results[lane_id] = lane_result
|
lane_results[lane_id] = lane_result
|
||||||
|
|
||||||
# Record timing
|
# Record timing
|
||||||
@@ -487,9 +513,15 @@ def execute_with_lain(envelope: dict) -> dict:
|
|||||||
# Fuse lane results
|
# Fuse lane results
|
||||||
fused_symbol = fuse_lanes(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)
|
resonance = compute_resonance(lane_results, context)
|
||||||
|
|
||||||
|
# Compute glyph resonance
|
||||||
|
glyph_resonance = compute_glyph_resonance(glyph_context)
|
||||||
|
|
||||||
# Render output text
|
# Render output text
|
||||||
output_text = render_output_text(fused_symbol, context)
|
output_text = render_output_text(fused_symbol, context)
|
||||||
|
|
||||||
@@ -500,6 +532,7 @@ def execute_with_lain(envelope: dict) -> dict:
|
|||||||
"lane_timings": lane_timings,
|
"lane_timings": lane_timings,
|
||||||
"errors": errors,
|
"errors": errors,
|
||||||
"resonance": resonance,
|
"resonance": resonance,
|
||||||
|
"glyph_resonance": glyph_resonance,
|
||||||
"interface_version": INTERFACE_VERSION,
|
"interface_version": INTERFACE_VERSION,
|
||||||
"elapsed": elapsed,
|
"elapsed": elapsed,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())
|
||||||
Reference in New Issue
Block a user