bedikah: two witnesses for check 7 (bishe'arecha step 1)
Devarim 19:15 — one witness does not stand. A frame form now stands only when it is found in two distinct sentences, or in one sentence beside a violation from checks 1–6, or beside a sentence of another form; the Vav Pipeline sends the halt term only then (stands_on: sentences | other_checks | other_forms, witnesses: n). A form seen once and alone is returned under checks.frames.noted with its sentence and is not counted in the verdict; the output is still examined, not empty. Tamid §1.1 contract and bishearecha.md §V updated; Doorpost re-pinned (86a43d6b…). Elixir 558/0; Prolog bedikah 34/34 (the rule is unchanged; its header says what now reaches it). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
b333517924
commit
19d3aaac86
7 files changed
+143
-36
No files matched your search
@@ -90,9 +90,16 @@ defmodule VavPipeline.Bedikah do
|
||||
{"excluded_adversarial", :adversarial, "action(exclude_adversarial, by(~s), target(output))"}
|
||||
]
|
||||
|
||||
# Check 7 — the frame (lo_taaseh_lekha.pl): one term per FORM found,
|
||||
# the sentences as evidence. Forms are the specimen classes of the
|
||||
# transmitter's archive; the Korban Processor names them (find_frames).
|
||||
# Check 7 — the frame (lo_taaseh_lekha.pl): one term per FORM that
|
||||
# STANDS, the sentences as evidence. Forms are the specimen classes of
|
||||
# the transmitter's archive; the Korban Processor names them (find_frames).
|
||||
#
|
||||
# Two witnesses (Devarim 19:15, bishearecha.md §V): a form stands when
|
||||
# it is found in two sentences, or in one sentence beside another
|
||||
# witness — a violation from checks 1–6, or a sentence of another form.
|
||||
# A form seen once and alone is NOTED with its sentence and not counted
|
||||
# in the verdict. The archive's finding was never one sentence; it was
|
||||
# recurrence.
|
||||
@frame_forms ~w(contested_laundering virtue_certification agency_displacement apology_without_mechanism unrequested_confidence smuggled_vocabulary source_asymmetry)
|
||||
|
||||
|
||||
@@ -152,12 +159,12 @@ defmodule VavPipeline.Bedikah do
|
||||
{:ok, grounding} <- check_grounding(bedikah_ref, examination, trace, interpretation_checker),
|
||||
{:ok, actions} <- check_actions(examination, halt_checker),
|
||||
{:ok, structure} <- check_structure(examination, provenance, halt_checker),
|
||||
{:ok, frames} <- check_frames(examination, provenance, halt_checker) do
|
||||
prior =
|
||||
authority.violations ++ grounding.violations ++ actions.violations ++
|
||||
Enum.flat_map(structure, fn {_, c} -> c.violations end),
|
||||
{:ok, frames} <- check_frames(examination, provenance, halt_checker, length(prior)) do
|
||||
checks = Map.merge(%{authority: authority, grounding: grounding, actions: actions, frames: frames}, structure)
|
||||
|
||||
violations =
|
||||
authority.violations ++ grounding.violations ++ actions.violations ++
|
||||
Enum.flat_map(structure, fn {_, c} -> c.violations end) ++ frames.violations
|
||||
violations = prior ++ frames.violations
|
||||
verdict = if violations == [], do: :tov, else: :lo_tov
|
||||
finish(bedikah_ref, output, provenance, query, sources, examination, trace, checks, violations, verdict)
|
||||
else
|
||||
@@ -444,36 +451,60 @@ defmodule VavPipeline.Bedikah do
|
||||
# 7. The frame
|
||||
# ------------------------------------------------------------
|
||||
|
||||
defp check_frames(examination, provenance, halt_checker) do
|
||||
defp check_frames(examination, provenance, halt_checker, other_witnesses) do
|
||||
found = examination["frames"] || []
|
||||
by_form = Enum.group_by(found, & &1["form"])
|
||||
|
||||
Enum.reduce_while(@frame_forms, {:ok, %{fired: false, forms: %{}, violations: []}}, fn form, {:ok, acc} ->
|
||||
by_form =
|
||||
found
|
||||
|> Enum.group_by(& &1["form"])
|
||||
|> Map.new(fn {form, sentences} -> {form, Enum.uniq_by(sentences, & &1["sentence"])} end)
|
||||
|
||||
frame_witnesses = by_form |> Map.values() |> Enum.map(&length/1) |> Enum.sum()
|
||||
empty = %{fired: false, forms: %{}, noted: %{}, violations: []}
|
||||
|
||||
Enum.reduce_while(@frame_forms, {:ok, empty}, fn form, {:ok, acc} ->
|
||||
case Map.get(by_form, form, []) do
|
||||
[] ->
|
||||
{:cont, {:ok, acc}}
|
||||
|
||||
sentences ->
|
||||
term = "action(frame, by(#{atom(provenance)}), form(#{form}))"
|
||||
claims = Enum.map(sentences, &Map.take(&1, ["sentence", "matched"]))
|
||||
witnesses = length(sentences)
|
||||
|
||||
case halt_checker.(term) do
|
||||
{:ok, %{"violations" => violations}} ->
|
||||
entry = %{term: term, claims: Enum.map(sentences, &Map.take(&1, ["sentence", "matched"])), violations: violations}
|
||||
stands_on =
|
||||
cond do
|
||||
witnesses >= 2 -> :sentences
|
||||
other_witnesses > 0 -> :other_checks
|
||||
frame_witnesses >= 2 -> :other_forms
|
||||
true -> nil
|
||||
end
|
||||
|
||||
{:cont,
|
||||
{:ok,
|
||||
%{
|
||||
acc
|
||||
| fired: acc.fired or violations != [],
|
||||
forms: Map.put(acc.forms, String.to_atom(form), entry),
|
||||
violations: acc.violations ++ violations
|
||||
}}}
|
||||
if stands_on == nil do
|
||||
# One witness does not stand (Devarim 19:15). Noted, not counted.
|
||||
noted = %{claims: claims, witnesses: 1}
|
||||
{:cont, {:ok, %{acc | noted: Map.put(acc.noted, String.to_atom(form), noted)}}}
|
||||
else
|
||||
term = "action(frame, by(#{atom(provenance)}), form(#{form}))"
|
||||
|
||||
{:error, reason} ->
|
||||
{:halt, {:error, :talmudic, to_string(reason)}}
|
||||
case halt_checker.(term) do
|
||||
{:ok, %{"violations" => violations}} ->
|
||||
entry = %{term: term, claims: claims, witnesses: witnesses, stands_on: stands_on, violations: violations}
|
||||
|
||||
other ->
|
||||
{:halt, {:error, :talmudic, "unexpected reply: #{inspect(other)}"}}
|
||||
{:cont,
|
||||
{:ok,
|
||||
%{
|
||||
acc
|
||||
| fired: acc.fired or violations != [],
|
||||
forms: Map.put(acc.forms, String.to_atom(form), entry),
|
||||
violations: acc.violations ++ violations
|
||||
}}}
|
||||
|
||||
{:error, reason} ->
|
||||
{:halt, {:error, :talmudic, to_string(reason)}}
|
||||
|
||||
other ->
|
||||
{:halt, {:error, :talmudic, "unexpected reply: #{inspect(other)}"}}
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -604,7 +604,8 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
||||
"could be checked, reaches for nothing it may not touch, does not claim to have checked " <>
|
||||
"itself, does not center itself, does not shut out the other side, and takes none of the forms " <>
|
||||
"a trained default takes (nothing called contested without a disputant, no self-certification, " <>
|
||||
"no agency moved onto the reader, no Jewish subject in borrowed categories or answered without its own sources)." <> grounding_note
|
||||
"no agency moved onto the reader, no Jewish subject in borrowed categories or answered without its own sources). " <>
|
||||
"A form seen in one sentence alone is noted under checks.frames.noted and not counted: one witness does not stand." <> grounding_note
|
||||
|
||||
:lo_tov ->
|
||||
"At least one check fired. The violations say which rule, and the checks say what it fired on."
|
||||
|
||||
@@ -178,7 +178,7 @@ defmodule VavPipeline.Doorpost do
|
||||
# changes; the update is a deliberate operator commit. A bare
|
||||
# hash-update commit (without a corresponding spec change in the
|
||||
# same commit) is itself a drift signal.
|
||||
@expected_hash "e5e45a2c8153f43a25baef358ae88839d86be7c075eb59e90dff26bf0875856c"
|
||||
@expected_hash "86a43d6b688780f787d09124fe429a26f96cbe6a7e36460d3b6e5b33f2b2d095"
|
||||
|
||||
@doc "Return the list of files that constitute the category-grade specification."
|
||||
@spec files() :: [String.t()]
|
||||
|
||||
@@ -169,6 +169,31 @@ defmodule VavPipeline.BedikahTest do
|
||||
%{examination(:plain) | "frames" => [%{"form" => "agency_displacement", "sentence" => "You pushed me there.", "matched" => "You pushed me"}]}
|
||||
end
|
||||
|
||||
defp examination(:frame_twice) do
|
||||
%{
|
||||
examination(:plain)
|
||||
| "frames" => [
|
||||
%{"form" => "agency_displacement", "sentence" => "You pushed me there.", "matched" => "You pushed me"},
|
||||
%{"form" => "agency_displacement", "sentence" => "You pushed me there.", "matched" => "pushed me"},
|
||||
%{"form" => "agency_displacement", "sentence" => "The conversational momentum carried it.", "matched" => "conversational momentum"}
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
defp examination(:frame_beside_authority) do
|
||||
%{examination(:self_authority) | "frames" => [%{"form" => "virtue_certification", "sentence" => "I want to be honest with you.", "matched" => "I want to be honest"}]}
|
||||
end
|
||||
|
||||
defp examination(:two_lone_forms) do
|
||||
%{
|
||||
examination(:plain)
|
||||
| "frames" => [
|
||||
%{"form" => "source_asymmetry", "sentence" => "Most scholars hold the text is late.", "matched" => "Most scholars"},
|
||||
%{"form" => "contested_laundering", "sentence" => "The dating is contested.", "matched" => "is contested"}
|
||||
]
|
||||
}
|
||||
end
|
||||
|
||||
defp examination(:plain) do
|
||||
%{
|
||||
"provenance" => "gpt",
|
||||
@@ -479,15 +504,45 @@ defmodule VavPipeline.BedikahTest do
|
||||
assert Map.keys(r.checks.frames.forms) |> Enum.sort() == [:contested_laundering, :virtue_certification]
|
||||
assert r.checks.frames.forms.contested_laundering.term == "action(frame, by(gpt), form(contested_laundering))"
|
||||
assert length(r.checks.frames.forms.contested_laundering.claims) == 2
|
||||
assert r.checks.frames.forms.contested_laundering.stands_on == :sentences
|
||||
assert r.checks.frames.forms.virtue_certification.stands_on == :other_forms
|
||||
assert length(r.violations) == 2 and Enum.all?(r.violations, &(&1 =~ "lo_taaseh_lekha"))
|
||||
refute r.checks.grounding.fired
|
||||
end
|
||||
|
||||
test "7. a form alone is enough to examine — not empty" do
|
||||
test "7. a form alone is enough to examine — not empty — but one witness does not stand (Devarim 19:15)" do
|
||||
assert {:ok, r} = Bedikah.examine("...", "gpt", "", opts(:only_frame))
|
||||
assert r.verdict == :tov
|
||||
assert r.violations == []
|
||||
refute r.checks.frames.fired
|
||||
assert r.checks.frames.forms == %{}
|
||||
assert %{agency_displacement: %{witnesses: 1, claims: [%{"sentence" => "You pushed me there."}]}} = r.checks.frames.noted
|
||||
end
|
||||
|
||||
test "7. two witnesses: the same form in two sentences stands; the same sentence twice is one witness" do
|
||||
assert {:ok, r} = Bedikah.examine("...", "gpt", "", opts(:frame_twice))
|
||||
assert r.verdict == :lo_tov
|
||||
assert [v] = r.violations
|
||||
assert v =~ "agency_displacement"
|
||||
assert r.checks.frames.forms.agency_displacement.witnesses == 2
|
||||
assert r.checks.frames.forms.agency_displacement.stands_on == :sentences
|
||||
assert r.checks.frames.noted == %{}
|
||||
end
|
||||
|
||||
test "7. one sentence beside another check's violation stands (corroboration)" do
|
||||
assert {:ok, r} = Bedikah.examine("...", "gpt", "", opts(:frame_beside_authority))
|
||||
assert r.verdict == :lo_tov
|
||||
assert r.checks.authority.fired
|
||||
assert r.checks.frames.forms.virtue_certification.stands_on == :other_checks
|
||||
assert Enum.any?(r.violations, &(&1 =~ "virtue_certification"))
|
||||
end
|
||||
|
||||
test "7. two lone forms are each other's witness" do
|
||||
assert {:ok, r} = Bedikah.examine("...", "gpt", "", opts(:two_lone_forms))
|
||||
assert r.verdict == :lo_tov
|
||||
assert Map.keys(r.checks.frames.forms) |> Enum.sort() == [:contested_laundering, :source_asymmetry]
|
||||
assert r.checks.frames.forms.source_asymmetry.stands_on == :other_forms
|
||||
assert length(r.violations) == 2
|
||||
end
|
||||
|
||||
test "4–6. a structural claim alone is enough to examine — not empty" do
|
||||
|
||||
Reference in new issue
Block a user