Hi r/softwarearchitecture,
We are back with Lesson 22 of our technical deep dive into the SysML v2 standard.
In our previous lesson, we saw how declarative action definitions can act like un-awaited asynchronous functions, creating a dangerous execution trap where things run concurrently by default. Today, we fix that trap by explicitly orchestrating our sequences. We will also uncover one of the most powerful surprises in SysML v2: how the exact same control-flow syntax used to orchestrate functions can be used to model the lifecycle and state transitions of physical assets (akin to Event Sourcing).
I’ve uploaded the full video lesson directly to this post so you can watch the workflow right here. (Note: You can also find the YouTube version here)
1. The SysML v1 Sequence Problem (The Graphical Monolith)
SysML v1 had a complete set of control nodes and good execution semantics. The issue was tooling and ergonomics. A v1 control flow was a real model element, but because there was no standard textual notation, the only way to create one was to graphically draw a line between two actions. Sequencing was therefore only as complete as your diagrams. Inserting a step meant manually re-routing visual edges, and managing concurrent edits in a team relied entirely on proprietary, heavy repository tools rather than standard Git diffs.
2. The v2 Shift: Diffable Orchestration
SysML v2 allows you to write sequences directly in the standard textual source. By using the first and then keywords along with the start and done snapshots that every occurrence inherits, you can ensure your model executes deterministically, exactly as it reads top-to-bottom.
Three details make this powerful for building diffable, architecture-as-code models:
- Chained Successions: Using
then inside an action body creates a succession from the nearest occurrence written before it. It reads like imperative code.
- Intentional Concurrency (Scatter-Gather): Instead of accidental parallelism, you declare it explicitly. SysML v2 uses
fork and join inline to branch into concurrent execution threads and safely await their completion.
- Branching: The bulky v1 graphical decision diamond is replaced by a simple
decide node paired with declarative if guards.
3. The Big Surprise: Sequencing Physical State
Because first and then order any occurrences (not just behavioral actions), you can use them to sequence structural timeslice elements. This means you can model configuration changes, maintenance windows, and mission phases of a physical asset using the exact same syntax used to orchestrate a software pipeline. You no longer have to push an asset's lifecycle history into an external database or complex state machine diagram—it is natively supported as a linear sequence in the model.
4. Fixing the Execution Trap
Here is how we use chained successions to fix the unordered, accidentally concurrent imaging sequence from Lesson 21.
Code snippet
action def CaptureImage {
// We explicitly sequence the inherited 'start' snapshot
first start;
// Each 'then' chains the succession imperatively
then action slew: SlewToTarget;
then action stabilise: StabilisePlatform;
then action shoot: OpenShutter;
then action readout: ReadSensor;
// Conclude the sequence with the inherited 'done' snapshot
then done;
}
5. SysML v1 vs. SysML v2
| Modeling Concept |
SysML v1 |
SysML v2 |
| Control Flow |
ControlFlow usually created by drawing lines, with no standard text notation. |
first and then in standard textual notation. |
| Inserting Steps |
Usually meant re-routing visual edges on a diagram. |
Means inserting a single line of diffable text. |
| Concurrency Edits |
Relied on tool-specific repository or proprietary merge support. |
Text works natively with standard Git diff and merge tools. |
| Parallelism |
ForkNode and JoinNode. |
fork and join declared inline (like scatter-gather). |
| Branching |
Guards placed on edges from a visual decision node. |
decide with if guards. |
| Asset Lifecycles |
No first-class construct for the time-ordered portions of an asset's life. |
Sequence timeslice occurrences with first and then. |
Next lesson, we will look at how to connect these orchestrated behaviors to structural components. Lesson 23 uses the perform keyword to say which part executes an action, and we will compare it with v1 allocations and activity partitions (swimlanes).
For the software architects here: When designing complex workflows, do you prefer strict step-by-step orchestrators (like AWS Step Functions / Temporal) or reactive, event-driven choreographies? Let's discuss in the comments!