You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The per-PR smoke gate's py3.12 leg spends 553.0s executing scripts, and three
entries — imaging/subhalo_recovery.py (120.7s), misc/database/scrape/general.py
(63.4s) and point_source/jax_likelihood/point.py (47.7s) — are 42% of that.
This task makes each one materially faster or demotes it to the weekly/release
channels, per script, without weakening what the gate discriminates. Cost
attribution below was measured in a CI-equivalent environment (py3.12, source
chain install, smoke-profile env); the sibling prompt for running the gate less
often is out of scope here.
Plan
imaging/subhalo_recovery.py: split the script — keep the one-shot engine as
the PR-gate entry, move the warm-started iterative-LM confirmation leg to a
new script covered by the weekly/release channels (measured: the iterative leg
is ~80% of runtime and reproduces the one-shot metrics to 3 decimal places;
the iterative engine class stays PR-gated via the interferometer sibling).
misc/database/scrape/general.py: demote to the weekly/release channels with
the required smoke_tests.txt comment (its unique coverage — scraping a real
Nautilus run's outputs — is release-level, and the aggregator trio keeps the
scrape API covered on the gate); fallback if demotion is declined: shrink the
real search.
point_source/jax_likelihood/point.py: measured compile-dominated (~44s of
55s local is two JAX JIT compiles; likelihood evals are 0.03s), and problem
size is a weak lever (10x looser solver precision saves only ~15%) — instead
drop the FitPositionsImagePairAllSolved block, whose coverage the weekly
channel already runs verbatim in image_plane.py; or demote the whole
script if the ~6:00 acceptance is strict (see arithmetic below).
Re-measure the gate on the PR and record per-entry timings; verify 23/23 pass
and the py3.12 leg lands under ~6 minutes.
CI-equivalent environment: py3.12 venv, chain installed from source checkouts
per .github/scripts/smoke_install.sh, smoke-profile env per config/build/profile_smoke.yaml + each script's ENV: declaration. Local
total for subhalo_recovery.py cold-cache is 148.0s vs 120.7s CI (factor
~0.82); warm-cache local is 134.7s (the ~13s delta is numba compile, which CI
always pays — fresh runners).
iterative log_evidence() (Laplace) — printed, never asserted
17.6s
18.2s
metrics + gauge asserts
0.0s
0.0s
Both engines recover essentially identical metrics: one-shot corr 0.8228 /
peak dist 0.06", iterative corr 0.8233 / 0.06". The warm-started iterative leg
is a stationarity confirmation of the one-shot optimum, not independent
discrimination.
Levers measured (all still assertion-green variants):
variant
effect
verdict
grid 120→100
mask 5858→5870 px (S/N-driven), no time change
dead end
dpsi mesh factor 2→3
no time change (cost is data x source dense algebra)
point_source/jax_likelihood/point.py phase split (local, 55.4s total vs 47.7s CI):
phase
time
imports
1.8s
dataset + PointSolver.for_grid construction
0.5s
first _vmap — FitPositionsImagePairAll JIT compile
11.3s
cached _vmap + NumPy fit + jit(fit_from) round-trip
0.5s
first _vmap — FitPositionsImagePairAllSolved JIT compile
33.0s
remainder (NumPy solved cross-check)
8.2s
Compile-dominated: ~44s of 55s is XLA compilation of the two pinned code
paths; each actual likelihood evaluation is 0.03s. Problem size was measured
as a WEAK lever: loosening pixel_scale_precision 0.001→0.01 (10x, ≈3 fewer
traced refinement levels) only cuts the compiles to 8.9s + 28.4s (total
55.4→47.3s, −15%) — the XLA cost is mostly a per-program floor, not
refinement depth. The strong lever is that the 33s Solved-block compile
duplicates coverage image_plane.py already provides on the weekly channel.
misc/database/scrape/general.py phase split (local, ~78s total vs 63.4s CI,
from run log timestamps):
phase
time
import + dataset bootstrap/load + mask (2828 px)
~6s
real Nautilus search (n_like_max=300, JAX): sampling
~54s
— of which JAX compiles (vmap 3.3s + per-sample latent 14.3s)
~18s in the above
database scrape + ALL aggregator assertions
~3s
The search is ~72s of ~78s; the scrape + assertions the script uniquely
gate-tests are ~3s. The misc/aggregator/ trio on the gate covers the same
scrape/aggregator API under PYAUTO_TEST_MODE=1 fixtures; general.py's unique
coverage is scraping a REAL search's output directory.
Trim imaging/subhalo_recovery.py to simulate + arc mask + one-shot FitDpsiSrcImaging + dkappa corr/dist assertions (thresholds unchanged:
corr > 0.5, dist < 0.5"). Keep the ENV: full_datasets declaration and the
docstring's parity-anchor framing; note in the docstring where the
iterative leg went.
Create imaging/subhalo_recovery_iterative.py carrying the iterative-LM
leg verbatim (warm start recomputed from a fresh one-shot fit, or
restructured to re-derive x0 locally), with its existing corr/dist/gauge
assertions. Do NOT add it to smoke_tests.txt; the weekly workspace-smoke.yml and release-integrate run every script, so it is
covered there automatically — but note it in smoke_tests.txt's comment
for the record.
Either way, delete the unasserted iter_fit.log_evidence() print from
whichever script keeps the iterative leg (−15s+; nothing discriminates on it).
Discrimination demonstration (constraint 1): break the guarded thing —
e.g. zero the recovered dkappa or simulate without the subhalo — and show
the one-shot corr assertion fail; record the demonstration in the PR.
Engine-class coverage note for the PR: the PR gate still runs BOTH pc
engines via interferometer/subhalo_recovery_interferometer.py (one-shot
sparse+dense parity + IterFitDpsiSrcInterferometer n_iter=5 cold start,
~28s); imaging's iterative leg additionally runs weekly + at release.
Fallback if the human wants both engines on the PR gate: keep one script,
drop the Laplace print and set n_iter=2 (measured corr 0.8231 vs 0.8233,
gauge asserts unchanged) → est. ~85s CI. State which option was chosen.
Remove from smoke_tests.txt with the required comment naming the
channels that still run it: Heart's weekly workspace-smoke.yml (Mondays
03:00 UTC, library main, same profile) and release-integrate
(PYAUTO_TEST_MODE=0, full resolution).
Rationale to record: its unique gate coverage is scraping a REAL Nautilus
run's output directory into the SQLite database (the misc/aggregator/
trio on the gate covers the same scrape/aggregator API under PYAUTO_TEST_MODE=1 fixtures); a lens-modelling PR that breaks real-run
database serialization without tripping the aggregator trio, the JAX
likelihood pins, or the library unit tests is the least likely regression
of the three, and it remains covered twice weekly.
Fallback if demotion is declined: keep it but shrink the real search
(n_like_max 300→100 and/or a smaller in-script circular mask) — its
assertions are relational (> 0, name/info checks), not pinned literals,
so a smaller fit preserves them; verify the scrape still ingests > 0
samples and every agg.values(...) generator still yields.
point_source/jax_likelihood/point.py → drop the gate-redundant Solved
block (or demote the script).
Primary: remove the __Model: Solved Source (Parameter-Free)__ block
(the second _vmap compile, 33s measured, plus its ~8s NumPy
cross-check) from point.py. Its coverage — FitPositionsImagePairAllSolved
with a pinned literal — already exists in image_plane.py, which the
weekly workspace-smoke.yml and release-integrate run; update
point.py's docstring (it currently says the solved variant is here
BECAUSE this script is the gate entry — record the demotion decision and
name the covering channel). The base FitPositionsImagePairAll pin
(-83.38049778), the NumPy cross-check and the jit(fit_from) round-trip
stay on the gate untouched — no literal re-pins needed.
Est. 47.7 → ~18s CI.
Alternative if the ~6:00 acceptance is read strictly: demote the whole
script to the weekly channel (comment in smoke_tests.txt naming
image_plane.py + weekly/release as the covering surface) — but this
removes the last point-source entry from the PR gate; flag that trade
explicitly to the human.
Re-measure + close out.
Run the full smoke gate locally (python .github/scripts/run_smoke.py)
and on the PR; grep the [PASS] <name> — <n>s lines; confirm 23/23 (or
22/23+new script count if split) and py3.12 script time < ~360s.
Projected arithmetic from measurements (CI seconds): 553.0 − 84
(subhalo split, 120.7→37) − 63.4 (general demote) − 30 (point Solved
block, 47.7→18) ≈ 376s ≈ 6m16s; with point.py demoted entirely
instead: ≈ 358s ≈ 5m58s. The recommended set lands ~16s above a
strict 360s; whether "~6 minutes" tolerates that, or point.py should be
fully demoted, is the one open acceptance call — flag it on the PR.
Key Files
scripts/imaging/subhalo_recovery.py — split: one-shot stays; iterative leg
moves to scripts/imaging/subhalo_recovery_iterative.py (new)
smoke_tests.txt — general.py demotion comment; no new-script addition
scripts/misc/database/scrape/general.py — only if fallback-shrink chosen
scripts/point_source/jax_likelihood/point.py — remove the Solved block
(coverage stays in image_plane.py on the weekly channel); no re-pins
config/build/profile_smoke.yaml — unchanged (no cap changes; constraint 3)
Work Classification
Workspace
Worktree root
~/Code/PyAutoLabs-wt/smoke-gate-slowest-scripts/ (created later by /start_workspace)
Original Prompt
Click to expand starting prompt
Speed up the three slowest autolens_workspace_test smoke-gate scripts
Type: test
Target: workspaces
Repos:
autolens_workspace_test
Difficulty: medium
Autonomy: supervised
Priority: normal
Status: formalised
The per-PR smoke gate in autolens_workspace_test costs ~11m20s wall-clock, of
which ~9m13s is script execution. Three entries are 42% of that. This prompt is
the make them cheaper half; cutting how often the gate runs at all is the
sibling prompt draft/test/pyautoheart/smoke_relevance_gate.md. Do not merge
the two — one edits scripts, the other edits a workflow, and they land in
different repos.
Measured
CI run 32605025472 (2026-08-22, main), py3.12 leg (the critical path; py3.13
is ~6% faster). 23 entries, 23/23 pass, 553.0s total — which reconciles to
the step wall-clock exactly, so the runner adds no measurable overhead and the
scripts are the cost.
py3.12
share
script
120.7s
21.8%
imaging/subhalo_recovery.py
63.4s
11.5%
misc/database/scrape/general.py
47.7s
8.6%
point_source/jax_likelihood/point.py
33.9s
6.1%
imaging/jax_likelihood/rectangular.py
31.5s
5.7%
misc/jax_assertions/delaunay_nn.py
30.2s
5.5%
imaging/jax_likelihood/mge.py
The remaining 17 entries are 4.5–29.2s each and are not in scope. Reproduce
with gh api on the job log and grep the runner's [PASS] <name> — <n>s
lines; the runner prints one per entry.
Note the tail is short: after these three the curve flattens, so this prompt
can win ~4 minutes and no more. Do not chase entries below ~30s.
Task
Per script, either make it materially faster or demote it — both are
acceptable outcomes, and the choice is per script, not global.
imaging/subhalo_recovery.py (120.7s). Already the subject of one
speed-up pass: complete/2026/08/potential-correction-validation.md leg 1
recorded it at 232s/224s against the 300s cap, and it now runs at 120.7s, so
half the work is done and the why is documented there — read it before
re-deriving. It asserts end-to-end dkappa recovery of a simulated 1e10
Msun subhalo for both the one-shot and iterative engines. Ask whether the
PR gate needs both engines or whether one belongs on the weekly channel.
misc/database/scrape/general.py (63.4s). Un-parked on 2026-07-21
(chore(no_run): un-park database/scrape/general, autolens_workspace_test#192).
A database-scrape regression is the least likely of the three to be broken
by a typical lens-modelling PR, so it is the strongest demotion candidate —
check what it uniquely covers before deciding.
point_source/jax_likelihood/point.py (47.7s). Check whether the cost
is PointSolver iterations or JAX compile time; if compile-dominated, the
lever is problem size, not sample count.
The cap does not apply to these scripts, and cannot be made to
Read this before proposing "just turn PYAUTO_SMALL_DATASETS on".
config/build/profile_smoke.yaml has set PYAUTO_SMALL_DATASETS: "1" in its
defaults since the file was created (2026-04-08, then spelled PYAUTO_WORKSPACE_SMALL_DATASETS; renamed 2026-04-30). It has never been
missing. What has grown is the set of entries exempted from it:
date
entries exempted from the cap
2026-04-30
10 profile overrides
2026-05-28
23
2026-07-23
27 — then migrated into in-file ENV: declarations (PyAutoHands#187), leaving 1 override
today
90 ENV: … full_datasets declarations repo-wide
Of the 23 live smoke entries, 16 declare ENV: [jax] full_datasets and a
17th (misc/database/scrape/general.py) is exempted by the one surviving
profile override. That is 516.5s of the 553.0s — 93% of the gate — running
uncapped. Only six entries actually run capped (3 aggregator + 2 latent at
9-pixel masks, multi_galaxy/model_fit.py at 80), totalling 36.5s.
Measured mask sizes from the same CI run, against autolens_workspace's
80–208 pixels:
entry
mask
imaging/subhalo_recovery.py
5858 px
misc/database/scrape/general.py
2828 px
multi_galaxy/jax_likelihood/lp.py
2828 px
imaging/jax_likelihood/potential_correction.py
1466 px
imaging/jax_likelihood/{rectangular,mge}.py
952 px
imaging/jax_likelihood/{lp,smbh}.py
716 px
The exemptions are deliberate and load-bearing: the jax_likelihood scripts
assert hardcoded full-resolution likelihood literals at rtol 1e-4, so a capped
dataset changes the likelihood and the assertion fails. That failure has been
hit and recorded — see complete/2026/08/sph-transform-name-check.md
("ran with capped datasets against full-resolution reference assertions and
failed") and complete/2026/08/mge-sigma-min-workspace-sweep.md.
So the real question this prompt has to answer is not "why is the cap off"
but "should the per-PR gate be running full-resolution parity assertions at
all?" For each of the three scripts, the options are: re-derive the literals
at a capped size (buys the cap but re-pins every literal, and those pins have
already had to be regenerated once — autolens_workspace_test#257, "repin vmap
literals halved by the PositionsLH penalty fix", which blocked the nightly
release at Stage 3 on 08-18/08-19), shrink the problem some other way, or
demote to the weekly channel that is meant for full-fidelity work. Choose per
script and say which.
Constraints
A faster script that no longer tests anything is a regression, not a win.
This repo has three recorded instances of exactly that failure mode: the
vacuous JAX assertions (complete/2026/07/vacuous-jax-assertions.md), the
NUFFT parity legs that compared nufftax against itself and reported max |Δ| = 0.0000e+00, and latent/latent_nan_robustness passing vacuously
under the smoke profile (see planned.md). For every reduction, state what
the assertion still discriminates against and show it failing when the thing
it guards is broken.
Coverage given up is not coverage lost. Heart's weekly workspace-smoke.yml
(Mondays 03:00 UTC) already runs every script in this repo against library main under the same profile_smoke.yaml, and release-integrate re-runs
the matrix at PYAUTO_TEST_MODE=0, full resolution. The curated PR list is a
strict subset of both. Demotion = removing the entry from smoke_tests.txt
with a comment saying which channel still covers it.
Do not raise BUILD_SCRIPT_TIMEOUT for these. The 300s smoke cap is a
runaway detector; three entries sitting under it is the problem, not the cap.
Keep the entries that stay inside the cap with real margin — 120.7s against
300s already flaked into timeout historically under sweep-load contention
(planned.md records 252s uncontended vs a 300s timeout under load).
Acceptance
Smoke step wall-clock for the py3.12 leg drops below ~6 minutes.
23/23 still pass, and every touched script has a stated, demonstrated
discriminating assertion.
Any demoted entry is commented in smoke_tests.txt naming the channel that
still runs it.
Overview
The per-PR smoke gate's py3.12 leg spends 553.0s executing scripts, and three
entries —
imaging/subhalo_recovery.py(120.7s),misc/database/scrape/general.py(63.4s) and
point_source/jax_likelihood/point.py(47.7s) — are 42% of that.This task makes each one materially faster or demotes it to the weekly/release
channels, per script, without weakening what the gate discriminates. Cost
attribution below was measured in a CI-equivalent environment (py3.12, source
chain install, smoke-profile env); the sibling prompt for running the gate less
often is out of scope here.
Plan
imaging/subhalo_recovery.py: split the script — keep the one-shot engine asthe PR-gate entry, move the warm-started iterative-LM confirmation leg to a
new script covered by the weekly/release channels (measured: the iterative leg
is ~80% of runtime and reproduces the one-shot metrics to 3 decimal places;
the iterative engine class stays PR-gated via the interferometer sibling).
misc/database/scrape/general.py: demote to the weekly/release channels withthe required
smoke_tests.txtcomment (its unique coverage — scraping a realNautilus run's outputs — is release-level, and the aggregator trio keeps the
scrape API covered on the gate); fallback if demotion is declined: shrink the
real search.
point_source/jax_likelihood/point.py: measured compile-dominated (~44s of55s local is two JAX JIT compiles; likelihood evals are 0.03s), and problem
size is a weak lever (10x looser solver precision saves only ~15%) — instead
drop the
FitPositionsImagePairAllSolvedblock, whose coverage the weeklychannel already runs verbatim in
image_plane.py; or demote the wholescript if the ~6:00 acceptance is strict (see arithmetic below).
and the py3.12 leg lands under ~6 minutes.
Detailed implementation plan
Affected Repositories
Branch Survey
Suggested branch:
feature/smoke-gate-slowest-scriptsMeasured baseline (this assessment, 2026-08-23)
CI-equivalent environment: py3.12 venv, chain installed from source checkouts
per
.github/scripts/smoke_install.sh, smoke-profile env perconfig/build/profile_smoke.yaml+ each script'sENV:declaration. Localtotal for
subhalo_recovery.pycold-cache is 148.0s vs 120.7s CI (factor~0.82); warm-cache local is 134.7s (the ~13s delta is numba compile, which CI
always pays — fresh runners).
imaging/subhalo_recovery.pyphase split (local warm / cold):fit.log_evidence+best_fit_dpsi)solve_joint_optimization(n_iter=3, warm-start)log_evidence()(Laplace) — printed, never assertedBoth engines recover essentially identical metrics: one-shot corr 0.8228 /
peak dist 0.06", iterative corr 0.8233 / 0.06". The warm-started iterative leg
is a stationarity confirmation of the one-shot optimum, not independent
discrimination.
Levers measured (all still assertion-green variants):
point_source/jax_likelihood/point.pyphase split (local, 55.4s total vs 47.7s CI):PointSolver.for_gridconstruction_vmap—FitPositionsImagePairAllJIT compile_vmap+ NumPy fit +jit(fit_from)round-trip_vmap—FitPositionsImagePairAllSolvedJIT compileCompile-dominated: ~44s of 55s is XLA compilation of the two pinned code
paths; each actual likelihood evaluation is 0.03s. Problem size was measured
as a WEAK lever: loosening
pixel_scale_precision0.001→0.01 (10x, ≈3 fewertraced refinement levels) only cuts the compiles to 8.9s + 28.4s (total
55.4→47.3s, −15%) — the XLA cost is mostly a per-program floor, not
refinement depth. The strong lever is that the 33s Solved-block compile
duplicates coverage
image_plane.pyalready provides on the weekly channel.misc/database/scrape/general.pyphase split (local, ~78s total vs 63.4s CI,from run log timestamps):
n_like_max=300, JAX): samplingThe search is ~72s of ~78s; the scrape + assertions the script uniquely
gate-tests are ~3s. The
misc/aggregator/trio on the gate covers the samescrape/aggregator API under
PYAUTO_TEST_MODE=1fixtures; general.py's uniquecoverage is scraping a REAL search's output directory.
Implementation Steps
imaging/subhalo_recovery.py→ split (recommended).imaging/subhalo_recovery.pyto simulate + arc mask + one-shotFitDpsiSrcImaging+ dkappa corr/dist assertions (thresholds unchanged:corr > 0.5, dist < 0.5"). Keep the
ENV: full_datasetsdeclaration and thedocstring's parity-anchor framing; note in the docstring where the
iterative leg went.
imaging/subhalo_recovery_iterative.pycarrying the iterative-LMleg verbatim (warm start recomputed from a fresh one-shot fit, or
restructured to re-derive
x0locally), with its existing corr/dist/gaugeassertions. Do NOT add it to
smoke_tests.txt; the weeklyworkspace-smoke.ymlandrelease-integraterun every script, so it iscovered there automatically — but note it in
smoke_tests.txt's commentfor the record.
iter_fit.log_evidence()print fromwhichever script keeps the iterative leg (−15s+; nothing discriminates on it).
e.g. zero the recovered dkappa or simulate without the subhalo — and show
the one-shot corr assertion fail; record the demonstration in the PR.
engines via
interferometer/subhalo_recovery_interferometer.py(one-shotsparse+dense parity +
IterFitDpsiSrcInterferometern_iter=5 cold start,~28s); imaging's iterative leg additionally runs weekly + at release.
drop the Laplace print and set
n_iter=2(measured corr 0.8231 vs 0.8233,gauge asserts unchanged) → est. ~85s CI. State which option was chosen.
misc/database/scrape/general.py→ demote (recommended).smoke_tests.txtwith the required comment naming thechannels that still run it: Heart's weekly
workspace-smoke.yml(Mondays03:00 UTC, library
main, same profile) andrelease-integrate(
PYAUTO_TEST_MODE=0, full resolution).run's output directory into the SQLite database (the
misc/aggregator/trio on the gate covers the same scrape/aggregator API under
PYAUTO_TEST_MODE=1fixtures); a lens-modelling PR that breaks real-rundatabase serialization without tripping the aggregator trio, the JAX
likelihood pins, or the library unit tests is the least likely regression
of the three, and it remains covered twice weekly.
(
n_like_max300→100 and/or a smaller in-script circular mask) — itsassertions are relational (
> 0, name/info checks), not pinned literals,so a smaller fit preserves them; verify the scrape still ingests > 0
samples and every
agg.values(...)generator still yields.point_source/jax_likelihood/point.py→ drop the gate-redundant Solvedblock (or demote the script).
__Model: Solved Source (Parameter-Free)__block(the second
_vmapcompile, 33s measured, plus its ~8s NumPycross-check) from point.py. Its coverage —
FitPositionsImagePairAllSolvedwith a pinned literal — already exists in
image_plane.py, which theweekly
workspace-smoke.ymlandrelease-integraterun; updatepoint.py's docstring (it currently says the solved variant is here
BECAUSE this script is the gate entry — record the demotion decision and
name the covering channel). The base
FitPositionsImagePairAllpin(
-83.38049778), the NumPy cross-check and thejit(fit_from)round-tripstay on the gate untouched — no literal re-pins needed.
Est. 47.7 → ~18s CI.
pixel_scale_precision/ solver grid: measured a10x loosening saves only ~15% (XLA floor), and it would force re-pinning
both literals for nothing (cf. test: repin vmap literals halved by the PositionsLH penalty fix (PyAutoLens#700) #257 repin pain).
script to the weekly channel (comment in
smoke_tests.txtnamingimage_plane.py + weekly/release as the covering surface) — but this
removes the last point-source entry from the PR gate; flag that trade
explicitly to the human.
Re-measure + close out.
python .github/scripts/run_smoke.py)and on the PR; grep the
[PASS] <name> — <n>slines; confirm 23/23 (or22/23+new script count if split) and py3.12 script time < ~360s.
8437) − 63.4 (general demote) −(subhalo split, 120.7→
30 (point Solved18) ≈ 376s ≈ 6m16s; with point.py demoted entirelyblock, 47.7→
instead: ≈ 358s ≈ 5m58s. The recommended set lands ~16s above a
strict 360s; whether "~6 minutes" tolerates that, or point.py should be
fully demoted, is the one open acceptance call — flag it on the PR.
Key Files
scripts/imaging/subhalo_recovery.py— split: one-shot stays; iterative legmoves to
scripts/imaging/subhalo_recovery_iterative.py(new)smoke_tests.txt— general.py demotion comment; no new-script additionscripts/misc/database/scrape/general.py— only if fallback-shrink chosenscripts/point_source/jax_likelihood/point.py— remove the Solved block(coverage stays in
image_plane.pyon the weekly channel); no re-pinsconfig/build/profile_smoke.yaml— unchanged (no cap changes; constraint 3)Work Classification
Workspace
Worktree root
~/Code/PyAutoLabs-wt/smoke-gate-slowest-scripts/(created later by/start_workspace)Original Prompt
Click to expand starting prompt
Speed up the three slowest autolens_workspace_test smoke-gate scripts
Type: test
Target: workspaces
Repos:
Difficulty: medium
Autonomy: supervised
Priority: normal
Status: formalised
The per-PR smoke gate in
autolens_workspace_testcosts ~11m20s wall-clock, ofwhich ~9m13s is script execution. Three entries are 42% of that. This prompt is
the make them cheaper half; cutting how often the gate runs at all is the
sibling prompt
draft/test/pyautoheart/smoke_relevance_gate.md. Do not mergethe two — one edits scripts, the other edits a workflow, and they land in
different repos.
Measured
CI run 32605025472 (2026-08-22,
main), py3.12 leg (the critical path; py3.13is ~6% faster). 23 entries, 23/23 pass, 553.0s total — which reconciles to
the step wall-clock exactly, so the runner adds no measurable overhead and the
scripts are the cost.
imaging/subhalo_recovery.pymisc/database/scrape/general.pypoint_source/jax_likelihood/point.pyimaging/jax_likelihood/rectangular.pymisc/jax_assertions/delaunay_nn.pyimaging/jax_likelihood/mge.pyThe remaining 17 entries are 4.5–29.2s each and are not in scope. Reproduce
with
gh apion the job log and grep the runner's[PASS] <name> — <n>slines; the runner prints one per entry.
Note the tail is short: after these three the curve flattens, so this prompt
can win ~4 minutes and no more. Do not chase entries below ~30s.
Task
Per script, either make it materially faster or demote it — both are
acceptable outcomes, and the choice is per script, not global.
imaging/subhalo_recovery.py(120.7s). Already the subject of onespeed-up pass:
complete/2026/08/potential-correction-validation.mdleg 1recorded it at 232s/224s against the 300s cap, and it now runs at 120.7s, so
half the work is done and the why is documented there — read it before
re-deriving. It asserts end-to-end
dkapparecovery of a simulated 1e10Msun subhalo for both the one-shot and iterative engines. Ask whether the
PR gate needs both engines or whether one belongs on the weekly channel.
misc/database/scrape/general.py(63.4s). Un-parked on 2026-07-21(
chore(no_run): un-park database/scrape/general, autolens_workspace_test#192).A database-scrape regression is the least likely of the three to be broken
by a typical lens-modelling PR, so it is the strongest demotion candidate —
check what it uniquely covers before deciding.
point_source/jax_likelihood/point.py(47.7s). Check whether the costis
PointSolveriterations or JAX compile time; if compile-dominated, thelever is problem size, not sample count.
The cap does not apply to these scripts, and cannot be made to
Read this before proposing "just turn PYAUTO_SMALL_DATASETS on".
config/build/profile_smoke.yamlhas setPYAUTO_SMALL_DATASETS: "1"in itsdefaults since the file was created (2026-04-08, then spelled
PYAUTO_WORKSPACE_SMALL_DATASETS; renamed 2026-04-30). It has never beenmissing. What has grown is the set of entries exempted from it:
ENV:declarations (PyAutoHands#187), leaving 1 overrideENV: … full_datasetsdeclarations repo-wideOf the 23 live smoke entries, 16 declare
ENV: [jax] full_datasetsand a17th (
misc/database/scrape/general.py) is exempted by the one survivingprofile override. That is 516.5s of the 553.0s — 93% of the gate — running
uncapped. Only six entries actually run capped (3 aggregator + 2 latent at
9-pixel masks,
multi_galaxy/model_fit.pyat 80), totalling 36.5s.Measured mask sizes from the same CI run, against autolens_workspace's
80–208 pixels:
imaging/subhalo_recovery.pymisc/database/scrape/general.pymulti_galaxy/jax_likelihood/lp.pyimaging/jax_likelihood/potential_correction.pyimaging/jax_likelihood/{rectangular,mge}.pyimaging/jax_likelihood/{lp,smbh}.pyThe exemptions are deliberate and load-bearing: the
jax_likelihoodscriptsassert hardcoded full-resolution likelihood literals at rtol 1e-4, so a capped
dataset changes the likelihood and the assertion fails. That failure has been
hit and recorded — see
complete/2026/08/sph-transform-name-check.md("ran with capped datasets against full-resolution reference assertions and
failed") and
complete/2026/08/mge-sigma-min-workspace-sweep.md.So the real question this prompt has to answer is not "why is the cap off"
but "should the per-PR gate be running full-resolution parity assertions at
all?" For each of the three scripts, the options are: re-derive the literals
at a capped size (buys the cap but re-pins every literal, and those pins have
already had to be regenerated once — autolens_workspace_test#257, "repin vmap
literals halved by the PositionsLH penalty fix", which blocked the nightly
release at Stage 3 on 08-18/08-19), shrink the problem some other way, or
demote to the weekly channel that is meant for full-fidelity work. Choose per
script and say which.
Constraints
This repo has three recorded instances of exactly that failure mode: the
vacuous JAX assertions (
complete/2026/07/vacuous-jax-assertions.md), theNUFFT parity legs that compared nufftax against itself and reported
max |Δ| = 0.0000e+00, andlatent/latent_nan_robustnesspassing vacuouslyunder the smoke profile (see
planned.md). For every reduction, state whatthe assertion still discriminates against and show it failing when the thing
it guards is broken.
workspace-smoke.yml(Mondays 03:00 UTC) already runs every script in this repo against library
mainunder the sameprofile_smoke.yaml, andrelease-integratere-runsthe matrix at
PYAUTO_TEST_MODE=0, full resolution. The curated PR list is astrict subset of both. Demotion = removing the entry from
smoke_tests.txtwith a comment saying which channel still covers it.
BUILD_SCRIPT_TIMEOUTfor these. The 300s smoke cap is arunaway detector; three entries sitting under it is the problem, not the cap.
300s already flaked into timeout historically under sweep-load contention
(
planned.mdrecords 252s uncontended vs a 300s timeout under load).Acceptance
discriminating assertion.
smoke_tests.txtnaming the channel thatstill runs it.