satisfactory¶
satisfactory is constraint solving as a service. You submit a planning problem, a roster of shifts to staff or a day of deliveries to route, and get back a solution, or follow the stream of improving ones while it solves. The solving is done by Timefold Solver, and the service runs as two ankka services on any ankka installation.
The API is a reimplementation of the Timefold Platform's model API: the same vocabulary, paths, statuses and delivery rules, diverging only with a reason, and every divergence is written down. A client written against Timefold's platform will find the same shape here.
The shape, in five lines¶
- A model is a planning problem type, compiled Java behind a small interface. A request names a model and carries a dataset: the problem's input and how long to solve it.
- Datasets are immutable, with lineage. Changing the problem creates a new dataset derived from the old one; the old one keeps its solution.
- Every dataset is an event sourced entity that is the source of truth for its status and best solution. Workers pull datasets from a queue, solve them, and report each improvement with a fenced lease, so a worker that dies mid-solve costs seconds, not the solve.
- Results arrive by webhook in production, by server-sent events during development, or by polling.
- An ankka application uses it through ankka-satisfactory: agent tools generated from the model's catalog, a verifier for the webhook, and a fake for tests.
A dataset's life¶
POST /api/models/employee-scheduling/v1/schedules 202 { "id": "…", "solverStatus": "DATASET_CREATED" }
SOLVING_SCHEDULED queued for a worker
DATASET_VALIDATED the model checked the input
DATASET_COMPUTED the input's own score and metrics
SOLVING_STARTED
SOLVING_ACTIVE improving solutions arrive
GET …/schedules/{id}/events one frame per improvement, score and status
GET …/schedules/{id} the best solution so far, with KPIs
SOLVING_COMPLETED the webhook fires
Where to start¶
- Trying it. Run it on your machine starts the whole system in one process; Your first solve submits a demo dataset with curl and watches it improve.
- Understanding it. How satisfactory works is the overview. Models and datasets, Lineage instead of mutation and Receiving results are the three ideas everything else follows.
- Calling it. Submit and poll is the request in full, Stream progress and Receive webhooks the two other ways to get results, and Use the client does all of it from Scala.
- From an ankka application. From an ankka application: an agent submits with generated tools, a workflow owns the wait, the webhook resumes it.
- Adding a model. Write a model.
- Running it. Deploy on ankka and Operate the service.
- Looking something up. The Model API, the Platform API, the two models (employee scheduling, vehicle routing), and the glossary.
- Checking what is missing. Limitations.
For models and agents¶
This documentation is published in forms a model can read directly. llms.txt at the site root lists
every page with a one-sentence description, llms-full.txt holds every page in one file, and each page
is also served as Markdown at its own path with a .md suffix. The same pages ship as agent skills in
the satisfactory plugin of the ankka marketplace.
Work with a coding agent sets that up.