Anatomy of a Defect That Stays Open for 40 Days
A defect report sits in the queue for 40 days. It was new for 3 days, then assigned for 2, then 'fixed' — except the fix went to the wrong branch, so it spent 9 days in re-open, then 14 in a state someone labeled 'on hold' that no workflow defines, and it is now invisible in a triage view nobody filters. The bug took 20 minutes to actually fix. The lifecycle exists because defects do not stall for technical reasons — they stall because nobody owns the next transition. Every state answers one question: who must do what to move this forward, and how do we know when they are done?
The standard lifecycle, with each state's contract:
[New] → [Assigned/Confirmed] → [In Progress] → [Fixed] → [Verify/Retest] → [Closed]
↓ ↓ ↓
[Rejected] [Deferred] [Re-opened] → back to In Progress
| State | Entry condition | Who acts next | Exit condition |
|---|---|---|---|
| New | Report submitted with steps, env, evidence | QA lead / triage | Confirmed as a real defect, or rejected |
| Assigned | Confirmed, severity set, target release chosen | Named developer | Developer acknowledges ownership |
| In Progress | Developer accepts | Developer | Fix committed to the correct branch with commit ref |
| Fixed | Fix merged, build contains it | Tester | Retest executed, result recorded |
| Verify/Retest | Fix deployed to test env | Tester | Pass → Closed; fail → Re-opened with fresh evidence |
| Closed | Verified fixed, or terminal disposition | — | Terminal; changes require re-open |
| Reopened | Retest failed, or regression found | Developer | Back to In Progress with the failure data |
| Rejected | Not a defect (works as specified), not reproducible, user error | Reporter informed | Terminal; rationale recorded |
| Deferred | Real defect, fix scheduled for a later release | Product (decision), developer (later fix) | Target release set and tracked |
| Duplicate | Same root cause as an existing defect | Reporter links the original | Terminal; original keeps the thread |
Read the table as a set of ownership contracts rather than labels, because that is how the 40-day defect happened. 'New' without a triage owner means confirmation is nobody's job. 'Fixed' without a commit reference means the tester cannot find what to verify. 'Verify' without a deployed build means retesting against the old version and the pointless re-open loop that follows. The most valuable columns are the ones teams skip: entry and exit conditions per state.
Two lifecycle facts interviewers probe. First, rejected is a first-class outcome, not a failure: 'works as specified' (the behavior matches the requirement — the requirement may need a change request), 'not reproducible' (with the conditions you tried listed — never a bare verdict), and 'by design' (with the product owner's confirmation) all close defects legitimately, and a tester who never rejects anything is rubber-stamping. Second, re-open is evidence-driven: a closed defect comes back only with fresh evidence — the build number where the retest failed, the new stack trace, the regression case that caught it — because a re-open without evidence is indistinguishable from a retest against a stale build, the most common false re-open in existence.
The Four Exits: Rejected, Duplicate, Deferred, Reopened — and Their Evidence
Most lifecycle disputes live in the non-forward transitions, and each one is defined by the evidence it requires. Handle them with consistent proof and your defect queue becomes trusted; handle them loosely and triage meetings become debates about what the tool even means.
Rejected. Three flavors, each needing different proof. Not a defect / works as specified: the observed behavior matches the spec — the fix is a requirements change request, not a code fix, and the report should say so explicitly ('behavior matches REQ-118; if the intent is different, file a change request against the requirement'). Not reproducible: only close with the reproduction attempt documented — the builds tried, the environments, the steps deviated from, and an invitation to reopen with new information; a bare 'cannot reproduce' verdict from a developer with no data is the fastest way for QA-developer trust to collapse. By design: cite the product owner's confirmation and the decision record; the designer of the behavior is the authority, not the developer's intuition.
Duplicate. Only valid when one defect causes the other — link the original as the master, state the suspected common root ('both traces converge on the same serialization error'), and close the copy. Duplicates matter statistically: if five reports trace to one root cause, the defect count is one with five sightings, and the sighting count is real risk information — it belongs in the triage notes even though the tracker shows one open item.
Deferred. The most abused terminal, because it feels like a solution. A legitimate deferral names: the target release ('scheduling fix for 4.13', never 'later'), the accepted impact during the deferral period ('admin users see stale counts for up to 24h'), the approver (product, since deferral is a business risk decision), and the trigger that would pull it forward earlier (customer escalation, data corruption evidence). A defect deferred without those four fields has not been decided — it has been hidden, and it will surface as a surprise in the next release's first day of testing.
Reopened. Reopening is correct in exactly two situations: the retest failed (fix did not resolve the original symptom — attach your new evidence), or a later change regressed the same area (attach the regression case and the introducing build if you have it). The classic anti-pattern is the re-open ping-pong: tester re-opens with no new data, developer closes as 'working on my machine', tester re-opens — the fix is a rule: re-open requires a failing test on a named build; without it, the discussion moves to a comment thread, not a state change.
A fifth transition deserves attention because it is where queues die: stalled states — Assigned, In Progress, Verify — where items age without an owner's action. Instrument the tracker with age targets per state (New → triage within 1 business day, Fixed → retest within 1 day of build availability, Verify failures → re-open within 1 day) and review the aging report at triage. The 40-day defect is always visible in that report three weeks before anyone feels its consequences — queue aging is the cheapest early-warning system a QA team can run, and it is the diagnostic to reach for when an interviewer asks 'how would you improve a team's defect process?'
Matching the Tool's Workflow to the Team's Reality
The lifecycle you configure in Jira or Azure DevOps should describe how your team actually moves defects — and when it diverges, the tool wins the argument and the truth lives in comment threads. The failure looks like this: the tracker has five states, the team uses two of them, 'Fixed' means 'I think I fixed it' to one developer and 'merged to main' to another, and the tester learns to read commit logs because the states are meaningless. Customization is a design exercise, not a configuration chore.
Step 1 — draw the real flow first. Interview the team for two weeks of recent defects: who confirmed, who fixed, where verification happened, what the ambiguous moments were. The real flow usually has three or four states nobody's default template contains — 'fixed pending deployment' (merged but not yet in a test build) is the classic, and it explains most 're-opened but nothing failed' confusion.
Step 2 — define states with written entry/exit contracts (the table from the first chapter, customized). The team signs off on the definitions, and the definitions go in the tracker's description field — the one place a reporter actually looks. Fewer states with sharp definitions beat many states with vague ones: five well-defined states carry more process truth than twelve that people route around.
Step 3 — enforce the transitions that protect data quality. Configure required fields per transition: severity and environment on creation; commit reference on entry to Fixed; build number and result on exit from Verify; approver and target release on entry to Deferred. Required fields at the right transitions are the cheapest quality control in defect management — they make every state change carry the evidence the next actor needs.
Step 4 — instrument and review. Two reports run the process: the aging report (open items by state-age, catching stalls) and the flow report (count by transition per week: how many re-opens, rejections, deferrals). A rising re-open rate is a fix-quality or retest-environment signal; a rising rejection rate is a report-quality signal; a deferral pileup without target releases is a triage-discipline signal. Reviewing both at a weekly 15-minute defect-process sync keeps the workflow honest and gives the team a measurable basis for adjusting it — add a state only when two consecutive months of flow data show a recurring ambiguous transition, never on someone's preference.
For interviews, the composite scenario is 'the team's defect process is chaotic — what would you do?'. Structure the answer: diagnose with the two reports (aging shows where items die, flow shows which transitions are abused), define states with contracts and required-field enforcement at evidence points (commit ref into Fixed, build number out of Verify), and only then add or remove states — ending with the principle that the tracker's states are a shared language, and a shared language is maintained by definitions everyone can quote, not by the number of columns on the board. This lifecycle is the container; the next topic fills it with reports that developers can act on the first time — Writing Reproducible Bug Reports.
Quiz
1. A developer moves a defect to 'Fixed' with the comment 'should be working now' and no commit reference. What is the process consequence?
2. Which re-open of a closed defect is legitimate?
3. What four fields make a defect deferral a real decision instead of a hidden bug?
4. Your tracker has twelve states but the team routes around half of them and communicates real status in comments. What is the correct fix?
Flashcards
Question
The standard defect lifecycle states in order, with the key transition guards.
Click to reveal answer
Answer
New → (triage) → Assigned/Confirmed → In Progress → Fixed (commit ref required) → Verify/Retest (build deployed) → Closed (verified) or Reopened (fresh evidence) → back to In Progress. Side exits: Rejected (not-a-defect/not-reproducible-by-design with rationale), Deferred (target release + accepted impact + approver), Duplicate (linked to master).
Question
Why is 'rejected' a first-class lifecycle outcome, and what does each rejection flavor require?
Click to reveal answer
Answer
Because not every report is a code defect: 'works as specified' redirects to a requirements change request; 'not reproducible' requires the attempted-repro conditions documented (builds, environments, deviations) — never a bare verdict; 'by design' requires the product owner's confirmation. A queue where nothing is ever rejected is rubber-stamping, not quality.
Question
The re-open evidence rule and the anti-pattern it prevents.
Click to reveal answer
Answer
Re-open requires fresh evidence — a failing retest on a named build, or a regression case with the introducing change. Without it, the tracker accumulates false re-opens (retest against stale builds) and the re-open/close ping-pong between tester and developer. No evidence → discuss in comments, not state changes.
Question
What two reports diagnose a stalled defect process?
Click to reveal answer
Answer
The aging report (open items by time-in-state; catches stalls — New untriaged > 1 day, Fixed un-retested > 1 day) and the flow report (transition counts per week: re-opens, rejections, deferrals). Rising re-open = fix-quality or stale-build signal; rising rejection = report-quality signal; deferrals without target releases = triage discipline signal.
Question
How do you right-size a tracker's workflow for a team?
Click to reveal answer
Answer
Draw the real flow from recent defect history, define states with written entry/exit contracts the team signs off on, enforce required fields at evidence transitions (severity/env at creation, commit ref into Fixed, build+result at Verify exit, approver+release at Deferred), instrument with aging/flow reports, and add states only when two months of data show a recurring ambiguous transition.
Revision Notes
Key Takeaways
- 1. Defects stall for process reasons — missing next-transition ownership — so every state needs an entry/exit contract and a named next actor
- 2. Rejected, duplicate, and deferred are legitimate exits defined by the evidence they carry, not by anyone's frustration
- 3. Deferrals without target release, accepted impact, approver, and early-pull trigger are hidden bugs, not decisions
- 4. Re-open requires fresh evidence on a named build; the rule eliminates re-open ping-pong and stale-build false re-opens
- 5. Aging and flow reports make queue health measurable — the 40-day defect is visible in the report three weeks before anyone feels it
Interview Tips
- • "Walk me through the defect lifecycle." — states in order with the evidence per transition (commit ref into Fixed, build number out of Verify, fresh evidence to re-open); the contracts, not just the labels, mark you as someone who has run a queue
- • "A developer says 'works on my machine'." — not-reproducible needs documented attempt conditions, and you offer the missing variable (env, build, data); reject only with that record, or pair-debug the environment difference
- • "How would you fix our defect process?" — diagnose first with aging (where items die) and flow (which transitions are abused), then consolidate states with contracts and required-field enforcement; end with 'states are a shared language, maintained by definitions'
- • "Product wants to defer a critical bug." — ask for the four fields: target release, accepted impact, approver, early-pull trigger; without them it is not a deferral, it is a surprise scheduled for next release
Cheat Sheet
Defect Lifecycle States
Canonical flow: New → Assigned/Confirmed → In Progress → Fixed → Verify → Closed; side exits Rejected / Deferred / Duplicate; Reopened loops to In Progress with evidence.
Evidence contracts per transition:
| Transition | Must carry |
|---|---|
| New → Confirmed | Triage owner, severity, environment |
| In Progress → Fixed | Commit reference, correct branch |
| Fixed → Verify | Build deployed to test env |
| Verify → Closed | Retest result recorded on that build |
| Verify → Reopened | Fresh failure evidence (build + steps/trace) |
| → Deferred | Target release + accepted impact + approver + early-pull trigger |
| → Rejected | Flavor + proof (spec match / repro attempts / PO confirmation) |
Doubles count: five sightings of one root cause = one defect, five risk signals — keep the sighting count in triage notes.
Queue hygiene: age targets (triage ≤ 1 day, retest ≤ 1 day after build) + weekly aging (stalls) and flow (re-open/reject/defer counts) reviews; add states only when data proves a recurring ambiguous transition.