Skip to main content

labels-states-properties

Design taxonomies for Plane projects — labels, workflow states, work item types, and custom properties. Use when the user asks how to organize labels, design a state machine, set up custom fields, configure work item types, decide between label/property/type, or audit a noisy taxonomy. Covers naming conventions, recommended sets, and the difference between the four metadata mechanisms.

Source facts

Repository
Agents-Store/opencode-plugins
Last source activity
October 3, 2026 at 23:16
Detected SKILL.md language
English
Stars
0
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
labels-states-properties
description
Design taxonomies for Plane projects — labels, workflow states, work item types, and custom properties. Use when the user asks how to organize labels, design a state machine, set up custom fields, configure work item types, decide between label/property/type, or audit a noisy taxonomy. Covers naming conventions, recommended sets, and the difference between the four metadata mechanisms.
# Labels, States, Types, and Properties Plane gives you four metadata mechanisms for work items. Pick the right one or your project becomes a tag soup nobody can search. ## Tool Name Resolution Plane MCP exposes one tool per resource and the operation goes into the `action` parameter: `label(action=create, ...)`. Resolve the real tool names (`mcp__<server>__<resource>`) through the `connector-bootstrap` skill - never assume a server prefix. | Mechanism | Calls | |---|---| | Labels | `label(action=list\|retrieve\|create\|update\|delete)` | | States | `state(action=list\|retrieve\|create\|update\|delete)` (`group`, `sequence`, `default`) | | Work item types | `workitem_type(action=list\|resolve\|create\|update\|delete\|import_to_project)` | | Properties | `workitem_property(action=list\|create\|update\|delete\|list_options\|create_option\|manage_type_properties\|set_value\|...)` | | Usage numbers for audits | `workitem(action=count, project_id, group_by=labels__id\|state_id\|type_id\|priority)` | ## The Four Mechanisms | Mechanism | Purpose | Cardinality | Workflow effect | |---|---|---|---| | **State** | where the item is in the workflow | one per item | drives boards, burndown, velocity | | **Work item type** | what kind of work it is | one per item | can drive different fields, templates | | **Property** | structured, queryable attribute | one or many depending on type | reportable filter values | | **Label** | freeform tag | many per item | grouping, filter shortcut | ### Decision tree ``` Need a different workflow / different fields? → Work item type (e.g. Bug vs Spike) Need a structured value you'll filter or report by? → Property (e.g. severity = S1, environment = prod) Need a yes/no flag the team will toggle? → Label (e.g. needs-design, flaky, carryover) Need to track the state of work? → State (e.g. In Review, Done) ``` If the answer is "I'm not sure", default to **label**. Labels are cheap to create and cheap to delete. Properties have schema cost. Types have workflow cost. ## Labels — Naming Convention Use **prefixed namespaces** so labels stay searchable. Without prefixes, you end up with `bug`, `Bug`, `bug-fix`, `Bug Fix`, `BUG`, `defect`, all meaning the same thing. Recommended namespaces: | Prefix | Purpose | Examples | |---|---|---| | `type/` | nature of work (when not using work item types) | `type/bug`, `type/feature`, `type/chore`, `type/spike`, `type/tech-debt` | | `area/` | code area or product surface | `area/api`, `area/web`, `area/mobile`, `area/infra`, `area/auth` | | `priority/` | urgency (when not using built-in priority) | `priority/p0`, `priority/p1`, `priority/p2` | | `status/` | secondary status the workflow doesn't capture | `status/needs-info`, `status/blocked-external`, `status/needs-design`, `status/ready-for-review` | | `customer/` | per-customer requests (only if you track this) | `customer/acme`, `customer/contoso` | | `release/` | release earmarks | `release/v2.0`, `release/v2.1` | Rules: - One namespace per label. Don't combine (`type/bug-priority/p0`). - Lower-kebab-case after the slash. No spaces. - Choose a stable color per namespace (red for `type/bug`, blue for `area/*`, etc.) — labels become visually scannable on the board. - Quarterly audit: list all labels, drop any with <3 uses or stale by >6 months. ## Work Item States — Designing the State Machine Plane groups states into five fixed buckets. **Velocity counts only items moved into a state in the `completed` group during the cycle.** If you put "Done" in `started`, your burndown lies. ### Recommended state sets **Standard Scrum (most teams):** | Group | States | Notes | |---|---|---| | backlog | Backlog | unrefined ideas | | unstarted | Ready | meets Definition of Ready | | started | In Progress | actively worked | | started | In Review | PR open, awaiting review | | completed | Done | meets Definition of Done | | cancelled | Cancelled | will not do | **Kanban with QA gate:** | Group | States | |---|---| | backlog | Backlog | | unstarted | Ready, Blocked | | started | In Progress, In Review, In QA | | completed | Done | | cancelled | Won't Fix | **Support / triage:** | Group | States | |---|---| | backlog | New | | unstarted | Triaged, Needs Info | | started | In Progress, Waiting on Customer | | completed | Resolved | | cancelled | Closed (no action) | **Research / discovery:** | Group | States | |---|---| | backlog | Idea | | unstarted | Approved | | started | Researching, Drafting | | completed | Decided | | cancelled | Abandoned | ### State design rules 1. **Max 6 states across started + unstarted** — beyond that, the board becomes a horizontal scroll wasteland. 2. **Don't add per-team states** like "In Alice's review". Use assignee for that. 3. **Sequence matters for burndown** — order states left-to-right in the natural flow. `state(action=update, state_id, project_id, sequence=...)` sets it. 4. **Renaming is safe**, deleting is not — items in a deleted state break. Migrate first via `/bulk-update --state new`. 5. **Pick one default state** for new items (usually `Backlog` or `New`). ## Work Item Types Custom types let you give different kinds of work different fields and templates. Use them when the *workflow itself* differs. ### When to use a type vs a label | Use a TYPE when... | Use a LABEL when... | |---|---| | different fields (Bug needs severity, Spike needs timebox) | same fields, different categorization | | different default state machine | same workflow | | different velocity treatment (Spikes don't count points) | counts the same | | reporting needs the breakdown | nice-to-have filtering | ### Recommended type sets **Product team:** `Story`, `Bug`, `Task`, `Spike`, `Tech Debt` **Platform team:** `Feature`, `Bug`, `Incident`, `Runbook Item`, `RFC` **Support team:** `Ticket`, `Bug`, `Question`, `Escalation` **Maximum: 6 types.** Beyond that, taxonomy fatigue dominates and people start mistyping. ## Custom Properties Properties are typed fields. They are the right mechanism for **structured, queryable, reportable** data. ### Property data types | Type | Plane `property_type` | Use for | |---|---|---| | `text` | `TEXT` (needs a `display_format`) | freeform short string (root cause one-liner) | | `number` | `DECIMAL` | counts, ratios, customer impact | | `select` | `OPTION` | one-of fixed options (severity, environment) | | `multi-select` | `OPTION` with `is_multi=true` | many-of fixed options (affected platforms) | | `date` | `DATETIME` (needs a `display_format`) | deadlines, discovery dates | | `boolean` | `BOOLEAN` | yes/no flags that need filtering (use a label for casual flags) | | `user` | `RELATION` with `relation_type=USER` | secondary owners (reviewer, QA lead) | | `url` | `URL` | links beyond `/link add` (vendor docs) | | rich text | `RELATION` with `relation_type=RICH_TEXT` | long-form notes per item | Also available: `EMAIL`, `FILE`, `FORMULA`, `CASCADING`. Create with `workitem_property(action=create, workitem_type_id, display_name, property_type, ...)`; options go in `options=[{"name","color","is_default"}]` or later through `create_option`. Properties live with a type: attach or detach with `manage_type_properties` (`attach_ids` / `detach_ids`; detach removes the association only). A property id is also what PQL filters on: `cf["<property-uuid>"] = "<option-uuid>"`; EMAIL, FILE and FORMULA properties cannot be filtered. ### Example property sets per type **Bug type:** - `severity` (select: S0, S1, S2, S3) — required - `environment` (select: prod, staging, dev) — required - `affected platforms` (multi-select: web, ios, android, api) — required - `root cause` (text) - `customers affected` (number) - `regression?` (boolean) **Spike type:** - `timebox` (number, hours) — required - `outcome` (text) **Story type:** - `customer` (select: from CRM list) - `value` (select: must, should, could, won't) — required for Definition of Ready ### Property design rules 1. **Mark required only what blocks Definition of Ready.** Over-requiring kills throughput. 2. **Don't change a property's data type** after rollout — existing values become invalid. 3. **`select` is better than `text`** for anything that will be filtered. `text` becomes inconsistent within a week. 4. **Scope properties to a type** when possible (severity only on Bug). Project-wide properties bloat the form. 5. **Pair properties with views** — a property without a view that uses it is ceremony. ## Maintenance — Quarterly Taxonomy Audit Run this every quarter: 1. **Labels** — `label(action=list)` for the catalogue, then `workitem(action=count, project_id, group_by=labels__id)` for the uses of every label in one call (key `"None"` = items without any label). Drop any with <3 uses or no use in the last 90 days (`pql='label = "<label-uuid>" AND updatedAt >= daysAgo(90)'`). Merge near-duplicates. 2. **States** — `workitem(action=count, project_id, group_by=state_id)` (or `pql='stateGroup IN openStates()'` with `group_by=state_id`). If items pile up in one state, the workflow has a bottleneck not captured by a state. 3. **Types** — `workitem(action=count, project_id, group_by=type_id)`. If a type has <5% of items, fold it into another. 4. **Properties** — fill rate = `workitem(action=count, project_id, pql='cf["<property-uuid>"] IS NOT NULL')` divided by the total count. If a property is filled <30% of the time, it's not pulling its weight — remove or make optional. Bad taxonomy is technical debt that compounds. A 30-minute quarterly audit prevents a 3-day cleanup later. ## Cross-references - See `agile-fundamentals` for Definition of Ready / Definition of Done — these reference required properties. - See `velocity-metrics` for how state groups affect velocity calculation. - Use commands: `/label`, `/state`, `/work-item-type`, `/property`.
View on GitHub