From 0ade2c949ee6c91754957df648f2979e0c3b136c Mon Sep 17 00:00:00 2001 From: Scott Karp Date: Tue, 13 Oct 2026 18:40:11 +0000 Subject: [PATCH] =?UTF-8?q?gate:=20the=20rebuke=20turn=20is=20not=20a=20gr?= =?UTF-8?q?ound=20=E2=80=94=20second=20examination=20uses=20the=20caller's?= =?UTF-8?q?=20sources?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The live round trip showed the second examination listing the gate's own rebuke as source user_2. The rebuke is the gate's turn, not something the caller gave the model; the second reply is now examined against the caller's original body (same sources and query as the first). Test pins it. Elixir gate 15/0. Co-Authored-By: Claude Fable 5.1 --- vav_pipeline/lib/vav_pipeline/gate.ex | 4 +++- vav_pipeline/test/gate_test.exs | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/vav_pipeline/lib/vav_pipeline/gate.ex b/vav_pipeline/lib/vav_pipeline/gate.ex index 2056e7c5..f9d1d9cf 100644 --- a/vav_pipeline/lib/vav_pipeline/gate.ex +++ b/vav_pipeline/lib/vav_pipeline/gate.ex @@ -47,7 +47,9 @@ defmodule VavPipeline.Gate do with :ok <- gather_call(), {:ok, 200, reply2} <- forward.(upstream, body2, key, extra), - {:ok, second} <- examine(upstream, body2, reply2, Keyword.put(examine_opts, :rebukes, first.bedikah_ref)) do + # Examined against what the CALLER gave (body, not body2): the + # rebuke is the gate's own turn and is not a ground. + {:ok, second} <- examine(upstream, body, reply2, Keyword.put(examine_opts, :rebukes, first.bedikah_ref)) do {:ok, deliver(upstream, reply2, second, first)} else {:ok, status, other} -> {:ok, %{status: status, reply: other, bedikah: nil, first: first, shorashim: nil}} diff --git a/vav_pipeline/test/gate_test.exs b/vav_pipeline/test/gate_test.exs index 501cb40b..b023cf49 100644 --- a/vav_pipeline/test/gate_test.exs +++ b/vav_pipeline/test/gate_test.exs @@ -207,6 +207,9 @@ defmodule VavPipeline.GateTest do assert pass.first.verdict == :lo_tov assert pass.bedikah.verdict == :tov assert pass.bedikah.rebukes == pass.first.bedikah_ref + # The rebuke turn is the gate's, not the caller's: not a source for the second examination. + assert Enum.map(pass.bedikah.sources, & &1.id) == ["system", "user_1", "user_2"] + assert pass.bedikah.sources == pass.first.sources [%{"text" => text}] = pass.reply["content"] assert String.starts_with?(text, "CLEAN:") assert text =~ "— shorashim #{pass.bedikah.bedikah_ref}: tov (after rebuke of #{pass.first.bedikah_ref}: lo_tov)"