diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d00546c36e906bd3c931b19c26407fc8df9e8afc..378fb83aa2f6c926ced5cdd125be2a50ca75033e 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -8,7 +8,7 @@ variables:
   ## Application versions used for the main release 
   ## note: nightly builds will always use the master/main branch
   JUGGLER_VERSION: "v10.1.0"
-  EICRECON_VERSION: "v1.5.1"
+  EICRECON_VERSION: "v1.7.0"
 
   ## Local registry
   CI_PUSH: 1
@@ -44,6 +44,7 @@ variables:
   INTERNAL_TAG: "pipeline-${CI_PIPELINE_ID}"
 
 stages:
+  - status-pending
   - config
   - base            ## base OS image
   - jug             ## jug container images
@@ -51,6 +52,7 @@ stages:
   - benchmarks
   - test
   - finalize
+  - status-report
 
 ## only run CI for in the following cases:
 ## master, stable branch, release tag, MR event and nightly builds
@@ -61,8 +63,8 @@ workflow:
     - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
     - if: '$CI_PIPELINE_SOURCE == "web"'
     - if: '$CI_COMMIT_BRANCH == "master"'
-    - if: '$CI_COMMIT_BRANCH =~ /^v[0-9]+\.[0-9]+-stable/'          ## main stable branch: vX.Y-stable
-    - if: '$CI_COMMIT_BRANCH =~ /^v[0-9]+\.[0-9]+-[a-z]+-stable/'   ## special stable branch: vX.Y-acadia-stable (etc)
+    - if: '$CI_COMMIT_BRANCH =~ /^v[0-9]+\.[0-9]+-(alpha|beta|stable)/'          ## main stable branch: vX.Y-stable
+    - if: '$CI_COMMIT_BRANCH =~ /^v[0-9]+\.[0-9]+-[a-z]+-(alpha|beta|stable)/'   ## special stable branch: vX.Y-acadia-stable (etc)
     - if: '$CI_COMMIT_TAG =~ /^v[0-9]+\.[0-9]+\.[0-9]+/'            ## commit tags start with vX.Y.Z with optional suffix
 
 ## plan:
@@ -105,10 +107,10 @@ version:
       elif [[ "$CI_COMMIT_TAG" =~ ^v[0-9.]+\.[0-9]+\.[0-9]+ ]]; then
         VERSION="${CI_COMMIT_TAG:1}"
         EXPORT_TAG="${VERSION}"
-      elif [[ "$CI_COMMIT_BRANCH" =~ ^v[0-9.]+\.[0-9]+-stable ]]; then
+      elif [[ "$CI_COMMIT_BRANCH" =~ ^v[0-9.]+\.[0-9]+-\(alpha\|beta\|stable\) ]]; then
         VERSION="${CI_COMMIT_BRANCH:1}"
         EXPORT_TAG="${VERSION}"
-      elif [[ "$CI_COMMIT_BRANCH" =~ ^v[0-9.]+\.[0-9]+-[a-z]+-stable ]]; then
+      elif [[ "$CI_COMMIT_BRANCH" =~ ^v[0-9.]+\.[0-9]+-[a-z]+-\(alpha\|beta\|stable\) ]]; then
         VERSION="${CI_COMMIT_BRANCH:1}"
         EXPORT_TAG="${VERSION}"
       elif [[ "$CI_COMMIT_BRANCH" =~ ^master$ ]]; then
@@ -128,6 +130,32 @@ version:
     reports:
       dotenv: build.env
 
+.status:
+  image: curlimages/curl:latest
+  before_script: []
+  script:
+    - |
+      if [ -n "${GITHUB_SHA}" ] ; then
+          curl \
+            -X POST \
+            -H "Accept: application/vnd.github+json" \
+            -H "Authorization: token ${GITHUB_REPO_STATUS_TOKEN}" \
+            "https://api.github.com/repos/${GITHUB_REPOSITORY}/statuses/${GITHUB_SHA}" \
+            -d '{"state":"'"${STATE}"'",
+                 "target_url":"'"${CI_PIPELINE_URL}"'",
+                 "description":"'"${DESCRIPTION} $(TZ=America/New_York date)"'",
+                 "context":"eicweb/eic_container"
+                }' ;
+      fi
+
+status:pending:
+  stage: status-pending
+  extends: .status
+  variables:
+    STATE: "pending"
+    DESCRIPTION: "Started..."
+  when: always
+
 ## base job settings for all docker interactions
 .docker:
   image: ${DOCKER_IMAGE}
@@ -244,21 +272,25 @@ jug_dev:
         BASE_IMAGE: debian_stable_base
         BUILD_IMAGE: jug_
         PLATFORM: linux/amd64,linux/arm64/v8
-        ENV: [dev, prod]
+        ENV:
+        - dev
+        - prod
 #      - BUILD_TYPE:
 #        - default
 #        - nightly
 #        BASE_IMAGE: oneapi_base
 #        BUILD_IMAGE: oneapi_
 #        PLATFORM: linux/amd64
-#        ENV: [prod]
+#        ENV:
+#        - prod
 #      - BUILD_TYPE:
 #        - default
 #        - nightly
 #        BASE_IMAGE: cuda_base_new
 #        BUILD_IMAGE: cuda_
 #        PLATFORM: linux/amd64
-#        ENV: [prod]
+#        ENV:
+#        - prod
   extends: .build
   stage: jug
   needs:
@@ -329,7 +361,16 @@ jug_xl:default:
   stage: jug
   needs:
     - version
-    - jug_dev
+    - job: jug_dev
+      parallel:
+        matrix:
+        - BUILD_TYPE:
+          - default
+          BASE_IMAGE: debian_stable_base
+          BUILD_IMAGE: jug_
+          PLATFORM: linux/amd64,linux/arm64/v8
+          ENV:
+          - dev
   script:
     - apk add git
     - docker buildx build --push ${BUILD_OPTIONS}
@@ -369,7 +410,16 @@ jug_xl:nightly:
     - when: never
   needs:
     - version
-    - jug_dev
+    - job: jug_dev
+      parallel:
+        matrix:
+        - BUILD_TYPE:
+          - nightly
+          BASE_IMAGE: debian_stable_base
+          BUILD_IMAGE: jug_
+          PLATFORM: linux/amd64,linux/arm64/v8
+          ENV:
+          - dev
   script:
     - |
       PUSH_NIGHTLY_WITH_DATE=""
