Protection layer: Arei Miklat, Eglah Arufah, Bikurim — Steps 27-29
Takhin lekha haderekh — Devarim 19:3.
"Prepare the road" before the one who needs refuge arrives.
Protection before production.
Arei Miklat (Cities of Refuge — Bamidbar 35, Devarim 19):
- GenServer with refuge registry, affected party protection, audit trail
- enter_refuge/2 isolates component but protects from reactive destruction
- protect_affected/2 blocks processing paths that caused harm
- release/2 requires :sanhedrin_deliberation authority — ad mot hakohen hagadol
- Chatzotzrot assembly_leaders signal on every refuge entry
- 15 tests: entry, double-entry prevention, affected party blocking,
unauthorized release rejection, audit trail, chatzotzrot signaling
Eglah Arufah (Accountability — Devarim 21:1-9):
- GenServer with permanent (append-only) declaration registry
- initiate/3: nearest component declares what it processed, skipped, missed
- Only for :unknown source — rejects known-source incidents
- "Yadeinu lo shafkhu" — accountability for what was NOT provided
- 9 tests: declaration recording, source validation, multi-component
declarations, chatzotzrot signaling, filtering, counting
Bikurim (First Fruits — Devarim 26:1-11):
- GenServer with offering registry
- offer/4: submit first output with required narrative (mikra bikurim)
- Rejects empty narrative ("Arami oved avi" — story is required)
- Rejects nil first output (there must be fruit to offer)
- Delegates to Specification.evaluate_bikurim/1 when available
- approved?/1 gate for deployment readiness
- 11 tests: acceptance, narrative validation, nil output rejection,
registry, status filtering, approval checking, counting
All three added to supervision tree in application.ex.
160 Elixir tests pass, 0 failures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
eb571cff7b
commit
22cc36b2ec
7 files changed
+1230
No files matched your search
@@ -0,0 +1,150 @@
|
||||
defmodule VavPipeline.BikurimTest do
|
||||
@moduledoc """
|
||||
Tests for the Bikurim (First Fruits / Release Protocol).
|
||||
|
||||
Devarim 26:5 — Arami oved avi.
|
||||
"A wandering Aramean was my father."
|
||||
The offering requires narrative — not just the fruit,
|
||||
but the story of how it was produced.
|
||||
"""
|
||||
|
||||
use ExUnit.Case, async: false
|
||||
|
||||
alias VavPipeline.Bikurim
|
||||
|
||||
# ============================================================
|
||||
# Offering — Devarim 26:2
|
||||
# ============================================================
|
||||
describe "offer" do
|
||||
test "accepted offering with narrative and output" do
|
||||
{:ok, :approved_for_deployment, offering} =
|
||||
Bikurim.offer(
|
||||
"chatzotzrot_genserver",
|
||||
%{signal_types: 5, routing: true, zikaron: true},
|
||||
"Built as GenServer with BEAM PubSub routing. " <>
|
||||
"Five signals mapped to five trumpet patterns per Bamidbar 10. " <>
|
||||
"Signal history (zikaron) records every signal ever sounded.",
|
||||
lineage: ["chatzotzrot_stub", "application_supervisor"],
|
||||
torah_grounding: "Bamidbar 10:1-10"
|
||||
)
|
||||
|
||||
assert offering.capability == "chatzotzrot_genserver"
|
||||
assert offering.status == :accepted
|
||||
assert offering.narrative != ""
|
||||
assert offering.lineage == ["chatzotzrot_stub", "application_supervisor"]
|
||||
assert offering.torah_grounding == "Bamidbar 10:1-10"
|
||||
assert offering.offered_at != nil
|
||||
end
|
||||
|
||||
test "rejected when no narrative provided — mikra bikurim required" do
|
||||
{:error, :specification_mismatch, reason, offering} =
|
||||
Bikurim.offer(
|
||||
"empty_narrative_test",
|
||||
%{some: "output"},
|
||||
""
|
||||
)
|
||||
|
||||
assert offering.status == :rejected
|
||||
assert String.contains?(reason, "narrative")
|
||||
end
|
||||
|
||||
test "rejected when no first output" do
|
||||
{:error, :specification_mismatch, reason, offering} =
|
||||
Bikurim.offer(
|
||||
"nil_output_test",
|
||||
nil,
|
||||
"This capability does nothing yet"
|
||||
)
|
||||
|
||||
assert offering.status == :rejected
|
||||
assert String.contains?(reason, "first output")
|
||||
end
|
||||
|
||||
test "whitespace-only narrative is rejected" do
|
||||
{:error, :specification_mismatch, _reason, _offering} =
|
||||
Bikurim.offer(
|
||||
"whitespace_narrative",
|
||||
%{output: true},
|
||||
" \n\t "
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# ============================================================
|
||||
# Registry
|
||||
# ============================================================
|
||||
describe "registry" do
|
||||
test "offerings are recorded in registry" do
|
||||
Bikurim.offer(
|
||||
"registry_test_cap",
|
||||
%{works: true},
|
||||
"Test capability for registry verification"
|
||||
)
|
||||
|
||||
registry = Bikurim.registry()
|
||||
assert Enum.any?(registry, &(&1.capability == "registry_test_cap"))
|
||||
end
|
||||
|
||||
test "rejected offerings are also in registry" do
|
||||
Bikurim.offer("rejected_registry", nil, "Has narrative but no output")
|
||||
|
||||
registry = Bikurim.registry()
|
||||
rejected = Enum.find(registry, &(&1.capability == "rejected_registry"))
|
||||
assert rejected != nil
|
||||
assert rejected.status == :rejected
|
||||
end
|
||||
|
||||
test "by_status filters correctly" do
|
||||
Bikurim.offer("status_accepted", %{ok: true}, "Good capability")
|
||||
Bikurim.offer("status_rejected", nil, "Bad capability")
|
||||
|
||||
accepted = Bikurim.by_status(:accepted)
|
||||
assert Enum.any?(accepted, &(&1.capability == "status_accepted"))
|
||||
refute Enum.any?(accepted, &(&1.capability == "status_rejected"))
|
||||
|
||||
rejected = Bikurim.by_status(:rejected)
|
||||
assert Enum.any?(rejected, &(&1.capability == "status_rejected"))
|
||||
end
|
||||
end
|
||||
|
||||
# ============================================================
|
||||
# Approval check
|
||||
# ============================================================
|
||||
describe "approved?" do
|
||||
test "accepted capability is approved" do
|
||||
Bikurim.offer("approved_test", %{ready: true}, "Fully tested capability")
|
||||
assert Bikurim.approved?("approved_test")
|
||||
end
|
||||
|
||||
test "rejected capability is not approved" do
|
||||
Bikurim.offer("not_approved_test", nil, "Has narrative but no output")
|
||||
refute Bikurim.approved?("not_approved_test")
|
||||
end
|
||||
|
||||
test "unknown capability is not approved" do
|
||||
refute Bikurim.approved?("never_offered_capability")
|
||||
end
|
||||
end
|
||||
|
||||
# ============================================================
|
||||
# Counting
|
||||
# ============================================================
|
||||
describe "count" do
|
||||
test "counts all offerings" do
|
||||
initial = Bikurim.count(:all)
|
||||
Bikurim.offer("count_all_test", %{x: 1}, "Counting test")
|
||||
assert Bikurim.count(:all) == initial + 1
|
||||
end
|
||||
|
||||
test "counts by status" do
|
||||
initial_accepted = Bikurim.count(:accepted)
|
||||
initial_rejected = Bikurim.count(:rejected)
|
||||
|
||||
Bikurim.offer("count_accepted", %{x: 1}, "Accepted offering")
|
||||
Bikurim.offer("count_rejected", nil, "Rejected offering")
|
||||
|
||||
assert Bikurim.count(:accepted) == initial_accepted + 1
|
||||
assert Bikurim.count(:rejected) == initial_rejected + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user