Task Planning

SkillProductivity

Use when work spans multiple steps, phases, or sessions, when resuming a task started earlier, when the user asks for a plan/roadmap/progress tracking, or when they use the `/dxos:project` command (any verb — list, tasks, new, end, track, hydrate, resume). Covers the project registry, maintaining a durable TASKS.md + DESIGN.md per work-stream, and checkpointing/reloading project state across sessions and PRs.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Task Planning skill

What this skill tells your AI

The instructions your AI receives, as published by dxos/dxos in tools/claude/plugins/dxos/skills/task-planning/SKILL.md and read by ahel’s review.

Overview

TASKS.md at the root of the unit of work you are actively in — usually a package, or the directory you're working in when there is no package (e.g. a skill, a hook, a script) — is the durable, committed task ledger for that work. It survives context resets and new sessions, so both you and the user can resume mid-task and see exactly what is done, in progress, and pending.

It is distinct from in-session TodoWrite: TodoWrite is ephemeral scratch for the current turn; TASKS.md is the persistent source of truth that lives in the repo. Use your judgment about when a task warrants one — err toward creating it.

Never reach for a background task chip (spawn_task) to record a follow-up on the work you're doing — that follow-up belongs in TASKS.md. Task chips are only for genuinely separate work that should spin off into its own session.

Projects (registry)

A project is a work-stream — one coherent effort, usually one branch/worktree — with its own TASKS.md (the ledger) and DESIGN.md (the why: spec + decisions). All projects are listed in a committed registry so you and any future session can see everything in flight and resume the right one.

Registry — one entry per project, recording where its docs and PRs live. Its location is not fixed by this skill: the /dxos:project directive ends with a BACKEND: line naming the store (by default the file .agents/projects/registry.yml, overridable via DX_PROJECT_REGISTRY). Obey that line; a future backend is a service rather than a file, and the schema below is the shape either way.

projects:
  - name: mailbox-research # stable slug
    status: active # active | paused | blocked | ended
    user: burdon # owner (git/system username, e.g. `whoami`)
    host: burdon-mbp-2022 # machine the project lives on (`hostname -s`)
    created: 2026-07-05
    summary: One line — what this stream delivers.
    tasks: path/to/TASKS.md # a package file, or <registry-dir>/<name>/TASKS.md
    design: path/to/DESIGN.md # spec + decisions (a REPORT.md counts)
    prs: [12163]
    resume: 'The single next action.'
ended: []
  • The registry records the location of each doc, so an existing effort points at its package files and a brand-new project defaults to <registry-dir>/<name>/{TASKS.md,DESIGN.md}. Keep it committed and current.

The /dxos:project command

/dxos:project VERB [ARGS] drives the registry — (bare) | list [all] | tasks | new | end | track | hydrate | resume. The per-verb instructions are not repeated here. The plugin's hooks/track.sh reads the raw typed text on UserPromptSubmit and injects the directive for the verb actually given; that directive is authoritative and arrives whether or not the command expansion does. Follow it, obey its BACKEND: line, and confirm in one short line.

This file covers what applies without the command — the TASKS.md convention, the registry schema, and the handoff steps below — because the skill loads on "work spans several steps" or "resuming work", when nobody has typed anything.

A lone number in the user's next message after a /dxos:project list table means "resume the project at that row". With no argument, resume/hydrate fall back to the single active entry for the current user; if more than one is active, ask which (list them numbered) — never a guess.

The registry deliberately does not record a branch/worktree. Each session runs in a fresh harness-assigned worktree, and a project's original branch is typically already merged to main, so there is nothing stable to match. On resume, never warn about a worktree/branch "mismatch" — a fresh worktree is the expected state — and never leave the assigned worktree to chase the project's old one: do not cd into, edit in, or adopt another worktree or branch as a working directory. If unmerged prior work lives elsewhere, report where it is and ask the user; continuing the work-stream always happens in this session's own worktree.

