Identity
Table of Contents
This page defines the workflow Identity: the engine's own fixture, and the reference implementation of the step protocol. It runs the steps its request declares and reports the outcome each one asks for, so a caller exercises a completion, a completion with warnings, a failure, a compensation, a slow step and a long run from the shell, with no domain data and no other component. A run leaves the workflow instance and its steps behind, and changes no record of another component. Recovery is the engine's own path: a completed step that declared a compensation is unwound when a later step fails, and a failed step carries its error and its log to the progress read.
1. Purpose
The identity workflow exists to exercise the engine. It makes every path the engine supports reachable from the shell with no other component: a start and a dispatch, a step that completes, a step that completes with warnings, a step that fails, a run that compensates its completed steps, a step that waits so a run can be observed in flight, and a run of many steps. When it finishes, the workflow instance and its steps are the whole of what exists, and the progress read reports what happened.
The fixture is also the worked reference for the step protocol. Its step handler takes the step context from the message headers and reports its outcome through the same completion path a domain step uses, so a reader sees the contract implemented rather than described.
2. Participants
The caller starts a run from the shell, declaring the steps and the outcome each one reports, then follows the run. The workflow service owns the definition and serves both step subjects itself, because the fixture's work is the engine's rather than a domain component's. The process manager builds the step list from the request, dispatches one step at a time, records each outcome, and settles the run. The store holds the run, its steps, their results, errors and logs.
| Participant | Kind | Responsibility |
|---|---|---|
| Caller | role | Starts a run from the shell, declaring the steps and the outcome each one reports, and follows it |
| Workflow service | component | Owns the definition and serves both step subjects |
| Process manager | component | Builds the step list, dispatches each step, records each outcome, and settles the run |
| Store | store | Holds the run, its steps, their results, errors and logs |
| Client | component | Follows the run through the progress read |
3. Messages
One subject dispatches every step, because the payload rather than the subject says what a step does. A step is addressed by its name, so a later step reads an earlier step's result by name.
| Message | Subject | Objective |
|---|---|---|
| Start message | workflow.v1.ops.start_workflow |
Opens the run with the type identity_workflow and the request that lists the steps |
| Step command | workflow.v1.identity.step |
Dispatches one declared step to the fixture's own handler |
| Compensation command | workflow.v1.identity.compensate |
Dispatches the compensation of a completed step that declared one |
| Step completion | workflow.v1.ops.step_completed |
Reports the outcome the request asked for: completed, completed with warnings, or failed |
| Progress read | workflow.v1.ops.get_workflow_steps |
Returns the run's status and one summary per declared step |
| Retry action | workflow.v1.ops.retry_workflow_instance |
Resumes a stopped run from its failed step |
The fields the request carries, and the fields of a step within it:
Figure 1: The fixture's request: the steps to run, each naming the outcome it should report, whether it declares a compensation, and how long it should wait before it reports.
The fields of the step command and of the completion a step reports:
Figure 2: The fields a step command carries: the step identifier, the instance identifier, the tenant, and the payload the operation performs.
Figure 3: The fields a step completion carries: the step identifier it echoes, the outcome, the result, the error, and one log entry per item the step could not do cleanly.
4. Steps
Every step is one entry in the request, and its name is its identity. A step performs no domain work: it waits if the request asks it to, then reports the outcome the request declares.
| Operation | Produces | On failure |
|---|---|---|
| Report completion | The step marked completed, with the request echoed as its result | Nothing; the run advances to the next step |
| Report warnings | The step marked completed with warnings, with one log entry | Nothing; the run advances |
| Report failure | The step marked failed, with an error and a log entry | The engine compensates the completed steps that declared a compensation |
| Wait, then report | The outcome its behaviour declares, after the stated delay | The delay does not change the failure rule |
| Declare a compensation | A compensation subject on the step | The step is unwound when a later failure compensates the run |
A behaviour the request does not recognise fails the step rather than passing for a completion, so a mistyped request is visible in the run rather than silently succeeding.
5. Interaction
The diagram draws one run: the caller starting it, the process manager dispatching each declared step to the fixture's own handler, the handler reporting the outcome the request asked for, the compensation path when a step fails, and the client reading progress.
Figure 4: Identity: the caller starts a run declaring its steps, the process manager dispatches each one to the fixture's handler, the handler reports the declared outcome, a failure compensates the completed steps that declared a compensation, and the client follows the run through the progress read.
Source: identity_workflow_interaction.puml. Regenerate with
plantuml -tpng doc/knowledge/workflows/identity_workflow_interaction.puml.
6. Failure and recovery
The definition declares the compensate policy, because the fixture's completed steps are its own records and nothing a person expects to keep. What a failing run unwinds is decided by the compensation subjects the request declares: a completed step that declared one is compensated at a negative step index when a later step fails, and a completed step that declared none has nothing to undo, so the failure stands on the failing step with its error and its log.
A retry resumes a failed run at its failed step, under the same step identity, and the completed steps keep their results. The fixture's steps do no domain work, so a retry leaves no data to repair; its value is as a rehearsal of the engine's own path. The policies themselves live in failure, compensation and retry.
7. Progress
The fixture adds nothing to the platform's progress read. A client follows the
run through workflow.v1.ops.get_workflow_steps and renders one line per declared
step, with the step's state and its error. The states a run occupies are
pending, in progress, completed, completed with warnings, compensated and
failed, and a client must be ready to display each of them, because the fixture
can reach all of them from a request.
8. Patterns used
- Saga — the fixture compensates the steps that declared a compensation.
- Process Manager — the engine runs the steps the request declares.
9. Related
- The workflow definition — how this definition is registered, and what a change to it does to a run in progress.
- The step protocol — the contract the fixture's handler implements.
- The workflow instance and step states — the states a run of the fixture occupies.
- Workflows — the structure note for the workflow cluster this page belongs to.
- Workflow pages — the inventory of the platform's workflows.
- Document type: workflow — the contract this page follows.
- Task: Add the identity workflow and the commands that drive it — the task that built the fixture.
- The shell recipes — the six configurations of this workflow: happy path, warnings, fail fast, saga, fan out and long running.
10. See also
- Garcia-Molina and Salem,
Sagas— the compensation the fixture exercises, and why a completed step must be able to undo itself.