Skip to content

release: wire PyAutoCTI into the lockstep release train (cti-upkeep p1) #332

Closed

Description

@Jammy2211

Overview

autocti on PyPI is still 2024.11.13.2, and it pins autofit==2024.11.13.2, because PyAutoCTI was never added back to the release train after it was revived. This phase puts PyAutoCTI on the lockstep train as the sixth library (ruling R6) and gives the autocti workspaces Colab-ready notebooks, so the first modern autocti release can go out with the nightly. This is epic cti-upkeep, phase 1; rulings R1–R6 are closed.

Plan

  • PyAutoNerves: add an autocti entry to setup_colab and a for_autocti() helper. On Colab it builds arcticpy by running PyAutoHeart's install_arcticpy.sh (human ruling 2026-11-04), so the arcticpy pin stays in one place.
  • PyAutoHands: add PyAutoCTI everywhere the train lists its libraries: LIB_PROJECTS; release.yml (TestPyPI and PyPI matrices, release smoke, label clearing, release notes, Slack and aggregate maps, release_workspaces, wiki_currency_check_autocti); python_matrix.yml (3.12 and 3.13 only, per R4); pre_build.sh WORKSPACE_SPECS; workspaces.yaml; and COLAB_PROJECTS. Only the CTI legs install arcticpy, through Heart's install-arcticpy action.
  • PyAutoBrain: add CTI to the library lists in the release scripts (rehearse, validate, nightly, clean-slate).
  • PyAutoHeart: set release_gate: true for PyAutoCTI, and add CTI rows to Release Integrate, workspace-validation.yml and docs-build.yml.
  • PyAutoMind: add FIREWALL_ALLOWLIST tokens for organ files that gain CTI names.
  • autocti_workspace: regenerate the notebooks with the real generate.py autocti, after a control test against an unchanged script. Add config/build/profile_release.yaml and correct AGENTS.md.
  • Rehearsal: run /release rehearse --ref feature/cti-release-train-wiring (TestPyPI only) before any merge. Then the PRs go to /prm in this order: Nerves, then Hands, Brain, Heart and Mind, then the workspace. The first real release goes out with the next nightly. release.yml is never dispatched by hand.
  • Tier: judge. Merge mode: human /prm.
Detailed implementation plan

Affected Repositories

  • PyAutoHands (primary), PyAutoNerves, PyAutoBrain, PyAutoHeart, PyAutoMind, autocti_workspace

Branch Survey

