---
name: rules-rule-obj-flow
description: The primary authoring guide for Flow rules (Rule-Obj-Flow). Load this first before any examples.
---

**Prerequisite:** Load `methodology-rule-authoring` first

## Authoring Notes

### Identity constraints

`pyFlowType` is the flow identity key (with `pyClassName`). `pyWorkClass` must
always equal `pyClassName`. These are enforced by the server and will cause
save failures if mismatched.

### Flow naming

Flow names (`pyFlowType`) cannot contain hyphens (`-`).
Use PascalCase or underscores. The server's KeyValidate activity rejects
names with hyphens.

### Navigation map fields

`pyFromTasks`, `pyEndingActivities`, and `pyStartActivity` are
auto-regenerated by the Validate activity on every save. However, they may
be required in the initial **create** payload for the server to accept the
rule. Include them when creating a new flow; on subsequent updates they will
be overwritten by the server.

### Empty class values

Use `""` (empty string) for blank class entries in `pyPagesAndClasses` and
shape `pyClassName`. Do not use `$None` or `$none` — the OnBeforeDisplay
activity normalizes those to `""`.

### Expression decision limitations

EXPRESSION-type Decision shapes (`pyDecisionClass: "EXPRESSION"`) only accept
a **bare property reference** in `pyImplementation` (e.g., `.DoNotAttachCorrespondence`,
`.ResolutionStatus`). The property is evaluated as a boolean at runtime.

**Not valid in `pyImplementation`:**
- Function calls: `pxIsBlank(.pyRouteTo)` — rejected by the expression parser
- Operator expressions: `.pyLabel == ""` — not supported for EXPRESSION decisions

EXPRESSION decisions use `Status` connectors (`pyConditionType: "Status"`) with
`pyExpression: "true"` or `"false"`, not `When`/`Else` connectors.

For operator-based branching, use a `Data-MO-Gateway-DataXOR` decision with `When`
connectors. When connectors accept both named When rules (e.g., `RunningConversionUtility`)
and inline property comparisons (e.g., `.pyAssignedOperator != ""`).

`pyExpressionGadget` is absent from all observed production flows and should not be
included when creating EXPRESSION decisions via the API.

### ScreenFlow differences

ScreenFlow flows (`pyCategory: "ScreenFlow"` or `"ScreenFlowStandard"`) use
a different Start shape class (`Data-MO-Event-Start-StartScreenFlow` vs
`Data-MO-Event-Start`), a different start shape template
(`pyFromMODefName: "Start"` with `pyMOId: "Start62"`), ScreenFlow
assignments (`Data-MO-Activity-Assignment-WorkAction`), and ScreenFlow
subprocesses (`Data-MO-Activity-SubProcess-ScreenflowProcess` with
`pySubProcessCategory: "ScreenFlow"`). See the `flow-screenflow`,
`flow-shape-start-screenflow`, `flow-shape-assignment-screenflow`, and
`flow-shape-subprocess-screenflow` examples.

#### Per-shape category stamps

Every shape carries a shape-level `pyCategory` that varies by flow category:

| Flow category | Shape-level `pyCategory` | Shape-level `pyFlowType` |
|---|---|---|
| **FlowStandard** | `"FlowStandard"` on all shapes | not set |
| **ScreenFlow** (modern) | `"ScreenFlow"` on Start/Assignment/Utility; `"ScreenFlowStandard"` on End | `"ScreenFlowStandard"` on End only |
| **ScreenFlow** (legacy 2013-imported) | absent on all shapes | absent on all shapes |

#### Per-shape boilerplate fields by category

FlowStandard non-Start/non-End shapes carry `pyBaseClass` (the work class) and `pyUseCaseWorkType` (short case-type name). Start and End shapes omit both. ScreenFlow shapes do not carry these fields.

`pyTicketShapes` also differs:

