Overview
A census of the Google Colab infrastructure (2026-07-09) found that while the release-time machinery is solid (tag bumper wired into release.yml, central Heart URL sweep), only 9 of 489 notebooks are actually Colab-runnable — docs and READMEs link 100+ notebooks (all HowTo chapters, the PyAutoFit flagship badge) that die on ModuleNotFoundError. This task makes Colab support mature and maintainable by construction: a generalized setup_colab registry in PyAutoConf, generation-time injection of a standard setup cell into every notebook in PyAutoBuild, and hardened forbidden-URL guards in PyAutoHeart. After this merges, the next release regenerates all notebooks Colab-ready automatically, with zero per-script maintenance.
Phase 2 (link rot: HowTo chapter README URLs, library-docs dead links, allowlist purges) is parked at PyAutoMind/feature/workspaces/colab_link_rot.md and will be issued when this phase nears shipping.
Plan
- Generalize
autoconf.setup_colab into one parameterized per-project registry covering all 6 notebook repos (autofit/autogalaxy/autolens workspaces + HowToFit/HowToGalaxy/HowToLens), fixing the GPU-detection bug, the import-time env mutation, and duplicated package lists; clone the release-matched tag shallowly; add the module's first unit tests.
- Inject a standard Colab setup cell (markdown + code) into every notebook PyAutoBuild generates, parameterized by project, skipping notebooks that already carry a hand-written setup; add tests and document the end-to-end Colab architecture in
docs/internals.md.
- Extend PyAutoHeart's offline URL guard with the two rot classes the census found: unpinned
blob/main Colab URLs (invisible to the release bumper) and Colab links to notebooks/chapter_* paths in workspace repos (chapters live in the HowTo repos). This intentionally turns the Monday sweep red until phase 2 fixes the rot.
Detailed implementation plan
Affected Repositories
- PyAutoBuild (primary)
- PyAutoConf
- PyAutoHeart
Branch Survey
| Repository |
Current Branch |
Dirty? |
| ./PyAutoConf |
main |
clean |
| ./PyAutoBuild |
main |
clean |
| ./PyAutoHeart |
main |
clean |
Suggested branch: feature/colab-maturity
Work Classification: Library
Worktree root: ~/Code/PyAutoLabs-wt/colab-maturity/ (created by /start_library)
Implementation Steps
-
PyAutoConf — autoconf/setup_colab.py rewrite
_PROJECTS registry keyed autofit | autogalaxy | autolens | howtofit | howtogalaxy | howtolens → package list, workspace repo URL, workspace dir, display name, GPU error message. One shared extras list (pyvis, dill, jaxnnls, nautilus-sampler, timeout_decorator, anesthetic) + per-project core stack — kills the duplicated lists in for_autolens/for_autogalaxy.
- Public API:
setup(project: str, raise_error_if_not_gpu: bool = False). Keep for_autolens / for_autogalaxy as thin back-compat wrappers (released notebooks at old tags call them); add for_autofit and HowTo wrappers.
- Fix
check_jax_using_gpu: accumulate across all devices (today the last device wins) and handle the empty-device case (today UnboundLocalError).
- Delete the module-level
os.environ['XLA_FLAGS'] mutation (line 4) — it already happens inside _colab_setup; today every from autoconf import setup_colab clobbers user env even outside Colab.
- Clone
--depth 1 --branch <installed-version> (version via importlib.metadata.version of the project's top package), falling back to the default branch — removes the version skew between the pip-installed release, the tagged notebook, and today's main-HEAD clone; --depth 1 makes the clone fast on the large workspaces.
- New
test_autoconf/test_setup_colab.py: registry completeness/shape, wrapper delegation, clone tag-fallback (mocked subprocess), GPU-detection logic on stub device objects (numpy-only — no JAX in library unit tests), no import-time env mutation.
-
PyAutoBuild — generation-time injection
autobuild/build_util.py: new inject_colab_setup(notebook_path, project) — prepend a markdown cell (what the cell does, GPU-runtime tip) and a code cell (try: import google.colab → bootstrap pip install autoconf --no-deps → from autoconf import setup_colab; setup_colab.setup("<project>")). Skip injection when the notebook source already contains setup_colab (the 9 hand-written start_here setups keep working, no double setup).
autobuild/generate.py: call the injector after both py_to_notebook sites (root start_here*.py + the scripts loop), mapping the project CLI arg to the registry key. Copy-files (verbatim .py) are not notebooks and are not injected.
- Tests (
tests/): cell injected with valid JSON, idempotent, skip-if-present, project key threaded correctly.
docs/internals.md: new "Colab architecture" section — bootstrap module (PyAutoConf) → generation-time injection (Build) → release-time URL bumper (bump_colab_urls.sh) → weekly central sweep (Heart).
-
PyAutoHeart — guard hardening
heart/checks/url_check.sh: two new forbidden entries: colab.research.google.com/github/PyAutoLabs/(autofit_workspace|autogalaxy_workspace|autolens_workspace|HowToFit|HowToGalaxy|HowToLens)/blob/main/ ("pin to a date tag — the release bumper skips main") and colab.research.google.com/github/PyAutoLabs/(autofit|autogalaxy|autolens)_workspace/blob/<ref>/notebooks/chapter_ ("chapter tutorials live in the HowTo repos").
- Extend
tests/test_url_check.py with both patterns (positive + negative cases).
Key Files
PyAutoConf/autoconf/setup_colab.py — runtime bootstrap, rewritten around the registry
PyAutoConf/test_autoconf/test_setup_colab.py — new test module
PyAutoBuild/autobuild/build_util.py — py_to_notebook + new inject_colab_setup
PyAutoBuild/autobuild/generate.py — injection call sites
PyAutoBuild/docs/internals.md — Colab architecture docs
PyAutoHeart/heart/checks/url_check.sh — forbidden-pattern guard
PyAutoHeart/tests/test_url_check.py — guard tests
Trade-offs
- Setup cells go into all notebooks, including advanced pipelines impractical on Colab — harmless (no-op outside Colab, and bootstrap is still correct if opened there).
- The
--no-deps install strategy is deliberately kept (Colab ships the scientific stack; full dependency resolution is slow and can break Colab's numpy).
- Injected cells use
raise_error_if_not_gpu=False for frictionless first contact; the markdown cell tells users how to enable a GPU runtime.
- The new Heart guard patterns will fail the Monday sweep until phase 2 lands — accepted forcing function.
Original Prompt
Click to expand starting prompt
See PyAutoMind/issued/colab_maturity.md — includes the full 2026-07-09 census (coverage counts, URL-form inventory, allowlist rot, setup_colab defect list).
We have most of the infrastructure in place to make workspace exampels and tutorials run in Google colab, such that users can mess around with everything without installation. This includes docs pointing to them, links on our README.md, etc. But, the infrastructure could be developed in a more mature and robust way, including better on going maintenance during release and whatnot. Given we only have Fable access until Sunday, can you do a census of the Google Colab setup for all projects and do the work to make it more polished, mature and maintainable?
Overview
A census of the Google Colab infrastructure (2026-07-09) found that while the release-time machinery is solid (tag bumper wired into
release.yml, central Heart URL sweep), only 9 of 489 notebooks are actually Colab-runnable — docs and READMEs link 100+ notebooks (all HowTo chapters, the PyAutoFit flagship badge) that die onModuleNotFoundError. This task makes Colab support mature and maintainable by construction: a generalizedsetup_colabregistry in PyAutoConf, generation-time injection of a standard setup cell into every notebook in PyAutoBuild, and hardened forbidden-URL guards in PyAutoHeart. After this merges, the next release regenerates all notebooks Colab-ready automatically, with zero per-script maintenance.Phase 2 (link rot: HowTo chapter README URLs, library-docs dead links, allowlist purges) is parked at
PyAutoMind/feature/workspaces/colab_link_rot.mdand will be issued when this phase nears shipping.Plan
autoconf.setup_colabinto one parameterized per-project registry covering all 6 notebook repos (autofit/autogalaxy/autolens workspaces + HowToFit/HowToGalaxy/HowToLens), fixing the GPU-detection bug, the import-time env mutation, and duplicated package lists; clone the release-matched tag shallowly; add the module's first unit tests.docs/internals.md.blob/mainColab URLs (invisible to the release bumper) and Colab links tonotebooks/chapter_*paths in workspace repos (chapters live in the HowTo repos). This intentionally turns the Monday sweep red until phase 2 fixes the rot.Detailed implementation plan
Affected Repositories
Branch Survey
Suggested branch:
feature/colab-maturityWork Classification: Library
Worktree root:
~/Code/PyAutoLabs-wt/colab-maturity/(created by/start_library)Implementation Steps
PyAutoConf —
autoconf/setup_colab.pyrewrite_PROJECTSregistry keyedautofit | autogalaxy | autolens | howtofit | howtogalaxy | howtolens→ package list, workspace repo URL, workspace dir, display name, GPU error message. One shared extras list (pyvis,dill,jaxnnls,nautilus-sampler,timeout_decorator,anesthetic) + per-project core stack — kills the duplicated lists infor_autolens/for_autogalaxy.setup(project: str, raise_error_if_not_gpu: bool = False). Keepfor_autolens/for_autogalaxyas thin back-compat wrappers (released notebooks at old tags call them); addfor_autofitand HowTo wrappers.check_jax_using_gpu: accumulate across all devices (today the last device wins) and handle the empty-device case (todayUnboundLocalError).os.environ['XLA_FLAGS']mutation (line 4) — it already happens inside_colab_setup; today everyfrom autoconf import setup_colabclobbers user env even outside Colab.--depth 1 --branch <installed-version>(version viaimportlib.metadata.versionof the project's top package), falling back to the default branch — removes the version skew between the pip-installed release, the tagged notebook, and today'smain-HEAD clone;--depth 1makes the clone fast on the large workspaces.test_autoconf/test_setup_colab.py: registry completeness/shape, wrapper delegation, clone tag-fallback (mockedsubprocess), GPU-detection logic on stub device objects (numpy-only — no JAX in library unit tests), no import-time env mutation.PyAutoBuild — generation-time injection
autobuild/build_util.py: newinject_colab_setup(notebook_path, project)— prepend a markdown cell (what the cell does, GPU-runtime tip) and a code cell (try: import google.colab→ bootstrappip install autoconf --no-deps→from autoconf import setup_colab; setup_colab.setup("<project>")). Skip injection when the notebook source already containssetup_colab(the 9 hand-written start_here setups keep working, no double setup).autobuild/generate.py: call the injector after bothpy_to_notebooksites (rootstart_here*.py+ the scripts loop), mapping theprojectCLI arg to the registry key. Copy-files (verbatim.py) are not notebooks and are not injected.tests/): cell injected with valid JSON, idempotent, skip-if-present, project key threaded correctly.docs/internals.md: new "Colab architecture" section — bootstrap module (PyAutoConf) → generation-time injection (Build) → release-time URL bumper (bump_colab_urls.sh) → weekly central sweep (Heart).PyAutoHeart — guard hardening
heart/checks/url_check.sh: two new forbidden entries:colab.research.google.com/github/PyAutoLabs/(autofit_workspace|autogalaxy_workspace|autolens_workspace|HowToFit|HowToGalaxy|HowToLens)/blob/main/("pin to a date tag — the release bumper skips main") andcolab.research.google.com/github/PyAutoLabs/(autofit|autogalaxy|autolens)_workspace/blob/<ref>/notebooks/chapter_("chapter tutorials live in the HowTo repos").tests/test_url_check.pywith both patterns (positive + negative cases).Key Files
PyAutoConf/autoconf/setup_colab.py— runtime bootstrap, rewritten around the registryPyAutoConf/test_autoconf/test_setup_colab.py— new test modulePyAutoBuild/autobuild/build_util.py—py_to_notebook+ newinject_colab_setupPyAutoBuild/autobuild/generate.py— injection call sitesPyAutoBuild/docs/internals.md— Colab architecture docsPyAutoHeart/heart/checks/url_check.sh— forbidden-pattern guardPyAutoHeart/tests/test_url_check.py— guard testsTrade-offs
--no-depsinstall strategy is deliberately kept (Colab ships the scientific stack; full dependency resolution is slow and can break Colab's numpy).raise_error_if_not_gpu=Falsefor frictionless first contact; the markdown cell tells users how to enable a GPU runtime.Original Prompt
Click to expand starting prompt
See
PyAutoMind/issued/colab_maturity.md— includes the full 2026-07-09 census (coverage counts, URL-form inventory, allowlist rot,setup_colabdefect list).