The OPM language
Procedural links
Procedural links join a process and an object on the same board, and say what the process does to the object. They are what a run follows. Each is drawn below as the board draws it, with the sentence Spoletta writes for it.
Drawing a link
Inputs enter a card at its top, outputs leave from its bottom, and each state of an object has handles of its own. Drag from one handle to another:
- Object → process makes an input link: the process takes the object.
- Process → object makes an output link: the process yields the object. A process links to a given object only once.
- Dropping on a state's row links that state; dropping on the card's body still connects.
Select an input link to choose how the process takes the object: takes, instrument or consumes. To delete a link, select it and press the delete key.
Transforming links
What the process does to the object itself: makes it, uses it up, or changes it.
Result: the process creates the object
The everyday output link. Once Draft succeeds, Notes exists, and processes waiting for it can run. Drawn to a state, it creates the object in that state: “Draft” yields “Notes” as “draft”.
Consumption: the process uses the object up
Once taken, the object is gone: no later process gets it until something generates it again. Only one process may consume a given object.
Effect: the process changes the object
The process both takes and yields the same object. An agent sees it marked as affected, its to change, and what it hands in is the new version.
Enabling links
What the process needs but does not change.
Instrument: needed, not changed
A reference the process reads and must leave alone. Its link ends in a hollow circle. An agent is told it is an instrument.
Agent: a person carries the process out
A person object taken by a human process. Its link ends in a filled circle. Only people given the Editor role (or admins) can decide that review; see People in the loop.
Event and condition
A link out of one of an object's states makes the process care about the state. It comes in two flavours, chosen on the selected link: when it enters or only if in it.
Event: entering the state triggers the process
Write runs whenever Post enters weak, and only then. Several event links on one process are alternatives: any one triggers it. This is how review loops send work back.
Condition: run only if the object is in the state
The link counts as an ordinary input for readiness, and is marked c. Once the process is ready the state is checked: if the object isn't in it, the process is skipped and what it would have generated is settled as absent. Use conditions for if/else branches that rejoin.
Looking up stored records
Query: take what earlier runs stored
An agent's or script's input link to a stored object (or a shared one) can carry a query. The process then gets the records that runs ending done stored of the object, rather than the object in this run, as a JSON array in the object's shape. The array may be empty. The link is labelled records.
Set it in the process's panel, under Stored records: tick Look up stored Review, then narrow it down.
| Setting | Picks |
|---|---|
| Where | Records whose fields hold a rule, written as a state's, such as score >= 4 and kind == "bug". Left empty, all of them. |
| State | Records in one state, or In any state. |
| Order | Newest first or Oldest first. |
| At most | How many records, 20 by default and 100 at most. With 1 it is the latest record, or the first. |
A query doesn't make the process wait, nor does it make it run: what else it takes, the start or a next does that. What this run stored isn't among the records. A query must be the process's only link taking that object, and it names no state and consumes nothing.
Deciding a state
Decision: the process picks the state
An agent's or a person's link to the object itself (not one of its states) can list states to choose between. Select the link and press the pill on it (Decide a state for an agent, Choose states for a person) to pick them.
If the process also takes the object, it is a review: the object keeps its content and only gains a state. “Critic” decides whether “Post” is “good” or “weak”. A human process's link with no states picked reads Filled in: the person fills the object in instead.
Connections between processes
OPM links processes only through objects. Spoletta adds three connections a running system needs, drawn between processes.
Start: where a run begins
Every board has one Start node. Drag from it to the process a run begins with; a new link replaces the old. Without one, nothing runs, and the Run button stays disabled.
Failure: a process handles another's failure
Drag from one process onto another. When the source fails (after its retries), the handler runs instead of the run failing. Only agent, script and Sentry processes can have one. See Handling failure.
Next: run right after, whatever objects say
Ordering without data, written in setup files as next. Prefer data links: if the second process needs what the first made, link it to that object instead. A next out of a human process is not followed.
All links at a glance
| Link | Drawn as | Sentence |
|---|---|---|
| Result | process → object, arrow | “P” yields “O”. |
| Takes | object → process, arrow | “P” takes “O”. |
| Consumption | arrow labelled consumes | “P” consumes “O”. |
| Effect | arrows both ways | “P” affects “O”. |
| Instrument | hollow circle at the process | “P” requires “O”, which it doesn't change. |
| Agent | filled circle, from a person | “Person” handles “P”. |
| Event | from a state's pill | “O” entering “s” triggers “P”. |
| Condition | from a state's pill, marked c | “P” occurs if “O” is “s”, and is skipped otherwise. |
| Query | object → process, labelled records | “P” looks up the latest 20 stored records of “O”. |
| Failure | red dashed, process → process | “H” handles a failure of “P”. |