@@ -442,36 +492,24 @@ jug_xl:singularity:nightly:
     - version
     - jug_xl:nightly
 
-benchmarks:reconstruction:default:
+benchmarks:detector:default:
   stage: benchmarks
   needs: 
     - version
     - jug_xl:default
   variables:
+    DETECTOR: "epic"
+    DETECTOR_CONFIG: epic_craterlake
+    DETECTOR_REPOSITORYURL: 'https://github.com/eic/epic.git'
     BENCHMARKS_TAG: "${INTERNAL_TAG}-default"
     BENCHMARKS_CONTAINER: "jug_xl"
     BENCHMARKS_REGISTRY: "$CI_REGISTRY_IMAGE"
   trigger:
-    project: EIC/benchmarks/reconstruction_benchmarks
+    project: EIC/benchmarks/detector_benchmarks
     strategy: depend
   allow_failure: true
   
-benchmarks:physics:default:
-  stage: benchmarks
-  needs: 
-    - version
-    - jug_xl:default
-  variables:
-    RECO: "eicrecon"
-    BENCHMARKS_TAG: "${INTERNAL_TAG}-default"
-    BENCHMARKS_CONTAINER: "jug_xl"
-    BENCHMARKS_REGISTRY: "$CI_REGISTRY_IMAGE"
-  trigger:
-    project: EIC/benchmarks/physics_benchmarks
-    strategy: depend
-  allow_failure: false
-
-benchmarks:reconstruction:nightly:
+benchmarks:detector:nightly:
   stage: benchmarks
   rules:
     - !reference ['.nightly', rules]
@@ -479,36 +517,20 @@ benchmarks:reconstruction:nightly:
     - version
     - jug_xl:nightly
   variables:
+    DETECTOR: "epic"
+    DETECTOR_CONFIG: epic_craterlake
+    DETECTOR_REPOSITORYURL: 'https://github.com/eic/epic.git'
     BENCHMARKS_TAG: "${INTERNAL_TAG}-nightly"
     BENCHMARKS_CONTAINER: "jug_xl"
     BENCHMARKS_REGISTRY: "$CI_REGISTRY_IMAGE"
   trigger:
-    project: EIC/benchmarks/reconstruction_benchmarks
+    project: EIC/benchmarks/detector_benchmarks
     strategy: depend
   allow_failure: true
   
-benchmarks:physics:nightly:
-  stage: benchmarks
-  rules:
-    - !reference ['.nightly', rules]
-  needs: 
-    - version
-    - jug_xl:nightly
-  variables:
-    RECO: "eicrecon"
-    BENCHMARKS_TAG: "${INTERNAL_TAG}-nightly"
-    BENCHMARKS_CONTAINER: "jug_xl"
-    BENCHMARKS_REGISTRY: "$CI_REGISTRY_IMAGE"
-  trigger:
-    project: EIC/benchmarks/physics_benchmarks
-    strategy: depend
-  allow_failure: false
-
 clean_internal_tag:
   image: alpine/curl
   stage: finalize
-  dependencies:
-    - version
   when: always
   script:
     - |
@@ -521,8 +543,6 @@ clean_internal_tag:
 clean_unstable_mr:
   extends: .docker
   stage: finalize
-  dependencies:
-    - version
   tags:
     - docker-new
   when: always
@@ -554,7 +574,7 @@ clean_unstable_mr:
 clean_pipeline:
   extends: .docker
   stage: finalize
-  dependencies:
+  needs:
     - version
     - clean_internal_tag
   tags:
@@ -583,3 +603,20 @@ clean_pipeline:
     - docker system prune --filter until=24h --force
     - docker system df
     - docker images
+
+status:success:
+  stage: status-report
+  extends: .status
+  variables:
+    STATE: "success"
+    DESCRIPTION: "Succeeded!"
+  when: on_success
+
+status:failure:
+  stage: status-report
+  extends: .status
+  variables:
+    STATE: "failure"
+    DESCRIPTION: "Failed!"
+  when: on_failure
+
diff --git a/containers/debian/base.Dockerfile b/containers/debian/base.Dockerfile
index fac3952c76dcef6366af65df8e0a0ec8ff0972cc..9cc1d95cc8a3219a298b3faa261fa0367649d899 100644
--- a/containers/debian/base.Dockerfile
+++ b/containers/debian/base.Dockerfile
@@ -10,6 +10,10 @@ LABEL maintainer="Sylvester Joosten <sjoosten@anl.gov>" \
 
 COPY bashrc /root/.bashrc
 
+## With heredocs for multi-line scripts, we want to fail on error and the print failing line.
+## Ref: https://docs.docker.com/engine/reference/builder/#example-running-a-multi-line-script
+SHELL ["bash", "-ex", "-c"]
+
 ENV CLICOLOR_FORCE=1                                                    \
     LANGUAGE=en_US.UTF-8                                                \
     LANG=en_US.UTF-8                                                    \
@@ -17,13 +21,13 @@ ENV CLICOLOR_FORCE=1                                                    \
 
 ## Install additional packages. Remove the auto-cleanup functionality
 ## for docker, as we're using the new buildkit cache instead.
-RUN --mount=type=cache,target=/var/cache/apt,sharing=locked             \
-    --mount=type=cache,target=/var/lib/apt/lists,sharing=locked         \
-    rm -f /etc/apt/apt.conf.d/docker-clean                              \
- && ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime          \
- && echo "US/Eastern" > /etc/timezone                                   \
- && apt-get -yqq update                                                 \
- && apt-get -yqq install --no-install-recommends                        \
+RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
+    --mount=type=cache,target=/var/lib/apt/lists,sharing=locked <<EOF
+rm -f /etc/apt/apt.conf.d/docker-clean
+ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
+echo "US/Eastern" > /etc/timezone
+apt-get -yqq update
+apt-get -yqq install --no-install-recommends                            \
         bc                                                              \
         bzip2                                                           \
         ca-certificates                                                 \
@@ -52,52 +56,41 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked             \
         poppler-utils                                                   \
         time                                                            \
         unzip                                                           \
-        valgrind                                                        \
         vim-nox                                                         \
-        wget                                                            \
- && apt-get -yqq autoremove                                             \
- && localedef -i en_US -f UTF-8 en_US.UTF-8
+        wget
+apt-get -yqq autoremove
+localedef -i en_US -f UTF-8 en_US.UTF-8
+EOF
 
 # Install updated compilers, with support for multiple base images
 ## Ubuntu: latest gcc from toolchain ppa, latest stable clang
 ## Debian: default gcc with distribution, latest stable clang
