Skip to content

04. Workflow and State Model

Why This Page Matters

If a newcomer understands only one architectural idea in this repo, it should probably be this one:

the workstation behaves through explicit state, not through scattered boolean flags and UI event shortcuts.

That choice drives command availability, machine readiness, run transitions, fault handling, and recovery semantics.

The Central State Model

The most important state type in the repo is:

  • src/InspectionPrototype.Application/State/AppState.cs

AppState is the canonical runtime snapshot. It includes:

  • connection state
  • workflow state
  • motion state
  • camera state
  • safety signals
  • stage position
  • loaded recipe and recipe catalog
  • active run and last run summary
  • run history
  • active alarms and diagnostics
  • latest telemetry and frame
  • pipeline counters and operational counters
  • simulator profile catalog and selected profile

This is the concrete implementation of ADR-001.

Why A Canonical State Store Was Chosen

Without one central state model, this app would be unusually easy to break:

  • background services would update UI state directly
  • command guards would drift apart
  • machine readiness would become inconsistent
  • tests would need to boot more of the UI stack to verify behavior

The central store is not there for style points. It is there because the app has several independent producers:

  • workflow orchestration
  • motion updates
  • safety signal changes
  • telemetry streaming
  • frame streaming
  • fault injection and clearance
  • startup hydration for history and recipes

Workflow State

The most visible state machine is WorkflowState:

  • Idle
  • Preparing
  • Homing
  • Ready
  • Running
  • Stopping
  • Stopped
  • Completed
  • Aborted
  • Faulted

Relevant file:

  • src/InspectionPrototype.Application/State/WorkflowState.cs

The happy-path story is simple:

Idle or Ready -> Preparing -> Running -> Completed

But the real teaching value comes from the non-happy paths:

  • Homing is explicit
  • Stopping is explicit
  • Aborted is distinct from Stopped
  • Faulted is distinct from both operator stop and operator abort

Quick Workflow Sketch

text
Idle/Ready
    |
    v
Preparing --> Running --> Completed
               |
               +--> Stopping --> Stopped
               |
               +--> Aborted
               |
               +--> Faulted --(clear + recover)--> Idle/Ready

Homing --> Idle/Ready

This sketch is intentionally simplified, but it captures the teaching point: the repo models graceful stop, immediate abort, and unsafe fault as different runtime stories.

Command Guards

Command enablement is intentionally derived from state rather than hand-maintained in the UI.

Relevant file:

  • src/InspectionPrototype.Application/Guards/CommandGuards.cs

This means commands such as:

  • Connect
  • Home
  • Start
  • Stop
  • Abort
  • Acknowledge
  • Recover

all use the same underlying runtime truth.

That is a strong teaching example because it prevents a common WPF mistake: putting business rules inside button-enable logic spread across view models and XAML.

Workflow Ownership

WorkflowService owns state transitions and runtime coordination.

Relevant file:

  • src/InspectionPrototype.Application/Services/WorkflowService.cs

This service coordinates:

  • connection lifecycle
  • homing
  • run startup
  • stop and abort behavior
  • terminal run summaries
  • fault handling
  • recovery
  • history updates
  • recipe catalog loading into active state

This is one of the most important design decisions in the repo. The app prefers explicit orchestration over “smart” UI code.

Trade-Offs

Benefits

  • state transitions are inspectable
  • command semantics stay consistent
  • tests can verify runtime behavior without the full UI
  • the architecture matches the mental model of a machine workstation

Costs

  • AppState becomes broad
  • WorkflowService becomes a high-context file
  • newcomers must learn several related state types together

These costs are real. But they are easier to manage than hidden state duplication.

Practical Reading Path

To understand the runtime model well:

  1. read AppState.cs
  2. read WorkflowState.cs
  3. read CommandGuards.cs
  4. read WorkflowService.cs
  5. run the happy-path and stop/abort/fault scenarios while those files are open

That combination makes the architecture much easier to internalize.

Diagram Brief

  • Title: Workflow and canonical state model
  • Purpose: Show the main workflow states and how command guards depend on a wider canonical state snapshot
  • Audience: newcomer developer learning why the repo uses explicit state
  • Nodes: AppState, ConnectionState, WorkflowState, MotionState, SafetySignals, LoadedRecipe, ActiveRunState, ActiveAlarms, CommandGuards
  • Edges: AppState aggregates the other state partitions; CommandGuards evaluate AppState; WorkflowService mutates AppState; WorkflowState transitions between Idle, Homing, Preparing, Running, Stopping, terminal states, and Faulted
  • Grouping: Canonical state object, sub-state partitions, guard evaluation, workflow transitions
  • Caption: The workflow state machine is only one part of the model; command correctness depends on the full canonical app state
  • Destination file path: docs/diagrams/source/architecture-04-workflow-state-model.drawio

Docs-first project memory for AI-assisted implementation.