- 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>
63 lines
2.3 KiB
Python
63 lines
2.3 KiB
Python
"""
|
|
Tests for semichah — provenance tagging.
|
|
|
|
Architecture §3.5: semichah associates input with its source.
|
|
Every korban must have known provenance. Anonymous input is rejected.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from korban_processor.korban import Korban, OfferingType, Provenance
|
|
from korban_processor.semichah import semichah
|
|
|
|
|
|
class TestSemichahTagsProvenance:
|
|
def test_tags_claude_provenance(self):
|
|
korban = semichah("some content", Provenance.CLAUDE, "test query")
|
|
assert korban.provenance == Provenance.CLAUDE
|
|
|
|
def test_tags_human_provenance(self):
|
|
korban = semichah("some content", Provenance.HUMAN, "test query")
|
|
assert korban.provenance == Provenance.HUMAN
|
|
|
|
def test_all_provenance_sources(self):
|
|
for prov in Provenance:
|
|
korban = semichah("content", prov, "query")
|
|
assert korban.provenance == prov
|
|
|
|
def test_preserves_raw_content(self):
|
|
raw = "The root ר-א-ש means beginning. Bereishit 1:1."
|
|
korban = semichah(raw, Provenance.CLAUDE, "query")
|
|
assert korban.raw_content == raw
|
|
|
|
def test_preserves_source_query(self):
|
|
query = "what does bereishit mean?"
|
|
korban = semichah("content", Provenance.CLAUDE, query)
|
|
assert korban.source_query == query
|
|
|
|
def test_default_offering_type_is_olah(self):
|
|
korban = semichah("content", Provenance.CLAUDE, "query")
|
|
assert korban.offering_type == OfferingType.OLAH
|
|
|
|
def test_explicit_offering_type(self):
|
|
korban = semichah("content", Provenance.CLAUDE, "query", OfferingType.SHELAMIM)
|
|
assert korban.offering_type == OfferingType.SHELAMIM
|
|
|
|
def test_returns_korban_instance(self):
|
|
result = semichah("content", Provenance.CLAUDE, "query")
|
|
assert isinstance(result, Korban)
|
|
|
|
|
|
class TestSemichahRejectsInvalidInput:
|
|
def test_rejects_empty_content(self):
|
|
with pytest.raises(ValueError, match="Empty korban"):
|
|
semichah("", Provenance.CLAUDE, "query")
|
|
|
|
def test_rejects_whitespace_only_content(self):
|
|
with pytest.raises(ValueError, match="Empty korban"):
|
|
semichah(" \n\t ", Provenance.CLAUDE, "query")
|
|
|
|
def test_rejects_non_provenance_source(self):
|
|
with pytest.raises((ValueError, AttributeError)):
|
|
semichah("content", "claude", "query") # type: ignore[arg-type]
|