From d7c2815310402e48697bffb3b881057ee2791bca Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 15:05:55 +0000 Subject: [PATCH 1/2] fix: stop clobbering the working tfp-nightly in the smoke installer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The smoke installer ran `pip install tensorflow-probability==0.25.0` after `PyAutoArray[optional]`, overwriting the working `tfp-nightly` (which PyAutoArray[optional] pins) with the stable release. Stable tfp crashes at import under the resolved modern JAX — it references `jax.interpreters.xla.pytype_aval_mappings`, removed from JAX >=0.10 — which broke the JAX Matern-kernel (`delaunay_mge`) likelihood path. Remove the line and document why; the JAX path now imports the compatible tfp-nightly. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_013ciVftxvYpefh59wSkR7jN --- .github/scripts/smoke_install.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/scripts/smoke_install.sh b/.github/scripts/smoke_install.sh index 9c8c2e35..33ea037d 100644 --- a/.github/scripts/smoke_install.sh +++ b/.github/scripts/smoke_install.sh @@ -13,5 +13,9 @@ else pip install ./PyAutoNerves ./PyAutoFit ./PyAutoArray ./PyAutoGalaxy pip install numba nufftax fi -pip install tensorflow-probability==0.25.0 +# NOTE: do NOT `pip install tensorflow-probability==0.25.0` here. The stable +# release crashes at import under the resolved modern JAX +# (`jax.interpreters.xla.pytype_aval_mappings` was removed), which broke the +# JAX Matern-kernel (delaunay_mge) likelihood path. The working modified-Bessel +# dependency is `tfp-nightly`, pinned by `PyAutoArray[optional]` above. pip install jupyter nbconvert ipynb-py-convert From aed0b41b3fc84064974c784529de178da627247b Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 15:22:43 +0000 Subject: [PATCH 2/2] fix: run notebook smoke from the workspace root so dataset paths resolve `jupyter nbconvert --execute` runs the kernel in the notebook's own directory (e.g. `notebooks/interferometer/`), so a notebook that reads a committed dataset via a repo-root-relative path (`Path("dataset", ...)`, matching the workspace "run from the repo root" convention and the script smoke's `cwd=WORKSPACE`) fails with FileNotFoundError. Stage a temporary copy of the notebook at the workspace root before executing so the kernel's working directory is the root. This fixes the `interferometer/simulator.ipynb` and `imaging/modeling.ipynb` notebook smoke failures (missing `dataset/interferometer/uv_wavelengths/sma.fits`). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_013ciVftxvYpefh59wSkR7jN --- .github/scripts/run_smoke.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/scripts/run_smoke.py b/.github/scripts/run_smoke.py index 98e4b750..98ad946a 100644 --- a/.github/scripts/run_smoke.py +++ b/.github/scripts/run_smoke.py @@ -101,6 +101,13 @@ def execute_notebook(nb_path: Path, env: dict) -> tuple[int, str]: # Write the executed copy to a throwaway path so the on-disk notebook # under notebooks/ is never modified — checked-in notebooks stay clean. tmp_dir = Path(tempfile.mkdtemp(prefix="smoke_nb_")) + # `jupyter nbconvert --execute` runs the kernel in the *notebook's own + # directory*, but the workspace convention (and the script smoke, which runs + # with cwd=WORKSPACE) is that relative `dataset/` paths resolve from the repo + # root. Stage a temporary copy of the notebook at the workspace root so the + # kernel's working directory is the root and root-relative paths resolve. + staged = WORKSPACE / f".smoke_run_{os.getpid()}_{nb_path.name}" + shutil.copyfile(nb_path, staged) try: result = subprocess.run( [ @@ -113,7 +120,7 @@ def execute_notebook(nb_path: Path, env: dict) -> tuple[int, str]: str(tmp_dir), "--output", nb_path.name, - str(nb_path), + str(staged), ], cwd=str(WORKSPACE), env=env, @@ -121,6 +128,7 @@ def execute_notebook(nb_path: Path, env: dict) -> tuple[int, str]: text=True, ) finally: + staged.unlink(missing_ok=True) shutil.rmtree(tmp_dir, ignore_errors=True) return result.returncode, result.stdout + result.stderr