04 — Linear QA Workflow¶
How you log, label, prioritize, and track every bug. This is the process everyone agreed on — follow it exactly so triage stays clean during the launch crunch.
Linear is the issue tracker. Every ticket you file is called an "issue" and has an ID like PIN-123.
The flow in one picture¶
You find a bug
│
▼
Run /qa-report ──► it structures the bug, resolves the cycle, sets `qa` + Priority,
│ suggests the developer ──► you approve ──► it files the ticket
▼
Marko reviews assignments daily ──► reassigns if needed
│
▼
Dev fixes it (their own code-review step happens here — not something you need to track)
│
▼
Dev moves the ticket to "QA" ──► that's your cue: go verify on staging
│
▼
YOU verify ──► ✅ move to Done (only you close qa tickets)
└► ❌ move back to Todo + comment (say what's still wrong)
The easy way: /qa-report¶
You don't have to do any of the steps below by hand. In Claude Code, run:
/qa-report the drawings viewer resets zoom every time I switch sheets
It walks the whole checklist for you — structures the bug into the template, resolves the current launch cycle live, adds the qa label, sets Priority from severity, checks for duplicates, and suggests the developer who owns that surface (with a load-based fallback if they're buried). It shows you the finished ticket and stops — nothing is filed until you say "file it." You can edit any field, override the assignee, or backlog it before it writes. Point it at a screenshot path and it uploads the image to the issue.
The manual checklist below is the fallback (and the reference for what /qa-report is doing under the hood) — use it if you'd rather file straight in the Linear UI.
Filing a bug — the checklist¶
Every bug, every time:
- Cycle: file it into the current launch cycle (the cutover + QA cycle —
/qa-reportlooks this up live so you never have to hardcode a number). If you're not sure which cycle is active, ask me or check Linear before filing manually. - Label: add the
qalabel. This is what makes your bugs filterable as one queue. (There's also aclient-feedbacklabel — that's for Conor's feedback, not your QA bugs.) - Priority = severity. Linear's Priority field is where severity lives — set it using this mapping:
- Blocker → Urgent — data loss/corruption, can't log in, core pilot workflow fully broken, wrong money numbers, immutability violation, in-scope confidential-data leak
- Major → High — important feature broken or wrong result, but a workaround exists
- Minor → Medium — small functional issue, usable but annoying
- Cosmetic → Low — visual, copy, or polish only
- Assignee:
/qa-reportauto-assigns to the developer who owns that surface (drawings → Artem, bids → Ivan B, Cara/infra → Marko, cross-cutting UI → Mateo), falling back to the least-loaded dev if the owner is overloaded. Marko reviews assignments daily and reassigns if needed — so it's fine if the suggestion isn't perfect. (Filing manually? You can still leave it blank and let Marko assign.) - Use the bug template (below) in the description.
- Attach evidence: screenshot or screen recording, and the exact error text if any. Paste any
/debuginvestigation output or link it.
The bug template (use this every time)¶
Copy-paste this into the Linear issue description and fill it in:
Source: QA (Marijana) — <date>
Location / module / surface: <e.g. Daily Logs → Complete Work Day>
What happened:
<one-line summary>
Steps to reproduce:
1.
2.
3.
Expected:
<what should happen>
Actual:
<what actually happened>
Severity: blocker | major | minor | cosmetic
Env: staging or development (say which — see doc 03) / build <sha or version if known>
Role: <the role you were logged in as>
Attachments / documents:
<screenshot / screen recording / exact error text — attached to the issue>
Technical details for developer:
<console/network errors, failing request, suspected component/route, /debug findings; is this a regression, and which build introduced it?>
A few rules for filling it in:
- Plain language everywhere except Technical details for developer. Write "What happened," Steps, Expected, and Actual the way you'd explain it to a non-technical teammate. Save component names, code references, and jargon for the Technical details section at the bottom — that split is what makes the ticket easy for anyone to verify later, not just the person who filed it.
- Same bug, multiple spots? List all of them. If you find the same root cause breaking in several places, don't file a separate ticket for each — add every spot it happens to Steps to reproduce (or as separate numbered cases within the one ticket). One fix, and whoever verifies can check every affected spot in a single pass instead of hunting for duplicates.
- Put anything significant into Steps to reproduce, including preconditions. If a specific role, a specific data state, or something you did earlier in the session mattered to reproducing it, say so as a step — don't make the developer or the next verifier guess what you were quietly assuming.
Title tip: make it specific and scannable — [Daily Logs] Completing a day wipes manpower rows beats daily log bug.
After you file — the review loop¶
- Marko reviews assignments daily — confirming or repointing the developer
/qa-reportsuggested. - The developer fixes it. They may pass it through their own "In Review" step first (code review among the dev team) — that's internal to them, not something you need to watch.
- Once it's fixed and deployed, the developer moves the ticket to "QA." That's your cue to verify it. Re-test the exact reproduction steps on staging (confirm the fix is actually deployed to staging first — ask if unsure).
- ✅ Fixed → move it to Done. Only you close
qatickets — devs don't close them. - ❌ Still broken (or the fix caused something new) → move it back to Todo and add a comment saying precisely what's still wrong, with fresh steps/screenshots. Don't silently leave it; comment so the dev knows why it bounced.
- Keep an eye on your "QA" status, filtered to the
qalabel — that's your daily verification worklist.
The lockdown rule (important for this cycle)¶
This is a time-boxed launch cycle (pilot cutover before July 29). The launch cycle is for real, valid bugs — things that are broken, wrong, or lost.
- Feature ideas, polish, "it'd be nicer if…", and September-scope items → the backlog, labeled
target-sep— NOT the launch cycle. (When you spot a good idea, capture it as a backlog issue withtarget-sepso it isn't lost, but keep it out of the launch cycle.) - If you think something is a real bug but it's borderline scope, flag the tradeoff in the ticket (or ask Marko) rather than assuming it belongs in the launch cycle.
- Cosmetic/Low issues are still worth logging (with
qa+ Low), but they won't jump the queue ahead of blockers — and purely subjective polish should go to backlog, not the cycle.
Rule of thumb: "Is it broken, wrong, or lost?" → launch cycle. "Would it be better if…?" → backlog.
Quick reference¶
| Thing | Value |
|---|---|
| Cycle for launch bugs | The current launch cycle — /qa-report resolves this live; ask me or check Linear if filing manually |
| Label for your bugs | qa |
| Priority mapping | Urgent=blocker, High=major, Medium=minor, Low=cosmetic |
| Assignee | /qa-report auto-assigns by surface + load; Marko reviews & reassigns (blank if filing manually) |
| Your verification cue | Ticket status = QA (not "In Review" — that's a separate dev-side step) |
Who closes qa tickets |
Only you |
| Backlog for ideas/polish | label target-sep, keep out of the cycle |
| Client feedback label (not yours) | client-feedback |
If Linear itself is confusing (filters, cycles, labels), ask me (Claude Code) — I can walk you through the exact Linear steps, and Marko can grant access.