Repository Current Branch Dirty?
./organs/PyAutoHands main clean. Claimed by generate-converter-preflight (PyAutoHands#331, open)
./organs/PyAutoNerves main clean
./organs/PyAutoBrain main clean
./organs/PyAutoHeart main clean
./organs/PyAutoMind main clean
./cti/autocti_workspace main clean

Suggested branch: feature/cti-release-train-wiring

Implementation Steps

  1. Nerves autonerves/setup_colab.py: add _AUTOCTI_STACK = _AUTOFIT_STACK + ["autoarray", "autocti"] and a _PROJECTS["autocti"] entry with pre_install="arcticpy". _colab_setup runs that hook before the pip install: it fetches raw.githubusercontent.com/PyAutoLabs/PyAutoHeart/main/.github/actions/install-arcticpy/install_arcticpy.sh and runs it with ARCTICPY_SUDO=false PYTHON=sys.executable. Add for_autocti() and tests.
  2. Hands:
    • autohands/tag_and_merge.sh: add PyAutoCTI to LIB_PROJECTS.
    • pre_build.sh: add the rows autocti_workspace autocti true false and autocti_workspace_test autocti false false.
    • autohands/build_util.py: add autocti to COLAB_PROJECTS.
    • autohands/config/workspaces.yaml: add autocti / autocti_test to run_all, PyAutoCTI to libraries, and autocti to colab_setup and colab_gemini (assistant: autocti_assistant).
    • .github/workflows/release.yml: add PyAutoCTI to release_test_pypi and release (with if-gated install-arcticpy and autocti install steps), autocti_workspace to the run_smoke_tests matrix (arcticpy-gated), clear_pending_release_labels repositories, publish_release_notes, the release_workspaces rows, and a wiki_currency_check_autocti / wiki_drift_issue_autocti pair. The pyautocti-release visualization dispatch is included if autocti_visualization has a receiver.
    • python_matrix.yml: CTI unit and smoke legs on 3.12 and 3.13.
    • generate_release_notes.py, slack_release_notes.py, aggregate_results.py, generate_markdown.py, navigator.py, bin/autohands: add the repo maps.
  3. Brain: add PyAutoCTI to LIBRARIES in agents/conductors/release/{rehearse,validate}.sh, the nightly library list, and bin/clean_slate.sh PACKAGING_REPOS.
  4. Heart: set config/repos.yaml PyAutoCTI release_gate: true, and add CTI rows to the Release Integrate / workspace-validation.yml / docs-build.yml maps.
  5. Mind: add FIREWALL_ALLOWLIST tokens.
  6. autocti_workspace: control-test generate.py on an unchanged script, then run generate.py autocti and check that no notebook has a Finish. cell or a literal # %% or '''. Add config/build/profile_release.yaml and update the Notebook regeneration line in AGENTS.md.
  7. Validation: generate.py <unknown> still refuses with notebooks/ intact; generate.py howtolens gives a zero diff; Hands, Nerves, Brain and Heart test suites pass; then the TestPyPI rehearsal and Heart ingest.

Key Files

  • PyAutoHands/.github/workflows/release.yml, python_matrix.yml, pre_build.sh, autohands/{tag_and_merge.sh,build_util.py,config/workspaces.yaml}
  • PyAutoNerves/autonerves/setup_colab.py
  • PyAutoHeart/config/repos.yaml
  • PyAutoBrain/agents/conductors/release/{rehearse,validate}.sh

Risks

  • The release job uploads to PyPI with fail-fast on; the human confirmed on 2026-11-04 that the PYPI token covers autocti.
  • After release_gate: true, Heart's readiness depends on CTI's CI.

Original Prompt

Click to expand starting prompt

CTI release-train wiring — first modern autocti release

Type: release
Target: PyAutoHands
Repos:

  • @PyAutoHands
  • @PyAutoNerves
  • @autocti_workspace
    Themes:
  • release
  • cti
    Difficulty: medium
    Autonomy: human-required
    Priority: normal
    Status: formalised
    Consequence: judge
    Review-minutes: 20
    Unattended: never
    Epic: cti-upkeep
    Phase: 1
    Filed: 2026-07-17 (backfilled from git)

Follow-up to the CTI resurrection epic (Phases 0-5; workspace_test + Heart
polling shipped 2026-07-17). Wire autocti into the release train and produce
its first modern PyPI release. Deliberately split from the epic's Phase 5:
this touches the nightly's most dangerous machinery and must be done with a
TestPyPI rehearsal, in a fresh session.

Scope

  1. PyAutoHands: tag_and_merge.sh LIB_PROJECTS += PyAutoCTI;
    pre_build.sh run_workspace lines for autocti_workspace (+ _test,
    generate=false); release.yml / python_matrix.yml matrices;
    generate_release_notes.py + slack_release_notes.py +
    aggregate_results.py repo maps; build_util.py COLAB_PROJECTS +=
    autocti; FIREWALL_ALLOWLIST tokens in Mind for every file gaining CTI names.
  2. PyAutoNerves autonerves/setup_colab.py: an autocti _PROJECTS entry
    whose package list handles arcticpy correctly on Colab (apt
    libgsl-dev + pip install numpy cython + arcticpy==2.6 --no-build-isolation --no-deps — a naive pip install downgrades numpy
    below 2.0). May need a per-project pre_install hook in the setup
    machinery.
  3. Notebook generation: generate.py autocti (blocked today by the
    COLAB_PROJECTS registry check) → commit regenerated notebooks to
    autocti_workspace. This is a fork, not a formality: either register
    autocti (items 1-2 above, if its notebooks are meant to carry Colab setup)
    or give generate.py a documented no-Colab mode for workspaces that do
    not. Whichever path is taken, update autocti_workspace/AGENTS.md's
    Notebook regeneration line to match it — that line currently implies the
    standard path works, which it does not.
  4. Rehearsal then release: TestPyPI rehearsal of the extended train
    (release rehearse / release validate through the Release Agent), fix
    fallout, then the first modern autocti release rides the next nightly or
    a human-authorized release. Never hand-dispatch the nightly.

Context

  • Item 3's blocker is now a clean refusal, not a destructive one (fix: generate.py deletes notebooks/ before validating the project name #215
    / PR fix: validate the project before generate.py deletes notebooks/ #216, 2026-07-30). generate.py used to rmtree the whole notebooks/
    tree before reaching the COLAB_PROJECTS check, so probing generate.py autocti deleted 113 tracked notebooks and then aborted. It now validates up
    front and exits with "Nothing was modified", leaving the tree untouched — so
    this task can probe the registry check freely. The registration itself
    (items 1-2) is untouched and still belongs here. Pinned by
    PyAutoHands/tests/test_generate_validates_project.py; the ordering is
    invisible in a passing run, so do not remove that test while reworking
    generate.py for item 3.
  • Why this stayed invisible. autocti_workspace is absent from
    PyAutoHands/pre_build.sh's run_workspace matrix entirely (the
    generate=true set is autofit_workspace, autogalaxy_workspace,
    autolens_workspace, HowToGalaxy, HowToLens, HowToFit), so no release path has
    ever exercised generate.py autocti. Corroborating: 0 of the repo's 79
    notebooks carry a Colab setup cell
    , dating them to before
    inject_colab_setup became strict. They do still track scripts/ 1:1 (79
    scripts, 79 notebooks, no orphans either way), so they were maintained by
    some path that no longer works. Item 1's pre_build.sh line is what closes
    this hole for good.
  • Backlog item 3 will clear when it runs: autocti_workspace/notebooks/
    currently carries 34 Finish. markdown cells (from the crutch sweep,
    docs: remove the Finished./Finish. notebook-generation crutch autocti_workspace#16) and 4 mangled code cells containing a literal
    # %% and ''' — a SyntaxError if run — in
    notebooks/imaging_ci/modeling/features/{cosmic_rays,non_uniform,serial_cti,visualize_full}.ipynb,
    plus the 5 script-reference fixes from autocti_workspace#15. All are already
    correct in scripts/; one successful generate.py autocti clears all of them.
    So item 3 is the single gate on three separate merged sweeps reaching the
    notebooks.
  • Do not hand-roll the regeneration. build_util.py_to_notebook alone is not
    equivalent to generate.py: control-tested against an unchanged script
    (scripts/dataset_1d/extract.py vs the committed
    notebooks/dataset_1d/extract.ipynb), the committed notebook carries a
    trailing empty code cell that py_to_notebook does not emit — 343 vs 336
    lines, otherwise identical. That cell is the signature of the pre-2026-07-24
    generator (before PyAutoHands 6916814 a closing docstring always emitted a
    # %%), so these 79 notebooks predate it — expect the regeneration to drop
    those empty cells across the board, which is correct. Control-test against an
    unchanged script before trusting any regeneration path here; that is what
    caught this.
  • Epic records: PyAutoMind/complete/2026/07/cti-resurrection-phase{0..5}.md.
  • PyAutoCTI pyproject floors are release-ready (setuptools-scm, Phase 0);
    CI green via Heart lib-tests (Phase 3); Heart polls the CTI repos (Phase 5).
  • arcticpy traps + CI install recipe: PyAutoCTI/AGENTS.md and
    autocti_workspace_test/.github/scripts/smoke_install.sh.

Validation

  • generate.py autocti exits 0 from autocti_workspace/; all 79 notebooks
    regenerate; no code cell contains a literal # %% or '''; no markdown cell
    is Finish..
  • generate.py <unknown-project> still exits non-zero with notebooks/
    intact and no stray .ipynb beside any script
    (PyAutoHands/tests/test_generate_validates_project.py stays green).
  • generate.py howtolens from HowToLens/ still gives a zero diff — the
    registry change must not perturb the projects already on the train.
  • autocti_workspace/AGENTS.md's Notebook regeneration line matches whatever
    path item 3 actually chose.
  • pre_build.sh's run_workspace matrix names autocti_workspace, so the next
    nightly exercises the path rather than skipping it.

Provenance

Folded 2026-08-26: draft/bug/pyautohands/generate_rejects_autocti_after_deleting_notebooks.md
was retired into this file. That prompt tracked two defects — the destructive
ordering in generate.py (fixed by #215 / PR #216,
regression-tested) and the missing autocti registration. Only the second was
ever this file's items 1-3, so the bug prompt had no startable work of its own;
its residual requirements (the AGENTS.md doc line, the pre_build-matrix
evidence, the control-test detail) are absorbed above. It had itself
consolidated three independently-filed prompts describing the same defect.

Activity

  1. Jammy2211 commented on Nov 5, 2026

    @Jammy2211
    CollaboratorAuthor

    Progress 2026-11-05: PRs open, TestPyPI rehearsal passed

    PRs (judge tier, human /prm in this order):

    1. feat: Colab setup for autocti, arcticpy via Heart's install script PyAutoNerves#210
    2. feat: wire PyAutoCTI into the lockstep release train #333, feat(release): add PyAutoCTI to rehearse/validate and clean_slate PyAutoBrain#585, feat: PyAutoCTI joins the release gate PyAutoHeart#323, chore: firewall allowlist for CTI release-train tokens, file fits_fit bug PyAutoMind#535
    3. feat: regenerated notebooks with Colab setup, release smoke profile autocti_workspace#40

    Rehearsal from the Hands branch: run 42011123173 at 92ec5f4. All six wheels, PyAutoCTI included, built, uploaded and installed from TestPyPI as 2026.11.5.1.dev86501. Heart ingest: rehearse stage pass. The overall readiness verdict is RED only for local-checkout reasons that clear on merge and pull: PyAutoNerves is on the feature branch, and Fit, Galaxy and Lens are 2 commits behind origin.

    The first rehearsal (run 42008346668) also passed, but its rehearsal.json listed only five packages. That is fixed in Hands ac3c75d and 92ec5f4.

    Found on the way: with PYAUTO_FAST_PLOTS=1, autocti fits_fit writes fit.fits into a folder that does not exist yet, and all 3 release smoke scripts fail. The autocti release profile uses PYAUTO_FAST_PLOTS: "0" for now (3/3 pass). The library fix is filed as draft/bug/autocti/fits_fit_missing_output_dir_under_fast_plots.md (cti-upkeep phase 3).

    Next: human /prm in the order above.

    🤖 Generated with Claude Code

  2. Jammy2211 commented on Nov 5, 2026

    @Jammy2211
    CollaboratorAuthor

    Shipped 2026-11-05

    All six PRs are merged, in gate order:

    The TestPyPI rehearsal from the branch (run 42011123173) built, uploaded and installed all six packages, and Heart ingested it as a rehearse-stage pass.

    Next: the first modern autocti PyPI release goes out with the next lockstep release. The release now includes autocti, and Heart's release gate now covers it. Still deferred to cti-upkeep phase 3/5: workspace-validation / release-integrate rows, run_all, the docs-build mapping, and the fits_fit FAST_PLOTS fix.

    🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions