defmodule VavPipeline.Tablet39ParashahBreaksTest do @moduledoc """ Tablet 39 (2026-10-04) — L1 had no paragraphs. The WLC marks every petuchah (פ) and setumah (ס). `scripts/build_l1.py` read past them, so the scroll in the aron was 5,853 verses with no division between them but chapter numbers, which are not Torah's. They are now engraved per verse as `parashah_breaks`, and the reader carries them. """ use ExUnit.Case, async: true alias VavPipeline.L1Reader defp breaks(book, chapter, verse) do {:ok, v} = L1Reader.read_verse(book, chapter, verse) {v.parashah_breaks, length(v.words)} end test "the six days of creation each close with a petuchah" do for verse <- [5, 8, 13, 19, 23, 31] do {brks, word_count} = breaks("bereishit", 1, verse) assert brks == [%{after_word: word_count, type: :petuchah}], "Bereishit 1:#{verse}" end end test "a verse with no break after it carries an empty list, not a missing field" do assert {[], _} = breaks("bereishit", 1, 1) assert {[], _} = breaks("bereishit", 1, 6) end test "the Shema opens after a petuchah and its first paragraph closes with a setumah" do # Devarim 6:3 ends the preceding section; 6:4–9 is one parashah. {before, n} = breaks("devarim", 6, 3) assert before == [%{after_word: n, type: :petuchah}] for verse <- 4..8, do: assert({[], _} = breaks("devarim", 6, verse)) {closing, m} = breaks("devarim", 6, 9) assert closing == [%{after_word: m, type: :setumah}] end test "pisqa b'emtza pasuq — a break inside the verse is placed by the word it follows" do # Bereishit 35:22: "…vayishma Yisrael" [פ] "vayihyu v'nei Ya'akov…" {[brk], word_count} = breaks("bereishit", 35, 22) assert brk == %{after_word: 14, type: :petuchah} assert brk.after_word < word_count {:ok, v} = L1Reader.read_verse("bereishit", 35, 22) assert Enum.at(v.words, 13).consonants == "ישראל" assert Enum.at(v.words, 14).consonants == "ויהיו" end test "Devarim 5:21 has two setumot — one within the verse, one after it" do {brks, word_count} = breaks("devarim", 5, 21) assert brks == [ %{after_word: 4, type: :setumah}, %{after_word: word_count, type: :setumah} ] end test "the text of a verse is unchanged — the break is structure, not letters" do {:ok, v} = L1Reader.read_verse("bereishit", 1, 5) assert String.ends_with?(v.text_hebrew, "׃") refute String.ends_with?(String.trim_trailing(v.text_hebrew, "׃") |> String.trim(), "פ") end test "the whole scroll: 293 petuchot and 394 setumot, in 686 verses" do index = L1Reader.l1_root() |> Path.join("torah/index.json") |> File.read!() |> Jason.decode!() counts = for book <- index["books"], {chapter, verses} <- book["chapter_verse_counts"], verse <- 1..verses, reduce: %{petuchah: 0, setumah: 0, verses: 0} do acc -> {:ok, v} = L1Reader.read_verse(book["book"], String.to_integer(chapter), verse) Enum.reduce(v.parashah_breaks, acc, fn b, acc -> Map.update!(acc, b.type, &(&1 + 1)) end) |> Map.update!(:verses, &(&1 + if(v.parashah_breaks == [], do: 0, else: 1))) end assert counts == %{petuchah: 293, setumah: 394, verses: 686} end end