Deterministic weighted task sampling and task lifecycle handling for Org mode.
org-task helps you keep a focused, rotating shortlist of tasks without random churn.
org-task is designed for agenda-like workflows, without the need for explicit date scheduling. Instead it provides rotating shortlist of tasks with dynamic sampling.
- It reads eligible tasks from one Org file (default:
org-directory/tasks.org). - It samples
Ktasks using weighted deterministic sampling with temperatureT. - It keeps picks stable for a given seed (default seed: local date), so your list is reproducible.
- It supports task lifecycle metadata updates from both Org buffers and Org Agenda.
Why this package:
- A plain random list tends to reshuffle too much.
- A purely static top-priority list can starve other tasks forever.
org-taskbalances both: stable deterministic noise + weighted urgency/recency.
How it works at a high level:
- Each eligible task gets a stable
ID. - Weight is computed from base weight, tweak, age boost, and open-pressure boost.
- A deterministic pseudo-random value is derived from
(seed, id). - Tasks are ranked by weighted sampling key and top
Kare selected.
If you install directly from GitHub with straight.el:
(straight-use-package
'(org-task :type git :host github :repo "vardwyn/org-task"))If you use use-package + straight:
(use-package org-task
:straight (:type git :host github :repo "vardwyn/org-task"))Use this as a practical default setup:
(use-package org-task
:straight (:type git :host github :repo "vardwyn/org-task")
:after org
:custom
(org-task-file (expand-file-name "tasks.org" org-directory))
(org-task-include-tag "task")
(org-task-default-k 5)
(org-task-default-temperature 1.0)
(org-task-age-s0 7.0)
(org-task-age-alpha 1.2)
(org-task-open-s0 7.0)
(org-task-open-alpha 1.2)
(org-task-once-backlog-keyword "TODO")
(org-task-once-active-keyword "STRT")
(org-task-finalize-keyword "FIN")
:config
(org-task-mode 1)
(add-to-list
'org-agenda-custom-commands
`("T" "Sampled org-task list"
,(list (org-task-agenda-block "Sampled org-task entries" 5 1.0)))))Minimum data model in your task file:
- Use leaf headings tagged
:task:as sampleable tasks. - Non-leaf headings can hold inherited properties for subtrees.
IDis created automatically when needed.- If you want fast TODO selection in agenda (e.g.
t d,t s), define TODO keywords with fast keys, e.g.#+TODO: TODO(t) STRT(s) | DONE(d) FIN(f).
Sample tasks from Lisp:
(org-task-sample-tasks) ;; uses configured defaults
(org-task-sample-tasks 8 0.8) ;; explicit K and temperatureShow sampled titles in minibuffer:
(message "%S"
(mapcar #'org-task-core-task-title
(org-task-sample-tasks)))See also tasks.org for example task file.
Extend agenda views:
- Use
org-task-agenda-blockto inject sampled tasks into custom commands. - Or call
org-task-agenda-skip-non-sampleddirectly in a hand-written block.
Helper block (recommended):
(org-task-agenda-block "Sampled org-task entries" 5 1.0)Manual block wiring:
(tags "task"
((org-agenda-files (list org-task-file))
(org-agenda-skip-function '(org-task-agenda-skip-non-sampled 5 1.0))))ID: Org built-in stable identifier used for deterministic sampling keys.ORG_TASK_WEIGHT: inherited base weight multiplier.ORG_TASK_TWEAK: per-task tweak multiplier; if unset, Org priority maps to tweak (high=2.0,default/none=1.0,low=0.5).ORG_TASK_AGE_S0,ORG_TASK_AGE_ALPHA,ORG_TASK_AGE_CAP: per-task age boost controls.ORG_TASK_OPEN_S0,ORG_TASK_OPEN_ALPHA,ORG_TASK_OPEN_CAP: per-task open-pressure controls.ORG_TASK_REPEAT:repeat(default) oroncelifecycle mode.ORG_TASK_OPENED_ON: first-open date for once-tasks (YYYY-MM-DD).ORG_TASK_LAST_DONE: last completion date (YYYY-MM-DD).
- Repeat tasks (
ORG_TASK_REPEAT=repeat):- Marking done with non-final done keyword updates
ORG_TASK_LAST_DONEand reopens task. - Marking done with finalize keyword (default
FIN) keeps task closed permanently.
- Marking done with non-final done keyword updates
- Once tasks (
ORG_TASK_REPEAT=once):- First non-final done (typically
TODO -> DONE): writesORG_TASK_OPENED_ON, moves task toSTRT. - Subsequent non-final done while opened: updates
ORG_TASK_LAST_DONE, keepsOPENED_ON, moves back toSTRT. - Final done using finalize keyword (
FIN): updatesLAST_DONE, keeps task closed.
- First non-final done (typically
Hook transitions work from both Org buffers and Agenda TODO changes.
Run tests from repo root:
make test