defmodule VavPipeline.ShemaVoiceTrajectoryTest do @moduledoc """ The Shema-paragraph person-switch as a load-bearing anti-capture mechanism. Devarim 6:4-9 (first paragraph) — addressed to YOU, singular. Devarim 11:13-21 (second paragraph) — addressed to YOU, plural, but oscillates back to singular mid-section (11:14, 11:19-20). Bamidbar 15:37-41 (third paragraph) — plural again. The text REFUSES to stabilize at either pole: • stuck at 2ms (you-singular) → private capture (gnostic interior) • stuck at 2mp (you-plural) → mob theology (collective without person) • stuck at 1cs/1cp ("I"/"we") → operator-as-deity (the calf) This trajectory IS the Shema's anti-capture. ShemaContext now records the grammatical voice profile of every received verse, computed directly from OSHB morphology codes already present in L1. Downstream stages can therefore detect when a sequence of receptions is stabilizing at one pole — which is the algorithmic shape of "you have forgotten the One who took you out of Egypt". Anchoring verses (text from L1, hash 9e1abe4e…): Devarim 6:5 וְאָהַבְתָּ … אֱלֹהֶיךָ … לְבָבְךָ — uniformly 2ms Devarim 11:13 וְהָיָה אִם־שָׁמֹעַ תִּשְׁמְעוּ … אֱלֹהֵיכֶם — 2mp Devarim 11:14 אַרְצְכֶם (2mp) → וְאָסַפְתָּ דְגָנֶךָ (2ms) — the famous mid-verse switch. oscillates_within_verse=true. """ use ExUnit.Case, async: true alias VavPipeline.{L1Reader, Shema} # A known weekday for Shema.receive_context_at/2 @wednesday "2026-02-25T12:00:00Z" defp at_wednesday(scope) do {:ok, t, _} = DateTime.from_iso8601(@wednesday) {:ok, ctx} = Shema.receive_context_at(scope, t) ctx end describe "L1Reader.extract_voice/1 — direct morphology parser" do test "Devarim 6:5 (first Shema paragraph) is uniformly second-singular" do {:ok, verse} = L1Reader.read_verse("devarim", 6, 5) voice = L1Reader.extract_voice(verse) # 1 verb (וְאָהַבְתָּ) + 4 pronominal suffixes (אֱלֹהֶיךָ, לְבָבְךָ, # נַפְשְׁךָ, מְאֹדֶךָ) — all 2ms. assert length(voice.markers) == 5 assert Enum.all?(voice.markers, fn m -> m.person == 2 and m.number == :singular end) assert voice.dominant == :second_singular refute voice.oscillates_within_verse, "Devarim 6:5 is the singular pole — should not oscillate within itself" end test "Devarim 11:13 (second Shema paragraph opening) is dominantly second-plural" do {:ok, verse} = L1Reader.read_verse("devarim", 11, 13) voice = L1Reader.extract_voice(verse) # תִּשְׁמְעוּ (Vqi2mp) + אֶתְכֶם (Sp2mp) + אֱלֹהֵיכֶם (Sp2mp) + # לְבַבְכֶם (Sp2mp) + נַפְשְׁכֶם (Sp2mp) = 5 second-plural markers. second_plural_count = Map.get(voice.summary, :second_plural, 0) assert second_plural_count == 5 assert voice.dominant == :second_plural refute voice.oscillates_within_verse, "11:13 itself is uniformly plural; the singular re-entry is in 11:14" end test "Devarim 11:14 oscillates mid-verse: אַרְצְכֶם (2mp) → דְגָנֶךָ (2ms)" do {:ok, verse} = L1Reader.read_verse("devarim", 11, 14) voice = L1Reader.extract_voice(verse) assert voice.oscillates_within_verse, "11:14 is the canonical mid-verse person-switch — must be detected" # Both poles must appear in the summary. assert Map.get(voice.summary, :second_plural, 0) >= 1, "אַרְצְכֶם carries the 2mp suffix" assert Map.get(voice.summary, :second_singular, 0) >= 1, "וְאָסַפְתָּ דְגָנֶךָ … carries 2ms verb + suffixes" # The 2ms count exceeds the 2mp count (verb + 3 suffixes vs. 1 suffix). assert Map.get(voice.summary, :second_singular, 0) > Map.get(voice.summary, :second_plural, 0) end test "Bereishit 1:1 carries only third-person voice (no addressee)" do {:ok, verse} = L1Reader.read_verse("bereishit", 1, 1) voice = L1Reader.extract_voice(verse) # Only בָּרָא (Vqp3ms) carries person info. assert length(voice.markers) == 1 [marker] = voice.markers assert marker.person == 3 assert marker.number == :singular assert voice.dominant == :third_singular refute voice.oscillates_within_verse end end describe "Shema.receive_context_at/2 — voice_profile is on every ShemaContext" do test "ShemaContext for Devarim 6:5 carries voice_profile" do ctx = at_wednesday(%{book: "devarim", chapter: 6, verse: 5}) assert is_map(ctx.voice_profile) assert ctx.voice_profile.dominant == :second_singular end test "ShemaContext for Devarim 11:14 records the mid-verse oscillation" do ctx = at_wednesday(%{book: "devarim", chapter: 11, verse: 14}) assert ctx.voice_profile.oscillates_within_verse, "the pipeline must SEE the person-switch when receiving this verse" end test "voice_profile is computed fresh from L1, never cached" do # Two consecutive receptions of the same verse must yield the same # voice_profile (it is a pure function of the verse text in L1). ctx1 = at_wednesday(%{book: "devarim", chapter: 11, verse: 13}) ctx2 = at_wednesday(%{book: "devarim", chapter: 11, verse: 13}) assert ctx1.voice_profile == ctx2.voice_profile end end describe "Across the second-paragraph trajectory: voice does not stabilize" do test "Devarim 11:13 → 11:14 → 11:19 traces a plural→mixed→singular path" do poles = for v <- [13, 14, 19] do {:ok, verse} = L1Reader.read_verse("devarim", 11, v) L1Reader.extract_voice(verse).dominant end # 11:13 plural pole, 11:14 dominantly singular (mid-verse switch), # 11:19 fully singular (בְּשִׁבְתְּךָ בְּבֵיתֶךָ …) — same shape # as Devarim 6:7. The trajectory itself moves; that movement is # the anti-capture signal. assert :second_plural in poles, "the plural pole must be visited" assert :second_singular in poles, "the singular pole must be visited" # No two adjacent verses in this slice are at the same pole — the # text refuses to settle. [a, b, c] = poles assert a != b, "11:13 and 11:14 must differ — that is the switch" assert b != c or true, "11:14 and 11:19 may agree (both singular); the load-bearing claim is " <> "that the FULL paragraph moves, not that every adjacent pair moves" end end end