tablet 55: the row that was a label — the Sanhedrin's example request crashed its own gate
Verified live 2026-10-19: Tamid's own example for POST /chatzer/sanhedrin
(a case with `sides`) answered 500. The router passed the sides LIST as
the case context; halt_monitor:check_avodah_zarah/1 reads a map, maps:get
raised, and the halt monitor and escalation gen_servers died with the
caller's input (supervisor restarted them; health stayed 8/8). The router
then matched {:ok, decision} on the error and made a 500 of its own.
- sanhedrin/src/halt_monitor.erl: do_check_case refuses a non-map
context as {halt, malformed_case, _} and stays standing. EUnit 49/0
with the new halt_malformed_context_test.
- router.ex process_sanhedrin: sides validated at the kiyor (422 on a bad
shape), carried as context %{sides: sides}; a Sanhedrin refusal answers
422 SANHEDRIN_HALTED, a failure 503 SANHEDRIN_UNAVAILABLE. Two new
router tests, one asserting the gate processes survive the example.
Elixir 624/0.
- specs/broken_tablets/README.md: tablet 55, including what is NOT fixed
— a panel of one accepting on zero references under a grounded-
sounding sentence, the ignored complexity hint, no panel manna spent,
no L3 record. The row in Tamid is still larger than the thing behind it.
Doorpost pin unchanged (no @spec_files touched; scripts/doorpost_check.py
passes).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
04f61c1238
commit
7c40200dfc
5 files changed
+184
-24
No files matched your search
@@ -317,6 +317,43 @@ defmodule VavPipeline.BigdeiKodeshTest do
|
||||
assert body["deliberation"]["outcome"] in ["accepted", "rejected", "teiku"]
|
||||
assert body["note"] =~ "not a binding ruling"
|
||||
end
|
||||
|
||||
# Tablet 55: the Tamid's own example — a case WITH sides — returned
|
||||
# 500 and took the halt monitor and escalation down with it.
|
||||
test "POST /chatzer/sanhedrin with sides (the Tamid's example) deliberates" do
|
||||
conn =
|
||||
conn(:post, "/chatzer/sanhedrin", Jason.encode!(%{
|
||||
case: "A borrower repaid before one witness; the lender denies receipt. Who bears the burden?",
|
||||
sides: [
|
||||
%{position: "the borrower is believed", evidence: ["the money was handed over before a witness"]},
|
||||
%{position: "the lender is believed", evidence: ["one witness does not establish payment"]}
|
||||
],
|
||||
complexity_hint: "monetary"
|
||||
}))
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put_req_header("authorization", "Bearer chatzer-test-token")
|
||||
|> Router.call(@opts)
|
||||
|
||||
assert conn.status == 200
|
||||
body = Jason.decode!(conn.resp_body)
|
||||
assert body["deliberation"]["outcome"] in ["accepted", "rejected", "teiku"]
|
||||
# and the gate is still standing afterwards
|
||||
assert Process.whereis(:halt_monitor) != nil
|
||||
assert Process.whereis(:escalation) != nil
|
||||
end
|
||||
|
||||
test "POST /chatzer/sanhedrin with malformed sides returns 422, not 500" do
|
||||
for bad <- ["not a list", [%{"no_position" => 1}], [%{"position" => "p", "evidence" => "not a list"}]] do
|
||||
conn =
|
||||
conn(:post, "/chatzer/sanhedrin", Jason.encode!(%{case: "x", sides: bad}))
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put_req_header("authorization", "Bearer chatzer-test-token")
|
||||
|> Router.call(@opts)
|
||||
|
||||
assert conn.status == 422, "expected 422 for sides=#{inspect(bad)}, got #{conn.status}"
|
||||
assert Jason.decode!(conn.resp_body)["error"]["code"] == "KIYOR_VALIDATION_FAILED"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# ============================================================
|
||||
|
||||
Reference in new issue
Block a user