Claude Code Plugins

Community-maintained marketplace

Feedback

linear-quality-audit

@harshfolio/claude-orbit
0
0

Find problematic tickets with member attribution - missing labels, assignees, projects, poor descriptions.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name linear-quality-audit
description Find problematic tickets with member attribution - missing labels, assignees, projects, poor descriptions.

Linear Quality Audit

Usage

linear-quality-audit
Run quality audit on Linear board

Process

1. Load Context

board = read('../data/board.json')
excludedTeams = board.settings.team_exclusions.quality_audits

2. Find Problems (Filter-First for 100% Coverage)

Run targeted queries to find ALL problematic tickets:

// Get tickets missing team labels
missing_team = list_issues({
  state: "!Backlog,!Done,!Canceled",
  limit: 250
  // Filter: tickets WITHOUT any team label (Backend Team, Mobile Team, WebDev Team)
})

// Get tickets missing platform labels
missing_platform = list_issues({
  state: "!Backlog,!Done,!Canceled",
  limit: 250
  // Filter: tickets WITHOUT platform labels (Web/Desktop, Mobile/Android, etc.)
})

// Get tickets missing assignees (when required)
missing_assignee = list_issues({
  assignee: null,
  state: "In Progress,In Review,Ready for QA,In QA,Ready for Design QC",
  limit: 250
})

// Get tickets missing projects (when required)
missing_project = list_issues({
  project: null,
  state: "!Backlog,!Done,!Canceled",
  limit: 250
})

Then get recent activity to catch fresh tickets:

recently_created = list_issues({
  limit: 250,
  orderBy: "createdAt"
})

recently_updated = list_issues({
  limit: 250,
  orderBy: "updatedAt"
})

// Detect stale tickets (now included in quality audit)

staleThresholdDays = board.settings.stale_threshold_days || 14

stale_14_15 = list_issues({
  state: "In Progress,In Review,Ready for QA,In QA,Ready for Design QC",
  updatedBefore: now() - 14d,
  updatedAfter: now() - 15d,
  limit: 250
})

stale_15_30 = list_issues({
  state: "In Progress,In Review,Ready for QA,In QA,Ready for Design QC",
  updatedBefore: now() - 15d,
  updatedAfter: now() - 30d,
  limit: 250
})

stale_30_plus = list_issues({
  state: "In Progress,In Review,Ready for QA,In QA,Ready for Design QC",
  updatedBefore: now() - 30d,
  limit: 250
})

3. Merge & Deduplicate

all_tickets = merge_by_id([
  missing_team,
  missing_platform,
  missing_assignee,
  missing_project,
  recently_created,
  recently_updated,
  stale_14_15,
  stale_15_30,
  stale_30_plus
])

// Filter out excluded teams
filtered_tickets = all_tickets.filter(t => !excludedTeams.includes(t.team))

4. Categorize Problems

For each unique ticket, check:

Determine Reporting Team:

  • Check for "Backend Team", "Mobile Team", or "WebDev Team" labels → Engineering subteam
  • Otherwise use Linear team field → Standalone team
  • Skip if team in excludedTeams

Missing Labels:

  • No team label (Backend Team, WebDev Team, Mobile Team)
  • No platform label (for Bugs/Features)
  • No feature/service label (for Bugs/Features)

Missing Assignee:

  • No assignee AND status ≠ "Backlog"

Missing Project:

  • No project AND status ≠ "Backlog"
  • Skip if team excluded from project requirements

Poor Quality:

  • Empty/short description (<20 chars)
  • Placeholder text ("TBD", "TODO", "fix this")
  • Bugs: No repro steps or context
  • Features: No acceptance criteria

Stale (by age bucket):

  • 14–15 days
  • 15–30 days
  • 30 days

Use LLM to judge quality for ambiguous cases.

5. Resolve Unknowns

If creator/assignee not in board.json:

  • Use resolveUser() helper
  • See ../utils/sync-helpers.md

