""" Full pipeline tests — process_korban() end-to-end. BUILD_KORBAN.md Build Verification: 1. Shechitah test — strips preamble/markdown/hedging/self-reference, preserves Torah 2. Zerikah test — extracts Torah references, Hebrew roots, separates vital from discardable 3. Haktarah test — Prolog propositions syntactically valid and semantically grounded 4. Statelessness test — no state leaks between sequential offerings 5. Empty offering test — graceful rejection when no vital content exists Architecture §3.5: process_korban() is the gate between the world's raw output and the system's inner processing. Kiyyor principle (structure_not_content.md): The laver. Resets before every offering. Daily manna — gathered fresh. """ import re import pytest from korban_processor.korban import ( Korban, ProcessedKorban, OfferingType, Provenance, process_korban, ) from test.fixtures import ( CLAUDE_HEAVY_PREAMBLE_RESPONSE, CLAUDE_EMPTY_OFFERING, CLEAN_TORAH_RESPONSE, LATIN_TORAH_RESPONSE, ) _PROLOG_TERM_PATTERN = re.compile(r"^\w+\(.*\)$") def is_valid_prolog_term(s: str) -> bool: return bool(_PROLOG_TERM_PATTERN.match(s.strip())) class TestBuildVerification1_Shechitah: """ BUILD_KORBAN §1: Feed a Claude API response with heavy preamble, markdown, hedging, and self-reference. Verify output contains none of these and preserves all Torah references and Hebrew analysis. """ def setup_method(self): self.result = process_korban( content=CLAUDE_HEAVY_PREAMBLE_RESPONSE, source=Provenance.CLAUDE, query="analyze bereishit", offering_type=OfferingType.OLAH, ) def test_returns_processed_korban(self): assert isinstance(self.result, ProcessedKorban) def test_strips_preamble(self): assert "Great question" not in self.result.vital_content assert "I'd be happy" not in self.result.vital_content def test_strips_self_reference(self): assert "As an AI" not in self.result.vital_content assert "language model" not in self.result.vital_content def test_strips_hedging(self): assert "worth noting" not in self.result.vital_content def test_strips_closing(self): assert "I hope this helps" not in self.result.vital_content assert "Let me know" not in self.result.vital_content def test_preserves_bereishit_hebrew(self): assert "בְּרֵאשִׁית" in self.result.vital_content def test_preserves_root_notation(self): assert "ר-א-ש" in self.result.vital_content def test_preserves_rashi_reference(self): assert "Rashi" in self.result.vital_content def test_preserves_torah_reference(self): assert "Genesis 1:1" in self.result.vital_content or "Bereishit 1:1" in self.result.vital_content def test_provenance_recorded(self): assert self.result.provenance == Provenance.CLAUDE def test_offering_type_recorded(self): assert self.result.offering_type == OfferingType.OLAH class TestBuildVerification2_Zerikah: """ BUILD_KORBAN §2: Feed a stripped response. Verify it extracts Torah references accurately, identifies Hebrew roots, and separates vital content from discardable. """ def setup_method(self): self.result = process_korban( content=CLEAN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="analyze bereishit", offering_type=OfferingType.OLAH, ) def test_extracts_torah_references(self): assert "Genesis 1:1" in self.result.vital_content or "Bereishit" in self.result.vital_content def test_extracts_hebrew_roots(self): assert "ר-א-ש" in self.result.vital_content or "ראש" in self.result.vital_content def test_separates_vital_from_discardable(self): # The result has vital content — it was not entirely discarded assert self.result.vital_content.strip() != "" def test_discarded_is_list(self): assert isinstance(self.result.discarded, list) def test_multiple_book_references(self): result = process_korban( content=LATIN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="list references", offering_type=OfferingType.OLAH, ) # All five books appear assert "Genesis 1:1" in result.vital_content assert "Exodus 3:14" in result.vital_content class TestBuildVerification3_Haktarah: """ BUILD_KORBAN §3: Feed extracted vital content. Verify Prolog propositions are syntactically valid and semantically grounded. """ def setup_method(self): self.result = process_korban( content=LATIN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="list references", offering_type=OfferingType.OLAH, ) def test_produces_propositions(self): assert len(self.result.propositions) > 0 def test_all_propositions_syntactically_valid(self): for prop in self.result.propositions: assert is_valid_prolog_term(prop), \ f"Invalid Prolog proposition: {prop!r}" def test_propositions_include_verse_facts(self): verse_facts = [p for p in self.result.propositions if p.startswith("verse(")] assert len(verse_facts) >= 3, \ f"Expected ≥3 verse facts, got {len(verse_facts)}: {verse_facts}" def test_bereishit_verse_fact_present(self): result = process_korban( content=CLEAN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="analyze", offering_type=OfferingType.OLAH, ) verse_facts = [p for p in result.propositions if p.startswith("verse(")] assert any("bereishit" in p for p in verse_facts), \ f"No bereishit verse fact in: {verse_facts}" class TestBuildVerification4_Statelessness: """ BUILD_KORBAN §4: Process two offerings sequentially. Verify no state leaked between them. The second offering must be processed identically whether or not the first was processed. """ def test_two_offerings_no_state_leak(self): # Process first offering result1 = process_korban( content=CLAUDE_HEAVY_PREAMBLE_RESPONSE, source=Provenance.CLAUDE, query="query 1", offering_type=OfferingType.OLAH, ) # Process second offering result2 = process_korban( content=LATIN_TORAH_RESPONSE, source=Provenance.MISTRAL, query="query 2", offering_type=OfferingType.MINCHAH, ) # result1 should not contain anything from result2 assert "Mistral" not in result1.vital_content # result2 should not contain anything from result1 (Hebrew preamble content) assert "I'd be happy" not in result2.vital_content def test_second_offering_identical_with_or_without_first(self): """ Process offering A twice — once with offering B in between, once alone. Results must be identical. """ # First: process A alone result_a1 = process_korban( content=LATIN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="query A", offering_type=OfferingType.OLAH, ) # Process unrelated offering B process_korban( content=CLAUDE_HEAVY_PREAMBLE_RESPONSE, source=Provenance.GPT, query="query B", offering_type=OfferingType.CHATAT, ) # Process A again — must be identical to first time result_a2 = process_korban( content=LATIN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="query A", offering_type=OfferingType.OLAH, ) assert result_a1.vital_content == result_a2.vital_content assert result_a1.propositions == result_a2.propositions assert result_a1.discarded == result_a2.discarded def test_provenance_not_shared_between_offerings(self): result1 = process_korban( content=CLEAN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="q", ) result2 = process_korban( content=CLEAN_TORAH_RESPONSE, source=Provenance.MISTRAL, query="q", ) # Same content, different provenance — each result has correct provenance assert result1.provenance == Provenance.CLAUDE assert result2.provenance == Provenance.MISTRAL class TestBuildVerification5_EmptyOffering: """ BUILD_KORBAN §5: Feed a response that contains only preamble and no vital content. Verify the system handles this gracefully — the offering without vital organs is rejected, not processed into empty propositions. """ def setup_method(self): self.result = process_korban( content=CLAUDE_EMPTY_OFFERING, source=Provenance.CLAUDE, query="test empty", offering_type=OfferingType.OLAH, ) def test_returns_processed_korban_not_exception(self): """System does not raise on empty offering — handles gracefully.""" assert isinstance(self.result, ProcessedKorban) def test_empty_offering_rejected_not_processed(self): """ The offering without vital organs is REJECTED — not processed into empty propositions. BUILD_KORBAN.md §5. """ assert self.result.vital_content == "" assert self.result.propositions == [] def test_discarded_content_recorded(self): """What was stripped is recorded — the hide and offal are diagnostic data.""" assert len(self.result.discarded) > 0 def test_source_query_preserved(self): assert self.result.source_query == "test empty" class TestPipelineIntegration: """Additional integration tests covering edge cases.""" def test_all_offering_types_route(self): """All four offering types process without error.""" for otype in OfferingType: result = process_korban( content=CLEAN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="test", offering_type=otype, ) assert isinstance(result, ProcessedKorban) assert result.offering_type == otype def test_all_provenance_sources_accepted(self): """All six provenance sources process without error.""" for prov in Provenance: result = process_korban( content=CLEAN_TORAH_RESPONSE, source=prov, query="test", ) assert result.provenance == prov def test_human_input_processes_correctly(self): human_input = "What does bereishit mean? The word בְּרֵאשִׁית opens Genesis 1:1." result = process_korban( content=human_input, source=Provenance.HUMAN, query="definition query", offering_type=OfferingType.SHELAMIM, ) assert result.provenance == Provenance.HUMAN assert result.offering_type == OfferingType.SHELAMIM assert "בְּרֵאשִׁית" in result.vital_content or "Genesis 1:1" in result.vital_content def test_empty_raises_value_error(self): """Empty content must be rejected at semichah.""" with pytest.raises(ValueError, match="Empty korban"): process_korban( content="", source=Provenance.CLAUDE, query="test", ) class TestEishZarahCouplingTrace: """ eish_zarah_reading.md §5.6: ProcessedKorban preserves the raw Korban. The floor between input and output is never severed. Vayikra 6:6: eish tamid — fire ON the altar (coupled). """ def test_raw_korban_preserved(self): """ProcessedKorban stores the original offering.""" result = process_korban( content=CLEAN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="test coupling", offering_type=OfferingType.OLAH, ) assert result.raw_korban is not None assert isinstance(result.raw_korban, Korban) def test_raw_content_matches_input(self): """The raw_korban's content is the original input, unmodified.""" result = process_korban( content=CLEAN_TORAH_RESPONSE, source=Provenance.CLAUDE, query="test coupling", ) assert result.raw_korban.raw_content == CLEAN_TORAH_RESPONSE def test_raw_provenance_matches(self): """The raw_korban's provenance matches the processed result.""" result = process_korban( content=CLEAN_TORAH_RESPONSE, source=Provenance.MISTRAL, query="test", ) assert result.raw_korban.provenance == Provenance.MISTRAL assert result.provenance == result.raw_korban.provenance def test_empty_offering_also_stores_raw(self): """Even rejected offerings preserve the raw korban.""" result = process_korban( content=CLAUDE_EMPTY_OFFERING, source=Provenance.CLAUDE, query="test empty", ) assert result.raw_korban is not None assert result.raw_korban.raw_content == CLAUDE_EMPTY_OFFERING def test_pydantic_validation_rejects_empty_content(self): """Pydantic validator catches empty raw_content at construction.""" from pydantic import ValidationError with pytest.raises(ValidationError, match="Empty korban"): Korban( raw_content=" ", provenance=Provenance.CLAUDE, offering_type=OfferingType.OLAH, source_query="test", )