defmodule VavPipeline.Tablet33EngineRootsTest do @moduledoc """ Tablet 33 (2026-10-04) — the Shoresh Engine now hears roots from L1 (shoresh-engine `Shoresh.Roots`), and its answers changed shape in three ways the cycle must carry faithfully: * a root may be two letters (`כל`), exactly as L1 records it — no padded He; * `binyan` is null for a noun, and for any word not in the verse; * a root heard through a word's lemma (`לבבך` → `לבב`) arrives with the `surface` word it was heard from, because L1 records no shoresh on the suffixed noun and the verse cannot be searched by shoresh. The engine's own behaviour is held by its HSpec suite (55 examples). This file holds the pipeline's reading of it, with an engine-shaped stand-in under the real port name answering as the rebuilt engine answered for Devarim 6:5 on 2026-10-04. """ use ExUnit.Case, async: false import Plug.Test import Plug.Conn alias VavPipeline.{HaltMonitor, MannaLedger} alias VavPipeline.BigdeiKodesh.Router @opts Router.init([]) defmodule EnginePort do use GenServer def start, do: GenServer.start(__MODULE__, :ok, name: VavPipeline.ShoreshEnginePort) @impl true def init(:ok), do: {:ok, :ok} @impl true def handle_call({:request, _json_line}, _from, s) do roots = [ root(["aleph", "he", "bet"], "אהב", 8, "Qal", "ואהבת", "verse"), root(["kaf", "lamed"], "כל", 50, nil, "בכל", "verse"), root(["lamed", "bet", "bet"], "לבב", 34, nil, "לבבך", "lemma") ] {:reply, {:ok, %{"roots_activated" => roots, "parse_tree" => nil, "dual_readings" => []}}, s} end defp root(letters, hebrew, gematria, binyan, surface, derivation) do %{ "shoresh" => letters, "shoresh_hebrew" => hebrew, "gematria_value" => gematria, "binyan" => binyan, "domain" => "unknown", "torah_refs" => [], "neighbors" => [], "gematria_neighbors" => [], "surface" => surface, "derivation" => derivation } end end setup do if HaltMonitor.halted?(), do: HaltMonitor.resolve("tablet33 test setup") write_provision(50) assert Process.whereis(VavPipeline.ShoreshEnginePort) == nil {:ok, pid} = EnginePort.start() on_exit(fn -> if Process.alive?(pid), do: GenServer.stop(pid) end) :ok end test "Devarim 6:5 — the engine's roots are placed in the verse and said plainly" do conn = post_ask("devarim 6:5") body = Jason.decode!(conn.resp_body) answer = body["answer"] assert conn.status == 200, "#{conn.status} #{conn.resp_body}" # A verb in the verse: binyan and position. assert answer =~ "א-ה-ב (gematria 8, Qal, word 1)" # A two-letter root stays two letters, and stands where L1 says: בכל # is word 5, ובכל words 7 and 9. assert answer =~ "כ-ל (gematria 50, word 5, 7, 9)" # Heard through the lemma; L1 gives לבבך no shoresh, so only the # surface word can place it. Word 6 — not "not in this verse". assert answer =~ "ל-ב-ב (gematria 34, word 6)" refute answer =~ "not in this verse" refute answer =~ "binyan unknown" assert body["processing"]["roots_consulted"] == ["א-ה-ב", "כ-ל", "ל-ב-ב"] end defp write_provision(compute_units) do MannaLedger.reset() on_exit(fn -> MannaLedger.reset() end) today = Date.utc_today() |> Date.to_iso8601() expires = DateTime.utc_now() |> DateTime.add(6 * 3600) |> DateTime.to_iso8601() provision = %{ "date" => today, "provision" => %{ "compute_units" => compute_units, "memory_mb" => 512, "api_calls_external" => 5, "storage_delta_mb" => 2, "sanhedrin_panels_max" => 2 }, "type" => "regular", "expires_at" => expires, "written_by" => "tablet33_test", "written_at" => DateTime.utc_now() |> DateTime.to_iso8601() } path = VavPipeline.Manna.provision_file() File.mkdir_p!(Path.dirname(path)) File.write!(path, Jason.encode!(provision)) on_exit(fn -> File.rm(path) end) path end defp post_ask(question) do conn(:post, "/peah/ask", Jason.encode!(%{question: question})) |> put_req_header("content-type", "application/json") |> Router.call(@opts) end end