| Flow category | Start | Non-Start, non-End | End |
|---|---|---|---|
| **FlowStandard** | `[]` | `[{ "pxObjClass": "Data-MO-Event-Exception", "pyMOName": "" }]` | `[{ "pxObjClass": "Data-MO-Event-Exception", "pyMOName": "" }]` |
| **ScreenFlow** | `[]` | `[]` | `[{ "pxObjClass": "Data-MO-Event-Exception", "pyMOName": "" }]` |

## Shape Types

### Shape name prefixes

The numeric suffix is assigned sequentially. Gaps are normal (e.g., `END52` does not mean 52 shapes). Uniqueness within the flow is the only requirement.

| Prefix | Shape Type | Category |
|--------|-----------|----------|
| `Start1` | Start (FlowStandard) | Start |
| `Start62` | Start (ScreenFlow) | Start |
| `Assignment1`, `Assignment2`, … | Assignment — routes work to a worklist/workbasket | Assignment |
| `AssignmentSF1`, `AssignmentSF2`, … | Screen flow assignment — one wizard step | Assignment |
| `Utility1`, `Utility2`, … | Utility — runs an activity | Utility |
| `SubProcess1`, `SubProcess2`, … | Sub-process — calls another flow | Sub-process |
| `SubProcessSF1`, `SubProcessSF2`, … | Screen flow sub-process | Sub-process |
| `GenerativeAISubProcess1`, `GenerativeAISubProcess2`, … | Agent — invokes an AI Agent rule | Agent |
| `Decision1`, `Decision2`, … | Decision/router — branches on a condition | Decision |
| `GenerativeAI1`, `GenerativeAI2`, … | GenAI shape — invokes an AI connector | GenAI |
| `SPLITFOREACH1`, `SPLITFOREACH2`, … | Split-for-each — iterate and spawn parallel branches | Parallel |
| `FORK1`, `FORK2`, … | Fork — split into parallel branches | Parallel |
| `SPLITJOIN1`, `SplitSplitJoin1`, `JoinSplitJoin1`, … | Split-join gateway | Parallel |
| `Wait1`, `Wait2`, … | Wait — pauses until a condition or timer | Wait |
| `End1`, `END52`, `END66`, `FLOWEND` | End — terminates the flow | End |

#### Unsupported shape types

If the user requests a shape type that does not appear in the table above or in the `pxObjClass` ↔ `pyFromMODefName` mapping below, **stop immediately and inform the user** that the requested shape type is not supported. Do not attempt to author it. List the supported shape types from the table above so the user can choose an alternative.

If the current flow has `pyCategory: "ScreenFlow"`, Approval and Agent shapes are not supported because ScreenFlow flows can only call other ScreenFlows as subprocesses.

### `pxObjClass` ↔ `pyFromMODefName` mapping

| `pyFromMODefName` | `pxObjClass` | Description |
|-------------------|--------------|-------------|
| `Start` | `Data-MO-Event-Start` (FlowStandard) / `Data-MO-Event-Start-StartScreenFlow` (ScreenFlow) | Entry point |
| `End` | `Data-MO-Event-End` | Terminal point |
| `Assignment` | `Data-MO-Activity-Assignment` | User task (FlowStandard) |
| `AssignmentSF` | `Data-MO-Activity-Assignment-WorkAction` | Screen flow assignment |
| `Utility` | `Data-MO-Activity-Utility` | Automated activity step |
| `SubProcess` | `Data-MO-Activity-SubProcess` | Calls another flow |
| `Spinoff` | `Data-MO-Activity-SubProcess-Spinoff` | Explicit spin-off — forks execution onto another flow in parallel. Uses both `pySpinOff: "true"` AND the dedicated subclass (both required). |
| `GenerativeAISubProcess` | `Data-MO-Activity-SubProcess-GenerativeAI` | Agent smart shape — invokes a Rule-AI-Agent via `pzAsyncAgent` |
| `Decision` | `Data-MO-Gateway-Decision` | Branching gateway |
| `GenerativeAI` | `Data-MO-Activity-Utility-GenerativeAI` | AI connector invocation |
| `AskAQuestion` | `Data-MO-Activity-SubProcess-Conversation-Question` | Conversation-flow question step (ConversationFlow only) |
| `SendAMessage` | `Data-MO-Activity-SubProcess-Conversation-Message` | Conversation-flow message step (ConversationFlow only) |

