from __future__ import annotations from backend.core.grounding_checker import _normalize_violation, check_section from backend.prompts.grounding_prompt import ( AUDITOR_SYSTEM_PROMPT, GROUNDING_SYSTEM, GROUNDING_SYSTEM_PROMPT, build_grounding_messages, ) def test_grounding_messages_match_input_contract(): msgs = build_grounding_messages( "Section body with slate tiles noted.", ["note bullet"], ["The chimney was inspected from ground level."], ) assert msgs[0]["content"] == AUDITOR_SYSTEM_PROMPT.strip() assert msgs[0]["content"] == GROUNDING_SYSTEM_PROMPT.strip() assert msgs[0]["content"] == GROUNDING_SYSTEM.strip() assert "[1] SURVEYOR_MESSY_NOTES" in msgs[1]["content"] assert "[2] GENERATED_REPORT_PARAGRAPH" in msgs[1]["content"] assert "[3] BASELINE_PARAGRAPH" in msgs[1]["content"] assert "* note bullet" in msgs[1]["content"] assert "Section body" in msgs[1]["content"] assert "read-only semantic audit engine" in msgs[0]["content"].lower() def test_normalize_structured_violation(): entry = { "violation_type": "invented_defect", "offending_text": "asbestos lagging to pipes", "reason": "Not stated in surveyor notes.", } text = _normalize_violation(entry) assert "invented_defect" in text assert "asbestos lagging" in text def test_regex_pass_scrubs_email_without_llm(): result = check_section( "Contact john@example.com about the chimney.", ["chimney cracked"], ["The chimney stack was inspected."], ) assert "john@example.com" not in result.cleaned_text assert result.had_pii def test_clean_text_unchanged_when_grounded(): notes = ["chimney stack cracked at apex"] template = ["The chimney stack was inspected from ground level."] body = "The chimney stack is cracked at the apex." result = check_section(body, notes, template) assert "cracked" in result.cleaned_text.lower() def test_generic_template_language_allowed_without_notes_match(): notes = ["minor cracking noted"] body = "Inspection was limited to ground level using binoculars. Minor cracking noted." result = check_section(body, notes, []) assert "binoculars" in result.cleaned_text.lower()