BuddyMath / tests /archive_scripts /verify_v42_firewall.py
dotandru's picture
Fix: Clean production deployment with sse-starlette
9d29c62
Raw
History Blame Contribute Delete
3.34 kB
# 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!")