When to Use

  • Work spans 3+ distinct steps, multiple files, or phases.
  • The task will likely outlive one session (you'll resume it later).
  • The user asks for a plan, roadmap, or to track progress.
  • The user uses /dxos:project track <text> — always record the item, never a task chip.
  • You are resuming work — read the existing TASKS.md first to reload state.

When NOT to use:

  • Throwaway one-offs (a single edit, a quick answer) — just do them.
  • Cross-package chores with no single home — keep those in TodoWrite.
  • Duplicating TodoWrite — pick one; don't mirror the same list in both.

Location & Format

One file per unit of work: <root>/TASKS.md, where <root> is the package root when there is one (e.g. packages/plugins/plugin-magazine/TASKS.md), or otherwise the directory you're working in (e.g. tools/claude/plugins/dxos/skills/task-planning/TASKS.md). Match the existing convention:

# <Package> — Tasks

## Phase 2: <goal>

Short paragraph of context — what this phase delivers and why.

### Tasks

- [ ] **Headline task**
  - Concrete sub-step with the specific API/file involved.
  - Another sub-step.
- [x] **Completed task** — one-line note on what shipped.

### References

- Links to specs, external docs, related PRs.
  • Phases are ##; tasks are - [ ] / - [x]; detail as nested bullets.
  • Keep headlines imperative and specific; put the why in the phase context.

Workflow

  1. At task start — read the existing TASKS.md (if any) to reload state; otherwise create one with the phase and its tasks.
  2. As you work — check off - [x] in the same change that completes the work. Never leave checkboxes stale, and never batch-check everything at the end.
  3. When parking a task — leave a one-line status note on the item (what's blocked, what's next) so it's resumable.
  4. Before claiming done — reconcile TASKS.md against reality: every checked item is actually complete, and no completed work is left unchecked.
  5. Commit itTASKS.md is committed alongside the work it tracks. Do not leave it as an uncommitted local edit (see "commit nothing silently").

Project handoff (/dxos:project hydrate / /dxos:project resume)

TASKS.md is the handoff medium — no separate HANDOFF.md (keep plans in the original doc). The two verbs are the explicit checkpoint/reload actions.

/dxos:project hydrate — checkpoint before stopping or opening a PR

  1. Reconcile TASKS.md — check off what's done; add a one-line status note to each in-progress item (what's blocked, what's next).
  2. Refresh the resume pointer — a single italic line under the title: _Resume: <the one next action>. Uncommitted: <none | files>. Last: <what just landed>._
  3. Push the why into the design doc (if the work has one — REPORT.md, DESIGN.md, a spec): decisions and findings live there; TASKS.md stays the ledger. Save durable, cross-session direction to memory (it auto-loads next session) — not to a doc.
  4. Account for uncommitted workgit status; commit everything or state plainly in the resume pointer what's left uncommitted. Uncommitted work is the number-one thing a resumed session loses.
  5. Confirm the checkpoint in one short block (done / in-progress / next / uncommitted).

/dxos:project resume — reload at the start of a session

  1. Stay put — resume continues the work-stream in this session's assigned worktree; never cd into or adopt the project's previous worktree/branch. If unmerged prior work lives elsewhere, report it and ask the user.
  2. Read the active TASKS.md (and any doc it links); memory is already loaded.
  3. Check the treegit status + recent git log; surface uncommitted work and the last commits.
  4. Report a concise state: done / in-progress / next action / uncommitted.
  5. Continue with the next action, or wait for direction if the user gave any.

Viewing

Open TASKS.md directly to see it rendered — Claude Code previews Markdown files in the Browser pane, so the checklist is visible while you work.

Common Mistakes

MistakeFix
Stale checkboxes (work done, box unchecked)Update TASKS.md in the same edit as the code.
Spawning a task chip for an in-scope follow-upRecord it in TASKS.md; chips are only for separate spin-off work.
TASKS.md in the wrong package/directory or worktreeWrite to the unit of work you're actually editing, in the session's worktree.
Duplicating TodoWrite and TASKS.mdTASKS.md = durable/committed; TodoWrite = in-session scratch. Don't mirror.
Leaving TASKS.md uncommittedCommit it with the work; account for it in git status.
Batch-checking all items at the very endCheck off incrementally as each task lands.

Signals

GitHub stars
520
Forks
49
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
task-planning
Source
github.com/dxos/dxos