From 6fc1a36a87606423ad40c41049955f11d337104c Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 24 Aug 2026 01:43:31 +0000 Subject: [PATCH] =?UTF-8?q?prompt:=20ship=20smoke-runner-delegation=20(#26?= =?UTF-8?q?0)=20=E2=86=92=20complete?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All ten vendored .github/scripts/run_smoke.py copies are now thin delegators over the PyAutoHands runners. 2085 lines -> 1127, and most of what remains is the docstring explaining why each file delegates. Merged, each verified from the CI log rather than the green tick: PyAutoHands#261 --list opt-in lists + the notebook leg PyAutoHands#262 allowlist authoritative (the 13-script finding) PyAutoHands#263 regenerate_notebook resolves by relative path autolens_workspace_test#273, autogalaxy_workspace_test#111, autofit_workspace_test#90, autocti_workspace_test#16 (198 -> 77) autofit_workspace#147, autogalaxy_workspace#226, autolens_workspace#500 (356 -> 119) The record keeps the two findings that mattered most: the no_run-wins rule shipped in #261 would have silently dropped 13 scripts from smoke coverage with CI still green, and regenerate_notebook's bare-filename lookup made the stale-notebook recovery dead for every real (nested) notebook. Both were caught by measuring the real repos before writing a delegator, and both are now pinned by tests that were negative-tested against the old behaviour. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01UpSFum81Jeq9KZ9wdKtaeZ --- active.md | 49 -------- .../2026/08/smoke-runner-delegation.md | 115 ++++++++++++++++++ complete/index.md | 3 +- dashboard.html | 17 ++- dashboard.md | 20 +-- 5 files changed, 131 insertions(+), 73 deletions(-) rename active/run_smoke_copy_drift.md => complete/2026/08/smoke-runner-delegation.md (60%) diff --git a/active.md b/active.md index fccf3fc3..fb25a165 100644 --- a/active.md +++ b/active.md @@ -13,52 +13,3 @@ - registered: 2026-08-19 by the wake_up session — the issuing session (claude/autofit-priors-messages-audit-ylvenv) filed the prompt + issue but not this entry, tripping Lifecycle Drift on main. - repos-none-claimed: this entry claims NO repos — one line deliberately, not 2-space bullets. - -## smoke-runner-delegation -- issue: https://github.com/PyAutoLabs/PyAutoHands/issues/260 (issued 2026-08-24) -- issued: 2026-08-24 -- prompt: active/run_smoke_copy_drift.md -- status: library-dev -- worktree: ~/Code/PyAutoLabs-wt/smoke-runner-delegation -- decision: the prompt's blocking question is ANSWERED before any repo is touched — - the timeout/kill behaviour was PROMOTED to everyone (PyAutoHands#226/#227 → 52408a84; - all 10 copies import timeout_for + kill_group). Shape chosen: full delegation to a - PyAutoHands-owned runner, staged. Phase 1 = --list allowlist mode + the 4 *_workspace_test - copies; phase 2 = notebook leg + the 3 workspace copies; phase 3 = HowTo, no work. -- measured: 2026-08-24, from every repo's main — 10 copies, 3 variants, ZERO functional - drift inside any variant (workspace 356L byte-identical; workspace_test 198L comment-only; - HowTo 75L differ by PROJECT alone). Prompt steps 1 and 4 verified already done. -- registered: 2026-08-24 by the start_dev session (claude/smoke-copy-drift-ci-docs-ozntvv); - worktree_check_conflict clean (exit 0) for all 8 repos. -- status-detail: HANDS LEGS MERGED, workspace collapses not started. The task stays - active deliberately — issue #260 scopes seven workspace PRs that have zero commits, - so this is not complete and must not be recorded as such. -- library-pr: https://github.com/PyAutoLabs/PyAutoHands/pull/261 MERGED 2026-08-24 → c0e2e53 - (both Hands legs: phase 1 `--list` opt-in script lists on run_python.py; phase 2 - the matching notebook leg on run.py — `--list`, `--no-write-back`, `--retry-from`). - 16 new tests; suite 388 passed / 5 skipped / 0 failed; CI green on all three - matrix legs (3.12/3.13/3.14) plus the tenant-firewall step in each. -- mind-pr: https://github.com/PyAutoLabs/PyAutoMind/pull/280 MERGED 2026-08-24 → 0cd8544a -- phase-2 findings (these changed the plan, recorded so the workspace PRs inherit them): - - run_notebook.py writes executed outputs back IN PLACE. Correct for generation - (the outputs are the product), wrong for a PR gate, which must not dirty the - tree it tests. Hence `--no-write-back`; it supersedes the workspace copy's - staged-copy-at-root trick rather than porting it, since the kernel cwd is - already pinned to the repo root. - - JUPYTER_MISSING_RC did NOT need promoting. It exists because the workspace copy - shelled out to a bare `jupyter`; execute_notebook invokes - `sys.executable run_notebook.py`, so the abort-with-no-summary failure mode is - structurally absent. One promotion item dissolved on inspection. -- remaining: the 7 workspace collapses (4 *_workspace_test 198L → ~75L, then 3 workspace - 356L → ~75L), each a one-file PR modelled on HowToLens's delegator. UNBLOCKED as of - 2026-08-24 — the library-first gate cleared when PyAutoHands#261 merged. Phase 3 - (HowTo ×3) needs no work; it is already the end state. - The delegator invocations these PRs should use: - *_workspace_test: run_python.py scripts --list smoke_tests.txt - --report-dir test-results - workspace: the above, plus run.py notebooks - --list smoke_notebooks.txt --no-write-back --retry-from scripts - `--report-dir` is load-bearing: without it run_python.py never propagates failure - and the gate is vacuously green. -- repos: - - PyAutoHands (branch claude/smoke-copy-drift-ci-docs-ozntvv) diff --git a/active/run_smoke_copy_drift.md b/complete/2026/08/smoke-runner-delegation.md similarity index 60% rename from active/run_smoke_copy_drift.md rename to complete/2026/08/smoke-runner-delegation.md index 9d77d38b..9b3e42f7 100644 --- a/active/run_smoke_copy_drift.md +++ b/complete/2026/08/smoke-runner-delegation.md @@ -1,3 +1,118 @@ +Ten repos each carried their own `.github/scripts/run_smoke.py` — the file +PyAutoHeart's reusable `smoke-tests.yml` invokes from inside each workspace, so +one must exist per repo. What was duplicated was not the file's existence but +its **driver loop**: read the allowlist, resolve per-entry env, spawn a +subprocess under the timeout cap, classify PASS/FAIL/TIMEOUT, accumulate, print +the summary, exit non-zero. Seven repos held that loop; the three HowTo repos +were already thin shims. + +All ten are now shims. 2085 lines became 1127, and 1127 is mostly prose: of +`autolens_workspace_test`'s 77 lines, 32 are the docstring explaining why it +delegates. + +## The argument, which was not "they have drifted" + +The prompt was filed on a drift finding. Re-measured 2026-08-24 from every +repo's `main`, there was **zero functional drift inside any variant** — the +three workspace copies byte-identical, the four `_test` copies differing in two +docstring lines, the three HowTo copies in `PROJECT` alone. + +That is not evidence the design was safe. It is the receipt for three manual +N-repo sweeps that had been paid to restore it: the env-resolver fork (#185), +the per-script timeout and process-group kill (#226/#227), and the jupyter +guard. The HowTo tier needed **none** of the three, precisely because it holds +no logic. The case for collapsing is maintenance cost, not drift. + +The prompt's blocking question — "does autolens_workspace_test's timeout/kill +get promoted, or keep a documented divergence?" — was already answered by +promotion in #226/#227. All ten copies imported `timeout_for` and `kill_group` +before this task started; `_kill_group` existed in zero. + +## The real obstacle was discovery model, not behaviour + +The shared runners were opt-out (recursive discovery minus `no_run.yaml`); the +seven logic-bearing copies are opt-in allowlists (`smoke_tests.txt`, +`smoke_notebooks.txt`). That mismatch is why they could not delegate. So each +phase was a PyAutoHands feature first and per-repo edits second. + +## Two bugs found by measuring before writing + +**1. The `no_run`-wins rule would have deleted 13 scripts from smoke coverage +(#262).** #261 shipped "an explicit exclusion is the more specific intent, so +`no_run` wins over the allowlist". Measured against the real repos, that rule +would have silently skipped 9 scripts in autogalaxy_workspace_test, 2 in +autolens_workspace_test, 1 in autofit_workspace and 1 in autolens_workspace — +every one of which runs in smoke today, since the vendored runners never opened +`no_run.yaml` at all. + +The rule was wrong because it conflated two policies for two different runs: +`no_run.yaml` governs the release mega-run and notebook generation, the +allowlist governs the PR gate, and a script legitimately appears in both. The +failure mode is the dangerous kind — **CI would have stayed green**, because a +skipped script is not a failure. Corrected to allowlist-authoritative before any +workspace was touched, and confirmed in production afterwards: autogalaxy's nine +all ran and passed, as did autolens's two and autofit's `searches/mcmc` in both +its script and notebook forms. + +Same PR fixed a second blocker: `autocti_workspace_test` is the only workspace +with no `config/build/no_run.yaml`, and the autohands-level fallback path does +not exist either, so both runners crashed with `FileNotFoundError` before +running anything. + +**2. `regenerate_notebook` resolved the source by bare filename (#263).** It +looked up `scripts_dir / nb_path.name`, dropping the subdirectory, so +`notebooks/imaging/model_fit.ipynb` searched for `scripts/model_fit.py`. Every +workspace notebook is in a subdirectory, so the stale-notebook recovery was dead +on arrival — and a bare filename can find the *wrong* source when two topics +share a name. The existing tests missed it because their fixture was **flat**, +which is the one layout where the bug is invisible. The replacement tests use a +nested notebook plus a decoy script at the scripts root, and were negative-tested +against the old resolution. + +## What was proven rather than assumed + +- **Env resolution is identical.** The old runners passed a *relative* script + path to `build_env_for_script`; the shared runners pass an *absolute* one. All + 128 listed scripts across all seven repos were resolved both ways and diffed: + 0 differences, in env and in args. Pattern matching is substring/stem based so + path form is irrelevant, and no profile pattern collides with the absolute + prefix. +- No profile sets per-script `args`, so the shared runners' extra-args support + changes nothing. +- Every allowlist entry resolves to a real file, and every listed notebook's + source script exists for the retry path. +- The two-leg exit code is the worst of both, verified in all three + pass/fail combinations — a failing notebook cannot be masked by passing + scripts. +- **Every merge was verified from the CI log, not the green tick**, because a + coverage regression here is indistinguishable from a pass. Each repo's + "Running N listed scripts/notebooks" was checked against its allowlist: + 11/11, 22/22, 35/35, 3/3, 8/8+2/2, 14/14+2/2, 35/35+2/2. + +## Traps for anyone touching this again + +- `--report-dir` is load-bearing. `run_python.py` only propagates failure when a + report was built; without it the gate runs to completion and always exits 0. +- `run_notebook.py` writes executed outputs back **in place**. Correct for + generation, where the outputs are the product; wrong for a PR gate, which must + not dirty the tree it tests. Hence `--no-write-back`. +- `JUPYTER_MISSING_RC` did **not** need promoting. It existed because the + workspace copies shelled out to a bare `jupyter`; the shared runner invokes + `sys.executable run_notebook.py`, so the abort-with-no-summary mode is + structurally absent. One planned promotion item dissolved on inspection. +- A bare `off`/`on`/`yes` entry in `no_run.yaml` parses as a YAML **boolean** and + crashes `should_skip` with `TypeError: argument of type 'bool' is not + iterable`. Hit while building a fixture; not fixed, no repo currently has such + a script name. + +## Still open + +The merged `claude/smoke-copy-drift-ci-docs-ozntvv` branches across nine repos +were not deleted — this session's git proxy refuses delete refspecs +(`send-pack: unexpected disconnect`). They are all proven merged into `main`. + +## Original prompt + # run_smoke.py: three runner variants across 10 repos, no sync mechanism Type: maintenance diff --git a/complete/index.md b/complete/index.md index 16f90c79..d07e2c98 100644 --- a/complete/index.md +++ b/complete/index.md @@ -6,7 +6,7 @@ Token-light navigation over the finished-work records (schema: only then grep a dated bucket. Curators: edit the band between the CURATED markers; everything below GENERATED is rebuilt. -1093 records across 7 buckets. +1094 records across 7 buckets. ## Highlights @@ -194,6 +194,7 @@ _(curate hard-won records here — survives regeneration.)_ - [small-datasets-loader-pixel-scales](2026/08/small-datasets-loader-pixel-scales.md) - [small-datasets-regime-stamp](2026/08/small-datasets-regime-stamp.md) - [small-datasets-rmtree-committed-data](2026/08/small-datasets-rmtree-committed-data.md) +- [smoke-runner-delegation](2026/08/smoke-runner-delegation.md) - [smoke-runner-jupyter-guard](2026/08/smoke-runner-jupyter-guard.md) - [spawn-autonomy-log-generated](2026/08/spawn-autonomy-log-generated.md) - [spawn-drift-self-heal](2026/08/spawn-drift-self-heal.md) diff --git a/dashboard.html b/dashboard.html index 069bf8dc..1bf29b17 100644 --- a/dashboard.html +++ b/dashboard.html @@ -123,7 +123,7 @@
📋

PyAutoMindDashboard

Intent. Priority. Flow.

Every task the Mind is holding. Tap a task's 📋 and its /start_dev command is on your clipboard — paste it into a Claude Code chat to route Claude straight to that task. Recent is the same work by date — what has been happening rather than what to do next.

-
  • 2In flight
  • 3Parked
  • 6Planned
  • 155Backlog
+
  • 1In flight
  • 3Parked
  • 6Planned
  • 155Backlog

markdown version

Start here

Highest priority (filed as high) — showing 12 of 17

@@ -145,7 +145,6 @@

Quick wins (small enough, and safe enough to run unatte

In flight markdown version

Issued — each has an open GitHub issue and usually a branch.

@PyAutoFit TransformedMessage.factor_gradient crashes on first callissue #1501 — issued 2026-08-19HOLD — do not start dev. Fix-or-delete hangs off the PyAutoFit#1498 logpdf-contract

-

Parked markdown version

3 task(s) @@ -326,12 +325,6 @@

Backlog The 50 newest things to happen to the work in hand, newest first — issued, parked, filed. Every other section on this page is laid out by state, which is exactly why none of them can answer “what has been happening?”. Shipped work is not here: it is read from complete/index.md, and a thousand records deep it would crowd out everything anyone can still act on. Showing the newest 10; … opens the next 10.

- - - - - - @@ -385,7 +378,7 @@

Backlog Remove pynufft + legacy TransformerNUFFTPyNUFFT

- + @@ -625,6 +618,12 @@

Backlog autolens_workspace_developer: broad stale-API rot (56 symbols, no CI)

+ + + + + +
2026-08-24issuedrun_smoke.py: three runner variants across 10 repos, no sync mechanism
2026-08-23 filed pynufft removal: unswept downstream residue (1 hard break + stale…
2026-08-22 filed Point-source JSON datasets record no resolution regime

Epics markdown version

diff --git a/dashboard.md b/dashboard.md index 96b36a41..26e04989 100644 --- a/dashboard.md +++ b/dashboard.md @@ -8,7 +8,7 @@ Every task the Mind is holding, on one page: what is in flight, what is parked, | Where | Count | |-------|------:| -| [In flight](#in-flight) (`active/`) | 2 | +| [In flight](#in-flight) (`active/`) | 1 | | [Parked](#parked) (`parked.md`) | 3 | | [Planned](#planned) (`planned.md`) | 6 | | [Backlog](#backlog) (`draft/`) | 155 | @@ -143,14 +143,6 @@ Issued — each has an open GitHub issue and usually a branch. The full record f
-
📋 run_smoke.py: three runner variants across 10 repos, no sync mechanismissue #260 — issued 2026-08-24 — library-dev - -``` -/start_dev active/run_smoke_copy_drift.md -``` - -
- ## Parked Started or scoped, not currently in flight — resume by moving the row back to `active.md`. Full detail in [`parked.md`](parked.md). @@ -1336,7 +1328,6 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | Date | Event | Task | |------|-------|------| -| 2026-08-24 | issued | run_smoke.py: three runner variants across 10 repos, no sync mechanism | | 2026-08-23 | filed | pynufft removal: unswept downstream residue (1 hard break + stale… | | 2026-08-23 | filed | Properly time and profile the smoke/release script surface | | 2026-08-23 | filed | Phase 3: stop installing pynufft in Hands/Heart CI and PyAutoCTI… | @@ -1346,12 +1337,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-22 | filed | Untrack the generated FITS test artifacts in autoarray | | 2026-08-22 | filed | The reconstruction noise map describes a different estimator than the… | | 2026-08-22 | filed | Remove pynufft + legacy TransformerNUFFTPyNUFFT | +| 2026-08-22 | filed | Point-source JSON datasets record no resolution regime |
… 10 more (40 left) | Date | Event | Task | |------|-------|------| -| 2026-08-22 | filed | Point-source JSON datasets record no resolution regime | | 2026-08-22 | filed | Is Intel macOS a supported platform, and what is the numpy-only… | | 2026-08-22 | filed | Defer the eager scipy.sparse import in derivative_util (~0.10 s of… | | 2026-08-22 | filed | Bug: fix the tracer.fits existence guard in autolens_workspace… | @@ -1361,12 +1352,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-20 | filed | Numba CPU likelihood phase 1: batched MGE convolution +… | | 2026-08-19 | filed | status.sh --repos sources a file that no longer exists | | 2026-08-19 | filed | jax 0.11 breaks beta/gamma message log_partition under jit… | +| 2026-08-19 | filed | autolens_workspace_test jax_likelihood pins: 4 scripts fail smoke on… |
… 10 more (30 left) | Date | Event | Task | |------|-------|------| -| 2026-08-19 | filed | autolens_workspace_test jax_likelihood pins: 4 scripts fail smoke on… | | 2026-08-19 | filed | autofit_profiling: bootstrap the repo + general PyAutoFit profiling… | | 2026-08-19 | filed | autoreduce 0.9 on PyPI never got the Python 3.12 floor | | 2026-08-19 | issued | @PyAutoFit TransformedMessage.factor_gradient crashes on first… | @@ -1376,12 +1367,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-19 | filed | PyAutoConf rename leftovers in Brain functional surfaces | | 2026-08-19 | filed | Explore: dashboardify the Brain's operational surfaces with pasteable… | | 2026-08-19 | filed | Deduplicate repos_sync.py's check/write pairs | +| 2026-08-19 | filed | Bug in autocti_workspace: the dataset_1d results/database example… |
… 10 more (20 left) | Date | Event | Task | |------|-------|------| -| 2026-08-19 | filed | Bug in autocti_workspace: the dataset_1d results/database example… | | 2026-08-18 | parked | single-source-density-design | | 2026-08-18 | parked | prior-message-collapse-design | | 2026-08-18 | filed | @PyAutoFit TransformedMessage.logpdf/pdf omit the transform… | @@ -1391,12 +1382,12 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-14 | filed | Three jax_likelihood pins are stale by ~1.24e-4 and fail the smoke… | | 2026-08-09 | found | isothermal-ell-sph-oversampling-at-the-cusp | | 2026-08-08 | parked | pyautoreduce-slacs1430-acs-comparison | +| 2026-08-08 | filed | Regenerate autolens_workspace markdown/ so the MGE pages show… |
… 10 more (10 left) | Date | Event | Task | |------|-------|------| -| 2026-08-08 | filed | Regenerate autolens_workspace markdown/ so the MGE pages show… | | 2026-08-07 | filed | autofit.plot functions accept **kwargs and silently discard them | | 2026-08-07 | filed | Regenerate setup_notebook-drifted notebooks in… | | 2026-08-06 | filed | Triage: Convolver "No blurring_image provided" warning in canonical… | @@ -1406,6 +1397,7 @@ The 50 newest things to happen to the work in hand, newest first — issued, par | 2026-08-04 | filed | dataset/imaging/jwst_lw is untracked because the gitignore was never… | | 2026-08-04 | filed | cosmos_web_ring stores boolean masks as float64, wasting ~3.4 MB of… | | 2026-08-04 | filed | autolens_workspace_developer: broad stale-API rot (56 symbols, no CI) | +| 2026-08-04 | filed | aplt.Output stale-API drift in the remaining workspace repos |