Skip to content
Search

How dependency scheduling works

A dependency makes one item wait for another. When a date changes, Teamhood moves the waiting items later by the fewest working days that keep every dependency true. A date change never moves an item earlier, and scheduling never moves the item you just placed.

Working days are Monday to Friday for the whole organization, and holidays still count as working days. Every day count in scheduling is in working days: lag, the days an item moves, and the free days before a limit.

A dependency joins a predecessor, the item that goes first, to a successor, the item that waits. The dependency sets the earliest date the successor may have. Scheduling always reads and writes the Start and Finish fields. A Gantt that maps other date fields draws its bars from those fields, and a drag there changes only them.

TypeDate it limitsEarliest allowed date
Finish to Startthe successor’s startthe next working day after the predecessor’s finish
Start to Startthe successor’s startthe predecessor’s start
Finish to Finishthe successor’s finishthe predecessor’s finish
Start to Finishthe successor’s finishthe predecessor’s start

Finish to Start is the default. Lag adds whole working days to the earliest allowed date, and weekends are skipped. A negative lag is a lead, and it moves the earliest allowed date earlier by that many working days.

  • Start or Finish changes, from any screen, for one item or for many at once.
  • A dependency is added. The successor moves only if it now sits too early, and only by the missing days.
  • The type or lag of a dependency changes. The successor is fitted exactly to the new rule, so it can move earlier or later. It never passes a limit set by another predecessor, its own or one of its ancestors’.

Three changes never reschedule:

  • removing a dependency;
  • dates written by the public API, an import or a webhook;
  • moving an item to a different parent.

A push travels down the whole chain, from successor to successor. An item with several predecessors moves by the largest number of missing working days.

A successor with enough free days before its limit absorbs the push, and the chain stops there. Every moved item keeps its length in working days. An item moved across a weekend covers more calendar days, because the weekend days are not counted.

Dependencies push and never pull. A successor placed later than its dependency requires stays where it is, and moving a predecessor earlier moves nothing.

To close a gap, change the lag, or use Re-apply link in the dependency editor. It names the date it moves the successor to, and it is hidden when nothing would move.

When you place one item by hand, every dependency of that item takes the gap now drawn as its lag. Placing means a Gantt drag or resize, or a date edited in the item details or in a date cell.

  • Drag a predecessor earlier, and its successor stays. The lag grows by the working days you left empty.
  • Drag a successor in front of its predecessor, and the dependency takes a lead.
  • A successor that scheduling pushed keeps its lag, because it sits exactly on its limit.

After the lag grows, the successor has no free days left, so the next later move of the predecessor pushes it at once. A change to many items at once does not rewrite any lag.

A dependency you draw between two items on the Gantt starts with the gap between them as its lag. If the successor sits too early for the new dependency, the dependency starts with lag 0 and scheduling pushes the successor.

  • The item you placed. Its dates are your input.
  • A predecessor, for its own links. Scheduling moves successors only. A predecessor still moves when a parent above it moves as a block.
  • An item with no dates anywhere below it. It neither limits nor moves, except in the case described under When empty dates are filled in. A parent with no dates of its own is scheduled on its children’s span.

Scheduling fills in dates for one kind of item: a successor with a Duration (d) and no dates anywhere below it. When a change reaches such a successor and one of its predecessors has dates, scheduling places it where its dependencies require. Its finish follows from the Duration (d), and its own successors are pushed like any other.

A parent is scheduled on its whole span, its own dates and the dates of every item below it. When a parent must move as a successor, every dated item under it moves by the same number of working days, and the spacing between them is kept. Changing a Start the parent already had moves every dated item under it the same way.

After you add or change a dependency, a message such as Rescheduled 4 items offers Undo. The count includes every dated item inside a moved parent.

A new dependency is refused when it would:

  • link an item to itself;
  • link an item to anything above or below it in the hierarchy;
  • repeat a dependency the two items already have;
  • close a loop.

The refusal appears while you pick or drag, and again when the change is saved. On save, a loop is named in full, for example “Would create a loop: Build → Test → Deploy → Build”.

A broken dependency is one whose successor sits earlier than the dependency allows. The dependency editor states how many working days too early. The two views draw a broken dependency differently:

  • On the Gantt, a broken dependency is a dashed red arrow.
  • On the mind map, a broken dependency is a red arrow. A dashed arrow there means a dependency of any type other than Finish to Start, so a broken dependency of such a type is red and dashed.

Scheduling never leaves the successors it moves too early. A broken dependency comes from a change that left the dependency behind. Examples are an import, a public API or webhook write, or a move to a new parent. A change to many items at once can also put one before its predecessor.

While the critical path is on, a solid red arrow on the Gantt is not broken. It is a dependency that drives the critical path. A broken dependency stays dashed.

