# GlyphOS Event System **Status**: ✅ Complete and Tested **Version**: 1.0.0 **Date**: May 20, 2026 ## Overview The **GlyphOS Event System** is a lightweight, in-process event bus that captures symbolic events from the Cognitive Kernel and LAIN cognition engine. It enables: - **Event-driven architecture** for GlyphOS applications - **Cognition monitoring** through first-class events - **Glyph activation tracking** via resonance changes - **Clean separation** of concerns (publish-subscribe pattern) ## Event Types The system defines five core event types: ```python EventType = Literal[ "cognition.started", # Cognition execution starting "cognition.completed", # Cognition execution finished "glyph.activation.changed", # Glyph activation mode changed "glyph.resonance.updated", # Glyph resonance metrics updated "kernel.warmup.completed", # Kernel initialization complete ] ``` ## Architecture ``` Application Layer ↓ on() / emit() ↓ ┌─────────────────────────────────────────┐ │ Event Bus (Singleton) │ │ ├─ Subscriptions (type → handlers) │ │ ├─ History (all published events) │ │ └─ Publish mechanism │ └─────────────────────────────────────────┘ ↑ Cognitive Kernel ├─ emit("kernel.warmup.completed") ├─ emit("cognition.started") ├─ emit("cognition.completed") └─ emit("glyph.resonance.updated") ``` ## Module: `glyphos/events.py` ### EventBus Class Main event bus implementation. #### Constructor ```python bus = EventBus() ``` Creates a new EventBus with no subscribers or history. #### Methods ##### subscribe() Register a handler for an event type. ```python def subscribe(self, event_type: EventType, handler: Callable[[Event], None]) -> None ``` **Parameters:** - `event_type`: Event type to listen for - `handler`: Callable that takes an Event and returns None **Behavior:** - Registers handler for this event type - Multiple handlers can subscribe to the same type - Handlers called in registration order - Handler registration is idempotent (no duplicate registrations) **Example:** ```python def on_warmup(event: Event): print(f"Warmed up at {event['timestamp']}") bus.subscribe("kernel.warmup.completed", on_warmup) ``` ##### unsubscribe() Remove a handler from an event type. ```python def unsubscribe(self, event_type: EventType, handler: Callable[[Event], None]) -> None ``` **Parameters:** - `event_type`: Event type to unsubscribe from - `handler`: The handler to remove **Behavior:** - Silently succeeds if handler not found - Does not raise exceptions ##### publish() Create an event, append to history, and invoke handlers. ```python def publish(self, event_type: EventType, payload: Dict[str, Any]) -> Event ``` **Parameters:** - `event_type`: Type of event - `payload`: Event data (arbitrary dict) **Returns:** ```python { "type": event_type, "timestamp": float, # time.time() "payload": payload } ``` **Behavior:** - Attaches current timestamp - Appends to event history - Invokes all registered handlers in order - Catches and silently suppresses handler exceptions - Returns the published Event ##### get_history() Retrieve recent events from history. ```python def get_history(self, event_type: Optional[EventType] = None, limit: int = 100) -> List[Event] ``` **Parameters:** - `event_type`: If provided, filter to only this type - `limit`: Maximum number of events (default 100) **Returns:** - List of Event dicts (newest last) - Empty list if no history **Examples:** ```python # All recent events (up to 100) all_events = bus.get_history() # All "cognition.completed" events cognition_events = bus.get_history("cognition.completed") # Last 10 events recent = bus.get_history(limit=10) # Last 5 glyph resonance events last_glyphs = bus.get_history("glyph.resonance.updated", limit=5) ``` ##### clear_history() Clear all stored events. ```python def clear_history(self) -> None ``` **Use case**: Reset history for clean testing or memory management. ### Functional API Module-level convenience functions. #### get_event_bus() Get or create the singleton event bus. ```python def get_event_bus() -> EventBus ``` **Returns:** Singleton EventBus instance **Behavior:** - Creates new EventBus on first call - Returns same instance on subsequent calls - No initialization required **Example:** ```python bus = get_event_bus() events = bus.get_history() ``` #### emit() Publish an event on the global bus. ```python def emit(event_type: EventType, payload: Dict[str, Any]) -> Event ``` **Parameters:** - `event_type`: Type of event - `payload`: Event payload **Returns:** Published Event **Equivalent to:** ```python get_event_bus().publish(event_type, payload) ``` **Example:** ```python emit("kernel.warmup.completed", { "glyph_stats": stats, "startup_time": time.time() }) ``` #### on() Subscribe to an event on the global bus. ```python def on(event_type: EventType, handler: Callable[[Event], None]) -> None ``` **Parameters:** - `event_type`: Event type to listen for - `handler`: Handler callback **Equivalent to:** ```python get_event_bus().subscribe(event_type, handler) ``` **Example:** ```python def handle_cognition_done(event: Event): print(f"Cognition completed in {event['payload']['elapsed']}s") on("cognition.completed", handle_cognition_done) ``` ## Events from Cognitive Kernel The Cognitive Kernel emits events at key points in the execution pipeline. ### kernel.warmup.completed Emitted when the kernel finishes warmup. **When:** After `CognitiveKernel.warmup()` completes **Payload:** ```python { "glyph_stats": { "total_glyphs": 600, "categories": [...], "fields_present": [...], "sample_ids": [...], "loaded": True, "load_path": "/path/to/glyphs.json", }, "startup_time": float, # time.time() } ``` **Use case:** Monitor kernel initialization, verify glyph registry loaded. ### cognition.started Emitted at the start of GX execution. **When:** At the beginning of `CognitiveKernel.execute_gx()` **Payload:** ```python { "gx_path": str, # Path to .gx file "mode": str, # "analyze", "debug", etc. "context": Optional[dict], # User-provided context } ``` **Use case:** Track when cognition starts, log execution attempts. ### cognition.completed Emitted after GX execution completes. **When:** After `execute_gx_path()` finishes and result is cached **Payload:** ```python { "gx_path": str, # Path to .gx file "mode": str, # Execution mode "elapsed": float, # Seconds (from diagnostics) "summary": str, # fused_symbol summary text "glyph_resonance": dict, # Full resonance dict (if present) } ``` **Use case:** Track execution performance, analyze cognition results. ### glyph.resonance.updated Emitted when glyph resonance metrics are available. **When:** During `execute_gx()` if glyph_resonance present in diagnostics **Condition:** Only emitted if `glyph_resonance["glyph_found"] == True` **Payload:** ```python { "glyph_id": str, # "G001", "G042", etc. "glyph_score": int, # Glyph strength metric "glyph_resonance": { # Full resonance data "activation_resonance": float, # 0.0-1.0 "frequency_resonance": float, # 0.0-1.0 "symbolic_resonance": float, # 0.0-1.0 "overall_resonance": float, # 0.0-1.0 "glyph_found": bool, "glyph_id": str, "glyph_score": int, } } ``` **Use case:** Track which glyphs are being used, monitor resonance profiles. ## Usage Examples ### Basic Event Subscription ```python from glyphos.events import on, emit # Subscribe to an event def on_cognition_done(event): elapsed = event["payload"]["elapsed"] print(f"Execution took {elapsed}s") on("cognition.completed", on_cognition_done) # Later, when cognition runs, handler is called automatically ``` ### Monitoring Kernel State ```python from glyphos.events import get_event_bus bus = get_event_bus() # Get all events since startup history = bus.get_history() print(f"Total events: {len(history)}") # Get only cognition events cognition_events = bus.get_history("cognition.completed") for event in cognition_events: print(f"Executed: {event['payload']['gx_path']}") ``` ### Event-Driven Cognition App ```python from glyphos.events import on, emit from glyphos.cognitive_kernel import run_gx # Set up listeners before running cognition execution_log = [] on("cognition.started", lambda e: execution_log.append({ "type": "start", "file": e["payload"]["gx_path"], "time": e["timestamp"] })) on("cognition.completed", lambda e: execution_log.append({ "type": "done", "elapsed": e["payload"]["elapsed"], "time": e["timestamp"] })) on("glyph.resonance.updated", lambda e: execution_log.append({ "type": "glyph", "id": e["payload"]["glyph_id"], "resonance": e["payload"]["glyph_resonance"]["overall_resonance"] })) # Run cognition result = run_gx("source.gx") # Inspect log for entry in execution_log: print(entry) ``` ### Testing with Events ```python from glyphos.events import get_event_bus, on from glyphos.cognitive_kernel import CognitiveKernel # Test fixture: collect emitted events events = [] bus = get_event_bus() def collector(event): events.append(event) bus.subscribe("kernel.warmup.completed", collector) # Run test kernel = CognitiveKernel() kernel.warmup() # Verify assert len(events) == 1 assert events[0]["type"] == "kernel.warmup.completed" assert events[0]["payload"]["glyph_stats"]["total_glyphs"] == 600 ``` ## Testing ### Test Coverage - **16 tests** in `tests/test_events.py` - **100% pass rate** ### Test Categories 1. **EventBus Core** (9 tests) - Initialization - Subscribe/unsubscribe - Publish mechanism - History tracking and filtering - History clearing - Handler error handling 2. **Functional API** (3 tests) - Singleton pattern - emit() and on() functions - Global bus management 3. **Kernel Integration** (4 tests) - kernel.warmup.completed emission - cognition.started emission - cognition.completed emission - glyph.resonance.updated emission ### Running Tests ```bash # Run event system tests python3 tests/test_events.py # Run all tests (52 total) python3 integration_tests/run_all_tests.py ``` ## Design Principles 1. **Lightweight**: No external dependencies, minimal code 2. **In-Process**: All events stay in application memory 3. **Fire-and-Forget**: Handlers don't need to return 4. **Error Resilient**: Handler exceptions don't cascade 5. **Observable**: Full event history available for inspection 6. **Singleton**: One global bus for simplicity ## Performance ### Timing | Operation | Duration | |-----------|----------| | emit() | <1ms | | subscribe() | <1ms | | publish() + handler call | <1ms | | get_history() | <1ms | ### Memory | Component | Usage | |-----------|-------| | Empty EventBus | ~100 bytes | | Per event | ~200-500 bytes | | 100 events in history | ~50KB | ## Constraints ✅ No external dependencies ✅ In-process only (no network/persistence) ✅ Type hints throughout ✅ Graceful error handling ✅ No global state beyond singleton ## Integration Points ### With Cognitive Kernel - Kernel emits 4-5 events per execution - Events contain result metadata - Handler can introspect execution details ### With External Systems (Future) - REST API wrapper (emit events → HTTP) - Message queue bridge (emit events → Kafka/RabbitMQ) - Logging integration (events → structured logs) - Metrics export (events → Prometheus/CloudWatch) ## API Summary | Function | Purpose | |----------|---------| | `get_event_bus()` | Singleton instance | | `emit(type, payload)` | Publish event | | `on(type, handler)` | Subscribe to events | | `bus.publish(...)` | Direct publish | | `bus.subscribe(...)` | Direct subscribe | | `bus.unsubscribe(...)` | Remove handler | | `bus.get_history(...)` | Query event history | | `bus.clear_history()` | Reset history | ## Files - **Implementation**: `glyphos/events.py` (175 lines) - **Tests**: `tests/test_events.py` (520 lines) - **Modified**: `glyphos/cognitive_kernel.py` (event emissions added) ## Status Summary ✅ **Implementation**: Complete ✅ **Testing**: 16/16 tests passing ✅ **Integration**: All 52 tests passing (36 + 16 new) ✅ **Documentation**: Complete ✅ **Backwards Compatibility**: Verified **Ready for production deployment.** ## Future Enhancements 1. **Event Filtering**: Advanced queries on history 2. **Async Handlers**: Non-blocking event processing 3. **Event Replay**: Replay historical events for debugging 4. **Custom Events**: Allow applications to emit custom events 5. **Event Logging**: Write events to persistent log 6. **Metrics**: Built-in event rate/latency metrics 7. **Event Schema**: Validation of event payloads --- **The GlyphOS Event System is now live.** 🚀