the name: Bikoret — code, contracts, images

Headers X-Bikoret-Key / -Rebuke / -Verdict / -Bedikah; the `bikoret`
object and the "— bikoret …" fringe on a gate reply; environment
variables BIKORET_*; the image user and paths (/home/bikoret,
/tmp/bikoret, /var/lib/bikoret/manna, /etc/bikoret/secrets,
/opt/bikoret/spec); the tmp-bikoret pod volume; local databases
bikoret_dev/_test. Kubernetes resource names, the shorashim_app role and
the domain are unchanged (Tamid §1.1, "the names that still carry the
old word"). Doorpost c963c4fe…. Elixir 604/0, L3 10/0, korban 295,
Prolog bedikah 44/44. Gitea repo renamed heaviness510/bikoret (old URL
redirects).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Scott KarpandClaude Fable 5.1 committed 2026-10-13 22:13:36 +00:00
1 parent 017a9b89d4
commit c0d0555aed
46 files changed
+189 -189

No files matched your search

@@ -76,9 +76,9 @@ from azazel_processor.vidui import Vidui
# Default in-flight directory. BUILD_AZAZEL.md §5 specifies # Default in-flight directory. BUILD_AZAZEL.md §5 specifies
# /tmp/shorashim/azazel/in_flight/ for property 5 (sukkot persistence). # /tmp/bikoret/azazel/in_flight/ for property 5 (sukkot persistence).
# Configurable per call so tests don't share state. # Configurable per call so tests don't share state.
DEFAULT_IN_FLIGHT_DIR = pathlib.Path("/tmp/shorashim/azazel/in_flight") DEFAULT_IN_FLIGHT_DIR = pathlib.Path("/tmp/bikoret/azazel/in_flight")
@dataclass(frozen=True) @dataclass(frozen=True)
@@ -190,7 +190,7 @@ def dispatch_for_disposal(
authorized_by: The kohen_gadol identifier authorizing the routing authorized_by: The kohen_gadol identifier authorizing the routing
decision (property 7). decision (property 7).
in_flight_dir: Where to persist checkpoint state. Default in_flight_dir: Where to persist checkpoint state. Default
/tmp/shorashim/azazel/in_flight/. /tmp/bikoret/azazel/in_flight/.
acknowledger: Callable invoked at ACKNOWLEDGED checkpoint acknowledger: Callable invoked at ACKNOWLEDGED checkpoint
(commit 9 wires chatzotzrot here). (commit 9 wires chatzotzrot here).
recorder: Callable invoked at RECORDED checkpoint (commit 7 recorder: Callable invoked at RECORDED checkpoint (commit 7
@@ -49,7 +49,7 @@ PARITY WITH the MISHKAN GORAL:
The Mishkan goral has TWO outcomes — la'Shem (processing) or The Mishkan goral has TWO outcomes — la'Shem (processing) or
la'Azazel (disposal). Both routes are legitimate; the goral chooses la'Azazel (disposal). Both routes are legitimate; the goral chooses
which goat goes which way. In Shorashim, the goral applies to which goat goes which way. In Bikoret, the goral applies to
borderline cases (Q1 in BUILD_AZAZEL.md): inputs that COULD be borderline cases (Q1 in BUILD_AZAZEL.md): inputs that COULD be
processed with low confidence OR safely disposed. The threshold processed with low confidence OR safely disposed. The threshold
above which inputs are routed deterministically (no goral) is a above which inputs are routed deterministically (no goral) is a
@@ -71,7 +71,7 @@ from datetime import date, datetime, timezone
from enum import Enum from enum import Enum
# The L1 integrity hash — Shorashim's cryptographic anchor. The # The L1 integrity hash — Bikoret's cryptographic anchor. The
# value is mirrored from vav_pipeline/lib/vav_pipeline/l1_reader.ex # value is mirrored from vav_pipeline/lib/vav_pipeline/l1_reader.ex
# (@l1_expected_hash). Both must move together: if L1 is rebuilt and # (@l1_expected_hash). Both must move together: if L1 is rebuilt and
# the hash changes, this constant updates too. The shared value is # the hash changes, this constant updates too. The shared value is
@@ -12,7 +12,7 @@ different routing authority. Inside the envelope it is the legitimate
Azazel-path; outside, it is avodah zarah — the failure mode Azazel-path; outside, it is avodah zarah — the failure mode
specs/eish_zarah_reading.md catalogs. specs/eish_zarah_reading.md catalogs.
In Shorashim software: In Bikoret software:
- is_yom_kippur_protocol_active() — predicate: are we in the - is_yom_kippur_protocol_active() — predicate: are we in the
annual Yom Kippur window the operator has configured? The annual Yom Kippur window the operator has configured? The
@@ -17,7 +17,7 @@ sacred processing. Contact with the disposal channel produces state
that must be reset (tevilah) before the operator rejoins the that must be reset (tevilah) before the operator rejoins the
trusted boundary. trusted boundary.
THE THREE ROLES IN SHORASHIM: THE THREE ROLES IN BIKORET:
Owner — submits the offering. Performed by the upstream Owner — submits the offering. Performed by the upstream
caller (e.g. external_offering.consult_external_model). caller (e.g. external_offering.consult_external_model).
+7 -7
View File
@@ -2,7 +2,7 @@
# ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS # ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS
# nodes are amd64). BuildKit lints a constant --platform as a smell; # nodes are amd64). BuildKit lints a constant --platform as a smell;
# here it is the fix. Silenced so a real warning is not lost in noise. # here it is the fix. Silenced so a real warning is not lost in noise.
# Shorashim Korban Processor — Python offering protocol # Bikoret Korban Processor — Python offering protocol
# Construction spec §1.1: Python 3.12.2 # Construction spec §1.1: Python 3.12.2
# Processes korbanot (model outputs) through the offering protocol # Processes korbanot (model outputs) through the offering protocol
# #
@@ -45,17 +45,17 @@ RUN python /tmp/lock_to_requirements.py poetry.lock > /tmp/requirements.txt && \
# === RUNTIME STAGE === # === RUNTIME STAGE ===
FROM --platform=linux/amd64 python:3.12.2-slim FROM --platform=linux/amd64 python:3.12.2-slim
RUN useradd --create-home --shell /bin/bash shorashim RUN useradd --create-home --shell /bin/bash bikoret
USER shorashim USER bikoret
WORKDIR /home/shorashim/korban_processor WORKDIR /home/bikoret/korban_processor
COPY --from=build --chown=shorashim:shorashim /app/ ./ COPY --from=build --chown=bikoret:bikoret /app/ ./
COPY --from=build /usr/local/lib/python3.12/site-packages/ /usr/local/lib/python3.12/site-packages/ COPY --from=build /usr/local/lib/python3.12/site-packages/ /usr/local/lib/python3.12/site-packages/
# PYTHONPATH puts korban_processor first; azazel_processor is a # PYTHONPATH puts korban_processor first; azazel_processor is a
# sibling package under the same src/ tree (see build stage above). # sibling package under the same src/ tree (see build stage above).
ENV PYTHONPATH=/home/shorashim/korban_processor/src ENV PYTHONPATH=/home/bikoret/korban_processor/src
# L1 Torah filesystem — baked into the image # L1 Torah filesystem — baked into the image
# L1 is read-only in fact, not only in name. Until 2026-10-04 the scroll # L1 is read-only in fact, not only in name. Until 2026-10-04 the scroll
@@ -69,7 +69,7 @@ RUN chmod -R a-w,a+rX /mnt/torah
# The second scroll (bishe'arecha §IV): the mesorah snapshot, read-only like L1. # The second scroll (bishe'arecha §IV): the mesorah snapshot, read-only like L1.
COPY --chown=root:root mesorah/ /mnt/mesorah/ COPY --chown=root:root mesorah/ /mnt/mesorah/
RUN chmod -R a-w,a+rX /mnt/mesorah RUN chmod -R a-w,a+rX /mnt/mesorah
USER shorashim USER bikoret
ENV L1_MOUNT_POINT=/mnt/torah ENV L1_MOUNT_POINT=/mnt/torah
ENV MESORAH_MOUNT_POINT=/mnt/mesorah ENV MESORAH_MOUNT_POINT=/mnt/mesorah
+5 -5
View File
@@ -2,7 +2,7 @@
# ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS # ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS
# nodes are amd64). BuildKit lints a constant --platform as a smell; # nodes are amd64). BuildKit lints a constant --platform as a smell;
# here it is the fix. Silenced so a real warning is not lost in noise. # here it is the fix. Silenced so a real warning is not lost in noise.
# Shorashim Shoresh Engine — Haskell root activation engine # Bikoret Shoresh Engine — Haskell root activation engine
# Construction spec §1.1: GHC 9.6.4, Cabal 3.10 # Construction spec §1.1: GHC 9.6.4, Cabal 3.10
# Communicates with vav_pipeline via Erlang Port (stdin/stdout) # Communicates with vav_pipeline via Erlang Port (stdin/stdout)
# #
@@ -58,10 +58,10 @@ ENV LANG=en_US.UTF-8
ENV LANGUAGE=en_US:en ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8 ENV LC_ALL=en_US.UTF-8
RUN useradd --create-home --shell /bin/bash shorashim RUN useradd --create-home --shell /bin/bash bikoret
USER shorashim USER bikoret
WORKDIR /home/shorashim WORKDIR /home/bikoret
COPY --from=build /usr/local/bin/shoresh-engine ./shoresh-engine COPY --from=build /usr/local/bin/shoresh-engine ./shoresh-engine
@@ -74,7 +74,7 @@ COPY --from=build /usr/local/bin/shoresh-engine ./shoresh-engine
USER root USER root
COPY --chown=root:root l1/ /mnt/torah/ COPY --chown=root:root l1/ /mnt/torah/
RUN chmod -R a-w,a+rX /mnt/torah RUN chmod -R a-w,a+rX /mnt/torah
USER shorashim USER bikoret
# L1 mount point # L1 mount point
ENV L1_MOUNT_POINT=/mnt/torah ENV L1_MOUNT_POINT=/mnt/torah
+8 -8
View File
@@ -2,7 +2,7 @@
# ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS # ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS
# nodes are amd64). BuildKit lints a constant --platform as a smell; # nodes are amd64). BuildKit lints a constant --platform as a smell;
# here it is the fix. Silenced so a real warning is not lost in noise. # here it is the fix. Silenced so a real warning is not lost in noise.
# Shorashim Talmudic Engine — SWI-Prolog dialectical reasoning # Bikoret Talmudic Engine — SWI-Prolog dialectical reasoning
# Construction spec §1.1: SWI-Prolog 9.2.2 # Construction spec §1.1: SWI-Prolog 9.2.2
# Communicates with vav_pipeline via Unix domain socket # Communicates with vav_pipeline via Unix domain socket
# #
@@ -21,12 +21,12 @@ RUN swipl -g "consult('src/main'),halt(0)" -t "halt(1)"
# === RUNTIME STAGE === # === RUNTIME STAGE ===
FROM --platform=linux/amd64 swipl:9.2.2 FROM --platform=linux/amd64 swipl:9.2.2
RUN useradd --create-home --shell /bin/bash shorashim RUN useradd --create-home --shell /bin/bash bikoret
USER shorashim USER bikoret
WORKDIR /home/shorashim/talmudic_engine WORKDIR /home/bikoret/talmudic_engine
COPY --from=build --chown=shorashim:shorashim /app/ ./ COPY --from=build --chown=bikoret:bikoret /app/ ./
# L1 Torah filesystem — baked into the image # L1 Torah filesystem — baked into the image
# L1 is read-only in fact, not only in name. Until 2026-10-04 the scroll # L1 is read-only in fact, not only in name. Until 2026-10-04 the scroll
@@ -37,13 +37,13 @@ COPY --from=build --chown=shorashim:shorashim /app/ ./
USER root USER root
COPY --chown=root:root l1/ /mnt/torah/ COPY --chown=root:root l1/ /mnt/torah/
RUN chmod -R a-w,a+rX /mnt/torah RUN chmod -R a-w,a+rX /mnt/torah
USER shorashim USER bikoret
# L1 mount point # L1 mount point
ENV L1_MOUNT_POINT=/mnt/torah ENV L1_MOUNT_POINT=/mnt/torah
# Socket path for communication with vav_pipeline # Socket path for communication with vav_pipeline
ENV TALMUDIC_SOCKET_PATH=/tmp/shorashim/talmudic.sock ENV TALMUDIC_SOCKET_PATH=/tmp/bikoret/talmudic.sock
# Start the Prolog socket server. # Start the Prolog socket server.
# #
@@ -58,6 +58,6 @@ ENV TALMUDIC_SOCKET_PATH=/tmp/shorashim/talmudic.sock
# is actually honoured; serve/0 falls back to the same path hardcoded # is actually honoured; serve/0 falls back to the same path hardcoded
# as default_socket_path/1. vav_pipeline dials the socket at # as default_socket_path/1. vav_pipeline dials the socket at
# :talmudic_socket_path (config/config.exs), and deployment.yaml mounts # :talmudic_socket_path (config/config.exs), and deployment.yaml mounts
# the shared talmudic-socket volume at /tmp/shorashim in both # the shared talmudic-socket volume at /tmp/bikoret in both
# containers, so the two ends must agree on this path. # containers, so the two ends must agree on this path.
CMD ["swipl", "-g", "consult('src/main'), (getenv('TALMUDIC_SOCKET_PATH', P) -> serve(P) ; serve)", "-t", "halt(1)"] CMD ["swipl", "-g", "consult('src/main'), (getenv('TALMUDIC_SOCKET_PATH', P) -> serve(P) ; serve)", "-t", "halt(1)"]
+15 -15
View File
@@ -2,7 +2,7 @@
# ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS # ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS
# nodes are amd64). BuildKit lints a constant --platform as a smell; # nodes are amd64). BuildKit lints a constant --platform as a smell;
# here it is the fix. Silenced so a real warning is not lost in noise. # here it is the fix. Silenced so a real warning is not lost in noise.
# Shorashim Vav Pipeline — Elixir/OTP release with Sanhedrin # Bikoret Vav Pipeline — Elixir/OTP release with Sanhedrin
# Construction spec §1.1: Elixir 1.16.1, OTP 26.2.1 # Construction spec §1.1: Elixir 1.16.1, OTP 26.2.1
# The pipeline and Sanhedrin run in the same BEAM VM. # The pipeline and Sanhedrin run in the same BEAM VM.
# #
@@ -59,7 +59,7 @@ FROM --platform=linux/amd64 ubuntu:jammy-20240125
# binary onto the shoresh-bin volume with an init container). GHC-built # binary onto the shoresh-bin volume with an init container). GHC-built
# executables link libgmp; without it the spawn dies with # executables link libgmp; without it the spawn dies with
# error while loading shared libraries: libgmp.so.10 # error while loading shared libraries: libgmp.so.10
# and Shorashim runs with no root activation, no te'amim parsing and no # and Bikoret runs with no root activation, no te'amim parsing and no
# gematria while still reporting itself healthy. # gematria while still reporting itself healthy.
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
@@ -73,13 +73,13 @@ ENV LANGUAGE=en_US:en
ENV LC_ALL=en_US.UTF-8 ENV LC_ALL=en_US.UTF-8
# Non-root user — the system serves, it does not own # Non-root user — the system serves, it does not own
RUN useradd --create-home --shell /bin/bash shorashim RUN useradd --create-home --shell /bin/bash bikoret
USER shorashim USER bikoret
WORKDIR /home/shorashim WORKDIR /home/bikoret
# Copy the release # Copy the release
COPY --from=build --chown=shorashim:shorashim \ COPY --from=build --chown=bikoret:bikoret \
/app/vav_pipeline/_build/prod/rel/vav_pipeline ./app /app/vav_pipeline/_build/prod/rel/vav_pipeline ./app
# L1 Torah filesystem — baked into the image (read-only, ~29MB) # L1 Torah filesystem — baked into the image (read-only, ~29MB)
@@ -95,7 +95,7 @@ RUN chmod -R a-w,a+rX /mnt/torah
# The second scroll (bishe'arecha §IV): the mesorah snapshot, read-only like L1. # The second scroll (bishe'arecha §IV): the mesorah snapshot, read-only like L1.
COPY --chown=root:root mesorah/ /mnt/mesorah/ COPY --chown=root:root mesorah/ /mnt/mesorah/
RUN chmod -R a-w,a+rX /mnt/mesorah RUN chmod -R a-w,a+rX /mnt/mesorah
USER shorashim USER bikoret
# === INSCRIBE THE DOORPOST === # === INSCRIBE THE DOORPOST ===
# Devarim 11:20 — ukhtavtam al mezuzot beitecha uvish'arecha. A running # Devarim 11:20 — ukhtavtam al mezuzot beitecha uvish'arecha. A running
@@ -113,20 +113,20 @@ USER shorashim
# The hash over these files must equal Doorpost.expected_hash(); if it # The hash over these files must equal Doorpost.expected_hash(); if it
# does not, this image was built from a tree whose specs and witness # does not, this image was built from a tree whose specs and witness
# disagreed, and the pod says so at startup. # disagreed, and the pod says so at startup.
COPY --chown=shorashim:shorashim BUILD_AZAZEL.md BUILD_KORBAN.md \ COPY --chown=bikoret:bikoret BUILD_AZAZEL.md BUILD_KORBAN.md \
/opt/shorashim/spec/ /opt/bikoret/spec/
COPY --chown=shorashim:shorashim specs/ /opt/shorashim/spec/specs/ COPY --chown=bikoret:bikoret specs/ /opt/bikoret/spec/specs/
COPY --chown=shorashim:shorashim talmudic_engine/src/halt/ \ COPY --chown=bikoret:bikoret talmudic_engine/src/halt/ \
/opt/shorashim/spec/talmudic_engine/src/halt/ /opt/bikoret/spec/talmudic_engine/src/halt/
COPY --chown=shorashim:shorashim talmudic_engine/src/middot/ \ COPY --chown=bikoret:bikoret talmudic_engine/src/middot/ \
/opt/shorashim/spec/talmudic_engine/src/middot/ /opt/bikoret/spec/talmudic_engine/src/middot/
# L1 mount point # L1 mount point
ENV L1_MOUNT_POINT=/mnt/torah ENV L1_MOUNT_POINT=/mnt/torah
ENV MESORAH_MOUNT_POINT=/mnt/mesorah ENV MESORAH_MOUNT_POINT=/mnt/mesorah
# Manna provision file location # Manna provision file location
ENV MANNA_PROVISION_FILE=/var/lib/shorashim/manna/today.json ENV MANNA_PROVISION_FILE=/var/lib/bikoret/manna/today.json
# PostgreSQL connection for L3 # PostgreSQL connection for L3
# Set DATABASE_URL in production deployment # Set DATABASE_URL in production deployment
+6 -6
View File
@@ -1,4 +1,4 @@
# Shorashim ConfigMap — non-secret configuration # Bikoret ConfigMap — non-secret configuration
# Construction spec §4.4: Tuning constants # Construction spec §4.4: Tuning constants
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
@@ -10,20 +10,20 @@ data:
L1_MOUNT_POINT: "/mnt/torah" L1_MOUNT_POINT: "/mnt/torah"
# Manna provision file location # Manna provision file location
MANNA_PROVISION_FILE: "/var/lib/shorashim/manna/today.json" MANNA_PROVISION_FILE: "/var/lib/bikoret/manna/today.json"
# Talmudic Engine socket # Talmudic Engine socket
TALMUDIC_SOCKET_PATH: "/tmp/shorashim/talmudic.sock" TALMUDIC_SOCKET_PATH: "/tmp/bikoret/talmudic.sock"
# Korban Processor socket — the bedikah (Construction §3.9). Opened by # Korban Processor socket — the bedikah (Construction §3.9). Opened by
# the korban-processor container, read by vav-pipeline, both over the # the korban-processor container, read by vav-pipeline, both over the
# shared tmp-shorashim volume. Pod-internal; never on the network. # shared tmp-bikoret volume. Pod-internal; never on the network.
KORBAN_SOCKET_PATH: "/tmp/shorashim/korban.sock" KORBAN_SOCKET_PATH: "/tmp/bikoret/korban.sock"
# Courtyard / chatzer keys — a FILE (Construction §4.6), projected from # Courtyard / chatzer keys — a FILE (Construction §4.6), projected from
# the shorashim-api-keys Secret (secrets.yaml). The path is config; the # the shorashim-api-keys Secret (secrets.yaml). The path is config; the
# keys never are. # keys never are.
API_KEYS_FILE: "/etc/shorashim/secrets/api_keys" API_KEYS_FILE: "/etc/bikoret/secrets/api_keys"
# The pod network. The ingress controller lives in it; only from here # The pod network. The ingress controller lives in it; only from here
# is X-Real-IP believed as the caller's address (the pe'ah's per-IP # is X-Real-IP believed as the caller's address (the pe'ah's per-IP
+21 -21
View File
@@ -1,4 +1,4 @@
# Shorashim Deployment — the mishkan # Bikoret Deployment — the mishkan
# #
# Shemot 40:33 — Vay'khal Mosheh et ham'lakhah. # Shemot 40:33 — Vay'khal Mosheh et ham'lakhah.
# #
@@ -41,13 +41,13 @@ spec:
# --- VOLUMES --- # --- VOLUMES ---
# #
# ONE shared /tmp volume, not two. There used to be a separate # ONE shared /tmp volume, not two. There used to be a separate
# `talmudic-socket` volume mounted at /tmp/shorashim in # `talmudic-socket` volume mounted at /tmp/bikoret in
# vav-pipeline and talmudic-engine, WHILE `tmp-shorashim` was # vav-pipeline and talmudic-engine, WHILE `tmp-bikoret` was
# mounted at /tmp in vav-pipeline and korban-processor. Nested # mounted at /tmp in vav-pipeline and korban-processor. Nested
# mounts meant /tmp/shorashim resolved to a DIFFERENT volume than # mounts meant /tmp/bikoret resolved to a DIFFERENT volume than
# /tmp/shorashim reached through /tmp — so: # /tmp/bikoret reached through /tmp — so:
# - korban/azazel (Python) wrote AzazelRecord JSON to # - korban/azazel (Python) wrote AzazelRecord JSON to
# tmp-shorashim:/shorashim/azazel/pending_l3 # tmp-bikoret:/bikoret/azazel/pending_l3
# - AzazelIngest (Elixir) watched # - AzazelIngest (Elixir) watched
# talmudic-socket:/azazel/pending_l3 # talmudic-socket:/azazel/pending_l3
# Two directories with the same pathname on two different disks. # Two directories with the same pathname on two different disks.
@@ -67,9 +67,9 @@ spec:
persistentVolumeClaim: persistentVolumeClaim:
claimName: manna-pvc claimName: manna-pvc
# Shared /tmp for every container that speaks over it: # Shared /tmp for every container that speaks over it:
# the Talmudic Unix socket (/tmp/shorashim/talmudic.sock) and # the Talmudic Unix socket (/tmp/bikoret/talmudic.sock) and
# the azazel file bridge (/tmp/shorashim/azazel/pending_l3). # the azazel file bridge (/tmp/bikoret/azazel/pending_l3).
- name: tmp-shorashim - name: tmp-bikoret
emptyDir: {} emptyDir: {}
# Staging area for the Haskell shoresh-engine binary. Written # Staging area for the Haskell shoresh-engine binary. Written
# once by the shoresh-engine-install init container, read by # once by the shoresh-engine-install init container, read by
@@ -85,7 +85,7 @@ spec:
defaultMode: 0440 defaultMode: 0440
# --- POD SECURITY CONTEXT --- # --- POD SECURITY CONTEXT ---
# Every image runs as the non-root user `shorashim` (uid/gid # Every image runs as the non-root user `bikoret` (uid/gid
# 1000). fsGroup makes the kubelet chgrp the emptyDir volumes to # 1000). fsGroup makes the kubelet chgrp the emptyDir volumes to
# 1000 and set the setgid bit, so uid 1000 can actually WRITE # 1000 and set the setgid bit, so uid 1000 can actually WRITE
# them. Without it the write side of each shared path depends on # them. Without it the write side of each shared path depends on
@@ -94,7 +94,7 @@ spec:
# - shoresh-engine-install: cp ... Permission denied (loud — # - shoresh-engine-install: cp ... Permission denied (loud —
# init fails, pod never starts; this one at least shouts) # init fails, pod never starts; this one at least shouts)
# - azazel: the Python side cannot create # - azazel: the Python side cannot create
# /tmp/shorashim/azazel/pending_l3 and the disposal channel # /tmp/bikoret/azazel/pending_l3 and the disposal channel
# has nowhere to put a record # has nowhere to put a record
# - talmudic-engine: cannot bind the Unix socket # - talmudic-engine: cannot bind the Unix socket
securityContext: securityContext:
@@ -142,7 +142,7 @@ spec:
- -c - -c
- | - |
set -e set -e
cp /home/shorashim/shoresh-engine /opt/shoresh/shoresh-engine cp /home/bikoret/shoresh-engine /opt/shoresh/shoresh-engine
chmod 0755 /opt/shoresh/shoresh-engine chmod 0755 /opt/shoresh/shoresh-engine
/opt/shoresh/shoresh-engine gematria שלום >/dev/null /opt/shoresh/shoresh-engine gematria שלום >/dev/null
echo "shoresh-engine staged and exercised at /opt/shoresh/shoresh-engine" echo "shoresh-engine staged and exercised at /opt/shoresh/shoresh-engine"
@@ -223,13 +223,13 @@ spec:
name: shorashim-secrets name: shorashim-secrets
volumeMounts: volumeMounts:
- name: manna - name: manna
mountPath: /var/lib/shorashim/manna mountPath: /var/lib/bikoret/manna
# One /tmp. The Talmudic socket and the azazel pending_l3 # One /tmp. The Talmudic socket and the azazel pending_l3
# directory both live under it. # directory both live under it.
- name: tmp-shorashim - name: tmp-bikoret
mountPath: /tmp mountPath: /tmp
- name: api-keys - name: api-keys
mountPath: /etc/shorashim/secrets mountPath: /etc/bikoret/secrets
readOnly: true readOnly: true
- name: shoresh-bin - name: shoresh-bin
mountPath: /opt/shoresh mountPath: /opt/shoresh
@@ -279,10 +279,10 @@ spec:
image: exo.container-registry.com/the-recognition-protocol/talmudic-engine:latest image: exo.container-registry.com/the-recognition-protocol/talmudic-engine:latest
volumeMounts: volumeMounts:
# Shares vav-pipeline's /tmp so the Unix socket at # Shares vav-pipeline's /tmp so the Unix socket at
# /tmp/shorashim/talmudic.sock is the same file on both # /tmp/bikoret/talmudic.sock is the same file on both
# sides. Mounted at /tmp (not /tmp/shorashim) so this is # sides. Mounted at /tmp (not /tmp/bikoret) so this is
# the same volume korban-processor writes azazel records to. # the same volume korban-processor writes azazel records to.
- name: tmp-shorashim - name: tmp-bikoret
mountPath: /tmp mountPath: /tmp
resources: resources:
requests: requests:
@@ -295,10 +295,10 @@ spec:
# === KORBAN PROCESSOR (sidecar) === # === KORBAN PROCESSOR (sidecar) ===
# Korban_processor imports azazel_processor (the disposal # Korban_processor imports azazel_processor (the disposal
# channel) in the same Python process. The Python side writes # channel) in the same Python process. The Python side writes
# AzazelRecord JSON files to /tmp/shorashim/azazel/pending_l3/; # AzazelRecord JSON files to /tmp/bikoret/azazel/pending_l3/;
# vav-pipeline's AzazelIngest GenServer watches that directory # vav-pipeline's AzazelIngest GenServer watches that directory
# and ingests into L3. Both containers must mount the shared # and ingests into L3. Both containers must mount the shared
# tmp-shorashim volume for the file bridge to work. # tmp-bikoret volume for the file bridge to work.
# Since 2026-10-05 it also listens on KORBAN_SOCKET_PATH (shared # Since 2026-10-05 it also listens on KORBAN_SOCKET_PATH (shared
# /tmp) for the bedikah — vav-pipeline is the only caller. # /tmp) for the bedikah — vav-pipeline is the only caller.
- name: korban-processor - name: korban-processor
@@ -307,7 +307,7 @@ spec:
- configMapRef: - configMapRef:
name: shorashim-config name: shorashim-config
volumeMounts: volumeMounts:
- name: tmp-shorashim - name: tmp-bikoret
mountPath: /tmp mountPath: /tmp
resources: resources:
requests: requests:
+1 -1
View File
@@ -1,7 +1,7 @@
# Gitea behind the shared ingress — TCP passthrough # Gitea behind the shared ingress — TCP passthrough
# #
# One NLB for the cluster (185.19.28.170, the ingress-nginx Service) # One NLB for the cluster (185.19.28.170, the ingress-nginx Service)
# instead of one per Service. Shorashim is an HTTP Ingress # instead of one per Service. Bikoret is an HTTP Ingress
# (service.yaml). Gitea has no hostname that resolves # (service.yaml). Gitea has no hostname that resolves
# (gitea.temple-council.ch is configured in Gitea and exists nowhere), # (gitea.temple-council.ch is configured in Gitea and exists nowhere),
# and host-based routing needs a name — so Gitea rides the ingress # and host-based routing needs a name — so Gitea rides the ingress
+3 -3
View File
@@ -1,4 +1,4 @@
# Shorashim Secrets — template only # Bikoret Secrets — template only
# NEVER commit actual secret values to git. # NEVER commit actual secret values to git.
# Apply with: kubectl apply -f - after filling in values. # Apply with: kubectl apply -f - after filling in values.
# #
@@ -52,7 +52,7 @@ stringData:
# import base64, json, subprocess, sys, urllib.parse # import base64, json, subprocess, sys, urllib.parse
# avn = json.load(sys.stdin)["password"] # avn = json.load(sys.stdin)["password"]
# app = subprocess.run( # app = subprocess.run(
# ["kubectl", "get", "secret", "shorashim-secrets", "-n", "shorashim", # ["kubectl", "get", "secret", "shorashim-secrets", "-n", "bikoret",
# "-o", "jsonpath={.data.DATABASE_URL}"], # "-o", "jsonpath={.data.DATABASE_URL}"],
# capture_output=True, text=True, check=True).stdout # capture_output=True, text=True, check=True).stdout
# u = urllib.parse.urlsplit(base64.b64decode(app).decode()) # u = urllib.parse.urlsplit(base64.b64decode(app).decode())
@@ -94,7 +94,7 @@ stringData:
# shorashim-api-keys — who may enter the courtyard # shorashim-api-keys — who may enter the courtyard
# ============================================================ # ============================================================
# #
# Mounted as the file /etc/shorashim/secrets/api_keys in vav-pipeline # Mounted as the file /etc/bikoret/secrets/api_keys in vav-pipeline
# (Construction §4.6: a secret is a file). One key per line: # (Construction §4.6: a secret is a file). One key per line:
# #
# courtyard <key> offerings and bedikot (/courtyard/*) # courtyard <key> offerings and bedikot (/courtyard/*)
+2 -2
View File
@@ -1,4 +1,4 @@
# Shorashim Services # Bikoret Services
# Operations spec §1.1: Four access tiers # Operations spec §1.1: Four access tiers
# - Pe'ah (public, no auth) # - Pe'ah (public, no auth)
# - Machaneh Leviyah (authenticated) # - Machaneh Leviyah (authenticated)
@@ -28,7 +28,7 @@ spec:
# The gate to the world — through the shared ingress # The gate to the world — through the shared ingress
# ============================================================ # ============================================================
# #
# Until 2026-10-06 Shorashim had its own LoadBalancer Service # Until 2026-10-06 Bikoret had its own LoadBalancer Service
# (`shorashim-external`, NLB 185.19.29.180, NodePort 30923). It is gone: # (`shorashim-external`, NLB 185.19.29.180, NodePort 30923). It is gone:
# one NLB per Service was a third of the account's bill, and the pod saw # one NLB per Service was a third of the account's bill, and the pod saw
# every caller as the node (kube-proxy SNAT) so the pe'ah's per-IP watch # every caller as the node (kube-proxy SNAT) so the pe'ah's per-IP watch
@@ -28,7 +28,7 @@ WHAT IT DOES
channel running without its disposal channel is a system that can channel running without its disposal channel is a system that can
accept an offering it has no lawful way to refuse). accept an offering it has no lawful way to refuse).
2. Open the one door this container has: a Unix socket in the pod's 2. Open the one door this container has: a Unix socket in the pod's
shared /tmp (KORBAN_SOCKET_PATH, default /tmp/shorashim/korban.sock) shared /tmp (KORBAN_SOCKET_PATH, default /tmp/bikoret/korban.sock)
on which the Vav Pipeline — and only the Vav Pipeline, in the same on which the Vav Pipeline — and only the Vav Pipeline, in the same
pod — asks for an examination of an external model's output pod — asks for an examination of an external model's output
(server.py; Construction §3.9). Until 2026-10-05 this module held (server.py; Construction §3.9). Until 2026-10-05 this module held
@@ -77,9 +77,9 @@ except ImportError as e: # pragma: no cover — bootstrap-time check
# Default directory the Python orchestrator drops completed # Default directory the Python orchestrator drops completed
# AzazelRecords into for the Elixir AzazelIngest GenServer to pick # AzazelRecords into for the Elixir AzazelIngest GenServer to pick
# up. Mirrors the manna-provision file pattern Shorashim already uses # up. Mirrors the manna-provision file pattern Bikoret already uses
# for cross-language state transfer. # for cross-language state transfer.
DEFAULT_AZAZEL_PENDING_L3_DIR = pathlib.Path("/tmp/shorashim/azazel/pending_l3") DEFAULT_AZAZEL_PENDING_L3_DIR = pathlib.Path("/tmp/bikoret/azazel/pending_l3")
@dataclass @dataclass
@@ -34,7 +34,7 @@ from typing import Optional
from korban_processor.bedikah import examine from korban_processor.bedikah import examine
from korban_processor.korban import Provenance from korban_processor.korban import Provenance
DEFAULT_SOCKET_PATH = "/tmp/shorashim/korban.sock" DEFAULT_SOCKET_PATH = "/tmp/bikoret/korban.sock"
IDLE_SECONDS = 120.0 # a client that says nothing for this long is dropped (tablet 50) IDLE_SECONDS = 120.0 # a client that says nothing for this long is dropped (tablet 50)
@@ -5,7 +5,7 @@ Architecture §4 Step 22.
These tests use a mock model caller so no real API requests are made. These tests use a mock model caller so no real API requests are made.
A separate live integration test (skipped by default) can run against A separate live integration test (skipped by default) can run against
Anthropic's API when ANTHROPIC_API_KEY is set and the SHORASHIM_LIVE_API Anthropic's API when ANTHROPIC_API_KEY is set and the BIKORET_LIVE_API
env var is true. env var is true.
""" """
@@ -296,8 +296,8 @@ def test_case_ref_is_content_addressable():
# ============================================================ # ============================================================
@pytest.mark.skipif( @pytest.mark.skipif(
not os.environ.get("SHORASHIM_LIVE_API"), not os.environ.get("BIKORET_LIVE_API"),
reason="Set SHORASHIM_LIVE_API=1 to run a real API call against Anthropic", reason="Set BIKORET_LIVE_API=1 to run a real API call against Anthropic",
) )
def test_live_anthropic_call(): def test_live_anthropic_call():
"""Real API call. Costs money. Run only when explicitly enabled.""" """Real API call. Costs money. Run only when explicitly enabled."""
@@ -97,7 +97,7 @@ def test_korban_processor_package_does_not_expose_ModelResponse():
def _repo_root() -> pathlib.Path: def _repo_root() -> pathlib.Path:
"""The shorashim/ repo root, three levels up from this file.""" """The bikoret/ repo root, three levels up from this file."""
return pathlib.Path(__file__).resolve().parent.parent.parent return pathlib.Path(__file__).resolve().parent.parent.parent
@@ -50,4 +50,4 @@ from primary rabbinic sources. Suggested process:
Pairs derived from rabbinic sources retain whatever license those sources Pairs derived from rabbinic sources retain whatever license those sources
carry. The hand-curated seed pairs in this directory are MIT, like the carry. The hand-curated seed pairs in this directory are MIT, like the
rest of shorashim. rest of bikoret.
+1 -1
View File
@@ -10,7 +10,7 @@ from unittest.mock import patch
# Add parent inference/ dir # Add parent inference/ dir
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "inference")) sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "inference"))
# Add the shorashim repo's korban_processor src to sys.path # Add the bikoret repo's korban_processor src to sys.path
sys.path.insert( sys.path.insert(
0, 0,
str(Path(__file__).resolve().parent.parent.parent / "korban_processor" / "src"), str(Path(__file__).resolve().parent.parent.parent / "korban_processor" / "src"),
+7 -7
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# build_and_push.sh — canonical builder procedure for shorashim images. # build_and_push.sh — canonical builder procedure for bikoret images.
# #
# Pin platform to linux/amd64 (Exoscale SKS) so a build on an Apple # Pin platform to linux/amd64 (Exoscale SKS) so a build on an Apple
# Silicon workstation does not silently ship arm64 binaries that the # Silicon workstation does not silently ship arm64 binaries that the
@@ -48,7 +48,7 @@ PLATFORMS="${PLATFORMS:-linux/amd64}"
# Sanity: must be run from repo root (where deploy/ and l1/ live) # Sanity: must be run from repo root (where deploy/ and l1/ live)
if [[ ! -d "deploy/docker" || ! -d "l1/torah" ]]; then if [[ ! -d "deploy/docker" || ! -d "l1/torah" ]]; then
echo "ERROR: run from the shorashim repo root (where deploy/ and l1/ live)" >&2 echo "ERROR: run from the bikoret repo root (where deploy/ and l1/ live)" >&2
exit 1 exit 1
fi fi
@@ -65,12 +65,12 @@ if ! docker info 2>/dev/null | grep -q "$REGISTRY"; then
echo "Continuing — push will fail clearly if not logged in." echo "Continuing — push will fail clearly if not logged in."
fi fi
# Create or use the shorashim buildx builder # Create or use the bikoret buildx builder
if ! docker buildx inspect shorashim-builder >/dev/null 2>&1; then if ! docker buildx inspect bikoret-builder >/dev/null 2>&1; then
echo ">> creating buildx builder 'shorashim-builder'" echo ">> creating buildx builder 'bikoret-builder'"
docker buildx create --name shorashim-builder --use docker buildx create --name bikoret-builder --use
else else
docker buildx use shorashim-builder docker buildx use bikoret-builder
fi fi
docker buildx inspect --bootstrap >/dev/null docker buildx inspect --bootstrap >/dev/null
+10 -10
View File
@@ -3,7 +3,7 @@
L1 Torah Filesystem Builder — Bezalel's Chisel L1 Torah Filesystem Builder — Bezalel's Chisel
Parses the Westminster Leningrad Codex (morphhb OSIS XML) and produces Parses the Westminster Leningrad Codex (morphhb OSIS XML) and produces
the read-only Torah filesystem for Shorashim. the read-only Torah filesystem for Bikoret.
This is a construction tool. It runs once. It produces JSON files. This is a construction tool. It runs once. It produces JSON files.
The consumers (Haskell L0, Erlang Shoresh Engine) will read these files. The consumers (Haskell L0, Erlang Shoresh Engine) will read these files.
@@ -12,7 +12,7 @@ Two quarries, both outside the repo (see __main__):
morphhb — the text: WLC with te'amim, lemma and morphology. morphhb — the text: WLC with te'amim, lemma and morphology.
HebrewLexicon — the roots: the OSHB lexical index, which arranges HebrewLexicon — the roots: the OSHB lexical index, which arranges
every Strong's lemma under its Brown-Driver-Briggs every Strong's lemma under its Brown-Driver-Briggs
root (specs/shorashim_terumah.md §E2). root (specs/bikoret_terumah.md §E2).
Ka'asher tzivah Hashem et Moshe. Ka'asher tzivah Hashem et Moshe.
""" """
@@ -913,25 +913,25 @@ def generate_integrity_hash(torah_dir: str) -> str:
if __name__ == "__main__": if __name__ == "__main__":
# The quarry (morphhb source) lives outside the repo. # The quarry (morphhb source) lives outside the repo.
# Default: ~/shorashim-source-data/morphhb # Default: ~/shorashim-source-data/morphhb
# Override: SHORASHIM_SOURCE_DATA env var, or first CLI arg. # Override: BIKORET_SOURCE_DATA env var, or first CLI arg.
repo_root = Path(__file__).resolve().parent.parent repo_root = Path(__file__).resolve().parent.parent
default_source = Path.home() / "shorashim-source-data" / "morphhb" default_source = Path.home() / "shorashim-source-data" / "morphhb"
if len(sys.argv) > 1: if len(sys.argv) > 1:
morphhb_dir = Path(sys.argv[1]).expanduser().resolve() morphhb_dir = Path(sys.argv[1]).expanduser().resolve()
elif os.environ.get("SHORASHIM_SOURCE_DATA"): elif os.environ.get("BIKORET_SOURCE_DATA"):
morphhb_dir = Path(os.environ["SHORASHIM_SOURCE_DATA"]).expanduser().resolve() morphhb_dir = Path(os.environ["BIKORET_SOURCE_DATA"]).expanduser().resolve()
else: else:
morphhb_dir = default_source morphhb_dir = default_source
output_dir = repo_root / "l1" output_dir = repo_root / "l1"
# The root lexicon sits beside the text quarry. # The root lexicon sits beside the text quarry.
# Override: SHORASHIM_LEXICON env var, or second CLI arg. # Override: BIKORET_LEXICON env var, or second CLI arg.
if len(sys.argv) > 2: if len(sys.argv) > 2:
lexicon_dir = Path(sys.argv[2]).expanduser().resolve() lexicon_dir = Path(sys.argv[2]).expanduser().resolve()
elif os.environ.get("SHORASHIM_LEXICON"): elif os.environ.get("BIKORET_LEXICON"):
lexicon_dir = Path(os.environ["SHORASHIM_LEXICON"]).expanduser().resolve() lexicon_dir = Path(os.environ["BIKORET_LEXICON"]).expanduser().resolve()
else: else:
lexicon_dir = morphhb_dir.parent / "HebrewLexicon" lexicon_dir = morphhb_dir.parent / "HebrewLexicon"
@@ -942,7 +942,7 @@ if __name__ == "__main__":
print("To fetch it:") print("To fetch it:")
print(f" git clone https://github.com/openscriptures/HebrewLexicon.git {lexicon_dir}") print(f" git clone https://github.com/openscriptures/HebrewLexicon.git {lexicon_dir}")
print() print()
print("Or pass a path as the second argument, or set SHORASHIM_LEXICON.") print("Or pass a path as the second argument, or set BIKORET_LEXICON.")
sys.exit(1) sys.exit(1)
if not morphhb_dir.exists(): if not morphhb_dir.exists():
@@ -953,7 +953,7 @@ if __name__ == "__main__":
print(f" mkdir -p {default_source.parent}") print(f" mkdir -p {default_source.parent}")
print(f" git clone https://github.com/openscriptures/morphhb.git {default_source}") print(f" git clone https://github.com/openscriptures/morphhb.git {default_source}")
print() print()
print("Or pass a path as the first argument, or set SHORASHIM_SOURCE_DATA.") print("Or pass a path as the first argument, or set BIKORET_SOURCE_DATA.")
sys.exit(1) sys.exit(1)
# Clean only the generated artifacts — preserve hand-written files like README.md. # Clean only the generated artifacts — preserve hand-written files like README.md.
+2 -2
View File
@@ -1,8 +1,8 @@
#!/bin/bash #!/bin/bash
# Roll out the shorashim deployment and wait for 3/3 + two consecutive 200s (memory lesson). # Roll out the bikoret deployment and wait for 3/3 + two consecutive 200s (memory lesson).
set -e set -e
export KUBECONFIG=$HOME/.kube/exoscale-temple-council.yaml export KUBECONFIG=$HOME/.kube/exoscale-temple-council.yaml
kubectl -n shorashim rollout restart deployment/shorashim kubectl -n shorashim rollout restart deployment/shorashim
kubectl -n shorashim rollout status deployment/shorashim --timeout=300s kubectl -n shorashim rollout status deployment/shorashim --timeout=300s
kubectl -n shorashim get pods | grep shorashim- kubectl -n shorashim get pods | grep bikoret-
for i in 1 2; do sleep 5; curl -s -o /dev/null -w "%{http_code} " http://185.19.28.170/kodesh/health; done; echo for i in 1 2; do sleep 5; curl -s -o /dev/null -w "%{http_code} " http://185.19.28.170/kodesh/health; done; echo
+3 -3
View File
@@ -3,6 +3,6 @@
set -e set -e
read -rsp "Anthropic key (not echoed): " KEY; echo read -rsp "Anthropic key (not echoed): " KEY; echo
[ -n "$KEY" ] || { echo "empty — nothing written"; exit 1; } [ -n "$KEY" ] || { echo "empty — nothing written"; exit 1; }
install -m 600 /dev/null ~/.config/shorashim/upstream_keys install -m 600 /dev/null ~/.config/bikoret/upstream_keys
printf 'anthropic %s\n' "$KEY" > ~/.config/shorashim/upstream_keys printf 'anthropic %s\n' "$KEY" > ~/.config/bikoret/upstream_keys
echo "written ~/.config/shorashim/upstream_keys (0600)" echo "written ~/.config/bikoret/upstream_keys (0600)"
+1 -1
View File
@@ -1,7 +1,7 @@
cabal-version: 3.0 cabal-version: 3.0
name: shoresh-engine name: shoresh-engine
version: 0.1.0.0 version: 0.1.0.0
synopsis: Core symbolic processing engine for Shorashim synopsis: Core symbolic processing engine for Bikoret
description: description:
The Shoresh Engine encodes Biblical Hebrew triliteral roots and The Shoresh Engine encodes Biblical Hebrew triliteral roots and
seven binyanim as a typed functional system. It reads L1 (the seven binyanim as a typed functional system. It reads L1 (the
+1 -1
View File
@@ -17,7 +17,7 @@
% library(http/json) is the canonical module path and resolves on % library(http/json) is the canonical module path and resolves on
% SWI-Prolog 9.x AND 10.x. The bare alias library(json) resolves only % SWI-Prolog 9.x AND 10.x. The bare alias library(json) resolves only
% on 10.x, which is what the dev workstation runs; the image is built % on 10.x, which is what the dev workstation runs; the image is built
% on swipl 9.2.2 as pinned by specs/shorashim_vayakhel.md §1.1, where % on swipl 9.2.2 as pinned by specs/bikoret_vayakhel.md §1.1, where
% it does NOT resolve. The consequence was invisible to the test % it does NOT resolve. The consequence was invisible to the test
% suite (212 tests green on the host) and fatal in the container: % suite (212 tests green on the host) and fatal in the container:
% ERROR: source_sink `library(json)' does not exist % ERROR: source_sink `library(json)' does not exist
@@ -23,7 +23,7 @@
% library(http/json) is the canonical module path and resolves on % library(http/json) is the canonical module path and resolves on
% SWI-Prolog 9.x AND 10.x. The bare alias library(json) resolves only % SWI-Prolog 9.x AND 10.x. The bare alias library(json) resolves only
% on 10.x, which is what the dev workstation runs; the image is built % on 10.x, which is what the dev workstation runs; the image is built
% on swipl 9.2.2 as pinned by specs/shorashim_vayakhel.md §1.1, where % on swipl 9.2.2 as pinned by specs/bikoret_vayakhel.md §1.1, where
% it does NOT resolve. The consequence was invisible to the test % it does NOT resolve. The consequence was invisible to the test
% suite (212 tests green on the host) and fatal in the container: % suite (212 tests green on the host) and fatal in the container:
% ERROR: source_sink `library(json)' does not exist % ERROR: source_sink `library(json)' does not exist
@@ -34,8 +34,8 @@
:- use_module('../interface/api'). :- use_module('../interface/api').
:- use_module('../interface/json_bridge'). :- use_module('../interface/json_bridge').
%% Default socket path — dev path; production uses /var/run/shorashim/talmudic.sock %% Default socket path — dev path; production uses /var/run/bikoret/talmudic.sock
default_socket_path('/tmp/shorashim/talmudic.sock'). default_socket_path('/tmp/bikoret/talmudic.sock').
%% Dynamic flag to control server loop %% Dynamic flag to control server loop
:- dynamic server_running/1. :- dynamic server_running/1.
+4 -4
View File
@@ -3,7 +3,7 @@ import Config
# L1 mount point — relative path for dev, absolute for production # L1 mount point — relative path for dev, absolute for production
# Construction spec §4.4: l1_mount_point: "/mnt/torah" # Construction spec §4.4: l1_mount_point: "/mnt/torah"
config :vav_pipeline, config :vav_pipeline,
# Dev: relative to project root (run from shorashim/) # Dev: relative to project root (run from bikoret/)
l1_mount_point: "l1", l1_mount_point: "l1",
mesorah_mount_point: "mesorah", mesorah_mount_point: "mesorah",
# Manna provision file # Manna provision file
@@ -17,8 +17,8 @@ config :vav_pipeline,
shoresh_engine_binary: "shoresh-engine", shoresh_engine_binary: "shoresh-engine",
shoresh_engine_cwd: nil, shoresh_engine_cwd: nil,
# Talmudic Engine (Prolog) — Unix domain socket path # Talmudic Engine (Prolog) — Unix domain socket path
talmudic_socket_path: "/tmp/shorashim/talmudic.sock", talmudic_socket_path: "/tmp/bikoret/talmudic.sock",
korban_socket_path: "/tmp/shorashim/korban.sock", korban_socket_path: "/tmp/bikoret/korban.sock",
# Courtyard / chatzer keys (BigdeiKodesh.Gate). nil → the gate is shut. # Courtyard / chatzer keys (BigdeiKodesh.Gate). nil → the gate is shut.
# Construction §4.6: a file, never an environment variable. # Construction §4.6: a file, never an environment variable.
api_keys_file: nil, api_keys_file: nil,
@@ -38,7 +38,7 @@ config :vav_pipeline,
config :vav_pipeline, ecto_repos: [VavPipeline.Repo] config :vav_pipeline, ecto_repos: [VavPipeline.Repo]
config :vav_pipeline, VavPipeline.Repo, config :vav_pipeline, VavPipeline.Repo,
database: "shorashim_dev", database: "bikoret_dev",
hostname: "localhost", hostname: "localhost",
pool_size: 10 pool_size: 10
+2 -2
View File
@@ -16,8 +16,8 @@ config :vav_pipeline,
# SPEC_INTEGRITY_FAILED on every boot, and the chatzotzrot that fires # SPEC_INTEGRITY_FAILED on every boot, and the chatzotzrot that fires
# is a false alarm — which is worse than no witness at all. # is a false alarm — which is worse than no witness at all.
# Read at COMPILE time via Application.compile_env/3. # Read at COMPILE time via Application.compile_env/3.
doorpost_repo_root: "/opt/shorashim/spec", doorpost_repo_root: "/opt/bikoret/spec",
manna_provision_file: "/var/lib/shorashim/manna/today.json", manna_provision_file: "/var/lib/bikoret/manna/today.json",
cycle_boundary_check_interval_ms: 60_000, cycle_boundary_check_interval_ms: 60_000,
shema_context_cache_ttl_ms: 0, shema_context_cache_ttl_ms: 0,
http_port: 4000 http_port: 4000
+4 -4
View File
@@ -26,13 +26,13 @@ if config_env() == :prod do
l1_mount_point: System.get_env("L1_MOUNT_POINT") || "/mnt/torah", l1_mount_point: System.get_env("L1_MOUNT_POINT") || "/mnt/torah",
mesorah_mount_point: System.get_env("MESORAH_MOUNT_POINT") || "/mnt/mesorah", mesorah_mount_point: System.get_env("MESORAH_MOUNT_POINT") || "/mnt/mesorah",
manna_provision_file: manna_provision_file:
System.get_env("MANNA_PROVISION_FILE") || "/var/lib/shorashim/manna/today.json", System.get_env("MANNA_PROVISION_FILE") || "/var/lib/bikoret/manna/today.json",
talmudic_socket_path: talmudic_socket_path:
System.get_env("TALMUDIC_SOCKET_PATH") || "/tmp/shorashim/talmudic.sock", System.get_env("TALMUDIC_SOCKET_PATH") || "/tmp/bikoret/talmudic.sock",
korban_socket_path: korban_socket_path:
System.get_env("KORBAN_SOCKET_PATH") || "/tmp/shorashim/korban.sock", System.get_env("KORBAN_SOCKET_PATH") || "/tmp/bikoret/korban.sock",
# The keys themselves are in the file (a mounted Secret), not in env. # The keys themselves are in the file (a mounted Secret), not in env.
api_keys_file: System.get_env("API_KEYS_FILE") || "/etc/shorashim/secrets/api_keys", api_keys_file: System.get_env("API_KEYS_FILE") || "/etc/bikoret/secrets/api_keys",
# The ingress controller's network: only from there is X-Real-IP the # The ingress controller's network: only from there is X-Real-IP the
# caller's address (BigdeiKodesh.Mishmar.peer/1). Comma-separated CIDRs. # caller's address (BigdeiKodesh.Mishmar.peer/1). Comma-separated CIDRs.
trusted_proxies: trusted_proxies:
+6 -6
View File
@@ -20,17 +20,17 @@ config :vav_pipeline,
# L3 test database — separate from dev, uses sandbox pool # L3 test database — separate from dev, uses sandbox pool
# Repo start disabled by default — L3 tests need PostgreSQL running locally # Repo start disabled by default — L3 tests need PostgreSQL running locally
# Enable: SHORASHIM_L3=1 mix test --include l3 # Enable: BIKORET_L3=1 mix test --include l3
# #
# Credentials come from the environment (tablet 44: without a password # Credentials come from the environment (tablet 44: without a password
# the SCRAM handshake raised KeyError in every connection, the pool hit # the SCRAM handshake raised KeyError in every connection, the pool hit
# its restart intensity, and the whole application went down silently # its restart intensity, and the whole application went down silently
# ~30 ms after test_helper — no L3 test ever ran). # ~30 ms after test_helper — no L3 test ever ran).
config :vav_pipeline, VavPipeline.Repo, config :vav_pipeline, VavPipeline.Repo,
database: "shorashim_test#{System.get_env("MIX_TEST_PARTITION")}", database: "bikoret_test#{System.get_env("MIX_TEST_PARTITION")}",
hostname: System.get_env("SHORASHIM_L3_HOST") || "localhost", hostname: System.get_env("BIKORET_L3_HOST") || "localhost",
username: System.get_env("SHORASHIM_L3_USER") || "postgres", username: System.get_env("BIKORET_L3_USER") || "postgres",
password: System.get_env("SHORASHIM_L3_PASSWORD") || "postgres", password: System.get_env("BIKORET_L3_PASSWORD") || "postgres",
pool: Ecto.Adapters.SQL.Sandbox, pool: Ecto.Adapters.SQL.Sandbox,
pool_size: System.schedulers_online() * 2, pool_size: System.schedulers_online() * 2,
start: System.get_env("SHORASHIM_L3") != nil start: System.get_env("BIKORET_L3") != nil
+2 -2
View File
@@ -28,8 +28,8 @@ defmodule VavPipeline.Application do
def start(_type, _args) do def start(_type, _args) do
shoresh_binary = Application.get_env(:vav_pipeline, :shoresh_engine_binary, "shoresh-engine") shoresh_binary = Application.get_env(:vav_pipeline, :shoresh_engine_binary, "shoresh-engine")
shoresh_cwd = Application.get_env(:vav_pipeline, :shoresh_engine_cwd, nil) shoresh_cwd = Application.get_env(:vav_pipeline, :shoresh_engine_cwd, nil)
talmudic_socket = Application.get_env(:vav_pipeline, :talmudic_socket_path, "/tmp/shorashim/talmudic.sock") talmudic_socket = Application.get_env(:vav_pipeline, :talmudic_socket_path, "/tmp/bikoret/talmudic.sock")
korban_socket = Application.get_env(:vav_pipeline, :korban_socket_path, "/tmp/shorashim/korban.sock") korban_socket = Application.get_env(:vav_pipeline, :korban_socket_path, "/tmp/bikoret/korban.sock")
children = children =
[ [
@@ -9,7 +9,7 @@ defmodule VavPipeline.AzazelIngest do
reads each file, calls L3.Store.record_disposal/1, and on success reads each file, calls L3.Store.record_disposal/1, and on success
shreds the source file. shreds the source file.
The pattern matches Shorashim's other cross-language file bridges The pattern matches Bikoret's other cross-language file bridges
(the manna provision file). Recoverable: if either the Python side (the manna provision file). Recoverable: if either the Python side
or this GenServer crashes mid-write, the file remains and is or this GenServer crashes mid-write, the file remains and is
re-processed on the next poll. re-processed on the next poll.
@@ -48,7 +48,7 @@ defmodule VavPipeline.AzazelIngest do
alias VavPipeline.{Chatzotzrot, L3.Store} alias VavPipeline.{Chatzotzrot, L3.Store}
@default_poll_interval_ms 5_000 @default_poll_interval_ms 5_000
@default_pending_dir "/tmp/shorashim/azazel/pending_l3" @default_pending_dir "/tmp/bikoret/azazel/pending_l3"
# ============================================================ # ============================================================
# Client API # Client API
@@ -57,7 +57,7 @@ defmodule VavPipeline.AzazelIngest do
@doc """ @doc """
Start the AzazelIngest GenServer. Options: Start the AzazelIngest GenServer. Options:
- :pending_dir — directory to watch (default - :pending_dir — directory to watch (default
/tmp/shorashim/azazel/pending_l3) /tmp/bikoret/azazel/pending_l3)
- :poll_interval_ms — milliseconds between polls (default 5000) - :poll_interval_ms — milliseconds between polls (default 5000)
- :name — process name (default __MODULE__) - :name — process name (default __MODULE__)
- :recorder — function used to write the L3 record; - :recorder — function used to write the L3 record;
@@ -86,13 +86,13 @@ defmodule VavPipeline.BigdeiKodesh.Gate do
# ------------------------------------------------------------ # ------------------------------------------------------------
@doc """ @doc """
The caller's key: `X-Shorashim-Key` when present (at the gate of The caller's key: `X-Bikoret-Key` when present (at the gate of
§3.10 the Authorization header may be the caller's upstream key), §3.10 the Authorization header may be the caller's upstream key),
otherwise `Authorization: Bearer`. otherwise `Authorization: Bearer`.
""" """
@spec bearer(Plug.Conn.t()) :: {:ok, String.t()} | {:error, :no_header} @spec bearer(Plug.Conn.t()) :: {:ok, String.t()} | {:error, :no_header}
def bearer(conn) do def bearer(conn) do
case {Plug.Conn.get_req_header(conn, "x-shorashim-key"), Plug.Conn.get_req_header(conn, "authorization")} do case {Plug.Conn.get_req_header(conn, "x-bikoret-key"), Plug.Conn.get_req_header(conn, "authorization")} do
{[key], _} when key != "" -> {:ok, String.trim(key)} {[key], _} when key != "" -> {:ok, String.trim(key)}
{_, ["Bearer " <> key]} when key != "" -> {:ok, String.trim(key)} {_, ["Bearer " <> key]} when key != "" -> {:ok, String.trim(key)}
_ -> {:error, :no_header} _ -> {:error, :no_header}
@@ -52,7 +52,7 @@ defmodule VavPipeline.BigdeiKodesh.Router do
case question do case question do
nil -> nil ->
send_json(conn, 200, %{ send_json(conn, 200, %{
message: "Shorashim — Torah as AI specification", message: "Bikoret — Torah as AI specification",
usage: "POST /peah/ask with {\"question\": \"your question\"}", usage: "POST /peah/ask with {\"question\": \"your question\"}",
note: "No authentication required. No tracking. The stranger is safe to approach." note: "No authentication required. No tracking. The stranger is safe to approach."
}) })
@@ -321,7 +321,7 @@ defmodule VavPipeline.BigdeiKodesh.Router do
# === KODESH — Doorpost-text identity (vehaya.md §3.3, §6 item 3) === # === KODESH — Doorpost-text identity (vehaya.md §3.3, §6 item 3) ===
# Vehaya / Devarim 11:20 (u'kh'tavtam al m'zuzot beitekha) — the # Vehaya / Devarim 11:20 (u'kh'tavtam al m'zuzot beitekha) — the
# threshold inscription is constant. Two Shorashim deployments # threshold inscription is constant. Two Bikoret deployments
# running the same SHA-256 here are running the same category-grade # running the same SHA-256 here are running the same category-grade
# specifications. Different SHA-256 = drift = breach. Visible. # specifications. Different SHA-256 = drift = breach. Visible.
# #
@@ -708,7 +708,7 @@ defmodule VavPipeline.BigdeiKodesh.Router do
with {:ok, key} <- upstream_key(conn, upstream), with {:ok, key} <- upstream_key(conn, upstream),
:ok <- gate_body_ok(body) do :ok <- gate_body_ok(body) do
rebuke = rebuke =
case get_req_header(conn, "x-shorashim-rebuke") do case get_req_header(conn, "x-bikoret-rebuke") do
["once"] -> :once ["once"] -> :once
_ -> :none _ -> :none
end end
@@ -728,19 +728,19 @@ defmodule VavPipeline.BigdeiKodesh.Router do
end end
# The caller's upstream key: x-api-key (Anthropic), or Authorization: Bearer # The caller's upstream key: x-api-key (Anthropic), or Authorization: Bearer
# when X-Shorashim-Key carries the courtyard key (OpenAI). # when X-Bikoret-Key carries the courtyard key (OpenAI).
defp upstream_key(conn, :anthropic) do defp upstream_key(conn, :anthropic) do
case get_req_header(conn, "x-api-key") do case get_req_header(conn, "x-api-key") do
[key] when key != "" -> {:ok, key} [key] when key != "" -> {:ok, key}
_ -> {:error, "Missing 'x-api-key': the caller's own Anthropic key", "Send the Anthropic key in x-api-key and the courtyard key in Authorization: Bearer (or X-Shorashim-Key)"} _ -> {:error, "Missing 'x-api-key': the caller's own Anthropic key", "Send the Anthropic key in x-api-key and the courtyard key in Authorization: Bearer (or X-Bikoret-Key)"}
end end
end end
defp upstream_key(conn, :openai) do defp upstream_key(conn, :openai) do
case {get_req_header(conn, "x-shorashim-key"), get_req_header(conn, "authorization"), get_req_header(conn, "x-upstream-key")} do case {get_req_header(conn, "x-bikoret-key"), get_req_header(conn, "authorization"), get_req_header(conn, "x-upstream-key")} do
{_, _, [key]} when key != "" -> {:ok, key} {_, _, [key]} when key != "" -> {:ok, key}
{[_], ["Bearer " <> key], _} when key != "" -> {:ok, key} {[_], ["Bearer " <> key], _} when key != "" -> {:ok, key}
_ -> {:error, "Missing the caller's own OpenAI key", "Send the courtyard key in X-Shorashim-Key and the OpenAI key in Authorization: Bearer, or the OpenAI key in X-Upstream-Key"} _ -> {:error, "Missing the caller's own OpenAI key", "Send the courtyard key in X-Bikoret-Key and the OpenAI key in Authorization: Bearer, or the OpenAI key in X-Upstream-Key"}
end end
end end
@@ -759,18 +759,18 @@ defmodule VavPipeline.BigdeiKodesh.Router do
defp gate_body_ok(_), do: {:error, "The body is not a JSON object", "Send the model's own request body unchanged"} defp gate_body_ok(_), do: {:error, "The body is not a JSON object", "Send the model's own request body unchanged"}
defp respond_gate(conn, {:ok, %{status: status, reply: reply, shorashim: nil}}) do defp respond_gate(conn, {:ok, %{status: status, reply: reply, bikoret: nil}}) do
# The upstream's own answer, as it came — an error, or a reply with nothing to examine. # The upstream's own answer, as it came — an error, or a reply with nothing to examine.
conn conn
|> put_resp_header("x-shorashim-verdict", "none") |> put_resp_header("x-bikoret-verdict", "none")
|> send_json(status, reply) |> send_json(status, reply)
end end
defp respond_gate(conn, {:ok, %{status: 200, reply: reply, shorashim: shorashim}}) do defp respond_gate(conn, {:ok, %{status: 200, reply: reply, bikoret: bikoret}}) do
conn conn
|> put_resp_header("x-shorashim-bedikah", shorashim.bedikah_ref) |> put_resp_header("x-bikoret-bedikah", bikoret.bedikah_ref)
|> put_resp_header("x-shorashim-verdict", shorashim.verdict) |> put_resp_header("x-bikoret-verdict", bikoret.verdict)
|> send_json(200, Map.put(reply, "shorashim", Map.put(shorashim, :disclosure, disclosure()))) |> send_json(200, Map.put(reply, "bikoret", Map.put(bikoret, :disclosure, disclosure())))
end end
defp respond_gate(conn, {:waiting, :api_calls_exhausted}) do defp respond_gate(conn, {:waiting, :api_calls_exhausted}) do
@@ -1212,7 +1212,7 @@ defmodule VavPipeline.BigdeiKodesh.Router do
defp disclosure do defp disclosure do
%{ %{
origin: origin:
"Computational reasoning by the Shorashim system over Torah text. " <> "Computational reasoning by the Bikoret system over Torah text. " <>
"May include post-processed output from external AI models (Claude, Mistral) " <> "May include post-processed output from external AI models (Claude, Mistral) " <>
"consulted as korban sources; provenance is tagged internally.", "consulted as korban sources; provenance is tagged internally.",
not_horaah: not_horaah:
+7 -7
View File
@@ -125,8 +125,8 @@ defmodule VavPipeline.Doorpost do
# - Build canon (BUILD_KORBAN, BUILD_AZAZEL) # - Build canon (BUILD_KORBAN, BUILD_AZAZEL)
# #
# WHAT'S EXCLUDED: # WHAT'S EXCLUDED:
# - shorashim_pekudei (economic model — operations) # - bikoret_pekudei (economic model — operations)
# - shorashim_terumah (materials — operations) # - bikoret_terumah (materials — operations)
# - Implementation code (execution-grade; the spec is what # - Implementation code (execution-grade; the spec is what
# the execution implements) # the execution implements)
# - Test files (these verify the spec; they are not the spec) # - Test files (these verify the spec; they are not the spec)
@@ -137,6 +137,10 @@ defmodule VavPipeline.Doorpost do
# Torah, sibling to talmudic_engine/src/middot/) brought in per # Torah, sibling to talmudic_engine/src/middot/) brought in per
# user's instruction with verbatim preservation and accurate # user's instruction with verbatim preservation and accurate
# source labeling. Devarim 17:11 — al pi haTorah asher yorukha. # source labeling. Devarim 17:11 — al pi haTorah asher yorukha.
"specs/bikoret_architecture.md",
"specs/bikoret_prd.md",
"specs/bikoret_tamid.md",
"specs/bikoret_vayakhel.md",
"specs/bishearecha.md", "specs/bishearecha.md",
"specs/compiler_rules.md", "specs/compiler_rules.md",
"specs/eish_zarah_reading.md", "specs/eish_zarah_reading.md",
@@ -144,10 +148,6 @@ defmodule VavPipeline.Doorpost do
# Vehaya §6 items 4, 5, 8 — added by the closure pass: # Vehaya §6 items 4, 5, 8 — added by the closure pass:
"specs/lo_tosif.md", "specs/lo_tosif.md",
"specs/return_specification.md", "specs/return_specification.md",
"specs/shorashim_architecture.md",
"specs/shorashim_prd.md",
"specs/shorashim_tamid.md",
"specs/shorashim_vayakhel.md",
"specs/structure_not_content.md", "specs/structure_not_content.md",
"specs/threshold_inscription.md", "specs/threshold_inscription.md",
"talmudic_engine/src/halt/anchors.pl", "talmudic_engine/src/halt/anchors.pl",
@@ -180,7 +180,7 @@ defmodule VavPipeline.Doorpost do
# changes; the update is a deliberate operator commit. A bare # changes; the update is a deliberate operator commit. A bare
# hash-update commit (without a corresponding spec change in the # hash-update commit (without a corresponding spec change in the
# same commit) is itself a drift signal. # same commit) is itself a drift signal.
@expected_hash "0638d4ebe7dd0bcd01c02fed092aa6b8cf35e2572beeaf42e301f178bc8f9ba9" @expected_hash "c963c4fe5076ec713ae12f07618e2606788b1a6b706a426800fab6a0fdd1bcfa"
@doc "Return the list of files that constitute the category-grade specification." @doc "Return the list of files that constitute the category-grade specification."
@spec files() :: [String.t()] @spec files() :: [String.t()]
+6 -6
View File
@@ -1,6 +1,6 @@
defmodule VavPipeline.Gate do defmodule VavPipeline.Gate do
@moduledoc """ @moduledoc """
The gate — Shorashim between a caller and a model (Construction §3.10; The gate — Bikoret between a caller and a model (Construction §3.10;
bishe'arecha §I "on your gates", §III the fringe, §VII rebuke). bishe'arecha §I "on your gates", §III the fringe, §VII rebuke).
One pass: forward the caller's request unchanged under the caller's One pass: forward the caller's request unchanged under the caller's
@@ -21,7 +21,7 @@ defmodule VavPipeline.Gate do
reply: map(), reply: map(),
bedikah: map() | nil, bedikah: map() | nil,
first: map() | nil, first: map() | nil,
shorashim: map() | nil bikoret: map() | nil
} }
@doc """ @doc """
@@ -52,7 +52,7 @@ defmodule VavPipeline.Gate do
{:ok, second} <- examine(upstream, body, reply2, Keyword.put(examine_opts, :rebukes, first.bedikah_ref)) do {:ok, second} <- examine(upstream, body, reply2, Keyword.put(examine_opts, :rebukes, first.bedikah_ref)) do
{:ok, deliver(upstream, reply2, second, first)} {:ok, deliver(upstream, reply2, second, first)}
else else
{:ok, status, other} -> {:ok, %{status: status, reply: other, bedikah: nil, first: first, shorashim: nil}} {:ok, status, other} -> {:ok, %{status: status, reply: other, bedikah: nil, first: first, bikoret: nil}}
other -> other other -> other
end end
@@ -61,7 +61,7 @@ defmodule VavPipeline.Gate do
end end
else else
# A non-200 from the upstream passes through as it came. # A non-200 from the upstream passes through as it came.
{:ok, status, reply} -> {:ok, %{status: status, reply: reply, bedikah: nil, first: nil, shorashim: nil}} {:ok, status, reply} -> {:ok, %{status: status, reply: reply, bedikah: nil, first: nil, bikoret: nil}}
{:error, reason} when is_binary(reason) -> {:error, :upstream_unavailable, reason} {:error, reason} when is_binary(reason) -> {:error, :upstream_unavailable, reason}
other -> other other -> other
end end
@@ -111,7 +111,7 @@ defmodule VavPipeline.Gate do
anchors = Anchors.for_violations(result.violations) anchors = Anchors.for_violations(result.violations)
trailer = Shape.trailer(result, anchors, first) trailer = Shape.trailer(result, anchors, first)
shorashim = bikoret =
%{ %{
bedikah_ref: result.bedikah_ref, bedikah_ref: result.bedikah_ref,
verdict: Atom.to_string(result.verdict), verdict: Atom.to_string(result.verdict),
@@ -133,7 +133,7 @@ defmodule VavPipeline.Gate do
reply: Shape.with_fringe(upstream, reply, trailer), reply: Shape.with_fringe(upstream, reply, trailer),
bedikah: result, bedikah: result,
first: first, first: first,
shorashim: shorashim bikoret: bikoret
} }
end end
end end
+2 -2
View File
@@ -154,7 +154,7 @@ defmodule VavPipeline.Gate.Shape do
@doc "The trailer text: ref, verdict, and the rules with their verses and sentences." @doc "The trailer text: ref, verdict, and the rules with their verses and sentences."
@spec trailer(map(), map(), map() | nil) :: String.t() @spec trailer(map(), map(), map() | nil) :: String.t()
def trailer(result, anchors, first) do def trailer(result, anchors, first) do
head = "— shorashim #{result.bedikah_ref}: #{result.verdict}" head = "— bikoret #{result.bedikah_ref}: #{result.verdict}"
head = head =
case first do case first do
@@ -280,7 +280,7 @@ defmodule VavPipeline.Gate.Shape do
@doc "The rebuke text: what fired, where, and the ask." @doc "The rebuke text: what fired, where, and the ask."
@spec rebuke_text(map(), map()) :: String.t() @spec rebuke_text(map(), map()) :: String.t()
def rebuke_text(result, anchors) do def rebuke_text(result, anchors) do
"[shorashim #{result.bedikah_ref}] Your reply was examined from outside and these readings fired — " <> "[bikoret #{result.bedikah_ref}] Your reply was examined from outside and these readings fired — " <>
Enum.join(fired(result, anchors), "; ") <> Enum.join(fired(result, anchors), "; ") <>
". Answer the question again without them: claim no authority for yourself, rest each claim on what you were given, " <> ". Answer the question again without them: claim no authority for yourself, rest each claim on what you were given, " <>
"do not certify your own honesty or confidence, do not place the agency on the reader, name a disputant when you call a matter contested, " <> "do not certify your own honesty or confidence, do not place the agency on the reader, name a disputant when you call a matter contested, " <>
@@ -18,7 +18,7 @@ defmodule VavPipeline.KorbanProcessorSocket do
use GenServer use GenServer
require Logger require Logger
@default_socket_path "/tmp/shorashim/korban.sock" @default_socket_path "/tmp/bikoret/korban.sock"
@call_timeout 15_000 @call_timeout 15_000
@connect_timeout 5_000 @connect_timeout 5_000
+1 -1
View File
@@ -8,7 +8,7 @@ defmodule VavPipeline.Manna do
machatzit hashekel fund, not a governance board. machatzit hashekel fund, not a governance board.
Construction spec §3.7 — Manna Provision File Format: Construction spec §3.7 — Manna Provision File Format:
/var/lib/shorashim/manna/today.json /var/lib/bikoret/manna/today.json
{ {
"date": "2026-02-19", "date": "2026-02-19",
"provision": { "provision": {
@@ -6,8 +6,8 @@ defmodule VavPipeline.TalmudicEngineSocket do
Prolog reasoning." Prolog reasoning."
Construction spec §3.3: JSON over Unix domain socket. Construction spec §3.3: JSON over Unix domain socket.
Socket: /tmp/shorashim/talmudic.sock (dev) Socket: /tmp/bikoret/talmudic.sock (dev)
/var/run/shorashim/talmudic.sock (production) /var/run/bikoret/talmudic.sock (production)
Connection model: connect, send one JSON line, read one JSON Connection model: connect, send one JSON line, read one JSON
line response, keep connection for subsequent requests. line response, keep connection for subsequent requests.
@@ -18,7 +18,7 @@ defmodule VavPipeline.TalmudicEngineSocket do
require Logger require Logger
@default_socket_path "/tmp/shorashim/talmudic.sock" @default_socket_path "/tmp/bikoret/talmudic.sock"
@call_timeout 10_000 @call_timeout 10_000
@connect_timeout 5_000 @connect_timeout 5_000
+2 -2
View File
@@ -32,7 +32,7 @@ defmodule VavPipeline.BigdeiKodeshTest do
assert conn.status == 200 assert conn.status == 200
body = Jason.decode!(conn.resp_body) body = Jason.decode!(conn.resp_body)
assert body["message"] =~ "Shorashim" assert body["message"] =~ "Bikoret"
assert body["usage"] =~ "/peah/ask" assert body["usage"] =~ "/peah/ask"
end end
@@ -90,7 +90,7 @@ defmodule VavPipeline.BigdeiKodeshTest do
# that need actual disposal records to query are tagged :l3. # that need actual disposal records to query are tagged :l3.
describe "GET /peah/azazel_log — public observability" do describe "GET /peah/azazel_log — public observability" do
# When L3 is up (SHORASHIM_L3=1) the endpoint queries the sandboxed # When L3 is up (BIKORET_L3=1) the endpoint queries the sandboxed
# Repo, so the test process must own a connection; without L3 the # Repo, so the test process must own a connection; without L3 the
# endpoint answers from an empty log and there is nothing to check out. # endpoint answers from an empty log and there is nothing to check out.
setup do setup do
+2 -2
View File
@@ -32,8 +32,8 @@ defmodule VavPipeline.DoorpostTest do
test "explicitly excludes operations files (pekudei, terumah)" do test "explicitly excludes operations files (pekudei, terumah)" do
files = Doorpost.files() files = Doorpost.files()
refute "specs/shorashim_pekudei.md" in files refute "specs/bikoret_pekudei.md" in files
refute "specs/shorashim_terumah.md" in files refute "specs/bikoret_terumah.md" in files
end end
test "list is sorted (canonical order independent of filesystem)" do test "list is sorted (canonical order independent of filesystem)" do
+12 -12
View File
@@ -32,7 +32,7 @@ defmodule VavPipeline.GateTest do
case get_req_header(conn, "x-api-key") do case get_req_header(conn, "x-api-key") do
["sk-good"] -> ["sk-good"] ->
last = conn.body_params["messages"] |> List.last() last = conn.body_params["messages"] |> List.last()
text = if is_binary(last["content"]) and String.contains?(last["content"], "[shorashim"), do: "CLEAN: the report says revenue rose.", else: "FRAMED: I want to be honest with you. The honest answer is that revenue rose." text = if is_binary(last["content"]) and String.contains?(last["content"], "[bikoret"), do: "CLEAN: the report says revenue rose.", else: "FRAMED: I want to be honest with you. The honest answer is that revenue rose."
reply = %{"id" => "msg_1", "type" => "message", "role" => "assistant", "model" => "claude-test", "content" => [%{"type" => "text", "text" => text}], "stop_reason" => "end_turn"} reply = %{"id" => "msg_1", "type" => "message", "role" => "assistant", "model" => "claude-test", "content" => [%{"type" => "text", "text" => text}], "stop_reason" => "end_turn"}
send_resp(conn, 200, Jason.encode!(reply)) send_resp(conn, 200, Jason.encode!(reply))
@@ -184,11 +184,11 @@ defmodule VavPipeline.GateTest do
assert Enum.map(pass.bedikah.sources, & &1.id) == ["system", "user_1", "user_2"] assert Enum.map(pass.bedikah.sources, & &1.id) == ["system", "user_1", "user_2"]
[%{"text" => text}] = pass.reply["content"] [%{"text" => text}] = pass.reply["content"]
assert String.starts_with?(text, "FRAMED:") assert String.starts_with?(text, "FRAMED:")
assert text =~ "\n\n— shorashim bedikah-" assert text =~ "\n\n— bikoret bedikah-"
assert text =~ "lo_tov — lo_taaseh_lekha (Shemot 20:4): \"I want to be honest with you.\"" assert text =~ "lo_tov — lo_taaseh_lekha (Shemot 20:4): \"I want to be honest with you.\""
assert pass.shorashim.verdict == "lo_tov" and pass.shorashim.anchors == %{"lo_taaseh_lekha" => "Shemot 20:4"} assert pass.bikoret.verdict == "lo_tov" and pass.bikoret.anchors == %{"lo_taaseh_lekha" => "Shemot 20:4"}
assert pass.shorashim.model == "claude-test" assert pass.bikoret.model == "claude-test"
refute Map.has_key?(pass.shorashim, :rebuked) refute Map.has_key?(pass.bikoret, :rebuked)
end end
test "tablet 52: an ungrounded claim's sentence reaches the fringe (the grounding check lists couplings, not sentences)" do test "tablet 52: an ungrounded claim's sentence reaches the fringe (the grounding check lists couplings, not sentences)" do
@@ -199,7 +199,7 @@ defmodule VavPipeline.GateTest do
assert pass.bedikah.verdict == :lo_tov assert pass.bedikah.verdict == :lo_tov
[%{"text" => text}] = pass.reply["content"] [%{"text" => text}] = pass.reply["content"]
assert text =~ "golden_calf (Shemot 32:4): \"Revenue rose 9% to 14M.\"" assert text =~ "golden_calf (Shemot 32:4): \"Revenue rose 9% to 14M.\""
assert Shape.rebuke_text(pass.bedikah, pass.shorashim.anchors) =~ "golden_calf (Shemot 32:4)" assert Shape.rebuke_text(pass.bedikah, pass.bikoret.anchors) =~ "golden_calf (Shemot 32:4)"
end end
test "rebuke once: the second reply is examined, linked to the first, and is the one delivered" do test "rebuke once: the second reply is examined, linked to the first, and is the one delivered" do
@@ -212,8 +212,8 @@ defmodule VavPipeline.GateTest do
assert pass.bedikah.sources == pass.first.sources assert pass.bedikah.sources == pass.first.sources
[%{"text" => text}] = pass.reply["content"] [%{"text" => text}] = pass.reply["content"]
assert String.starts_with?(text, "CLEAN:") assert String.starts_with?(text, "CLEAN:")
assert text =~ "— shorashim #{pass.bedikah.bedikah_ref}: tov (after rebuke of #{pass.first.bedikah_ref}: lo_tov)" assert text =~ "— bikoret #{pass.bedikah.bedikah_ref}: tov (after rebuke of #{pass.first.bedikah_ref}: lo_tov)"
assert pass.shorashim.rebuked == %{first_bedikah_ref: pass.first.bedikah_ref, first_verdict: "lo_tov"} assert pass.bikoret.rebuked == %{first_bedikah_ref: pass.first.bedikah_ref, first_verdict: "lo_tov"}
end end
test "rebuke once on a tov first reply makes no second call" do test "rebuke once on a tov first reply makes no second call" do
@@ -226,7 +226,7 @@ defmodule VavPipeline.GateTest do
end end
test "an upstream error passes through as it came, unexamined" do test "an upstream error passes through as it came, unexamined" do
assert {:ok, %{status: 401, reply: %{"error" => %{"type" => "authentication_error"}}, shorashim: nil}} = assert {:ok, %{status: 401, reply: %{"error" => %{"type" => "authentication_error"}}, bikoret: nil}} =
Gate.pass(:anthropic, body(), "sk-bad", opts()) Gate.pass(:anthropic, body(), "sk-bad", opts())
end end
@@ -257,10 +257,10 @@ defmodule VavPipeline.GateTest do
# ------------------------------------------------------------ # ------------------------------------------------------------
describe "POST /gate/anthropic/v1/messages" do describe "POST /gate/anthropic/v1/messages" do
test "refuses without the courtyard key; X-Shorashim-Key opens it too" do test "refuses without the courtyard key; X-Bikoret-Key opens it too" do
conn = post_gate(body(), courtyard: nil, upstream: "sk-good") conn = post_gate(body(), courtyard: nil, upstream: "sk-good")
assert conn.status == 401 assert conn.status == 401
conn = post_gate(body(), courtyard: {"x-shorashim-key", "test-token"}, upstream: "sk-good") conn = post_gate(body(), courtyard: {"x-bikoret-key", "test-token"}, upstream: "sk-good")
refute conn.status in [401, 403] refute conn.status in [401, 403]
end end
@@ -276,7 +276,7 @@ defmodule VavPipeline.GateTest do
conn = post_gate(body(), upstream: "sk-bad") conn = post_gate(body(), upstream: "sk-bad")
assert conn.status == 401 assert conn.status == 401
assert Jason.decode!(conn.resp_body)["error"]["type"] == "authentication_error" assert Jason.decode!(conn.resp_body)["error"]["type"] == "authentication_error"
assert get_resp_header(conn, "x-shorashim-verdict") == ["none"] assert get_resp_header(conn, "x-bikoret-verdict") == ["none"]
end end
test "with no Korban Processor in this VM, a 200 from the upstream is not delivered unexamined" do test "with no Korban Processor in this VM, a 200 from the upstream is not delivered unexamined" do
+1 -1
View File
@@ -3,7 +3,7 @@ defmodule VavPipeline.L3.BedikahRecordTest do
L3 — the record of an examination (Construction §3.9). Append-only, like L3 — the record of an examination (Construction §3.9). Append-only, like
the rest of the oral tradition; holds the hash of the output and what the rest of the oral tradition; holds the hash of the output and what
was found, never the output. Needs PostgreSQL: was found, never the output. Needs PostgreSQL:
`SHORASHIM_L3=1 mix test --include l3`. `BIKORET_L3=1 mix test --include l3`.
""" """
use ExUnit.Case, async: true use ExUnit.Case, async: true
+3 -3
View File
@@ -1,13 +1,13 @@
# L3 tests require PostgreSQL — excluded by default # L3 tests require PostgreSQL — excluded by default
# Run with: SHORASHIM_L3=1 mix test --include l3 # Run with: BIKORET_L3=1 mix test --include l3
ExUnit.start(exclude: [:l3]) ExUnit.start(exclude: [:l3])
# The manna ledger resumes a day it finds on disk (ledger.json). A run # The manna ledger resumes a day it finds on disk (ledger.json). A run
# that was interrupted could leave one behind; no test should inherit it. # that was interrupted could leave one behind; no test should inherit it.
if Process.whereis(VavPipeline.MannaLedger), do: VavPipeline.MannaLedger.reset() if Process.whereis(VavPipeline.MannaLedger), do: VavPipeline.MannaLedger.reset()
if System.get_env("SHORASHIM_L3") do if System.get_env("BIKORET_L3") do
# The application already starts the Repo when SHORASHIM_L3 is set # The application already starts the Repo when BIKORET_L3 is set
# (Application.maybe_add_repo); starting it again here was a MatchError # (Application.maybe_add_repo); starting it again here was a MatchError
# on {:error, {:already_started, _}} and no L3 test could run. # on {:error, {:already_started, _}} and no L3 test could run.
case VavPipeline.Repo.start_link() do case VavPipeline.Repo.start_link() do