Skip to main content

Validate Issue

Shared function to validate and normalize a Linear issue — type label inference, estimate defaulting, complexity derivation, description structure validation, monochrome prefix application, and assignee/project checks.

Validate Issue

Shared validation function called by /new, /go, and any command that needs to ensure a Linear issue meets Definition of Ready (DoR) standards. This is NOT a standalone user-facing command — it is a procedure referenced by other commands.

Scope: This skill covers issue validation and normalization. It is NOT about issue creation (see create-enriched-issue) or media processing (see process-media).

Inputs

  • Issue ID (required) — Linear issue identifier (e.g., ORC-455)
  • .linear.json (required) — Must exist in project root. Contains label UUIDs, status UUIDs, team/project/assignee IDs.

Outputs

After running validate-issue, the issue will have:

  • A type label (bug, feature, chore, docs, planning, spike)
  • An estimate (defaults to M / 3pts if missing)
  • A complexity label (trivial, standard, complex)
  • A valid description structure (Summary, Acceptance Criteria, Scope headings)
  • A monochrome prefix on the title
  • An assignee and project (or awaiting-input label if missing)

Procedure

V1. Read .linear.json

Read .linear.json from project root. Extract:

  • labels.type.* UUIDs (bug, feature, chore, docs, planning, spike)
  • labels.complexity.* UUIDs (trivial, standard, complex)
  • team.id, assignee.id, projects.* (first value), statuses.backlog

If .linear.json is missing, stop with error: ".linear.json not found in project root."

V2. Fetch the issue

npx tsx tools/scripts/linear-api.ts get-issue <ID>

V3. Determine type label

Read labels.nodes[]. Find first label matching bug, feature, chore, docs, planning, spike.

If no type label found, infer from title prefix:

Title prefix Inferred type
fix: or fix( bug
feat: or feat( feature
chore: or chore( chore
docs: or docs( docs
No recognized prefix default to feature

Apply type label if missing:

npx tsx tools/scripts/linear-api.ts update-issue <ID> --labels <EXISTING_UUIDS>,<TYPE_UUID>

V4. Default estimate

If estimate is null, default to M (3 points):

npx tsx tools/scripts/linear-api.ts update-issue <ID> --estimate 3

V5. Derive complexity label

If no complexity label present, derive from type × estimate:

Type XS (1) / S (2) M (3) / L (5) / XL (8)
docs trivial trivial
planning trivial trivial
spike trivial trivial
chore trivial standard
bug trivial standard
feature standard complex

Apply complexity label:

npx tsx tools/scripts/linear-api.ts update-issue <ID> --labels <ALL_UUIDS>,<COMPLEXITY_UUID>

Important: --labels replaces all labels. Include ALL existing label UUIDs to preserve them.

V6. Validate description structure

Check for #### Summary, #### Acceptance Criteria, #### Scope headings. If any missing, auto-heal: restructure description preserving all existing content, then update:

npx tsx tools/scripts/linear-api.ts update-issue <ID> --description "..."

V7. Apply monochrome prefix

If the title is missing its monochrome prefix, apply it using this map:

Type Symbol Example title
bug ✕ dashboard crash on null user
feature ★ add retry logic to webhook handler
chore ⚙ upgrade Tailwind to v4
docs ☰ add architecture decision record
planning ◎ map out auth redesign
spike ↯ evaluate vector DB options

Monochrome prefix format: <symbol> <description> — the title contains only the symbol and a plain description. No conventional commit prefix (feat:, fix:, chore:, docs:) in the Linear title. Git commits still use conventional format — the type-to-prefix mapping happens at SHIP time, not in the title.

If the title already starts with the correct symbol, do not modify it.

Update the title:

npx tsx tools/scripts/linear-api.ts update-issue <ID> --title "<prefixed title>"

V8. Check assignee and project

If either assignee or project is null, apply awaiting-input label and STOP. The calling command should handle this failure gracefully.

Error handling

  • If .linear.json is missing → stop with error message
  • If issue fetch fails → retry up to 3 times, then propagate error to caller
  • If assignee/project is null → apply awaiting-input label and return failure status
  • All other steps are self-healing (apply defaults, auto-fix structure)

Search Framework Explorer

Search agents, skills, and standards