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>
This commit is contained in:
1 parent
0f8ff56f74
commit
33f8b03583
16 files changed
+1816
-31
No files matched your search
@@ -0,0 +1,112 @@
|
||||
"""
|
||||
Tests for router — output routing based on offering type.
|
||||
|
||||
Architecture §3.5: Route to appropriate component based on offering type.
|
||||
|
||||
Kiyyor principle (structure_not_content.md):
|
||||
Stateless — no module-level routing log, no state between calls.
|
||||
"""
|
||||
|
||||
from korban_processor.korban import ProcessedKorban, OfferingType, Provenance
|
||||
from korban_processor.router import route, RoutingResult
|
||||
|
||||
|
||||
_DEFAULT_PROPOSITIONS = ["verse(bereishit, 1, 1)", 'root("ראש", hebrew)']
|
||||
|
||||
|
||||
def make_processed(
|
||||
offering_type: OfferingType,
|
||||
propositions: list[str] | None = None,
|
||||
) -> ProcessedKorban:
|
||||
props = _DEFAULT_PROPOSITIONS if propositions is None else propositions
|
||||
return ProcessedKorban(
|
||||
vital_content="The root ר-א-ש means beginning. Bereishit 1:1.",
|
||||
propositions=props,
|
||||
provenance=Provenance.CLAUDE,
|
||||
offering_type=offering_type,
|
||||
discarded=[],
|
||||
source_query="test query",
|
||||
)
|
||||
|
||||
|
||||
class TestRoutingResults:
|
||||
def test_olah_routes_to_talmudic_engine(self):
|
||||
processed = make_processed(OfferingType.OLAH)
|
||||
result = route(processed, OfferingType.OLAH)
|
||||
assert result.destination == "talmudic_engine"
|
||||
assert result.returned_to_source is False
|
||||
|
||||
def test_shelamim_routes_to_talmudic_engine_with_return(self):
|
||||
processed = make_processed(OfferingType.SHELAMIM)
|
||||
result = route(processed, OfferingType.SHELAMIM)
|
||||
assert result.destination == "talmudic_engine"
|
||||
assert result.returned_to_source is True
|
||||
|
||||
def test_chatat_routes_to_error_correction(self):
|
||||
processed = make_processed(OfferingType.CHATAT)
|
||||
result = route(processed, OfferingType.CHATAT)
|
||||
assert result.destination == "error_correction"
|
||||
assert result.returned_to_source is False
|
||||
|
||||
def test_minchah_routes_to_talmudic_engine(self):
|
||||
processed = make_processed(OfferingType.MINCHAH)
|
||||
result = route(processed, OfferingType.MINCHAH)
|
||||
assert result.destination == "talmudic_engine"
|
||||
assert result.returned_to_source is False
|
||||
|
||||
def test_returns_routing_result_instance(self):
|
||||
processed = make_processed(OfferingType.OLAH)
|
||||
result = route(processed, OfferingType.OLAH)
|
||||
assert isinstance(result, RoutingResult)
|
||||
|
||||
def test_propositions_sent_count_is_correct(self):
|
||||
propositions = ["verse(bereishit, 1, 1)", 'root("ראש", hebrew)', 'claim("a", "b")']
|
||||
processed = make_processed(OfferingType.OLAH, propositions)
|
||||
result = route(processed, OfferingType.OLAH)
|
||||
assert result.propositions_sent == 3
|
||||
|
||||
def test_zero_propositions(self):
|
||||
processed = make_processed(OfferingType.OLAH, [])
|
||||
result = route(processed, OfferingType.OLAH)
|
||||
assert result.propositions_sent == 0
|
||||
|
||||
|
||||
class TestRouterStateless:
|
||||
"""
|
||||
BUILD_KORBAN verification §4:
|
||||
Kiyyor principle — no state leaks between calls.
|
||||
No module-level routing log.
|
||||
"""
|
||||
|
||||
def test_no_module_level_routing_log(self):
|
||||
"""router.py must not have a module-level _routing_log accumulator."""
|
||||
import korban_processor.router as router_module
|
||||
assert not hasattr(router_module, "_routing_log"), (
|
||||
"router.py has module-level _routing_log — violates kiyyor principle"
|
||||
)
|
||||
|
||||
def test_successive_calls_independent(self):
|
||||
"""Second call returns correct result regardless of first call."""
|
||||
p1 = make_processed(OfferingType.OLAH, ["prop1"])
|
||||
p2 = make_processed(OfferingType.CHATAT, ["prop2", "prop3"])
|
||||
|
||||
result1 = route(p1, OfferingType.OLAH)
|
||||
result2 = route(p2, OfferingType.CHATAT)
|
||||
|
||||
assert result1.destination == "talmudic_engine"
|
||||
assert result1.propositions_sent == 1
|
||||
assert result2.destination == "error_correction"
|
||||
assert result2.propositions_sent == 2
|
||||
|
||||
def test_same_input_same_output(self):
|
||||
"""Identical input always produces identical output — no accumulated state."""
|
||||
processed = make_processed(OfferingType.SHELAMIM, ["verse(bereishit, 1, 1)"])
|
||||
|
||||
result1 = route(processed, OfferingType.SHELAMIM)
|
||||
# Run an unrelated routing between
|
||||
route(make_processed(OfferingType.CHATAT, []), OfferingType.CHATAT)
|
||||
result2 = route(processed, OfferingType.SHELAMIM)
|
||||
|
||||
assert result1.destination == result2.destination
|
||||
assert result1.propositions_sent == result2.propositions_sent
|
||||
assert result1.returned_to_source == result2.returned_to_source
|
||||
Reference in new issue
Block a user