-RUN --mount=type=cache,target=/var/cache/apt,sharing=locked             \
-    --mount=type=cache,target=/var/lib/apt/lists,sharing=locked         \
-    . /etc/os-release                                                   \
- && mkdir -p /etc/apt/source.list.d                                     \
- && if [ "${ID}" = "ubuntu" ] ; then                                    \
-      echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/ppa/ubuntu/ \
-            ${VERSION_CODENAME} main"                                   \
-      > /etc/apt/source.list.d/ubuntu-toolchain.list                    \
-   && if [ "${VERSION_ID}" = "20.04" ] ; then GCC="-10" CLANG="-12" ; fi\
-   && if [ "${VERSION_ID}" = "22.04" ] ; then GCC="-12" CLANG="-14" ; fi\
-   && curl -s https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -\
-   && echo "deb http://apt.llvm.org/${VERSION_CODENAME}                 \
-            llvm-toolchain-${VERSION_CODENAME}${CLANG} main"            \
-      > /etc/apt/source.list.d/llvm.list                                \
-   && apt-get -yqq update                                               \
-   && apt-get -yqq install                                              \
-          gcc${GCC} g++${GCC} gfortran${GCC}                            \
-   && apt-get -yqq install                                              \
-          clang${CLANG} clang-tidy${CLANG} clang-format${CLANG}         \
-          iwyu                                                          \
-   && update-alternatives --install /usr/bin/gcc gcc                    \
-                                    /usr/bin/gcc${GCC} 100              \
-   && update-alternatives --install /usr/bin/g++ g++                    \
-                                    /usr/bin/g++${GCC} 100              \
-   && update-alternatives --install /usr/bin/gfortran gfortran          \
-                                    /usr/bin/gfortran${GCC} 100         \
-   && update-alternatives --install /usr/bin/clang clang                \
-                                    /usr/bin/clang${CLANG} 100          \
-   && update-alternatives --install /usr/bin/clang++ clang++            \
-                                    /usr/bin/clang++${CLANG} 100        \
- ; else                                                                 \
-      apt-get -yqq update                                               \
-   && apt-get -yqq install                                              \
-          gcc g++ gfortran                                              \
-          clang clang-tidy clang-format                                 \
-          iwyu                                                          \
- ; fi                                                                   \
- && apt-get -yqq autoremove                                             \
- && gcc --version                                                       \
- && clang --version
+RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
+    --mount=type=cache,target=/var/lib/apt/lists,sharing=locked <<EOF
+. /etc/os-release
+mkdir -p /etc/apt/source.list.d
+if [ "${ID}" = "ubuntu" ] ; then
+  echo "deb http://ppa.launchpad.net/ubuntu-toolchain-r/ppa/ubuntu/${VERSION_CODENAME} main" > /etc/apt/source.list.d/ubuntu-toolchain.list
+  if [ "${VERSION_ID}" = "20.04" ] ; then GCC="-10" CLANG="-12" ; fi
+  if [ "${VERSION_ID}" = "22.04" ] ; then GCC="-12" CLANG="-14" ; fi
+  curl -s https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
+  echo "deb http://apt.llvm.org/${VERSION_CODENAME} llvm-toolchain-${VERSION_CODENAME}${CLANG} main" > /etc/apt/source.list.d/llvm.list
+  apt-get -yqq update
+  apt-get -yqq install gcc${GCC} g++${GCC} gfortran${GCC}
+  apt-get -yqq install clang${CLANG} clang-tidy${CLANG} clang-format${CLANG}
+  apt-get -yqq install iwyu
+  update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc${GCC} 100
+  update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++${GCC} 100
+  update-alternatives --install /usr/bin/gfortran gfortran /usr/bin/gfortran${GCC} 100
+  update-alternatives --install /usr/bin/clang clang /usr/bin/clang${CLANG} 100
+  update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++${CLANG} 100
+else
+  apt-get -yqq update
+  apt-get -yqq install gcc g++ gfortran
+  apt-get -yqq install clang clang-tidy clang-format
+  apt-get -yqq install iwyu
+fi
+apt-get -yqq autoremove
+gcc --version
+clang --version
+EOF
diff --git a/containers/jug/dev.Dockerfile b/containers/jug/dev.Dockerfile
index 91bcf51b538850b769749037fb6e9ebade98fa62..bbea66a02145a73201437c29af32b510a795869d 100644
--- a/containers/jug/dev.Dockerfile
+++ b/containers/jug/dev.Dockerfile
@@ -10,17 +10,22 @@ ARG INTERNAL_TAG="testing"
 FROM ${DOCKER_REGISTRY}${BASE_IMAGE}:${INTERNAL_TAG} as spack
 ARG TARGETPLATFORM
 
+## With heredocs for multi-line scripts, we want to fail on error and the print failing line.
+## Ref: https://docs.docker.com/engine/reference/builder/#example-running-a-multi-line-script
+SHELL ["bash", "-ex", "-c"]
+
 ## install some extra spack dependencies
 RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=${TARGETPLATFORM} \
-    --mount=type=cache,target=/var/lib/apt/lists,sharing=locked,id=${TARGETPLATFORM} \
-    rm -f /etc/apt/apt.conf.d/docker-clean                              \
- && apt-get -yqq update                                                 \
- && apt-get -yqq install --no-install-recommends                        \
+    --mount=type=cache,target=/var/lib/apt/lists,sharing=locked,id=${TARGETPLATFORM} <<EOF
+rm -f /etc/apt/apt.conf.d/docker-clean
+apt-get -yqq update
+apt-get -yqq install --no-install-recommends                            \
         python3                                                         \
         python3-dev                                                     \
         python3-distutils                                               \
         python3-boto3                                                   \
         python-is-python3
+EOF
 
 ## Setup spack
 ENV SPACK_ROOT=/opt/spack
@@ -28,60 +33,65 @@ ARG SPACK_ORGREPO="spack/spack"
 ARG SPACK_VERSION="releases/v0.20"
 ARG SPACK_CHERRYPICKS=""
 ADD https://api.github.com/repos/${SPACK_ORGREPO}/commits/${SPACK_VERSION} /tmp/spack.json
