#!/usr/bin/env python3 """ Test suite for Uni-Wizard v2 — Three-House Architecture Tests: - House policy enforcement - Provenance tracking - Routing decisions - Cross-house workflows - Telemetry logging """ import sys import json import tempfile import shutil from pathlib import Path from unittest.mock import Mock, patch # Add parent to path sys.path.insert(0, str(Path(__file__).parent.parent)) from harness import ( UniWizardHarness, House, HousePolicy, Provenance, ExecutionResult, SovereigntyTelemetry ) from router import HouseRouter, TaskType, CrossHouseWorkflow class TestHousePolicy: """Test house policy enforcement""" def test_timmy_policy(self): policy = HousePolicy.get(House.TIMMY) assert policy["requires_provenance"] is True assert policy["can_override"] is True assert policy["telemetry"] is True assert "Sovereignty" in policy["motto"] def test_ezra_policy(self): policy = HousePolicy.get(House.EZRA) assert policy["requires_provenance"] is True assert policy["must_read_before_write"] is True assert policy["citation_required"] is True assert policy["evidence_threshold"] == 0.8 assert "Read" in policy["motto"] def test_bezalel_policy(self): policy = HousePolicy.get(House.BEZALEL) assert policy["requires_provenance"] is True assert policy["requires_proof"] is True assert policy["test_before_ship"] is True assert "Build" in policy["motto"] class TestProvenance: """Test provenance tracking""" def test_provenance_creation(self): p = Provenance( house="ezra", tool="git_status", started_at="2026-03-30T20:00:00Z", evidence_level="full", confidence=0.95, sources_read=["repo:/path", "git:HEAD"] ) d = p.to_dict() assert d["house"] == "ezra" assert d["evidence_level"] == "full" assert d["confidence"] == 0.95 assert len(d["sources_read"]) == 2 class TestExecutionResult: """Test execution result with provenance""" def test_success_result(self): prov = Provenance( house="ezra", tool="git_status", started_at="2026-03-30T20:00:00Z", evidence_level="full", confidence=0.9 ) result = ExecutionResult( success=True, data={"status": "clean"}, provenance=prov, execution_time_ms=150 ) json_result = result.to_json() parsed = json.loads(json_result) assert parsed["success"] is True assert parsed["data"]["status"] == "clean" assert parsed["provenance"]["house"] == "ezra" class TestSovereigntyTelemetry: """Test telemetry logging""" def setup_method(self): self.temp_dir = tempfile.mkdtemp() self.telemetry = SovereigntyTelemetry(log_dir=Path(self.temp_dir)) def teardown_method(self): shutil.rmtree(self.temp_dir) def test_log_creation(self): prov = Provenance( house="timmy", tool="test", started_at="2026-03-30T20:00:00Z", evidence_level="full", confidence=0.9 ) result = ExecutionResult( success=True, data={}, provenance=prov, execution_time_ms=100 ) self.telemetry.log_execution("timmy", "test", result) # Verify log file exists assert self.telemetry.telemetry_log.exists() # Verify content with open(self.telemetry.telemetry_log) as f: entry = json.loads(f.readline()) assert entry["house"] == "timmy" assert entry["tool"] == "test" assert entry["evidence_level"] == "full" def test_sovereignty_report(self): # Log some entries for i in range(5): prov = Provenance( house="ezra" if i % 2 == 0 else "bezalel", tool=f"tool_{i}", started_at="2026-03-30T20:00:00Z", evidence_level="full", confidence=0.8 + (i * 0.02) ) result = ExecutionResult( success=True, data={}, provenance=prov, execution_time_ms=100 + i ) self.telemetry.log_execution(prov.house, prov.tool, result) report = self.telemetry.get_sovereignty_report() assert report["total_executions"] == 5 assert "ezra" in report["by_house"] assert "bezalel" in report["by_house"] assert report["avg_confidence"] > 0 class TestHarness: """Test UniWizardHarness""" def test_harness_creation(self): harness = UniWizardHarness("ezra") assert harness.house == House.EZRA assert harness.policy["must_read_before_write"] is True def test_ezra_read_before_write(self): """Ezra must read git_status before git_commit""" harness = UniWizardHarness("ezra") # Try to commit without reading first # Note: This would need actual git tool to fully test # Here we test the policy check logic evidence_level, confidence, sources = harness._check_evidence( "git_commit", {"repo_path": "/tmp/test"} ) # git_commit would have evidence from params assert evidence_level in ["full", "partial", "none"] def test_bezalel_proof_verification(self): """Bezalel requires proof verification""" harness = UniWizardHarness("bezalel") # Test proof verification logic assert harness._verify_proof("git_status", {"success": True}) is True assert harness.policy["requires_proof"] is True def test_timmy_review_generation(self): """Timmy can generate reviews""" harness = UniWizardHarness("timmy") # Create mock results mock_results = { "tool1": ExecutionResult( success=True, data={"result": "ok"}, provenance=Provenance( house="ezra", tool="tool1", started_at="2026-03-30T20:00:00Z", evidence_level="full", confidence=0.9 ), execution_time_ms=100 ), "tool2": ExecutionResult( success=True, data={"result": "ok"}, provenance=Provenance( house="bezalel", tool="tool2", started_at="2026-03-30T20:00:00Z", evidence_level="full", confidence=0.85 ), execution_time_ms=150 ) } review = harness.review_for_timmy(mock_results) assert review["house"] == "timmy" assert review["summary"]["total"] == 2 assert review["summary"]["successful"] == 2 assert "recommendation" in review class TestRouter: """Test HouseRouter""" def test_task_classification(self): router = HouseRouter() # Read tasks assert router.classify_task("git_status", {}) == TaskType.READ assert router.classify_task("system_info", {}) == TaskType.READ # Build tasks assert router.classify_task("git_commit", {}) == TaskType.BUILD # Test tasks assert router.classify_task("health_check", {}) == TaskType.TEST def test_routing_decisions(self): router = HouseRouter() # Read → Ezra task_type = TaskType.READ routing = router.ROUTING_TABLE[task_type] assert routing["house"] == House.EZRA # Build → Bezalel task_type = TaskType.BUILD routing = router.ROUTING_TABLE[task_type] assert routing["house"] == House.BEZALEL # Judge → Timmy task_type = TaskType.JUDGE routing = router.ROUTING_TABLE[task_type] assert routing["house"] == House.TIMMY def test_routing_stats(self): router = HouseRouter() # Simulate some routing for _ in range(3): router.route("git_status", repo_path="/tmp") stats = router.get_routing_stats() assert stats["total"] == 3 class TestIntegration: """Integration tests""" def test_full_house_chain(self): """Test Ezra → Bezalel → Timmy chain""" # Create harnesses ezra = UniWizardHarness("ezra") bezalel = UniWizardHarness("bezalel") timmy = UniWizardHarness("timmy") # Ezra reads ezra_result = ExecutionResult( success=True, data={"analysis": "issue understood"}, provenance=Provenance( house="ezra", tool="read_issue", started_at="2026-03-30T20:00:00Z", evidence_level="full", confidence=0.9, sources_read=["issue:42"] ), execution_time_ms=200 ) # Bezalel builds bezalel_result = ExecutionResult( success=True, data={"proof": "tests pass"}, provenance=Provenance( house="bezalel", tool="implement", started_at="2026-03-30T20:00:01Z", evidence_level="full", confidence=0.85 ), execution_time_ms=500 ) # Timmy reviews review = timmy.review_for_timmy({ "ezra_analysis": ezra_result, "bezalel_implementation": bezalel_result }) assert "APPROVE" in review["recommendation"] or "REVIEW" in review["recommendation"] def run_tests(): """Run all tests""" import inspect test_classes = [ TestHousePolicy, TestProvenance, TestExecutionResult, TestSovereigntyTelemetry, TestHarness, TestRouter, TestIntegration ] passed = 0 failed = 0 print("=" * 60) print("UNI-WIZARD v2 TEST SUITE") print("=" * 60) for cls in test_classes: print(f"\n📦 {cls.__name__}") print("-" * 40) instance = cls() # Run setup if exists if hasattr(instance, 'setup_method'): instance.setup_method() for name, method in inspect.getmembers(cls, predicate=inspect.isfunction): if name.startswith('test_'): try: # Get fresh instance for each test test_instance = cls() if hasattr(test_instance, 'setup_method'): test_instance.setup_method() method(test_instance) print(f" ✅ {name}") passed += 1 if hasattr(test_instance, 'teardown_method'): test_instance.teardown_method() except Exception as e: print(f" ❌ {name}: {e}") failed += 1 # Run teardown if exists if hasattr(instance, 'teardown_method'): instance.teardown_method() print("\n" + "=" * 60) print(f"Results: {passed} passed, {failed} failed") print("=" * 60) return failed == 0 if __name__ == "__main__": success = run_tests() sys.exit(0 if success else 1)