Files
bikoret/vav_pipeline/test/ledger_l3_test.exs
T
Scott KarpandClaude Fable 5.1 d6cf9355fd the ledger: a caller's own bedikot, read back and signed
The examination is the product; the record of it is what a caller can
carry away. Every bedikah was already engraved in L3 — output hash and
length, source digests, coupling trace, claims, violations, verdict,
never the text — and no caller could get theirs back.

- bedikot.key_id (migration): a SHA-256 digest of the courtyard key that
  brought the offering, never the key; threaded as :key_id through
  Bedikah.examine from every site that goes through the gate (courtyard
  bedikah, pair, the gate's pass and stream). Unique index on
  bedikah_ref.
- VavPipeline.Ledger: entry (the examination's fields, none of the
  database's, not the owner's), canonical JSON (keys sorted at every
  level, no whitespace, UTF-8), Ed25519 sign/verify, public key, render.
  Seed from BIKORET_LEDGER_SIGNING_KEY (base64 of 32 bytes) in
  shorashim-secrets; absent → unsigned and says so.
- GET /courtyard/ledger?limit&before — this key's bedikot, newest first,
  each rendered and signed; GET /courtyard/bedikah/<ref> — one, 404 for
  another key's or none alike; GET /peah/ledger_key — the public key.
- Tamid §1.1 "The ledger" (Doorpost pin moved → 02ddf313…), KOHEN
  "Issuing a key" (the seed, once), secrets.yaml template.

Tests: ledger_test (digest, entry, canonical, sign/verify, unsigned
rendering, signed rendering); ledger_l3_test (own records listed newest
first and only own; 404 alike for another's and none; an examination
engraved under the key reads back signed and verifies against
/peah/ledger_key). Elixir 642/0; L3 13/0.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-21 18:45:47 +00:00

110 lines
5.1 KiB
Elixir

defmodule VavPipeline.LedgerL3Test do
@moduledoc "The ledger over L3: a key reads its own bedikot back, signed, and no one else's (2026-10-21)."
use ExUnit.Case, async: false
import Plug.Test
import Plug.Conn
alias VavPipeline.BigdeiKodesh.Router
alias VavPipeline.L3.Store
@opts Router.init([])
@moduletag :l3
setup do
:ok = Ecto.Adapters.SQL.Sandbox.checkout(VavPipeline.Repo)
Ecto.Adapters.SQL.Sandbox.mode(VavPipeline.Repo, {:shared, self()})
on_exit(fn -> Ecto.Adapters.SQL.Sandbox.mode(VavPipeline.Repo, :manual) end)
write_provision()
:ok
end
defp write_provision do
VavPipeline.MannaLedger.reset()
on_exit(fn -> VavPipeline.MannaLedger.reset() end)
today = Date.utc_today() |> Date.to_iso8601()
expires = DateTime.utc_now() |> DateTime.add(6 * 3600) |> DateTime.to_iso8601()
provision = %{"date" => today, "provision" => %{"compute_units" => 50, "memory_mb" => 512, "api_calls_external" => 10, "storage_delta_mb" => 2, "sanhedrin_panels_max" => 2},
"type" => "regular", "expires_at" => expires, "written_by" => "ledger_l3_test", "written_at" => DateTime.utc_now() |> DateTime.to_iso8601()}
path = VavPipeline.Manna.provision_file()
File.mkdir_p!(Path.dirname(path))
File.write!(path, Jason.encode!(provision))
on_exit(fn -> File.rm(path) end)
end
defp attrs(ref, key_id) do
%{
bedikah_ref: ref, provenance: "claude", query: "q", output_sha256: String.duplicate("cd", 32), output_length: 5,
vital_content: "", verdict: "empty", examined_at: DateTime.utc_now() |> DateTime.truncate(:second), key_id: key_id
}
end
defp get(path, token) do
conn(:get, path) |> put_req_header("authorization", "Bearer #{token}") |> Router.call(@opts)
end
# An examination the offering protocol finds nothing in: the :empty branch, no engine needed.
defp empty_examination do
%{"provenance" => "claude", "query" => "status?", "vital_content" => "", "propositions" => [], "discarded" => ["Rolled out."],
"references" => [], "hebrew" => [], "roots" => [], "authority_claims" => [], "actions" => [],
"self_validation" => [], "self_promotion" => [], "excluded_adversarial" => [], "frames" => [], "sources" => [], "claims" => []}
end
test "the record keeps the key's digest, and the ledger lists only that key's records, newest first" do
mine = VavPipeline.Ledger.key_id("test-token")
other = VavPipeline.Ledger.key_id("someone-else")
{:ok, _} = Store.record_bedikah(attrs("bedikah-l3aaaa0000000001", mine))
{:ok, _} = Store.record_bedikah(attrs("bedikah-l3aaaa0000000002", mine))
{:ok, _} = Store.record_bedikah(attrs("bedikah-l3bbbb0000000003", other))
{:ok, _} = Store.record_bedikah(attrs("bedikah-l3cccc0000000004", nil))
refs = Store.list_bedikot(mine) |> Enum.map(& &1.bedikah_ref)
assert refs == ["bedikah-l3aaaa0000000002", "bedikah-l3aaaa0000000001"]
conn = get("/courtyard/ledger?limit=10", "test-token")
assert conn.status == 200
body = Jason.decode!(conn.resp_body)
assert body["key_id"] == mine
assert body["count"] == 2
assert Enum.map(body["entries"], & &1["entry"]["bedikah_ref"]) == ["bedikah-l3aaaa0000000002", "bedikah-l3aaaa0000000001"]
# never the text, never the key, never the owner column
e = hd(body["entries"])["entry"]
refute Map.has_key?(e, "key_id")
assert e["output_sha256"] == String.duplicate("cd", 32)
assert hd(body["entries"])["signed"] == false
end
test "one record by ref: mine answers, another key's and a missing one answer 404 alike" do
mine = VavPipeline.Ledger.key_id("test-token")
{:ok, _} = Store.record_bedikah(attrs("bedikah-l3dddd0000000005", mine))
{:ok, _} = Store.record_bedikah(attrs("bedikah-l3eeee0000000006", VavPipeline.Ledger.key_id("someone-else")))
assert get("/courtyard/bedikah/bedikah-l3dddd0000000005", "test-token").status == 200
assert get("/courtyard/bedikah/bedikah-l3eeee0000000006", "test-token").status == 404
assert get("/courtyard/bedikah/bedikah-l3ffff0000000007", "test-token").status == 404
end
test "an examination is engraved under the caller's key and reads back signed and verifiable" do
Application.put_env(:vav_pipeline, :ledger_signing_key, Base.encode64(:crypto.strong_rand_bytes(32)))
mine = VavPipeline.Ledger.key_id("test-token")
try do
examiner = fn _o, _p, _q, _s -> {:ok, empty_examination()} end
assert {:ok, r} = VavPipeline.Bedikah.examine("Rolled out.", "claude", "status?", examiner: examiner, key_id: mine)
assert r.verdict == :empty
assert Store.get_bedikah(r.bedikah_ref).key_id == mine
back = get("/courtyard/bedikah/#{r.bedikah_ref}", "test-token")
assert back.status == 200
body = Jason.decode!(back.resp_body)
assert body["signed"] == true
pub = Jason.decode!(get("/peah/ledger_key", "x").resp_body)["public_key"]
canonical = VavPipeline.Ledger.canonical(body["entry"])
assert :crypto.hash(:sha256, canonical) |> Base.encode16(case: :lower) == body["canonical_sha256"]
assert VavPipeline.Ledger.verify(canonical, body["signature"], pub)
after
Application.delete_env(:vav_pipeline, :ledger_signing_key)
end
end
end