-RUN git clone --filter=tree:0 https://github.com/${SPACK_ORGREPO}.git ${SPACK_ROOT}     \
- && git -C ${SPACK_ROOT} checkout ${SPACK_VERSION}                      \
- && if [ -n "${SPACK_CHERRYPICKS}" ] ; then                             \
-      git -C ${SPACK_ROOT} cherry-pick -n ${SPACK_CHERRYPICKS} ;        \
-    fi                                                                  \
- && ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash                \
-          /usr/bin/docker-shell                                         \
- && ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash                \
-          /usr/bin/interactive-shell                                    \
- && ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash                \
-          /usr/bin/spack-env
-
+RUN <<EOF
+git clone --filter=tree:0 https://github.com/${SPACK_ORGREPO}.git ${SPACK_ROOT}
+git -C ${SPACK_ROOT} checkout ${SPACK_VERSION}
+if [ -n "${SPACK_CHERRYPICKS}" ] ; then
+  SPACK_CHERRYPICKS=$(git -C ${SPACK_ROOT} rev-list --topo-order ${SPACK_CHERRYPICKS} | grep -m $(echo ${SPACK_CHERRYPICKS} | wc -w)  "${SPACK_CHERRYPICKS}" | tac)
+  git -C ${SPACK_ROOT} cherry-pick -n ${SPACK_CHERRYPICKS}
+fi
+ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/docker-shell
+ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/interactive-shell
+ln -s $SPACK_ROOT/share/spack/docker/entrypoint.bash /usr/bin/spack-env
+EOF
+
+## Use spack entrypoint. NOTE: Requires `set -ex` in all multi-line scripts!
 SHELL ["docker-shell"]
 
 ## Setup build configuration
 ARG jobs=64
-RUN declare -A target=(                                                 \
-      ["linux/amd64"]="x86_64_v2"                                       \
-      ["linux/arm64"]="aarch64"                                         \
-    )                                                                   \
- && target=${target[${TARGETPLATFORM}]}                                 \
- && spack config --scope site add "packages:all:require:[target=${target}]" \
- && spack config --scope site add "packages:all:target:[${target}]"     \
- && spack config blame packages                                         \
- && spack config --scope user add "config:suppress_gpg_warnings:true"   \
- && spack config --scope user add "config:build_jobs:${jobs}"           \
- && spack config --scope user add "config:db_lock_timeout:${jobs}00"    \
- && spack config --scope user add "config:source_cache:/var/cache/spack" \
- && spack config --scope user add "config:install_tree:root:/opt/software" \
- && spack config --scope user add "config:ccache:true"                  \
- && spack config blame config                                           \
- && spack compiler find --scope site                                    \
- && spack config blame compilers
+RUN <<EOF
+set -ex
+declare -A target=(["linux/amd64"]="x86_64_v2" ["linux/arm64"]="aarch64")
+target=${target[${TARGETPLATFORM}]}
+spack config --scope site add "packages:all:require:[target=${target}]"
+spack config --scope site add "packages:all:target:[${target}]"
+spack config blame packages
+spack config --scope user add "config:suppress_gpg_warnings:true"
+spack config --scope user add "config:build_jobs:${jobs}"
+spack config --scope user add "config:db_lock_timeout:${jobs}00"
+spack config --scope user add "config:source_cache:/var/cache/spack"
+spack config --scope user add "config:install_tree:root:/opt/software"
+spack config --scope user add "config:ccache:true"
+spack config blame config
+spack compiler find --scope site
+spack config blame compilers
+EOF
 
 ## Setup local buildcache mirrors
-RUN --mount=type=cache,target=/var/cache/spack                          \
-    spack mirror add local /var/cache/spack/mirror/${SPACK_VERSION}     \
- && spack buildcache update-index local                                 \
- && spack mirror list
+RUN --mount=type=cache,target=/var/cache/spack <<EOF
+set -ex
+spack mirror add local /var/cache/spack/mirror/${SPACK_VERSION}
+spack buildcache update-index local
+spack mirror list
+EOF
 
 ## Setup eics3 buildcache mirrors
 ## - this always adds the read-only mirror to the container
 ## - the write-enabled mirror is provided later as a secret mount
 ARG S3_ACCESS_KEY=""
 ARG S3_SECRET_KEY=""
-RUN --mount=type=cache,target=/var/cache/spack                          \
-    if [ -n "${S3_ACCESS_KEY}" ] ; then                                 \
-    spack mirror add --scope site                                       \
+RUN --mount=type=cache,target=/var/cache/spack <<EOF
+set -ex
+if [ -n "${S3_ACCESS_KEY}" ] ; then
+  spack mirror add --scope site                                         \
       --s3-endpoint-url https://eics3.sdcc.bnl.gov:9000                 \
       --s3-access-key-id "${S3_ACCESS_KEY}"                             \
       --s3-access-key-secret "${S3_SECRET_KEY}"                         \
-      eics3 s3://eictest/EPIC/spack/${SPACK_VERSION}                    \
-    ; fi                                                                \
- && spack mirror list
+      eics3 s3://eictest/EPIC/spack/${SPACK_VERSION}
+fi
+spack mirror list
+EOF
 
 ## Setup eic-spack
 ENV EICSPACK_ROOT=${SPACK_ROOT}/var/spack/repos/eic-spack
@@ -89,12 +99,28 @@ ARG EICSPACK_ORGREPO="eic/eic-spack"
 ARG EICSPACK_VERSION="$SPACK_VERSION"
 ARG EICSPACK_CHERRYPICKS=""
 ADD https://api.github.com/repos/${EICSPACK_ORGREPO}/commits/${EICSPACK_VERSION} /tmp/eic-spack.json
