Skip to content

Task ordering specification

Tasks in gtdhelper are displayed in a three-tier ordered list. Each tier has its own sort rules, and drag-and-drop allows users to override automatic ordering within any tier.

Tasks are displayed in this priority order:

1. Pinned tasks (pinned == true)
2. Manually-ranked (pinned == false, manual_rank is Some)
3. Auto-sorted (pinned == false, manual_rank is None)

Within each tier:

TierDefault sortManual override
Pinnedupdated_at DESCYes — drag reorders within pins
Manually-rankedmanual_rank ASCYes — drag updates rank
Auto-sortedupdated_at DESCN/A (no rank set)

Each task can optionally have a manual rank. Pinned tasks with a manual rank appear first (sorted by rank), followed by pinned tasks without a rank (sorted by most recently updated). The same logic applies within unpinned tasks: manually-ranked items come before auto-sorted ones.

When you drag a task to a new position, ranks are reassigned as contiguous integers within the relevant tier (pinned or unpinned) to avoid gaps and collisions.

Two mechanisms to clear a task’s manual_rank (set it back to None):

  1. Context menu on grip handle: Right-click the drag handle → “Reset to auto-sort”. Sets manual_rank = None for that task.
  2. Drag to auto-sorted section: Dragging a manually-ranked task past the section divider into the auto-sorted section clears its manual_rank. The auto-sorted section highlights as a drop target during drag.

No bulk reset. Users reset individual tasks only.

  • All rows are draggable.
  • Dragging within the pinned section reorders within pins.
  • Dragging within the unpinned section sets a manual rank on the task, moving it from auto-sorted to the manually-ranked tier.
  • Dragging a manually-ranked task into the auto-sorted zone clears its manual rank.
  • Manually-ordered rows: Always show a subtle grip handle (drag dots).
  • Auto-sorted rows: Grip handle appears on hover only.
  • Section divider: A thin visual separator between the manually-ranked and auto-sorted sections (only visible when manually-ranked tasks exist).
  • manual_rank is preserved during merges, like snoozed_until.
  • New tasks from sources appear in the auto-sorted tier (no manual_rank).
  • Tasks that disappear from sources retain their manual_rank in the persisted state (they become snoozed/archived as usual).

Pinning and manual ordering are orthogonal:

  • pinned controls which tier a task is in (tier 1 vs tier 2/3).
  • manual_rank controls position within a tier.
  • A pinned task can have a manual_rank (custom position within pins) or not (auto-sorted within pins by updated_at).
  • Unpinning a task with a manual_rank moves it to the manually-ranked unpinned tier, keeping its rank.

There is no cap on manually-ordered tasks. The auto-sorted section shrinks as more tasks are manually placed.