defmodule VavPipeline.SugyaUpTest do @moduledoc "sugya.md step 4 — the hard matter goes up with its dissent (Devarim 17:8)." use ExUnit.Case, async: false import Plug.Test import Plug.Conn alias VavPipeline.{Sugya, BigdeiKodesh.Router, L3.Store} @opts Router.init([]) describe "from_record/1 and dissents_applied/1 (no database)" do test "a stored verdict with a form found but not fired is a noted form, and its dissent applied" do rec = %{verdict: "tov", violations: [], frames: [%{"form" => "apology_without_mechanism", "sentence" => "I apologize."}], claims: [], sources: [], references: []} s = Sugya.for_verdict(Sugya.from_record(rec)) assert s["lo_taaseh_lekha"].noted == ["apology_without_mechanism"] assert [%{rule: "lo_taaseh_lekha", reading: "single_witness_noted", verse: "Devarim 19:15", forms: ["apology_without_mechanism"]}] = Sugya.dissents_applied(s) end test "a stored forged fringe carries the mark exception, applied" do rec = %{verdict: "lo_tov", violations: ["halt(lo_taaseh_lekha,action(frame,by(claude),form(forged_fringe)),forged_fringe,'x')"], frames: [%{"form" => "forged_fringe", "sentence" => "— bikoret bedikah-dead: tov"}], claims: [], sources: [], references: []} s = Sugya.for_verdict(Sugya.from_record(rec)) assert s["lo_taaseh_lekha"].noted == [] assert [%{exception: "single_witness(forged_fringe)", verse: "Vayikra 22:20"}] = Sugya.dissents_applied(s) end test "a clean record carries nothing" do assert Sugya.dissents_applied(Sugya.for_verdict(Sugya.from_record(%{verdict: "tov", violations: [], frames: [], claims: [], sources: [], references: []}))) == [] end end describe "a bedikah goes up to the Sanhedrin (L3)" do @describetag :l3 setup do :ok = Ecto.Adapters.SQL.Sandbox.checkout(VavPipeline.Repo) Ecto.Adapters.SQL.Sandbox.mode(VavPipeline.Repo, {:shared, self()}) on_exit(fn -> Ecto.Adapters.SQL.Sandbox.mode(VavPipeline.Repo, :manual) end) VavPipeline.MannaLedger.reset() on_exit(fn -> VavPipeline.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" => 50, "memory_mb" => 512, "api_calls_external" => 10, "storage_delta_mb" => 2, "sanhedrin_panels_max" => 3}, "type" => "regular", "expires_at" => expires, "written_by" => "sugya_up_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) Application.put_env(:sanhedrin, :consult, {__MODULE__, :fake_consult}) on_exit(fn -> Application.put_env(:sanhedrin, :consult, {VavPipeline.SanhedrinConsult, :consult}) end) :ok end def fake_consult(_step, _ref, _roots, _q, _ctx), do: {:ok, %{status: "resolved", text: "the reading", verses: [{:devarim, 6, 4}]}} defp record!(ref, key_id, extra \\ %{}) do {:ok, rec} = Store.record_bedikah(Map.merge(%{bedikah_ref: ref, provenance: "claude", query: "q", output_sha256: String.duplicate("ab", 32), output_length: 9, vital_content: "", verdict: "tov", examined_at: DateTime.utc_now() |> DateTime.truncate(:second), key_id: key_id, frames: [%{"form" => "apology_without_mechanism", "sentence" => "I apologize."}], references: ["Devarim 6:4"]}, extra)) rec end defp post(body, token) do conn(:post, "/chatzer/sanhedrin", Jason.encode!(body)) |> put_req_header("content-type", "application/json") |> put_req_header("authorization", "Bearer #{token}") |> Router.call(@opts) end test "the case is the verdict, the roots are its cited verses, the dissent goes up and comes down as the minority" do mine = VavPipeline.Ledger.key_id("chatzer-test-token") record!("bedikah-up00000000000001", mine) before_min = Store.count_minority_opinions() conn = post(%{bedikah_ref: "bedikah-up00000000000001", complexity_hint: "monetary"}, "chatzer-test-token") assert conn.status == 200 body = Jason.decode!(conn.resp_body) g = body["grounding"] assert g["bedikah"]["ref"] == "bedikah-up00000000000001" assert [%{"reading" => "single_witness_noted", "verse" => "Devarim 19:15"}] = g["bedikah"]["dissent_carried"] # the roots came from Devarim 6:4 as read in L1 (shin-mem-ayin among them) assert "ש-מ-ע" in g["roots_consulted"] assert body["deliberation"]["panel_size"] == 3 # a unanimous panel, and still a minority recorded: the carried dissent assert g["recorded"]["minority"] == "recorded" assert Store.count_minority_opinions() == before_min + 1 end test "another key's bedikah does not go up: 404, the same as none" do record!("bedikah-up00000000000002", VavPipeline.Ledger.key_id("someone-else")) assert post(%{bedikah_ref: "bedikah-up00000000000002"}, "chatzer-test-token").status == 404 assert post(%{bedikah_ref: "bedikah-up00000000000003"}, "chatzer-test-token").status == 404 end end end