> **ConversationFlow shapes.** `AskAQuestion` / `SendAMessage` are supported when paired with `pyStructureType: "ConversationFlow"` — the `pxObjClass` is the `Data-MO-Activity-SubProcess-Conversation-*` subclass family.
>
> **Legacy-only — do not author.** `Spin` / `SpinEnd` (`Data-MO-Gateway-Spin` / `Data-MO-Gateway-SpinEnd`) are Visio-era shapes. For spin-off patterns use `Data-MO-Activity-SubProcess-Spinoff` with `pyFromMODefName: "Spinoff"`.

### Common shape fields

Every shape carries these regardless of type:

| Field | Description |
|-------|-------------|
| `pyMOId` | Unique shape ID (also the PageGroup key in `pyShapes`) |
| `pyMOName` | Display name on the canvas |
| `pyClassName` | Class context for the shape |
| `pyFromMODefName` | Shape template type |
| `pyCoordX` / `pyCoordY` | Canvas coordinates |
| `pyWidth` / `pyHeight` | Shape dimensions |
| `pyLane` | Swim-lane identifier |
| `pyAuditNote` | Audit/history note |
| `pyCallParams` | Shape-level parameter key/value pairs |

Start and End shapes use `pyMOName: "Start"` / `"End"` on legacy flows; modern Process Modeler may write `""` or the `pyMOId` instead. On recreation, preserve the server's value. On fresh authoring, either convention is acceptable.

### Flow-level `pyParameters` convention

When a flow declares input parameters, the rule-level `pyParameters` list carries one `Embed-MethodParams` row per parameter. This convention differs from shape-embedded parameter rows:

| Convention | Where | `pyParametersParamInOut` | `pyParametersParamReq` |
|---|---|---|---|
| Rule-level `pyParameters` | top-level flow rule | `""` | `"-1"` |
| Notify smart-shape embedded | shape `pzRuleParameters` | `"IN"` | `"0"` |
| Approval-bundle embedded | SubProcess `pzRuleParameters` | `""` | `""` |
| Plain-activity Utility embedded | shape `pzRuleParameters[1]` | `"IN"` | `""` |

When a flow declares no parameters, emit a single empty placeholder row with `pyParametersParamName: ""` and all other fields blank.

## Rule-level Fields by Structure-Type — Canonical Matrix

> **The single highest-leverage cross-reference in this skill.** Eight
> `pyStructureType` family-values (or explicit absence) each write a
> different rule-level field signature. Use this table to answer: "given
> this structure-type, what rule-level fields do I write, and with what
> values?" Cells contain the canonical value, `(absent)` if the field
> is not emitted at all, `(varies)` for context-dependent values
> documented elsewhere, or a back-pointer to the authoritative
> section. The eight columns are the eight observed family-values
> including BPMN (`pyStructureType` field fully absent — its identity
> signal is `pyCategory: "BPMN"`) and Stub (skeletal flows).

| Field | Linear | Simple | Multi | ConversationFlow | ScreenFlow | ProcessFlow | BPMN | Stub |
|---|---|---|---|---|---|---|---|---|
| `pyStructureType` | `"Linear"` | `"Simple"` | `"Multi"` | `"ConversationFlow"` | `"ScreenFlow"`; also `"Multi"` for branching ScreenFlow | `"Simple"` on shipped flows | **(absent)** — field omitted entirely | `"Linear"` |
| `pySuggestedStructureType` | (absent) | (absent) | (absent) | `"ConversationFlow"` | (absent) | (absent) | (absent) | (absent) |
| `pyCategory` | `"FlowStandard"` | `"FlowStandard"` | `"ScreenFlowStandard"` | `"ConversationFlow"` | `"ScreenFlowStandard"` — or self-rule-name override | `"ProcessFlow"` | `"BPMN"` | `"FlowStandard"` |
| `pyFlowType` | self-register flow name | flow name or `"FlowStandard"` | flow name or taxonomy | `"FlowStandard"` (decoupled) | self-rule wins over `"ScreenFlowStandard"` default | `"FlowStandard"` | `"FlowStandard"` (decoupled) | `"FlowStandard"` |
| `pyPageRTE` | (absent) | (absent) | (absent) | `{ pxObjClass: "Embed-RTE-Conversation" }` | (absent) | (absent) | (absent) | (absent) |
| `pyCustomFields.pyGalleryType` | `"CaseManagementGallery"` when self-registering | (varies — palette self-registration) | (varies) | (absent — see for ConversationFlow custom-fields cluster) | (varies) | (absent) | (absent) | (absent) |
| `pyCustomFields` other | sparse | sparse | sparse | rich — 17-field cluster | sparse | sparse | sparse | sparse |
| `pyTaskInfo` rollup | shape-level only | shape-level only | shape-level only | shape-level only | shape-level only | shape-level only | shape-level + **top-level rollup** | empty placeholder |
| `pyUseCaseLinks` | rollup of action shapes | rollup | rollup | rollup including AskAQuestion / SendAMessage with parent-class `pxLinkedClassTo` | rollup with screen-flow assignment labels | rollup with parent-class for Spinoff | rollup with parent-class for SplitForEach | empty |
| `pyContexts` | PrimaryPath / AlternatePath | same | same | same | same | same | same | same |
| `pyModifiers` (rule-level) | `[]` | `[]` | `[]` | `[]` | `[]` | `[]` | populated — ticket wiring (/72/74) | `[]` |
| `pyStencils` | `[]` | `[]` | `[]` | `[]` | `[]` | `[]` | populated — annotation shapes | `[]` |
| `pyCoveredBy` / `pyCoveredByCount` | `[]` / `"0"` | `[]` / `"0"` | `[]` / `"0"` | `[]` / `"0"` | `[]` / `"0"` | `[]` / `"0"` | populated when sub-case spin-off | `[]` / `"0"` |
| `pxNamedPageReferences` | as needed | as needed | as needed | as needed | as needed | as needed | as needed | as needed |
| `pyRuleParamsStreamName` | (absent) | populated when Utility smart-shape with embedded params | same | populated for Conversation-Question shapes | same | same | same | (absent) |
| `pyParameters` (rule-level placeholder) | placeholder row | placeholder row | placeholder row | placeholder row | placeholder row | populated when flow has declared params | placeholder row | placeholder row |
| Author-default cluster (~25 fields: `pyShowGrid`, `pyModelerGridModeON`, `pySkipNewHarness`, `pyInterface`, `pyInterfaceHolder` = `"Process Engine"`, `pyHistoryObject`, etc.) | author defaults | same | same | + 17-field modeler-UI cluster | same | same | same | same |
| `pyTaskStatusXml` | empty shell | same | same | same | same | same | same | empty shell |
| `pyEndingActivities` | populated when End shape carries activity | same | same | preserves legacy `pyMOId` literal e.g. `"END52"` | same | same | same | populated |
| `pyNextAssignment` TTFF quad | (absent on stubs) | as needed | as needed | quad populated for ConversationFlow | as needed | as needed | as needed | (absent) |
| Shape coordinates | modeler pixels (`"60"`..`"540"`) | modeler pixels (modern); fractional inches `0.0`..`10.0` on legacy | modeler pixels | modeler pixels | modeler pixels | **fractional inches `0.0`..`10.0`** | modeler pixels | modeler pixels |
| Connector waypoints (`pyConnectorPoints`) | always pixels | always pixels | always pixels | always pixels | always pixels | always pixels (even when shapes are inches) | always pixels | always pixels |

### Reading the matrix

