SOTER
BPMN Projection Implementation
Purpose
This document specifies the current SOTER BPMN projection pipeline: how Logos elements are mapped to BPMN constructs, how flow and gateways are inferred, and how the built-in and Graphviz layout engines place the resulting diagram.
It is the current engineering baseline. Treat it as authoritative over roadmap items, GH board issues, or broader product documentation when they disagree with what is implemented.
Primary implementation files:
analytics/projections/builder.pyanalytics/projections/adapters/bpmn.pyanalytics/projections/layout/bpmn_layout.pyanalytics/projections/projectors/mappings/bpmn.jsoncore/pipeline/__init__.pycli/cli.pyportal/portal/templates/settings.html
Scope
This document covers:
- the mapping from Logos/SVO entities to BPMN constructs via the Visual Graph Model (VGM),
- inference of BPMN sequence flow, message flow, gateways, and start/end events from data dependencies,
- rendering of BPMN data associations,
- the built-in topological layout and the optional Graphviz layout,
- known limitations of the current implementation.
Non-Goals
- This document does not restate why BPMN is treated as a projection rather than a source model; see BpmnExecutableVsNonExecutableAnalysis.md.
- It does not define notation-neutral projection mapping; see ProjectionMappingSpec.md.
- It does not define the SVO semantic model; see LogosSvoSemanticsSpec.md.
- It does not cover BPMN editor/modeler integration in Epiphany — not implemented.
- It does not cover execution semantics. Generated BPMN is not executable.
Terminology
| Term | Meaning |
|---|---|
| VGM | Visual Graph Model — the notation-agnostic geometry dataset produced before BPMN rendering. |
| Isolation boundary | The grouping (by default, pool) inside which sequence flow is legal; crossing it requires message flow. |
| Decision attribute | A Logos Action attribute (alternative, options, all) that selects a BPMN gateway type when multiple same-pool successors are inferred. |
| Data object cloning | A layout-level tactic that duplicates a data node's visual shape per connected activity without implying multiple semantic objects. |
Model or Contract
Subjects and Containers
Container-like elements define process boundaries and responsibility structure. The current mapping file is:
analytics/projections/projectors/mappings/bpmn.json
Important mappings:
{
"class = 'Subject' AND parent": "lane",
"class = 'Subject' AND ismember": "lane",
"class = 'Subject' AND NOT parent AND NOT ismember": "pool",
"type = 'system'": "pool"
}
A Subject becomes a BPMN pool or lane depending on its hierarchy and
membership attributes. Container resolution uses these parent attributes:
["parent", "performer", "system", "actor", "ismember"]
Actions and Tasks
Actions are rendered as BPMN work nodes:
{
"type = 'task'": "task",
"type = 'process' OR type = 'action' OR type = 'operation' OR class = 'Action'": "task",
"type = 'interaction'": "serviceTask"
}
An action can also carry a decision attribute, used when multiple
same-pool successors are inferred. Supported decision values:
alternative -> exclusiveGateway
options -> inclusiveGateway
all -> parallelGateway
Objects and Data References
Objects are mapped to BPMN data references:
{
"class = 'Object' OR type = 'artifact'": "dataObjectReference",
"type = 'datastore'": "dataStoreReference"
}
The renderer emits:
bpmn:dataObjectReferencebpmn:dataObjectbpmn:dataStoreReferencebpmn:dataInputAssociationbpmn:dataOutputAssociation
Layout Engines
The default layout engine is the built-in topological BPMN layout. It:
- groups flow nodes by topological generation,
- places sequence successors left-to-right,
- sizes pools and lanes from their contents,
- places data objects relative to their associated task,
- falls back safely for cyclic graphs.
This is the default because it is deterministic and requires no external dependencies.
SOTER also supports an optional Graphviz-based layout path, which depends on
dot being installed on the runtime host. If Graphviz is unavailable or
produces no coordinates, the pipeline falls back to the built-in BPMN
layout.
Rules
Flow inference
The VGMBuilder infers BPMN flow from data dependencies. The governing
relation pattern is:
ProducerTask --out--> Object --in--> ConsumerTask
From this, SOTER infers:
ProducerTask --> ConsumerTask
The inferred edge type depends on process isolation boundaries.
- Sequence flow. If producer and consumer are inside the same isolation
boundary, SOTER creates a BPMN sequence flow (
Task A --sequence--> Task B). By default, the isolation boundary is["pool"], so sequence flow is inferred inside the same pool. - Message flow. If producer and consumer are in different isolation
boundaries, SOTER creates a BPMN message flow (
Task A --message--> Task B) to avoid illegal cross-pool sequence flow.
Gateway inference
When one producer has multiple same-pool successors and the source task has
a supported decision value, SOTER injects a gateway:
Logos decision |
BPMN gateway |
|---|---|
alternative |
exclusiveGateway |
options |
inclusiveGateway |
all |
parallelGateway |
If no supported decision value is present, SOTER creates direct sequence flows.
Start and end event inference
- A start event is added for a task with no same-pool inbound inferred sequence flow.
- An end event is added for a task with no same-pool outbound inferred sequence flow.
These are projection artifacts. They do not have to exist as first-class Logos source elements.
Data associations
The BPMN renderer emits data associations from in and out dependencies:
a task with an input object gets a bpmn:dataInputAssociation; a task with
an output object gets a bpmn:dataOutputAssociation. The DI renderer also
creates bpmndi:BPMNEdge elements for rendered data associations.
Data object layout
- Input data objects are placed above the task.
- Output data objects are placed below the task.
- Multiple inputs/outputs attached to one task get horizontal offsets.
- Shared data objects are cloned per connected activity when needed, so one
data object is not visually pulled between multiple unrelated tasks. For
example, if
Documentis connected to three activities, SOTER keeps the original data node for the first activity and creates clone nodes for the remaining activity-specific associations.
Data object cloning is a visual/layout tactic. It does not mean the source model contains multiple semantic objects.
Examples
Gateway from a decision attribute
element ReviewApplication
class: Action
performer: Clerk
decision: alternative
in: Application[submitted]
out: Application[accepted], Application[rejected]
If the outputs are consumed by different follow-up actions in the same pool, the projection creates:
ReviewApplication -> exclusiveGateway -> successor actions
Data associations
element RegisterInvoice
class: Action
performer: Accountant
in: Invoice[received]
<bpmn:dataInputAssociation id="Assoc_In_...">
<bpmn:sourceRef>...</bpmn:sourceRef>
</bpmn:dataInputAssociation>
element RegisterInvoice
class: Action
performer: Accountant
out: Invoice[registered]
<bpmn:dataOutputAssociation id="Assoc_Out_...">
<bpmn:targetRef>...</bpmn:targetRef>
</bpmn:dataOutputAssociation>
End-to-end model
soter v1
element Clerk
class: Subject
name: Clerk
element Application
class: Object
name: Application
element ReceiveApplication
class: Action
performer: Clerk
out: Application[received]
element ReviewApplication
class: Action
performer: Clerk
in: Application[received]
out: Application[reviewed]
element ArchiveApplication
class: Action
performer: Clerk
in: Application[reviewed]
Expected BPMN projection:
start -> ReceiveApplication -> ReviewApplication -> ArchiveApplication -> end
The Application object appears as BPMN data references and data
associations:
ReceiveApplication --dataOutputAssociation--> Application[received]
Application[received] --dataInputAssociation--> ReviewApplication
ReviewApplication --dataOutputAssociation--> Application[reviewed]
Application[reviewed] --dataInputAssociation--> ArchiveApplication
Graphviz layout
Enable Graphviz layout explicitly:
soter genesis process.view --projector bpmn-io --bpmn-graphviz-layout
Disable it explicitly:
soter genesis process.view --projector bpmn-io --no-bpmn-graphviz-layout
Config/env equivalents:
bpmn_graphviz_layout=true
SOTER_BPMN_GRAPHVIZ_LAYOUT=true
Epiphany UI equivalent:
Settings -> Integrations -> BPMN Layout Engine -> Use Graphviz for BPMN Layout
Validation
Relevant test areas:
pytest tests/unit/projections/test_bpmn.py
pytest tests/unit/portal/test_portal_django.py
Full unit suite without browser E2E:
pytest tests/ --ignore=tests/e2e
E2E tests require a running Epiphany server and browser runtime.
Compatibility
The current implementation is functional but not final. Known limitations:
- the inferred process model depends on consistent
in/outobject naming, - object state parsing is still shallow in the projection layer,
- data object cloning is a layout-level tactic, not a semantic graph normalization step,
- Graphviz layout is optional and host-dependent,
- explicit BPMN editor/modeler integration in Epiphany is not implemented,
- some diagnostic scripts are still ad hoc and should be folded into normal test/dev tooling.
Open Questions
- When should the diagnostic scripts referenced above be folded into normal test/dev tooling?
- This document should be used to update
docs/02_spec/LogosSvoBpmnSemantics.md,docs/02_spec/Projections.md, roadmap/GH board items for BPMN projection maturity, and user-facing examples once the current docs reorganization is committed.
Related Documents
- ProjectionOverview.md - entry point for projection documentation.
- LogosOverview.md - Logos-side modeling context.
- ProjectionMappingSpec.md - notation-neutral mapping rules from Logos dependencies to projection targets.
- LogosSvoSemanticsSpec.md - SVO parser/compiler semantics behind this implementation.
- BpmnExecutableVsNonExecutableAnalysis.md - rationale for non-executable BPMN.
- TextToBpmnToolingAnalysis.md - external tooling analysis.
- DocumentationStyleGuide.md - writing profile and document-type rules.
- TechnicalSpecTemplate.md - technical document template.