Tasks use the Links field to hold dependencies. The dependencies are defined on the dependant task and link to the predicate (predecessor) task.
The dependencies use a two-character code. The first character indicates what condition the predicate task must be before this task can start, and can be "s" for started, "f" for finished, or "*" for any. The second character indicates what condition the predicate task must have for this task to be considered finished, using the same conventions. There are five valid options.
f* | finish-start | The predicate must finish before this task can start. |
s* | start-start | The predicate must start before this task can start. |
*f | finish-finish | The predicate must finish before this task can finish. |
*s | start-finish | The predicate must start before this task can finish. |
sf | start-start, finish-finish | The predicate must start before this task can start and the predicate must finish before this task can finish. |
A finish dependency does not stop the user finishing the task. The finish dependency is only used to determine whether dependant tasks consider that the task is finished.
As well as these explicit dependencies, there are implicit dependencies within the work breakdown structure. There is an implicit start-start dependency to parent tasks, i.e. parents must be marked as started before child tasks can start. There is an implicit finish-finish to child tasks, i.e. a parent cannot be considered finished until all the children are finished.
Dependencies are maintained through the task script or task step type.
Each task keeps track of whether it has started and finished, and also keeps track of whether it may start and may finish, i.e. whether its dependencies have been fulfilled. These indicators are maintained through the methods that change phase. If start dependencies are not met, then the ready() method will set the task phase to wait, rather than ready. The finish() method for a task will inform dependants that the task has finished only if its finish dependencies have been met.
The start and finish methods publish messages and these are available to related workers (parents, children and linked workers), allowing dependants to use an @consume action to react to changes in start and finish states. @consume would use the check taskAction of the task step type to recheck dependencies, which has an additional consume option to efficiently filter messages that may be relevant. This may change a wait phase to ready, or trigger a finish condition, if appropriate dependencies are met.