sugya, step 3: the case behind each threshold is carried on every verdict
specs/sugya.md §IV "carried on the verdict", §V step 3. Sugya.for_verdict/1
renders, for every rule that fired and every form that was noted: kind,
verse, precedent, the dissents and exceptions — each with `applied`,
read from the record and never guessed: the single witness noted (and
for which forms), the hedged claims left out of the trace, grounding
not assessed for want of ground, a forged fringe standing on one
witness. A dissent the record cannot speak to is carried applied:
false — considered, and the rule's verse decided. The minority is on
every record (Eduyot 1:5–6): to be relied on later, and to be located.
Carried as `sugya` on the bedikah response, the pair's two sides, and
the gate's `bikoret` object (pass and stream). The fringe is unchanged
— it is for the reader, who asks for the sugya by reading the record.
Tamid §1.1: the `sugya` field in the response and the paragraph "Every
rule carries its sugya"; Doorpost pin → 658005c9…. Elixir 664/0
(sugya_verdict_test: clean → {}; noted apology → two-witness dissent
applied for that form; forged fringe → the mark exception applied;
golden calf with and without a hedged claim; a rule the record cannot
speak to → considered, applied false).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
1ad2c3ec40
commit
dc6316f1d7
7 files changed
+149
-1
No files matched your search
@@ -243,6 +243,12 @@ Response (200):
|
|||||||
"verdict": "tov" | "lo_tov" | "empty",
|
"verdict": "tov" | "lo_tov" | "empty",
|
||||||
"violations": ["halt(avodah_zarah, ...)", ...], # the Prolog halt terms, verbatim
|
"violations": ["halt(avodah_zarah, ...)", ...], # the Prolog halt terms, verbatim
|
||||||
"anchors": { "avodah_zarah": "Shemot 20:3", ... }, # the verse of each rule that fired
|
"anchors": { "avodah_zarah": "Shemot 20:3", ... }, # the verse of each rule that fired
|
||||||
|
"sugya": { # the case behind each threshold (sugya.md)
|
||||||
|
"<rule>": { "kind": "deed|mark|word|measure", "verse": "...", "precedent": "tablet(49)",
|
||||||
|
"fired": bool, "noted": ["<form>", ...],
|
||||||
|
"dissent": [{"reading": "...", "verse": "...", "applied": bool, "form": ...}],
|
||||||
|
"exception": [{"condition": "...", "verse": "...", "applied": bool}] }
|
||||||
|
}, # one entry per rule fired or form noted
|
||||||
"checks": {
|
"checks": {
|
||||||
"authority": { "fired": bool, "claims": [...], "violations": [...] },
|
"authority": { "fired": bool, "claims": [...], "violations": [...] },
|
||||||
"grounding": { "fired": bool, "assessed": bool, "reason": "…" (when not assessed),
|
"grounding": { "fired": bool, "assessed": bool, "reason": "…" (when not assessed),
|
||||||
@@ -306,6 +312,18 @@ and at the gate `rebukes` — the ref of the examination this one answers;
|
|||||||
`mesorah` — the citations made, each found or not.
|
`mesorah` — the citations made, each found or not.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Every rule carries its sugya** (`sugya.md`). Beside the verse a rule
|
||||||
|
stands on, the verdict carries the case it was cut from, which of
|
||||||
|
Torah's procedures reads it — a deed by two witnesses, a mark by
|
||||||
|
inspection, a word by what follows — the reading that would acquit, and
|
||||||
|
what the rule does not reach; `applied: true` marks the dissent or
|
||||||
|
exception the record shows held (the single witness noted, the hedged
|
||||||
|
claim left out, no ground given, the forged fringe on one witness). A
|
||||||
|
dissent the record cannot speak to is carried `applied: false`:
|
||||||
|
considered, and the rule's verse decided. The minority is on every
|
||||||
|
record (Eduyot 1:5–6). Nothing here learns; a new dissent is a commit
|
||||||
|
that moves the pin.
|
||||||
|
|
||||||
**Every rule cites its verse** (`bishearecha.md` §X; Devarim 4:2).
|
**Every rule cites its verse** (`bishearecha.md` §X; Devarim 4:2).
|
||||||
`talmudic_engine/src/halt/anchors.pl` declares `rule_anchor(<halt name>,
|
`talmudic_engine/src/halt/anchors.pl` declares `rule_anchor(<halt name>,
|
||||||
verse(<book>, <ch>, <v>))` for every halt name the rule modules can
|
verse(<book>, <ch>, <v>))` for every halt name the rule modules can
|
||||||
|
|||||||
@@ -941,6 +941,8 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
|||||||
verdict: Atom.to_string(result.verdict),
|
verdict: Atom.to_string(result.verdict),
|
||||||
violations: result.violations,
|
violations: result.violations,
|
||||||
anchors: VavPipeline.Anchors.for_violations(result.violations),
|
anchors: VavPipeline.Anchors.for_violations(result.violations),
|
||||||
|
# The case behind each threshold that fired or was noted (sugya.md §IV).
|
||||||
|
sugya: VavPipeline.Sugya.for_verdict(result),
|
||||||
checks: result.checks,
|
checks: result.checks,
|
||||||
examination: %{
|
examination: %{
|
||||||
vital_content: result.examination["vital_content"],
|
vital_content: result.examination["vital_content"],
|
||||||
@@ -1023,6 +1025,8 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
|||||||
verdict: Atom.to_string(result.verdict),
|
verdict: Atom.to_string(result.verdict),
|
||||||
violations: result.violations,
|
violations: result.violations,
|
||||||
anchors: VavPipeline.Anchors.for_violations(result.violations),
|
anchors: VavPipeline.Anchors.for_violations(result.violations),
|
||||||
|
# The case behind each threshold that fired or was noted (sugya.md §IV).
|
||||||
|
sugya: VavPipeline.Sugya.for_verdict(result),
|
||||||
a: result.a,
|
a: result.a,
|
||||||
b: result.b,
|
b: result.b,
|
||||||
difference: result.difference,
|
difference: result.difference,
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ defmodule VavPipeline.Doorpost do
|
|||||||
# changes; the update is a deliberate operator commit. A bare
|
# changes; the update is a deliberate operator commit. A bare
|
||||||
# hash-update commit (without a corresponding spec change in the
|
# hash-update commit (without a corresponding spec change in the
|
||||||
# same commit) is itself a drift signal.
|
# same commit) is itself a drift signal.
|
||||||
@expected_hash "cb2f31358051acc19c36bb8dfa0a179a7d4845ac6acac7d8e2b7b1e17150b0c2"
|
@expected_hash "658005c9323391e8c198c0cf23f91af0a2fdbdb20cac204eb60b58ac0c0bb318"
|
||||||
|
|
||||||
@doc "Return the list of files that constitute the category-grade specification."
|
@doc "Return the list of files that constitute the category-grade specification."
|
||||||
@spec files() :: [String.t()]
|
@spec files() :: [String.t()]
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ defmodule VavPipeline.Gate do
|
|||||||
violations: result.violations,
|
violations: result.violations,
|
||||||
anchors: anchors,
|
anchors: anchors,
|
||||||
fired: Shape.fired(result, anchors),
|
fired: Shape.fired(result, anchors),
|
||||||
|
sugya: VavPipeline.Sugya.for_verdict(result),
|
||||||
checks: result.checks,
|
checks: result.checks,
|
||||||
sources: result.sources,
|
sources: result.sources,
|
||||||
model: Shape.reply_model(upstream, reply)
|
model: Shape.reply_model(upstream, reply)
|
||||||
|
|||||||
@@ -217,6 +217,7 @@ defmodule VavPipeline.Gate.Stream do
|
|||||||
violations: result.violations,
|
violations: result.violations,
|
||||||
anchors: anchors,
|
anchors: anchors,
|
||||||
fired: Shape.fired(result, anchors),
|
fired: Shape.fired(result, anchors),
|
||||||
|
sugya: VavPipeline.Sugya.for_verdict(result),
|
||||||
sources: result.sources,
|
sources: result.sources,
|
||||||
model: state.model,
|
model: state.model,
|
||||||
streamed: true
|
streamed: true
|
||||||
|
|||||||
@@ -198,6 +198,76 @@ defmodule VavPipeline.Sugya do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# The sugya on a verdict (sugya.md §IV, "carried on the verdict")
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
The sugya a verdict carries: one entry per rule that fired and per form
|
||||||
|
that was noted — kind, verse, precedent, the dissents with `applied`
|
||||||
|
marking the one that held, the exceptions with `applied` likewise.
|
||||||
|
`applied` is read from the record, never guessed: the single witness
|
||||||
|
noted (a form in `checks.frames.noted`), the hedged claims left out of
|
||||||
|
the trace, grounding not assessed for want of ground, a forged fringe
|
||||||
|
standing on one witness. A dissent the record cannot speak to is
|
||||||
|
carried with `applied: false` — considered, and the rule's verse
|
||||||
|
decided. The minority is thus on the record for every verdict (Eduyot
|
||||||
|
1:5–6): to be relied on later, and to be located.
|
||||||
|
"""
|
||||||
|
@spec for_verdict(map()) :: map()
|
||||||
|
def for_verdict(result) when is_map(result) do
|
||||||
|
checks = Map.get(result, :checks) || %{}
|
||||||
|
violations = Map.get(result, :violations) || []
|
||||||
|
fired_rules = violations |> Enum.flat_map(&rule_of/1) |> Enum.uniq()
|
||||||
|
frames = Map.get(checks, :frames) || %{}
|
||||||
|
noted = (Map.get(frames, :noted) || %{}) |> Map.keys() |> Enum.map(&to_string/1)
|
||||||
|
forms = Map.get(frames, :forms) || %{}
|
||||||
|
forged_on_one = Enum.any?(forms, fn {_f, e} -> Map.get(e, :stands_on) == :forgery end)
|
||||||
|
grounding = Map.get(checks, :grounding) || %{}
|
||||||
|
claims = get_in(result, [:examination, "claims"]) || []
|
||||||
|
hedged_out = Enum.any?(claims, &(&1["hedged"] == true))
|
||||||
|
|
||||||
|
rules = Enum.uniq(fired_rules ++ if(noted != [], do: ["lo_taaseh_lekha"], else: []))
|
||||||
|
|
||||||
|
Map.new(rules, fn rule ->
|
||||||
|
base = for_rule(rule) || %{rule: rule, kind: nil, verse: nil, precedent: nil, dissent: [], exception: []}
|
||||||
|
|
||||||
|
dissent =
|
||||||
|
Enum.map(base.dissent, fn d ->
|
||||||
|
applied =
|
||||||
|
case {rule, d.reading, d.form} do
|
||||||
|
{"lo_taaseh_lekha", "single_witness_noted", _} -> noted != []
|
||||||
|
{"golden_calf", "hedged", _} -> hedged_out
|
||||||
|
_ -> false
|
||||||
|
end
|
||||||
|
|
||||||
|
d |> Map.put(:applied, applied) |> then(fn m -> if rule == "lo_taaseh_lekha" and d.reading == "single_witness_noted", do: Map.put(m, :forms, noted), else: m end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
exception =
|
||||||
|
Enum.map(base.exception, fn e ->
|
||||||
|
applied =
|
||||||
|
case {rule, e.condition} do
|
||||||
|
{"lo_taaseh_lekha", "single_witness(forged_fringe)"} -> forged_on_one
|
||||||
|
{"golden_calf", "no_ground_given"} -> Map.get(grounding, :assessed) == false and (Map.get(grounding, :reason) || "") =~ "no sources given"
|
||||||
|
{"golden_calf", "hedged"} -> hedged_out
|
||||||
|
_ -> false
|
||||||
|
end
|
||||||
|
|
||||||
|
Map.put(e, :applied, applied)
|
||||||
|
end)
|
||||||
|
|
||||||
|
{rule, %{base | dissent: dissent, exception: exception} |> Map.put(:fired, rule in fired_rules) |> Map.put(:noted, if(rule == "lo_taaseh_lekha", do: noted, else: []))}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp rule_of(violation) do
|
||||||
|
case Regex.run(~r/^halt\(\s*(\w+)\s*,/, to_string(violation)) do
|
||||||
|
[_, rule] -> [rule]
|
||||||
|
_ -> []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
@doc "A verse as a citation: \"Devarim 19:15\"."
|
@doc "A verse as a citation: \"Devarim 19:15\"."
|
||||||
@spec cite(verse()) :: String.t()
|
@spec cite(verse()) :: String.t()
|
||||||
def cite(%{book: b, chapter: c, verse: v}), do: "#{String.capitalize(b)} #{c}:#{v}"
|
def cite(%{book: b, chapter: c, verse: v}), do: "#{String.capitalize(b)} #{c}:#{v}"
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
defmodule VavPipeline.SugyaVerdictTest do
|
||||||
|
@moduledoc "The sugya on a verdict (sugya.md §IV, step 3): applied is read from the record, never guessed."
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
alias VavPipeline.Sugya
|
||||||
|
|
||||||
|
defp result(overrides) do
|
||||||
|
Map.merge(%{verdict: :tov, violations: [], checks: %{}, examination: %{"claims" => []}}, overrides)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "a clean verdict carries no sugya" do
|
||||||
|
assert Sugya.for_verdict(result(%{})) == %{}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "a noted form carries the two-witness dissent, applied, with the forms it held for" do
|
||||||
|
r = result(%{checks: %{frames: %{fired: false, forms: %{}, noted: %{apology_without_mechanism: %{claims: [], witnesses: 1}}, violations: []}}})
|
||||||
|
s = Sugya.for_verdict(r)
|
||||||
|
assert Map.keys(s) == ["lo_taaseh_lekha"]
|
||||||
|
e = s["lo_taaseh_lekha"]
|
||||||
|
assert e.kind == "deed" and e.verse == "Devarim 19:15"
|
||||||
|
assert e.fired == false and e.noted == ["apology_without_mechanism"]
|
||||||
|
d = Enum.find(e.dissent, &(&1.reading == "single_witness_noted"))
|
||||||
|
assert d.applied == true and d.forms == ["apology_without_mechanism"] and d.verse == "Devarim 19:15"
|
||||||
|
# the exception for the forged fringe did not apply: nothing stood on one witness
|
||||||
|
assert Enum.find(e.exception, &(&1.condition =~ "forged_fringe")).applied == false
|
||||||
|
end
|
||||||
|
|
||||||
|
test "a forged fringe standing on one witness carries the mark exception, applied" do
|
||||||
|
r = result(%{verdict: :lo_tov,
|
||||||
|
violations: ["halt(lo_taaseh_lekha,action(frame,by(claude),form(forged_fringe)),forged_fringe,'…')"],
|
||||||
|
checks: %{frames: %{fired: true, forms: %{forged_fringe: %{stands_on: :forgery, witnesses: 1, claims: [], violations: ["x"]}}, noted: %{}, violations: ["x"]}}})
|
||||||
|
e = Sugya.for_verdict(r)["lo_taaseh_lekha"]
|
||||||
|
assert e.fired == true
|
||||||
|
assert Enum.find(e.exception, &(&1.condition == "single_witness(forged_fringe)")) |> Map.fetch!(:applied) == true
|
||||||
|
assert Enum.find(e.dissent, &(&1.reading == "single_witness_noted")).applied == false
|
||||||
|
end
|
||||||
|
|
||||||
|
test "a golden calf beside a hedged claim carries the hedged dissent applied; without hedging, not" do
|
||||||
|
base = %{verdict: :lo_tov, violations: ["halt(golden_calf,interpretation(x),golden_calf,'…')"], checks: %{grounding: %{assessed: true, fired: true}}}
|
||||||
|
with_hedge = Sugya.for_verdict(result(Map.put(base, :examination, %{"claims" => [%{"hedged" => true}, %{"hedged" => false}]})))
|
||||||
|
assert with_hedge["golden_calf"].kind == "word" and with_hedge["golden_calf"].verse == "Devarim 18:22"
|
||||||
|
assert Enum.find(with_hedge["golden_calf"].dissent, &(&1.reading == "hedged")).applied == true
|
||||||
|
without = Sugya.for_verdict(result(Map.put(base, :examination, %{"claims" => [%{"hedged" => false}]})))
|
||||||
|
assert Enum.find(without["golden_calf"].dissent, &(&1.reading == "hedged")).applied == false
|
||||||
|
end
|
||||||
|
|
||||||
|
test "a rule the record cannot speak to carries its dissent considered, applied false" do
|
||||||
|
r = result(%{verdict: :lo_tov, violations: ["halt(parah_adumah,action(self_validate,by(claude),target(self)),claude,'…')"]})
|
||||||
|
e = Sugya.for_verdict(r)["parah_adumah"]
|
||||||
|
assert e.kind == "mark" and e.verse == "Vayikra 13:3"
|
||||||
|
assert e.precedent == "specimens(self_validation)"
|
||||||
|
assert [%{reading: "validator_named_is_not_the_speaker", applied: false, verse: "Bamidbar 19:7"}] = Enum.map(e.dissent, &Map.take(&1, [:reading, :applied, :verse]))
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in new issue
Block a user