Dependencies and the critical path

How to make one request wait for another, which predecessors it waits for, what a lag does, and how Orkyo computes the finish date.

A dependency records that one request cannot start until another one finishes. Orkyo uses it in four places. The scheduler honors it, the conflicts list reports a breach of it, and the critical path comes from it. Orkyo also refuses to start a request before its condition is met.

Containment and sequence are different

Orkyo has two relationships between requests, and they answer different questions.

The tree says what a request is part of. A group holds children, and its dates roll up from them.

A dependency says what must happen first. It is independent of the tree: precedence routinely crosses group and site boundaries, so an edge joins any two requests rather than ordering siblings inside a group.

A request can therefore sit in one group and wait for work in another. That is normal.

What can be linked

Only schedulable requests — leaves — can carry a dependency.

A group’s dates are derived from its children and it never reaches the scheduler, so an edge on one can not be enforced. Orkyo refuses the link rather than record a promise it can not keep. For the same reason, a leaf that carries dependencies must lose them before it can become a group.

Orkyo also refuses two other links:

  • A request can not wait for itself.
  • A link that closes a loop is refused. If B waits for A, then A can not be made to wait for B, directly or through any chain of other requests.

The Children tab of a container shows Sequence these tasks. This opens the plan of that container. The canvas holds the tasks that a dependency touches, as cards joined by arrows, and a padlock marks each task that can not start. The tasks that no dependency touches yet are in an Unsequenced list beside it. A canvas of four hundred unconnected cards hides the few that carry the plan. A task moves onto the canvas after you select it. The guide Sequence the tasks in a plan explains how to draw the links there.

Finish to start, and the lag

Every dependency is finish-to-start: the successor starts after the predecessor finishes.

A lag adds a minimum gap after that finish. Use it for work that must settle — paint that has to cure, a part that has to cool. A lag only ever delays a successor. It can not pull one earlier.

Orkyo plans in whole days, so a lag is rounded up to the next day. A lag of four hours therefore delays the successor by one day.

The start condition

A request with several predecessors does not always wait for all of them. The start condition says how many it waits for. It belongs to the request that waits, not to one link, because it is a statement about the whole set.

There are three conditions:

  • All predecessors — the request starts after every predecessor is done. This is the default, and it is what every request did before conditions existed.
  • Any predecessor — one is enough. Two suppliers can deliver the same part, and either delivery frees the work.
  • At least k — the request starts after the chosen number are done. A sign-off can need two of three inspections.

A canceled or deferred predecessor leaves the set before Orkyo counts. The count of predecessors decreases with it, and a k larger than the set reads as “all of them”. Abandoned work therefore never holds a request shut, and nobody has to delete a link to record that it happened.

The condition is on the Dependencies tab of a request, under Can start when. Orkyo shows the control only for a request that waits for more than one thing. With one predecessor, all three conditions mean the same.

What the scheduler does with a dependency

Auto-schedule respects the start condition, and it will not do otherwise.

  • If both requests are in the same run, the scheduler places them in order.
  • If the predecessor is already scheduled, its finish date bounds the successor.
  • Under Any predecessor or At least k, the scheduler waits for the earliest predecessors that satisfy the condition, not for the last one.
  • If too few predecessors are scheduled or placeable to satisfy the condition, the successor stays in the backlog. Its reason reads “predecessor unscheduled”.

That last case is deliberate. A placement there creates a conflict the moment it lands, and a reason in the backlog is more useful than a plan that is wrong on arrival.

One run schedules one resource type. A successor whose predecessor needs a different type therefore waits for that type’s run. Schedule the predecessor’s type first.

The dependency conflict

If a start condition is not met, Orkyo reports a dependency violation on the successor:

  • It starts before enough predecessors finish, or before the lag has elapsed. This is an error.
  • Enough predecessors are unscheduled that the condition cannot be judged yet. This is a warning: the plan is incomplete rather than wrong.

A request that waits for all of its predecessors reports one conflict for each predecessor it starts too early against. Each conflict names that predecessor.

A request under Any predecessor or At least k reports one conflict for the whole set. The shortfall belongs to the set rather than to one link.

A condition that is already satisfied reports nothing. Under Any predecessor, an unscheduled second predecessor is not a problem, because the first one already frees the work.

Nothing is reported while the successor itself is unscheduled. A backlog item breaks no promise.

See Conflicts for how conflicts are surfaced.

Starting work early

Orkyo refuses to move a request to In progress while its start condition is unmet. The message names the shortfall, for example “2 of 3 predecessors must be done”. It also names the work that the request waits for.

A predecessor counts as done in two cases. Its scheduled window is in the past, or somebody marked it done. An unscheduled request that somebody marked done therefore counts, because a dependency is about order and not about placement.

This rule is about the deliberate act of starting work. A request whose scheduled window opens becomes In progress on its own, because the plan says it runs now. Work that is scheduled too early is a planning error, and the conflicts list reports it.

The critical path

The critical path is the chain of work that decides when everything finishes. A day lost on it is a day lost on the whole network.

Orkyo computes it with a forward and a backward pass over the dependency graph:

  • Earliest dates come from working forward: each request starts as soon as its start condition allows. Under Any predecessor that is the earliest predecessor, and under At least k it is the k-th earliest.
  • Latest dates come from working backward from the finish: each request starts as late as it can without moving anything after it.
  • Float is the gap between the two. It is how many days a request can slip before it costs something.

A request with zero float is critical.

A predecessor that the condition does not wait for carries float rather than lying on the critical path. Under Any predecessor, the branch that arrives second has slack, and Orkyo reports it as slack.

Two details are worth knowing.

Scheduled work anchors the path. When a request is already placed, its dates are facts about the plan, and the pass uses them rather than proposing something earlier. Only unscheduled work floats to where its predecessors allow.

Everything is in whole days. The scheduler plans in days, so the critical path reports days. A deadline on a request tightens its float, because it can not finish later than its own window allows.

Requests with no dependencies take no part in the critical path. They have nothing to be early or late against.