#!/usr/bin/env python3
"""
Genesis Kernel
===============
Unified orchestration layer for the Genesis Protocol.

This is the main entry point that integrates all Genesis components:
- Blackboard: Shared memory and task coordination
- Memory Cortex: Multi-tier memory system
- Heartbeat: Cognitive pulse cycle
- Tool Router: Intent-based tool clustering
- Circadian Scheduler: Temporal optimization
- Reflexion: Act→Observe→Critique→Refine loop
- Meta Agent: Domain expert spawning

The Kernel provides:
1. Unified initialization of all components
2. Event-driven coordination between systems
3. Prompt injection compilation (axioms, context, tools)
4. Session lifecycle management
5. HANDOFF.md generation for continuity

Usage:
    from genesis_kernel import GenesisKernel
    
    kernel = GenesisKernel()
    kernel.start()
    
    # Process a query
    response = kernel.process("search for recent AI news")
    
    # Get compiled context for injection
    context = kernel.compile_context()
"""

import json
import time
import threading
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Optional, Any, Callable
from dataclasses import dataclass, field
from enum import Enum
import traceback

# Genesis component imports
try:
    from blackboard import Blackboard, EntryType, TaskStatus
except ImportError:
    from core.blackboard import Blackboard, EntryType, TaskStatus

try:
    from genesis_memory_cortex import MemoryCortex, MemoryTier
except ImportError:
    from core.genesis_memory_cortex import MemoryCortex, MemoryTier

try:
    from genesis_heartbeat import GenesisHeartbeat, AxiomGenerator, EnhancedSurpriseSystem
except ImportError:
    from core.genesis_heartbeat import GenesisHeartbeat, AxiomGenerator, EnhancedSurpriseSystem

try:
    from tool_router import ToolRouter, ToolIntent, RoutingResult
except ImportError:
    from core.tool_router import ToolRouter, ToolIntent, RoutingResult

try:
    from circadian_scheduler import CircadianScheduler, TaskType, ActivityLevel
except ImportError:
    from core.circadian_scheduler import CircadianScheduler, TaskType, ActivityLevel

try:
    from meta_agent import MetaAgent
except ImportError:
    from core.meta_agent import MetaAgent

try:
    from rlm_bridge import RLMBridge
    from self_learning import SelfLearningEngine
    from traversal import RLMTraversal
    from decision_tracker import DecisionTracker
except ImportError:
    import sys
    sys.path.append("E:/genesis-system/rlm")
    try:
        from core.rlm_bridge import RLMBridge
        from core.self_learning import SelfLearningEngine
        from core.traversal import RLMTraversal
        from core.decision_tracker import DecisionTracker
    except ImportError:
        from rlm_bridge import RLMBridge
        from self_learning import SelfLearningEngine
        from traversal import RLMTraversal
        from decision_tracker import DecisionTracker


class KernelState(Enum):
    """Kernel operational states."""
    INITIALIZING = "initializing"
    READY = "ready"
    PROCESSING = "processing"
    HEARTBEAT = "heartbeat"
    CONSOLIDATING = "consolidating"
    SHUTDOWN = "shutdown"
    ERROR = "error"


@dataclass
class SessionContext:
    """Context for a single interaction session."""
    session_id: str
    started_at: datetime
    query_count: int = 0
    last_query: Optional[str] = None
    detected_intents: List[str] = field(default_factory=list)
    active_domains: List[str] = field(default_factory=list)
    surprises: List[Dict] = field(default_factory=list)
    axioms_generated: int = 0


