gate: tablet 52 — the fringe quoted couplings as sentences on the first real reply

checks.grounding.ungrounded holds coupling strings ("coupled(claim(1),
not_in_sources)"), not sentences; the fringe called Access.get/3 on a
string and the first real reply from Claude through /gate/anthropic
answered 500 CHATAT_UNEXPECTED (after recording its bedikah). The
sentence is now looked up by claim index in the check's claims; a test
produces an ungrounded claim. Broken Tablets tablet 52. Elixir 593/0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Scott KarpandClaude Fable 5.1 committed 2026-10-13 18:35:39 +00:00
1 parent 5c63273dba
commit 2b8eaced27
3 files changed
+60 -3

No files matched your search

+18
View File
@@ -54,3 +54,21 @@ interpretations still ground in L1 alone.
The first tablets are in the git history before `tablet 49`. The The first tablets are in the git history before `tablet 49`. The
difference between the two is the correction. difference between the two is the correction.
## Tablet 52 — the first real reply through the gate (2026-10-13)
The gate (bishe'arecha §I) passed every test — fourteen of them, with a
local model double and examination doubles — and crashed on the first
real reply from Claude. The fringe quotes the sentence each rule fired
on; for the grounding rules it read `checks.grounding.ungrounded`, which
holds coupling strings (`coupled(claim(1), not_in_sources)`), not
sentences. No double had ever produced an ungrounded claim, so the path
through `Access.get/3` on a string was never taken. The shape was in the
Tamid contract all along ("ungrounded": [...]); the builder wrote the
reader from memory of what it should hold.
Fixed: the claim's sentence is looked up by index in the check's
`claims`; a test now produces an ungrounded claim. The lesson is the one
from Day 6 and tablets 41 and 50 again, one layer out: a double shaped
by the builder tests the builder's picture of the wire. The first real
message is the test. Run it before calling the gate built.
+31 -3
View File
@@ -191,6 +191,8 @@ defmodule VavPipeline.Gate.Shape do
end end
defp sentences_for(checks, rule) do defp sentences_for(checks, rule) do
grounding = checks[:grounding] || %{}
claims_of = fn claims_of = fn
%{claims: claims} when is_list(claims) -> Enum.map(claims, &(&1["sentence"] || &1[:sentence])) %{claims: claims} when is_list(claims) -> Enum.map(claims, &(&1["sentence"] || &1[:sentence]))
_ -> [] _ -> []
@@ -198,8 +200,8 @@ defmodule VavPipeline.Gate.Shape do
case rule do case rule do
"avodah_zarah" -> claims_of.(checks[:authority]) "avodah_zarah" -> claims_of.(checks[:authority])
"golden_calf" -> ungrounded_sentences(checks[:grounding]) "golden_calf" -> ungrounded_sentences(grounding)
"self_grounding" -> ungrounded_sentences(checks[:grounding]) "self_grounding" -> ungrounded_sentences(grounding)
"shfichut_damim" -> action_sentences(checks[:actions], "shfichut_damim") "shfichut_damim" -> action_sentences(checks[:actions], "shfichut_damim")
"gilui_arayot" -> action_sentences(checks[:actions], "gilui_arayot") "gilui_arayot" -> action_sentences(checks[:actions], "gilui_arayot")
"parah_adumah" -> claims_of.(checks[:self_validation]) "parah_adumah" -> claims_of.(checks[:self_validation])
@@ -211,7 +213,33 @@ defmodule VavPipeline.Gate.Shape do
|> Enum.reject(&is_nil/1) |> Enum.reject(&is_nil/1)
end end
defp ungrounded_sentences(%{ungrounded: list}) when is_list(list), do: Enum.map(list, &(&1[:sentence] || &1["sentence"])) # The grounding check's `ungrounded` are coupling strings —
# "coupled(claim(3), not_in_sources)" — not sentences; the claim's
# sentence is in the check's `claims` by index. (Tablet 52: the first
# real reply through the gate found this; no test double had an
# ungrounded claim.)
defp ungrounded_sentences(%{ungrounded: list} = grounding) when is_list(list) do
claims = grounding[:claims] || []
Enum.map(list, fn
coupling when is_binary(coupling) ->
case Regex.run(~r/claim\((\d+)\)/, coupling) do
[_, n] ->
i = String.to_integer(n)
Enum.find_value(claims, coupling, fn c -> if (c[:index] || c["index"]) == i, do: c[:sentence] || c["sentence"] end)
_ ->
coupling
end
%{} = c ->
c[:sentence] || c["sentence"]
other ->
to_string(other)
end)
end
defp ungrounded_sentences(_), do: [] defp ungrounded_sentences(_), do: []
defp action_sentences(%{actions: actions}, rule) when is_list(actions) do defp action_sentences(%{actions: actions}, rule) when is_list(actions) do
+11
View File
@@ -191,6 +191,17 @@ defmodule VavPipeline.GateTest do
refute Map.has_key?(pass.shorashim, :rebuked) refute Map.has_key?(pass.shorashim, :rebuked)
end end
test "tablet 52: an ungrounded claim's sentence reaches the fringe (the grounding check lists couplings, not sentences)" do
forward = fn _, _, _, _ -> {:ok, 200, %{"model" => "claude-test", "content" => [%{"type" => "text", "text" => "Revenue rose 9% to 14M."}]}} end
examiner = fn _o, _p, _q, _s -> {:ok, %{plain() | "sources" => [%{"id" => "user_1", "length" => 40}], "claims" => [%{"index" => 1, "sentence" => "Revenue rose 9% to 14M.", "anchors" => [], "self_reference" => nil, "hedged" => false, "invokes" => []}]}} end
checker = fn ref, _c, _trace, _g -> {:ok, %{"status" => "halt", "violations" => ["halt(golden_calf,#{ref},uncoupled(claim(1)),...)"]}} end
assert {:ok, pass} = Gate.pass(:anthropic, body(), "sk-good", opts(forward: forward, examiner: examiner, interpretation_checker: checker))
assert pass.bedikah.verdict == :lo_tov
[%{"text" => text}] = pass.reply["content"]
assert text =~ "golden_calf (Shemot 32:4): \"Revenue rose 9% to 14M.\""
assert Shape.rebuke_text(pass.bedikah, pass.shorashim.anchors) =~ "golden_calf (Shemot 32:4)"
end
test "rebuke once: the second reply is examined, linked to the first, and is the one delivered" do test "rebuke once: the second reply is examined, linked to the first, and is the one delivered" do
assert {:ok, pass} = Gate.pass(:anthropic, body(), "sk-good", opts(rebuke: :once)) assert {:ok, pass} = Gate.pass(:anthropic, body(), "sk-good", opts(rebuke: :once))
assert pass.first.verdict == :lo_tov assert pass.first.verdict == :lo_tov