Skip to content

fix(termination)!: apply every criterion, literal time limits, no hidden limit - #183

Merged
blackopsrepl merged 3 commits into
mainfrom
feature/174-termination
Nov 4, 2026
Merged

blackopsrepl merged 3 commits into
mainfrom
feature/174-termination

Conversation

@blackopsrepl

Copy link
Copy Markdown
Collaborator

Closes #174. Base main @ 51e1bcaf, three commits:

  • df48d5a7 make time_limit literal and saturating
  • 9a27c3bc apply every configured solver termination criterion
  • fb8a0e0e add no hidden time limit

Gate on fb8a0e0e (fmt, clippy -D warnings, doc-names file-length facade-reachability public-api deps, rustdoc -D warnings, examples, workspace all-feature tests, doctests): EXIT 0, 1521 passed, 0 failed, 65 result lines. Slice checks: df48d5a7 871 passed / 0 failed; 9a27c3bc 888 passed / 0 failed (clippy, rustdoc, public-api, config/solver/bridge/trybuild/facade tests). Mutation checks: the old time_limit fails time_limit_is_literal_and_saturating; dropping the step criterion fails every_configured_criterion_applies.

`seconds_spent_limit = 0` (or `minutes_spent_limit = 0`) meant no limit,
and `minutes_spent_limit * 60` could overflow. `TerminationConfig::time_limit`
is now `None` only when neither field is set, so zero is a limit of zero,
and the sum saturates at `Duration::MAX`.

BREAKING CHANGE: `seconds_spent_limit = 0` or `minutes_spent_limit = 0`
is now a zero time limit instead of no limit.
Solver-level `[termination]` honoured only the first of `best_score_limit`,
`step_count_limit`, `unimproved_step_count_limit` and
`unimproved_seconds_spent_limit`, paired with the time limit; the others
were silently ignored, while phase-level termination combined all of them.
`ConfiguredSolverTermination` now holds every configured criterion as its
own concrete termination and stops the solve at whichever is reached first.
It replaces `AnyTermination` and the tuple `OrTermination`. The candidate
trace execution policy lists every installed criterion.

BREAKING CHANGE: every configured solver-level termination criterion now
applies, combined with OR; a solve with several criteria can stop earlier
than before. The `solverforge.execution_policy` trace drops the
`criterion` and `criterion_target` attributes and gains one attribute per
criterion; `termination_composition` names every installed criterion.
A solve with a score or work criterion but no time limit was silently
capped at 30 seconds (60 for list models) by
`__solverforge_default_time_limit_secs`. The fallback is gone: nothing is
added that is not configured, so a score or work criterion without a time
limit runs without one. The generated function and the
`default_time_limit_secs` parameter of the run entrypoints are removed, and
the execution-policy trace no longer records a fallback.

Closes #174.

BREAKING CHANGE: a solve with `best_score_limit`, `step_count_limit` or an
unimproved limit but no `seconds_spent_limit`/`minutes_spent_limit` is no
longer capped at 30 or 60 seconds. `try_run_solver_with_config_and_search`,
`try_run_weighted_solver_with_config_and_search` and
`try_run_dynamic_solver_with_config_parts` lose their
`default_time_limit_secs` parameter. The `solverforge.execution_policy`
trace drops `configured_entrypoint_default_time_limit_ns`,
`effective_time_limit_ns` and `time_limit_source`.
@blackopsrepl
blackopsrepl merged commit fb8a0e0 into main Nov 4, 2026
12 checks passed
@blackopsrepl
blackopsrepl deleted the feature/174-termination branch November 4, 2026 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Solver termination: one criterion only, hidden 30/60 s guard, zero means unlimited

1 participant