# verify_v42_firewall.py import sys import os import json # Add current directory to path sys.path.append(os.getcwd()) from proof_graph import ProofGraph, ProofStep from pedagogical_builder import build_pedagogical_response import explanation_math_firewall def test_firewall_block(): print("🧪 Testing Behavioral Firewall Block (V4.2)...") # 1. Create a simple ProofGraph (Algebra) steps = [ProofStep(1, "x + 2 = 5", "שיוויון בסיסי")] graph = ProofGraph(steps) # 2. Mock LLM output that injects a forbidden concept ("נגזרת") llm_output = { "steps_explanations": [ {"step_id": 1, "pedagogical_explanation": "נשתמש במושג הנגזרת כדי למצוא את המשתנה"} # VIOLATION! ], "teacher_summary": "זה סיכום המורה" } # 3. Build response - should raise LLMSchemaError due to firewall try: build_pedagogical_response("GENERAL", llm_output, {}, proof_graph=graph) print("❌ Failure: Firewall ALLOWED a forbidden concept!") except Exception as e: if "Behavioral Firewall Violation" in str(e) and "נגזרת" in str(e): print(f"✅ Success: Firewall BLOCKED forbidden concept. Reason: {e}") else: print(f"❌ Failure: Got wrong error: {e}") def test_projection_only_lock(): print("\n🧪 Testing Projection-Only Lock (V4.2)...") # ProofGraph with 1 step graph = ProofGraph([ProofStep(1, "x = 3", "תשובה סופית")]) # LLM with NO steps llm_output = {} # Response should still have 1 step because it's a projection of the ProofGraph response = build_pedagogical_response("GENERAL", llm_output, {}, proof_graph=graph) ui_steps = response["sections"][0]["steps"] if len(ui_steps) == 1 and ui_steps[0]["block_math"] == "x = 3": print("✅ Success: UI is a projection of the ProofGraph even without LLM input.") else: print(f"❌ Failure: Projection mismatch. Steps found: {len(ui_steps)}") def test_deterministic_summary(): print("\n🧪 Testing Deterministic Summary Renderer (V4.2)...") # This test simulates the orchestrator's summary generation from orchestrator import BuddyOrchestrator # We mock the parts needed for BuddyOrchestrator to run _generate_deterministic_summary class MockOrchestrator(BuddyOrchestrator): def __init__(self): pass # No need for real init orchestrator = MockOrchestrator() graph = ProofGraph([ProofStep(1, "x=3", "בידוד הנעלם", operator_used="BASIC_ALGEBRA")]) summary = orchestrator._generate_deterministic_summary( "GENERAL", "משוואות", "x=3", proof_graph=graph ) print(f"Generated Summary: {summary}") if "נבדק שהשתמשת בשיטות: בידוד הנעלם" in summary and "הגענו לתשובה: x=3" in summary: print("✅ Success: Deterministic summary followed the template correctly.") else: print("❌ Failure: Summary did not follow the template or missing data.") if __name__ == "__main__": test_firewall_block() test_projection_only_lock() test_deterministic_summary() print("\n✨ V4.2 Behavioral Firewall Verification PASSED!")