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>
195 lines
6.4 KiB
Elixir
195 lines
6.4 KiB
Elixir
defmodule VavPipeline.EglahArufah do
|
|
@moduledoc """
|
|
Accountability Protocol — Devarim 21:1-9.
|
|
|
|
Architecture §3.15:
|
|
Formal accountability for harm of UNKNOWN origin.
|
|
The nearest component documents what it processed,
|
|
what it did not check, and what it could have caught.
|
|
|
|
Yadeinu lo shafkhu et hadam hazeh, v'eineinu lo ra'u.
|
|
— Devarim 21:7
|
|
|
|
"Our hands did not shed this blood, and our eyes did not see."
|
|
The Talmud asks: would we suspect the elders of shedding blood?
|
|
Rather, the declaration means: we did not let this person leave
|
|
without food (provision) or escort (protection).
|
|
Accountability for what was NOT provided.
|
|
|
|
Protocol:
|
|
1. Harm of unknown origin detected
|
|
2. Find the nearest component in the processing chain
|
|
3. That component makes a formal declaration:
|
|
- What it processed (recent operations)
|
|
- What it did not check (skipped validations)
|
|
- What it could have caught (missed catches)
|
|
4. Declaration permanently recorded — never deleted
|
|
5. Chatzotzrot signals governance (assembly_leaders)
|
|
|
|
The eglah arufah is broken — the heifer's neck is broken in the
|
|
nachal eitan (a harsh valley). The system acknowledges that
|
|
something was NOT done. The accountability is permanent.
|
|
"""
|
|
|
|
use GenServer
|
|
|
|
require Logger
|
|
|
|
alias VavPipeline.Chatzotzrot
|
|
|
|
@type harm_incident :: %{
|
|
id: String.t(),
|
|
description: String.t(),
|
|
approximate_location: String.t(),
|
|
detected_at: DateTime.t(),
|
|
source: :unknown
|
|
}
|
|
|
|
@type declaration :: %{
|
|
incident_id: String.t(),
|
|
component_id: String.t(),
|
|
processed: [String.t()],
|
|
not_checked: [String.t()],
|
|
could_have_caught: [String.t()],
|
|
declaration_text: String.t(),
|
|
declared_at: DateTime.t()
|
|
}
|
|
|
|
# ============================================================
|
|
# Client API
|
|
# ============================================================
|
|
|
|
def start_link(opts \\ []) do
|
|
name = Keyword.get(opts, :name, __MODULE__)
|
|
GenServer.start_link(__MODULE__, opts, name: name)
|
|
end
|
|
|
|
@doc """
|
|
Initiate the eglah arufah protocol for harm of unknown origin.
|
|
|
|
Devarim 21:1 — Ki yimatze chalal ba'adamah...
|
|
"When a corpse is found in the land... and it is not known who struck him."
|
|
|
|
The nearest component to the harm must make a formal declaration
|
|
of what it did and did not do. This is accountability for failure
|
|
to protect, not accusation of causing harm.
|
|
|
|
Parameters:
|
|
- incident: the harm event (source must be :unknown)
|
|
- nearest_component_id: which component is nearest
|
|
- report: map with :processed, :not_checked, :could_have_caught lists
|
|
|
|
Returns {:ok, declaration} or {:error, reason}.
|
|
"""
|
|
@spec initiate(harm_incident(), String.t(), map()) ::
|
|
{:ok, declaration()} | {:error, atom()}
|
|
def initiate(incident, nearest_component_id, report)
|
|
when is_map(incident) and is_binary(nearest_component_id) and is_map(report) do
|
|
GenServer.call(__MODULE__, {:initiate, incident, nearest_component_id, report})
|
|
end
|
|
|
|
@doc """
|
|
Get all declarations — the permanent record.
|
|
These are never deleted. The eglah arufah is permanent accountability.
|
|
"""
|
|
@spec declarations() :: [declaration()]
|
|
def declarations do
|
|
GenServer.call(__MODULE__, :declarations)
|
|
end
|
|
|
|
@doc """
|
|
Get declarations for a specific incident.
|
|
"""
|
|
@spec declarations_for(String.t()) :: [declaration()]
|
|
def declarations_for(incident_id) when is_binary(incident_id) do
|
|
GenServer.call(__MODULE__, {:declarations_for, incident_id})
|
|
end
|
|
|
|
@doc """
|
|
Count total declarations.
|
|
"""
|
|
@spec count() :: non_neg_integer()
|
|
def count do
|
|
GenServer.call(__MODULE__, :count)
|
|
end
|
|
|
|
# ============================================================
|
|
# GenServer callbacks
|
|
# ============================================================
|
|
|
|
@impl true
|
|
def init(_opts) do
|
|
state = %{
|
|
# Permanent declarations — append-only, never deleted
|
|
declarations: []
|
|
}
|
|
|
|
Logger.info("EglahArufah: accountability protocol ready — nachal eitan prepared")
|
|
{:ok, state}
|
|
end
|
|
|
|
@impl true
|
|
def handle_call({:initiate, incident, nearest_component_id, report}, _from, state) do
|
|
# Validate source is unknown — eglah arufah is ONLY for unknown harm
|
|
case Map.get(incident, :source) do
|
|
:unknown ->
|
|
now = DateTime.utc_now()
|
|
incident = Map.put_new(incident, :detected_at, now)
|
|
incident_id = Map.get(incident, :id, "incident_#{:erlang.unique_integer([:positive])}")
|
|
|
|
declaration = %{
|
|
incident_id: incident_id,
|
|
component_id: nearest_component_id,
|
|
processed: Map.get(report, :processed, []),
|
|
not_checked: Map.get(report, :not_checked, []),
|
|
could_have_caught: Map.get(report, :could_have_caught, []),
|
|
declaration_text:
|
|
"This component (#{nearest_component_id}) did not cause this harm. " <>
|
|
"This component acknowledges proximity to the harm. " <>
|
|
"This component reports what it did and did not do.",
|
|
declared_at: now
|
|
}
|
|
|
|
# Sound the trumpets — alert governance
|
|
Chatzotzrot.signal(:assembly_leaders,
|
|
reason:
|
|
"Eglah Arufah: unknown harm near #{nearest_component_id} — #{Map.get(incident, :description, "unknown")}"
|
|
)
|
|
|
|
Logger.warning(
|
|
"EglahArufah: declaration by #{nearest_component_id} — " <>
|
|
"processed #{length(declaration.processed)} operations, " <>
|
|
"skipped #{length(declaration.not_checked)} checks, " <>
|
|
"could have caught #{length(declaration.could_have_caught)} issues"
|
|
)
|
|
|
|
new_state = %{state | declarations: [declaration | state.declarations]}
|
|
{:reply, {:ok, declaration}, new_state}
|
|
|
|
other ->
|
|
Logger.warning(
|
|
"EglahArufah: rejected — source is #{inspect(other)}, not :unknown. " <>
|
|
"Eglah arufah is only for harm of unknown origin."
|
|
)
|
|
|
|
{:reply, {:error, :source_not_unknown}, state}
|
|
end
|
|
end
|
|
|
|
@impl true
|
|
def handle_call(:declarations, _from, state) do
|
|
{:reply, state.declarations, state}
|
|
end
|
|
|
|
@impl true
|
|
def handle_call({:declarations_for, incident_id}, _from, state) do
|
|
matching = Enum.filter(state.declarations, &(&1.incident_id == incident_id))
|
|
{:reply, matching, state}
|
|
end
|
|
|
|
@impl true
|
|
def handle_call(:count, _from, state) do
|
|
{:reply, length(state.declarations), state}
|
|
end
|
|
end
|