diff --git a/containers/jug/dev.Dockerfile b/containers/jug/dev.Dockerfile
index ee6c6e02c74813e4d5db4b8026cd37d2a8f949d1..f59d3d8d02b15f78d1d15a48aff059dfcef187e5 100644
--- a/containers/jug/dev.Dockerfile
+++ b/containers/jug/dev.Dockerfile
@@ -157,11 +157,11 @@ make --jobs ${jobs} --keep-going --directory /opt/spack-environment \
   SPACK_ENV=${SPACK_ENV} \
   BUILDCACHE_OCI_PROMPT="eicweb" \
   BUILDCACHE_OCI_FINAL="ghcr"
-spack find --implicit --no-groups \
+spack find --long --no-groups \
 | sed -e '1,/Installed packages/d;s/\([^@]*\).*/\1/g' \
-| uniq -d | grep -v py-pip | grep -v py-cython \
+| uniq -D -f1 | grep -v -w -e "\(epic\|py-pip\|py-cython\)" \
 | tee /tmp/duplicates.txt
-test -s /tmp/duplicates.txt && exit 1
+test -s /tmp/duplicates.txt && ( cat /tmp/duplicates.txt | while read hash spec ; do spack spec --long /${hash} ; done ) && exit 1
 ccache --show-stats
 ccache --zero-stats
 EOF
@@ -208,11 +208,11 @@ spack concretize --fresh --force
 make --jobs ${jobs} --keep-going --directory /opt/spack-environment \
   SPACK_ENV=${SPACK_ENV} \
   BUILDCACHE_OCI_FINAL="eicweb"
-spack find --implicit --no-groups \
+spack find --long --no-groups \
 | sed -e '1,/Installed packages/d;s/\([^@]*\).*/\1/g' \
-| uniq -d | grep -v py-pip | grep -v py-cython \
+| uniq -D -f1 | grep -v -w -e "\(epic\|py-pip\|py-cython\)" \
 | tee /tmp/duplicates.txt
-test -s /tmp/duplicates.txt && exit 1
+test -s /tmp/duplicates.txt && ( cat /tmp/duplicates.txt | while read hash spec ; do spack spec --long /${hash} ; done ) && exit 1
 ccache --show-stats
 ccache --zero-stats
 EOF
diff --git a/spack-environment/Makefile b/spack-environment/Makefile
index 9b363d3b3b30d7f0147de33b82012e12d860250c..0ce2ee2c35e0745aa8f70f6aafb8e95ab10ab44c 100644
--- a/spack-environment/Makefile
+++ b/spack-environment/Makefile
@@ -1,6 +1,6 @@
 MAKEFLAGS += -Orecurse
 
-SPACK ?= spack
+SPACK ?= spack --backtrace
 SPACK_INSTALL_FLAGS += --no-check-signature --show-log-on-error
 
 export SPACK_COLOR = always
@@ -22,15 +22,15 @@ include $(SPACK_ENV)/spack.mk
 endif
 
 $(SPACK_ENV)/push: $(addprefix $(SPACK_ENV)/push/,$($(SPACK_ENV)/SPACK_PACKAGE_IDS))
-	$(foreach buildcache, $(BUILDCACHE_S3_FINAL), $(SPACK) buildcache push --unsigned $(buildcache) ;)
+	$(foreach buildcache, $(BUILDCACHE_S3_FINAL), $(SPACK) buildcache push --private --unsigned $(buildcache) ;)
 	$(foreach buildcache, $(BUILDCACHE_S3_FINAL), $(SPACK) buildcache update-index $(buildcache) ;)
 	$(foreach buildcache, $(BUILDCACHE_S3_PROMPT), $(SPACK) buildcache update-index $(buildcache) ;)
-	$(foreach buildcache, $(BUILDCACHE_OCI_FINAL), $(SPACK) buildcache push --unsigned --base-image $(BUILDCACHE_OCI_BASE_IMAGE) $(buildcache) | grep -v "Using cached archive" ;)
+	$(foreach buildcache, $(BUILDCACHE_OCI_FINAL), $(SPACK) buildcache push --private --unsigned --base-image $(BUILDCACHE_OCI_BASE_IMAGE) $(buildcache) | grep -v "Using cached archive" ;)
 
 $(SPACK_ENV)/push/%: $(SPACK_ENV)/install/%
 	@mkdir -p $(dir $@)
-	$(foreach buildcache, $(BUILDCACHE_S3_PROMPT), $(SPACK) buildcache push --unsigned --only=package $(buildcache) /$(HASH) ;) # push $(SPEC)
-	$(foreach buildcache, $(BUILDCACHE_OCI_PROMPT), $(SPACK) buildcache push --unsigned --base-image $(BUILDCACHE_OCI_BASE_IMAGE) $(buildcache) /$(HASH) | grep -v "Using cached archive" ;) # push $(SPEC)
+	$(foreach buildcache, $(BUILDCACHE_S3_PROMPT), $(SPACK) buildcache push --private --unsigned --only=package $(buildcache) /$(HASH) ;) # push $(SPEC)
+	$(foreach buildcache, $(BUILDCACHE_OCI_PROMPT), $(SPACK) buildcache push --private --unsigned --base-image $(BUILDCACHE_OCI_BASE_IMAGE) $(buildcache) /$(HASH) | grep -v "Using cached archive" ;) # push $(SPEC)
 	@touch $@
 
 $(SPACK_ENV)/spack.lock: $(SPACK_ENV)/spack.yaml Makefile
