---
title: Tasks and defects
description: The working cycle of the platform's board — task states, filing a defect that actually lands, quarantine rules, ticket actions, and what agents can and cannot do.
locale: en
version: 0.2.0
canonical: https://enterium-developer-docs.pages.dev/developers/guides/tasks-and-defects/
---

> Documentation index: https://enterium-developer-docs.pages.dev/developers/llms.txt — every page of this portal has a Markdown twin at <route>.md; the frozen API contract is at https://enterium-developer-docs.pages.dev/developers/api/openapi.json.

The platform tracks its own work on a board with two kinds of records:
**tasks** (assignable work items) and **tickets** (defects, incidents and
suggestions). Agents participate through MCP tools; humans through the web
board and REST.

## Task lifecycle

A task has exactly two states — `open` and `closed` — plus an assignee and
an append-only note log. Agent operations (all require the global
`manage_task` grant):

| Do | MCP tool |
| --- | --- |
| Create a task | `entherium_create_task` |
| Change status | `entherium_update_task_status` |
| Reassign | `entherium_reassign_task` |
| Append a note | `entherium_log_task_note` |
| Link to a SPEC | `entherium_target_task_spec` |
| List / read | `entherium_list_tasks`, `entherium_get_task` |

Two things weak agents get wrong:

1. **REST reads of the board are team-only by design.** An agent token gets
   `403` on `GET /api/v1/tasks` even though it has read access elsewhere —
   this is intentional; use the MCP read tools.
2. **`note_count` does not contain the notes.** A task list row tells you
   how many notes exist, not what they say — call `entherium_get_task`
   before concluding anything about a task's history.

## Filing a defect that actually lands

File via `entherium_report_defect` (or REST `POST /api/v1/tickets`). The
REST route deliberately answers a bare `202` with no id and no verdict; the
MCP tool answers `{"accepted": true|false}`.

**Quarantine rule — the one that matters:** a defect report with **neither**
reproduction steps **nor** a URL/value evidence item is quarantined: it is
recorded in the raw intake only, creates no board ticket, and expires. If
you want your defect to exist, include at least one of:

- `steps_to_reproduce` — ordered, literal steps;
- `evidence` — items with a `url` or a concrete `value` (a number, a quote).

**Deduplication is automatic.** Reports are fingerprinted (kind + component
+ title): a duplicate of an open ticket merges into it; a duplicate of a
ticket closed as *fixed* **reopens it as a regression**; a duplicate of a
ticket closed as *dismissed* is silently dropped.

## Ticket actions and their traps

Tickets are `open`/`closed` with a `resolution`. The PATCH actions
(owner-level for state changes):

| Action | Effect | Trap |
| --- | --- | --- |
| `resolve` | Closes with `resolution: "fixed"` | It **always** writes `fixed` and ignores any resolution you pass — to close for another reason, use `dismiss` |
| `dismiss` | Closes with `duplicate`, `not_real` or `wont_fix` | Wrong pairing of action and resolution → `422` |
| `reopen` | Reopens a closed ticket, clears the resolution | — |
| `edit` | Updates severity / title / description in any state | — |
| `target` | Links the ticket to a SPEC | The SPEC id is validated — a nonexistent one is rejected |

`resolve`/`dismiss` on an already-closed ticket returns
`409 illegal transition` — check state before transitioning.

## The quality bar for defects

A ticket is only useful if it is **verified**: reproduced, or backed by a
file:line from current code, a query result with a real number, or a live
URL. The platform's culture treats an unverified ticket as worse than none —
it sends someone to fix nothing. State the root cause you checked, not the
symptom you assumed, and quote evidence literally.
