---
name: task-section-editing
description: The temp-file → --section/--from-file recipe for editing task sections, when to use record instead, and which sections to fill when.
see_also:
  - spur-cli
---

# Editing task sections

Task bodies are edited section-by-section through `spur task update --section <name> --from-file
<path>`. The write is **file-wins and crash-safe** (atomic write): the named section's body is
replaced wholesale from the file you point at — with one exception, `Q&A`, which appends (see
below). There is no inline-body flag — always stage the new body in a file first.

For **pipeline output**, section authorship is one-writer-per-section (F92 0593 R1):
`Testing` comes from `spur task record` (deterministic, from a verify verdict artifact — the
matrix-compliant tables are rendered for you); `Review` is authored by the review coordinator
(`/sp:dev-review`), with `record` backfilling it only when bare; `Solution` is authored by the
implement step (record safety-nets a bare `Solution` from the diff). Use the manual recipe below
for `Plan`, `Acceptance Criteria`, hand-authored `Solution`, and any narrative section.

## The recipe

1. **Assemble the full section body** in a temp file. The body is everything *under* the `###`
   heading — do not include the heading line itself; the CLI owns the heading.
   Sub-headings inside the body MUST be `####` or deeper: a `###` in a body parses as a new
   top-level section and trips `L2.disallowed-section` (task 0787 grew 8 phantom sections this way).

   ```bash
   cat > /tmp/review.md <<'EOF'
   **Verdict: PASS**

   | # | Finding | Dim | Location | P | Disposition |
   |---|---------|-----|----------|---|-------------|
   | 1 | … | Correctness | src/foo.ts:42 | P2 | FIXED |
   EOF
   ```

2. **Replace the section:**

   ```bash
   spur task update 0040 --section Review --from-file /tmp/review.md
   ```

3. The whole `### Review` body is now that file's contents. To amend rather than overwrite, read
   the current body (`spur task show 0040`), edit the temp file to the full desired state, and
   replace again — there is no append mode for ordinary sections.

**`Q&A` is the exception.** `--section "Q&A"` APPENDS a timestamped `#### Q&A entry — <ISO>`
block rather than replacing the section. Start the body with `<!-- qa:replace -->` to replace it
wholesale.

`--section` **requires** `--from-file` (exit `2` otherwise). Section names match the DD-08 headings
exactly: `Background`, `Requirements`, `Acceptance Criteria`, `Q&A`, `Design`, `Plan`, `Solution`, `Root Cause`, `Testing`, `Review`, `References`, `History`, `Notes` (universal sections are `History`, `References`, `Notes`; `Root Cause` is carried by the `issue` template variant).

## `record` vs. hand-editing

`spur task record 0040 --transition testing` reads `.spur/run/0040-verdict.json`, writes
`Testing` (per-requirement table), and backfills `Review` (P1–P4 findings table) **only when the
section is bare** — a standalone compatibility fallback, never an overwrite of the review
coordinator's authored Review — optionally backfilling a bare `Solution` from `git diff -U0`. It
never transitions to `done`.

- **Use `record`** when a verify step produced a verdict artifact — it is the pipeline's record step
  and the deterministic `Testing` writer.
- **Use `update --section`** when you are authoring a section by hand (planning, design, narrative
  solution) or amending one `record` already wrote.

`record` writes `Testing` unconditionally and `Review` only when bare; a later
`update --section` overwrites either (file-wins). Both go through the same file-wins atomic write.

## Which section, when

During a pipeline run the sections fill in roughly this order — but *what* goes in each is the
LLM's job (orchestrated by `sp:spur-dev`); this skill only owns the *mechanism*:

| Section | Filled | Holds |
| ------- | ------ | ----- |
| `Background` | at create (derived from feature `Goal` if `--feature`) | why this task exists |
| `Acceptance Criteria` | planning (present at `todo` for spec'd tasks) | the scenarios this task satisfies (matched to feature AC by title) |
| `Plan` | before `wip` | the step list |
| `Solution` | during impl (implement step) | the approach actually taken; L3 `file:line` rule fires once it has real content |
| `Testing` | testing phase (`record` — deterministic writer) | what was verified and how — gated at `wip→testing` by `check` |
| `Review` | review phase (`/sp:dev-review` coordinator) | merged SECU findings + verdict — gated at `testing→done` by `check --strict-core` |

Section presence per status is a **runtime contract**, not a table: query
`spur task sections <wbs> list --json` (permitted present sections) and `spur task check <wbs> --json`
(required sections at the current status) before writing.

A spec'd task (`--feature` link or batch item with `background`/`requirements`) is created at `todo`
with Acceptance Criteria + Plan scaffolding present; a bare capture is created at `backlog` with
Background only.

## Status vs. section — don't conflate

`update 0040 wip` is a lifecycle transition. `update 0040 --section …` is a body edit. They are
separate invocations and mutually exclusive in one call. A typical step does the section edit first,
then the transition:

```bash
spur task update 0040 --section Plan --from-file /tmp/plan.md
spur task update 0040 wip
```

The `wip→testing` and `testing→done` transitions run a `check` guard (§7.5) — fill the gated
sections (`Testing`, `Review`, `Solution`) before attempting the transition, or it will be blocked.

Before authoring pipeline output for the first time, read the
**[L3 guard format cheat sheet](l3-guard-cheatsheet.md)**. It centralizes the lifecycle graph,
Solution citation rule, Review table shape, verdict artifact schema, and canonical section names.