- **BPMN is the only structure-type where the `pyStructureType` field is fully absent** — not `""`, not `null`, not present. The identity signal is `pyCategory: "BPMN"` alone.
- **ConversationFlow is the only structure-type that emits `pySuggestedStructureType` and `pyPageRTE`.**
- **ProcessFlow is the only structure-type with shape-level fractional-inch coordinates.** Connector waypoints stay in pixels even on ProcessFlow.
- **ScreenFlow is the only structure-type where a self-registering rule name OVERRIDES the taxonomy default** for `pyFlowType`.
- **Tickets / annotations / sub-case rollup** (`pyModifiers` / `pyStencils` / `pyCoveredBy`) populate only on canvas-modeled flows that wire those features — independent of structure-type taxonomy.

### Cross-references

- ConversationFlow 17-field custom-fields cluster: see `rule-level-fields`.

## References

Whenever editing a flow, to ensure you understand the full context, load one or more of these skills

| Skill | Description |
|-------|-------------|
| `blueprint-stub-discovery` | Load when working with a BluePrint-generated app to find stub shapes that need wiring |
| `flow-creation-workflow` | Load when creating a brand-new flow from scratch |
| `adding-steps-workflow` | Load when adding a new shape to an existing flow |
| `enhancing-steps-workflow` | Load when modifying what an existing flow shape does — changing its backing rule without adding or removing shapes |
| `flowaction-wiring-patterns` | Load when creating or configuring a FlowAction for a flow's Assignment shape — view connection and field pitfalls |
| `canvas-structure` | Load when updating an existing flow's shapes or connectors — field sync rules and deep-merge |
| `shapes-start-end` | Load when authoring Start or End shapes in a flow — field subsets, ScreenFlow Start variant, and Change-to-Stage End wiring |
| `legacy-shape-ids` | Load when updating or recreating a pre-2020 imported flow that uses semantic shape IDs like FLOWEND or Fork592 instead of modern auto-generated IDs |
| `shapes-subprocess` | Load when authoring a SubProcess or Spinoff shape in a flow — shape fields, parameter passing, Spinoff subclass, and Annotation shapes |

| `top-level-rollups` | Load when a flow needs rule-level summary lists that mirror shape-level data — pyUseCaseLinks, pyCoveredBy, pyTaskInfo, pxDataReferences |
| `rule-level-fields` | Load when copying or recreating a flow and encountering unfamiliar rule-level fields |
| `shapes-assignment` | Load when authoring an Assignment shape in a flow — routing fields, BPMN differences, ticket wiring |
| `routing-assignment` | Load when configuring who a flow's Assignment routes work to — current operator, worklist, or workbasket |
| `shapes-utility` | Load when authoring a Utility shape in a flow — smart-shape variants (data transform, notification, change-to-stage), plain-activity wiring, and variant differences |
| `shapes-decision` | Load when authoring a Decision shape in a flow (any variant) — required fields, connector wiring, type-specific gotchas |
| `shapes-genai` | Load when authoring a GenerativeAI shape in a flow — pxConnectToGenerativeAI wiring, pyGenAIPage sub-page, placeholder vs configured differences |
| `shapes-parallel` | Load when authoring parallel execution in a flow — SplitForEach iteration, SplitJoin parallel branches, Fork shapes, and pyFromTasks wiring |
| `connectors-and-mo-id-naming` | Load when wiring connectors between flow shapes — condition types, expressions, likelihoods, naming |
| `routing-decision` | Load when a flow's Decision shape has multiple outgoing branches — ordering, pyFromTasks mirroring, multi-destination keying |
| `flow-schema-vs-modeler-validation` | Load when a shape passes schema validation but renders incorrectly in Process Modeler — verification approach and common symptoms |

## Verification Checklists

**Schema-tolerated vs modeler-significant fields:** See
`flow-schema-vs-modeler-validation` — schema validation alone is not
sufficient for flow shapes; fields the schema accepts may not render in
Process Modeler.

Run the relevant checklist after creating or updating a flow.

### After creating a new flow

- [ ] Flow (`Rule-Obj-Flow`): `pyRuleFormStatus: Good`; `pyFromTasks` contains expected shape names
- [ ] FlowAction (`Rule-Obj-FlowAction`): same name as the Assignment shape; `pyAutoHTML: true`
- [ ] Backing View (`Rule-UI-View`): resolved by convention (same name as FlowAction); `pyRuleFormStatus: Good`
- [ ] Decision rule (if any): `Rule-Declare-DecisionTable` or `Rule-Declare-DecisionTree`; not a stub
- [ ] Activity (if any): `pySteps` contains real logic, not just a `COMMENT`
- [ ] Flow `pxWarnings[0]` is empty; no unresolved shape references

