Lifecycle
Table of Contents
This document is the generic state machine that applies to every stateful document — tasks, stories, sprints, and versions. It defines what each TODO keyword means, the legal transitions between them, and the rules audit uses to verify the system is healthy. It is not agile-specific — the rhythm around these states lives in agile process — and it is not document-type-specific — per-type frontmatter and section requirements live in document types.
Principle
State lives inside the document, as the TODO keyword on the * Status
headline. The folder structure encodes composition only — which version, sprint,
story, or task the document belongs to. Folders never carry state.
Transitions are TODO keyword changes (one edit, or C-c C-t in emacs).
Org auto-stamps the transition in the headline's LOGBOOK and adds
CLOSED: when entering a terminal state.
Task lifecycle
TODO vocabulary: DISCOVERED BACKLOG STARTED BLOCKED | DONE ABANDONED.
Source: task_lifecycle.puml. Regenerate with
plantuml -tpng doc/meta/task_lifecycle.puml.
Meaning of each state:
DISCOVERED- spotted in passing while executing another task; not yet triaged. Minimum content: title, description, link back to the discovering task.
BACKLOG- triaged into a story, scheduled but not started.
STARTED- an agent or human is actively working on it.
#+owneridentifies them. BLOCKED- paused waiting on review, CI, a local build, or anything
external. The reason lives in
#+blocked_on; the timestamp in#+blocked_since.BLOCKEDis a real state, not just an attribute — agenda views and audits treat it distinctly fromSTARTED. DONE- PR merged. Task document updated with
* Result. Org has stampedCLOSED:on the Status headline. ABANDONED- explicitly dropped. Must record why in the
* Notessection.
Where a discovered task physically lives
If the discovered task is logically related to the current story, it is
filed in-place under that story with state DISCOVERED:
versions/v0/sprint_NN/<current_story>/<discovered_task_slug>/task.org
If it does not fit the current story (or any active story), it goes to the sprint-level inbox:
versions/v0/sprint_NN/inbox/<discovered_task_slug>/task.org
The orchestrator (System 2) makes this classification when filing the
task. Triage promotes the file to BACKLOG and, for inbox tasks, moves
the folder under the story that eventually claims it.
Triage rule
Discovered tasks must leave DISCOVERED within one System 2 session of
the story or sprint they were discovered in. They move to: BACKLOG
(claimed by the same story), BACKLOG under a different story (folder
move), the product backlog (as a deferred story candidate), or ABANDONED
with a reason.
Story lifecycle
TODO vocabulary: BACKLOG STARTED | DONE ABANDONED.
Transitions:
BACKLOG → STARTED- the sprint claims the story (the user assigns it to an orchestrator).
STARTED → DONE- every task in the story is
DONE,ABANDONED, or has been explicitly moved to a future story (with a recorded reason in* Notes). * → ABANDONED- the story is dropped. Record why in
* Decisions.
Cross-sprint stories
A story belongs to exactly one sprint. When work does not fit, the preferred pattern is not to drag the story across sprints but to close it in the current sprint and continue under a new story in the next:
- At sprint close, the story in sprint N moves to
DONEreflecting whatever landed. Tasks that didn't make it are either moved to the successor'sBACKLOGor recorded in the predecessor's* Out of scope. - A successor story is created in sprint N+1 with:
- A fresh
:ID:and a slug suffixed with_continuedor_phase_2. #+predecessor: <id-of-prior-story>frontmatter.- A
Continued from: [[id:...][...]]line under the parent-sprint link.
- A fresh
- The predecessor is updated:
#+successor: <id-of-successor-story>frontmatter.- A
Continued in: [[id:...][...]]note in* Decisions.
The same pattern applies across version boundaries.
Tasks can carry over in practice (an attempted task in sprint N
finishes in sprint N+1). The task itself lives where it finished; we
don't track per-task predecessor links. If the original attempt was
substantial enough to matter, it is mentioned in the task's * Notes.
Discovered work that doesn't fit either the current sprint or the next goes to the product backlog rather than into a sprint. System 3 (sprint planning) pulls it into a sprint when it fits.
Sprint lifecycle
TODO vocabulary: STARTED | DONE.
A sprint is STARTED while it is the current sprint (the
lexicographically highest sprint_NN/ folder under the version).
Closing a sprint requires:
- The
* Retrospectivesection filled. - The release notes generated (if applicable).
- TODO state moved to
DONE.
No BACKLOG for sprints: a sprint exists when its folder exists.
Future sprints are not pre-allocated.
The process a sprint goes through — planning (define mission, choose stories, decompose), execution (run tasks), closure (release notes, release, post-mortem) — is detailed in agile process / Sprint phases. The state machine here is just the two endpoints those phases bracket.
Version lifecycle
TODO vocabulary: STARTED | RELEASED.
A version is STARTED while it is the active version (one at a time).
On release, TODO moves to RELEASED and a release note is generated.
Plan lifecycle
Plans are not on a TODO. They live as a * Plan section inside the
task or story document. (Tasks are flat files, not folders, so there
is no separate plan.org.)
- Created when System 1 or System 2 needs to think before acting.
- Closed when the task lands: decisions distil into the parent story's
* Decisionssection. The* Plansection is then cleared or summarised into* Notes. Plans must not outlive their task.
Knowledge, recipes, functions
Not stateful by TODO. Audit may attach a :stale: tag for review, but
these documents do not change state through the lifecycle machinery.
What audit checks
- Every stateful document has a
* Statusheadline with a valid TODO keyword from its document type's vocabulary. DISCOVEREDtasks are no older than one System 2 session.STARTEDandBLOCKEDtasks have#+owner,#+branch, and#+blocked_onset.BLOCKEDadditionally has#+blocked_sinceno older than a configurable threshold.#+updatedis fresh for any task inSTARTEDorBLOCKED(the heartbeat).- No plans survive the closure of their parent task.
STARTEDstories have at least one task inSTARTED,BLOCKED, orDONEwithin the last N days.- Every id-link resolves.
- For every story carrying
#+predecessor, the target story has a matching#+successorpointing back (and vice versa).