diff --git a/create_job_widget_script.sh b/create_job_widget_script.sh
index c5dcadfbba32022bf4025dd0007793b8a4701dc6..c81cbc42dbc75eca9b01a86893692a37079cf5f6 100644
--- a/create_job_widget_script.sh
+++ b/create_job_widget_script.sh
@@ -46,8 +46,7 @@ spec:
           . \$INSTALLATION_ROOT/spack/share/spack/setup-env.sh
           spack env activate --without-view \$EBRAINS_SPACK_ENV
           KERNEL_PATH=\$LAB_KERNEL_ROOT/\$(echo "\$RELEASE_NAME" | tr '[:upper:]' '[:lower:]')
-          spack load --sh --first clb-nb-utils py-pip py-tvb-ext-bucket py-tvb-ext-unicore py-tvb-ext-xircuits > \$KERNEL_PATH/bin/widget_activation.sh
-        env:
+          spack load --sh --first clb-nb-utils py-pip py-tvb-ext-bucket py-tvb-ext-unicore py-tvb-ext-xircuits > \$KERNEL_PATH/bin/widget_activation.sh        env:
           - name: SYSTEMNAME
             value: ebrainslab
           - name: SPACK_DISABLE_LOCAL_CONFIG
diff --git a/packages/py-jaxopt/package.py b/packages/py-jaxopt/package.py
new file mode 100644
index 0000000000000000000000000000000000000000..b45801a6c0bd486a1507b52f493066786f9ee8aa
--- /dev/null
+++ b/packages/py-jaxopt/package.py
@@ -0,0 +1,30 @@
+# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+
+from spack.package import *
+
+
+class PyJaxopt(PythonPackage):
+    """Hardware accelerated, batchable and differentiable optimizers in JAX."""
+
+    homepage = "https://github.com/google/jaxopt"
+    pypi     = "jaxopt/jaxopt-0.8.5.tar.gz"
+
+    maintainers = ['jaxopt']
+
+    version('0.8.5', sha256='ff221d1a86908ec759eb1e219ee1d12bf208a70707e961bf7401076fe7cf4d5e')
+    version('0.8.4', sha256='420878c37650c8c0752f8a75b20afb0ddc52bc12b63667910131057295b0e6ab')
+    version('0.8.3', sha256='4be2f82798393682529c9ca5046e5397ac6c8657b8acb6bf275e773b28df15b6')
+    version('0.8.2', sha256='5dd94a635ae52899d4a5063ec88b4c1ca9f04d921b888f73211a444c937b7cfa')
+    version('0.8.1', sha256='af6ef03d11d72dcf51b606d3046ebec8be0227f5d4e653cd1768cc8dab12cabb')
+
+    depends_on('python@3.7:', type=('build', 'run'))
+
+    depends_on('py-setuptools', type='build')
+
+    depends_on('py-numpy@1.18.4:', type=('build', 'run'))
+    depends_on('py-scipy@1.0.0:', type=('build', 'run'))
+    depends_on('py-jax@0.2.18:', type=('build', 'run'))
+    depends_on('py-jaxlib@0.1.69:', type=('build', 'run'))
diff --git a/packages/wf-inversion/package.py b/packages/wf-inversion/package.py
new file mode 100644
index 0000000000000000000000000000000000000000..b3d6836906f6f455ae54dbd77265e4f7c1a336af
--- /dev/null
+++ b/packages/wf-inversion/package.py
@@ -0,0 +1,66 @@
+# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+
+from spack.package import *
+
+
+class WfInversion(Package):
+    """Meta-package to collect all dependencies for EBR task 3.3."""
+
+    git = "https://gitlab.ebrains.eu/ri/projects-and-initiatives/ebrains-2/wp3/workflows/Task3.3.git"
+    maintainer = ["Tomas Fiers"]
+
+    # version("0.1.0")
+    version("master",  branch="master")
+
+    depends_on("py-numpyro", type=("run", "test"))
+    depends_on("py-arviz@0.6.1:", type=("run", "test"))
+    depends_on("py-graphviz@0.20.3:", type=("run", "test"))
+    depends_on("py-vbjax@0.0.16:", type=("run", "test"))
+    depends_on("py-frites@0.4.4:", type=("run", "test"))
+
+    depends_on("py-jax@0.4.24:", type=("build", "run"))
+    depends_on("py-jaxopt@0.8.1:", type=("build", "run"))
+
+    depends_on("py-matplotlib@3.7.3:", type=("run", "test"))
+    depends_on("py-pyyaml@6.0:", type=("run", "test"))
+
+    def install(self, spec, prefix):
+        install_tree(".", join_path(prefix, "notebooks"))
+
+    def _nbconvert(self, nb, nb_out):
+        jupyter = Executable("jupyter")
+        args = [
+            "nbconvert",
+            "--ExecutePreprocessor.kernel_name=python3",
+            "--execute",
+            "--to",
+            "notebook",
+            nb,
+            "--output",
+            nb_out
+        ]
+        try:
+            # execute notebook and save
+            jupyter(*args)
+        except Exception as e:
+            # if the above fails, re-run notebook to produce output with error
+            jupyter(*(args+["--allow-errors"]))
+            raise
+
+    def _run_notebooks(self, output_dir):
+        mkdirp(output_dir)
+        self._nbconvert(join_path(self.prefix, "notebooks", "DCM_PPLs", "running on ebrains -- DCM_EPR_Numpyro_NUTS_Demo.ipynb"), join_path(output_dir, "running on ebrains -- DCM_EPR_Numpyro_NUTS_Demo.ipynb"))
+        self._nbconvert(join_path(self.prefix, "notebooks", "DCM_HGA", "examples", "dcm_bilinear_dataset_TRLs-mix_GammaInput.ipynb"), join_path(output_dir, "dcm_bilinear_dataset_TRLs-mix_GammaInput.ipynb"))
+        self._nbconvert(join_path(self.prefix, "notebooks", "DCM_HGA", "examples", "dcm_bilinear_dataset_TRLs-nstat_GammaInput.ipynb"), join_path(output_dir, "dcm_bilinear_dataset_TRLs-nstat_GammaInput.ipynb"))
+
+    @run_after("install")
+    @on_package_attributes(run_tests=True)
+    def installcheck(self):
+        self._run_notebooks(join_path(self.stage.path, ".install_time_tests"))
+        copy_tree(join_path(self.stage.path, ".install_time_tests"), join_path(self.prefix, '.build'))
+
+    def test_notebook(self):
+        self._run_notebooks(join_path(self.test_suite.stage, self.spec.format("out-{name}-{version}-{hash:7}")))