### After adding a step

- [ ] Updated flow: shape appears in `pyFromTasks`; wiring present in `pyLocalActions` (Assignment) or `pyShapes` (Utility/Notification)
- [ ] New FlowAction (Assignment step): `pyRuleFormStatus: Good`; companion View resolved
- [ ] New Activity or DT (Utility step): contains real logic, not a `COMMENT`-only stub
- [ ] New Notification (Notification step): `pyPurpose == pyRuleName`; `pyCorrespondence` is `"{Name} Email"` not just `"{Name}"`
- [ ] Flow `pyRuleFormStatus: Good`; no `pxWarnings`

### After enhancing a step

- [ ] Updated FlowAction (Assignment): routing/transitions reflect changes; `pyRuleFormStatus: Good`
- [ ] Updated View (Assignment): field count matches expectation; `pxContextMetadata.$fields` updated
- [ ] Updated Activity (Automation): `pySteps` contains new logic; no stale `COMMENT` placeholder
- [ ] Updated Decision rule: rows reflect new conditions; `pyRuleFormStatus: Good`
- [ ] Updated Corr template (Notification): `pySourceStream` updated
- [ ] Flow `pyRuleFormStatus: Good` after any shape re-wiring

### After wiring a Notification step (4-rule bundle)

- [ ] `Rule-Notification`: `pyRuleFormStatus: Good`; `pyPurpose == pyRuleName`; `pyChannelsList` has at least one enabled channel
- [ ] `Rule-Obj-Corr`: rule name is `"{Name} Email"` (not just `"{Name}"`); `pySourceStream` contains the email body; `pyRuleFormStatus: Good`
- [ ] `Rule-Obj-FieldValue`: `pyLocalizedValue` contains the push/gadget message; `pyRuleFormStatus: Good`
- [ ] Flow Utility shape: `pyImplementation = "pzNotifyWrapper"`; `pyNotificationName` and `pyCallParams.NotificationName` both equal `{Name}`; `pzRuleParamsHolder.pyName = {Name}`; `pzRuleParamsHolder.pyReferExisting = "Existing"`

### After wiring a GenAI step (2-rule bundle)

- [ ] `Rule-Connect-GenerativeAI`: `pyModelId` set; `pyUserPrompt` references the correct FieldValue; `pyOutputProperty` set; `pyRuleFormStatus: Good`
- [ ] `Rule-Obj-FieldValue`: `pyLocalizedValue` contains the prompt text; `pyRuleFormStatus: Good`
- [ ] Flow GenAI shape: `pzRuleParamsHolder.pyServiceName` = connector name; `pyGenAIPage.pyServiceName` = connector name; `pyGenAIPage.pyReferExisting = "Existing"`; `pyImplementation = "pxConnectToGenerativeAI"`

### After wiring a Utility (Data Transform) step

- [ ] Data Transform (`Rule-Obj-Model`): `pyRuleFormStatus: Good`; `pyProperties` contains real assignments; `pyCallSuperClassModel: false`
- [ ] Flow Utility shape: `pyImplementation = "pzRunDataTransform"`; `pyCallParams.DataTransformName` = DT name
- [ ] Flow `pyRuleFormStatus: Good`; no `pxWarnings`

### Reflection format

For each rule in a bundle, record:
- `what worked`: instance key confirmed; `pyRuleFormStatus: Good`; expected fields present
- `what failed`: `Bad`/`Warning` status; stubs; missing references; or "none"
- `next fix`: corrective action for each failure; or "none"

### Dependent rule detection

For any rule that fails its checklist item, call `get-rule` with `detail="full"` on its `pzInsKey` and inspect `references` and `pxDependencies` to identify downstream rules that may also need updating. Report all failing rules and their dependents before returning.

