Files
bikoret/vav_pipeline/test/sugya_up_test.exs
T
Scott KarpandClaude Fable 5.1 ba3ff4a2f4 sugya, step 4: the hard matter goes up with its dissent
כי יפלא ממך דבר למשפט ... ובין נגע לנגע דברי ריבת בשעריך וקמת ועלית
(Devarim 17:8, read from L1). A mark the inspection cannot settle, a
dispute in your gates — it goes up. specs/sugya.md §V step 4: a
bedikah's applied dissents become the minority the clerk stores when
the case goes up.

POST /chatzer/sanhedrin takes `bedikah_ref`. Only this key's own
bedikah goes up (404 alike for another's or none). The case is that
verdict; the roots are the verses the output cited, read from L1 — the
output's text is not re-read, the record never kept it; the sugya is
rebuilt from the record (Sugya.from_record/1: forms found but not fired
are the noted ones; a fired forged fringe stood on one witness); the
applied dissents (Sugya.dissents_applied/1) travel in the case context
and down into L3: beside the panel's minority, or AS the minority when
the panel was unanimous — "the panel was unanimous | carried up from
the bedikah (Devarim 17:8): single_witness_noted (Devarim 19:15) for
apology_without_mechanism", grounding achorai. The response's grounding
carries the bedikah, its carried dissent and its sugya. Tamid §1.1: the
request field. Doorpost pin → 7eac65cf….

Tests: from_record/dissents_applied (noted form; forged fringe; clean);
L3 — a noted bedikah goes up under its key: roots from Devarim 6:4 as
read in L1 (ש-מ-ע among them), panel 3, the carried dissent in the
response, a minority recorded though the panel was unanimous; another
key's bedikah 404. Elixir 669/0; L3 8/0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-25 01:44:40 +00:00

98 lines
5.2 KiB
Elixir

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