Red on a bar is a different signal. It marks the part of a child’s bar that runs past its parent’s finish. While a baseline is selected, a red bar marks a finish that slipped against the baseline. While the critical path is on, a red line along the bottom edge of a bar marks a critical item, and a red bracket marks a critical parent.

Every arrow on the mind map is the same dependency the Gantt draws, stored once. A dependency drawn on the mind map is Finish to Start with no lag, and it reschedules like any other.

A plan is a top-level item and every item below it. Top-level means the item has no parent at all. A view that shows only part of a plan, such as the contents of one item, still measures float against the whole plan. The plan finishes on the latest finish inside it.

Total float is how many working days an item can finish later before a plan finishes later. That plan is the item’s own plan, or a plan that waits on it through a dependency. An item with no float left is critical, and the critical items together are the critical path.

  • Float is counted in working days, so holidays count as working days here too.
  • Float is measured on the Start and Finish fields, at the dates every item would have with all dependencies met. When no dependency is broken, those are the dates the items have now.
  • A Gantt that maps other date fields still takes float and the critical path from Start and Finish. Its bars can then disagree with its critical marks.
  • A parent is critical when its own dates, or any item below it, are critical.
  • A completed item is never critical: finished work cannot delay the plan any more. Its float is still shown, and it still holds back the items that wait on it. A parent whose only critical items are completed is not critical either.
  • A dependency between two top-level items carries float across them, so a late item in one plan can make another plan finish later.
  • Float cannot be worked out for an item without both a start and a finish date, unless an item below it has both. Nor can it for an item in a loop of dependencies, an item with such a loop below it, or an item that waits on one. The Total float cell of such an item shows a dash.
  • Float is worked out in your browser whenever a Start or Finish date, a dependency, completion or an item’s parent changes. Nothing is stored, and turning the critical path on or off changes nothing for anyone else.

Until float has been worked out for every item in the view, which can take a moment after the critical path is turned on or the view changes, nothing fades and no bar or arrow turns red. The key at the bottom appears straight away.

  • Bars, brackets, dotted rails, baseline ghosts and arrows that are not critical are drawn faded. On a grouped view, a group’s bracket is never critical, so it fades too.
  • The buttons at the left and right edges of the timeline, which scroll to a bar out of view, do not fade.
  • A faded bar still moves, resizes and opens as usual. Point at a faded bar and it returns to its normal strength. Faded brackets, dotted rails and baseline ghosts stay faded.
  • A critical item gets a red line along the bottom edge of its bar. A critical parent’s bracket turns red.
  • A dependency between two critical items, with no gap between them, is drawn as a solid red arrow. It drives the critical path.
  • A broken dependency stays a dashed red arrow. A broken dependency that drives the critical path stays at full strength. Every other dashed arrow fades.
  • The key Critical path — open items with no float sits at the bottom of the timeline, centred. The key replaces the bracket that spans the whole view. That bracket comes back when the critical path is turned off.
  • A negative number means the plan already finishes later. Its hint starts with Over by.
  • A dash means float cannot be worked out. The cell also shows a dash briefly while the column first loads.
  • Sorted ascending, the least float comes first. Sorted descending, the most float comes first. Rows with a dash sort last in both directions.
  • Export to CSV writes the plain number, and an empty cell where the screen shows a dash.

Three items, each joined by Finish to Start. The dates are in March 2026.

ItemDatesWaits for
DesignMonday 2 to Friday 6 Marchnothing
BuildMonday 9 to Friday 13 MarchDesign, lag 0
TestWednesday 18 to Thursday 19 MarchBuild, lag +2

Build starts on Monday 9 March, because the weekend after Design finishes is skipped.

  1. Drag Design 3 working days later, to Thursday 5 to Wednesday 11 March. Design keeps its 5 working days across the weekend.
    • Build must now start on Thursday 12 March, so it moves to Thursday 12 to Wednesday 18 March.
    • Test must start on Monday 23 March, so it moves to Monday 23 to Tuesday 24 March.
    • No lag changes.
  2. Drag Design 2 working days earlier, to Tuesday 3 to Monday 9 March. Build and Test stay. The dependency from Design to Build now shows lag +2, the 2 working days you left empty.
  3. Set that lag back to 0 in the dependency editor. Build is fitted to the new rule and moves earlier, to Tuesday 10 to Monday 16 March. Test stays, because a fit reaches only the successor of the dependency you edited.
  • No item is pinned. A completed item with dates moves like any other, and no setting holds dates in place.
  • A single undo step reverts the dates you changed, every item that scheduling moved, and any lag your placement rewrote.
  • A dependency held by a parent is not given a new lag when you place one of its children, so it can stay red.
  • A dependency whose successor you may not edit is never given a new lag. Your drag still lands, and that dependency can stay red.