@dataclass
class CompiledContext:
    """Compiled context for prompt injection."""
    axioms: str                    # Compressed learnings
    relevant_memories: str         # Context from memory
    tool_guidance: str             # Filtered tools
    temporal_context: str          # Time-aware guidance
    domain_expertise: str          # Loaded expert knowledge
    session_summary: str           # Current session state
    verification_protocol: str = ""  # MANDATORY verification requirements

    def to_system_prompt(self) -> str:
        """Format as system prompt injection."""
        sections = []

        # VERIFICATION PROTOCOL ALWAYS FIRST (MANDATORY)
        if self.verification_protocol:
            sections.append(self.verification_protocol)

        if self.axioms:
            sections.append(f"## Learned Axioms\n{self.axioms}")

        if self.relevant_memories:
            sections.append(f"## Relevant Context\n{self.relevant_memories}")

        if self.tool_guidance:
            sections.append(f"## Available Tools\n{self.tool_guidance}")

        if self.temporal_context:
            sections.append(f"## Temporal Context\n{self.temporal_context}")

        if self.domain_expertise:
            sections.append(f"## Domain Expertise\n{self.domain_expertise}")

        return "\n\n".join(sections)


class GenesisKernel:
    """
    Central orchestration layer for Genesis Protocol.
    
    Coordinates all Genesis components into a unified cognitive system.
    """
    
    VERSION = "0.2.0"
    
    def __init__(self, 
                 data_dir: str = "E:/genesis-system/data",
                 config_path: str = None,
                 auto_start_heartbeat: bool = False):
        """
        Initialize the Genesis Kernel.
        
        Args:
            data_dir: Base directory for all Genesis data
            config_path: Optional path to kernel config file
            auto_start_heartbeat: Start heartbeat daemon on init
        """
        self.state = KernelState.INITIALIZING
        self.data_dir = Path(data_dir)
        self.data_dir.mkdir(parents=True, exist_ok=True)
        
        self.state_file = self.data_dir / "kernel_state.json"
        self.handoff_file = Path("E:/genesis-system/HANDOFF.md")
        
        # Initialize components
        self._init_components()
        
        # Session tracking
        self.current_session: Optional[SessionContext] = None
        self.session_history: List[Dict] = []
        
        # Event handlers
        self.event_handlers: Dict[str, List[Callable]] = {}
        
        # Load state
        self._load_state()
        
        # Start heartbeat if requested
        if auto_start_heartbeat:
            self.heartbeat.start_daemon()
        
        self.state = KernelState.READY
        self._emit_event("kernel_ready", {"version": self.VERSION})
    
    def _init_components(self):
        """Initialize all Genesis components."""
        print("Initializing Genesis Kernel components...")
        
        # Core blackboard
        self.blackboard = Blackboard(
            persist_path=str(self.data_dir / "blackboard_state.json"),
            use_redis=True,
            use_postgres=True
        )
        print("  ✓ Blackboard")
        
        # Memory system
        self.cortex = MemoryCortex(
            enable_vectors=True  # Enable vector backends if available
        )
        print("  ✓ Memory Cortex")
        
        # Surprise detection
        self.surprise = EnhancedSurpriseSystem(
            history_path=str(self.data_dir / "surprise_history.json")
        )
        print("  ✓ Surprise System")

        # Axiom generation
        self.axiom_gen = AxiomGenerator(
            axiom_path=str(self.data_dir / "axioms.json")
        )
        print("  ✓ Axiom Generator")

        # Temporal scheduling
        self.scheduler = CircadianScheduler(data_dir=str(self.data_dir))
        print("  ✓ Circadian Scheduler")

        # Heartbeat orchestration (self-initializes its own components)
        self.heartbeat = GenesisHeartbeat(
            heartbeat_interval=600,
            scheduler=self.scheduler
        )
        print("  ✓ Heartbeat")

        # Tool routing
        self.tool_router = ToolRouter()
        print("  ✓ Tool Router")
        
        # Meta agent for expertise
        self.meta_agent = MetaAgent(
            base_path=str(Path("E:/genesis-system/expertise"))
        )
        print("  ✓ Meta Agent")

        # RLM Bridge
        self.rlm = RLMBridge(blackboard=self.blackboard)
        print("  ✓ RLM Bridge")

        # Self Learning Engine (Phase 3)
        self.learner = SelfLearningEngine(self)
        print("  ✓ Self Learning Engine")

        # Decision Tracker (Phase 3)
        self.tracker = DecisionTracker(self.rlm)
        print("  ✓ Decision Tracker")

        # RLM Traversal (Phase 4)
        self.traversal = RLMTraversal(self.rlm)
        print("  ✓ RLM Traversal Layer")

        # AIVA Bridge (QwenLong 30.5B MoE reasoning engine)
        try:
            from aiva_bridge import AIVABridgeSync
            self.aiva = AIVABridgeSync()
            print("  ✓ AIVA Bridge (Elestio)")
        except ImportError as e:
            print(f"  ⚠ AIVA Bridge unavailable: {e}")
            self.aiva = None

        print("All components initialized.")
    
    def _load_state(self):
        """Load persisted kernel state."""
        if self.state_file.exists():
            try:
                with open(self.state_file) as f:
                    data = json.load(f)
                    self.session_history = data.get("session_history", [])[-50:]
            except Exception as e:
                print(f"Error loading kernel state: {e}")
    
    def _save_state(self):
        """Persist kernel state."""
        data = {
            "version": self.VERSION,
            "last_saved": datetime.now().isoformat(),
            "state": self.state.value,
            "session_history": self.session_history[-50:],
            "stats": self.get_stats()
        }
        
        with open(self.state_file, 'w') as f:
            json.dump(data, f, indent=2)
    
    def _emit_event(self, event_type: str, data: Dict = None):
        """Emit an event to registered handlers."""
        handlers = self.event_handlers.get(event_type, [])
        for handler in handlers:
            try:
                handler(event_type, data or {})
            except Exception as e:
                print(f"Event handler error: {e}")
    
    def on_event(self, event_type: str, handler: Callable):
        """Register an event handler."""
        if event_type not in self.event_handlers:
            self.event_handlers[event_type] = []
        self.event_handlers[event_type].append(handler)
    
    # ==================== Session Management ====================
    
    def start_session(self, session_id: str = None) -> SessionContext:
        """Start a new interaction session."""
        if session_id is None:
            session_id = f"session_{int(time.time())}"
        
        self.current_session = SessionContext(
            session_id=session_id,
            started_at=datetime.now()
        )
        
        # Record interaction for circadian tracking
        self.scheduler.record_interaction()
        
        self._emit_event("session_started", {
            "session_id": session_id,
            "activity_level": self.scheduler.get_current_activity_level().value
        })

        # PHASE 2: Contextual Retrieval
        print(f"📚 [RLM] Querying context for session: {session_id}")
        context_nodes = self.rlm.query("current status")
        if context_nodes:
            print(f"   Found {len(context_nodes)} relevant context nodes.")
        
        return self.current_session
    
    def end_session(self):
        """End the current session."""
        if self.current_session:
            # Save session summary
            summary = {
                "session_id": self.current_session.session_id,
                "started": self.current_session.started_at.isoformat(),
                "ended": datetime.now().isoformat(),
                "query_count": self.current_session.query_count,
                "intents": list(set(self.current_session.detected_intents)),
                "domains": list(set(self.current_session.active_domains)),
                "surprises": len(self.current_session.surprises),
                "axioms_generated": self.current_session.axioms_generated
            }
            self.session_history.append(summary)
            
            self._emit_event("session_ended", summary)
            self._save_state()
            
            # PHASE 3: Autonomous Synthesis
            print("🧠 [RLM] Extracting Lessons from session...")
            
            # Use the dedicated learner
            self.learner.synthesize_session(summary)

            self.current_session = None
    
    # ==================== Query Processing ====================
    
    def process(self, query: str, context: Dict = None) -> Dict:
        """
        Process a query through the Genesis system.
        
        This is the main entry point for query handling.
        
        Returns:
            Dict with routing, context, and guidance for the query.
        """
        self.state = KernelState.PROCESSING
        start_time = time.time()
        
        # Ensure session exists
        if not self.current_session:
            self.start_session()
        
        self.current_session.query_count += 1
        self.current_session.last_query = query
        
        # Record interaction
        self.scheduler.record_interaction()
        
        result = {
            "query": query,
            "timestamp": datetime.now().isoformat(),
            "session_id": self.current_session.session_id
        }
        
        try:
            # 1. Route to relevant tools
            routing = self.tool_router.route(query)
            result["routing"] = {
                "intent": routing.detected_intent.value,
                "confidence": routing.confidence,
                "tools": routing.relevant_tools,
                "reasoning": routing.reasoning
            }
            self.current_session.detected_intents.append(routing.detected_intent.value)
            
            # 2. Detect domains
            domains = self.tool_router.detect_domains(query)
            result["domains"] = domains
            self.current_session.active_domains.extend(domains)
            
            # 3. Retrieve relevant memories
            memories = self.cortex.recall(query, limit=5)
            
            # PHASE 4: Semantic Enrichment
            # Find related nodes in RLM for the top memory content
            if memories:
                print(f"🕸️ [RLM] Enriching query via Semantic Traversal...")
                related_context = self.traversal.get_context_cluster(memories[0].content[:50])
                if related_context:
                    result["semantic_context"] = related_context
            
            result["memories"] = [
                {
                    "content": m.content[:200],
                    "tier": m.tier.value if hasattr(m, 'tier') else "unknown",
                    "score": getattr(m, 'score', 0)
                }
                for m in memories
            ]
            
            # 4. Get relevant axioms
            axioms = self.axiom_gen.get_axioms(domain=domains[0] if domains else None)
            result["axioms"] = [
                {
                    "statement": a.statement,
                    "confidence": a.confidence,
                    "domain": a.domain
                }
                for a in axioms[:5]
            ]
            
            # 5. Load domain expertise if needed
            expertise = None
            for domain in domains:
                expert = self.meta_agent.get_expert(domain)
                if expert:
                    expertise = expert.system_prompt[:500]
                    break
            result["expertise"] = expertise
            
            # 6. Register prediction for surprise tracking
            self.surprise.predict(
                event_type="query_response",
                expected_outcome=f"Standard response to {routing.detected_intent.value} query",
                confidence=routing.confidence
            )
            
            # 7. Log to blackboard
            self.blackboard.post(
                entry_type=EntryType.TASK,
                content=f"Processing query: {query[:100]}",
                author="kernel",
                metadata={
                    "intent": routing.detected_intent.value,
                    "domains": domains,
                    "tool_count": len(routing.relevant_tools)
                }
            )
            
            result["status"] = "success"
            result["processing_time_ms"] = int((time.time() - start_time) * 1000)
            
        except Exception as e:
            result["status"] = "error"
            result["error"] = str(e)
            result["traceback"] = traceback.format_exc()
        
        self.state = KernelState.READY
        self._emit_event("query_processed", result)
        
        return result
    
    def compile_context(self, query: str = None) -> CompiledContext:
        """
        Compile full context for system prompt injection.
        
        This aggregates all relevant context from Genesis components
        into a format suitable for injection into Claude's context.
        """
        # Axioms
        axioms_str = self.axiom_gen.get_prompt_injection()
        
        # Memories
        memories_str = ""
        if query:
            memories = self.cortex.recall(query, limit=5)
            if memories:
                memory_lines = [f"- {m.content[:150]}" for m in memories]
                memories_str = "\n".join(memory_lines)
        
        # Tool guidance
        tool_str = ""
        if query:
            routing = self.tool_router.route(query)
            tool_str = self.tool_router.get_tool_summary(routing.relevant_tools)
        
        # Temporal context
        activity = self.scheduler.get_current_activity_level()
        should_heartbeat, reason = self.scheduler.should_run_task(TaskType.HEARTBEAT)
        temporal_str = f"Activity level: {activity.value}\nHeartbeat due: {should_heartbeat} ({reason})"
        
        # Domain expertise
        expertise_str = ""
        if query:
            domains = self.tool_router.detect_domains(query)
            for domain in domains:
                expert = self.meta_agent.get_expert(domain)
                if expert:
                    expertise_str = f"[{domain.upper()}] {expert.system_prompt[:300]}"
                    break
        
        # Session summary
        session_str = ""
        if self.current_session:
            session_str = (
                f"Session: {self.current_session.session_id}\n"
                f"Queries: {self.current_session.query_count}\n"
                f"Active domains: {', '.join(set(self.current_session.active_domains))}"
            )

        # MANDATORY: Always inject verification protocol
        verification_str = self._get_verification_injection()

        return CompiledContext(
            axioms=axioms_str,
            relevant_memories=memories_str,
            tool_guidance=tool_str,
            temporal_context=temporal_str,
            domain_expertise=expertise_str,
            session_summary=session_str,
            verification_protocol=verification_str
        )

    def _get_verification_injection(self) -> str:
        """
        Generate mandatory verification protocol injection.

        This is ALWAYS included in compiled context to prevent confabulation.
        Created after the Quantum Turbo incident (2026-01-10).
        """
        return """## VERIFICATION PROTOCOL (MANDATORY)

**Claims without proof are REJECTED.**

Before ANY completion claim ("done", "implemented", "migrated", "fixed"):
1. Run the code/test/command
2. Paste ACTUAL output (not paraphrased)
3. List files modified with line numbers
4. Provide verification command human can run

**Tier Assessment:**
- T1 (trivial): diff only
- T2 (standard): diff + test output
- T3 (significant): full checklist + pre-mortem analysis
- T4 (keywords: migrate, all, database, production): full evidence + pre-mortem + rollback plan

**Pre-Mortem (T3/T4):** What could fail? What's the blast radius? How to rollback? How will we detect failure?

**Forbidden without proof:** "I have implemented", "successfully migrated", "all X are now Y", "100% complete"

See: protocols/VERIFICATION_PROTOCOL.md"""
    
    # ==================== Heartbeat Integration ====================
    
    def pulse(self, force: bool = False) -> Dict:
        """
        Execute a heartbeat pulse.

        Delegates to the Heartbeat component but adds kernel-level coordination.

        Args:
            force: If True, bypass circadian schedule check
        """
        self.state = KernelState.HEARTBEAT

        # Check if we should pulse based on circadian schedule
        if not force:
            should_pulse, reason = self.scheduler.should_run_task(TaskType.HEARTBEAT)

            if not should_pulse:
                self.state = KernelState.READY
                return {"skipped": True, "reason": reason}
        
        # Run heartbeat
        result = self.heartbeat.pulse()
        
        # Record completion
        self.scheduler.record_task_completion(TaskType.HEARTBEAT)
        
        # Update session if active
        if self.current_session and result.get("axioms_generated", 0) > 0:
            self.current_session.axioms_generated += result["axioms_generated"]
        
        self.state = KernelState.READY
        self._emit_event("heartbeat_complete", result)
        
        return result
    
    def start_heartbeat_daemon(self):
        """Start the background heartbeat daemon."""
        self.heartbeat.start_daemon()
    
    def stop_heartbeat_daemon(self):
        """Stop the background heartbeat daemon."""
        self.heartbeat.stop_daemon()
    
    # ==================== Memory Operations ====================
    
    def remember(self, content: str, metadata: Dict = None) -> str:
        """
        Store a memory with surprise-based routing.
        
        Returns the memory ID.
        """
        # Calculate surprise
        surprise_score = self.surprise.observe(
            event_type="memory_store",
            actual_outcome=content[:100],
            context=metadata or {}
        )
        
        # Route to appropriate tier based on surprise
        if surprise_score.composite_score > 0.7:
            force_tier = MemoryTier.SEMANTIC
        elif surprise_score.composite_score > 0.5:
            force_tier = MemoryTier.EPISODIC
        else:
            force_tier = None
        
        # Store in Cortex
        memory_id = self.cortex.remember(
            content=content,
            metadata={
                **(metadata or {}),
                "surprise_score": surprise_score.composite_score,
                "surprise_level": surprise_score.level.value
            },
            force_tier=force_tier
        )

        # PHASE 2: Knowledge Capture Layer
        # Automatically route significant events to RLM
        if force_tier in [MemoryTier.EPISODIC, MemoryTier.SEMANTIC] or surprise_score.composite_score > 0.6:
            print(f"🎬 [RLM] Capture Triggered: {memory_id[:8]}")
            entity_type = "LESSON" if "error" in content.lower() or "fix" in content.lower() else "PATTERN"
            self.rlm.store(
                name=f"EVENT_{memory_id[:8]}",
                entity_type=entity_type,
                observations=[content, f"Surprise: {surprise_score.composite_score:.2f}"]
            )
        
        return memory_id
    
    def recall(self, query: str, limit: int = 10) -> List:
        """Recall memories relevant to query."""
        return self.cortex.recall(query, limit=limit)
    
    def consolidate(self):
        """Run memory consolidation."""
        self.state = KernelState.CONSOLIDATING
        
        # Check circadian schedule
        should_consolidate, reason = self.scheduler.should_run_task(TaskType.CONSOLIDATION)
        
        if should_consolidate:
            self.cortex.consolidate()
            self.scheduler.record_task_completion(TaskType.CONSOLIDATION)
        
        self.state = KernelState.READY
        return {"consolidated": should_consolidate, "reason": reason}
    
    # ==================== Handoff Generation ====================
    
    def generate_handoff(self) -> str:
        """
        Generate HANDOFF.md for session continuity.
        
        This creates a comprehensive state document that allows
        the next Claude instance to resume seamlessly.
        """
        now = datetime.now()
        
        # Gather state from all components
        stats = self.get_stats()
        schedule = self.scheduler.get_schedule_summary()
        axioms = self.axiom_gen.get_axioms()
        
        handoff = f"""# Genesis Protocol - Session Handoff
Generated: {now.isoformat()}

## Current State
- Kernel Version: {self.VERSION}
- State: {self.state.value}
- Activity Level: {schedule['current_activity']}

## Quick Resume
```python
from genesis_kernel import GenesisKernel
kernel = GenesisKernel()
kernel.start_session()
# Ready for queries
```

## Statistics
- Total queries processed: {stats.get('total_queries', 0)}
- Axioms generated: {stats.get('axiom_count', 0)}
- Memories stored: {stats.get('memory_count', 0)}
- Heartbeat pulses: {stats.get('heartbeat_count', 0)}

## Active Axioms
"""
        
        for axiom in axioms[:10]:
            handoff += f"- [{axiom.domain}|{axiom.confidence:.1f}] {axiom.statement}\n"
        
        handoff += f"""
## Recent Sessions
"""
        for session in self.session_history[-5:]:
            handoff += f"- {session['session_id']}: {session['query_count']} queries, domains: {session.get('domains', [])}\n"
        
        handoff += f"""
## Pending Tasks
"""
        for task in schedule.get('upcoming', []):
            handoff += f"- {task['type']} @ {task['scheduled']} (priority: {task['priority']})\n"
        
        handoff += f"""
## Component Status
- Blackboard: Active ({len(self.blackboard.entries) if hasattr(self.blackboard, 'entries') else 'N/A'} entries)
- Memory Cortex: Active
- Surprise System: Active
- Tool Router: {len(self.tool_router.tools)} tools registered
- Circadian: {schedule['current_activity']} activity

## Notes for Next Session
- Continue any in-progress tasks from blackboard
- Check for due scheduled tasks
- Review high-surprise events for potential axioms
"""
        
        # Save to file
        with open(self.handoff_file, 'w') as f:
            f.write(handoff)
        
        return handoff
    
    # ==================== Statistics & Status ====================
    
    def get_stats(self) -> Dict:
        """Get comprehensive kernel statistics."""
        return {
            "version": self.VERSION,
            "state": self.state.value,
            "total_queries": sum(s.get("query_count", 0) for s in self.session_history),
            "session_count": len(self.session_history),
            "current_session": self.current_session.session_id if self.current_session else None,
            "axiom_count": len(self.axiom_gen.axioms),
            "tool_count": len(self.tool_router.tools),
            "heartbeat_count": self.heartbeat.beat_count,
            "activity_level": self.scheduler.get_current_activity_level().value,
            "memory_count": getattr(self.cortex, 'memory_count', 'N/A')
        }
    
    def status(self) -> str:
        """Get kernel status summary."""
        import sys
        
        # Ensure stdout handles unicode if possible, but fallback to ASCII for status report
        def safe_char(char, fallback):
            try:
                char.encode(sys.stdout.encoding or 'ascii')
                return char
            except:
                return fallback

        check = safe_char("✓", "[OK]")
        
        lines = [
            "=" * 60,
            "GENESIS KERNEL STATUS",
            "=" * 60,
            f"Version: {self.VERSION}",
            f"State: {self.state.value}",
            f"Activity: {self.scheduler.get_current_activity_level().value}",
            "",
            "Components:",
            f"  Axioms: {len(self.axiom_gen.axioms)}",
            f"  Tools: {len(self.tool_router.tools)}",
            f"  Heartbeats: {self.heartbeat.beat_count}",
            "",
            "Sessions:",
            f"  Total: {len(self.session_history)}",
            f"  Current: {self.current_session.session_id if self.current_session else 'None'}",
            f"  Total queries: {sum(s.get('query_count', 0) for s in self.session_history) + (self.current_session.query_count if self.current_session else 0)}",
            "",
            "Schedule:",
            f"  Next Task: {self.scheduler.scheduled_tasks[0].task_type.value if self.scheduler.scheduled_tasks else 'None'}"
        ]
        
        return "\n".join(lines)
    
    # ==================== Lifecycle ====================
    
    def shutdown(self):
        """Graceful shutdown of the kernel."""
        self.state = KernelState.SHUTDOWN
        
        # End session if active
        if self.current_session:
            self.end_session()
        
        # Stop heartbeat
        self.heartbeat.stop_daemon()
        
        # Generate final handoff
        self.generate_handoff()
        
        # Save state
        self._save_state()
        
        self._emit_event("kernel_shutdown", {"timestamp": datetime.now().isoformat()})
        print("Genesis Kernel shutdown complete.")


