Tablet 46: the watch — rate limits at every gate, per IP at the pe'ah, per key inside
Tamid §1.1 wrote the pe'ah's limit (10/min, 100/h per IP); nothing enforced it, on any tier, and every admitted request spends manna. VavPipeline.BigdeiKodesh.Mishmar: fixed minute and hour windows per subject in ETS, the subject stored only as sha256(boot salt, tier, subject) — no IP and no key is ever in memory as itself, the sweep drops closed windows, nothing survives a restart (the Tamid's "not logged beyond the current request", kept in memory too). A refused knock is not counted. 429 RATE_LIMITED with Retry-After and the manna explanation (Shemot 16:18). Pe'ah per peer address; courtyard and chatzer per key, after the gate (a wrong key is 401 and never counted). Numbers: pe'ah 10/100 (Tamid), courtyard 20/200 and chatzer 5/60 (from Construction §2.3; config :rate_limits). Service shorashim-external: externalTrafficPolicy Local. With Cluster the pod saw every caller as the node, 91.92.153.113 (observed via /proc/net/tcp) — a per-IP limit would have been one bucket for the world. Spec: tamid §1.1 (watch, 429 rows, the Service note), KOHEN.md. Doorpost 42b38626… → e4e3d56d…. tablet46_mishmar_test; Elixir 533/0 (L3 on and off). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
79eb34840f
commit
54ca651f37
12 files changed
+406
-17
No files matched your search
@@ -1 +0,0 @@
|
||||
{"consumed":{"api_calls_external":0,"compute_units":3,"memory_mb":0,"sanhedrin_panels_max":0,"storage_delta_mb":0},"cycle_date":"2026-10-06","written_at":"2026-10-06T15:15:24.042079Z"}
|
||||
@@ -0,0 +1,135 @@
|
||||
defmodule VavPipeline.Tablet46MishmarTest do
|
||||
@moduledoc """
|
||||
Tablet 46 (2026-10-06) — no gate had a watch.
|
||||
|
||||
Tamid §1.1 writes the pe'ah's limit in the spec; nothing enforced it,
|
||||
on any tier. Every admitted request spends manna; one caller could
|
||||
gather the whole omer.
|
||||
"""
|
||||
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
import Plug.Test
|
||||
import Plug.Conn
|
||||
|
||||
alias VavPipeline.BigdeiKodesh.{Mishmar, Router}
|
||||
|
||||
@opts Router.init([])
|
||||
|
||||
setup do
|
||||
original = Application.get_env(:vav_pipeline, :rate_limits)
|
||||
|
||||
Application.put_env(:vav_pipeline, :rate_limits,
|
||||
peah: [minute: 3, hour: 5],
|
||||
courtyard: [minute: 2, hour: 100],
|
||||
chatzer: [minute: 10_000, hour: 100_000]
|
||||
)
|
||||
|
||||
Mishmar.reset()
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:vav_pipeline, :rate_limits, original)
|
||||
Mishmar.reset()
|
||||
end)
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "Mishmar.knock/3" do
|
||||
test "counts the minute, then the hour, per subject; a refusal is not counted" do
|
||||
t = 1_000_000 * 60
|
||||
|
||||
assert {:ok, 2} = Mishmar.knock(:peah, "a", t)
|
||||
assert {:ok, 1} = Mishmar.knock(:peah, "a", t + 1)
|
||||
assert {:ok, 0} = Mishmar.knock(:peah, "a", t + 2)
|
||||
assert {:error, :minute, 57} = Mishmar.knock(:peah, "a", t + 3)
|
||||
assert {:error, :minute, 57} = Mishmar.knock(:peah, "a", t + 3)
|
||||
|
||||
# Another subject is another count.
|
||||
assert {:ok, 2} = Mishmar.knock(:peah, "b", t + 3)
|
||||
|
||||
# The next minute opens — but the hour (5) is nearly spent: 3 so far.
|
||||
assert {:ok, 2} = Mishmar.knock(:peah, "a", t + 60)
|
||||
assert {:ok, 1} = Mishmar.knock(:peah, "a", t + 61)
|
||||
assert {:error, :hour, retry} = Mishmar.knock(:peah, "a", t + 62)
|
||||
assert retry == 3600 - rem(t + 62, 3600)
|
||||
|
||||
# The next hour opens.
|
||||
assert {:ok, 2} = Mishmar.knock(:peah, "a", t + 3600)
|
||||
end
|
||||
|
||||
test "tiers are counted apart" do
|
||||
t = 2_000_000 * 60
|
||||
assert {:ok, 1} = Mishmar.knock(:courtyard, "k", t)
|
||||
assert {:ok, 0} = Mishmar.knock(:courtyard, "k", t)
|
||||
assert {:error, :minute, _} = Mishmar.knock(:courtyard, "k", t)
|
||||
assert {:ok, 2} = Mishmar.knock(:peah, "k", t)
|
||||
end
|
||||
|
||||
test "the sweep drops closed windows and nothing else" do
|
||||
t = 3_000_000 * 60
|
||||
assert {:ok, _} = Mishmar.knock(:peah, "old", t)
|
||||
assert {:ok, _} = Mishmar.knock(:peah, "new", t + 7200)
|
||||
:ok = Mishmar.sweep(Mishmar, t + 7200)
|
||||
|
||||
# "old" has been forgotten entirely; "new" is still counted.
|
||||
assert :ets.info(Mishmar, :size) == 2
|
||||
assert {:ok, 1} = Mishmar.knock(:peah, "new", t + 7200)
|
||||
end
|
||||
|
||||
test "the table holds hashes, never the subject" do
|
||||
:ok = Mishmar.reset()
|
||||
{:ok, _} = Mishmar.knock(:peah, "203.0.113.7")
|
||||
|
||||
for {{id, _, _}, _} <- :ets.tab2list(Mishmar) do
|
||||
assert is_binary(id) and byte_size(id) == 32
|
||||
refute id =~ "203.0.113"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "at the router" do
|
||||
test "the pe'ah: the fourth knock from one address in a minute is 429 with Retry-After and the manna explanation" do
|
||||
statuses = for _ <- 1..4, do: ask({203, 0, 113, 9}).status
|
||||
assert Enum.take(statuses, 3) |> Enum.all?(&(&1 != 429))
|
||||
|
||||
conn = ask({203, 0, 113, 9})
|
||||
assert conn.status == 429
|
||||
[retry] = get_resp_header(conn, "retry-after")
|
||||
assert String.to_integer(retry) in 1..60
|
||||
body = Jason.decode!(conn.resp_body)
|
||||
assert body["error"]["code"] == "RATE_LIMITED"
|
||||
assert body["error"]["guidance"]["manna"] =~ "Shemot 16:18"
|
||||
|
||||
# Another address is not held back by this one.
|
||||
refute ask({203, 0, 113, 10}).status == 429
|
||||
end
|
||||
|
||||
test "the courtyard: per key, and only past the gate" do
|
||||
# A wrong key knocks all it likes and is never counted — 401, not 429.
|
||||
for _ <- 1..5, do: assert(bedikah("Bearer wrong").status == 401)
|
||||
|
||||
assert bedikah("Bearer test-token").status != 429
|
||||
assert bedikah("Bearer test-token").status != 429
|
||||
conn = bedikah("Bearer test-token")
|
||||
assert conn.status == 429
|
||||
assert Jason.decode!(conn.resp_body)["error"]["guidance"]["issue"] =~ "courtyard allows 2 a minute"
|
||||
|
||||
# The chatzer key is its own hand, even at the same door.
|
||||
refute bedikah("Bearer chatzer-test-token").status == 429
|
||||
end
|
||||
end
|
||||
|
||||
defp ask(ip) do
|
||||
%{conn(:post, "/peah/ask", Jason.encode!(%{question: "x"})) | remote_ip: ip}
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> Router.call(@opts)
|
||||
end
|
||||
|
||||
defp bedikah(auth) do
|
||||
conn(:post, "/courtyard/bedikah", Jason.encode!(%{output: "", model: "gpt"}))
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put_req_header("authorization", auth)
|
||||
|> Router.call(@opts)
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user