-RUN git clone --filter=tree:0 https://github.com/${EICSPACK_ORGREPO}.git ${EICSPACK_ROOT} \
- && git -C ${EICSPACK_ROOT} checkout ${EICSPACK_VERSION}                \
- && if [ -n "${EICSPACK_CHERRYPICKS}" ] ; then                          \
-      git -C ${EICSPACK_ROOT} cherry-pick -n ${EICSPACK_CHERRYPICKS} ;  \
-    fi                                                                  \
- && spack repo add --scope site "${EICSPACK_ROOT}"
+RUN <<EOF
+set -ex
+git clone --filter=tree:0 https://github.com/${EICSPACK_ORGREPO}.git ${EICSPACK_ROOT}
+git -C ${EICSPACK_ROOT} checkout ${EICSPACK_VERSION}
+if [ -n "${EICSPACK_CHERRYPICKS}" ] ; then
+  git -C ${EICSPACK_ROOT} cherry-pick -n ${EICSPACK_CHERRYPICKS}
+fi
+spack repo add --scope site "${EICSPACK_ROOT}"
+EOF
+
+## Setup key4hep-spack
+ENV KEY4HEPSPACK_ROOT=${SPACK_ROOT}/var/spack/repos/key4hep-spack
+ARG KEY4HEPSPACK_ORGREPO="key4hep/key4hep-spack"
+ARG KEY4HEPSPACK_VERSION="main"
+ADD https://api.github.com/repos/${KEY4HEPSPACK_ORGREPO}/commits/${KEY4HEPSPACK_VERSION} /tmp/key4hep-spack.json
+RUN <<EOF
+set -ex
+git clone --filter=tree:0 https://github.com/${KEY4HEPSPACK_ORGREPO}.git ${KEY4HEPSPACK_ROOT}
+git -C ${KEY4HEPSPACK_ROOT} checkout ${KEY4HEPSPACK_VERSION}
+spack repo add --scope site "${KEY4HEPSPACK_ROOT}"
+EOF
+
 
 ## ========================================================================================
 ## STAGE1: builder
@@ -113,38 +139,40 @@ ENV SPACK_ENV=/opt/spack-environment/${ENV}
 RUN --mount=type=cache,target=/ccache,id=${TARGETPLATFORM}              \
     --mount=type=cache,target=/var/cache/spack                          \
     --mount=type=secret,id=mirrors,target=/opt/spack/etc/spack/mirrors.yaml \
-    source $SPACK_ROOT/share/spack/setup-env.sh                         \
- && export CCACHE_DIR=/ccache                                           \
- && spack buildcache update-index local                                 \
- && spack buildcache update-index eics3rw                               \
- && spack env activate --dir ${SPACK_ENV}                               \
- && spack add juggler@git.${JUGGLER_VERSION}                            \
- && spack add eicrecon@git.${EICRECON_VERSION}                          \
- && make --jobs ${jobs} --keep-going --directory /opt/spack-environment \
-    SPACK_ENV=${SPACK_ENV}                                              \
-    BUILDCACHE_MIRROR="local eics3rw"                                   \
- && ccache --show-stats                                                 \
- && ccache --zero-stats
+    <<EOF
+set -ex
+export CCACHE_DIR=/ccache
+spack buildcache update-index local
+spack buildcache update-index eics3rw
+spack env activate --dir ${SPACK_ENV}
+spack add juggler@git.${JUGGLER_VERSION}
+spack add eicrecon@git.${EICRECON_VERSION}
+make --jobs ${jobs} --keep-going --directory /opt/spack-environment SPACK_ENV=${SPACK_ENV} BUILDCACHE_MIRROR="local eics3rw"
+ccache --show-stats
+ccache --zero-stats
+EOF
 
 ## Create view at /usr/local
-RUN --mount=type=cache,target=/var/cache/spack                          \
-    source $SPACK_ROOT/share/spack/setup-env.sh                         \
- && spack env activate --dir ${SPACK_ENV}                               \
- && rm -r /usr/local                                                    \
- && spack env view enable /usr/local
+RUN --mount=type=cache,target=/var/cache/spack <<EOF
+set -ex
+spack env activate --dir ${SPACK_ENV}
+rm -r /usr/local
+spack env view enable /usr/local
+EOF
 
 ## Optional, nuke the buildcache after install, before (re)caching
 ## This is useful when going to completely different containers,
 ## or intermittently to keep the buildcache step from taking too much time
 ARG CACHE_NUKE=""
-RUN --mount=type=cache,target=/var/cache/spack,sharing=locked           \
-    [ -z "${CACHE_NUKE}" ]                                              \
-    || rm -rf /var/cache/spack/mirror/${SPACK_VERSION}/build_cache/*
+RUN --mount=type=cache,target=/var/cache/spack,sharing=locked <<EOF
+[ -z "${CACHE_NUKE}" ] || rm -rf /var/cache/spack/mirror/${SPACK_VERSION}/build_cache/*
+EOF
 
-## Including some small fixes
-RUN echo "Grabbing environment info"                                    \
- && spack env activate --sh --dir ${SPACK_ENV}                          \
-    > /etc/profile.d/z10_spack_environment.sh
+## Store environment
+RUN <<EOF
+set -ex
+spack env activate --sh --dir ${SPACK_ENV} > /etc/profile.d/z10_spack_environment.sh
+EOF
 
 ## make sure we have the entrypoints setup correctly
 ENTRYPOINT []
@@ -152,6 +180,7 @@ CMD ["bash", "--rcfile", "/etc/profile", "-l"]
 USER 0
 WORKDIR /
 
+
 ## ========================================================================================
 ## STAGE 2: staging image with unnecessariy packages removed and stripped binaries
 ## ========================================================================================
@@ -167,17 +196,21 @@ RUN git -C $SPACK_ROOT gc --prune=all --aggressive
 ## See
 #https://askubuntu.com/questions/1034313/ubuntu-18-4-libqt5core-so-5-cannot-open-shared-object-file-no-such-file-or-dir
 ## and links therin for more info
-RUN if [ -f /usr/local/lib/libQt5Core.so ] ; then                       \
-      strip --remove-section=.note.ABI-tag /usr/local/lib/libQt5Core.so;\
-    fi
-
-RUN spack debug report                                                  \
-      | sed "s/^/ - /" | sed "s/\* \*\*//" | sed "s/\*\*//"             \
-    >> /etc/jug_info                                                    \
- && spack find --no-groups --long --variants | sed "s/^/ - /" >> /etc/jug_info \
- && spack graph --dot --installed > /opt/spack-environment/env.dot
-
-
+RUN <<EOF
+set -ex
+if [ -f /usr/local/lib/libQt5Core.so ] ; then
+  strip --remove-section=.note.ABI-tag /usr/local/lib/libQt5Core.so
+fi
+EOF
+
+RUN <<EOF
+set -ex
+spack debug report | sed "s/^/ - /" | sed "s/\* \*\*//" | sed "s/\*\*//" >> /etc/jug_info
+spack find --no-groups --long --variants | sed "s/^/ - /" >> /etc/jug_info
+spack graph --dot --installed > /opt/spack-environment/env.dot
+EOF
+
+## Copy custom content
 COPY eic-shell /usr/local/bin/eic-shell
 COPY eic-info /usr/local/bin/eic-info
 COPY entrypoint.sh /usr/local/sbin/entrypoint.sh
