From 3e83d220af815bc6b9433a5c5e3257eb4985e2ae Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Sat, 22 Aug 2026 13:23:37 +0000 Subject: [PATCH 1/3] prompt: register optional-dependency-skip-guards (PyAutoFit#1511) + correct the test_nautilus drift MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Files the task that closes follow-up 4 of complete/2026/08/uniform-prior-bounds-numpy-path.md, filed 2026-08-18 but never turned into a prompt. test_nautilus.py::test__single_core_builds_no_pool has been reported as "pre-existing on clean main" in at least six completion records since 2026-08-16. It is not: the test runs a real search.fit, which imports the optional `nautilus` sampler, and that ships only in the [optional] extra. CI installs [optional] and the test passes there (latest main: 2024 passed, 3 skipped, 0 failed). Envs without the extras get a hard ModuleNotFoundError. Same cause for the astropy collection errors and the nine aggregator errors. - active/17_optional_dependency_skip_guards.md — the prompt, with the evidence from all three envs and the full correction trail across the records - active.md — registry entry, issue #1511, PR #1512 - three completion records annotated with a dated correction rather than rewritten in place, following the prior-support-clipper.md precedent: multistart-gradient-resume-fom-sanity-check, clipper-usage-in-search-summary, uniform-prior-bounds-numpy-path - dashboard regenerated (in-flight 2 -> 3) lifecycle.py check: OK. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01F1uQdHt11NPBc5cXA5cvme --- active.md | 13 +++ active/17_optional_dependency_skip_guards.md | 92 +++++++++++++++++++ .../08/clipper-usage-in-search-summary.md | 18 ++++ ...istart-gradient-resume-fom-sanity-check.md | 18 ++++ .../08/uniform-prior-bounds-numpy-path.md | 18 ++++ dashboard.html | 3 +- dashboard.md | 10 +- 7 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 active/17_optional_dependency_skip_guards.md diff --git a/active.md b/active.md index ab06b16d..f05e4d01 100644 --- a/active.md +++ b/active.md @@ -1,5 +1,18 @@ # Active Tasks +## optional-dependency-skip-guards +- issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1511 (issued 2026-08-22) +- prompt: active/17_optional_dependency_skip_guards.md +- status: PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, awaiting CI +- scope-note: tests only, no `autofit/` source touched. Verified inert in the CI env + (2024 passed / 3 skipped, identical to main), so no coverage is lost. +- context: closes follow-up 4 of complete/2026/08/uniform-prior-bounds-numpy-path.md, + filed there 2026-08-18 but never turned into a prompt. Ends the recurring + "test_nautilus fails pre-existing on main" false alarm — see the correction trail + in the prompt. +- repos: + - PyAutoFit: claude/test-nautilus-single-core-builds-35kyot + ## transformed-message-factor-gradient-unpack - issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1501 (issued 2026-08-19) - prompt: active/16_transformed_message_factor_gradient_unpack.md diff --git a/active/17_optional_dependency_skip_guards.md b/active/17_optional_dependency_skip_guards.md new file mode 100644 index 00000000..6fdef648 --- /dev/null +++ b/active/17_optional_dependency_skip_guards.md @@ -0,0 +1,92 @@ +# `@PyAutoFit` `[optional]`-dependency tests have no skip guards + +Type: test +Target: autofit +Difficulty: small +Autonomy: autonomous +Priority: normal +Status: issued 2026-08-22 as PyAutoFit#1511; PR #1512 open, awaiting CI + +Not a defect on `main` — a test-hygiene gap that has been *repeatedly +misdiagnosed* as one. That misdiagnosis is the actual cost. + +## The finding + +`test_autofit/non_linear/search/nest/test_nautilus.py::test__single_core_builds_no_pool` +runs a real `search.fit`, which reaches `from nautilus import Sampler` +(`autofit/non_linear/search/nest/nautilus/search.py:238`). +`nautilus-sampler==1.0.5` ships **only** in the `[optional]` extra +(`pyproject.toml:85`), and the test carries **no skip guard**. + +CI installs `[optional]` — PyAutoHeart's `lib-tests.yml` does +`pip install "./$r[optional]"` — so CI never sees it. Every env installed +without those extras (cloud sandboxes, local venvs) gets a hard +`ModuleNotFoundError`. + +It is the only optional-sampler test in the suite without a guard. Precedent +is everywhere else: `test_blackjax_nuts.py:14`, `nest/nss/test_search.py:20`, +`test_arithmetic_jax_trace.py:6`, `test_fork_context.py:31`. + +`astropy` is the same class of noise: two modules fail *collection* on its +top-level import, and nine aggregator tests error on it at runtime +(`autofit/aggregator/file_output.py:101`, +`autofit/aggregator/summary/aggregate_fits.py:105,165`). + +## Why this was worth a task + +The single nautilus failure has been reported as "pre-existing on clean +`main`" in at least six completion records since 2026-08-16 — see the +correction trail below. Each session spent a control run re-disproving it, +and the wrong gloss propagated into PR bodies #1479 and #1480. Main is **not** +red: latest main CI (run 32546158666) is 2024 passed, 3 skipped, 0 failed on +3.12, 3.13 and the no-jax leg. + +## Evidence (untouched main @ `a639226`, py3.12) + +| env | result | +|---|---| +| no `nautilus-sampler` | `1 failed, 3 passed` — `ModuleNotFoundError` at `search.py:242` | +| `pip install nautilus-sampler==1.0.5`, same tree, no other change | `4 passed` | +| full suite, no optional extras | 2 collection errors → then 4 failed / 9 errors, **all** missing-`astropy` | + +## The fix + +Skip-if-missing guards in the house pattern — an `importlib.util.find_spec` +`skipif` marker, or `pytest.importorskip` where the import is module-level. +Tests only; no `autofit/` source touched. + +Verified three ways on the branch: + +- no extras at all — nautilus test skips with its reason: `3 passed, 1 skipped` +- no `astropy` — `1985 passed, 33 skipped, 0 failed, 0 errors` +- full `[optional]` extras (the CI env) — `2024 passed, 3 skipped`, **identical + to CI on main**, so the guards are inert where the deps exist and no + coverage is lost + +## Correction trail + +The claim "fails identically on the untouched tree — pre-existing, not this +change" is right about causation and wrong about `main`. Records carrying the +loose gloss: + +- `complete/2026/08/prior-support-clipper.md:152,218` — already issued the + correction ("read it as environment-specific"); the correct reading +- `complete/2026/08/covariance-interpolator-rng-seed.md:14` — the only record + that names the real `ModuleNotFoundError`; correct +- `complete/2026/08/uniform-prior-bounds-numpy-path.md:31,50` — follow-up 4 + proposed exactly this fix but it was never filed as a prompt, so nothing + acted on it; this task is that follow-up +- `complete/2026/08/multistart-gradient-resume-fom-sanity-check.md:14` — + "confirmed pre-existing on unmodified `main`"; wrong gloss +- `complete/2026/08/clipper-usage-in-search-summary.md:89` — "**pre-existing**"; + wrong gloss + +Once this merges, no env reproduces the failure and the gloss stops +recurring. + +## Prior art + +`complete/2026/08/nautilus-1core-serial-pool.md` — the task that *added* +`test__single_core_builds_no_pool` (PyAutoFit#1442 → #1443). The test itself is +sound and still guards the real fork-pool deadlock; only its environment +assumption was missing. diff --git a/complete/2026/08/clipper-usage-in-search-summary.md b/complete/2026/08/clipper-usage-in-search-summary.md index 0bcc6b29..5656e43e 100644 --- a/complete/2026/08/clipper-usage-in-search-summary.md +++ b/complete/2026/08/clipper-usage-in-search-summary.md @@ -64,6 +64,24 @@ wired up and firing at all". Multi-start summaries gained a `Constrained Lane-Steps` line. Everything else is additive and gated. +## Correction (2026-08-22) — the `test_nautilus` failure + +`test_nautilus.py::test__single_core_builds_no_pool` is **not** a failure on +clean `main`. It is a **missing optional dependency**: the test runs a real +`search.fit`, which reaches `from nautilus import Sampler`, and +`nautilus-sampler` ships only in the `[optional]` extra. CI installs +`[optional]` and the test passes there — latest main CI is 2024 passed, +3 skipped, 0 failed. Sandboxes and local venvs without the extras get a hard +`ModuleNotFoundError`. + +The in-flight note above calls it **pre-existing**, alongside the `astropy` +collection error in `paths/test_save_and_load.py` — same cause, same +correction. Both were environment-specific, not defects on `main`. + +Fixed by PyAutoFit#1511 / PR #1512 (skip-if-missing guards, also covering the +`astropy` collection errors and aggregator errors from the same cause). Full +investigation: `active/17_optional_dependency_skip_guards.md`. + ## Original prompt # Report how much the Clipper actually fired — surface the count in `search.summary` diff --git a/complete/2026/08/multistart-gradient-resume-fom-sanity-check.md b/complete/2026/08/multistart-gradient-resume-fom-sanity-check.md index d84fe1aa..b67ad9e4 100644 --- a/complete/2026/08/multistart-gradient-resume-fom-sanity-check.md +++ b/complete/2026/08/multistart-gradient-resume-fom-sanity-check.md @@ -19,6 +19,24 @@ - assertion design worth reusing: the load-bearing invariant is **equality with an uninterrupted reference run** (the search is deterministic), not "the counters went up". Injecting the regression (resetting both counters on resume) yields 402 against the reference's 403 — a `>=` assertion accepts that happily, equality catches it. A separate decisive check also ran: stamping sentinel values (7000/9000) into the live checkpoint and resuming gave 7045/9008, so the restored totals are provably carried rather than recounted. - also confirmed while doing it: a resumed run's final counters are independent of *where* the kill landed (killed at step 72 and at step 74 both finished at the reference totals), i.e. the checkpoint captures the full accumulator state. +## Correction (2026-08-22) — the `test_nautilus` failure + +`test_nautilus.py::test__single_core_builds_no_pool` is **not** a failure on +clean `main`. It is a **missing optional dependency**: the test runs a real +`search.fit`, which reaches `from nautilus import Sampler`, and +`nautilus-sampler` ships only in the `[optional]` extra. CI installs +`[optional]` and the test passes there — latest main CI is 2024 passed, +3 skipped, 0 failed. Sandboxes and local venvs without the extras get a hard +`ModuleNotFoundError`. + +The validation bullet above says "confirmed pre-existing on unmodified +`main`". "Not caused by this work" was right; "pre-existing on `main`" is the +wrong gloss — read it as environment-specific. + +Fixed by PyAutoFit#1511 / PR #1512 (skip-if-missing guards, also covering the +`astropy` collection errors and aggregator errors from the same cause). Full +investigation: `active/17_optional_dependency_skip_guards.md`. + ## Original prompt # MultiStartGradient cannot resume a killed mid-run search — FoM sanity check compares log-likelihood against chi-squared diff --git a/complete/2026/08/uniform-prior-bounds-numpy-path.md b/complete/2026/08/uniform-prior-bounds-numpy-path.md index 49536eac..a11a4437 100644 --- a/complete/2026/08/uniform-prior-bounds-numpy-path.md +++ b/complete/2026/08/uniform-prior-bounds-numpy-path.md @@ -50,6 +50,24 @@ 4. `test_beta` + `test__single_core_builds_no_pool` fail on clean main without optional deps (sympy?/nautilus-sampler absence) — hygiene candidate: skip-if-missing markers. +## Correction (2026-08-22) — the `test_nautilus` failure + +`test_nautilus.py::test__single_core_builds_no_pool` is **not** a failure on +clean `main`. It is a **missing optional dependency**: the test runs a real +`search.fit`, which reaches `from nautilus import Sampler`, and +`nautilus-sampler` ships only in the `[optional]` extra. CI installs +`[optional]` and the test passes there — latest main CI is 2024 passed, +3 skipped, 0 failed. Sandboxes and local venvs without the extras get a hard +`ModuleNotFoundError`. + +Follow-up 4 above ("hygiene candidate: skip-if-missing markers") called this +correctly and proposed the fix, but was never filed as a prompt, so nothing +acted on it for four days. It is now filed and fixed. + +Fixed by PyAutoFit#1511 / PR #1512 (skip-if-missing guards, also covering the +`astropy` collection errors and aggregator errors from the same cause). Full +investigation: `active/17_optional_dependency_skip_guards.md`. + ## Original prompt # UniformPrior bounds are not enforced in the objective on the NumPy path diff --git a/dashboard.html b/dashboard.html index 00f7e868..eca8af49 100644 --- a/dashboard.html +++ b/dashboard.html @@ -38,7 +38,7 @@

📋 PyAutoMind Dashboard

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.

-

In flight 2 · Parked 3 · Planned 6 · Backlog 144 · markdown version

+

In flight 3 · Parked 3 · Planned 6 · Backlog 144 · markdown version

Start here

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

TRIAGE: needs manual review before routingmedium · safe · high

@@ -58,6 +58,7 @@

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 #1501HOLD — do not start dev. Fix-or-delete hangs off the PyAutoFit#1498 logpdf-contract

+

@PyAutoFit [optional]-dependency tests have no skip guardsissue #1511PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, awaiting CI

Parked markdown version

diff --git a/dashboard.md b/dashboard.md index d1644d8e..bd598926 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/`) | 3 | | [Parked](#parked) (`parked.md`) | 3 | | [Planned](#planned) (`planned.md`) | 6 | | [Backlog](#backlog) (`draft/`) | 144 | @@ -129,6 +129,14 @@ Issued — each has an open GitHub issue and usually a branch. The full record f
+
📋 @PyAutoFit [optional]-dependency tests have no skip guardsissue #1511 — PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, awaiting CI + +``` +/start_dev active/17_optional_dependency_skip_guards.md +``` + +
+
📋 Hands hygiene: expired announcement dead code, unregistered modulesissue #249 — library-dev ``` From 1cd1ca6c8c644e65efcfd3f6236b7445ed6ac5c1 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Sat, 22 Aug 2026 13:26:33 +0000 Subject: [PATCH 2/3] =?UTF-8?q?prompt:=20optional-dependency-skip-guards?= =?UTF-8?q?=20=E2=80=94=20PyAutoFit#1512=20CI=20green?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All three legs pass on b814937 (run 32575550710): unittest 3.12, unittest 3.13 and unittest-nojax. PR mergeable state clean, no review comments. Status lines advanced in active.md and the prompt; dashboard regenerated. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01F1uQdHt11NPBc5cXA5cvme --- active.md | 3 ++- active/17_optional_dependency_skip_guards.md | 2 +- dashboard.html | 2 +- dashboard.md | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/active.md b/active.md index f05e4d01..8d20c44a 100644 --- a/active.md +++ b/active.md @@ -3,7 +3,8 @@ ## optional-dependency-skip-guards - issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1511 (issued 2026-08-22) - prompt: active/17_optional_dependency_skip_guards.md -- status: PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, awaiting CI +- status: PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, CI GREEN + (unittest 3.12 + 3.13 + nojax, run 32575550710), mergeable clean, awaiting review - scope-note: tests only, no `autofit/` source touched. Verified inert in the CI env (2024 passed / 3 skipped, identical to main), so no coverage is lost. - context: closes follow-up 4 of complete/2026/08/uniform-prior-bounds-numpy-path.md, diff --git a/active/17_optional_dependency_skip_guards.md b/active/17_optional_dependency_skip_guards.md index 6fdef648..752fbac2 100644 --- a/active/17_optional_dependency_skip_guards.md +++ b/active/17_optional_dependency_skip_guards.md @@ -5,7 +5,7 @@ Target: autofit Difficulty: small Autonomy: autonomous Priority: normal -Status: issued 2026-08-22 as PyAutoFit#1511; PR #1512 open, awaiting CI +Status: issued 2026-08-22 as PyAutoFit#1511; PR #1512 open, CI green, awaiting review Not a defect on `main` — a test-hygiene gap that has been *repeatedly misdiagnosed* as one. That misdiagnosis is the actual cost. diff --git a/dashboard.html b/dashboard.html index eca8af49..d9585e4a 100644 --- a/dashboard.html +++ b/dashboard.html @@ -58,7 +58,7 @@

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 #1501HOLD — do not start dev. Fix-or-delete hangs off the PyAutoFit#1498 logpdf-contract

-

@PyAutoFit [optional]-dependency tests have no skip guardsissue #1511PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, awaiting CI

+

@PyAutoFit [optional]-dependency tests have no skip guardsissue #1511PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, CI GREEN

Parked markdown version

diff --git a/dashboard.md b/dashboard.md index bd598926..35f15dcf 100644 --- a/dashboard.md +++ b/dashboard.md @@ -129,7 +129,7 @@ Issued — each has an open GitHub issue and usually a branch. The full record f
-
📋 @PyAutoFit [optional]-dependency tests have no skip guardsissue #1511 — PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, awaiting CI +
📋 @PyAutoFit [optional]-dependency tests have no skip guardsissue #1511 — PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, CI GREEN ``` /start_dev active/17_optional_dependency_skip_guards.md From a5d475fddd50bc92ef0161b1a95e7578ebabf7b4 Mon Sep 17 00:00:00 2001 From: James Nightingale Date: Sat, 22 Aug 2026 13:32:18 +0000 Subject: [PATCH 3/3] =?UTF-8?q?prompt:=20complete=20optional-dependency-sk?= =?UTF-8?q?ip-guards=20=E2=80=94=20PyAutoFit#1512=20merged?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shipped 2026-08-22, merge commit 14eb8393. Advances the task to complete/2026/08/optional-dependency-skip-guards.md via lifecycle.py record: prompt folded, active.md section removed, index refreshed, dashboard regenerated. The record keeps the part worth remembering: the fix was one line per file, but the diagnosis had already been written down twice (prior-support-clipper.md on 08-17, uniform-prior-bounds-numpy-path.md follow-up 4 on 08-18) and the false alarm still fired three more times, because a follow-up that lives only in a completion record has no owner. lifecycle.py check: OK. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01F1uQdHt11NPBc5cXA5cvme --- active.md | 14 -- active/17_optional_dependency_skip_guards.md | 92 ----------- .../08/optional-dependency-skip-guards.md | 151 ++++++++++++++++++ complete/index.md | 3 +- dashboard.html | 3 +- dashboard.md | 10 +- 6 files changed, 155 insertions(+), 118 deletions(-) delete mode 100644 active/17_optional_dependency_skip_guards.md create mode 100644 complete/2026/08/optional-dependency-skip-guards.md diff --git a/active.md b/active.md index 8d20c44a..ab06b16d 100644 --- a/active.md +++ b/active.md @@ -1,19 +1,5 @@ # Active Tasks -## optional-dependency-skip-guards -- issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1511 (issued 2026-08-22) -- prompt: active/17_optional_dependency_skip_guards.md -- status: PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, CI GREEN - (unittest 3.12 + 3.13 + nojax, run 32575550710), mergeable clean, awaiting review -- scope-note: tests only, no `autofit/` source touched. Verified inert in the CI env - (2024 passed / 3 skipped, identical to main), so no coverage is lost. -- context: closes follow-up 4 of complete/2026/08/uniform-prior-bounds-numpy-path.md, - filed there 2026-08-18 but never turned into a prompt. Ends the recurring - "test_nautilus fails pre-existing on main" false alarm — see the correction trail - in the prompt. -- repos: - - PyAutoFit: claude/test-nautilus-single-core-builds-35kyot - ## transformed-message-factor-gradient-unpack - issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1501 (issued 2026-08-19) - prompt: active/16_transformed_message_factor_gradient_unpack.md diff --git a/active/17_optional_dependency_skip_guards.md b/active/17_optional_dependency_skip_guards.md deleted file mode 100644 index 752fbac2..00000000 --- a/active/17_optional_dependency_skip_guards.md +++ /dev/null @@ -1,92 +0,0 @@ -# `@PyAutoFit` `[optional]`-dependency tests have no skip guards - -Type: test -Target: autofit -Difficulty: small -Autonomy: autonomous -Priority: normal -Status: issued 2026-08-22 as PyAutoFit#1511; PR #1512 open, CI green, awaiting review - -Not a defect on `main` — a test-hygiene gap that has been *repeatedly -misdiagnosed* as one. That misdiagnosis is the actual cost. - -## The finding - -`test_autofit/non_linear/search/nest/test_nautilus.py::test__single_core_builds_no_pool` -runs a real `search.fit`, which reaches `from nautilus import Sampler` -(`autofit/non_linear/search/nest/nautilus/search.py:238`). -`nautilus-sampler==1.0.5` ships **only** in the `[optional]` extra -(`pyproject.toml:85`), and the test carries **no skip guard**. - -CI installs `[optional]` — PyAutoHeart's `lib-tests.yml` does -`pip install "./$r[optional]"` — so CI never sees it. Every env installed -without those extras (cloud sandboxes, local venvs) gets a hard -`ModuleNotFoundError`. - -It is the only optional-sampler test in the suite without a guard. Precedent -is everywhere else: `test_blackjax_nuts.py:14`, `nest/nss/test_search.py:20`, -`test_arithmetic_jax_trace.py:6`, `test_fork_context.py:31`. - -`astropy` is the same class of noise: two modules fail *collection* on its -top-level import, and nine aggregator tests error on it at runtime -(`autofit/aggregator/file_output.py:101`, -`autofit/aggregator/summary/aggregate_fits.py:105,165`). - -## Why this was worth a task - -The single nautilus failure has been reported as "pre-existing on clean -`main`" in at least six completion records since 2026-08-16 — see the -correction trail below. Each session spent a control run re-disproving it, -and the wrong gloss propagated into PR bodies #1479 and #1480. Main is **not** -red: latest main CI (run 32546158666) is 2024 passed, 3 skipped, 0 failed on -3.12, 3.13 and the no-jax leg. - -## Evidence (untouched main @ `a639226`, py3.12) - -| env | result | -|---|---| -| no `nautilus-sampler` | `1 failed, 3 passed` — `ModuleNotFoundError` at `search.py:242` | -| `pip install nautilus-sampler==1.0.5`, same tree, no other change | `4 passed` | -| full suite, no optional extras | 2 collection errors → then 4 failed / 9 errors, **all** missing-`astropy` | - -## The fix - -Skip-if-missing guards in the house pattern — an `importlib.util.find_spec` -`skipif` marker, or `pytest.importorskip` where the import is module-level. -Tests only; no `autofit/` source touched. - -Verified three ways on the branch: - -- no extras at all — nautilus test skips with its reason: `3 passed, 1 skipped` -- no `astropy` — `1985 passed, 33 skipped, 0 failed, 0 errors` -- full `[optional]` extras (the CI env) — `2024 passed, 3 skipped`, **identical - to CI on main**, so the guards are inert where the deps exist and no - coverage is lost - -## Correction trail - -The claim "fails identically on the untouched tree — pre-existing, not this -change" is right about causation and wrong about `main`. Records carrying the -loose gloss: - -- `complete/2026/08/prior-support-clipper.md:152,218` — already issued the - correction ("read it as environment-specific"); the correct reading -- `complete/2026/08/covariance-interpolator-rng-seed.md:14` — the only record - that names the real `ModuleNotFoundError`; correct -- `complete/2026/08/uniform-prior-bounds-numpy-path.md:31,50` — follow-up 4 - proposed exactly this fix but it was never filed as a prompt, so nothing - acted on it; this task is that follow-up -- `complete/2026/08/multistart-gradient-resume-fom-sanity-check.md:14` — - "confirmed pre-existing on unmodified `main`"; wrong gloss -- `complete/2026/08/clipper-usage-in-search-summary.md:89` — "**pre-existing**"; - wrong gloss - -Once this merges, no env reproduces the failure and the gloss stops -recurring. - -## Prior art - -`complete/2026/08/nautilus-1core-serial-pool.md` — the task that *added* -`test__single_core_builds_no_pool` (PyAutoFit#1442 → #1443). The test itself is -sound and still guards the real fork-pool deadlock; only its environment -assumption was missing. diff --git a/complete/2026/08/optional-dependency-skip-guards.md b/complete/2026/08/optional-dependency-skip-guards.md new file mode 100644 index 00000000..1f9df4fb --- /dev/null +++ b/complete/2026/08/optional-dependency-skip-guards.md @@ -0,0 +1,151 @@ +- issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1511 +- completed: 2026-08-22 +- library-pr: https://github.com/PyAutoLabs/PyAutoFit/pull/1512 (MERGED 2026-08-22, merge commit 14eb8393) +- summary: `test_nautilus.py::test__single_core_builds_no_pool` had no skip guard + while running a real `search.fit`, which reaches `from nautilus import Sampler` + (`autofit/non_linear/search/nest/nautilus/search.py:238`). `nautilus-sampler` + ships only in the `[optional]` extra, so the test hard-failed with + `ModuleNotFoundError` in every env without those extras while passing in CI, + which installs `[optional]`. Same cause for the two `astropy` collection errors + and nine aggregator errors. Fixed with `importlib.util.find_spec` skipif markers + (and `pytest.importorskip` where the import is module-level), matching the + existing house pattern in `test_blackjax_nuts.py`, `nest/nss/test_search.py`, + `test_arithmetic_jax_trace.py` and `test_fork_context.py`. Tests only — no + `autofit/` source touched. +- **the real cost was the misdiagnosis, not the failure.** The same red test was + reported as "pre-existing on clean `main`" in at least six completion records + from 2026-08-16 onward, each session spending a control run to re-disprove it, + and the wrong gloss propagated into PR bodies #1479 and #1480. Main was never + red: CI on main @ `a639226` was 2024 passed / 3 skipped / 0 failed across 3.12, + 3.13 and the no-jax leg. +- evidence at ship (untouched main @ `a639226`, py3.12, measured before any edit): + without `nautilus-sampler` → 1 failed / 3 passed, `ModuleNotFoundError` at + `search.py:242`; after `pip install nautilus-sampler==1.0.5` on the same tree + with no other change → 4 passed. Full suite with no optional extras → 2 + collection errors, then 4 failed / 9 errors, **all** missing-`astropy`. +- verification of the fix, three envs on the branch: no extras at all → the + nautilus test skips with its reason (3 passed, 1 skipped); no `astropy` → 1985 + passed, 33 skipped, 0 failed, 0 errors; full `[optional]` extras, i.e. the CI + env → **2024 passed, 3 skipped, identical to CI on main**. That last leg is the + load-bearing one: it proves the guards are inert wherever the deps exist, so no + coverage is lost. A skip guard that quietly disabled tests in CI would be a + worse bug than the one it fixes — check it that way, not by trusting green. +- CI at merge: unittest 3.12, unittest 3.13 and unittest-nojax all green on + `b814937` (run 32575550710); mergeable state clean, no review comments. +- **process finding worth more than the fix.** This was already diagnosed + correctly on 2026-08-18 as follow-up 4 of + `complete/2026/08/uniform-prior-bounds-numpy-path.md` ("hygiene candidate: + skip-if-missing markers"), and the "environment-specific, not pre-existing" + correction was already written on 2026-08-17 in + `complete/2026/08/prior-support-clipper.md:218`. Both were right; both lived + only in completion records, which nothing reads on the way *into* a new task. + The false alarm therefore fired three more times after the right answer was + written down. A follow-up that stays in a record has no owner — file it as a + prompt or it does not exist. +- correction trail (records annotated in this pass with a dated `## Correction` + block rather than rewritten in place, per the prior-support-clipper precedent): + `multistart-gradient-resume-fom-sanity-check.md`, + `clipper-usage-in-search-summary.md`, `uniform-prior-bounds-numpy-path.md`. + Already correct and left alone: `covariance-interpolator-rng-seed.md` (the only + record that named the real `ModuleNotFoundError`) and + `prior-support-clipper.md`. +- prior art: `complete/2026/08/nautilus-1core-serial-pool.md` — the task that + *added* this test (PyAutoFit#1442 → #1443). The test itself is sound and still + guards the real fork-pool deadlock; only its environment assumption was missing. +- worktree: none — cloud session from a direct clone at `/home/user/pyautofit`, + with a py3.12 venv built three ways to isolate the dependency variable. + +## Original prompt + +# `@PyAutoFit` `[optional]`-dependency tests have no skip guards + +Type: test +Target: autofit +Difficulty: small +Autonomy: autonomous +Priority: normal +Status: issued 2026-08-22 as PyAutoFit#1511; PR #1512 open, CI green, awaiting review + +Not a defect on `main` — a test-hygiene gap that has been *repeatedly +misdiagnosed* as one. That misdiagnosis is the actual cost. + +## The finding + +`test_autofit/non_linear/search/nest/test_nautilus.py::test__single_core_builds_no_pool` +runs a real `search.fit`, which reaches `from nautilus import Sampler` +(`autofit/non_linear/search/nest/nautilus/search.py:238`). +`nautilus-sampler==1.0.5` ships **only** in the `[optional]` extra +(`pyproject.toml:85`), and the test carries **no skip guard**. + +CI installs `[optional]` — PyAutoHeart's `lib-tests.yml` does +`pip install "./$r[optional]"` — so CI never sees it. Every env installed +without those extras (cloud sandboxes, local venvs) gets a hard +`ModuleNotFoundError`. + +It is the only optional-sampler test in the suite without a guard. Precedent +is everywhere else: `test_blackjax_nuts.py:14`, `nest/nss/test_search.py:20`, +`test_arithmetic_jax_trace.py:6`, `test_fork_context.py:31`. + +`astropy` is the same class of noise: two modules fail *collection* on its +top-level import, and nine aggregator tests error on it at runtime +(`autofit/aggregator/file_output.py:101`, +`autofit/aggregator/summary/aggregate_fits.py:105,165`). + +## Why this was worth a task + +The single nautilus failure has been reported as "pre-existing on clean +`main`" in at least six completion records since 2026-08-16 — see the +correction trail below. Each session spent a control run re-disproving it, +and the wrong gloss propagated into PR bodies #1479 and #1480. Main is **not** +red: latest main CI (run 32546158666) is 2024 passed, 3 skipped, 0 failed on +3.12, 3.13 and the no-jax leg. + +## Evidence (untouched main @ `a639226`, py3.12) + +| env | result | +|---|---| +| no `nautilus-sampler` | `1 failed, 3 passed` — `ModuleNotFoundError` at `search.py:242` | +| `pip install nautilus-sampler==1.0.5`, same tree, no other change | `4 passed` | +| full suite, no optional extras | 2 collection errors → then 4 failed / 9 errors, **all** missing-`astropy` | + +## The fix + +Skip-if-missing guards in the house pattern — an `importlib.util.find_spec` +`skipif` marker, or `pytest.importorskip` where the import is module-level. +Tests only; no `autofit/` source touched. + +Verified three ways on the branch: + +- no extras at all — nautilus test skips with its reason: `3 passed, 1 skipped` +- no `astropy` — `1985 passed, 33 skipped, 0 failed, 0 errors` +- full `[optional]` extras (the CI env) — `2024 passed, 3 skipped`, **identical + to CI on main**, so the guards are inert where the deps exist and no + coverage is lost + +## Correction trail + +The claim "fails identically on the untouched tree — pre-existing, not this +change" is right about causation and wrong about `main`. Records carrying the +loose gloss: + +- `complete/2026/08/prior-support-clipper.md:152,218` — already issued the + correction ("read it as environment-specific"); the correct reading +- `complete/2026/08/covariance-interpolator-rng-seed.md:14` — the only record + that names the real `ModuleNotFoundError`; correct +- `complete/2026/08/uniform-prior-bounds-numpy-path.md:31,50` — follow-up 4 + proposed exactly this fix but it was never filed as a prompt, so nothing + acted on it; this task is that follow-up +- `complete/2026/08/multistart-gradient-resume-fom-sanity-check.md:14` — + "confirmed pre-existing on unmodified `main`"; wrong gloss +- `complete/2026/08/clipper-usage-in-search-summary.md:89` — "**pre-existing**"; + wrong gloss + +Once this merges, no env reproduces the failure and the gloss stops +recurring. + +## Prior art + +`complete/2026/08/nautilus-1core-serial-pool.md` — the task that *added* +`test__single_core_builds_no_pool` (PyAutoFit#1442 → #1443). The test itself is +sound and still guards the real fork-pool deadlock; only its environment +assumption was missing. diff --git a/complete/index.md b/complete/index.md index a8a75a31..bf25d158 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. -1072 records across 7 buckets. +1073 records across 7 buckets. ## Highlights @@ -123,6 +123,7 @@ _(curate hard-won records here — survives regeneration.)_ - [numba-first-call-garbage-psf-weighted-data](2026/08/numba-first-call-garbage-psf-weighted-data.md) - [numerical-hazard-profiling](2026/08/numerical-hazard-profiling.md) — Phase 1 established the reusable numerical-hazard profiling framework, typed risk measurements, reachability a… - [one-tap-dashboard-rollout](2026/08/one-tap-dashboard-rollout.md) — the pattern (a generated page + one-tap 📋 copy-for-Claude payloads, phone +- [optional-dependency-skip-guards](2026/08/optional-dependency-skip-guards.md) — `test_nautilus.py::test__single_core_builds_no_pool` had no skip guard - [organism-board-final-readmes](2026/08/organism-board-final-readmes.md) — close on record - [paper-management-pipeline](2026/08/paper-management-pipeline.md) — auto-closed on merge - [per-parameter-step-scaling](2026/08/per-parameter-step-scaling.md) diff --git a/dashboard.html b/dashboard.html index d9585e4a..00f7e868 100644 --- a/dashboard.html +++ b/dashboard.html @@ -38,7 +38,7 @@

📋 PyAutoMind Dashboard

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.

-

In flight 3 · Parked 3 · Planned 6 · Backlog 144 · markdown version

+

In flight 2 · Parked 3 · Planned 6 · Backlog 144 · markdown version

Start here

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

TRIAGE: needs manual review before routingmedium · safe · high

@@ -58,7 +58,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 #1501HOLD — do not start dev. Fix-or-delete hangs off the PyAutoFit#1498 logpdf-contract

-

@PyAutoFit [optional]-dependency tests have no skip guardsissue #1511PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, CI GREEN

Parked markdown version

diff --git a/dashboard.md b/dashboard.md index 35f15dcf..d1644d8e 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/`) | 3 | +| [In flight](#in-flight) (`active/`) | 2 | | [Parked](#parked) (`parked.md`) | 3 | | [Planned](#planned) (`planned.md`) | 6 | | [Backlog](#backlog) (`draft/`) | 144 | @@ -129,14 +129,6 @@ Issued — each has an open GitHub issue and usually a branch. The full record f
-
📋 @PyAutoFit [optional]-dependency tests have no skip guardsissue #1511 — PR OPEN — https://github.com/PyAutoLabs/PyAutoFit/pull/1512, CI GREEN - -``` -/start_dev active/17_optional_dependency_skip_guards.md -``` - -
-
📋 Hands hygiene: expired announcement dead code, unregistered modulesissue #249 — library-dev ```