/mdtask-do — Task workflow
Use the
mdtaskCLI to find and read tasks — don't hand-scan the Markdown files to discover or reason about them. Runmdtask list/mdtask view <ID>(add--jsonfor machine-readable output); open the Markdown only after the CLI points you at the exact task and file. Invoke it asmdtask <command>, or a project-defined wrapper such aspnpm mdtask <command>if the project sets one.
Flow
Gate — do this before reading any further. Your first action is to materialize the steps below as a live, checkable list and tick items off as you go (you'll confirm against it before the commit in Step 8). The tracked artifact is mandatory; the mechanism is whatever your harness offers — a task-list tool, a scratch ./tmp markdown checklist, or, if nothing else, the same checklist written into your visible reply. (For example: in Claude, the task tools — ToolSearch for select:TaskCreate,TaskUpdate, then TaskCreate one item per step; in Pi, a ./tmp markdown file.) The steps: Pick, Plan, Review plan, Execute, Behavior check, Review code, Final validation, Update spec, Commit. Don't summarize them in prose as a substitute; create the tracked list, then go straight into Step 1.
One checklist per run. Before creating this run's items, check (TaskList) for a checklist left by a previous task in this session. If there is none, or every item in it is closed, clear it and start fresh. If it still has open (unfinished) items, the rule depends on how you're running: interactively (the user is present and hasn't told you to act independently, here or in standing instructions) → STOP and ask the user what to do with them — never wipe someone's in-progress work; autonomously (the user set independent / loop operation in instructions or chat) → there's no one to ask, so just clear all of them and start fresh, don't block the loop.
Modes
- normal (default) — full cycle, autonomous: pick the most logical task and approve your own plan.
- fast (
fast,--fast,-f) — skip planning, both review steps, test-first work, the behavior check, and final validation. Still pick the task with the CLI, make the change, update the task and spec, and — when the project commits task changes — commit unless told not to.
#noqa tag — if the picked task carries #noqa, skip the two review steps (Step 3 and Step 5). Everything else, including the behavior check and commit, still runs.
Task boundaries
Do only the work required for the result of the current task.
An implementation change belongs to the current task when it is required for that result and has no independent outcome outside it.
If a change would still be useful without the current task, or changes other product behavior, treat it as a separate task. Stop before doing it and report:
- what was discovered
- how it affects the current task
- whether the current task can continue without it
Do not include the separate task without an explicit user decision. A review may check or reject work within the current task, but it does not authorize combining tasks.
Step 1 — Pick a task
mdtask listfor open, unblocked tasks. The CLI hides tasks with unresolved@blocked_by:IDby default. Skip tasks tagged#user-required— they're parked for a human decision (see "When you can't decide" below).- If the user gave scope (tag, area, specific task), filter by it. Otherwise pick the most logical next task.
- No open tasks left → tell the user and stop. (This is what makes the skill safe to run in a loop — see "Working a list of tasks" below.)
Step 2 — Plan
Skip in fast mode.
- Get the task's full details with
mdtask view <ID>(add--jsonfor the whole body); open the Markdown file only if you need surrounding context. - Understand what to build — don't invent extra scope.
- Write a concrete plan: files to create/modify, functions/modules, how to structure the code.
- State the behavior check you will run after tests pass: a local command, CLI flow, API call, UI path, integration check, or another realistic use case that proves the requested result. If a direct behavior check cannot run, say why and name the strongest available replacement evidence; don't use ordinary tests, lint, code reading, or
mdtask validateas the replacement when a realistic check is possible.
Step 3 — Review the plan
Skip if the task has
#noqa, or in fast mode.
A different model catches more than self-review, so send the plan to an external reviewer:
- Use whatever review mechanism the project or your harness provides. A project may name one in its agent instructions (e.g.
AGENTS.md/CLAUDE.md); if not, fall back in this order.- A review tool/mechanism is available → use it. Send plan + task spec + relevant files; ask: is it correct? missing pieces? better approach? does the planned behavior check prove the requested result?
- Only a subagent is available → ⚠️ note it's the same model checking itself (weaker), then launch a subagent for the review.
- Nothing external is available → ⚠️ note that no external review was configured, then review the plan yourself. Don't skip silently.
- Fold the feedback into a refined plan.
Step 4 — Execute with risk-based validation and behavior check
Fast mode: implement directly — no test-first, no validation unless the user asks.
Pick the smallest useful validation for the change:
- Logic, parsers, data transforms, CLI behavior, bug fixes → write a failing test first when practical.
- Data contracts, schemas, imports/exports, migrations → validate real structure with fixtures or representative input/output.
- UI, copy, styling, layout-only → no new test unless there's branching logic, state, accessibility behavior, or a known regression.
Then implement, run the relevant existing tests, and run lint/typecheck if configured. If you added no test, say in one line why existing validation is enough. Skip shallow snapshot tests and tests that only restate static data.
After tests and lint/typecheck pass, run the planned behavior check. Report the exact check and result. If it fails, fix the issue and re-run the behavior check before review or final validation. If the behavior check cannot run, record why and report the replacement evidence named in the plan. #noqa skips reviews only; it still runs this behavior check. Fast mode skips this whole step's behavior check because it has no plan.
Step 5 — Review the code
Skip if the task has
#noqa, or in fast mode.
Resolve the reviewer the same way as Step 3 (named tool → subagent fallback with a warning → self-review with a warning). Send the current implementation diff + task context; ask about correctness, edge cases, style, security. Review it yourself too. Fix all safe actionable technical findings. If fixes change the implementation diff, run relevant validation and behavior checks as needed, then run code review again on the updated diff. Repeat until the latest review has no remaining actionable findings on the current implementation diff; optional nits or subjective suggestions do not keep the loop open unless they affect the requested result. If a later implementation change happens after a clean review, return to this step before committing. If a decision genuinely needs a human — ambiguous business logic, a product call you can't make, a finding you cannot safely accept or reject — don't guess: park the task (see "When you can't decide" below).
Step 6 — Final validation
Skip in fast mode unless the user asks for it.
Run all tests again to confirm nothing broke after review fixes, and lint/typecheck if configured. Confirm the final report has an explicit behavior-check status: passed, skipped by fast mode, or replaced with the reason and evidence from the plan.
Step 7 — Record what was done
Full workflow with examples: the
mdtaskskill's "Spec-driven development" section.
The task body (always): mark it [x] and add an **Implemented:** block (2–5 bullets, outcomes only — no code, no internals). Only touch the task you worked on — never modify other tasks or their Implemented blocks.
The feature description (only for SDD-style specs): if the task lives in a spec that keeps feature prose above # Tasks, add a new ## Section for a new feature, or update the existing section if the task extends one. Match the section to the feature, not to the task. Describe it from the user's side — what to run, what config to use — concise, how-to-use, not implementation detail. If the task is just a checkbox in an ordinary Markdown file, there's no prose section to update — skip this.
Step 8 — Commit
First confirm against the checklist from the Flow gate: every step done or consciously skipped (fast/#noqa), the behavior-check status is recorded, the last implementation diff was reviewed cleanly or review was validly skipped, and nothing was silently dropped. Then, when the project commits task changes (or the user approves), commit the code and the task/spec update together, with a message describing what was built.
When you can't decide — park it
At any step, if you hit a decision that genuinely needs a human — ambiguous business logic, a product call you can't make, a spec gap — don't guess, and don't open a separate task. Park the current task so the loop moves on:
- Tag it:
mdtask set <ID> '#user-required'(quote the#— unquoted it's a shell comment). - Append a short note to the task body: the exact open question and what you already found (options weighed, where in the code the problem sits). This is what keeps the context from being lost — the tag only marks the task, the note explains it.
- Commit the parked state (if the project commits task changes), then stop. The loop picks the next task; parked tasks are skipped (Step 1).
A human later reviews everything parked with mdtask list '#user-required', makes the call, and removes the #user-required tag to put the task back in play. (mdtask set only adds metadata — to remove the tag, open the task with mdtask open <ID> and delete the #user-required token from the header line.)
Working a list of tasks
This skill does one task and stops cleanly when none are left. To work through a backlog, run it repeatedly from your coding agent's own loop — driving a whole scope of tasks is the agent's job, not part of mdtask, so use whatever loop mechanism your harness provides.