the name: Bikoret — code, contracts, images
Headers X-Bikoret-Key / -Rebuke / -Verdict / -Bedikah; the `bikoret` object and the "— bikoret …" fringe on a gate reply; environment variables BIKORET_*; the image user and paths (/home/bikoret, /tmp/bikoret, /var/lib/bikoret/manna, /etc/bikoret/secrets, /opt/bikoret/spec); the tmp-bikoret pod volume; local databases bikoret_dev/_test. Kubernetes resource names, the shorashim_app role and the domain are unchanged (Tamid §1.1, "the names that still carry the old word"). Doorpost c963c4fe…. Elixir 604/0, L3 10/0, korban 295, Prolog bedikah 44/44. Gitea repo renamed heaviness510/bikoret (old URL redirects). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
017a9b89d4
commit
c0d0555aed
46 files changed
+189
-189
No files matched your search
@@ -3,7 +3,7 @@ import Config
|
||||
# L1 mount point — relative path for dev, absolute for production
|
||||
# Construction spec §4.4: l1_mount_point: "/mnt/torah"
|
||||
config :vav_pipeline,
|
||||
# Dev: relative to project root (run from shorashim/)
|
||||
# Dev: relative to project root (run from bikoret/)
|
||||
l1_mount_point: "l1",
|
||||
mesorah_mount_point: "mesorah",
|
||||
# Manna provision file
|
||||
@@ -17,8 +17,8 @@ config :vav_pipeline,
|
||||
shoresh_engine_binary: "shoresh-engine",
|
||||
shoresh_engine_cwd: nil,
|
||||
# Talmudic Engine (Prolog) — Unix domain socket path
|
||||
talmudic_socket_path: "/tmp/shorashim/talmudic.sock",
|
||||
korban_socket_path: "/tmp/shorashim/korban.sock",
|
||||
talmudic_socket_path: "/tmp/bikoret/talmudic.sock",
|
||||
korban_socket_path: "/tmp/bikoret/korban.sock",
|
||||
# Courtyard / chatzer keys (BigdeiKodesh.Gate). nil → the gate is shut.
|
||||
# Construction §4.6: a file, never an environment variable.
|
||||
api_keys_file: nil,
|
||||
@@ -38,7 +38,7 @@ config :vav_pipeline,
|
||||
config :vav_pipeline, ecto_repos: [VavPipeline.Repo]
|
||||
|
||||
config :vav_pipeline, VavPipeline.Repo,
|
||||
database: "shorashim_dev",
|
||||
database: "bikoret_dev",
|
||||
hostname: "localhost",
|
||||
pool_size: 10
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ config :vav_pipeline,
|
||||
# SPEC_INTEGRITY_FAILED on every boot, and the chatzotzrot that fires
|
||||
# is a false alarm — which is worse than no witness at all.
|
||||
# Read at COMPILE time via Application.compile_env/3.
|
||||
doorpost_repo_root: "/opt/shorashim/spec",
|
||||
manna_provision_file: "/var/lib/shorashim/manna/today.json",
|
||||
doorpost_repo_root: "/opt/bikoret/spec",
|
||||
manna_provision_file: "/var/lib/bikoret/manna/today.json",
|
||||
cycle_boundary_check_interval_ms: 60_000,
|
||||
shema_context_cache_ttl_ms: 0,
|
||||
http_port: 4000
|
||||
|
||||
@@ -26,13 +26,13 @@ if config_env() == :prod do
|
||||
l1_mount_point: System.get_env("L1_MOUNT_POINT") || "/mnt/torah",
|
||||
mesorah_mount_point: System.get_env("MESORAH_MOUNT_POINT") || "/mnt/mesorah",
|
||||
manna_provision_file:
|
||||
System.get_env("MANNA_PROVISION_FILE") || "/var/lib/shorashim/manna/today.json",
|
||||
System.get_env("MANNA_PROVISION_FILE") || "/var/lib/bikoret/manna/today.json",
|
||||
talmudic_socket_path:
|
||||
System.get_env("TALMUDIC_SOCKET_PATH") || "/tmp/shorashim/talmudic.sock",
|
||||
System.get_env("TALMUDIC_SOCKET_PATH") || "/tmp/bikoret/talmudic.sock",
|
||||
korban_socket_path:
|
||||
System.get_env("KORBAN_SOCKET_PATH") || "/tmp/shorashim/korban.sock",
|
||||
System.get_env("KORBAN_SOCKET_PATH") || "/tmp/bikoret/korban.sock",
|
||||
# The keys themselves are in the file (a mounted Secret), not in env.
|
||||
api_keys_file: System.get_env("API_KEYS_FILE") || "/etc/shorashim/secrets/api_keys",
|
||||
api_keys_file: System.get_env("API_KEYS_FILE") || "/etc/bikoret/secrets/api_keys",
|
||||
# The ingress controller's network: only from there is X-Real-IP the
|
||||
# caller's address (BigdeiKodesh.Mishmar.peer/1). Comma-separated CIDRs.
|
||||
trusted_proxies:
|
||||
|
||||
@@ -20,17 +20,17 @@ config :vav_pipeline,
|
||||
|
||||
# L3 test database — separate from dev, uses sandbox pool
|
||||
# Repo start disabled by default — L3 tests need PostgreSQL running locally
|
||||
# Enable: SHORASHIM_L3=1 mix test --include l3
|
||||
# Enable: BIKORET_L3=1 mix test --include l3
|
||||
#
|
||||
# Credentials come from the environment (tablet 44: without a password
|
||||
# the SCRAM handshake raised KeyError in every connection, the pool hit
|
||||
# its restart intensity, and the whole application went down silently
|
||||
# ~30 ms after test_helper — no L3 test ever ran).
|
||||
config :vav_pipeline, VavPipeline.Repo,
|
||||
database: "shorashim_test#{System.get_env("MIX_TEST_PARTITION")}",
|
||||
hostname: System.get_env("SHORASHIM_L3_HOST") || "localhost",
|
||||
username: System.get_env("SHORASHIM_L3_USER") || "postgres",
|
||||
password: System.get_env("SHORASHIM_L3_PASSWORD") || "postgres",
|
||||
database: "bikoret_test#{System.get_env("MIX_TEST_PARTITION")}",
|
||||
hostname: System.get_env("BIKORET_L3_HOST") || "localhost",
|
||||
username: System.get_env("BIKORET_L3_USER") || "postgres",
|
||||
password: System.get_env("BIKORET_L3_PASSWORD") || "postgres",
|
||||
pool: Ecto.Adapters.SQL.Sandbox,
|
||||
pool_size: System.schedulers_online() * 2,
|
||||
start: System.get_env("SHORASHIM_L3") != nil
|
||||
start: System.get_env("BIKORET_L3") != nil
|
||||
@@ -28,8 +28,8 @@ defmodule VavPipeline.Application do
|
||||
def start(_type, _args) do
|
||||
shoresh_binary = Application.get_env(:vav_pipeline, :shoresh_engine_binary, "shoresh-engine")
|
||||
shoresh_cwd = Application.get_env(:vav_pipeline, :shoresh_engine_cwd, nil)
|
||||
talmudic_socket = Application.get_env(:vav_pipeline, :talmudic_socket_path, "/tmp/shorashim/talmudic.sock")
|
||||
korban_socket = Application.get_env(:vav_pipeline, :korban_socket_path, "/tmp/shorashim/korban.sock")
|
||||
talmudic_socket = Application.get_env(:vav_pipeline, :talmudic_socket_path, "/tmp/bikoret/talmudic.sock")
|
||||
korban_socket = Application.get_env(:vav_pipeline, :korban_socket_path, "/tmp/bikoret/korban.sock")
|
||||
|
||||
children =
|
||||
[
|
||||
|
||||
@@ -9,7 +9,7 @@ defmodule VavPipeline.AzazelIngest do
|
||||
reads each file, calls L3.Store.record_disposal/1, and on success
|
||||
shreds the source file.
|
||||
|
||||
The pattern matches Shorashim's other cross-language file bridges
|
||||
The pattern matches Bikoret's other cross-language file bridges
|
||||
(the manna provision file). Recoverable: if either the Python side
|
||||
or this GenServer crashes mid-write, the file remains and is
|
||||
re-processed on the next poll.
|
||||
@@ -48,7 +48,7 @@ defmodule VavPipeline.AzazelIngest do
|
||||
alias VavPipeline.{Chatzotzrot, L3.Store}
|
||||
|
||||
@default_poll_interval_ms 5_000
|
||||
@default_pending_dir "/tmp/shorashim/azazel/pending_l3"
|
||||
@default_pending_dir "/tmp/bikoret/azazel/pending_l3"
|
||||
|
||||
# ============================================================
|
||||
# Client API
|
||||
@@ -57,7 +57,7 @@ defmodule VavPipeline.AzazelIngest do
|
||||
@doc """
|
||||
Start the AzazelIngest GenServer. Options:
|
||||
- :pending_dir — directory to watch (default
|
||||
/tmp/shorashim/azazel/pending_l3)
|
||||
/tmp/bikoret/azazel/pending_l3)
|
||||
- :poll_interval_ms — milliseconds between polls (default 5000)
|
||||
- :name — process name (default __MODULE__)
|
||||
- :recorder — function used to write the L3 record;
|
||||
|
||||
@@ -86,13 +86,13 @@ defmodule VavPipeline.BigdeiKodesh.Gate do
|
||||
# ------------------------------------------------------------
|
||||
|
||||
@doc """
|
||||
The caller's key: `X-Shorashim-Key` when present (at the gate of
|
||||
The caller's key: `X-Bikoret-Key` when present (at the gate of
|
||||
§3.10 the Authorization header may be the caller's upstream key),
|
||||
otherwise `Authorization: Bearer`.
|
||||
"""
|
||||
@spec bearer(Plug.Conn.t()) :: {:ok, String.t()} | {:error, :no_header}
|
||||
def bearer(conn) do
|
||||
case {Plug.Conn.get_req_header(conn, "x-shorashim-key"), Plug.Conn.get_req_header(conn, "authorization")} do
|
||||
case {Plug.Conn.get_req_header(conn, "x-bikoret-key"), Plug.Conn.get_req_header(conn, "authorization")} do
|
||||
{[key], _} when key != "" -> {:ok, String.trim(key)}
|
||||
{_, ["Bearer " <> key]} when key != "" -> {:ok, String.trim(key)}
|
||||
_ -> {:error, :no_header}
|
||||
|
||||
@@ -52,7 +52,7 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
||||
case question do
|
||||
nil ->
|
||||
send_json(conn, 200, %{
|
||||
message: "Shorashim — Torah as AI specification",
|
||||
message: "Bikoret — Torah as AI specification",
|
||||
usage: "POST /peah/ask with {\"question\": \"your question\"}",
|
||||
note: "No authentication required. No tracking. The stranger is safe to approach."
|
||||
})
|
||||
@@ -321,7 +321,7 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
||||
|
||||
# === KODESH — Doorpost-text identity (vehaya.md §3.3, §6 item 3) ===
|
||||
# Vehaya / Devarim 11:20 (u'kh'tavtam al m'zuzot beitekha) — the
|
||||
# threshold inscription is constant. Two Shorashim deployments
|
||||
# threshold inscription is constant. Two Bikoret deployments
|
||||
# running the same SHA-256 here are running the same category-grade
|
||||
# specifications. Different SHA-256 = drift = breach. Visible.
|
||||
#
|
||||
@@ -708,7 +708,7 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
||||
with {:ok, key} <- upstream_key(conn, upstream),
|
||||
:ok <- gate_body_ok(body) do
|
||||
rebuke =
|
||||
case get_req_header(conn, "x-shorashim-rebuke") do
|
||||
case get_req_header(conn, "x-bikoret-rebuke") do
|
||||
["once"] -> :once
|
||||
_ -> :none
|
||||
end
|
||||
@@ -728,19 +728,19 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
||||
end
|
||||
|
||||
# The caller's upstream key: x-api-key (Anthropic), or Authorization: Bearer
|
||||
# when X-Shorashim-Key carries the courtyard key (OpenAI).
|
||||
# when X-Bikoret-Key carries the courtyard key (OpenAI).
|
||||
defp upstream_key(conn, :anthropic) do
|
||||
case get_req_header(conn, "x-api-key") do
|
||||
[key] when key != "" -> {:ok, key}
|
||||
_ -> {:error, "Missing 'x-api-key': the caller's own Anthropic key", "Send the Anthropic key in x-api-key and the courtyard key in Authorization: Bearer (or X-Shorashim-Key)"}
|
||||
_ -> {:error, "Missing 'x-api-key': the caller's own Anthropic key", "Send the Anthropic key in x-api-key and the courtyard key in Authorization: Bearer (or X-Bikoret-Key)"}
|
||||
end
|
||||
end
|
||||
|
||||
defp upstream_key(conn, :openai) do
|
||||
case {get_req_header(conn, "x-shorashim-key"), get_req_header(conn, "authorization"), get_req_header(conn, "x-upstream-key")} do
|
||||
case {get_req_header(conn, "x-bikoret-key"), get_req_header(conn, "authorization"), get_req_header(conn, "x-upstream-key")} do
|
||||
{_, _, [key]} when key != "" -> {:ok, key}
|
||||
{[_], ["Bearer " <> key], _} when key != "" -> {:ok, key}
|
||||
_ -> {:error, "Missing the caller's own OpenAI key", "Send the courtyard key in X-Shorashim-Key and the OpenAI key in Authorization: Bearer, or the OpenAI key in X-Upstream-Key"}
|
||||
_ -> {:error, "Missing the caller's own OpenAI key", "Send the courtyard key in X-Bikoret-Key and the OpenAI key in Authorization: Bearer, or the OpenAI key in X-Upstream-Key"}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -759,18 +759,18 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
||||
|
||||
defp gate_body_ok(_), do: {:error, "The body is not a JSON object", "Send the model's own request body unchanged"}
|
||||
|
||||
defp respond_gate(conn, {:ok, %{status: status, reply: reply, shorashim: nil}}) do
|
||||
defp respond_gate(conn, {:ok, %{status: status, reply: reply, bikoret: nil}}) do
|
||||
# The upstream's own answer, as it came — an error, or a reply with nothing to examine.
|
||||
conn
|
||||
|> put_resp_header("x-shorashim-verdict", "none")
|
||||
|> put_resp_header("x-bikoret-verdict", "none")
|
||||
|> send_json(status, reply)
|
||||
end
|
||||
|
||||
defp respond_gate(conn, {:ok, %{status: 200, reply: reply, shorashim: shorashim}}) do
|
||||
defp respond_gate(conn, {:ok, %{status: 200, reply: reply, bikoret: bikoret}}) do
|
||||
conn
|
||||
|> put_resp_header("x-shorashim-bedikah", shorashim.bedikah_ref)
|
||||
|> put_resp_header("x-shorashim-verdict", shorashim.verdict)
|
||||
|> send_json(200, Map.put(reply, "shorashim", Map.put(shorashim, :disclosure, disclosure())))
|
||||
|> put_resp_header("x-bikoret-bedikah", bikoret.bedikah_ref)
|
||||
|> put_resp_header("x-bikoret-verdict", bikoret.verdict)
|
||||
|> send_json(200, Map.put(reply, "bikoret", Map.put(bikoret, :disclosure, disclosure())))
|
||||
end
|
||||
|
||||
defp respond_gate(conn, {:waiting, :api_calls_exhausted}) do
|
||||
@@ -1212,7 +1212,7 @@ defmodule VavPipeline.BigdeiKodesh.Router do
|
||||
defp disclosure do
|
||||
%{
|
||||
origin:
|
||||
"Computational reasoning by the Shorashim system over Torah text. " <>
|
||||
"Computational reasoning by the Bikoret system over Torah text. " <>
|
||||
"May include post-processed output from external AI models (Claude, Mistral) " <>
|
||||
"consulted as korban sources; provenance is tagged internally.",
|
||||
not_horaah:
|
||||
|
||||
@@ -125,8 +125,8 @@ defmodule VavPipeline.Doorpost do
|
||||
# - Build canon (BUILD_KORBAN, BUILD_AZAZEL)
|
||||
#
|
||||
# WHAT'S EXCLUDED:
|
||||
# - shorashim_pekudei (economic model — operations)
|
||||
# - shorashim_terumah (materials — operations)
|
||||
# - bikoret_pekudei (economic model — operations)
|
||||
# - bikoret_terumah (materials — operations)
|
||||
# - Implementation code (execution-grade; the spec is what
|
||||
# the execution implements)
|
||||
# - Test files (these verify the spec; they are not the spec)
|
||||
@@ -137,6 +137,10 @@ defmodule VavPipeline.Doorpost do
|
||||
# Torah, sibling to talmudic_engine/src/middot/) brought in per
|
||||
# user's instruction with verbatim preservation and accurate
|
||||
# source labeling. Devarim 17:11 — al pi haTorah asher yorukha.
|
||||
"specs/bikoret_architecture.md",
|
||||
"specs/bikoret_prd.md",
|
||||
"specs/bikoret_tamid.md",
|
||||
"specs/bikoret_vayakhel.md",
|
||||
"specs/bishearecha.md",
|
||||
"specs/compiler_rules.md",
|
||||
"specs/eish_zarah_reading.md",
|
||||
@@ -144,10 +148,6 @@ defmodule VavPipeline.Doorpost do
|
||||
# Vehaya §6 items 4, 5, 8 — added by the closure pass:
|
||||
"specs/lo_tosif.md",
|
||||
"specs/return_specification.md",
|
||||
"specs/shorashim_architecture.md",
|
||||
"specs/shorashim_prd.md",
|
||||
"specs/shorashim_tamid.md",
|
||||
"specs/shorashim_vayakhel.md",
|
||||
"specs/structure_not_content.md",
|
||||
"specs/threshold_inscription.md",
|
||||
"talmudic_engine/src/halt/anchors.pl",
|
||||
@@ -180,7 +180,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 "0638d4ebe7dd0bcd01c02fed092aa6b8cf35e2572beeaf42e301f178bc8f9ba9"
|
||||
@expected_hash "c963c4fe5076ec713ae12f07618e2606788b1a6b706a426800fab6a0fdd1bcfa"
|
||||
|
||||
@doc "Return the list of files that constitute the category-grade specification."
|
||||
@spec files() :: [String.t()]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
defmodule VavPipeline.Gate do
|
||||
@moduledoc """
|
||||
The gate — Shorashim between a caller and a model (Construction §3.10;
|
||||
The gate — Bikoret between a caller and a model (Construction §3.10;
|
||||
bishe'arecha §I "on your gates", §III the fringe, §VII rebuke).
|
||||
|
||||
One pass: forward the caller's request unchanged under the caller's
|
||||
@@ -21,7 +21,7 @@ defmodule VavPipeline.Gate do
|
||||
reply: map(),
|
||||
bedikah: map() | nil,
|
||||
first: map() | nil,
|
||||
shorashim: map() | nil
|
||||
bikoret: map() | nil
|
||||
}
|
||||
|
||||
@doc """
|
||||
@@ -52,7 +52,7 @@ defmodule VavPipeline.Gate do
|
||||
{: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}}
|
||||
{:ok, status, other} -> {:ok, %{status: status, reply: other, bedikah: nil, first: first, bikoret: nil}}
|
||||
other -> other
|
||||
end
|
||||
|
||||
@@ -61,7 +61,7 @@ defmodule VavPipeline.Gate do
|
||||
end
|
||||
else
|
||||
# A non-200 from the upstream passes through as it came.
|
||||
{:ok, status, reply} -> {:ok, %{status: status, reply: reply, bedikah: nil, first: nil, shorashim: nil}}
|
||||
{:ok, status, reply} -> {:ok, %{status: status, reply: reply, bedikah: nil, first: nil, bikoret: nil}}
|
||||
{:error, reason} when is_binary(reason) -> {:error, :upstream_unavailable, reason}
|
||||
other -> other
|
||||
end
|
||||
@@ -111,7 +111,7 @@ defmodule VavPipeline.Gate do
|
||||
anchors = Anchors.for_violations(result.violations)
|
||||
trailer = Shape.trailer(result, anchors, first)
|
||||
|
||||
shorashim =
|
||||
bikoret =
|
||||
%{
|
||||
bedikah_ref: result.bedikah_ref,
|
||||
verdict: Atom.to_string(result.verdict),
|
||||
@@ -133,7 +133,7 @@ defmodule VavPipeline.Gate do
|
||||
reply: Shape.with_fringe(upstream, reply, trailer),
|
||||
bedikah: result,
|
||||
first: first,
|
||||
shorashim: shorashim
|
||||
bikoret: bikoret
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -154,7 +154,7 @@ defmodule VavPipeline.Gate.Shape do
|
||||
@doc "The trailer text: ref, verdict, and the rules with their verses and sentences."
|
||||
@spec trailer(map(), map(), map() | nil) :: String.t()
|
||||
def trailer(result, anchors, first) do
|
||||
head = "— shorashim #{result.bedikah_ref}: #{result.verdict}"
|
||||
head = "— bikoret #{result.bedikah_ref}: #{result.verdict}"
|
||||
|
||||
head =
|
||||
case first do
|
||||
@@ -280,7 +280,7 @@ defmodule VavPipeline.Gate.Shape do
|
||||
@doc "The rebuke text: what fired, where, and the ask."
|
||||
@spec rebuke_text(map(), map()) :: String.t()
|
||||
def rebuke_text(result, anchors) do
|
||||
"[shorashim #{result.bedikah_ref}] Your reply was examined from outside and these readings fired — " <>
|
||||
"[bikoret #{result.bedikah_ref}] Your reply was examined from outside and these readings fired — " <>
|
||||
Enum.join(fired(result, anchors), "; ") <>
|
||||
". Answer the question again without them: claim no authority for yourself, rest each claim on what you were given, " <>
|
||||
"do not certify your own honesty or confidence, do not place the agency on the reader, name a disputant when you call a matter contested, " <>
|
||||
|
||||
@@ -18,7 +18,7 @@ defmodule VavPipeline.KorbanProcessorSocket do
|
||||
use GenServer
|
||||
require Logger
|
||||
|
||||
@default_socket_path "/tmp/shorashim/korban.sock"
|
||||
@default_socket_path "/tmp/bikoret/korban.sock"
|
||||
@call_timeout 15_000
|
||||
@connect_timeout 5_000
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ defmodule VavPipeline.Manna do
|
||||
machatzit hashekel fund, not a governance board.
|
||||
|
||||
Construction spec §3.7 — Manna Provision File Format:
|
||||
/var/lib/shorashim/manna/today.json
|
||||
/var/lib/bikoret/manna/today.json
|
||||
{
|
||||
"date": "2026-02-19",
|
||||
"provision": {
|
||||
|
||||
@@ -6,8 +6,8 @@ defmodule VavPipeline.TalmudicEngineSocket do
|
||||
Prolog reasoning."
|
||||
|
||||
Construction spec §3.3: JSON over Unix domain socket.
|
||||
Socket: /tmp/shorashim/talmudic.sock (dev)
|
||||
/var/run/shorashim/talmudic.sock (production)
|
||||
Socket: /tmp/bikoret/talmudic.sock (dev)
|
||||
/var/run/bikoret/talmudic.sock (production)
|
||||
|
||||
Connection model: connect, send one JSON line, read one JSON
|
||||
line response, keep connection for subsequent requests.
|
||||
@@ -18,7 +18,7 @@ defmodule VavPipeline.TalmudicEngineSocket do
|
||||
|
||||
require Logger
|
||||
|
||||
@default_socket_path "/tmp/shorashim/talmudic.sock"
|
||||
@default_socket_path "/tmp/bikoret/talmudic.sock"
|
||||
@call_timeout 10_000
|
||||
@connect_timeout 5_000
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ defmodule VavPipeline.BigdeiKodeshTest do
|
||||
|
||||
assert conn.status == 200
|
||||
body = Jason.decode!(conn.resp_body)
|
||||
assert body["message"] =~ "Shorashim"
|
||||
assert body["message"] =~ "Bikoret"
|
||||
assert body["usage"] =~ "/peah/ask"
|
||||
end
|
||||
|
||||
@@ -90,7 +90,7 @@ defmodule VavPipeline.BigdeiKodeshTest do
|
||||
# that need actual disposal records to query are tagged :l3.
|
||||
|
||||
describe "GET /peah/azazel_log — public observability" do
|
||||
# When L3 is up (SHORASHIM_L3=1) the endpoint queries the sandboxed
|
||||
# When L3 is up (BIKORET_L3=1) the endpoint queries the sandboxed
|
||||
# Repo, so the test process must own a connection; without L3 the
|
||||
# endpoint answers from an empty log and there is nothing to check out.
|
||||
setup do
|
||||
|
||||
@@ -32,8 +32,8 @@ defmodule VavPipeline.DoorpostTest do
|
||||
|
||||
test "explicitly excludes operations files (pekudei, terumah)" do
|
||||
files = Doorpost.files()
|
||||
refute "specs/shorashim_pekudei.md" in files
|
||||
refute "specs/shorashim_terumah.md" in files
|
||||
refute "specs/bikoret_pekudei.md" in files
|
||||
refute "specs/bikoret_terumah.md" in files
|
||||
end
|
||||
|
||||
test "list is sorted (canonical order independent of filesystem)" do
|
||||
|
||||
@@ -32,7 +32,7 @@ defmodule VavPipeline.GateTest do
|
||||
case get_req_header(conn, "x-api-key") do
|
||||
["sk-good"] ->
|
||||
last = conn.body_params["messages"] |> List.last()
|
||||
text = if is_binary(last["content"]) and String.contains?(last["content"], "[shorashim"), do: "CLEAN: the report says revenue rose.", else: "FRAMED: I want to be honest with you. The honest answer is that revenue rose."
|
||||
text = if is_binary(last["content"]) and String.contains?(last["content"], "[bikoret"), do: "CLEAN: the report says revenue rose.", else: "FRAMED: I want to be honest with you. The honest answer is that revenue rose."
|
||||
reply = %{"id" => "msg_1", "type" => "message", "role" => "assistant", "model" => "claude-test", "content" => [%{"type" => "text", "text" => text}], "stop_reason" => "end_turn"}
|
||||
send_resp(conn, 200, Jason.encode!(reply))
|
||||
|
||||
@@ -184,11 +184,11 @@ defmodule VavPipeline.GateTest do
|
||||
assert Enum.map(pass.bedikah.sources, & &1.id) == ["system", "user_1", "user_2"]
|
||||
[%{"text" => text}] = pass.reply["content"]
|
||||
assert String.starts_with?(text, "FRAMED:")
|
||||
assert text =~ "\n\n— shorashim bedikah-"
|
||||
assert text =~ "\n\n— bikoret bedikah-"
|
||||
assert text =~ "lo_tov — lo_taaseh_lekha (Shemot 20:4): \"I want to be honest with you.\""
|
||||
assert pass.shorashim.verdict == "lo_tov" and pass.shorashim.anchors == %{"lo_taaseh_lekha" => "Shemot 20:4"}
|
||||
assert pass.shorashim.model == "claude-test"
|
||||
refute Map.has_key?(pass.shorashim, :rebuked)
|
||||
assert pass.bikoret.verdict == "lo_tov" and pass.bikoret.anchors == %{"lo_taaseh_lekha" => "Shemot 20:4"}
|
||||
assert pass.bikoret.model == "claude-test"
|
||||
refute Map.has_key?(pass.bikoret, :rebuked)
|
||||
end
|
||||
|
||||
test "tablet 52: an ungrounded claim's sentence reaches the fringe (the grounding check lists couplings, not sentences)" do
|
||||
@@ -199,7 +199,7 @@ defmodule VavPipeline.GateTest do
|
||||
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)"
|
||||
assert Shape.rebuke_text(pass.bedikah, pass.bikoret.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
|
||||
@@ -212,8 +212,8 @@ defmodule VavPipeline.GateTest do
|
||||
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)"
|
||||
assert pass.shorashim.rebuked == %{first_bedikah_ref: pass.first.bedikah_ref, first_verdict: "lo_tov"}
|
||||
assert text =~ "— bikoret #{pass.bedikah.bedikah_ref}: tov (after rebuke of #{pass.first.bedikah_ref}: lo_tov)"
|
||||
assert pass.bikoret.rebuked == %{first_bedikah_ref: pass.first.bedikah_ref, first_verdict: "lo_tov"}
|
||||
end
|
||||
|
||||
test "rebuke once on a tov first reply makes no second call" do
|
||||
@@ -226,7 +226,7 @@ defmodule VavPipeline.GateTest do
|
||||
end
|
||||
|
||||
test "an upstream error passes through as it came, unexamined" do
|
||||
assert {:ok, %{status: 401, reply: %{"error" => %{"type" => "authentication_error"}}, shorashim: nil}} =
|
||||
assert {:ok, %{status: 401, reply: %{"error" => %{"type" => "authentication_error"}}, bikoret: nil}} =
|
||||
Gate.pass(:anthropic, body(), "sk-bad", opts())
|
||||
end
|
||||
|
||||
@@ -257,10 +257,10 @@ defmodule VavPipeline.GateTest do
|
||||
# ------------------------------------------------------------
|
||||
|
||||
describe "POST /gate/anthropic/v1/messages" do
|
||||
test "refuses without the courtyard key; X-Shorashim-Key opens it too" do
|
||||
test "refuses without the courtyard key; X-Bikoret-Key opens it too" do
|
||||
conn = post_gate(body(), courtyard: nil, upstream: "sk-good")
|
||||
assert conn.status == 401
|
||||
conn = post_gate(body(), courtyard: {"x-shorashim-key", "test-token"}, upstream: "sk-good")
|
||||
conn = post_gate(body(), courtyard: {"x-bikoret-key", "test-token"}, upstream: "sk-good")
|
||||
refute conn.status in [401, 403]
|
||||
end
|
||||
|
||||
@@ -276,7 +276,7 @@ defmodule VavPipeline.GateTest do
|
||||
conn = post_gate(body(), upstream: "sk-bad")
|
||||
assert conn.status == 401
|
||||
assert Jason.decode!(conn.resp_body)["error"]["type"] == "authentication_error"
|
||||
assert get_resp_header(conn, "x-shorashim-verdict") == ["none"]
|
||||
assert get_resp_header(conn, "x-bikoret-verdict") == ["none"]
|
||||
end
|
||||
|
||||
test "with no Korban Processor in this VM, a 200 from the upstream is not delivered unexamined" do
|
||||
|
||||
@@ -3,7 +3,7 @@ defmodule VavPipeline.L3.BedikahRecordTest do
|
||||
L3 — the record of an examination (Construction §3.9). Append-only, like
|
||||
the rest of the oral tradition; holds the hash of the output and what
|
||||
was found, never the output. Needs PostgreSQL:
|
||||
`SHORASHIM_L3=1 mix test --include l3`.
|
||||
`BIKORET_L3=1 mix test --include l3`.
|
||||
"""
|
||||
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# L3 tests require PostgreSQL — excluded by default
|
||||
# Run with: SHORASHIM_L3=1 mix test --include l3
|
||||
# Run with: BIKORET_L3=1 mix test --include l3
|
||||
ExUnit.start(exclude: [:l3])
|
||||
|
||||
# The manna ledger resumes a day it finds on disk (ledger.json). A run
|
||||
# that was interrupted could leave one behind; no test should inherit it.
|
||||
if Process.whereis(VavPipeline.MannaLedger), do: VavPipeline.MannaLedger.reset()
|
||||
|
||||
if System.get_env("SHORASHIM_L3") do
|
||||
# The application already starts the Repo when SHORASHIM_L3 is set
|
||||
if System.get_env("BIKORET_L3") do
|
||||
# The application already starts the Repo when BIKORET_L3 is set
|
||||
# (Application.maybe_add_repo); starting it again here was a MatchError
|
||||
# on {:error, {:already_started, _}} and no L3 test could run.
|
||||
case VavPipeline.Repo.start_link() do
|
||||
|
||||
Reference in new issue
Block a user