Files
bikoret/korban_processor/test/test_haktarah.py
T
Scott KarpandClaude Sonnet 4.6 33f8b03583 Step 13: Korban Processor complete — 7 modules, 181 tests, all passing
- 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>
2026-03-09 09:37:25 -04:00

186 lines
6.3 KiB
Python

"""
Tests for haktarah — transform modality (prose → Prolog propositions).
BUILD_KORBAN.md Verification §3:
Feed it extracted vital content. Verify the Prolog propositions are
syntactically valid and semantically grounded.
Architecture §3.5: haktarah converts prose insights into Prolog-compatible
propositions for the Talmudic Engine.
"""
import re
from korban_processor.haktarah import (
haktarah,
torah_ref_to_prolog,
root_to_prolog,
extract_claims,
extract_connections,
sanitize_prolog_string,
)
from test.fixtures import CLEAN_TORAH_RESPONSE, LATIN_TORAH_RESPONSE
# Valid Prolog term pattern: functor(args...)
_PROLOG_TERM_PATTERN = re.compile(r"^\w+\(.*\)$")
def is_valid_prolog_term(s: str) -> bool:
"""Check if a string looks like a valid Prolog term."""
return bool(_PROLOG_TERM_PATTERN.match(s.strip()))
class TestTorahRefToProlog:
def test_genesis_becomes_bereishit(self):
result = torah_ref_to_prolog("Genesis 1:1")
assert result == "verse(bereishit, 1, 1)"
def test_bereishit_stays_bereishit(self):
result = torah_ref_to_prolog("Bereishit 1:1")
assert result == "verse(bereishit, 1, 1)"
def test_exodus_becomes_shemot(self):
result = torah_ref_to_prolog("Exodus 3:14")
assert result == "verse(shemot, 3, 14)"
def test_leviticus_becomes_vayikra(self):
result = torah_ref_to_prolog("Leviticus 19:18")
assert result == "verse(vayikra, 19, 18)"
def test_numbers_becomes_bamidbar(self):
result = torah_ref_to_prolog("Numbers 15:38")
assert result == "verse(bamidbar, 15, 38)"
def test_deuteronomy_becomes_devarim(self):
result = torah_ref_to_prolog("Deuteronomy 6:4")
assert result == "verse(devarim, 6, 4)"
def test_abbreviated_gen(self):
result = torah_ref_to_prolog("Gen. 1:1")
assert result == "verse(bereishit, 1, 1)"
def test_invalid_ref_returns_empty(self):
result = torah_ref_to_prolog("not a reference")
assert result == ""
class TestRootToProlog:
def test_dash_separated_hebrew_root(self):
result = root_to_prolog("ר-א-ש")
assert result.startswith('root("ראש"')
assert "hebrew" in result
def test_dot_separated_hebrew_root(self):
result = root_to_prolog("ר.א.ש")
assert result.startswith('root("ראש"')
def test_root_keyword_with_hebrew(self):
result = root_to_prolog("root ראש")
assert "ראש" in result
assert "hebrew" in result
def test_transliterated_root(self):
result = root_to_prolog("root shin")
assert "shin" in result
assert "transliterated" in result
def test_invalid_root_returns_empty(self):
result = root_to_prolog("not a root")
assert result == ""
class TestExtractClaims:
def test_extracts_means_claim(self):
text = "The root ר-א-ש means head or beginning."
claims = extract_claims(text)
assert len(claims) >= 1
assert any('claim(' in c for c in claims)
def test_extracts_indicates_claim(self):
text = "This passage indicates divine ownership of creation."
claims = extract_claims(text)
assert len(claims) >= 1
def test_claim_is_valid_prolog_term(self):
text = "The root ר-א-ש means head or beginning."
claims = extract_claims(text)
for claim in claims:
assert is_valid_prolog_term(claim), f"Not a valid Prolog term: {claim}"
def test_no_claims_returns_empty(self):
text = "This is a plain sentence without analytical markers."
claims = extract_claims(text)
# May be empty — that's fine
for claim in claims:
assert is_valid_prolog_term(claim)
class TestExtractConnections:
def test_extracts_connects_to(self):
text = "The concept of Shabbat connects to creation cessation."
conns = extract_connections(text)
assert len(conns) >= 1
assert any('connection(' in c for c in conns)
def test_connection_is_valid_prolog_term(self):
text = "Rosh Hashana parallels Bereishit through the root ר-א-ש."
conns = extract_connections(text)
for conn in conns:
assert is_valid_prolog_term(conn), f"Not a valid Prolog term: {conn}"
class TestSanitizePrologString:
def test_escapes_double_quotes(self):
result = sanitize_prolog_string('He said "hello"')
assert '\\"' in result
def test_replaces_newlines(self):
result = sanitize_prolog_string("line one\nline two")
assert "\n" not in result
def test_truncates_long_strings(self):
long_str = "x" * 300
result = sanitize_prolog_string(long_str)
assert len(result) <= 204 # 200 + "..."
class TestHaktarah:
def test_returns_list(self):
result = haktarah(CLEAN_TORAH_RESPONSE)
assert isinstance(result, list)
def test_empty_input_returns_empty_list(self):
result = haktarah("")
assert result == []
def test_all_propositions_are_valid_prolog_terms(self):
"""BUILD_KORBAN verification §3: Prolog propositions are syntactically valid."""
result = haktarah(CLEAN_TORAH_RESPONSE)
assert len(result) > 0
for prop in result:
assert is_valid_prolog_term(prop), f"Invalid Prolog term: {prop}"
def test_torah_refs_produce_verse_facts(self):
"""BUILD_KORBAN verification §3: semantically grounded."""
result = haktarah(LATIN_TORAH_RESPONSE)
verse_props = [p for p in result if p.startswith("verse(")]
assert len(verse_props) >= 3 # 5 books referenced
def test_contains_bereishit_verse(self):
result = haktarah(CLEAN_TORAH_RESPONSE)
assert any("verse(bereishit," in p for p in result)
def test_hebrew_roots_produce_root_facts(self):
content = "The root ר-א-ש means beginning. Genesis 1:1 uses בְּרֵאשִׁית."
result = haktarah(content)
root_props = [p for p in result if p.startswith("root(")]
assert len(root_props) >= 1
def test_stateless_between_calls(self):
"""Kiyyor principle: second call unaffected by first."""
result1a = haktarah(CLEAN_TORAH_RESPONSE)
_ = haktarah(LATIN_TORAH_RESPONSE)
result1b = haktarah(CLEAN_TORAH_RESPONSE)
assert result1a == result1b