Fundamentals 5: stage and case completion
“When is this stage finished?” is the question CMMN answers least obviously, because the answer depends on four separate rules that interact. This page works through them in the order the engine does.
Baseline completion
Section titled “Baseline completion”Without any rules at all:
A stage or case completes when no child is in an active state and none is required.
“Active state” is the engine’s grouping — it excludes the terminal states (completed, terminated, failed) and the other end states (unavailable, disabled, wait_repetition).
The part that catches people: a child sitting in available or enabled is still blocking. It has not finished, it has not been declined, and it has not been ruled out — so by default the stage waits for it, possibly forever.
That is what autoComplete exists to change.
autoComplete
Section titled “autoComplete”@autoComplete on a stage or the case plan model (29 corpus files) relaxes exactly one thing:
Under
autoComplete, non-required items sitting inavailableorenabledare ignored for the purposes of completion.
So a stage with autoComplete="true" finishes as soon as everything actually running has finished, without waiting for optional work nobody started.
Orvanta executes autoComplete.
flowable:autoCompleteCondition
Section titled “flowable:autoCompleteCondition”Flowable lets the autocomplete decision itself be an expression rather than a flag. Orvanta executes it for the decidable subset and refuses anything outside it at deploy. Three of 967 corpus documents are blocked here.
requiredRule — the veto
Section titled “requiredRule — the veto”A <requiredRule> (30 corpus files) marks a plan item as mandatory.
A required item blocks its parent’s completion even under
autoComplete.
That is the whole point of it: autoComplete says “don’t wait for optional work”, and requiredRule is how you declare that a particular piece of work is not optional. The two are designed to be used together.
A <requiredRule> with no <condition> means “always required”, not “unset”. Orvanta models the rule and its condition as separate optional things so that distinction survives — a rule that is present but conditionless is a different thing from no rule at all.
Orvanta executes requiredRule.
completionNeutralRule
Section titled “completionNeutralRule”A <completionNeutralRule> (31 corpus files) says “this item does not affect whether the parent can complete”. Orvanta executes it, with one specific behaviour worth knowing: it is ignored when the instance is available.
parentCompletionRule
Section titled “parentCompletionRule”flowable:parentCompletionRule (55 corpus occurrences) gives finer control than the completion-neutral flag. Orvanta executes all six values:
| Value | The child is ignored for parent completion… |
|---|---|
default | Never — normal blocking behaviour |
ignore | Always |
ignoreIfAvailable | When it is available |
ignoreIfAvailableOrEnabled | When it is available or enabled |
ignoreAfterFirstCompletion | Once it has completed at least once |
ignoreAfterFirstCompletionIfAvailableOrEnabled | Once it has completed at least once, and it is now available or enabled |
The last two are for repeating items: “this repeats, but the stage should not wait around for a further repetition that may never come”.
Genuinely optional work
Section titled “Genuinely optional work”The idiom worth learning, because it is not obvious from any single rule:
Manual activation +
autoCompleteon the parent = genuinely optional work.
Give the plan item a <manualActivationRule> so it stops at enabled and waits for a person, and give its stage autoComplete="true" so an enabled non-required item is ignored for completion.
The result is a piece of work that:
- appears on the case as something a person may do,
- can be started by hand at any point while the stage is open,
- can be explicitly declined (
disable) and later re-enabled if someone changes their mind, and - never blocks the stage from finishing if nobody touches it.
Without autoComplete, the enabled item blocks the stage forever. Without manual activation, the item just starts on its own and is not optional at all. You need both halves.
${cmmn:isStageCompletable()}
Section titled “${cmmn:isStageCompletable()}”The one built-in function Orvanta implements. It reads the containing stage’s completable flag — that is, “would this stage complete right now, if nothing were holding it”.
Orvanta refreshes the flag every evaluation cycle, so the value is current at the moment it is read rather than a snapshot from stage activation.
The standard use is on a user event listener, so that a “Finish this stage” button only becomes available once the stage genuinely could finish:
<userEventListener id="def_finish" name="Finish review" flowable:availableConditionExpression="${cmmn:isStageCompletable()}" />Orvanta executes flowable:availableConditionExpression on event listeners, including this built-in. An event listener held back by its available-condition sits in unavailable and is moved to available by the initiate transition when the condition turns true — and back again by dismiss if it turns false.
cmmn:isStageCompletable() is the only function call in the decidable subset. Every other method call is refused at deploy.
Exit as an alternative to completion
Section titled “Exit as an alternative to completion”A stage does not have to complete — it can be exited. Which downstream sentries see depends on the exit criterion’s @exitEventType, and which children go with it depends on @exitType. Both are covered on Sentries.
The one to remember: a sentry watching complete will not see a plain exit. If you exit a stage and expect the next one to start, set exitEventType="complete" on the exit criterion.
Case reactivation is refused
Section titled “Case reactivation is refused”CMMN’s reactivate transition brings a closed case back to life. Orvanta refuses case reactivation at deploy, and the reactivate transition is modelled but never driven.
The reason is that the transition’s landing state depends on the shape of the model, and no reactivation driver exists to decide it. Guessing would produce a case in a state its author never described.
<reactivateEventListener> is likewise recognised by name and refused — it appears zero times as an element name in the corpus (earlier counts for it were matching element ids, not tags).
Summary
Section titled “Summary”| Rule | Effect | Orvanta |
|---|---|---|
| Baseline | Waits for anything not in an end state | Executes |
autoComplete | Ignores non-required available/enabled items | Executes |
flowable:autoCompleteCondition | Expression instead of a flag | Executes for the decidable subset; otherwise refused |
requiredRule | Blocks the parent even under autoComplete | Executes |
completionNeutralRule | Never blocks; ignored when available | Executes |
parentCompletionRule | Six-way control over blocking | Executes, all six values |
${cmmn:isStageCompletable()} | Reads the container’s completable flag | Executes, refreshed every cycle |
| Case reactivation | Reopen a closed case | Refused |
That is the five-part fundamentals series. From here:
- Supported CMMN elements — the full support table and every refusal.
- Authoring a case model — the editor.
- Coming from Flowable — what Flowable has that Orvanta does not.