Constraint-Based Scheduling, Explained in Plain Language
Rules engine and constraint solver get used interchangeably in scheduling software marketing. They're built on genuinely different ideas, and the difference shows up in the schedule you actually get.
"Our software uses smart scheduling logic" could mean two very different things underneath, and the difference matters more than most marketing pages let on. One is a rules engine. The other is a constraint solver. Both can produce a schedule. Only one of them is actually trying to find the best one.
What a rules engine does
A rules engine works through orders in some priority order, usually sorted by due date, and for each one, places it into the first slot that satisfies whatever rules are configured: the right line, enough hours, maybe a basic changeover allowance. Once it places an order, it moves on to the next one and doesn't go back.
This is fast, easy to understand, and easy to explain: "we sorted by due date and filled slots as we went." It's also greedy, in the technical sense: every decision is final the moment it's made, based only on what's already been placed, with no ability to reconsider an earlier choice in light of what comes later in the list.
Here's the practical problem with that. Imagine order A gets placed early in a slot that's technically fine for it, but that same slot would have been a much better fit for order C, which comes later in the queue and now has to go somewhere worse, dragging in an expensive changeover that a different arrangement could have avoided entirely. A rules engine has no mechanism to notice this and correct it. It made a locally reasonable choice for A and never revisits it, even though a different early choice would have produced a better week overall.
What a real constraint solver does
A constraint solver approaches the same problem completely differently. Instead of committing to placements one at a time and moving forward, it treats the whole week (all the orders, all the lines, all the eligibility and changeover rules) as one combined problem, and searches for an arrangement, or a structured proof about what's possible, that satisfies every hard constraint (a SKU only goes on a line that can actually run it, no double-booking a line) while optimizing for a goal, like minimizing total changeover time or maximizing the percentage of orders that ship on time.
This is the same category of technique used in problems like airline crew scheduling and complex factory-floor optimization: define what "valid" means, define what "good" means, and let a systematic search find an arrangement that satisfies the first and does well on the second, rather than accepting whatever a first-pass greedy pass happens to produce.
A useful analogy: a rules engine packs a suitcase by picking up items in whatever order they're sitting on the bed and shoving each one into the first available space. A constraint solver tries different arrangements, potentially rearranging things already placed, until it finds a packing that actually fits everything, or can tell you definitively that it doesn't and here's why.
Why "it can prove infeasible" actually matters
A real solver doesn't just produce a schedule. When the underlying problem genuinely has no valid solution, too many orders, not enough hours, conflicting hard constraints, it can determine that and say so, rather than quietly forcing something together and leaving you to discover the conflict later on the floor. That's a materially different, and more honest, kind of answer than a rules engine silently producing a schedule that technically fills every slot but violates a constraint nobody built a rule to catch.
The trade-off
None of this is free. Searching a combined solution space is more computationally demanding than working through a priority list once, and on a large enough problem, a solver can take a long time to return an answer, or fail to find a provably optimal one within a reasonable window. That's a real engineering trade-off, not a reason to dismiss the approach, but it does mean a system built this way needs a sane way to handle the case where the solver can't finish in time.
How RunMark handles this
RunMark's scheduler is built around a real constraint solver, not a priority-ordered rules engine. When it generates a proposed schedule, it's searching for a combined arrangement that respects line eligibility and avoids double-booking while optimizing for on-time delivery and changeover cost, not just placing orders one at a time and moving on. When the solver can determine the problem is infeasible, that gets surfaced rather than papered over.
Because a solver can occasionally take longer than is useful on a very large or unusual problem, RunMark falls back to a faster local-search heuristic when the solver is unavailable, errors, or doesn't return in time, and it records which engine actually produced a given proposal, so you're never looking at a heuristic result and mistaking it for an optimized one. That provenance is a small detail, but it's the honest version of the trade-off: a real solver most of the time, a clearly labeled fallback the rest of the time, rather than pretending every schedule was produced the same way.