Skip to content

feat: PyAutoEyes phase 3 — birth autogalaxy_visualization #452

Description

@Jammy2211

Epic: pyautoeyes-birth, phase 3
Heart at the door (2026-09-29): YELLOW — "PyAutoMemory: open PR 7d old" (continue; acknowledgement is a ship-time act).

Overview

Birth the second <lib>_visualization project repo, PyAutoLabs/autogalaxy_visualization (local checkout galaxy/autogalaxy_visualization), so the PyAutoEyes cross-project dashboard shows every PyAutoGalaxy visualizer output. It mirrors the phase-1a autolens_visualization layout exactly: flat producers, tracked datasets, all-true plots.yaml, render harness, tracked PNGs + GALLERY.md + gallery/viz_manifest.yaml, lint/render workflows. The instance is then registered across the body map (Mind), Heart drift exclusion, Brain prose, and the PyAutoEyes registry.yaml.

Plan

  • Push an initial stub (LICENSE + README) to the empty repo's main, clone it to galaxy/autogalaxy_visualization, then build the repo on a feature branch by copying the lens repo's skeleton and rewriting every lens-specific piece for galaxy.
  • Three flat producers — imaging, interferometer, ellipse — rendering every PyAutoGalaxy visualizer output on HST-scale imaging and SMA interferometer data (instrument presets copied from the lens repo), with galaxy-only simulated datasets tracked and an all-true config/visualize/plots.yaml.
  • Render harness, tracked PNGs, GALLERY.md, tracked gallery/viz_manifest.yaml, lint.yml + render.yml (galaxy stack only; render.yml fires eyes-refresh at PyAutoEyes).
  • Register the instance: Mind repos.yaml row + ROUTING target + repos_sync --write; Heart drift exclusion; Brain prose; PyAutoEyes registry.yaml galaxy row + tests + regenerated dashboard.
  • Ship library-first in the 1a merge order: Brain → autogalaxy_visualization → Mind → Heart → Eyes (Eyes last: its check HEADs every galaxy PNG on the galaxy repo's main).

Corrections to the draft prompt (found in the survey):

  1. Nothing sends pyautolens-release today — PyAutoLens, PyAutoGalaxy and Hands release.yml contain no repository_dispatch sender; only the lens render.yml listens. This task's galaxy render.yml listens for pyautogalaxy-release + workflow_dispatch (parity with lens); the sender (Hands release.yml firing both pyautolens-release and pyautogalaxy-release via PAT_PYAUTOLABS) is filed as a separate Mind draft draft/feature/pyautohands/release_fires_visualization_dispatch.md. PyAutoGalaxy stays untouched (claimed by workspace-config-cleanup).
  2. The Eyes survey scans scripts/<domain>/*.py non-recursively (open bug draft), so the galaxy repo uses the flat scripts/<domain>/visualization.py producer layout.

Human-only steps (surfaced at ship):

  • Grant PAT_PYAUTOLABS access to autogalaxy_visualization (otherwise the eyes-refresh dispatch 403s/skips).
  • Create the eyes-critique label on the new repo (agent tries gh label create; human runs it if denied).
  • .github profile README patch from repos_sync stays human-only, as in phase 1a.
Detailed implementation plan

Affected Repositories

  • autogalaxy_visualization (primary; empty GitHub repo PyAutoLabs/autogalaxy_visualization, to be cloned at galaxy/autogalaxy_visualization)
  • PyAutoEyes
  • PyAutoMind
  • PyAutoBrain
  • PyAutoHeart
  • (PyAutoGalaxy deliberately NOT touched — claimed by workspace-config-cleanup)

Branch Survey

Repository Current Branch Dirty?
galaxy/autogalaxy_visualization main (empty remote; to be cloned) clean
organs/PyAutoEyes main clean
organs/PyAutoMind main clean
organs/PyAutoBrain main clean
organs/PyAutoHeart main clean

worktree_check_conflict: no conflict.

Suggested branch: feature/eyes-galaxy-instance (all five repos)
Worktree: ~/Code/PyAutoLabs-wt/eyes-galaxy-instance (via /start_library)

Implementation Steps

A. New repo galaxy/autogalaxy_visualization (template: lens/autolens_visualization @ 078c1e2)

Copy the whole tree except PNGs, dataset/, GALLERY.md, gallery/viz_manifest.yaml,
and .git; then rewrite. Files and the galaxy-specific change in each:

  • README.md, AGENTS.md, CLAUDE.md (@AGENTS.md stub), AI_POLICY.md, LICENSE,
    ruff.toml (repo-root sentinel), .gitignore, .claude/ hooks — lens → galaxy prose,
    repo names, Pages/registry links; note the eyes-critique label + /eyes review galaxy.
  • activate.sh: PYTHONPATH drops lens/PyAutoLens; keep Nerves/Fit/Array/Galaxy; the
    ../.. root walk works from galaxy/.
  • _viz_cli.py: RuntimeError text; no other logic change.
  • config/general.yaml (workspace_version_check: false), config/visualize/plots.yaml:
    derive from galaxy/PyAutoGalaxy/autogalaxy/config/visualize/plots.yaml with every
    boolean true (fit.subplot_fit_log10, subplot_of_galaxies, subplot_galaxy_images;
    galaxies.; inversion.subplot_mappings; fit_interferometer.subplot_fit_dirty_images,
    subplot_fit_real_space; fit_ellipse.
    already true).
  • instruments/{README.md,__init__.py,imaging.py,interferometer.py}: copy verbatim
    (presets euclid/hst/jwst/jwst_lw/ao; sma noise_sigma 10.0/alma/alma_high/jvla), prose
    only.
  • scripts/misc/simulators/imaging.py, interferometer.py: ag. models — Sersic bulge +
    Exponential disk galaxy (imaging, HST preset) and an MGE/Sersic galaxy (interferometer,
    SMA preset); write dataset/imaging/hst/{data,noise_map,psf}.fits + galaxies.json
    and dataset/interferometer/sma/{data,noise_map,uv_wavelengths}.fits + galaxies.json
    (tracked, as lens tracks its tracer.json). No positions.json (no lensing).
  • Producers (flat, one per domain, same 5-step shape as lens: push config with
    output_path=scripts/<d>/images, auto_simulate_if_missing, true model with every
    parameter fixed, visualize_before_fit once then visualize per source in
    ("parametric","delaunay"), wipe scripts/<d>/images/visualization/ first, scratch in
    output/visualization/<d>):
    • scripts/imaging/visualization.py — VisualizerImaging (port of
      galaxy/autogalaxy_workspace_test/scripts/imaging/visualization/visualization.py,
      keep parametric + delaunay, drop rectangular, plus visualize_combined if it produces
      figures); galaxy key ('galaxies','galaxy').
    • scripts/interferometer/visualization.py — VisualizerInterferometer (port of the
      workspace_test interferometer script), parametric + delaunay.
    • scripts/ellipse/visualization.py — VisualizerEllipse (port of the workspace_test
      ellipse script): before-fit + the four scenarios plain / multipole (m=4) / scaled /
      masked, on the tracked HST imaging dataset (as workspace_test reuses imaging); source
      subdirs named plain, multipole, multipole_scaled, masked. If the 300-iteration
      masked loop is too slow at HST scale, keep it but note runtime in the README.
  • gallery/gallery_build.py: VERSION_LINE_PREFIX = "Rendered with PyAutoGalaxy",
    STACK minus autolens, autogalaxy_version() in place of the autolens override,
    HTML/Markdown titles; manifest rendered_with must include autogalaxy (Eyes freshness
    column reads import_name). gallery/gallery_run.sh: unchanged logic (scripts/*/ visualization*.py, --all / domain / --build-only).
  • scripts/misc/test/test_gallery_build.py: FAKE_STACK drops autolens; assertion
    becomes "Rendered with PyAutoGalaxy 9.9.9".
  • .github/workflows/render.yml: triggers workflow_dispatch (input autogalaxy_version)
    • repository_dispatch: types: [pyautogalaxy-release]; installs autogalaxy[optional]
      from PyPI; runs gallery_run.sh --all; commits scripts/*/images GALLERY.md gallery/viz_manifest.yaml as github-actions[bot] [skip ci]; then
      gh api repos/PyAutoLabs/PyAutoEyes/dispatches -f event_type=eyes-refresh with
      client_payload[repo|sha|manifest], GH_TOKEN: secrets.PAT_PYAUTOLABS, skipped when
      empty.
  • .github/workflows/lint.yml: checkouts Nerves/Fit/Array/Galaxy mains only (drop
    PyAutoLens); ruff check + format, gallery_build.py --check, pytest scripts/misc/test,
    lychee, gallery_run.sh --all.
  • Render locally once (gallery_run.sh --all), commit the PNGs, GALLERY.md and
    gallery/viz_manifest.yaml; gallery_build.py --check must pass on the committed tree.

Initial push: one stub commit on main (LICENSE + README, mirroring lens c1e075d), then
everything above on feature/eyes-galaxy-instance as PR #1.

B. PyAutoEyes (organs/PyAutoEyes)

  • registry.yaml: append the galaxy row (one key: value per line — stdlib parser):
    name: galaxy, repo: autogalaxy_visualization, path: galaxy/autogalaxy_visualization,
    github: PyAutoLabs/autogalaxy_visualization, library: PyAutoGalaxy,
    import_name: autogalaxy, manifest: gallery/viz_manifest.yaml,
    images_base_url: https://raw.githubusercontent.com/PyAutoLabs/autogalaxy_visualization/main/,
    gallery: GALLERY.md, dispatch_event: pyautogalaxy-release.
  • tests/test_registry.py: add galaxy-row asserts beside the lens ones;
    tests/test_cli.py:83 rename the "unknown instance" fixture name away from galaxy.
  • bin/pyauto-eyes board → regenerate dashboard.md/dashboard.html; pyauto-eyes check
    (needs the galaxy PNGs on the galaxy main → Eyes PR is merged last).
  • README/REFERENCE prose: "autolens_visualization first" → two instances.

C. PyAutoMind (organs/PyAutoMind)

  • repos.yaml: new autogalaxy_visualization row directly after autolens_visualization
    (~line 324), category: project, path galaxy/autogalaxy_visualization, galaxy role
    text; widen the PyAutoEyes role (line 136) from "(autolens_visualization first)".
  • ROUTING.md:49: add autogalaxy_visualization to the target list.
  • python3 scripts/repos_sync.py --write then --check. Trap (memory --writeSpill):
    run it from the task worktree; it writes map blocks through symlinks into canonical
    sibling organs (Nerves, Gut, Scientist, Cortex, Hands, Heart, root AGENTS.md). Snapshot
    git status per canonical repo before, keep the diffs only in the claimed worktrees
    (Mind, Brain, Heart, Eyes), git diff > patch then revert the canonical spills; the
    saved patches become the sibling map-block PRs at ship (as 1a: Nerves/Gut/Scientist/
    Cortex). Root AGENTS.md is unversioned: keep its regenerated table (it is the
    workspace's live instruction file).
  • New draft draft/feature/pyautohands/release_fires_visualization_dispatch.md for the
    dispatch sender (see Context §1); mention it in the epic notes.

D. PyAutoHeart (organs/PyAutoHeart)

  • config/repos.yaml:193 excluded: — add
    - autogalaxy_visualization # galaxy figure gallery project (PNGs + manifest tracked; re-rendered on release).
  • Map block via repos_sync.

E. PyAutoBrain (organs/PyAutoBrain)

  • No conductor code change (agents/conductors/eyes/_eyes.py is repo-name-free).
  • Prose: agents/conductors/eyes/AGENTS.md:27-32, skills/eyes/eyes.md:7-21 (two
    instances, --instance galaxy), docs/organs/eyes.md:32, bin/clean_slate.sh:72-84
    prose ("the galaxy one sits under galaxy/"), AGENTS.md:23; map block via repos_sync.
  • If config/policy.yaml witness/tenant rows key on repo names, add the galaxy repo
    beside autolens_visualization (check grep -n autolens_visualization config/).

F. Human-only steps (surface at ship)

  • Grant PAT_PYAUTOLABS to autogalaxy_visualization (memory PAT403: every newborn repo
    must be added or the eyes-refresh dispatch 403s/skips).
  • Create the eyes-critique label on the new repo (agent will try gh label create;
    if the classifier denies it as a public surface, the human runs it).
  • .github profile README patch from repos_sync stays human-only, as in 1a.

Verification (the prompt's Witness, plus)

  1. In the galaxy repo: ruff check . && ruff format --check .;
    gallery/gallery_run.sh --all renders every domain; python gallery/gallery_build.py --check green on the committed tree; pytest scripts/misc/test green.
  2. pyauto-brain eyes survey galaxy/autogalaxy_visualization → no gaps, no orphans;
    pyauto-brain eyes survey --instance galaxy resolves via the registry.
  3. organs/PyAutoEyes: pytest tests/ green; bin/pyauto-eyes board then
    bin/pyauto-eyes check green with the galaxy row (post galaxy-main merge); dashboard
    shows a galaxy section.
  4. organs/PyAutoMind: python3 scripts/repos_sync.py --check clean; lifecycle.py check.
  5. organs/PyAutoHeart / organs/PyAutoBrain: their own test suites for the touched
    files (tests/test_board_theme.py, policy/registry tests).
  6. Post-merge: workflow_dispatch the galaxy render.yml once → it commits nothing new
    (already rendered) and fires eyes-refresh; PyAutoEyes dashboard_refresh.yml run
    green; Pages shows both instances.

Ship order

/start_library → implement (Opus subagents, progress file + Monitor) → /ship_library
per repo in the order Brain → autogalaxy_visualization → Mind → Heart → Eyes, with the
sibling map-block PRs (Nerves/Gut/Scientist/Cortex) opened from the saved patches; merge
stays human; Heart YELLOW acknowledged at ship.

Key Files

  • lens/autolens_visualization/ @ 078c1e2 — template tree
  • galaxy/autogalaxy_workspace_test/scripts/{imaging,interferometer,ellipse}/visualization/ — producers to port
  • galaxy/PyAutoGalaxy/autogalaxy/config/visualize/plots.yaml — source of the all-true config
  • organs/PyAutoEyes/registry.yaml, tests/test_registry.py, tests/test_cli.py
  • organs/PyAutoMind/repos.yaml, ROUTING.md, scripts/repos_sync.py
  • organs/PyAutoHeart/config/repos.yaml
  • organs/PyAutoBrain/agents/conductors/eyes/AGENTS.md, skills/eyes/eyes.md, docs/organs/eyes.md, bin/clean_slate.sh

Original Prompt

Click to expand starting prompt

PyAutoEyes phase 3 — birth autogalaxy_visualization (PyAutoGalaxy figures)

Type: feature
Target: autogalaxy_visualization
Repos:

  • autogalaxy_visualization
  • PyAutoEyes
  • PyAutoMind
  • PyAutoBrain
  • PyAutoHeart
    Themes:
  • visualization
  • infrastructure
    Difficulty: large
    Autonomy: supervised
    Priority: normal
    Lane: local-dev
    Status: draft
    Consequence: judge
    Witness: pyauto-brain eyes survey galaxy/autogalaxy_visualization reports no gaps/orphans; its gallery/gallery_build.py --check green and tracked gallery/viz_manifest.yaml committed; pyauto-eyes check green with the galaxy registry row; the PyAutoEyes dashboard shows a galaxy section; repos_sync.py --check clean
    Review-minutes: 15
    Epic: pyautoeyes-birth
    Phase: 3
    Filed: 2026-09-25

Blocked on: human repo creation (gh repo create PyAutoLabs/autogalaxy_visualization --public); phase 2 shipped 2026-09-28 (complete/2026/09/eyes-board-conductor-registry.md).

Task

Human first: gh repo create PyAutoLabs/autogalaxy_visualization --public.
Agent, local checkout at galaxy/autogalaxy_visualization, mirroring the
autolens_visualization project-repo layout from phase 1a:

  • Port autogalaxy_workspace_test/scripts/{imaging,interferometer,ellipse}/visualization/
    to flat producers scripts/<domain>/visualization.py (HST-scale imaging +
    SMA interferometer presets copied from autolens_visualization/instruments),
    all-true config/visualize/plots.yaml, datasets simulated into dataset/
    with simulators under scripts/misc/simulators/.
  • Render harness (gallery/gallery_build.py + gallery_run.sh), tracked PNGs,
    GALLERY.md, tracked gallery/viz_manifest.yaml; lint.yml + render.yml
    on the pyautogalaxy-release dispatch, which also fires eyes-refresh at
    PyAutoEyes.
  • Registration, as phase 1a: Mind repos.yaml project row + repos_sync --write, ROUTING.md target, Brain clean_slate.sh exclusion, Heart drift
    exclusion.
  • PyAutoEyes registry.yaml galaxy row; PyAutoGalaxy's release workflow fires
    the pyautogalaxy-release dispatch (as PyAutoLens does for lens).

Session: Claude Code CLI (Fable 5.1 architect, Opus execution), 2026-09-29; session ID unavailable.

Activity

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