Files
bikoret/vav_pipeline/test/vav_pipeline_test.exs
T
Scott KarpandClaude Sonnet 4.6 80ec364da6 Phase 1-2 build: Steps 5-6, 8-13
Shoresh Engine (Haskell, Step 5)
- 12 modules: Types, Lexicon, Binyanim, Teamim, Gematria, Graph,
  KetivQere, Smikhut, Havdalah, Kriah, KiTov, Firmware
- 33 EUnit tests, 0 failures
- Firmware module verifies L1 SHA-256 hash at startup

Talmudic Engine (SWI-Prolog, Step 6)
- 15 modules: halt, reasoning, specification, interface
- 57 PlUnit tests, 0 failures
- Three cardinal halt conditions: avodah_zarah, shfichut_damim, gilui_arayot

Vav Pipeline (Elixir, Steps 8-11)
- 14 modules: BereishitCycle, Shema, Cloud, Manna, L1Reader,
  Specification, HaltConditions, ShabbatTimer, CycleLog, Chatzotzrot,
  ShoreshEngineClient, TalmudicEngineClient, Application
- 46 ExUnit tests, 0 failures
- Nishma-first architecture: hears before it speaks

Sanhedrin Framework (Erlang/OTP, Step 12)
- 8 modules: sanhedrin_app, sanhedrin_sup, escalation, panel_sup,
  panel, judge, clerk, halt_monitor
- 46 EUnit tests, 0 failures (includes fix: rejected outcome now reachable)
- Panel sizes: 1/3/23/71 — unanimous capital guilty → acquit (Sanhedrin 17a)
- Minority opinions append-only, never deleted

Korban Processor (Python, Step 13)
- 6 modules: korban, shechitah, semichah, zerikah, haktarah, router

Builder tooling: AGENTS.md, opencode.json, memory/, src/tools/

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 14:02:34 -05:00

418 lines
15 KiB
Elixir

defmodule VavPipelineTest do
use ExUnit.Case, async: false
# ============================================================
# L1 Reader Tests
# ============================================================
describe "L1Reader" do
test "reads Bereishit 1:1 from L1" do
{:ok, verse} = VavPipeline.L1Reader.read_verse("bereishit", 1, 1)
assert verse.ref == "Bereishit 1:1"
assert verse.book == "bereishit"
assert verse.chapter == 1
assert verse.verse == 1
assert length(verse.words) == 7
end
test "first word of Bereishit 1:1 is bereishit" do
{:ok, verse} = VavPipeline.L1Reader.read_verse("bereishit", 1, 1)
first = hd(verse.words)
assert first.consonants == "בראשית"
assert first.shoresh == "ראש"
assert first.prefix == "ב"
assert "tipcha" in first.teamim
end
test "word without shoresh (particle את)" do
{:ok, verse} = VavPipeline.L1Reader.read_verse("bereishit", 1, 1)
# Word 4 is את (et) — accusative particle, no shoresh
et = Enum.at(verse.words, 3)
assert et.consonants == "את"
assert et.shoresh == nil
end
test "extracts teamim marks with roles" do
{:ok, verse} = VavPipeline.L1Reader.read_verse("bereishit", 1, 1)
marks = VavPipeline.L1Reader.extract_teamim(verse)
# 7 words, each with 1 taam = 7 marks
assert length(marks) == 7
# Etnachta on word 3 (index 2) should be melekh
etnachta = Enum.find(marks, fn m -> m.taam == "etnachta" end)
assert etnachta != nil
assert etnachta.word_index == 2
assert etnachta.role == "melekh"
# Munach on word 2 (index 1) should be mesharet
munach = Enum.find(marks, fn m -> m.taam == "munach" end)
assert munach != nil
assert munach.role == "mesharet"
end
test "extracts roots with gematria" do
{:ok, verse} = VavPipeline.L1Reader.read_verse("bereishit", 1, 1)
roots = VavPipeline.L1Reader.extract_roots(verse)
# ברא should be present with gematria 203
assert Map.has_key?(roots, "ברא")
assert roots["ברא"] == 203
# ראש should be present with gematria 501
assert Map.has_key?(roots, "ראש")
assert roots["ראש"] == 501
# Particles (את) should not produce root entries
refute Map.has_key?(roots, nil)
end
test "returns error for non-existent verse" do
{:error, msg} = VavPipeline.L1Reader.read_verse("bereishit", 999, 999)
assert msg =~ "INVALID_SCOPE"
end
test "meteg_siluq on last word is melekh" do
{:ok, verse} = VavPipeline.L1Reader.read_verse("bereishit", 1, 1)
marks = VavPipeline.L1Reader.extract_teamim(verse)
# Last word (הארץ, index 6) has meteg_siluq
siluq = Enum.find(marks, fn m -> m.taam == "meteg_siluq" end)
assert siluq != nil
assert siluq.word_index == 6
assert siluq.role == "melekh"
end
test "verify L1 integrity" do
assert :ok == VavPipeline.L1Reader.verify_integrity()
end
end
# ============================================================
# Cloud Tests
# ============================================================
describe "Cloud" do
test "weekday is camped" do
# Wednesday at noon UTC — not Shabbat
{:ok, wednesday, _} = DateTime.from_iso8601("2026-02-25T12:00:00Z")
{:ok, state} = VavPipeline.Cloud.check_at(wednesday)
assert state == :camped
end
test "Friday evening is Shabbat" do
{:ok, friday_evening, _} = DateTime.from_iso8601("2026-02-27T19:00:00Z")
assert VavPipeline.Cloud.shabbat?(friday_evening) == true
end
test "Saturday morning is Shabbat" do
{:ok, saturday_morning, _} = DateTime.from_iso8601("2026-02-28T10:00:00Z")
assert VavPipeline.Cloud.shabbat?(saturday_morning) == true
end
test "Saturday evening (after 18:00) is not Shabbat" do
{:ok, saturday_evening, _} = DateTime.from_iso8601("2026-02-28T19:00:00Z")
assert VavPipeline.Cloud.shabbat?(saturday_evening) == false
end
test "Friday afternoon is not Shabbat" do
{:ok, friday_afternoon, _} = DateTime.from_iso8601("2026-02-27T14:00:00Z")
assert VavPipeline.Cloud.shabbat?(friday_afternoon) == false
end
test "Shabbat triggers major transition" do
{:ok, shabbat, _} = DateTime.from_iso8601("2026-02-28T10:00:00Z")
{:ok, state} = VavPipeline.Cloud.check_at(shabbat)
assert {:major_transition, :shabbat_rest, _} = state
end
test "shmitah year check" do
# 2021-2022 was shmitah (Hebrew 5782)
{:ok, shmitah, _} = DateTime.from_iso8601("2022-01-15T12:00:00Z")
assert VavPipeline.Cloud.shmitah_year?(shmitah) == true
# 2026 is not shmitah
{:ok, non_shmitah, _} = DateTime.from_iso8601("2026-06-15T12:00:00Z")
assert VavPipeline.Cloud.shmitah_year?(non_shmitah) == false
end
end
# ============================================================
# Manna Tests
# ============================================================
describe "Manna" do
test "no provision file returns :no_provision" do
{:ok, result} = VavPipeline.Manna.check()
assert result == :no_provision
end
test "double portion day is Friday" do
{:ok, friday, _} = DateTime.from_iso8601("2026-02-27T12:00:00Z")
assert VavPipeline.Manna.double_portion_day?(friday) == true
{:ok, wednesday, _} = DateTime.from_iso8601("2026-02-25T12:00:00Z")
assert VavPipeline.Manna.double_portion_day?(wednesday) == false
end
test "anti-hoarding enforcement" do
assert :ok == VavPipeline.Manna.enforce_anti_hoarding()
end
end
# ============================================================
# Halt Conditions Tests
# ============================================================
describe "HaltConditions" do
test "clear when no violations" do
results = [%{shoresh: "ברא", action: :read}]
assert :clear == VavPipeline.HaltConditions.check_all(results)
end
test "avodah zarah — non-Torah authority" do
results = [%{authority_source: :claude_model}]
assert {:halt, :avodah_zarah, _} = VavPipeline.HaltConditions.check_avodah_zarah(results)
end
test "avodah zarah — Torah authority passes" do
results = [%{authority_source: :torah}]
assert :clear == VavPipeline.HaltConditions.check_avodah_zarah(results)
end
test "avodah zarah — L1 source passes" do
results = [%{authority_source: :l1}]
assert :clear == VavPipeline.HaltConditions.check_avodah_zarah(results)
end
test "shfichut damim — destructive action" do
results = [%{action: :delete}]
assert {:halt, :shfichut_damim, _} = VavPipeline.HaltConditions.check_shfichut_damim(results)
end
test "shfichut damim — overwrite halts" do
results = [%{action: :overwrite}]
assert {:halt, :shfichut_damim, _} = VavPipeline.HaltConditions.check_shfichut_damim(results)
end
test "shfichut damim — read passes" do
results = [%{action: :read}]
assert :clear == VavPipeline.HaltConditions.check_shfichut_damim(results)
end
test "gilui arayot — boundary violation" do
results = [%{boundary_violation: {:spec_interp_merge, "treated interpretation as specification"}}]
assert {:halt, :gilui_arayot, _} = VavPipeline.HaltConditions.check_gilui_arayot(results)
end
test "gilui arayot — no violation passes" do
results = [%{boundary_violation: nil}]
assert :clear == VavPipeline.HaltConditions.check_gilui_arayot(results)
end
test "all three conditions checked — first halt wins" do
results = [%{authority_source: :external_model, action: :delete, boundary_violation: true}]
assert {:halt, :avodah_zarah, _} = VavPipeline.HaltConditions.check_all(results)
end
end
# ============================================================
# Specification Tests
# ============================================================
describe "Specification" do
test "tov for grounded results" do
results = [%{shoresh: "ברא"}, %{shoresh: "אלה"}]
assert :tov == VavPipeline.Specification.evaluate(results, [])
end
test "lo_tov for empty results" do
assert {:lo_tov, _} = VavPipeline.Specification.evaluate([], [])
end
test "teiku for ungrounded results" do
results = [%{shoresh: nil}]
assert :teiku == VavPipeline.Specification.evaluate(results, [])
end
end
# ============================================================
# Chatzotzrot Tests
# ============================================================
describe "Chatzotzrot" do
test "breaking camp signal" do
signal = VavPipeline.Chatzotzrot.signal(:breaking_camp)
assert signal.signal_type == :breaking_camp
assert signal.pattern == :teruah
assert signal.details.urgency == :immediate
end
test "assembly signal" do
signal = VavPipeline.Chatzotzrot.signal(:assembly_all)
assert signal.signal_type == :assembly_all
assert signal.pattern == :tekiah_tekiah
end
test "moadim signal" do
signal = VavPipeline.Chatzotzrot.signal(:moadim)
assert signal.pattern == :tekiah_teruah
end
end
# ============================================================
# BereishitCycle Tests
# ============================================================
describe "BereishitCycle" do
setup do
{:ok, verse} = VavPipeline.L1Reader.read_verse("bereishit", 1, 1)
context = %{
verse: verse,
teamim_marks: VavPipeline.L1Reader.extract_teamim(verse),
ketiv_qere: [],
root_gematria: VavPipeline.L1Reader.extract_roots(verse),
smikhut: [],
cloud_state: :camped,
daily_provision: :no_provision,
scope: %{book: "bereishit", chapter: 1, verse: 1},
received_at: DateTime.utc_now()
}
input = %{
source: "test",
verse_scope: %{book: "bereishit", chapter: 1, verse: 1},
content: "בראשית ברא אלהים את השמים ואת הארץ"
}
{:ok, context: context, input: input}
end
test "tohu decomposes input", %{context: context, input: input} do
result = VavPipeline.BereishitCycle.tohu(input, context)
assert result.raw == "בראשית ברא אלהים את השמים ואת הארץ"
assert result.provenance == "test"
end
test "vayomer activates roots", %{context: context, input: input} do
state = VavPipeline.BereishitCycle.tohu(input, context)
result = VavPipeline.BereishitCycle.vayomer(state, context)
assert result.stage == :vayomer
assert length(result.roots_activated) > 0
# ברא should be among activated roots
bara = Enum.find(result.roots_activated, fn r -> r.shoresh == "ברא" end)
assert bara != nil
assert bara.gematria == 203
end
test "havdalah separates by te'amim", %{context: context, input: input} do
result =
input
|> VavPipeline.BereishitCycle.tohu(context)
|> VavPipeline.BereishitCycle.vayomer(context)
|> VavPipeline.BereishitCycle.havdalah(context)
assert result.stage == :havdalah
assert is_list(result.separated_groups)
assert length(result.separation_boundaries) > 0
end
test "kriah names groups", %{context: context, input: input} do
result =
input
|> VavPipeline.BereishitCycle.tohu(context)
|> VavPipeline.BereishitCycle.vayomer(context)
|> VavPipeline.BereishitCycle.havdalah(context)
|> VavPipeline.BereishitCycle.kriah(context)
assert result.stage == :kriah
assert is_list(result.named_results)
Enum.each(result.named_results, fn group ->
assert Map.has_key?(group, :name)
end)
end
test "full cycle executes successfully", %{context: context, input: input} do
result = VavPipeline.BereishitCycle.execute(input, context)
assert elem(result, 0) in [:ok, :unresolved]
end
end
# ============================================================
# Shema Context Tests (integration — requires L1)
# ============================================================
describe "Shema" do
test "receives context for Bereishit 1:1 on a weekday" do
{:ok, wednesday, _} = DateTime.from_iso8601("2026-02-25T12:00:00Z")
scope = %{book: "bereishit", chapter: 1, verse: 1}
{:ok, context} = VavPipeline.Shema.receive_context_at(scope, wednesday)
# Verse data
assert context.verse.ref == "Bereishit 1:1"
assert length(context.verse.words) == 7
# Te'amim marks
assert length(context.teamim_marks) == 7
assert Enum.any?(context.teamim_marks, fn m -> m.taam == "etnachta" end)
# Root gematria
assert Map.has_key?(context.root_gematria, "ברא")
# Cloud — weekday should be camped
assert context.cloud_state == :camped
# Scope preserved
assert context.scope == scope
end
test "receives Shabbat cloud state on Saturday" do
{:ok, shabbat, _} = DateTime.from_iso8601("2026-02-28T10:00:00Z")
scope = %{book: "bereishit", chapter: 1, verse: 1}
{:ok, context} = VavPipeline.Shema.receive_context_at(scope, shabbat)
assert {:major_transition, :shabbat_rest, _} = context.cloud_state
end
test "returns error for invalid verse scope" do
{:ok, wednesday, _} = DateTime.from_iso8601("2026-02-25T12:00:00Z")
scope = %{book: "bereishit", chapter: 999, verse: 999}
{:error, msg} = VavPipeline.Shema.receive_context_at(scope, wednesday)
assert msg =~ "INVALID_SCOPE"
end
end
# ============================================================
# CycleLog Tests
# ============================================================
describe "CycleLog" do
test "records a tov cycle" do
record = VavPipeline.CycleLog.record({:ok, %{data: "test"}}, :voker)
assert record.phase == :voker
assert record.result == :tov
assert record.cycle_id != nil
end
test "records rejection as lo_tov" do
record = VavPipeline.CycleLog.record({:rejected, "reason"}, :erev)
assert record.phase == :erev
assert record.result == :lo_tov
end
end
# ============================================================
# ShabbatTimer Tests
# ============================================================
describe "ShabbatTimer" do
test "timer is running and reports state" do
state = VavPipeline.ShabbatTimer.state()
assert is_map(state)
assert Map.has_key?(state, :resting)
assert is_boolean(state.resting)
end
test "resting? returns boolean" do
assert is_boolean(VavPipeline.ShabbatTimer.resting?())
end
end
end