Authoring schemas
This page is for contributors extending the Studyflow language with new element types or attributes. If you are a researcher or pipeline author using the modeler, see the Elements reference instead.
Studyflow uses direct moddle YAML as the authoring format for schema definitions. The schemas live in src/assets/schemas/ and ship with the modeler:
core.moddle.yaml– the core Studyflow language:Study,StartEvent,EndEvent,SequenceFlow, the abstractBaseElement/Activity/DataOperationActivitybases, and the data-infrastructure types (Dataset,DataStorage,DataCatalog,Schema,Array,Snapshot).cognitive.moddle.yaml– cognitive and behavioral elements (CognitiveTask,VideoGame,Rest,Questionnaire,Instruction,RandomGateway,StratifiedAllocationGateway,EligibilityGateway). Split out ofcoreso adopters can swap the cognitive layer without touching the core.behaverse.moddle.yaml,datatrove.moddle.yaml,galea.moddle.yaml,omniprocess.moddle.yaml– domain extensions you can enable from the modeler’s schema palette.
Core structure
Studyflow moddle YAML files follow this top-level layout:
name: Core
prefix: core
description: Core BPMN extension for modeling research processes.
uri: http://behaverse.org/schemas/studyflow/v1 # version segment = studyflow format version
icon: https://example.org/schema-icon.png # optional, shown in the modeler
xml:
tagAlias: lowerCase
associations: []
enumerations: []
types: []
examples: []The description is shown in the schema palette. The optional icon (URL or iconify <name>) appears next to the schema name. The uri is the stable identifier existing files are matched by – the core schema’s URI intentionally keeps studyflow even though its prefix was renamed to core.
Enumerations
enumerations define reusable closed value lists referenced from properties via type:.
enumerations:
- name: CompletionCodeTypeEnum
isAbstract: true
description: How the completion code is generated when the study ends.
literalValues:
- name: None
value: none
description: No completion code is issued.
- name: Static
value: static
- name: Dynamic
value: dynamicProperties typed with an enum can opt into free-text entry alongside the enum values by setting meta.editable: true.
Types and properties
Each moddle type defines a domain element plus the properties shown in the inspector. Two relationships compose types:
extends– pure mixin onto an existing BPMN class. Use it when you only want to add attributes to a BPMN base (e.g. extendbpmn:StartEventwithconsentFormUri) without creating a new visual element.superClass– class inheritance. Use it when defining a new concrete element. List the BPMN base first (e.g.bpmn:Task,bpmn:ExclusiveGateway,bpmn:DataStoreReference) and addbpmn:BaseElementso the inspector picks up the standard metadata fields.
Pair superClass with meta.bpmnType so the modeler knows which BPMN shape to render.
types:
- name: StartEvent
extends:
- bpmn:StartEvent
meta:
icon: iconify bpmn--start-event
properties:
- name: consentFormUri
description: Link to the consent form. Untick to skip the consent step entirely.
isAttr: true
type: String
meta:
pinned: false
optional: true
categories:
- Privacy
- name: RandomGateway
description: Randomly assigns participants to one of the outgoing branches.
superClass:
- bpmn:ExclusiveGateway
- bpmn:BaseElement
meta:
icon: iconify streamline-flex--dice-5
bpmnType: bpmn:ExclusiveGateway
properties:
- name: algorithm
isAttr: true
type: studyflow:AssignmentAlgorithmEnum
default: probabilistic
meta:
categories:
- AssignmentProperty modifiers
Property entries carry moddle behavior directly:
isAttr: true– serialized as an XML attribute in the BPMN XML form (most scalar properties). The YAML.studyflowformat maps every property to a plain key regardless of this flag.isBody: true– serialized as the element’s text body in the BPMN XML form. Used for free-form content like YAMLconfigurations.isMany: true– repeated property (rendered as a list in the inspector).default– initial value.redefines– override the type or default of an inherited property (e.g.redefines: bpmn:Process#isExecutable).replaces– replace an inherited property entirely.
Studyflow-specific modeler behavior lives under meta on the property:
meta.pinned: true– always visible in the inspector summary.meta.optional: true– the inspector shows a checkbox to opt the property in.meta.editable: true– enum properties also accept free-text entries.meta.categories: [Privacy]– tab the property lives under in the inspector.meta.condition.language: json+meta.condition.body: { otherField: value }– visibility predicate; the property only appears when other fields match. A value of$setmatches whenever the other field has any value.
Function calls (uses / with)
Any activity can declare the function that implements it, GitHub-Actions style. Two properties on the core studyflow:DataOperationActivity trait (which mixes onto every bpmn:Activity) carry the call:
uses– a scheme-prefixed reference,<scheme>://<ref>[@<version-or-digest>]. The runner recognizespython://(an importable callable, e.g.python://[email protected]),docker://(an image, e.g.docker://ghcr.io/lab/img@sha256:...), andhttps://(a script URL). Other schemes are allowed but flagged as unresolved. The ref/version split happens at the last@, so docker digests parse correctly.with– a YAML mapping of arguments passed to the function (GitHub Actions’with:block), carried as the text body of astudyflow:Withwrapper. The inspector edits it under the Execution tab and reveals it onceusesis set.
uses: python://[email protected]
with:
column: rt
fn: medianIn the BPMN XML form, uses is an attribute on the activity (studyflow:uses="...") and with is a <studyflow:with> child element holding the YAML as its body; both round-trip losslessly through the .studyflow YAML form. An activity that carries a uses value shows a function marker on the canvas. The reference runner resolves and validates the call (the uses grammar and that with parses as a YAML mapping) but does not execute it in the browser; execution is delegated to a downstream tool (a workflow engine, an evaluation harness, or a container runtime). See src/assets/examples/function_call_demo.studyflow for a worked example.
Examples
Schemas may define top-level examples entries that appear in the modeler create/append menus. Each entry uses object.type to identify the schema type to instantiate, plus any default property values to apply.
examples:
- description: Preprocess EEG data for a single subject.
object:
type: MapData
bpmn:name: Preprocess EEG (subject)
bpmn:documentation: Preprocess EEG data, including filtering, artifact removal, and normalization.
isDataOperation: true
icon: iconify icon-park--eegExample mixins
examples[].object.mixins lets an example compose additional defaults from other types. This is useful when the example should behave like a specialized BPMN shape without changing the underlying schema class.
examples:
- description: Preprocess EEG data for a single subject.
object:
type: MapData
bpmn:name: Preprocess EEG (subject)
bpmn:documentation: Preprocess EEG data, including filtering, artifact removal, and normalization.
isDataOperation: true
icon: iconify icon-park--eeg
mixins:
- bpmn:SubProcess- Use
mixinsfor example-time composition, not for defining reusable schema inheritance. Reusable schema inheritance belongs ontypes[].superClass.
Nested subprocess flow elements
If an example resolves to bpmn:SubProcess, it may also declare examples[].object.flowElements to create internal nodes and connections together with the root subprocess.
examples:
- description: Preprocess EEG data for a single subject.
object:
type: MapData
bpmn:name: Preprocess EEG (subject)
bpmn:width: 420
bpmn:height: 180
mixins:
- bpmn:SubProcess
flowElements:
- id: eeg_filter
type: MapData
bpmn:name: Filter signal
x: 70
y: 65
- id: eeg_clean
type: MapData
bpmn:name: Remove artifacts
x: 240
y: 65
- bpmn:type: bpmn:SequenceFlow
sourceRef: eeg_filter
targetRef: eeg_cleanExamples may declare promoted attributes explicitly using schema attributes: definitions.
examples:
- description: Preprocess EEG data for a single subject.
attributes:
param1:
range: string
description: Example-specific promoted attribute.
ifabsent: "default_value"
object:
type: MapData
bpmn:name: EEGPrepThese attributes are not added back onto the original schema class. Instead, the modeler generates an example-scoped derived moddle type for that specific example object, so the extra attributes persist in the saved diagram (both the YAML and the BPMN XML serializations) without changing other MapData examples or the base class definition.
If the same example also includes undeclared scalar properties such as param1: value1, those are inferred onto the same example-scoped derived type rather than onto the parent schema class.
Cross-schema references
Use the schema prefix to reference types from another schema, e.g. studyflow:YAMLString, studyflow:AssignmentAlgorithmEnum, studyflow:DataOperationActivity. The cognitive schema, for example, refers to studyflow:DataOperationActivity#isDataOperation when pinning the data-operation marker off for activities like CognitiveTask.
Common mistakes
- Prefix mismatch: type references using the wrong prefix (for example
core:vs local names, or the legacystudyflow:prefix). - Missing
type: moddle properties without a type often fall back to string-like behavior and may produce unintended interfaces. - Mixing up
extendsandsuperClass: useextendsto mix attributes onto an existing BPMN base; usesuperClassto define a new concrete type that inherits behavior. - Incorrect BPMN mapping: omit or misconfigure
meta.bpmnTypeand the element may no longer map to the intended BPMN shape. - Invalid condition shape: malformed
condition.bodyJSON disables conditional visibility. - Incorrect
redefinesowner: invalid targets are dropped.
Naming conventions
Property names follow camelCase (consentFormUri, completionCodeType), except where a type mirrors an external tool’s CLI one-to-one – e.g. PreprocessfMRI’s output_spaces matches the corresponding fMRIPrep flag verbatim so configurations can be copy-pasted.