In a tracked defect's explanation, how do the symptom, the condition that produced it, and the weakness that let it reach a user differ?
answer
- Three questions, not one
- What was seen, what happened, what allowed it
- Observation, occurrence condition, standing weakness
- Only the third layer generalises
basics
~20 sThe symptom is what was observed. The condition that produced it is the specific state or input that made the code fail that time. The weakness is the missing guard or assumption that allowed the whole family of failures.
solid answer
~50 sKeep three layers apart in the write-up. The **symptom** is the observation somebody reported: a wrong total, a blank screen, a refused save. The **condition that directly produced it** is the state the system was in on that occasion, such as an empty list, a value at the boundary, or two updates landing in the same instant. The **weakness** is what made that state dangerous: an unvalidated boundary, an assumption two components did not share, a design in which an invalid state can be built at all. Only the third layer generalises. Change the condition and the same weakness produces a different symptom tomorrow. Put all three on the defect record, because a reader who has only the symptom cannot judge the fix, and a reader who has only the condition will fix one occurrence.
code
pseudocode · 7 linesdefect DEF-4127:
symptom: "invoice total prints as 0.00 for baskets over 1000 items"
condition: "quantity sum exceeds the width of the accumulator at 32768 units"
weakness: "accumulator sized for one line, never re-checked when basket-wide
totals were added; no check of the sum against that width"
fixed_at: weakness
still_open: nonego deeper
Be ready to separate what you saw from why it happened. For a defect you fixed, say the observation, the state that produced it, and what in the code allowed that state to matter.
An interviewer expects you to explain why the middle layer is per-occurrence while the third is per-family, and to show where each one lands on a defect record so a later reader can act on it.
Demonstrate that you read other people's defect records for the missing layer, and that you push back when a fix note describes the change without saying which layer the change lands at.
Own the standard: what a defect record must carry before it can close, and what it costs the team when explanations stop at the observation. That is a norm you set, not a form you fill in.
## Three questions people collapse into one A defect explanation has to answer three separate questions, and most weak write-ups answer one of them and imply the rest. - **What was observed?** A wrong total on a printed invoice, a blank list where rows were expected, a save that returned an error to the person doing it. This is the **symptom**. - **What state was the system in when it happened?** The basket held more than a thousand items; an incoming data row arrived with an empty owner field; two updates for the same row landed within the same millisecond. This is the **condition that directly produced this occurrence**. - **Why was that state able to do damage?** The sum was accumulated in a counter narrower than the values it now receives; the read path assumed an owner is always present; the update path assumed no two writers. This is the **weakness**. Every real defect has all three. What varies is how many of them the record admits to. ## What each layer is for | Layer | The question it answers | Scope | Evidence behind it | |---|---|---|---| | Symptom | What did somebody see? | This one report | The message, the screen, the failing check, the reporter's words | | Condition | What made it happen that time? | This occurrence | Reproduction steps, the input value, the timing, the data row | | Weakness | Why was that state dangerous? | The whole family of failures | The code or design that assumed the state could not arise | The scope column is the point. The symptom is one person's experience of the defect, and it can change completely without the defect changing at all: the same missing guard shows up as a wrong number on one screen and as a refused save on another. The condition is specific to the occurrence you happened to catch. Only the weakness describes something that will still be true tomorrow if you do nothing. ## The symptom is not the defect Recording "shows zero" as the cause is the most common failure of a defect record, and it has a specific cost: the next reader cannot tell whether two reports are the same defect. Two reports with the same symptom and different weaknesses are two defects; two reports with different symptoms and one weakness are one. A record that stops at the symptom cannot be de-duplicated by anyone who did not do the original investigation. ## The condition is real, but it is narrow The condition is not a lesser layer. It is what makes a defect reproducible, and without it nobody can confirm a fix. But it answers "how do I make this happen again", not "why does this happen at all". Two tests separate them: 1. **Change the condition slightly.** If a neighbouring value, a different route into the same code, or the same shape in a different field also fails, you are looking at one weakness with many possible conditions. 2. **Ask what the code believed.** Every condition-level explanation ends in an assumption somebody held: that the field is always present, that the number fits, that the two calls cannot interleave. Naming that belief is the third layer. ## Reaching the weakness layer You have reached it when the sentence you write is about the system rather than about the occurrence, and when it predicts failures you have not seen yet. "The basket had 1,200 items" is about the occurrence. "Totals are accumulated in a counter sized for a single line, and nothing checks the sum against that size" is about the system, and it predicts that a 40,000-item bulk import fails too, which you can then go and confirm. Two cautions: - **Do not keep asking why until you arrive at the organisation.** The layer this question is about is the weakness in the system under test: the missing guard, the unshared assumption, the invalid state that can be constructed. How the weakness got there, and which phase should have contained it, are different questions with different owners. - **Do not invent a weakness for a defect nobody could reproduce.** If the middle layer is unknown, record it as unknown alongside the evidence you do have. A guessed condition sends the fix at the wrong layer and closes the record on a fiction. ## Writing all three down A record that carries all three lets a stranger do four things you would otherwise have to do yourself: judge whether their new report is the same defect, re-create the failure, judge whether the merged change actually addresses it, and find the same weakness elsewhere in the code. That is the whole return on a few extra lines. The discipline is cheap at the moment of the fix, when all three are in your head, and expensive to reconstruct three months later, when the change is merged and the reporter has moved on.
- Where do the reproduction steps belong among the three layers?With the condition that directly produced the occurrence. Reproduction steps describe the state the system had to be in, not what was observed and not why that state was dangerous. They are the strongest evidence a later reader has that the middle layer is right, and they are what a confirming check re-creates. The symptom is what those steps end in.
- A defect record names only the symptom and the change that was merged. What does the next reader lose?They cannot tell whether the change removed one occurrence or the whole family, so they cannot judge whether a similar report is a duplicate. They also cannot re-derive the condition, so nobody can re-create the failure to confirm the fix still holds. Months later the same weakness in another component arrives as an unrelated new report.
- Can a defect legitimately have a symptom with no condition anyone can pin down?Yes, when nobody can re-create it. The record then carries the observation, the evidence gathered around it, and an explicit note that the middle layer is unknown. Saying so is better than promoting a plausible guess, because a guessed condition sends the fix at the wrong layer and closes the record on something nobody verified.
The flooded kitchen is the symptom, the tap left running is the condition that produced this flood, and the missing overflow drain is the weakness that turns any forgotten tap into a flood.
saying these in an interview costs you the question
- Calls the observed error message the root cause
- Treats reproduction steps as the explanation of why it failed
- Records what was changed but never what was wrong
- Assumes one occurrence's input describes the whole family
- Stops the explanation at the line that failed