PowerSolver Docs
Back to Wizard
This page belongs to the full documentation. You don't need it to plan: back to the essentials.

PowerSolver rule reference

Generated from powersolver-api/src/main/resources/rules/catalog.json — do not edit by hand. Run python -I powersolver-verify/render_rule_reference.py after changing the catalogue.

How every rule is evaluated

Every rule except unassigned_count looks only at fully assigned items: in basic mode every planning variable of the item has a value; in list mode the item is placed in some resource's list. Unassigned items are counted only by unassigned_count.

Value conventions

Lists: a JSON array, or text whose comma-separated parts (trimmed, empty parts dropped) are the entries. Comparison as text: both sides are turned into text first (JSON true/false become "true"/"false"). Times: an ISO local date-time such as 2026-06-01T09:00 (no zone), or a plain number; two times are compared only when both are date-times or both are numbers. Durations count in minutes.

Stay within capacity (capacity)

The total load given to a {variable_field} may not exceed its {capacity_property}.

Default severity: hard · Works with: basic variables

How a violation is counted: Per resource: total = round(sum of the assigned items' load) (load_property, or 1 when the param is omitted; added exactly, rounded once; a duration counts in hours); matches = sum over resources of max(0, total - capacity). Resources without capacity_property are unlimited. With resource_property instead of variable_field, the resources are the items whose ids the item names there (one or a list, any collection), and every fully assigned item adds its load to each of them. Such a rule reads only data: "Can this work?" reports it when the data breaks it.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldnoa planning variable idany—The resource variable. Give this or resource_property, not both.
resource_propertynoa property of the planned itemsscalar_or_listitem not checked by this ruleInstead of variable_field: the resource fixed in the data, as the id of an item (or a list of ids) of any collection, e.g. the lesson's teacher.
capacity_propertyyesa property of the values of variable_fieldintegeritem not checked by this ruleEach resource's capacity; absent means unlimited.
load_propertynoa property of the planned itemsnumberrejected (every item needs it)Each item's load (a number or a duration, in hours); when omitted every item counts 1.

Minimise cost (cost)

Keep the total cost of the chosen {variable_field} as low as possible.

Default severity: soft · Works with: basic variables

How a violation is counted: Penalty = sum over assigned items of max(0, round(weight x rate x quantity / scale)); quantity = 1 and scale = 1 when omitted.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldyesa planning variable idany—The costed resource variable.
rate_propertyyesa property of the values of variable_fieldnumberrejected (every item needs it)Cost per unit of each resource.
quantity_propertynoa property of the planned itemsnumberrejected (every item needs it)Units per item; 1 when omitted.
scalenoa numbernumber—Divides every cost, to keep money comparable with other goals; must be > 0. Default: "1".

Balance the load (load_balance)

Spread {entities} evenly across {variable}.

Default severity: soft · Works with: basic variables

How a violation is counted: For each value used, count c of items assigned to it; matches = sum of c squared. The lowest possible total for n items over k values is x*(q+1)^2 + (k-x)*q^2 with q = n div k, x = n mod k.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldyesa planning variable idany—The variable to balance.

Days in a row (max_consecutive_days)

A person or resource works at most a given number of days in a row.

Default severity: hard · Works with: basic variables

How a violation is counted: Per resource (the assigned value of variable_field, or each id the item names in resource_property), the calendar days on which its fully assigned items start (slot_start_property of the chosen time option, or the item's entity_start_property; several items on one day count once; items without a date-time start are not counted). matches = sum over each run of consecutive days of max(0, run length - max_days); penalty = weight x matches.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldnoa planning variable idany—The person or resource variable. Give this or resource_property, not both.
resource_propertynoa property of the planned itemsscalar_or_listitem not checked by this ruleInstead of variable_field: the person or resource fixed on each item (an id or a list of ids).
slot_fieldnoa planning variable idany—The time variable, when the start comes from the chosen time option.
slot_start_propertynoa property of the values of slot_fielddatetimeitem not checked by this ruleWhen each time option starts.
entity_start_propertynoa property of the planned itemsdatetimeitem not checked by this ruleInstead of slot_field: when each item starts.
max_daysyesa numberinteger—The most days in a row (e.g. 5).

Enough people per time slot (min_coverage)

Every {slot_field} gets at least the number of {entities} its {required_property} asks for.

Default severity: hard · Works with: basic variables

How a violation is counted: Per option of slot_field (every one, including options nobody is placed in): covered = the number of fully assigned items placed in it or, with entity_hours_property and slot_start_property, the items whose interval [start of their option, + hours) contains the option's start (a duration counts in hours, so PT4H = 4). Options without a numeric required_property ask for nothing. matches = sum over options of max(0, required - covered); penalty = weight x matches.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
slot_fieldyesa planning variable idany—The time variable whose options carry the demand.
required_propertyyesa property of the values of slot_fieldintegeritem not checked by this ruleHow many items each time option needs; absent = none.
slot_start_propertynoa property of the values of slot_fielddatetimeitem not checked by this ruleWhen each time option starts; needed with entity_hours_property.
entity_hours_propertynoa property of the planned itemsnumberrejected (every item needs it)Each item's length in hours: it covers every option starting during it. Omitted = an item covers only its own option.

Minimum rest (min_rest)

Two {entities} of the same person or resource leave at least the minimum rest between them.

Default severity: hard · Works with: basic variables

How a violation is counted: Per resource (the assigned value of variable_field, or each id the item names in resource_property), one match per pair of its fully assigned items whose gap - from the end of the earlier to the start of the later, in either order; negative when they overlap - is shorter than min_rest_hours. Times come from the chosen time option (slot_field with slot_start_property and slot_end_property) or from the items (entity_start_property and entity_end_property); items without both times are not checked. Penalty per match = weight x missing rest in whole hours rounded up.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldnoa planning variable idany—The person or resource variable. Give this or resource_property, not both.
resource_propertynoa property of the planned itemsscalar_or_listitem not checked by this ruleInstead of variable_field: the person or resource fixed on each item (an id or a list of ids).
slot_fieldnoa planning variable idany—The time variable, when the times come from the chosen time option.
slot_start_propertynoa property of the values of slot_fielddatetimeitem not checked by this ruleWhen each time option starts.
slot_end_propertynoa property of the values of slot_fielddatetimeitem not checked by this ruleWhen each time option ends.
entity_start_propertynoa property of the planned itemsdatetimeitem not checked by this ruleInstead of slot_field: when each item starts.
entity_end_propertynoa property of the planned itemsdatetimeitem not checked by this ruleInstead of slot_field: when each item ends.
min_rest_hoursyesa numbernumber—Minimum rest between two items, in hours (e.g. 11).

Keep a number low (minimize_property)

Keep the total {property} as low as possible.

Default severity: soft · Works with: basic, list variables

How a violation is counted: Penalty = weight x round(sum over assigned items of value) - the values are added exactly and only the total is rounded; matches = assigned items with a numeric value. A duration counts in hours (PT20M = 0.33). The value must be placement-dependent (a derived shadow) to influence the plan.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
propertyyesa derived shadow or a property of the planned items (shadow kinds: derived, index, property)numberrejected (every item needs it)A derived shadow (or numeric item property) to minimise.

No double-booking (no_conflict)

No two {entities} may share the same {variables}; with {group_property}, only {entities} that share one of its values (e.g. the same class) are compared.

Default severity: hard · Works with: basic variables

How a violation is counted: Items are grouped by the combination of their values for all listed variables (items with any empty value are ignored); each group of k > 1 items gives k - 1 matches. With group_property, an item is counted once in each group it names (one value or a list; duplicates count once; items without it are ignored), so items clash only when they share a group and all listed values.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
fieldsyesa list of planning variable idsany—The variables whose combined values must be unique, e.g. [person, time slot].
group_propertynoa property of the planned itemsscalar_or_listitem not checked by this ruleOptional: who takes part in each item, fixed in the data (e.g. the class, or the list of classes, attending a lesson). With [time slot] it means: a class never has two lessons at the same time.

Same topic at most once a day per group (no_subject_repeat_per_day)

A {group_property} may not have the same {category_property} twice on one {day_property}.

Default severity: hard · Works with: basic variables

How a violation is counted: Items are grouped by (group, category, day of the assigned slot); items missing any of the three are ignored; each group of k > 1 items gives k - 1 matches.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
group_propertyyesa property of the planned itemsstringitem not checked by this ruleWho attends (e.g. class).
category_propertyyesa property of the planned itemsstringitem not checked by this ruleThe topic (e.g. subject).
slot_fieldyesa planning variable idany—The time-slot variable.
day_propertyyesa property of the values of slot_fieldstringrejected (every item needs it)The day of each slot.

Limit per period (period_limit)

The total load of a person or resource in one period (a day, a week...) may not exceed its limit.

Default severity: hard · Works with: basic variables

How a violation is counted: Per resource (the assigned value of variable_field, or each id the item names in resource_property) and per period of period_days days (1 = calendar day, 7 = ISO week, Monday to Sunday), total = round(sum of the fully assigned items' load) (load_property, or 1 when omitted; added exactly, rounded once; a duration counts in hours, so PT12H = 12). An item belongs to the period its start falls in (slot_start_property of the chosen time option, or the item's entity_start_property); items without a date-time start are not counted. Limit = the resource's limit_property, else max_load; with neither the resource is unlimited. matches = sum over resources and periods of max(0, total - limit); penalty = weight x matches.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldnoa planning variable idany—The person or resource variable. Give this or resource_property, not both.
resource_propertynoa property of the planned itemsscalar_or_listitem not checked by this ruleInstead of variable_field: the person or resource fixed on each item (an id or a list of ids).
slot_fieldnoa planning variable idany—The time variable, when the start comes from the chosen time option.
slot_start_propertynoa property of the values of slot_fielddatetimeitem not checked by this ruleWhen each time option starts.
entity_start_propertynoa property of the planned itemsdatetimeitem not checked by this ruleInstead of slot_field: when each item starts.
period_daysyesa numberinteger—Length of the period in days: 1 = a calendar day, 7 = an ISO week (Monday to Sunday).
limit_propertynoa property of the values of variable_fieldnumberitem not checked by this ruleEach resource's own limit per period; when absent, max_load applies.
max_loadnoa numbernumber—The limit per period for resources without limit_property; omitted = unlimited.
load_propertynoa property of the planned itemsnumberrejected (every item needs it)Each item's load (e.g. its hours); when omitted every item counts 1.

Do prerequisites first (precedence)

An {entity} starts only after the {entities} it depends on.

Default severity: hard · Works with: basic variables

How a violation is counted: One match per ordered pair (a, b) where b's depends_on_property lists a's id, both are assigned, and a's slot time is not strictly before b's. An item that lists its own id is ignored (no self-dependency). Penalty per match = weight x (1 + whole days by which a starts at or after b; whole units for numeric times), so a slightly broken order costs less than a badly broken one.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
slot_fieldyesa planning variable idany—The time-slot variable.
value_propertyyesa property of the values of slot_fielddatetimerejected (every item needs it)The time of each slot.
depends_on_propertyyesa property of the planned itemsid_listitem not checked by this ruleIds of the items that must come first.

Honour preferences (preference)

Give each {entity} a {variable_field} that prefers it.

Default severity: soft · Works with: basic variables

How a violation is counted: One match per item whose assigned value states a preference (non-empty value_property list) that does not contain the item's entity_property (comparison as text).

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldyesa planning variable idany—The variable holding the person/resource.
entity_propertyyesa property of the planned itemsstringitem not checked by this ruleThe item's attribute (e.g. shift type).
value_propertyyesa property of the values of variable_fieldscalar_or_listitem not checked by this ruleWhat each value prefers.

Never use protected options (protected_slot)

No {entity} may use a {variable} marked {value_property}.

Default severity: hard · Works with: basic variables

How a violation is counted: One match per item whose assigned value has value_property = true (JSON boolean).

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldyesa planning variable idany—The variable to check.
value_propertyyesa property of the values of variable_fieldbooleanuses the default (false)true marks a protected value; absent means not protected.

Keep special resources for items that need them (resource_exclusivity)

A {variable} with a special capability only takes {entities} that need it.

Default severity: hard · Works with: basic variables

How a violation is counted: Reserved capabilities = capabilities some item requires (all items count, assigned or not). One match per item whose assigned value offers at least one reserved capability while the item requires none of the reserved capabilities that value offers.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldyesa planning variable idany—The variable holding the resource.
entity_propertyyesa property of the planned itemsscalar_or_listitem not checked by this ruleWhat each item needs.
value_propertyyesa property of the values of variable_fieldscalar_or_listitem not checked by this ruleWhat each resource offers.

Respect unavailability (resource_unavailable)

A {variable_field} is never used when it is unavailable.

Default severity: hard · Works with: basic variables

How a violation is counted: One match per item whose assigned resource lists, in unavailable_property, the assigned slot's slot_property value (comparison as text). With resource_property instead of variable_field, the resources are the items whose ids the item names there (one or a list, any collection): one match per item when any of them is unavailable.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldnoa planning variable idany—The resource variable. Give this or resource_property, not both.
resource_propertynoa property of the planned itemsscalar_or_listitem not checked by this ruleInstead of variable_field: the resource fixed in the data, as the id of an item (or a list of ids) of any collection, e.g. the lesson's teacher.
slot_fieldyesa planning variable idany—The time-slot variable.
slot_propertyyesa property of the values of slot_fieldstringrejected (every item needs it)What is compared (e.g. day).
unavailable_propertyyesa property of the values of variable_fieldlistitem not checked by this ruleThe resource's unavailable list (on the variable's options, or on the items named by resource_property).

Grouped items share a value (same_value_in_group)

{entities} with the same {group_property} must get the same {variable}.

Default severity: hard · Works with: basic variables

How a violation is counted: Assigned items are grouped by their group_property value (items without it are ignored); within a group, items are grouped again by their value of variable_field; a group whose items hold d > 1 different values gives d - 1 matches.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldyesa planning variable idany—The variable the grouped items must share, e.g. the time slot.
group_propertyyesa property of the planned itemsstringitem not checked by this ruleThe item property naming the group, e.g. crew.

Capability must match (skill_match)

The {variable} given to each {entity} must have what the {entity} needs.

Default severity: hard · Works with: basic variables

How a violation is counted: One match per item whose assigned value does not have every required capability (required = list of the item's entity_property; capabilities = list of the value's value_property; comparison as text). Items with no requirement never match. With resource_property instead of variable_field, the resources are the items whose ids the item names there (one or a list, any collection): one match per item when any of them lacks a required capability. Such a rule reads only data: "Can this work?" reports it when the data breaks it.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldnoa planning variable idany—The variable holding the person/machine/room. Give this or resource_property, not both.
resource_propertynoa property of the planned itemsscalar_or_listitem not checked by this ruleInstead of variable_field: the resource fixed in the data, as the id of an item (or a list of ids) of any collection, e.g. the lesson's teacher.
entity_propertyyesa property of the planned itemsscalar_or_listitem not checked by this ruleWhat each item needs.
value_propertyyesa property of the values of variable_fieldscalar_or_listitem not checked by this ruleWhat each value offers.

Within the allowed time window (time_window)

Each {entity} must be scheduled between its {entity_start_property} and {entity_end_property}.

Default severity: hard · Works with: basic variables

How a violation is counted: One match per item whose assigned value's time is before the item's start bound or after its end bound. A missing bound is no bound.

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldyesa planning variable idany—The time-slot variable.
value_propertyyesa property of the values of variable_fielddatetimerejected (every item needs it)The time of each slot.
entity_start_propertyyesa property of the planned itemsdatetimeitem not checked by this ruleEarliest allowed time.
entity_end_propertyyesa property of the planned itemsdatetimeitem not checked by this ruleLatest allowed time.

Everything gets a value (unassigned_count)

Every {entity} must get a {variable}.

Default severity: hard · Works with: basic, list variables

How a violation is counted: One match per item that has no value for the variable (basic: the variable is empty; list: the item is in no resource's list).

ParamRequiredPoints toValue typeIf an item lacks itMeaning
variable_fieldnoa planning variable idany—The basic variable to check. Omit for a list variable.
inverse_fieldyes, unless variable_field is givena derived shadow or a property of the planned items (shadow kinds: inverseRelation)any—List mode only: the inverse-relation shadow naming the item's resource. Defaults to 'host'.