Fundamentals 1: stages, plan fragments and milestones
The three container-ish constructs in CMMN look similar on a canvas and behave completely differently at runtime. Getting them straight first makes everything else easier.
The case plan model
Section titled “The case plan model”Every case has exactly one case plan model (<casePlanModel>), the outermost container. It is the case’s own boundary: when it completes or terminates, the case is over.
Structurally it is a stage — the CMMN schema types it as one, and Orvanta compiles it to the same internal kind — so everything below about stages applies to it too. Two things are specific to it:
- It is the only container with no enclosing plan item, so an exit criterion placed on it terminates the whole case rather than one branch of it.
- It is what
@autoCompleteon the case as a whole attaches to.
Orvanta compiles exactly one <case> per document — the first, unless one is named. Three of the 968 Flowable corpus documents carry more than one; only the first is compiled, matching what a deploy path would do.
Stages
Section titled “Stages”A stage (<stage>) is a phase of the case: a container holding its own plan items, its own sentries, and nested definitions. Stages nest, and Orvanta allows 32 levels of nesting before the parser’s input budget refuses the document.
A stage’s runtime behaviour:
- It activates its children when it becomes active. Children with entry criteria wait for them; children without start immediately.
- It completes when its children do — the rules are involved enough to have their own page.
- It honours
@autoComplete, its own exit criteria, and both@exitTypeand@exitEventTypeon those criteria.
Orvanta’s engine executes stages. This is one of the constructs that genuinely runs.
Stage overview
Section titled “Stage overview”Flowable drives a runtime “stage overview” panel from flowable:includeInStageOverview (311 of 968 corpus files) and flowable:displayOrder (62). Orvanta’s parser captures both attributes and the editor exposes Show in stage overview as a stage property, so the information survives a round trip.
There is no case view to render it in. The engine crate derives the ordered overview from a compiled model, but no surface displays it. See Coming from Flowable.
Plan fragments — the one with no runtime existence
Section titled “Plan fragments — the one with no runtime existence”A plan fragment (<planFragment>) looks like a stage on a canvas. It is not one.
A plan fragment has no runtime existence at all. It creates no instance, holds no state, emits no lifecycle events, and cannot carry sentries of its own. It is visual grouping — a way of drawing a box around related plan items so a human reading the diagram can see they belong together.
Orvanta’s engine implements this faithfully: a plan fragment’s plan items are hoisted into the enclosing stage and the fragment itself disappears. Anything that would have watched the fragment has nothing to watch.
The practical consequences:
- You cannot attach an entry or exit criterion to a plan fragment and expect it to gate the contents. Put the criterion on each plan item, or use a real stage.
- A sentry cannot watch a plan fragment’s
completeevent, because it never emits one. - A plan fragment does not delay or group completion. Its children count toward the enclosing stage’s completion exactly as if the fragment were not drawn.
If you want a box that does something at runtime, you want a stage. Plan fragments appear in only 6 of the 968 corpus documents, which is roughly how often they are the right answer.
Milestones — available, then completed
Section titled “Milestones — available, then completed”A milestone (<milestone>) marks that something has been achieved. It carries no work: a milestone has nothing on it but an id, a name and an item control.
The behaviour that surprises people:
A milestone never reaches
active. It goesavailable→completeddirectly.
Orvanta’s engine drives this as an internal start-plus-occur in a single pass, so a milestone is never externally observed in active. If you are writing something that polls plan-item state and expects to see a milestone running, it will never see it — it will see available, and then it will see completed.
That is not an Orvanta quirk; it is CMMN’s lifecycle, transcribed from Flowable’s own PlanItemInstanceState.
Using a milestone
Section titled “Using a milestone”Because a milestone completes the instant its entry criteria are satisfied, it is a signal, not a step. The idiom is:
- Give the milestone an entry criterion whose sentry watches the tasks that constitute the achievement.
- Give downstream plan items entry criteria whose sentries watch the milestone’s
occurevent.
That second half is why occur is the second-most-common on-part event in the corpus (307 of ~1,005) — milestones and user event listeners are what emit it. See Sentries.
Milestones appear in 87 of the 968 corpus documents, and Orvanta’s engine executes them.
Summary
Section titled “Summary”| Construct | Runtime instance? | Reaches active? | Can carry a sentry? | Orvanta |
|---|---|---|---|---|
casePlanModel | Yes | Yes | Exit criterion terminates the case | Executes |
stage | Yes | Yes | Yes, entry and exit | Executes |
planFragment | No | No | No | Flattened into the parent stage |
milestone | Yes | No — available → completed | Yes, entry and exit | Executes |
Fundamentals 2: tasks and plan items — the plan-item/definition split, the task types, and the full twelve-state lifecycle.