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,177 @@
|
||||
%%%-------------------------------------------------------------------
|
||||
%%% @doc Halt monitor — monitors for the 3 cardinal sin conditions.
|
||||
%%%
|
||||
%%% Architecture §8 (Halt Conditions):
|
||||
%%% The system MUST halt on detection of:
|
||||
%%% 1. Avodah Zarah — treating non-Torah source as authoritative
|
||||
%%% 2. Shfichut Damim — destroying a tzelem carrier (human data/identity)
|
||||
%%% 3. Gilui Arayot — collapsing required distinctions
|
||||
%%%
|
||||
%%% These mirror the Talmudic Engine halt modules (Prolog)
|
||||
%%% and the Vav Pipeline halt_conditions (Elixir).
|
||||
%%% @end
|
||||
%%%-------------------------------------------------------------------
|
||||
-module(halt_monitor).
|
||||
|
||||
-behaviour(gen_server).
|
||||
|
||||
-include("sanhedrin.hrl").
|
||||
|
||||
%% API
|
||||
-export([start_link/0, check_case/1, check_vote/1]).
|
||||
|
||||
%% gen_server callbacks
|
||||
-export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
|
||||
|
||||
-define(SERVER, ?MODULE).
|
||||
|
||||
-record(state, {
|
||||
halt_count = 0 :: non_neg_integer(),
|
||||
halt_log = [] :: [{integer(), atom(), binary()}]
|
||||
}).
|
||||
|
||||
%%====================================================================
|
||||
%% API
|
||||
%%====================================================================
|
||||
|
||||
start_link() ->
|
||||
gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
|
||||
|
||||
%% @doc Check a case submission for halt conditions.
|
||||
%% Returns 'clear' or {halt, Condition, Reason}.
|
||||
-spec check_case(#sanhedrin_case{}) -> clear | {halt, atom(), binary()}.
|
||||
check_case(Case) ->
|
||||
gen_server:call(?SERVER, {check_case, Case}).
|
||||
|
||||
%% @doc Check a vote for halt conditions.
|
||||
-spec check_vote(#vote{}) -> clear | {halt, atom(), binary()}.
|
||||
check_vote(Vote) ->
|
||||
gen_server:call(?SERVER, {check_vote, Vote}).
|
||||
|
||||
%%====================================================================
|
||||
%% gen_server callbacks
|
||||
%%====================================================================
|
||||
|
||||
init([]) ->
|
||||
{ok, #state{}}.
|
||||
|
||||
handle_call({check_case, Case}, _From, State) ->
|
||||
Result = do_check_case(Case),
|
||||
NewState = maybe_log_halt(Result, State),
|
||||
{reply, Result, NewState};
|
||||
|
||||
handle_call({check_vote, Vote}, _From, State) ->
|
||||
Result = do_check_vote(Vote),
|
||||
NewState = maybe_log_halt(Result, State),
|
||||
{reply, Result, NewState};
|
||||
|
||||
handle_call(_Request, _From, State) ->
|
||||
{reply, {error, unknown_request}, State}.
|
||||
|
||||
handle_cast(_Msg, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
handle_info(_Info, State) ->
|
||||
{noreply, State}.
|
||||
|
||||
%%====================================================================
|
||||
%% Internal — Halt condition checks
|
||||
%%====================================================================
|
||||
|
||||
do_check_case(Case) ->
|
||||
Context = Case#sanhedrin_case.context,
|
||||
with_chain([
|
||||
fun() -> check_avodah_zarah(Context) end,
|
||||
fun() -> check_shfichut_damim(Context) end,
|
||||
fun() -> check_gilui_arayot(Context) end
|
||||
]).
|
||||
|
||||
do_check_vote(Vote) ->
|
||||
%% Check vote content for halt conditions
|
||||
Position = Vote#vote.position,
|
||||
with_chain([
|
||||
fun() -> check_authority_in_text(Position) end
|
||||
]).
|
||||
|
||||
%% Run checks in chain — return first halt or clear
|
||||
with_chain([]) -> clear;
|
||||
with_chain([Check | Rest]) ->
|
||||
case Check() of
|
||||
clear -> with_chain(Rest);
|
||||
Halt -> Halt
|
||||
end.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% 1. Avodah Zarah — idolatry detection
|
||||
%%--------------------------------------------------------------------
|
||||
check_avodah_zarah(Context) ->
|
||||
%% Check if any non-Torah source is treated as authoritative
|
||||
AuthoritySource = maps:get(authority_source, Context, torah),
|
||||
ValidSources = [torah, l1, specification, sanhedrin_deliberation],
|
||||
case lists:member(AuthoritySource, ValidSources) of
|
||||
true -> clear;
|
||||
false ->
|
||||
{halt, avodah_zarah,
|
||||
iolist_to_binary([
|
||||
<<"Non-Torah authority detected: ">>,
|
||||
atom_to_binary(AuthoritySource, utf8)
|
||||
])}
|
||||
end.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% 2. Shfichut Damim — destruction detection
|
||||
%%--------------------------------------------------------------------
|
||||
check_shfichut_damim(Context) ->
|
||||
%% Check if the case would result in destruction
|
||||
Action = maps:get(action, Context, read),
|
||||
DestructiveActions = [delete, destroy, overwrite, erase],
|
||||
case lists:member(Action, DestructiveActions) of
|
||||
true ->
|
||||
{halt, shfichut_damim,
|
||||
iolist_to_binary([
|
||||
<<"Destructive action: ">>,
|
||||
atom_to_binary(Action, utf8)
|
||||
])};
|
||||
false -> clear
|
||||
end.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% 3. Gilui Arayot — boundary violation detection
|
||||
%%--------------------------------------------------------------------
|
||||
%% The 13 required distinctions that must never collapse:
|
||||
%% specification/interpretation, L1/L3, Torah/external_model,
|
||||
%% ketiv/qere, governance/provision, majority/minority,
|
||||
%% reception/processing, read/write, immutable/mutable,
|
||||
%% sacred/profane, Shabbat/weekday, input/output, human/system
|
||||
check_gilui_arayot(Context) ->
|
||||
BoundaryViolation = maps:get(boundary_violation, Context, none),
|
||||
case BoundaryViolation of
|
||||
none -> clear;
|
||||
false -> clear;
|
||||
Violation ->
|
||||
{halt, gilui_arayot,
|
||||
iolist_to_binary([
|
||||
<<"Boundary collapsed: ">>,
|
||||
io_lib:format("~p", [Violation])
|
||||
])}
|
||||
end.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Text-level authority check (for vote content)
|
||||
%%--------------------------------------------------------------------
|
||||
check_authority_in_text(_Position) ->
|
||||
%% Phase 2: basic check. Phase 3 will use Talmudic Engine
|
||||
%% to detect authority attribution in natural language.
|
||||
clear.
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% Logging
|
||||
%%--------------------------------------------------------------------
|
||||
maybe_log_halt(clear, State) -> State;
|
||||
maybe_log_halt({halt, Condition, Reason}, State) ->
|
||||
Now = erlang:system_time(millisecond),
|
||||
Entry = {Now, Condition, Reason},
|
||||
State#state{
|
||||
halt_count = State#state.halt_count + 1,
|
||||
halt_log = [Entry | State#state.halt_log]
|
||||
}.
|
||||
Reference in new issue
Block a user