#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”
#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?
- 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 |