Phase 1-2 build: Steps 5-6, 8-13
Shoresh Engine (Haskell, Step 5) - 12 modules: Types, Lexicon, Binyanim, Teamim, Gematria, Graph, KetivQere, Smikhut, Havdalah, Kriah, KiTov, Firmware - 33 EUnit tests, 0 failures - Firmware module verifies L1 SHA-256 hash at startup Talmudic Engine (SWI-Prolog, Step 6) - 15 modules: halt, reasoning, specification, interface - 57 PlUnit tests, 0 failures - Three cardinal halt conditions: avodah_zarah, shfichut_damim, gilui_arayot Vav Pipeline (Elixir, Steps 8-11) - 14 modules: BereishitCycle, Shema, Cloud, Manna, L1Reader, Specification, HaltConditions, ShabbatTimer, CycleLog, Chatzotzrot, ShoreshEngineClient, TalmudicEngineClient, Application - 46 ExUnit tests, 0 failures - Nishma-first architecture: hears before it speaks Sanhedrin Framework (Erlang/OTP, Step 12) - 8 modules: sanhedrin_app, sanhedrin_sup, escalation, panel_sup, panel, judge, clerk, halt_monitor - 46 EUnit tests, 0 failures (includes fix: rejected outcome now reachable) - Panel sizes: 1/3/23/71 — unanimous capital guilty → acquit (Sanhedrin 17a) - Minority opinions append-only, never deleted Korban Processor (Python, Step 13) - 6 modules: korban, shechitah, semichah, zerikah, haktarah, router Builder tooling: AGENTS.md, opencode.json, memory/, src/tools/ Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
622e814c9e
commit
80ec364da6
86 files changed
+9646
No files matched your search
@@ -0,0 +1,111 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @doc Escalation — assess complexity and route cases to panels.
|
||||
%%%
|
||||
%%% Architecture §3.2:
|
||||
%%% assess(Case) determines complexity, route/2 convenes the panel.
|
||||
%%%
|
||||
%%% Panel sizes from halakha:
|
||||
%%% simple -> 1 judge (individual matters)
|
||||
%%% monetary -> 3 judges (dinei mamonot)
|
||||
%%% capital -> 23 judges (dinei nefashot)
|
||||
%%% novel -> 71 judges (Sanhedrin Gedolah)
|
||||
%%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(escalation).
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-include("sanhedrin.hrl").
|
||||
|
||||
%% API
|
||||
-export([start_link/0, submit_case/1, assess/1]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
|
||||
-record(state, {
|
||||
active_cases = #{} :: map(), %% case_ref => panel_pid
|
||||
case_count = 0 :: non_neg_integer()
|
||||
}).
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
|
||||
|
||||
%% @doc Submit a case for deliberation.
|
||||
%% Returns {ok, CaseRef} or {error, Reason}.
|
||||
-spec submit_case(#sanhedrin_case{}) -> {ok, binary()} | {error, term()}.
|
||||
submit_case(Case) ->
|
||||
gen_server:call(?SERVER, {submit_case, Case}, 30000).
|
||||
|
||||
%% @doc Assess complexity of a case. Pure function.
|
||||
-spec assess(#sanhedrin_case{}) -> {panel, pos_integer()}.
|
||||
assess(#sanhedrin_case{complexity = simple}) -> {panel, ?PANEL_SIMPLE};
|
||||
assess(#sanhedrin_case{complexity = monetary}) -> {panel, ?PANEL_MONETARY};
|
||||
assess(#sanhedrin_case{complexity = capital}) -> {panel, ?PANEL_CAPITAL};
|
||||
assess(#sanhedrin_case{complexity = novel}) -> {panel, ?PANEL_NOVEL}.
|
||||
|
||||
%%====================================================================
|
||||
%% gen_server callbacks
|
||||
%%====================================================================
|
||||
|
||||
init([]) ->
|
||||
{ok, #state{}}.
|
||||
|
||||
handle_call({submit_case, Case}, _From, State) ->
|
||||
%% First check halt conditions
|
||||
case halt_monitor:check_case(Case) of
|
||||
clear ->
|
||||
%% Assess complexity and route
|
||||
{panel, Size} = assess(Case),
|
||||
Timeout = timeout_for(Case#sanhedrin_case.complexity),
|
||||
case panel_sup:start_panel(Case, Size) of
|
||||
{ok, PanelPid} ->
|
||||
%% Start deliberation asynchronously
|
||||
panel:deliberate_async(PanelPid, Timeout),
|
||||
NewActive = maps:put(
|
||||
Case#sanhedrin_case.case_ref,
|
||||
PanelPid,
|
||||
State#state.active_cases
|
||||
),
|
||||
{reply,
|
||||
{ok, Case#sanhedrin_case.case_ref},
|
||||
State#state{
|
||||
active_cases = NewActive,
|
||||
case_count = State#state.case_count + 1
|
||||
}};
|
||||
{error, Reason} ->
|
||||
{reply, {error, {panel_start_failed, Reason}}, State}
|
||||
end;
|
||||
{halt, Condition, Reason} ->
|
||||
{reply, {error, {halted, Condition, Reason}}, State}
|
||||
end;
|
||||
|
||||
handle_call(_Request, _From, State) ->
|
||||
{reply, {error, unknown_request}, State}.
|
||||
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_info({panel_decided, CaseRef, Decision}, State) ->
|
||||
%% Panel has reached a decision — store via clerk
|
||||
clerk:store_decision(CaseRef, Decision),
|
||||
NewActive = maps:remove(CaseRef, State#state.active_cases),
|
||||
{noreply, State#state{active_cases = NewActive}};
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%%====================================================================
|
||||
%% Internal
|
||||
%%====================================================================
|
||||
|
||||
timeout_for(simple) -> ?TIMEOUT_SIMPLE;
|
||||
timeout_for(monetary) -> ?TIMEOUT_MONETARY;
|
||||
timeout_for(capital) -> ?TIMEOUT_CAPITAL;
|
||||
timeout_for(novel) -> ?TIMEOUT_NOVEL.
|
||||
Reference in new issue
Block a user