# check=skip=FromPlatformFlagConstDisallowed # ^ The --platform=linux/amd64 pins below are DELIBERATE (Exoscale SKS # 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. # Bikoret Talmudic Engine — SWI-Prolog dialectical reasoning # Construction spec §1.1: SWI-Prolog 9.2.2 # Communicates with vav_pipeline via Unix domain socket # # PLATFORM PIN: see Dockerfile.vav_pipeline for the rationale. # Exoscale SKS = amd64; arm64 images cannot exec on the cluster. # === BUILD STAGE === FROM --platform=linux/amd64 swipl:9.2.2 AS build WORKDIR /app COPY talmudic_engine/ ./ # Verify Prolog loads without errors RUN swipl -g "consult('src/main'),halt(0)" -t "halt(1)" # === RUNTIME STAGE === FROM --platform=linux/amd64 swipl:9.2.2 # CVE-2026-111497 (Brotli decoder out-of-bounds write, October 2026). # The swipl:9.2.2 base carries Debian bookworm's libbrotli1 1.0.9-2, # pulled in by libcurl3-gnutls. Nothing in this image decodes Brotli: # swipl does not link it, there is no curl binary, and the engine reads # JSON from vav over a Unix socket. The copy was dormant, not a path. # Debian fixed it in 1.0.9-2+deb12u1 (bookworm-security); take that one # package without moving the pinned base. The pin on SWI-Prolog 9.2.2 # (Construction §1.1) is the point of the base image, so this is # --only-upgrade of the one library, not a general upgrade. RUN apt-get update \ && apt-get install -y --no-install-recommends --only-upgrade libbrotli1 \ && rm -rf /var/lib/apt/lists/* RUN useradd --create-home --shell /bin/bash bikoret USER bikoret WORKDIR /home/bikoret/talmudic_engine COPY --from=build --chown=bikoret:bikoret /app/ ./ # L1 Torah filesystem — baked into the image # L1 is read-only in fact, not only in name. Until 2026-10-04 the scroll # was copied in owned by the service user with its write bits on: the # process that reads Torah could also have rewritten it, and only the # SHA-256 check would have noticed afterwards. Owned by root, no write # bit for anyone; the service user can read and traverse, nothing more. USER root COPY --chown=root:root l1/ /mnt/torah/ RUN chmod -R a-w,a+rX /mnt/torah USER bikoret # L1 mount point ENV L1_MOUNT_POINT=/mnt/torah # Socket path for communication with vav_pipeline ENV TALMUDIC_SOCKET_PATH=/tmp/bikoret/talmudic.sock # Start the Prolog socket server. # # The predicate is serve/0 and serve/1 (exported by # src/interface/socket_server.pl). The previous CMD called # start_socket_server/0, which is not defined anywhere in the engine — # the container exited 2 on every start: # ERROR: -g consult('src/main'),start_socket_server: # ''/1: Unknown procedure: start_socket_server/0 # # serve/1 is used when TALMUDIC_SOCKET_PATH is set so the env var above # is actually honoured; serve/0 falls back to the same path hardcoded # as default_socket_path/1. vav_pipeline dials the socket at # :talmudic_socket_path (config/config.exs), and deployment.yaml mounts # the shared talmudic-socket volume at /tmp/bikoret in both # 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)"]