- semichah: provenance tagging (6 sources, rejects empty/anonymous) - shechitah: strip preamble, self-reference, hedging, markdown, sycophancy - zerikah: extract Torah refs, Hebrew text, root analysis, insight markers - haktarah: transform prose to Prolog propositions (verse/3, root/2, claim/2, connection/3) - router: stateless routing — removed module-level _routing_log (kiyyor principle) - model_interface: outbound Claude API via httpx (Construction §3.4, HTTPS only) - hebrew_parser: nikkud/teamim stripping, consonant extraction, gematria, root identification All 5 BUILD_KORBAN.md verification tests pass. AGENTS.md: added structure_not_content.md to spec table, added Principle 6. build_log.md: recorded session, broken tablets #18-20, design decisions. Ka'asher tzivah Hashem et Moshe. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
184 lines
6.7 KiB
Python
184 lines
6.7 KiB
Python
"""
|
|
Tests for zerikah — extract vital content.
|
|
|
|
BUILD_KORBAN.md Verification §2:
|
|
Feed it a stripped response. Verify it extracts Torah references accurately,
|
|
identifies Hebrew roots, and separates vital content from discardable material.
|
|
|
|
Architecture §3.5: zerikah extracts Torah references, Hebrew text, root
|
|
analysis, novel insights, logical propositions. Records discards.
|
|
"""
|
|
|
|
from korban_processor.korban import Korban, OfferingType, Provenance
|
|
from korban_processor.zerikah import (
|
|
zerikah,
|
|
is_vital,
|
|
extract_torah_references,
|
|
extract_hebrew_words,
|
|
extract_roots,
|
|
split_sentences,
|
|
)
|
|
from test.fixtures import CLEAN_TORAH_RESPONSE, LATIN_TORAH_RESPONSE
|
|
|
|
|
|
def make_korban(content: str) -> Korban:
|
|
return Korban(
|
|
raw_content=content,
|
|
provenance=Provenance.CLAUDE,
|
|
offering_type=OfferingType.OLAH,
|
|
source_query="test query",
|
|
)
|
|
|
|
|
|
class TestIsVital:
|
|
def test_torah_reference_is_vital(self):
|
|
assert is_vital("Genesis 1:1 begins the Torah.")
|
|
|
|
def test_bereishit_reference_is_vital(self):
|
|
assert is_vital("Bereishit 1:1 opens with creation.")
|
|
|
|
def test_exodus_reference_is_vital(self):
|
|
assert is_vital("Exodus 3:14 reveals the divine name.")
|
|
|
|
def test_hebrew_text_is_vital(self):
|
|
assert is_vital("The word בְּרֵאשִׁית opens the Torah.")
|
|
|
|
def test_root_notation_is_vital(self):
|
|
assert is_vital("The root ר-א-ש means head or beginning.")
|
|
|
|
def test_rashi_reference_is_vital(self):
|
|
assert is_vital("Rashi explains this verse in his commentary.")
|
|
|
|
def test_gematria_mention_is_vital(self):
|
|
assert is_vital("The gematria of this word is 613.")
|
|
|
|
def test_binyan_mention_is_vital(self):
|
|
assert is_vital("The verb is in the piel binyan, indicating intensity.")
|
|
|
|
def test_means_insight_is_vital(self):
|
|
assert is_vital("The root means 'to create from nothing' in this context.")
|
|
|
|
def test_indicates_insight_is_vital(self):
|
|
assert is_vital("This word indicates a continuous action.")
|
|
|
|
def test_generic_filler_not_vital(self):
|
|
assert not is_vital("There are many perspectives on this topic.")
|
|
|
|
def test_empty_sentence_not_vital(self):
|
|
assert not is_vital("")
|
|
|
|
def test_whitespace_only_not_vital(self):
|
|
assert not is_vital(" ")
|
|
|
|
|
|
class TestExtractTorahReferences:
|
|
def test_extracts_genesis(self):
|
|
refs = extract_torah_references("See Genesis 1:1 and Genesis 2:3.")
|
|
assert len(refs) == 2
|
|
assert any("Genesis 1:1" in r for r in refs)
|
|
assert any("Genesis 2:3" in r for r in refs)
|
|
|
|
def test_extracts_bereishit(self):
|
|
refs = extract_torah_references("Bereishit 1:1 is the first verse.")
|
|
assert len(refs) == 1
|
|
assert "Bereishit 1:1" in refs[0]
|
|
|
|
def test_extracts_exodus(self):
|
|
refs = extract_torah_references("Exodus 3:14 reveals Ehyeh asher Ehyeh.")
|
|
assert len(refs) >= 1
|
|
|
|
def test_extracts_multiple_books(self):
|
|
text = "Genesis 1:1, Exodus 3:14, Leviticus 19:18, Numbers 15:38, Deuteronomy 6:4."
|
|
refs = extract_torah_references(text)
|
|
assert len(refs) == 5
|
|
|
|
def test_no_refs_returns_empty(self):
|
|
refs = extract_torah_references("This is general commentary without citations.")
|
|
assert refs == []
|
|
|
|
|
|
class TestExtractHebrewWords:
|
|
def test_extracts_hebrew_word(self):
|
|
words = extract_hebrew_words("The word בְּרֵאשִׁית opens Torah.")
|
|
assert len(words) >= 1
|
|
assert any("בר" in w or "בְּר" in w for w in words)
|
|
|
|
def test_extracts_multiple_hebrew_words(self):
|
|
words = extract_hebrew_words("בְּרֵאשִׁית בָּרָא אֱלֹהִים")
|
|
assert len(words) >= 3
|
|
|
|
def test_no_hebrew_returns_empty(self):
|
|
words = extract_hebrew_words("No Hebrew here, only Latin script.")
|
|
assert words == []
|
|
|
|
|
|
class TestExtractRoots:
|
|
def test_extracts_dash_separated_root(self):
|
|
roots = extract_roots("The root ר-א-ש means head.")
|
|
assert len(roots) >= 1
|
|
|
|
def test_extracts_dot_separated_root(self):
|
|
roots = extract_roots("The root ר.א.ש means head.")
|
|
assert len(roots) >= 1
|
|
|
|
def test_no_roots_returns_empty(self):
|
|
roots = extract_roots("No roots mentioned here.")
|
|
assert roots == []
|
|
|
|
|
|
class TestZerikah:
|
|
def test_returns_vital_and_discarded(self):
|
|
korban = make_korban(CLEAN_TORAH_RESPONSE)
|
|
vital, discarded = zerikah(CLEAN_TORAH_RESPONSE, korban)
|
|
assert isinstance(vital, str)
|
|
assert isinstance(discarded, list)
|
|
|
|
def test_vital_content_contains_torah_refs(self):
|
|
"""BUILD_KORBAN verification §2: extracts Torah references accurately."""
|
|
korban = make_korban(CLEAN_TORAH_RESPONSE)
|
|
vital, _ = zerikah(CLEAN_TORAH_RESPONSE, korban)
|
|
assert "Genesis 1:1" in vital or "Bereishit" in vital
|
|
|
|
def test_vital_content_contains_hebrew(self):
|
|
"""BUILD_KORBAN verification §2: identifies Hebrew roots."""
|
|
korban = make_korban(CLEAN_TORAH_RESPONSE)
|
|
vital, _ = zerikah(CLEAN_TORAH_RESPONSE, korban)
|
|
# The fixture has Hebrew text
|
|
assert "בְּרֵאשִׁית" in vital or "ר-א-ש" in vital
|
|
|
|
def test_vital_content_contains_rashi(self):
|
|
korban = make_korban(CLEAN_TORAH_RESPONSE)
|
|
vital, _ = zerikah(CLEAN_TORAH_RESPONSE, korban)
|
|
assert "Rashi" in vital
|
|
|
|
def test_latin_torah_refs_are_vital(self):
|
|
"""BUILD_KORBAN verification §2: separates vital from discardable."""
|
|
korban = make_korban(LATIN_TORAH_RESPONSE)
|
|
vital, _ = zerikah(LATIN_TORAH_RESPONSE, korban)
|
|
assert "Genesis 1:1" in vital
|
|
assert "Exodus 3:14" in vital
|
|
|
|
def test_empty_content_returns_empty_vital(self):
|
|
korban = make_korban(".")
|
|
vital, discarded = zerikah("", korban)
|
|
assert vital == ""
|
|
assert discarded == []
|
|
|
|
def test_all_filler_fallback_preserves_content(self):
|
|
"""If nothing is vital, zerikah preserves everything rather than discarding all."""
|
|
filler = "There are many perspectives. People disagree. Context matters."
|
|
korban = make_korban(filler)
|
|
vital, discarded = zerikah(filler, korban)
|
|
# Since nothing qualifies as vital, fallback returns everything
|
|
assert vital != "" or discarded == []
|
|
|
|
def test_stateless_between_calls(self):
|
|
"""Kiyyor principle: second call unaffected by first."""
|
|
k1 = make_korban(CLEAN_TORAH_RESPONSE)
|
|
k2 = make_korban(LATIN_TORAH_RESPONSE)
|
|
vital1a, _ = zerikah(CLEAN_TORAH_RESPONSE, k1)
|
|
vital2, _ = zerikah(LATIN_TORAH_RESPONSE, k2)
|
|
vital1b, _ = zerikah(CLEAN_TORAH_RESPONSE, k1)
|
|
# Same input → same output, regardless of what was processed between
|
|
assert vital1a == vital1b
|