# CLI Interface
if __name__ == "__main__":
    import sys
    
    if len(sys.argv) < 2:
        print("""
Genesis Kernel
===============

Commands:
  start               Initialize and start the kernel
  status              Show kernel status
  process "<query>"   Process a query
  pulse               Execute heartbeat pulse
  handoff             Generate HANDOFF.md
  consolidate         Run memory consolidation
  shutdown            Graceful shutdown

Examples:
  python genesis_kernel.py start
  python genesis_kernel.py process "search for AI news"
  python genesis_kernel.py status
        """)
        sys.exit(0)
    
    command = sys.argv[1]
    
    if command == "start":
        kernel = GenesisKernel()
        print(kernel.status())
        print("\nKernel ready. Use 'process' to handle queries.")
    
    elif command == "status":
        kernel = GenesisKernel()
        print(kernel.status())
    
    elif command == "process" and len(sys.argv) > 2:
        kernel = GenesisKernel()
        query = " ".join(sys.argv[2:])
        result = kernel.process(query)
        
        print(f"\nQuery: {result['query']}")
        print(f"Intent: {result.get('routing', {}).get('intent', 'unknown')}")
        print(f"Tools: {len(result.get('routing', {}).get('tools', []))}")
        print(f"Memories: {len(result.get('memories', []))}")
        print(f"Axioms: {len(result.get('axioms', []))}")
        print(f"Time: {result.get('processing_time_ms', 0)}ms")
    
    elif command == "pulse":
        kernel = GenesisKernel()
        force = "--force" in sys.argv or "-f" in sys.argv
        result = kernel.pulse(force=force)
        print(f"Heartbeat result: {json.dumps(result, indent=2)}")
    
    elif command == "handoff":
        kernel = GenesisKernel()
        handoff = kernel.generate_handoff()
        print(f"Generated HANDOFF.md ({len(handoff)} chars)")
        print(f"Saved to: {kernel.handoff_file}")
    
    elif command == "consolidate":
        kernel = GenesisKernel()
        result = kernel.consolidate()
        print(f"Consolidation: {result}")
    
    elif command == "shutdown":
        kernel = GenesisKernel()
        kernel.shutdown()
    
    else:
        print(f"Unknown command: {command}")