6. Group by Creator

Group problems by createdBy user, then by problem type.

7. Generate Report

# Linear Quality Audit

**Generated:** [timestamp]
**Audited:** [X] unique tickets (deduped from [Y] total queries)
**Problems:** [Z] tickets ([W]%)
**Excluded Teams:** [list]

## Query Summary

Targeted filters:
• Missing team labels: X tickets
• Missing platform labels: X tickets
• Missing assignees: X tickets
• Missing projects: X tickets
• Recently created: 250 tickets
• Recently updated: 250 tickets

After merge & dedup: X unique tickets analyzed

## Summary

| Problem | Count | % |
|---------|-------|---|
| Missing Labels | X | Y% |
| Missing Assignee | X | Y% |
| Missing Project | X | Y% |
| Poor Quality | X | Y% |
| Stale Tickets | X | Y% |

## Attribution by Creator

### [Name] - X quality issues

**Missing Labels (X):**
- TICKET-ID: Title - Missing: [specific]

**No Assignee (X):**
- TICKET-ID: Title - Status: [status]

**No Project (X):**
- TICKET-ID: Title

**Poor Quality (X):**
- TICKET-ID: Title - [reason]

## Stale Tickets

| Bucket | Count |
|--------|-------|
| >30 days | X |
| 15–30 days | X |
| 14–15 days | X |

## Actions

**Most Common Issues:**
1. [problem] - X tickets
2. [problem] - X tickets

**Needs Most Fixes:**
1. [name] - X tickets
2. [name] - X tickets

**Next Steps:**
1. Run linear-organise for auto-fixes
2. Share report for accountability
3. Follow up with top creators

8. Save & Cleanup

If unknown_cache modified: saveUnknownCache()

Offer to save report (user specifies location).


Rules

CRITICAL:

  • Filter-first approach: Query for specific problems, don't analyze everything
  • 100% coverage: Targeted filters catch ALL problematic tickets
  • Recency check: Always check last 250 created + updated to catch fresh issues
  • Merge & dedupe: Combine all queries by issue ID to avoid duplicates
  • Skip excluded teams: AI & Research entirely from all checks
  • DevOps different standards: Infrastructure work doesn't need all labels/projects
  • QA bug tickets expected incomplete initially: QA (Anurag, Arti) report bugs quickly - engineers add labels later. Note missing labels but don't flag harshly
  • Backlog tickets can lack assignee/project
  • Be specific: "Missing: Team label, Platform label"
  • Show ticket ID + TITLE not just ID
  • Track creation date for context
  • Include ticket URLs for easy fixing
  • Location agnostic - user chooses save path
  • Show query breakdown in report for transparency

Example Session

User: Use linear-quality-audit skill

Claude: Loading board context from data/board.json...
Running targeted queries to find problematic tickets...

• Missing team labels: 1 ticket
• Missing platform labels: 3 tickets
• Missing assignees: 2 tickets
• Missing projects: 1 ticket
• Recently created: 250 tickets
• Recently updated: 250 tickets

Analyzing 52 unique tickets (deduped)...

# Linear Quality Audit

**Generated:** 2025-11-05 10:30 AM
**Audited:** 52 unique tickets (deduped from 507 total queries)
**Problems:** 5 tickets (9.6%)
**Excluded Teams:** AI & Research

## Summary

| Problem | Count | % |
|---------|-------|---|
| Missing Labels | 3 | 60% |
| Missing Assignee | 1 | 20% |
| Missing Project | 1 | 20% |

## Attribution by Creator

### Nikhil Vaish - 2 quality issues

**Missing Labels (2):**
- ENG-1401: Selected address indicator - Missing: Platform label
- ENG-1520: Redis migration - Missing: Team label

### John Doe - 1 quality issue

**Missing Assignee (1):**
- ENG-1522: Fix login bug - Status: In Progress

Where would you like to save this report?