## Examples

Example descriptions follow the pattern: `Shape type → Shape type (variant) → Shape type`. Lead with the flow topology, then a short sentence on when to use the example. Use the shape type names from the "Shape Name Prefixes" table above; add a parenthetical variant only when the specific sub-type matters (e.g., `Assignment (worklist)`, `Utility (data transform)`, `SubProcess (approval)`).

### Rule-level

| Skill | Description | References |
|-------|-------------|------------|
| `flow-stub` | Start → End. Smallest valid FlowStandard create payload | |
| `flow-screenflow` | Start → Assignment (ScreenFlow) → End. Minimal valid ScreenFlow create payload | `shapes-start-end` |
| `flow-sparse-update` | Use when adding a shape to an existing flow via deep-merge update | `canvas-structure` |
| `flow-sparse-update-single-field` | Use when updating a single field on an existing flow shape | `canvas-structure` |
| `flow-assignment-step` | Start → Assignment (worklist) → End. Use when creating a flow that routes work to an operator worklist with a flow action | `shapes-assignment`, `routing-assignment`, `flowaction-wiring-patterns` |
| `flow-conversation-flow-template` | Start → SubProcess (AskAQuestion) → End. Use when creating a ConversationFlow | `rule-level-fields` |
| `flow-decision-step` | Start → Decision (DataXOR) → End, End. Use when creating a flow that branches on a property comparison with WHEN/ELSE connectors | `shapes-decision`, `routing-decision` |
| `flow-fork-split-join` | Start → Decision → SplitJoin (SubProcess) → Decision (multi-destination) → End. Use when creating a flow with parallel branches | `shapes-parallel`, `routing-decision` |
| `flow-genai-step` | Start → Utility (GenerativeAI) → End. Use when wiring a generative AI connector into a flow | `shapes-genai` |
| `flow-loopback-cascading-approval` | Start → Utility → Decision → SubProcess (approval) → Utility → Decision (loopback) → End. Use when creating a cascading approval flow | `connectors-and-mo-id-naming`, `routing-decision`, `shapes-subprocess` |
| `flow-notify-smart-shape` | Start → Utility (notification) → End. Use when wiring a notification smart-shape into a flow | `shapes-utility` |
| `flow-split-foreach-subcase` | Start → Assignment (workbasket) → Utility → SplitForEach → SubProcess → End. Use when creating a BPMN flow that iterates a list and spawns sub-cases | `shapes-parallel` |
| `flow-subprocess-approval` | Start → SubProcess (approval) → End. Use when wiring a pxApproval subprocess into a flow | `shapes-subprocess` |
| `flow-utility-change-to-stage` | Start → Utility (change-to-stage) → End. Use when creating a flow that transitions to a different case stage | `shapes-utility` |
| `flow-utility-data-transform` | Start → Utility (data transform) → End. Use when wiring a data transform smart-shape into a flow | `shapes-utility` |
| `flow-utility-plain-activity` | Start → Utility (plain activity) → End. Use when wiring a plain activity into a flow | `shapes-utility` |

### Shape-level

