Judges whether a written requirement can be tested at all, by scoring each claim against three heuristics: Observable (a state or output visible from outside the system), Decidable (a deterministic pass/fail against a named oracle), and Bounded (stated inputs, states, and users). Supplies untestable-to-testable rewrite pairs per heuristic, severity assignment, a BLOCK / REVIEW / OK verdict rule, and a findings table that pairs every flagged sentence with a concrete replacement. Scope is testability only: it does not write the tests, rank risk, or judge whether the requirement is correct or complete. Use when a user story, acceptance criterion, PRD section, API contract, or PR description is about to be handed to implementation and someone needs to know which sentences cannot be verified as written.
75
94%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Three end-to-end reviews at each verdict level. The three heuristics, the rubric procedure, the severity and verdict rules, the output format, and the anti-patterns live in SKILL.md.
Input:
"We will improve the checkout flow to feel modern and respond quickly. Users on mobile should have a smooth experience."
Output:
## Testability review - verdict: BLOCK
**Artifact:** checkout redesign PRD, the two sentences above
**Claims found:** 3
**Untestable claims:** 3
### Findings
| Severity | Claim | Violation | Suggested rewrite |
|----------|-------|-----------|-------------------|
| Block | "feel modern" | Observable | "Matches the approved design frame `Checkout-2026Q2`; the visual baseline test passes at the 375 / 768 / 1280 / 1920 viewports." |
| Block | "respond quickly" | Observable | "p95 page load on `/checkout` is at most 1.5s on a 4G profile; INP is at most 200ms during form interaction." |
| Block | "smooth experience [on mobile]" | Observable + Decidable | "No horizontal scrollbar at the 375px viewport; tap targets are at least 44 by 44 CSS pixels; the automated accessibility scan reports zero violations." |Notes on the rewrites:
Three vague phrases become three assertions someone can build to and someone else can verify.
Input:
"Acceptance criteria:
- Given a logged-in user with email confirmed,
- When they navigate to
/profile/settings,- Then the email field shows the confirmed address with a green checkmark icon (
data-testid="email-confirmed-icon")."
Output:
## Testability review - verdict: OK
**Artifact:** profile settings story, acceptance criteria block
**Claims found:** 1
**Untestable claims:** 0
The criterion names the actor state (logged in, email confirmed), a
specific URL, and a specific element via `data-testid`. It passes
Observable, Decidable, and Bounded. Ready to be formatted into executable
test cases.An OK verdict is not a rubber stamp on the requirement. It says only that the sentence can be tested, not that testing it is worthwhile or that the behavior is right.
Input:
"When a user logs in, redirect them to their last-visited page."
Output:
## Testability review - verdict: REVIEW
**Artifact:** login redirect story, single acceptance criterion
**Claims found:** 1
**Untestable claims:** 1
| Severity | Claim | Violation | Suggested rewrite |
|----------|-------|-----------|-------------------|
| Review | "redirect them to their last-visited page" | Bounded | "After a successful login, if `localStorage.lastVisitedPath` is set AND matches `/^\\/[a-z]/` (an in-app path), redirect there. Otherwise redirect to `/dashboard`. If `lastVisitedPath` is older than 7 days, ignore it and redirect to `/dashboard`." |The claim was already observable (a redirect target is inspectable) and decidable (a URL either equals the expected value or does not). Only the input domain was missing. Supplying it turns one ambiguous sentence into three deterministic cases: valid recent path, absent or external path, and stale path.