@@ -189,15 +222,16 @@ COPY singularity.d /.singularity.d
 ## Add minio client into /usr/local/bin
 ADD --chmod=0755 https://dl.min.io/client/mc/release/linux-amd64/mc /usr/local/bin/mc-amd64
 ADD --chmod=0755 https://dl.min.io/client/mc/release/linux-arm64/mc /usr/local/bin/mc-arm64
-RUN declare -A target=(                                                 \
-      ["linux/amd64"]="amd64"                                           \
-      ["linux/arm64"]="arm64"                                           \
-    )                                                                   \
- && mv /usr/local/bin/mc-${target[${TARGETPLATFORM}]} /usr/local/bin/mc \
- && unset target[${TARGETPLATFORM}]                                     \
- && for t in ${target[*]} ; do                                          \
-      rm /usr/local/bin/mc-${t} ;                                       \
-    done
+RUN <<EOF
+set -ex
+declare -A target=(["linux/amd64"]="amd64" ["linux/arm64"]="arm64")
+mv /usr/local/bin/mc-${target[${TARGETPLATFORM}]} /usr/local/bin/mc
+unset target[${TARGETPLATFORM}]
+for t in ${target[*]} ; do
+  rm /usr/local/bin/mc-${t}
+done
+EOF
+
 
 ## ========================================================================================
 ## STAGE 3
@@ -219,29 +253,38 @@ COPY --from=staging /etc/profile.d /etc/profile.d
 COPY --from=staging /etc/jug_info /etc/jug_info
 COPY --from=staging /etc/eic-env.sh /etc/eic-env.sh
 COPY --from=staging /.singularity.d /.singularity.d
+COPY --from=staging /usr/bin/docker-shell /usr/bin/docker-shell
+
+## Use spack entrypoint. NOTE: Requires `set -ex` in all multi-line scripts!
+ENV SPACK_ROOT=/opt/spack
+SHELL ["docker-shell"]
 
 ## ensure /usr/local link is pointing to the right view
-RUN rm -rf /usr/local                                                   \
- && PREFIX_PATH=$(realpath $(ls /usr/._local/ | tail -n1))              \
- && echo "Found spack true prefix path to be $PREFIX_PATH"              \
- && ln -s /usr/._local/${PREFIX_PATH} /usr/local
+RUN <<EOF
+set -ex
+rm -rf /usr/local
+PREFIX_PATH=$(realpath $(ls /usr/._local/ | tail -n1))
+echo "Found spack true prefix path to be $PREFIX_PATH"
+ln -s /usr/._local/${PREFIX_PATH} /usr/local
+EOF
 
 ## set the local spack configuration
 ENV SPACK_DISABLE_LOCAL_CONFIG="true"
-RUN . /opt/spack/share/spack/setup-env.sh                               \
- && spack config --scope site add "config:install_tree:root:~/spack"    \
- && spack config --scope site add "config:source_cache:~/.spack/cache"  \
- && spack config --scope site add "config:binary_index_root:~/.spack"   \
- && spack config --scope site add "config:environments_root:~/.spack/env" \
- && spack config --scope site add "config:suppress_gpg_warnings:true"   \
- && spack config blame config                                           \
- && spack config --scope site add "upstreams:eic-shell:install_tree:/opt/software" \
- && spack config blame upstreams
+RUN <<EOF
+set -ex
+spack config --scope site add "config:install_tree:root:~/spack"
+spack config --scope site add "config:source_cache:~/.spack/cache"
+spack config --scope site add "config:binary_index_root:~/.spack"
+spack config --scope site add "config:environments_root:~/.spack/env"
+spack config --scope site add "config:suppress_gpg_warnings:true"
+spack config blame config
+spack config --scope site add "upstreams:eic-shell:install_tree:/opt/software"
+spack config blame upstreams
+EOF
 
 ## set the jug_dev version and add the afterburner
 ARG JUG_VERSION=1
-RUN echo "" >> /etc/jug_info                                            \
- && echo " - jug_dev: ${JUG_VERSION}" >> /etc/jug_info
+RUN echo -e "\n - jug_dev: ${JUG_VERSION}" >> /etc/jug_info
 
 ## eicweb shortcut
 ARG EICWEB="https://eicweb.phy.anl.gov/api/v4/projects"
@@ -256,25 +299,18 @@ ADD ${EICWEB}/458/repository/tree?ref=${BENCHMARK_COM_VERSION} /tmp/485.json
 ADD ${EICWEB}/399/repository/tree?ref=${BENCHMARK_DET_VERSION} /tmp/399.json
 ADD ${EICWEB}/408/repository/tree?ref=${BENCHMARK_REC_VERSION} /tmp/408.json 
 ADD ${EICWEB}/400/repository/tree?ref=${BENCHMARK_PHY_VERSION} /tmp/400.json
-RUN mkdir -p /opt/benchmarks                                                    \
- && cd /opt/benchmarks                                                          \
- && git clone -b ${BENCHMARK_COM_VERSION} --depth 1                             \
-        https://eicweb.phy.anl.gov/EIC/benchmarks/common_bench.git              \
- && mkdir -p /opt/benchmarks                                                    \
- && cd /opt/benchmarks                                                          \
- && git clone -b ${BENCHMARK_DET_VERSION} --depth 1                             \
-        https://eicweb.phy.anl.gov/EIC/benchmarks/detector_benchmarks.git       \
- && ln -sf ../common_bench detector_benchmarks/.local                           \
- && mkdir -p /opt/benchmarks                                                    \
- && cd /opt/benchmarks                                                          \
- && git clone -b ${BENCHMARK_REC_VERSION} --depth 1                             \
-        https://eicweb.phy.anl.gov/EIC/benchmarks/reconstruction_benchmarks.git \
- && ln -sf ../common_bench reconstruction_benchmarks/.local                     \
- && mkdir -p /opt/benchmarks                                                    \
- && cd /opt/benchmarks                                                          \
- && git clone -b ${BENCHMARK_PHY_VERSION} --depth 1                             \
-        https://eicweb.phy.anl.gov/EIC/benchmarks/physics_benchmarks.git        \
- && ln -sf ../common_bench physics_benchmarks/.local
+RUN <<EOF
+set -ex
+mkdir -p /opt/benchmarks
+cd /opt/benchmarks
+git clone -b ${BENCHMARK_COM_VERSION} --depth 1 https://eicweb.phy.anl.gov/EIC/benchmarks/common_bench.git
+git clone -b ${BENCHMARK_DET_VERSION} --depth 1 https://eicweb.phy.anl.gov/EIC/benchmarks/detector_benchmarks.git
+ln -sf ../common_bench detector_benchmarks/.local
+git clone -b ${BENCHMARK_REC_VERSION} --depth 1 https://eicweb.phy.anl.gov/EIC/benchmarks/reconstruction_benchmarks.git
+ln -sf ../common_bench reconstruction_benchmarks/.local
+git clone -b ${BENCHMARK_PHY_VERSION} --depth 1 https://eicweb.phy.anl.gov/EIC/benchmarks/physics_benchmarks.git
+ln -sf ../common_bench physics_benchmarks/.local
+EOF
 
 ## Install campaigns into the container
 ARG CAMPAIGNS_SINGLE_VERSION="main"