diff --git a/spack-environment/packages.yaml b/spack-environment/packages.yaml
index 0d91a1d216b25921d3ca8cb4af2bda23256e1b2d..b610a5456658653a9597c32c90c5bd5f1dc3d946 100644
--- a/spack-environment/packages.yaml
+++ b/spack-environment/packages.yaml
@@ -14,8 +14,8 @@ packages:
     require:
     - '%gcc'
     - any_of: [+ipo, '@:']
+    - any_of: [build_system=cmake, '@:']
     - any_of: [build_type=Release, '@:']
-    - any_of: [^py-pip@23.1.2, '@:']
   acts:
     require:
     - '@31.2.0'
@@ -127,6 +127,9 @@ packages:
     require:
     - '@9.1.0'
     - +shared cxxstd=17
+  freetype:
+    require:
+    - build_system=autotools
   gaudi:
     require:
     - '@38.1'
@@ -144,9 +147,12 @@ packages:
     - '@11.2.2.east'
     - cxxstd=20 -vecgeom +threads -vtk
     - any_of: [+opengl +qt +x11, -opengl -qt -x11]
-  glew:
+  gettext: 
+    require:
+    - +libxml2
+  gl:
     require:
-    - gl=glx
+    - glx
   gloo:
     require:
     - '@2023-05-19'
@@ -251,6 +257,9 @@ packages:
     require:
     - '@3.0.2'
     - +plot
+  protobuf:
+    require:
+    - '@3.21.12'
   pythia8:
     require:
     - '@8.311'
@@ -333,6 +342,9 @@ packages:
   py-pre-commit:
     require:
     - '@3.3.3'
+  py-protobuf:
+    require:
+    - '@4.21.9'
   py-pygithub:
     require:
     - '@2.1.1'
diff --git a/spack-environment/view.yaml b/spack-environment/view.yaml
index 889bfaea85873416af15d4c13e0a31b485e2d4a7..8cc72277fd1be758e151fcaf21ed6157c11c9862 100644
--- a/spack-environment/view.yaml
+++ b/spack-environment/view.yaml
@@ -1,11 +1,14 @@
   view:
     default:
       root: /opt/local
-      exclude: [epic]
+      exclude: 
+      - epic
+      - py-pip@23.0
       link_type: symlink
     detectors:
       root: /opt/detector
-      select: [epic]
+      select:
+      - epic
       projections:
         all: '{name}-{version}'
       link: roots
diff --git a/spack.sh b/spack.sh
index c55cee5499aef3b228a0b5a010750a1d43b9e0b7..4ffc57ddad2255919ede63ca03905325ca179073 100644
--- a/spack.sh
+++ b/spack.sh
@@ -3,7 +3,7 @@ SPACK_ORGREPO="spack/spack"
 
 ## Spack github version, e.g. v0.18.1 or commit hash
 ## note: nightly builds will use e.g. releases/v0.19
-SPACK_VERSION="v0.22.0"
+SPACK_VERSION="v0.22.1"
 
 ## Space-separated list of spack cherry-picks
 read -r -d '' SPACK_CHERRYPICKS <<- \
@@ -11,7 +11,6 @@ read -r -d '' SPACK_CHERRYPICKS <<- \
 09f75ee426a2e05e0543570821582480ff823ba5
 f6d50f790ee8b123f7775429f6ca6394170e6de9
 63f6e6079aacc99078386e5c8ff06173841b9595
-9bcc43c4c158639fa6cb575c6106595a34682081
 9f3e45ddbee24aaa7993e575297827e0aed2e6fe
 85f13442d2a7486daba81fdd9a3b6a1182ba11f6
 f73d7d2dce226857cbc774e942454bad2992969e
@@ -34,7 +33,6 @@ read -r -d '' SPACK_CHERRYPICKS_FILES <<- \
 ## 09f75ee426a2e05e0543570821582480ff823ba5: setup-env.sh: if exe contains qemu, use /proc/$$/comm instead
 ## f6d50f790ee8b123f7775429f6ca6394170e6de9: gaudi: Add version 38.1
 ## 63f6e6079aacc99078386e5c8ff06173841b9595: gaudi: upstream patch when @38.1 for missing #include <list>
-## 9bcc43c4c158639fa6cb575c6106595a34682081: protobuf: update hash for patch needed when="@3.4:3.21"
 ## 9f3e45ddbee24aaa7993e575297827e0aed2e6fe: acts: pass cuda_arch to CMAKE_CUDA_ARCHITECTURES
 ## 85f13442d2a7486daba81fdd9a3b6a1182ba11f6: Consolidate concretization output for environments
 ## f73d7d2dce226857cbc774e942454bad2992969e: dd4hep: cleanup recipe, remove deprecated versions and patches