Floor the optimal-design budget at k + 1 on the pyoptex path (deflakes CI) - #531
Merged
kgdunn merged 13 commits intoAug 29, 2026
Merged
Conversation
…ptex path The point-exchange fallback already raises a budget below k + 1 to k + 1 (the smallest run count that can estimate the main-effects model), and the tests document that clamp as the contract. The pyoptex path passed the budget through unclamped, and pyoptex handles an infeasible run count unpredictably, which made test_budget_clamped_to_minimum_model_size fail intermittently across unrelated PRs. Apply the same floor in the d-, i-, and a-optimal dispatchers, except when the requested budget cannot even hold the fixed_runs, so that validation still raises on the requested value. Part of the DOE cluster tracked in #513. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
…floor The mcp floor accompanies the mcp 2.x server port from #528 included in the previous commit; both no-op once #528 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
kgdunn
pushed a commit
that referenced
this pull request
Aug 29, 2026
…p test is deterministic test_budget_clamped_to_minimum_model_size fails intermittently because the pyoptex path never implemented the documented k + 1 budget floor; ported verbatim from #531, no-ops once it merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
10 tasks
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
The exchange loop grows the design only when an addition improves the criterion, and a candidate consumed by a replacement is never considered for addition, so an unlucky shuffle ended below number_points on roughly 1 to 2% of unseeded runs; this is the actual mechanism behind the intermittent 'assert 3 >= 4' in the D-optimal dispatch test (the dispatcher-level budget floor in the previous commit is necessary for the contract but not sufficient, because the shortfall happened inside point_exchange itself). Complete the design greedily with the remaining candidates that best preserve D-optimality; measured 500/500 correct sizes after the fix versus 492/500 before. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
kgdunn
pushed a commit
that referenced
this pull request
Aug 29, 2026
The dispatcher budget floor alone was not sufficient: the shortfall happens inside point_exchange, which could end below number_points on 1 to 2% of unseeded runs. Ported verbatim from #531; no-ops once it merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
Seeds 122, 146, 199, 319, and 338 ended with 3 rows under the pre-fix algorithm, so they cover the greedy completion loop that codecov flagged as untested; the low seeds keep the ordinary path covered. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
…in point_exchange optimization_function guarded only the exactly singular case via LinAlgError; a numerically singular X'X passes np.linalg.inv and its garbage inverse can carry an exactly zero determinant, scoring log|det| = -inf. Under the lower-is-better convention that ranked the singular design as unbeatable, so no replacement or addition could ever improve on it: this froze the exchange loop (the underlying mechanism of the run-count shortfall) and let the new completion step pick a rank-deficient row (the pinned regression seeds caught it via a non-finite d_opt). Map any non-finite score to +inf, matching the existing convention for the exactly singular case. Verified 300/300 unseeded runs and all pinned seeds now return full-rank, correctly sized designs with finite scores. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
kgdunn
pushed a commit
that referenced
this pull request
Aug 29, 2026
Completes the earlier port: non-finite scores from a numerically singular X'X now read as unacceptable rather than unbeatable, which was the underlying freeze behind the run-count shortfall. No-ops once #531 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
…e-library-issues-hr7xxk-doeclamp # Conflicts: # CHANGELOG.md # CITATION.cff # pyproject.toml
…e-library-issues-hr7xxk-doeclamp # Conflicts: # CHANGELOG.md # CITATION.cff # pyproject.toml
…e-library-issues-hr7xxk-doeclamp # Conflicts: # CHANGELOG.md # CITATION.cff # pyproject.toml
kgdunn
pushed a commit
that referenced
this pull request
Aug 29, 2026
test_budget_clamped_to_minimum_model_size failed intermittently on this PR's CI (macOS, assert 3 >= 4) in code this PR does not touch. Root cause and fix are in #531 (a k+1 budget floor on the pyoptex path, a greedy run-count completion in point_exchange, and a singular-design scoring guard); ported verbatim here so this PR's CI is deterministic. No-ops once #531 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
12 tasks
kgdunn
pushed a commit
that referenced
this pull request
Aug 29, 2026
test_budget_clamped_to_minimum_model_size fails intermittently on any PR's CI (macOS, assert 3 >= 4) in code this PR does not touch. Root cause and fix are in #531; ported verbatim so this PR's CI is deterministic. No-ops once #531 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
kgdunn
pushed a commit
that referenced
this pull request
Aug 29, 2026
test_budget_clamped_to_minimum_model_size fails intermittently on any PR's CI (macOS, assert 3 >= 4) in code this PR does not touch. Root cause and fix are in #531; ported verbatim so this PR's CI is deterministic. No-ops once #531 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU
kgdunn
added a commit
that referenced
this pull request
Aug 29, 2026
* Publish real per-tool JSON Schemas from the MCP server (#506) The MCP server built every tool from an async (**kwargs) closure and assigned __annotations__ / __defaults__ afterwards, which cannot add parameters to a function that has none. Every registered tool was therefore published to MCP clients with an empty inputSchema: no parameter names, types, required/optional split, enums, or bounds. Registration now constructs explicit Tool objects whose `parameters` field, the schema the server publishes verbatim, is exactly the registry's spec["input_schema"] from get_tool_specs(). Argument validation stays where it always lived: execute_tool_call validates against each tool's real pydantic input model, so the hand-built FuncMetadata passes arguments through unchanged. The server now targets the MCP 2.x SDK (mcp.server.mcpserver.MCPServer, renamed from 1.x's FastMCP); the installed `mcp>=1.0` pin already resolved to 2.x, under which the old `from mcp.server.fastmcp import FastMCP` failed at import (and was mypy's one standing error). The `mcp` extra now pins `mcp>=2.0`, and the module is no longer omitted from coverage measurement (100% covered by the new tests, which also compare every published schema against the registry through the real list_tools() path). Drive-by from #513: the concurrent-dispatch test asserted on wall-clock elapsed time and could flake on loaded CI runners; it now proves the overlap with a barrier both in-flight calls must reach. Version 1.73.2; CITATION.cff and CHANGELOG.md updated in step. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the point_exchange/pyoptex-budget deflake from #531 test_budget_clamped_to_minimum_model_size failed intermittently on this PR's CI (macOS, assert 3 >= 4) in code this PR does not touch. Root cause and fix are in #531 (a k+1 budget floor on the pyoptex path, a greedy run-count completion in point_exchange, and a singular-design scoring guard); ported verbatim here so this PR's CI is deterministic. No-ops once #531 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU --------- Co-authored-by: Claude <noreply@anthropic.com>
kgdunn
added a commit
that referenced
this pull request
Aug 29, 2026
…least-privilege jobs (#507) (#525) * fix(release): close the dispatch, SBOM, and Makefile holes in the publish pipeline (#507) The ENG-21 gate promised that a typo in pyproject.toml on main cannot ship a release, but three paths around the gate remained. This closes them: - publish.yml: the version guard now also runs on workflow_dispatch, which becomes a republish-only path: the checked-out commit must already carry the v<version> tag for the version in pyproject.toml. - publish.yml: the build job additionally asserts CHANGELOG.md has a matching "## [X.Y.Z]" heading (mirroring the extraction regex), and the notes-extraction step fails loudly instead of silently falling back to auto-generated notes. - publish.yml: gh release create passes --target with the SHA of the checked-out commit (HEAD, not GITHUB_SHA, since a dispatch run may check out inputs.ref), so the release tag lands on the published commit rather than the default branch head. - publish.yml: the SBOM is generated from a fresh venv containing only the built wheel and its runtime closure, with pip/setuptools/wheel removed; cyclonedx-bom runs from a separate tooling venv so build tooling no longer ships as runtime components. - publish.yml: permissions are per-job. The build job, which executes repo code via PEP 517 hooks, holds only contents: read; id-token, contents, and attestations write scopes stay on the publish job. - publish.yml: pypa/gh-action-pypi-publish is pinned to the commit SHA that release/v1 resolves to (v1.14.2) instead of the mutable branch. - Makefile: the release target no longer builds or publishes; it prints the tag-gated release instructions and exits nonzero. Version 1.73.3; CITATION.cff and CHANGELOG.md updated in step. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the mcp 2.x migration from #528 so typecheck is green The typecheck gate is red on main itself: the unpinned mcp extra now resolves to mcp 2.x, where FastMCP was renamed MCPServer, so mypy fails on mcp_server.py on every branch. This ports the migrated server and the mcp>=2.0 floor verbatim from #528; the diff no-ops once #528 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the point_exchange/pyoptex-budget deflake from #531 test_budget_clamped_to_minimum_model_size fails intermittently on any PR's CI (macOS, assert 3 >= 4) in code this PR does not touch. Root cause and fix are in #531; ported verbatim so this PR's CI is deterministic. No-ops once #531 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU --------- Co-authored-by: Claude <noreply@anthropic.com>
…e-library-issues-hr7xxk-doeclamp # Conflicts: # CHANGELOG.md # CITATION.cff # pyproject.toml
kgdunn
added a commit
that referenced
this pull request
Aug 29, 2026
…at can fail (#508, #510, #511) (#529) * fix(experiments): bound the remote dataset fetch with an explicit timeout pd.read_csv(url) carries no timeout, so distillateflow() / oildoe() against a black-holing host blocked the caller indefinitely (#508). _read_remote_csv now fetches with urllib.request.urlopen(url, timeout=...) into a buffer and hands that to pandas. The default of 30 s lives on the config settings singleton as dataset_fetch_timeout, overridable via PROCESS_IMPROVE_DATASET_FETCH_TIMEOUT or a caller argument. Timeouts and URL errors still surface as the documented RuntimeError naming the URL. An on-disk cache stays out of scope. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * test(perf): replace non-asserting benchmarks with deterministic ENG-18 assertions The tests in tests/perf/ contained no assertions, had no stored baseline, and pytest-benchmark disables itself under the default -n auto, so a 100x slowdown passed green while the docstrings claimed regression tracking (#511). Option 2 from the issue: assert the cost-shape properties the ENG-18 lazy-frame work actually needs protected. The public DataFrame views are built exactly once and then cached (identity plus a counted single build), pickling excludes the cache and the views rebuild correctly, repeated transform / predict / diagnose calls cause zero lazy-frame rebuilds, and check_random_state passes a Generator through by identity while resolving an int seed to a fresh generator with bit-identical draws. Verified the new tests fail when the _LazyFrame cache write is removed. CONTRIBUTING.md's performance-regression policy now describes this honestly; the ENG-15 wall-clock benchmark CI job stays planned. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * test(experiments): skip the live openmv.net tests on the wrapped RuntimeError The loaders now wrap network failures (including timeouts) in the module's documented RuntimeError, so the offline skip helper must catch that too instead of failing when openmv.net is unreachable. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the mcp 2.x migration from #528 so typecheck is green The typecheck gate is red on main itself: the unpinned mcp dependency resolves to mcp 2.x, where FastMCP was renamed MCPServer, so mypy fails on src/process_improve/mcp_server.py. This ports the #528 fix verbatim (mcp_server.py plus the mcp>=2.0 pin in both pyproject.toml occurrences) so this PR's CI can pass on its own. It becomes a no-op once #528 merges; this PR's own version bump and CHANGELOG entries for #508/#510/#511 are in a separate commit. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * test: make the ENG-29 test tiers real with strict markers and measured slow marks The tiers were documented but unused: -m 'not slow' deselected almost nothing and -m 'not dataset' still hit the network (#510). - pytest.ini addopts gains --strict-markers, so a typo'd marker is a collection error instead of a silent warning. - test_pca_foods in tests/test_multivariate.py, the one test fetching from openmv.net, now carries @pytest.mark.dataset; a tests/ sweep for urlopen / openmv / http found no other unmarked network fetches. - 42 tests measured at >= 5 s with --durations on this runner now carry @pytest.mark.slow (threshold is 2 s per CONTRIBUTING.md; the margin keeps the marks honest on faster machines). The two end-to-end tests crossing library boundaries (sensory pipeline, sklearn halving grid search) also carry @pytest.mark.integration. - Wall clock: full suite 6:15, -m 'not slow and not dataset' 1:32 on the same runner. - Both CI test jobs run plain pytest with no -m filter, so every tier still executes in CI. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * chore: bump version to 1.73.4 with citation and changelog in sync PATCH bump for the #508/#510/#511 test-hygiene fixes. CITATION.cff carries the same version and today's date-released; CHANGELOG.md gains the 1.73.4 section and updated link footer. The version assumes the earlier queued 1.73.x PRs merge first. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * test: bind both accesses to names in the loadings cache-identity assertion CodeQL flags a self-comparison; two named reads assert the same cache-identity property without the identical-values pattern. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the optimal-design budget floor from #531 so the flaky clamp test is deterministic test_budget_clamped_to_minimum_model_size fails intermittently because the pyoptex path never implemented the documented k + 1 budget floor; ported verbatim from #531, no-ops once it merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the point_exchange run-count completion from #531 The dispatcher budget floor alone was not sufficient: the shortfall happens inside point_exchange, which could end below number_points on 1 to 2% of unseeded runs. Ported verbatim from #531; no-ops once it merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the point_exchange singular-design scoring guard from #531 Completes the earlier port: non-finite scores from a numerically singular X'X now read as unacceptable rather than unbeatable, which was the underlying freeze behind the run-count shortfall. No-ops once #531 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU --------- Co-authored-by: Claude <noreply@anthropic.com>
…e-library-issues-hr7xxk-doeclamp # Conflicts: # CHANGELOG.md # CITATION.cff # pyproject.toml
kgdunn
added a commit
that referenced
this pull request
Aug 29, 2026
…ic multiblock starts, one TPLS T2 (#502, #503, #504) (#530) * Make NIPALS convergence scale-relative across PCA, PLS, MBPCA and MBPLS terminate_check compared the raw norm of the change between successive score vectors against an absolute tolerance, so whether the loop converged depended on the magnitude of the data: large-magnitude X burned every md_max_iter iteration, tiny X converged instantly. The criterion is now the relative form already used by TPLS's _has_converged: the norm of the change divided by the norm of the current vector, floored via _nz so a fully-deflated all-zero score vector cannot divide by zero. The signature and the md_tol settings key are unchanged; md_tol is now interpreted as a relative tolerance. The MBPCA and MBPLS inner loops get the same relative criterion, and their absolute default tolerances at machine precision (eps**(9/10) and eps**(6/7)), which as relative tolerances sit below the floating-point oscillation floor, become the shared epsqrt default used by PCA, PLS and TPLS. In the same loops, the hard-coded np.random.default_rng(0) start for the MBPCA super-score and the MBPLS u vector is replaced by a deterministic seed from the column with the largest sum of squares, the way single-block PCA / PLS already seed (#195): no RNG remains in these fit paths, satisfying the reproducibility contract (the determinism tests for #503 follow in the next commit). Fitted components are unchanged up to the existing sign convention. Fixes #504. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * Add determinism tests for the multiblock deterministic NIPALS start MBPCA and MBPLS previously seeded their NIPALS super-score / u initialisation from a hard-coded np.random.default_rng(0), violating the reproducibility contract in docs/development/reproducibility.rst, and exposed no random_state. The previous commit removed the RNG from both fit paths in favour of a deterministic seed from the column with the largest sum of squares, matching single-block PCA / PLS (#195), so no random_state parameter is needed at all. These tests pin the contract: repeated fits are bit-identical, and no non-convergence warning fires on well-conditioned data. Fitted components on the reference and oracle suites are unchanged up to the existing sign convention. Fixes #503. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * Compute one Hotelling's T2 in TPLS, shared by fit() and diagnose() TPLS.fit() computed a full-Mahalanobis T2 over the super-scores with the covariance divided by N, shape (n_obs, 1), while diagnose() computed the cumulative diagonal form, shape (n_obs, n_components): two different statistics under one name, compared against one limit. Both now use the cumulative per-component form sum_a (t_a / s_a)^2 already used by PCA and PLS, which is what the class docstring promised, matches the sibling estimators, and extends to new observations without the training covariance. The score standard deviations (scaling_factor_for_scores, which also feeds ellipse_coordinates) use the unbiased N - 1 divisor, the estimator the F-distribution form in hotellings_t2_limit is derived for; the previous N divisor inflated T2 by N / (N - 1) and drew score ellipses slightly too small. The pinned test values change accordingly: the training super-scores are orthogonal (normalized off-diagonal cross-products ~1e-17), so the old full-Mahalanobis values equal the diagonal form with the N divisor, and the new pins are exactly the old ones times (N - 1) / N = 104 / 105. A new test asserts fit() and diagnose() return the same T2, at the same shape, for the same rows. Fixes #502. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * Bump version to 1.74.0 and add the changelog entry for #502/#503/#504 MINOR bump: all three fixes change numerical results or iteration behaviour, because the previous values were wrong. CITATION.cff is kept in sync in the same commit. The version assumes the queued sibling PRs land first in order. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * Appease ruff: rename a shadowing loop variable and apply formatting Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the mcp 2.x migration from #528 so typecheck is green The typecheck gate is red on main itself: the unpinned mcp dependency resolves to mcp 2.x, where FastMCP was renamed MCPServer, so mypy fails on src/process_improve/mcp_server.py. This ports the #528 fix verbatim (mcp_server.py plus the two mcp>=2.0 requirement bumps) and no-ops once #528 merges. The version bump and changelog entries for #528 are deliberately not taken here. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * Always run the first NIPALS iteration; relax one kernel-vs-NIPALS rtol Two CI follow-ups on the scale-relative convergence rework (#504). The PCA / PLS loops prime their convergence check with a seed offset of +1.0. Under the relative criterion that offset can be negligible for a large-magnitude seed column (a fuzzed Y entry of ~1.9e154), so the loop reported convergence before its first iteration: PLS then raised UnboundLocalError for the never-assigned t_a through the fit_pls tool boundary, and PCA would have silently returned the unrefined seed as the score with an all-zero loading. Both loops now force the first iteration with an explicit itern == 0 check, restoring the pre-rework behaviour on such inputs, and a deterministic (non-hypothesis) regression test pins the fuzz payload. test_adaptive_pls_initial_matches_batch_ldpe compared kernel-PLS and NIPALS beta coefficients at the assert_allclose default rtol of 1e-7; the relative stopping rule now ends the batch fit once successive score iterations agree to epsqrt (~1.49e-8) relative accuracy, and the agreement on this fixture sits at 1.07e-7 relative on one of 70 elements. Both solvers are converged to their own criteria, so that one assertion is relaxed to rtol=1e-6 with an explanatory comment; nothing else is loosened. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU * fix: port the point_exchange/pyoptex-budget deflake from #531 test_budget_clamped_to_minimum_model_size fails intermittently on any PR's CI (macOS, assert 3 >= 4) in code this PR does not touch. Root cause and fix are in #531; ported verbatim so this PR's CI is deterministic. No-ops once #531 merges. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019C3XXbJkuSYH9fMryLqNcU --------- Co-authored-by: Claude <noreply@anthropic.com>
…e-library-issues-hr7xxk-doeclamp # Conflicts: # CHANGELOG.md # CITATION.cff # pyproject.toml
…e-library-issues-hr7xxk-doeclamp # Conflicts: # CHANGELOG.md # CITATION.cff # pyproject.toml
…e-library-issues-hr7xxk-doeclamp # Conflicts: # CHANGELOG.md
kgdunn
deleted the
claude/process-improve-library-issues-hr7xxk-doeclamp
branch
August 29, 2026 09:29
63 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
tests/test_designs_screening_optimal.py::test_budget_clamped_to_minimum_model_size(assert 3 >= 4) has been failing intermittently across unrelated PRs (ECharts adapter correctness and honest visualization tests (#509, #512) #526's first run, Test hygiene: dataset-loader timeouts, live test tiers, perf tests that can fail (#508, #510, #511) #529's current head). Root cause: themax(budget, k + 1)floor documented and tested as the dispatcher contract exists only in the point-exchange fallback; with pyoptex installed (as in CI),dispatch_d_optimal(budget=2)passed the infeasible run count straight to pyoptex, whose handling of it is unpredictable, sometimes returning 3 rows.k + 1floor in thed_optimal,i_optimal, anda_optimaldispatchers before either backend runs, except when the requested budget cannot even holdfixed_runs, so that validation still raises on the requested value (test_fixed_runs_must_leave_room_to_optimizekeeps passing).Test plan
uv run pytest tests/test_designs_screening_optimal.py --no-cov: 21 passed, 5 consecutive runs (previously intermittent)uv run pytest tests/test_designs_optimal_pyoptex.py tests/test_design_generation.py tests/test_augment_design.py tests/test_designs_screening_optimal.py --no-cov: 200 passedruff check .,ruff format --check .,mypy src/process_improvecleanChecklist
pyproject.toml(PATCH for fixes/docs/config, MINOR for new features)ruff check .passesCHANGELOG.mdupdatedGenerated by Claude Code