Capability Step Sequence Alternatives
=====================================

Handling QA with two states, one for the DA and one for the AOD is an
interesting conundrum for the capability step sequence. The naïve
implementation concept we had fails to address a few aspects of it,
namely that we may want user-defined state transitions, and also that we
may want some capability definition-level control over when the steps
are run and what happens afterward, since QA appears to be an operation
that takes versions as input.

Mealy Machine Approach
----------------------

An approach suggested by Mark Whitehead is to allow user-defined states
and transitions. This can be implemented as a Mealy machine. In a Mealy
machine, you have a set of states, inputs, and destination states. We
augment this concept with the idea that we perform an action during a
transition to another state. Suppose you have a machine like this:

.. image:: media/capability-step-sequence-alternatives-1.png

We can represent this machine as a table:

==================== ========= ====================== ===============
**Current State**    **Input** **Action**             **Next State**
==================== ========= ====================== ===============
Waiting for Approval approval  start workflow         Executing
Waiting for Approval reject    notify user            Complete
Executing            complete  notify DAs             Waiting for QA
Waiting for QA       approval  notify AOD             Waiting for AOD
Waiting for QA       retry     start workflow         Executing
Waiting for AOD      accept    start QA-pass workflow Complete
Waiting for AOD      rejected  notify DAs             Waiting for QA
==================== ========= ====================== ===============

In this design the step sequence is replaced by this table and some
associated facts (what the start state is, at least). The states are
completely defined by this table, and may pertain only to this
particular capability (certain states, such as Complete, would have
meaning throughout the system). Every input is a message receipt, so
"input" needs to actually be a pattern, and what is obtained by the
pattern match needs to be available to the Action, somehow. The system
will have a finite set of actions, probably similar to the step
sequences we have now (send notification, execute workflow). A user
category could be permitted to force a request into a particular state,
bypassing the actions.

There are plenty of questions that need to be answered here but this
approach seems like a very human-friendly and flexible solution that is
considerably more powerful than the step sequence without being
especially dependent on third-party technology or greatly expanded
parsing.

BPMN Approach
-------------

Another approach suggested by Mark Whitehead is to investigate BPMN and
other business process systems, and see if we can create a pluggable
architecture for that. I think this is interesting and we have a story
to look into a prominent implementation in Python called "adhesive."

Python Steps
------------

Another approach would be to replace the step sequence with a real
programming language. It is possible to parse a piece of Python code
from Python, and I have a prototype of a mechanical transformation from
the natural syntax tree to a structure that can be paused and resumed at
any point in the computation. This requires a CPS (continuation-passing
style) transformation. The state of the step sequence is then embodied
in the continuation object and its state. In this manner, when you
execute a function that needs to wait, you simply return the message
pattern you want to reactive this computation along with the
continuation and local environment, and store these pieces in the
database. Later on when you want to resume the computation, you match up
the pattern to the continuation, retrieve it from the database and the
state, and resume the computation.

This approach is extremely flexible and powerful, but will be difficult
to understand, and would tend to leave the database in a state where it
would be hard for humans to inspect it and understand where we are in
executing a capability.