@@ -286,22 +322,15 @@ ADD https://api.github.com/repos/eic/simulation_campaign_single/commits/${CAMPAI
 ADD https://api.github.com/repos/eic/simulation_campaign_hepmc3/commits/${CAMPAIGNS_HEPMC3_VERSION} /tmp/simulation_campaign_hepmc3.json
 ADD https://api.github.com/repos/eic/job_submission_condor/commits/${CAMPAIGNS_CONDOR_VERSION} /tmp/job_submission_condor.json
 ADD https://api.github.com/repos/eic/job_submission_slurm/commits/${CAMPAIGNS_SLURM_VERSION} /tmp/job_submission_slurm.json
-RUN mkdir -p /opt/campaigns                                                     \
- && cd /opt/campaigns                                                           \
- && git clone -b ${CAMPAIGNS_SINGLE_VERSION} --depth 1                          \
-        https://github.com/eic/simulation_campaign_single.git single            \
- && mkdir -p /opt/campaigns                                                     \
- && cd /opt/campaigns                                                           \
- && git clone -b ${CAMPAIGNS_HEPMC3_VERSION} --depth 1                          \
-        https://github.com/eic/simulation_campaign_hepmc3.git hepmc3            \
- && mkdir -p /opt/campaigns                                                     \
- && cd /opt/campaigns                                                           \
- && git clone -b ${CAMPAIGNS_CONDOR_VERSION} --depth 1                          \
-        https://github.com/eic/job_submission_condor.git condor                 \
- && mkdir -p /opt/campaigns                                                     \
- && cd /opt/campaigns                                                           \
- && git clone -b ${CAMPAIGNS_SLURM_VERSION} --depth 1                           \
-        https://github.com/eic/job_submission_slurm.git slurm
+RUN <<EOF
+set -ex
+mkdir -p /opt/campaigns
+cd /opt/campaigns
+git clone -b ${CAMPAIGNS_SINGLE_VERSION} --depth 1 https://github.com/eic/simulation_campaign_single.git single
+git clone -b ${CAMPAIGNS_HEPMC3_VERSION} --depth 1 https://github.com/eic/simulation_campaign_hepmc3.git hepmc3
+git clone -b ${CAMPAIGNS_CONDOR_VERSION} --depth 1 https://github.com/eic/job_submission_condor.git condor
+git clone -b ${CAMPAIGNS_SLURM_VERSION} --depth 1 https://github.com/eic/job_submission_slurm.git slurm
+EOF
 
 ## make sure we have the entrypoints setup correctly
 ENTRYPOINT ["/usr/local/sbin/entrypoint.sh"]
@@ -312,8 +341,7 @@ SHELL ["/usr/local/bin/eic-shell"]
 
 ## eic-news
 COPY --chmod=0755 eic-news /usr/local/bin/eic-news
-RUN echo "test -f $HOME/.eic-news && source /usr/local/bin/eic-news"            \
-    > /etc/profile.d/z13_eic-news.sh 
+RUN echo "test -f $HOME/.eic-news && source /usr/local/bin/eic-news" > /etc/profile.d/z13_eic-news.sh 
 
 ## Hotfix for misbehaving OSG nodes
 RUN mkdir /hadoop
diff --git a/containers/jug/xl.Dockerfile b/containers/jug/xl.Dockerfile
index bbe6d3b8c8672aa99a5590ea6cf6d03c7c101a57..0ae17fb9318407f9aafacc2503491bda8d4eb356 100644
--- a/containers/jug/xl.Dockerfile
+++ b/containers/jug/xl.Dockerfile
@@ -17,8 +17,7 @@ ARG jobs=8
 ## the date
 ARG JUG_VERSION=1
 
-RUN cd /tmp                                                                     \
- && echo " - jug_xl: ${JUG_VERSION}" >> /etc/jug_info
+RUN echo " - jug_xl: ${JUG_VERSION}" >> /etc/jug_info
 
 ## also install detector/ip geometries into opt
 ARG NIGHTLY=''
@@ -31,11 +30,11 @@ ADD https://api.github.com/repos/eic/ip6 /tmp/ip6.json
 ADD https://api.github.com/repos/eic/epic /tmp/epic.json
 COPY setup_detectors.py /tmp
 COPY --from=detectors detectors.yaml /tmp
-RUN --mount=type=cache,target=/ccache/,sharing=locked,id=${TARGETPLATFORM}      \
-    cd /tmp                                                                     \
- && export CCACHE_DIR=/ccache                                                   \
- && [ "z$NIGHTLY" = "z1" ] && NIGHTLY_FLAG="--nightly" || NIGHTLY_FLAG=""       \
- && /tmp/setup_detectors.py --prefix /opt/detector --config /tmp/detectors.yaml \
-                         $NIGHTLY_FLAG                                          \
- && ccache --show-stats                                                         \
- && rm /tmp/setup_detectors.py
+RUN --mount=type=cache,target=/ccache/,sharing=locked,id=${TARGETPLATFORM} <<EOF
+cd /tmp
+export CCACHE_DIR=/ccache
+[ "z$NIGHTLY" = "z1" ] && NIGHTLY_FLAG="--nightly" || NIGHTLY_FLAG=""
+/tmp/setup_detectors.py --prefix /opt/detector --config /tmp/detectors.yaml $NIGHTLY_FLAG
+ccache --show-stats
+rm /tmp/setup_detectors.py
+EOF
diff --git a/detectors.yaml b/detectors.yaml
index 9bfd1ed809de8649bc15a23b85394d7e08d8ec3e..0a38b953c8116af83867a5c0024e433a775d948c 100644
--- a/detectors.yaml
+++ b/detectors.yaml
@@ -5,18 +5,6 @@ detectors:
       version: main
     main:
       version: main
