Close Task
close_taskClose a task that should not be built — a duplicate, or work already shipped.
For a task on the board that is obsolete: the change already landed in
another PR, a sibling task covers it, or the user changed direction. The
task is marked `cancelled` and keeps ALL of its history (acceptance
criteria, QA steps, iterations) — nothing is deleted.
`reason` is REQUIRED and is recorded on the audit trail in one line.
`superseded_by_pr_number` (or `superseded_by_task_id`) records verified
provenance when the work was genuinely delivered somewhere else, instead of
a bare abandon. Closing does NOT claim the content is on the default branch,
so any task that declared a dependency on this one keeps waiting; those are
delivered or re-planned separately.
Refuses with 409 while the task is being worked on by a running iteration
(an in-flight iteration must finish, or its machine must be stopped, before
the close succeeds). A task in another
workspace 404s. Business-level replay guard: closing an already-closed task
changes no task state. The call is not idempotent end to end — an
authenticated request also persists credential-use state.
The response echoes `open_tasks`: how many tasks are still open on the
project, counted after the close commits. A count that did not drop means
the ticket was already closed and this call changed nothing. It is the same
count `project_status` returns, and neither counts a closed task as open.
This is preferable to leaving a dead task on the board: unfinished tasks
count against the project's planning capacity, so stale duplicates quietly
stop new roadmap items from being expanded.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| task_id | Yes | ||
| project_id | Yes | ||
| superseded_by_task_id | No | ||
| superseded_by_pr_number | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |