solverforge-solver 0.12.1

Solver engine for SolverForge
Documentation
# solverforge-solver

`solverforge-solver` contains SolverForge's runtime phase assembly, move
implementations, selector builders, construction heuristics, local search, and
retained solver lifecycle.

## Grouped Scalar Reachability

Normal scalar construction is single-slot: each nullable scalar variable is
assigned independently through its descriptor/runtime scalar binding. That
behavior remains the default whenever a construction heuristic has no
`group_name`.

Use grouped scalar construction when a model has nullable scalar variables that
must change together before a hard-feasible state is reachable. A model declares
named `ScalarGroup` entries, and a construction heuristic opts in with
`group_name`. Candidate-backed groups evaluate a whole `ScalarCandidate` as one
compound scalar move, apply all legal edits atomically, and mark every touched
scalar slot complete through the normal committed mutation path.

Assignment-backed groups are declared with `ScalarGroup::assignment(...)` over
one nullable scalar target. They generate stock grouped construction candidates
for required and optional scalar assignments, use the same grouped selection
engine as candidate-backed groups, and support assignment-aware local-search
moves for required slots, capacity conflicts, reassignments, and bounded
sequence/position rematches.

`GroupedScalarMoveSelector` exposes the same declared groups during local search.
It is a first-class scalar neighborhood, not cartesian-product composition.

## Compound Conflict Repair

`CompoundConflictRepairMoveSelector` is the stock conflict-aware repair
primitive. Domain providers still supply candidate edit hints, but the framework
owns selector limits, duplicate filtering, legality checks, not-doable filtering,
hard-improvement filtering, scoring, tabu identity, and affected-entity
reporting through `CompoundScalarMove`.

Configured constraint keys resolve against scoring metadata by exact identity:
package-qualified constraints use `ConstraintRef::full_name()` strings, while
package-less constraints use the short name.

This keeps app-specific logic as domain candidate generation only. Applications
should not add seed repair, relaxed hard constraints, fake variables, or private
solver orchestration to make coupled scalar states reachable.