-    23.05.0:
-      version: 23.05.0
-      patches:
-      - https://github.com/eic/epic/pull/449.patch
-    23.05.1:
-      version: 23.05.1
-      patches:
-      - https://github.com/eic/epic/pull/449.patch
-    23.05.2:
-      version: 23.05.2
-      patches:
-      - https://github.com/eic/epic/pull/449.patch
     23.06.0:
       version: 23.06.0
       patches:
@@ -37,3 +25,7 @@ detectors:
       version: 23.09.0
     23.09.1:
       version: 23.09.1
+    23.10.0:
+      version: 23.10.0
+    23.11.0:
+      version: 23.11.0
diff --git a/eic-spack.sh b/eic-spack.sh
index 5165e2965db7ba31e3d7501d1c73e7325e691be5..1ef49afaf38db259c0eaf69c0b32b479aed85b70 100644
--- a/eic-spack.sh
+++ b/eic-spack.sh
@@ -1,9 +1,9 @@
 ## EIC spack organization and repository, e.g. eic/eic-spack
 EICSPACK_ORGREPO="eic/eic-spack"
 
-## EIC spack github version, e.g. v0.19.7 or commit hash
-## note: nightly builds will use e.g. releases/v0.19
-EICSPACK_VERSION="v0.20.20"
+## EIC spack commit hash or github version, e.g. v0.19.7
+## note: nightly builds could use a branch e.g. releases/v0.19
+EICSPACK_VERSION="1d2956a5f87ada2bf04ed1bdee761baf81b85feb"
 
 ## Space-separated list of eic-spack cherry-picks
 read -r -d '' EICSPACK_CHERRYPICKS <<- \
diff --git a/spack-environment/dev/spack.yaml b/spack-environment/dev/spack.yaml
index 20b183d058f359fff6889e919fd2d2a9d87189db..4a2dcd6d605eadc3299f9344577181bbd7537805 100644
--- a/spack-environment/dev/spack.yaml
+++ b/spack-environment/dev/spack.yaml
@@ -48,9 +48,11 @@ spack:
     - prmon
     - pythia8
     - py-awkward
+    - py-bokeh
     - py-boto3
     - py-dask
     - py-deepdiff
+    - py-epic-capybara
     - py-ipython
     - py-jinja2
     - py-jinja2-cli
@@ -74,8 +76,10 @@ spack:
     - py-wurlitzer
     - py-yapf
     - root
+    - snakemake
     - spdlog
     - stow
     - tensorflow-lite
+    - valgrind
     - xrootd
   view: false
diff --git a/spack-environment/packages.yaml b/spack-environment/packages.yaml
index 8229931680a6bbc9f1ef682cc6045dbc89fc4b2f..6ae53f2b22b70e7d508e4e435d18923a8a1b2c55 100644
--- a/spack-environment/packages.yaml
+++ b/spack-environment/packages.yaml
@@ -32,7 +32,7 @@ packages:
     - +root +zlib
   algorithms:
     require:
-    - '@main'
+    - '@git.ebc8f85709bc7233574843b843ee0191a5bf3c1d'
   cairo:
     require:
     - '@1.16.0'
@@ -80,7 +80,7 @@ packages:
     - '@656aa3192b097a631ddd1e0380e80c26fd6644a7'
   edm4eic:
     require:
-    - '@3.0.1'
+    - '@4.0.0'
     - cxxstd=17
   edm4hep:
     require:
@@ -88,7 +88,7 @@ packages:
     - cxxstd=17
   eic-smear:
     require:
-    - '@1.1.10'
+    - '@1.1.12'
   eigen:
     require:
     - '@3.4.0'
@@ -141,7 +141,7 @@ packages:
     - '@2020.3'
   irt:
     require:
-    - '@1.0.6'
+    - '@1.0.7'
   jana2:
     require:
     - '@2.1.1'
@@ -198,6 +198,9 @@ packages:
   py-awkward:
     require:
     - '@2.1.1'
+  py-bokeh:
+    require:
+    - '@2.4.3'
   py-boto3:
     require:
     - '@1.26.26'
@@ -207,6 +210,9 @@ packages:
   py-deepdiff:
     require:
     - '@6.3.0'
+  py-epic-capybara:
+    require:
+    - '@main'
   py-ipython:
     require:
     - '@8.11.0'
@@ -282,6 +288,10 @@ packages:
     - '@6.28.06'
     - cxxstd=17 +fftw +fortran +gdml +http -ipo +mlp +pythia8 +root7 +tmva +vc -webgui +xrootd +ssl
     - any_of: [+opengl +x, -opengl -x]
+  snakemake:
+    require:
+    - '@7.22.0'
+    - +http +s3
   spdlog:
     require:
     - '@1.11.0'
@@ -293,6 +303,9 @@ packages:
     require:
     - '@2.8.0'
     - -xnnpack
+  valgrind:
+    require:
+    - '@3.20.0'
   xrootd:
     require:
     - '@5.5.5'
diff --git a/spack.sh b/spack.sh
index ada33d274fc4555e79e504fd31474444aa616d3f..cb412258f4e488e58137000e985afc6a86f9f37d 100644
--- a/spack.sh
+++ b/spack.sh
@@ -28,6 +28,7 @@ ed76eab6943221f17776fd8d128ade6ba69e492c
 e3e7609af4903be7df42b6ae5ccf9a20293503d2
 df4a2457a41e7ab634e86d3148d8b22a9f433a6a
 a65f13f79f617b6aa0b235aa5db612473b6d8c0e
+53a45c820c983867e8b05cab3df34e98b468f932
 ---
 ## Ref: https://github.com/spack/spack/commit/[hash]
 ## [hash]: [description]
@@ -51,3 +52,4 @@ a65f13f79f617b6aa0b235aa5db612473b6d8c0e
 ## e3e7609af4903be7df42b6ae5ccf9a20293503d2: edm4hep: Add version 0.9
 ## df4a2457a41e7ab634e86d3148d8b22a9f433a6a: Fix broken semver regex
 ## a65f13f79f617b6aa0b235aa5db612473b6d8c0e: root: add latest available tag
+## 53a45c820c983867e8b05cab3df34e98b468f932: docker entrypoint.sh: fail multi-line RUN on first error with set -e