Why I Made This
It kept happening to me over and over again (last time yesterday - seriously). The customer would report an issue, and I would jump to looking at the code and trying to figure out what is wrong. This would usually lead to a never-ending back and forth where I try to explain the code’s point of view while in reality not really understanding the problem that was reported. Even if I did understand the problem, the exchange with the customer would hint that I didn’t actually understand it well enough to explain simply. So I created this “SPEC” system. My hope is that it will help me get better at resolving customer-reported issues - this is why I decided to share it with you, the reader. Maybe it will help you too next time you are diving into a reported “weird behavior” or a “data discrepancy” issue.
What is SPEC
SPEC is a four-step checklist:
- Specify the expected outcome
- Pinpoint the source of truth
- Enumerate allowed transformations
- Compare to actual behavior
The first three steps force you to understand the problem before you even look at the code.
When to Use
- Bug reports
- Data discrepancies
- “Weird behavior” investigations
- Feature validation
- Anywhere you’re tempted to say “the code does X, so X must be right”
Rule: The code tells you what it does, not what it should do. Start with should!
The Rule
You cannot say “I found the issue” until you’ve completed S, P, and E. Skipping to C first risks mistaking “what the code does” for “what it should do.”
The Process
(S) Specify the Expected Outcome
What SHOULD happen, in domain/business language?
- No code terms. No implementation details.
- Write one sentence a non-technical stakeholder would understand.
- If you can’t write this sentence, stop. You don’t understand the ticket yet.
Examples:
- “gross_spend should reflect what the demand partner originally bid.”
- “Clicking Submit should create exactly one order.”
- “The $12 floor tag should result in $12 CPM.”
(P) Pinpoint the Source of Truth
Where does the correct value/behavior originate?
- Name the canonical source: an API response, a database field, a spec, a user action.
- This is your reference point for “correct.”
Examples:
- “The DSP’s bid response → bidRevenue.revenue”
- “OpenRTB 2.5 spec defines bidfloor semantics”
- “User’s form input at time of submission”
(E) Enumerate Allowed Transformations
What operations are legitimate between source and outcome?
- List ONLY what should happen to the value.
- This is your whitelist - anything not listed is a bug candidate.
Examples:
- “Currency conversion. Nothing else.”
- “Validation → sanitization → storage”
- “Floor sent to bidder, not applied to their response”
(C) Compare to Actual
What does the system actually do?
Before inspecting the code: Confirm that you are looking at the version that produced the reported behavior.
- NOW look at the code/config/logs.
- The bug is where actual diverges from S, P, or E.
- If actual matches S/P/E and there’s still a problem, revisit your assumptions.
Quick Reference
| Step | Stands for | Question | Output |
|---|---|---|---|
| S | Specify | What should happen? | One plain sentence |
| P | Pinpoint | Where does truth live? | System/field/spec name |
| E | Enumerate | What ops are allowed? | Whitelist of transformations |
| C | Compare | What actually happens? | Code trace → find divergence |