| Skill | Shape type | Description | References |
|-------|-----------|-------------|------------|
| `flow-shape-start` | Start | Use when adding a Start shape as the entry point of a FlowStandard flow | `shapes-start-end` |
| `flow-shape-start-screenflow` | Start (screen flow) | Use when adding a Start (screen flow) shape as the entry point of a ScreenFlow | `shapes-start-end` |
| `flow-shape-end` | End | Use when adding an End shape as the terminal point of a flow | `shapes-start-end` |
| `flow-shape-assignment-worklist` | Assignment (worklist) | Use when adding an Assignment (worklist) shape to a flow | `shapes-assignment`, `routing-assignment` |
| `flow-shape-assignment-workbasket` | Assignment (workbasket) | Use when adding an Assignment (workbasket) shape to a flow | `shapes-assignment`, `routing-assignment` |
| `flow-shape-assignment-screenflow` | Assignment (ScreenFlow) | Use when adding an Assignment (ScreenFlow) shape. Shows FlowAction wiring for a screen flow step | `shapes-assignment`, `flowaction-wiring-patterns` |
| `flow-shape-utility-activity` | Utility (activity) | Use when adding a Utility (activity) shape that calls an activity directly | `shapes-utility` |
| `flow-shape-utility-data-transform` | Utility (data transform) | Use when adding a Utility (data transform) shape that runs a data transform via pzRunDataTransform | `shapes-utility` |
| `flow-shape-utility-data-transform-screenflow` | Utility (data transform, ScreenFlow) | Use when adding a Utility (data transform) shape to a ScreenFlow — ScreenFlow category stamps and verified Modeler-compatible fields | `shapes-utility` |
| `flow-shape-utility-notification` | Utility (notification) | Use when adding a Utility (notification) shape that sends a notification via pzNotifyWrapper | `shapes-utility` |
| `flow-shape-generative-ai` | Utility (generative AI) | Use when adding a Utility (generative AI) shape that invokes a Rule-Connect-GenerativeAI connector | `shapes-genai`, `shapes-utility` |
| `flow-shape-subprocess` | SubProcess | Use when adding a SubProcess shape that calls another flow within the current case | `shapes-subprocess` |
| `flow-shape-subprocess-screenflow` | SubProcess (screen flow) | Use when adding a SubProcess (screen flow) shape that calls another screen flow within the current case | `shapes-subprocess` |
| `flow-shape-agent` | Agent | Use when adding an Agent smart shape that invokes a Rule-AI-Agent via pzAsyncAgent | `shapes-subprocess` |
| `flow-shape-decision-expression` | Decision (expression) | Use when adding a Decision (expression) shape to a flow that branches on a boolean property reference | `shapes-decision`, `routing-decision`, `connectors-and-mo-id-naming` |
| `flow-shape-decision-table` | Decision (decision table) | Use when adding a Decision (decision table) shape to a flow that branches via a decision table | `shapes-decision`, `routing-decision`, `connectors-and-mo-id-naming` |
| `flow-shape-decision-tree` | Decision (decision tree) | Use when adding a Decision (decision tree) shape to a flow that branches via a decision tree | `shapes-decision`, `routing-decision`, `connectors-and-mo-id-naming` |
| `flow-shape-decision-fork` | Decision (fork) | Use when adding a Decision (fork) shape to a flow that branches on a property value | `shapes-decision`, `routing-decision`, `connectors-and-mo-id-naming` |
| `flow-shape-decision-map-value` | Decision (map value) | Use when adding a Decision (map value) shape to a flow that branches via a map value lookup | `shapes-decision`, `routing-decision`, `connectors-and-mo-id-naming` |
| `flow-shape-decision-predictive-model` | Decision (predictive model) | Use when adding a Decision (predictive model) shape to a flow that branches on a model propensity score | `shapes-decision`, `routing-decision`, `connectors-and-mo-id-naming` |
| `flow-shape-decision-scorecard` | Decision (scorecard) | Use when adding a Decision (scorecard) shape to a flow that branches on a weighted score | `shapes-decision`, `routing-decision`, `connectors-and-mo-id-naming` |
| `flow-shape-wait-timer` | Wait (timer) | Use when adding a Wait (timer) shape that pauses flow execution until a timer fires | `shapes-assignment`, `routing-assignment` |
| `flow-shape-send-a-message` | SubProcess (send a message) | Use when adding a SubProcess (send a message) shape to a ConversationFlow | `shapes-subprocess` |
| `flow-connector-status` | Connector (status) | Use when adding a Status connector to a flow Decision shape that fires on a specific result | `connectors-and-mo-id-naming`, `shapes-decision` |
| `flow-connector-else` | Connector (else) | Use when adding a default Else connector to a flow Decision shape | `connectors-and-mo-id-naming`, `shapes-decision` |

### Component-level

| Skill | Description | References |
|-------|-------------|------------|
| `flow-local-action` | Use when wiring a FlowAction to a flow via a pyLocalActions entry | `flowaction-wiring-patterns` |
