In this note

A team has two tasks to finish between 09:00 and 10:00. One needs analytics skills; the other needs support skills. Avery can do either, so assigning both to Avery might look reasonable in a written plan. It also asks Avery to do two one-hour jobs in the same hour.

That failure has a precise check. You don't need a model to debate whether double-booking is acceptable. Write the capacity rule, reject the plan, and find an assignment that satisfies it. A model may still help interpret the original request or explain the result, if those jobs need language interpretation.

The hypothetical example runs offline and checks every assignment in a small set of possibilities. Its people, rates, and availability are teaching inputs. No model is called and nobody is scheduled.

Write the rules before asking for a plan

The metric-report task needs analytics skills; access-check needs support skills. Both take one hour and must start at 09:00. Assign each task to one qualified person, and give nobody two tasks at that time. These are hard constraints: rules every acceptable plan must obey, however cheap another plan looks.

Hypothetical workers, availability, and declared USD assignment rates
WorkerInputs for the scheduling exercise
AveryAnalytics and support; available 09:00 and 10:00; $80 for a one-hour assignment
BlairAnalytics; available 09:00; $60 for a one-hour assignment
CaseySupport; available 09:00; $70 for a one-hour assignment

Among plans that obey the rules, we want the lowest total assignment rate. The rates are accounting inputs for this exercise; a lower total does not establish a cash saving. Your team may care more about speed, fairness, continuity, or keeping a specialist free. Ask the person responsible for the schedule to choose the objective and settle conflicts between goals.

Avery is also available at 10:00, so the input lists that possible slot. It cannot solve this problem: both tasks must start at 09:00. A real schedule would need more rules, such as timezone, breaks, dependencies, uncertain task lengths, and what completion means. This small example leaves those out.

A valid format can contain an impossible schedule

A deliberately invalid proposal: two jobs, one worker, one slot
[
  { "task_id": "metric-report", "worker_id": "Avery", "slot": "09:00" },
  { "task_id": "access-check", "worker_id": "Avery", "slot": "09:00" }
]

Both rows use known identifiers. Avery has both skills. Each task appears once. Those checks all pass, yet the schedule is infeasible because the same worker is occupied twice. The validator checks that relationship across rows. Checking each row's format in isolation would miss it.

The downloadable module checks missing or repeated tasks, unknown workers, wrong skills, unavailable people, and incorrect times. It also rejects extra fields. A proposal cannot add allow_double_booking and thereby change the rule that checks it. That protects this local input; it does not supply a production permission system.

Structural validation tells you whether fields have an allowed shape. Check the business meaning and cross-record constraints separately.

See the difference between shape and correctness

Compare the feasible assignments

Each task has three workers and two possible slots to try: six choices. Across two tasks, that makes 6 × 6 = 36 assignments before checking the rules. This is small enough to try every one, a method called enumeration. The program rejects the invalid schedules, prices the remaining three, and keeps every plan tied for the lowest cost.

All three feasible schedules in the declared teaching problem
Assignments, both at 09:00Declared total cost
Metric report: Avery; access check: Casey$80 + $70 = $150
Metric report: Blair; access check: Avery$60 + $80 = $140
Metric report: Blair; access check: Casey$60 + $70 = $130

The lowest total is $130. If we instead gave the report to the first available qualified person, Avery, Casey would do the access check and the total would be $150. Both plans work; one costs more under these rates. We haven't run a model comparison, so this says nothing about which plan a particular model would choose.

Run the downloaded module with Node.js from its directory
node --input-type=module -e 'import { scheduleProblem, solveTinySchedule } from "./tiny-schedule.mjs"; console.log(solveTinySchedule(scheduleProblem));'

// Key results: candidateCount 36; feasibleCount 3; bestCost 130.
// bestPlans assigns metric-report to Blair and access-check to Casey.

Before pricing any proposal, a separate checker tests it against the rules. Separate teaching tests check the lower-cost choice, equal-cost ties, and an impossible requirement; those tests are not included in the module download. They establish how the program handles these inputs and tested variants. They cannot tell you whether an organization's scheduling rules are right.

Have someone who does the work check the inputs. Recording a two-hour task as one hour gives the program the wrong problem to solve. So does forgetting travel time. Keep the source of each duration, availability window, and skill requirement. Check those facts before trusting even the cheapest valid plan.

Handle a problem with no valid plan

Change the support task to require a skill nobody has. The program returns zero valid plans, a null best cost, and an empty list of best plans. It cannot quietly move the task, substitute a different skill, or drop the work. A person with authority to change staffing, scope, or the deadline must decide what happens next.

If that person changes a rule, save the old request and the reason, then solve and check the new version. Equal-cost plans may need another criterion or a human choice. Choosing alphabetically is repeatable, but repeatability alone doesn't make it fair or useful.

Before putting a real plan into operation, the receiving software must check current availability, permissions, input versions, and any required approval, then confirm the saved assignment. Someone may have become unavailable since planning. This download has no dispatch connection or credentials and cannot make an assignment.

Keep interpretation and optimization separate

A request such as ‘use the usual analyst unless the customer needs the specialist’ is not ready for a solver. A model could help spot the missing definitions and draft questions. Someone still needs to identify the usual analyst, define specialist, and say whether this is a preference or a strict rule. Confirm those answers before solving.

A direct assignment or simple rule may be enough. Use a solver when you need to compare valid plans against a stated objective. Trying every possibility won't scale indefinitely: this teaching program refuses more than 50,000 candidates. That is its own limit, not a recommended default. Test a suitable solver on your actual kinds of rules, time limits, and impossible requests before relying on it.

Take one planning task and write its assignments, times, skills, capacity, objective, and person who can change the rules. Decide what happens if no plan works. Then give the checker a deliberately impossible plan and verify that it rejects it before comparing ways to find a valid one.

Back to notes