---
stacks:
  - "*"
---

# MORPH-SPEC Task Tracking

> Progress lives in `tasks.json` — nowhere else. There is no CLI command to mark a task done and
> no session-level checklist to keep in sync: this file IS the record of what happened.

## Persisting Progress to `tasks.json`

To record task progress for the feature, write `.morph/features/{feature}/2-plan/tasks.json`,
touching ONLY the mutable fields:

- `status` — `pending` → `in_progress` → `done` (também: `skipped`, `blocked`)
- `outputs` — the files the task produced
- `notes` — free-text record (deviations, context, resolved blockers)

> **O status terminal é `done`.** `completed` **não existe** no enum de
> `.morph/framework/schemas/tasks.schema.json` — é vocabulário de outro sistema, e o hook
> `protect-spec-files` rejeita a gravação.

The plan contract — `title`, `description`, `dependencies`, `effort`, `doneCriteria`,
`group`, `agent`, `standards` — is frozen after Gate 2. Any attempt to change it is
blocked by the `protect-spec-files` hook. `agent` (persona id, no `morph-` prefix)
and `standards` (paths pinned by morph-plan) are optional — legacy plans without
them remain valid.

Use the `Write` tool (whole-file rewrite) OR the `Edit` tool — `Edit` is allowed
as long as it touches only `status`, `outputs`, and `notes`. State is then synced
automatically by the `state-sync` PostToolUse hook; you do not call a CLI to mark
output.

Update each task as you go — `in_progress` when you pick it up, `done` when it is finished —
rather than batching every write to the end of the phase. `morph-spec status`, `dag`, `verify`
and the dashboard all read this file, so a stale `tasks.json` is a blind orchestrator.

## Deviation Tracking

When completing a task differently than originally planned, record the reason in the
task's `notes` field. `notes` is **uma única string** (o schema declara
`"notes": { "type": "string" }`) — para registrar mais de um desvio, separe-os com
`;` ou `\n` dentro da mesma string. Um array é **rejeitado** pelo validador, com a
mensagem `'notes' must be a string`.

```json
{
  "id": "T3",
  "status": "done",
  "outputs": ["Features/User/Update/Handler.cs"],
  "notes": "deviation: split validation into a separate validator for testability; blocker-resolved: EF migration conflict fixed by regenerating the snapshot"
}
```
