Skip to main content
Every feature and fix has a ## Tasks section. The parser walks this section to compute per-feature progress (completed / total) that the dashboard surfaces as a progress bar. The shape is rigid because the parser has to work on prose that humans and LLMs both write.

The contract

Three rules:
  1. The ## Tasks heading must be exactly that — ## Tasks, H2, capital T.
  2. Each task starts with ### N. Title — H3, digit number followed by a period, then the title.
  3. The next non-blank line must be status: <value>. Anything between this status: line and the next ### N. heading is the task body.
Anything outside this shape is invisible to the parser. You can put prose before the first ### 1. heading; that’s the “Tasks section preamble” and is ignored.

status: values

Anything else is rejected on push.

Task numbering

Tasks are numbered for readability. The parser tolerates non-sequential numbers — ### 1., ### 2., ### 5. parses to three tasks — but the CLI’s nt fmt will renumber to be sequential. Reordering tasks (cut-and-paste a ### 3. to before ### 2.) is fine; the parser uses heading position, not the literal number, to determine order.

Task body — optional, conventional sections

The body has no required structure, but a few **bold:** patterns are treated specially by the CLI’s nt task subcommands and by some agent integrations:
These are conventions, not requirements. The parser doesn’t error if you omit them.

What “completed total” means on the dashboard

Per-feature progress = (count of tasks with status: completed) / (total task count, excluding deferred). A feature with 1 completed, 1 in_progress, 1 deferred shows as 1 / 2 — deferred tasks are excluded from the denominator so a punted task doesn’t drag the bar down.

Mistakes the parser catches

nt fmt reports each of these with a fix-up suggestion before pushing.

See also