Skip to content

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.

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 on a stage or the case plan model (29 corpus files) relaxes exactly one thing:

Under autoComplete, non-required items sitting in available or enabled are 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 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.

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.

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.

flowable:parentCompletionRule (55 corpus occurrences) gives finer control than the completion-neutral flag. Orvanta executes all six values:

ValueThe child is ignored for parent completion…
defaultNever — normal blocking behaviour
ignoreAlways
ignoreIfAvailableWhen it is available
ignoreIfAvailableOrEnabledWhen it is available or enabled
ignoreAfterFirstCompletionOnce it has completed at least once
ignoreAfterFirstCompletionIfAvailableOrEnabledOnce 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”.

The idiom worth learning, because it is not obvious from any single rule:

Manual activation + autoComplete on 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.

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.

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.

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).

RuleEffectOrvanta
BaselineWaits for anything not in an end stateExecutes
autoCompleteIgnores non-required available/enabled itemsExecutes
flowable:autoCompleteConditionExpression instead of a flagExecutes for the decidable subset; otherwise refused
requiredRuleBlocks the parent even under autoCompleteExecutes
completionNeutralRuleNever blocks; ignored when availableExecutes
parentCompletionRuleSix-way control over blockingExecutes, all six values
${cmmn:isStageCompletable()}Reads the container’s completable flagExecutes, refreshed every cycle
Case reactivationReopen a closed caseRefused

That is the five-part fundamentals series. From here: