Flow Artifact Specification

Definition

A Flow is a multi-step legitimate sequence of Interactions that achieves a user or system goal. Flows represent intended behavior - the "happy path" through your system - with clear preconditions, step sequencing, invariant guards/effects, variants, and success criteria.

Flows compose Interactions into meaningful user journeys. While an Interaction is atomic (a single operation), a Flow chains multiple Interactions together to accomplish a larger goal like "checkout and pay" or "deploy a service."

Key principle: Flows describe intended behavior only. Negative paths, attacks, and deviations belong in Scenarios and Explorations, which reference Flows where they deviate.

Schema: flow.schema.yaml


Required Fields

FieldTypeDescription
idFlowIDUnique identifier following pattern F-<SYSTEM>-<NAME>
namestringHuman-readable name describing the user goal
actorstringPrimary actor executing the flow (concept ID or role)
goalstringThe outcome this flow achieves, expressed as a result
triggerFlowTriggerWhat initiates the flow (user action, event, schedule)
preconditionsFlowCondition[]Conditions that must hold before flow begins
stepsFlowStep[]Ordered sequence of interactions
postconditionsFlowCondition[]Conditions that must hold after completion

Optional Fields

FieldTypeDefaultDescription
descriptionstring-Detailed description of the flow's purpose
scopestring-Boundary clarification (what's included/excluded)
variantsFlowVariant[]-Alternative paths based on conditions
state_mapStateMap-Visual state transitions driven by flow
relatedRelatedArtifacts-Links to concepts, interactions, scenarios
security_insightsFlowSecurityInsights-Security considerations
observabilityFlowObservability-Live validation evidence (add only after testing)
statusArtifactStatusDRAFTLifecycle status
versionstring-Semantic version (e.g., 1.0.0)

Field Details

actor

The primary actor executing the flow. Can be:

  • A concept ID: C-SHOP-USER
  • A role description: Authenticated User
  • A system actor: Scheduled Job, Event Handler

The actor should be the entity whose perspective defines the flow's purpose.

goal

The goal is expressed as an outcome, not a list of actions:

  • Good: "Convert a shopping basket into a paid order"
  • Bad: "Login, add items, checkout, pay, confirm"

The goal should answer: "What does the actor want to accomplish?"

trigger

trigger describes what initiates the flow. To name the first operation, set trigger.initial_interaction to an I-* Interaction ID.

Note: initial_interaction is intentionally an Interaction reference; it is not an EP-* Entry Point artifact. Surfaces that can start the flow should be modeled via the triggering Interaction's entry_points (EP-*) and/or the flow's related links.

preconditions and postconditions

Conditions use a structured format supporting multiple types:

TypeUsageExample
invariantReference to INV-*INV-SHOP-AUTH-REQUIRED
stateConcept state requirementC-SHOP-ORDER.status = 'draft'
attributeAttribute value requirementC-SHOP-USER.verified = true
existsExistence checkEXISTS(C-SHOP-BASKET.items)
customCustom expressionbasket.total > 0

Example:

yaml
preconditions:
  - type: invariant
    invariant: INV-SHOP-AUTH-REQUIRED
    description: "User must be authenticated"
  - type: state
    concept: C-SHOP-BASKET
    state: ACTIVE
    description: "Basket must be active"
 
postconditions:
  - type: state
    concept: C-SHOP-ORDER
    state: PAID
    description: "Order is paid"
  - type: invariant
    invariant: INV-SHOP-ORDER-PAYMENT-CONSISTENT
    description: "Payment amount matches order total"

steps

Each step references an Interaction and provides context:

PropertyRequiredDescription
orderYesSequence number (1-based)
actorYesWho performs this step
interactionYesReference to I-*
purposeYesWhy this step exists in the flow
preNoStep-specific pre-invariants
postNoStep-specific post-invariants
conditionalNoWhen step is optional
on_failureNoFailure handling: abort, retry, skip, compensate
compensationNoRollback interaction if needed

Step satisfiability: Every step's pre-conditions should be implied by the flow's preconditions plus prior steps' post-conditions.

variants

Variants represent alternative paths through the flow:

  • Payment method variants (credit card, wallet, crypto)
  • User type variants (guest, member, admin)
  • Feature flag variants

Each variant can replace steps, insert additional steps, or modify postconditions.


Key Patterns

  • Legitimate behavior only. Flows document the happy path. Attacks and deviations go in Scenarios.

  • Steps are existing Interactions. Never define new operations inline - reference I-* IDs. If an interaction doesn't exist, create it first.

  • Preconditions enable first step. The flow's preconditions must satisfy the first step's pre-invariants.

  • Each step enables the next. Step N's post-conditions must satisfy step N+1's pre-conditions.

  • Postconditions span all steps. Flow-level postconditions capture guarantees that result from the entire sequence.


Flow Health Checks

Before considering a flow complete, verify:

CheckDescription
Step satisfiabilityEvery step's pre is implied by flow pre + prior posts
No dead branchesAll variant conditions can actually be true
Guards documentedState-changing steps cite relevant INV-*
Cycles have exitsAny loops have termination conditions
Idempotency notedRetry/parallel steps have integrity invariants
Boundaries markedTrust boundary crossings are identified

Common Mistakes

MistakeProblemFix
[ ] Including attack pathsFlows should be legitimate onlyMove negative paths to Scenarios
[ ] Inlining interaction logicSteps should reference, not defineCreate Interaction first, then reference
[ ] Missing step connectionsGap between step N post and step N+1 preEnsure post-conditions enable next step
[ ] Vague goals"Do checkout things" doesn't clarify intentExpress goal as concrete outcome
[ ] Monolithic stepsOne step does too muchSplit into smaller Interactions
[ ] No variants for alternativesReal flows have branchesAdd variants for different paths

Example: F-SHOP-CHECKOUT-001

yaml
id: F-SHOP-CHECKOUT-001
name: "User Checkout and Payment"
description: >
  A logged-in user converts their shopping basket into a paid order.
  Includes delivery selection, optional coupon application, and payment capture.
 
actor: C-SHOP-USER
goal: "Convert a shopping basket into a paid order for a logged-in user"
 
trigger:
  type: user_action
  description: "User clicks 'Proceed to Checkout' button"
  initial_interaction: I-SHOP-CREATE-ORDER-001
 
scope: "From basket to paid order, excludes order fulfillment and shipping"
 
preconditions:
  - type: invariant
    invariant: INV-SHOP-AUTH-REQUIRED
    description: "User must be authenticated"
 
  - type: state
    concept: C-SHOP-BASKET
    state: ACTIVE
    description: "User has an active basket"
 
  - type: custom
    expression: "basket.items.length > 0"
    description: "Basket is not empty"
 
steps:
  - order: 1
    actor: User
    interaction: I-SHOP-CREATE-ORDER-001
    purpose: "Create order from basket contents"
    pre:
      - INV-SHOP-BASKET-NOT-EMPTY
    post:
      - INV-SHOP-ORDER-CREATED
    notes: "Associates basket items with new order"
 
  - order: 2
    actor: User
    interaction: I-SHOP-SELECT-DELIVERY-001
    purpose: "Choose delivery method and address"
    pre:
      - INV-SHOP-ORDER-EDITABLE
    post:
      - INV-SHOP-DELIVERY-SET
    notes: "Order total recalculated with shipping"
 
  - order: 3
    actor: User
    interaction: I-SHOP-APPLY-COUPON-001
    purpose: "Apply discount coupon if available"
    conditional: "user.has_coupon"
    pre:
      - INV-SHOP-COUPON-VALID
    post:
      - INV-SHOP-ORDER-TOTAL-CONSISTENT
    on_failure: skip
    notes: "Optional step - flow continues if coupon invalid"
 
  - order: 4
    actor: User
    interaction: I-SHOP-CAPTURE-PAYMENT-001
    purpose: "Process payment and complete order"
    pre:
      - INV-SHOP-PAYMENT-AUTHORIZED
      - INV-SHOP-ORDER-TOTAL-CONSISTENT
    post:
      - INV-SHOP-ORDER-PAID
      - INV-SHOP-PAYMENT-CAPTURED
    compensation: I-SHOP-REFUND-PAYMENT-001
    notes: "Payment failure triggers order cancellation"
 
postconditions:
  - type: state
    concept: C-SHOP-ORDER
    state: PAID
    description: "Order is in paid state"
 
  - type: invariant
    invariant: INV-SHOP-ORDER-PAYMENT-CONSISTENT
    description: "Payment amount equals order total"
 
  - type: state
    concept: C-SHOP-BASKET
    state: CONVERTED
    description: "Basket has been converted to order"
 
variants:
  - name: wallet_payment
    condition: "user.preferred_payment == 'wallet'"
    replaces: [4]
    steps:
      - order: 4
        actor: User
        interaction: I-SHOP-DEBIT-WALLET-001
        purpose: "Pay using account wallet balance"
        pre:
          - INV-SHOP-WALLET-SUFFICIENT
        post:
          - INV-SHOP-ORDER-PAID
          - INV-SHOP-WALLET-DEBITED
    postconditions:
      - type: invariant
        invariant: INV-SHOP-ORDER-PAYMENT-CONSISTENT
        description: "Wallet debit equals order total"
 
  - name: guest_checkout
    condition: "user.type == 'guest'"
    inserts_after: 1
    steps:
      - order: 2
        actor: User
        interaction: I-SHOP-COLLECT-GUEST-INFO-001
        purpose: "Gather email and contact for guest"
        post:
          - INV-SHOP-GUEST-INFO-VALID
 
state_map:
  concept: C-SHOP-ORDER
  states:
    - CREATED
    - PENDING_DELIVERY
    - PENDING_PAYMENT
    - PAID
  transitions:
    - from: CREATED
      to: PENDING_DELIVERY
      step: 1
      interaction: I-SHOP-CREATE-ORDER-001
    - from: PENDING_DELIVERY
      to: PENDING_PAYMENT
      step: 2
      interaction: I-SHOP-SELECT-DELIVERY-001
    - from: PENDING_PAYMENT
      to: PAID
      step: 4
      interaction: I-SHOP-CAPTURE-PAYMENT-001
      guard: INV-SHOP-PAYMENT-AUTHORIZED
 
related:
  concepts:
    - C-SHOP-USER
    - C-SHOP-BASKET
    - C-SHOP-ORDER
    - C-SHOP-PAYMENT
    - C-SHOP-COUPON
  interactions:
    - I-SHOP-CREATE-ORDER-001
    - I-SHOP-SELECT-DELIVERY-001
    - I-SHOP-APPLY-COUPON-001
    - I-SHOP-CAPTURE-PAYMENT-001
  scenarios:
    - S-SHOP-PAYMENT-BYPASS-001
    - S-SHOP-COUPON-ABUSE-001
  explorations:
    - E-SHOP-PAYMENT-BYPASS-001-01
 
security_insights:
  identity_continuity: >
    User identity from initial auth must be maintained throughout.
    All steps validate against same user_id.
  cross_tenant: >
    Order, basket, and payment must belong to same user.
    No cross-user data access.
  idempotency: >
    Payment capture must be idempotent. Retry with same order_id
    should not double-charge.
  compensation: >
    If payment fails after order creation, order transitions to CANCELLED.
    If payment captured but confirmation fails, refund is triggered.
  race_conditions:
    - "Concurrent checkout from same basket"
    - "Coupon used simultaneously by multiple users"
    - "Price change during checkout"
  trust_boundaries:
    - "Auth service validates token"
    - "Payment gateway processes charge"
    - "Inventory service checks stock"
 
status: ACTIVE
version: "1.2.0"

Validation Criteria

A valid flow artifact MUST:

  1. Have a unique ID matching pattern F-<SYSTEM>-<NAME>
  2. Have a meaningful goal expressed as an outcome
  3. Have at least one precondition enabling the flow
  4. Have at least one step referencing a valid Interaction ID
  5. Have at least one postcondition guaranteeing the outcome
  6. Have step ordering with consecutive numbers starting at 1
  7. Reference only valid artifact IDs (I-, INV-, C-*)
  8. Have satisfiable step sequence (each step's pre enabled by prior context)


Common Pitfalls

  • Writing a flow as prose only (without stable references to I-* interactions and EP-* surfaces).
  • Skipping preconditions/postconditions, making later scenarios and explorations ambiguous.
  • Treating a “happy path” as exhaustive; flows should enumerate security-relevant variants.