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/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/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/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)