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:
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).
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)"]
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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,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
|
||||||
|
|||||||
@@ -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/*)
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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"),
|
||||||
|
|||||||
@@ -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
@@ -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.
|
||||||
|
|||||||
@@ -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,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,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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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:
|
||||||
|
|||||||
@@ -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()]
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in new issue
Block a user