Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Given an input field whose valid values form an integer range with fixed lower and upper limits, enumerates the complete boundary test set — three integers at each limit (the limit, the value just inside, and the value just outside), then deduplicated and sorted ascending — so off-by-one and wrong-comparison defects at the edges are caught. Use when someone gives a field's numeric min and max and asks which exact integer values to feed at the boundaries. Do NOT use for writing the test code or picking a framework, choosing among test-design techniques in the abstract, partitioning non-numeric value classes, or the edges of continuous / floating-point quantities.
.claude/skills/boundary-value-enumeration/SKILL.md| Model | Eval pass | Runs |
|---|---|---|
| gemini-3.6-flash | 100% | 2 |
| Model | Lift | Δ tokens | Δ turns | Cases | Verified |
|---|---|---|---|---|---|
| gemini-3.6-flashbest | +30% | +104% | 0% | 23 | 54d ago |
| gemini-3.5-flash | +12% | — | 0% | 26 | 61d ago |
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | — | — |
| case-13 | ✗→✓ | ▲ Improved | — | — |
| case-18 | ✗→✓ | ▲ Improved | — | — |
| case-14 | ✗→✓ | ▲ Improved | — | — |
| case-23 | ✗→✓ | ▲ Improved | — | — |
Handed a field that accepts an integer from a minimum to a maximum and asked which values to test at the edges, the base model names the two limits themselves — min and max — and stops. Sometimes it adds one step inside each. What it reliably omits are the two values just outside the valid range (min-1 and max+1), the invalid partitions that expose the most common defect of all: a > written where >= was meant, an array sized n instead of n+1, a loop that runs one iteration too few or too many. Testing only min and max cannot see those bugs — both endpoints are valid, so a wrong comparison that lets min-1 through or rejects max slips past.
The knowledge this skill supplies is the full three-points-per-boundary set and the rule for collapsing it when the range is small.
Activate when the input is an integer field bounded by a fixed lowest and highest allowed value — an age 18..120, a quantity 1..99, a port 1024..65535, a string length 3..30, a temperature in whole degrees — and the ask is which specific numbers to test at the edges. The answer is a concrete list of integers.
Do not activate to write the test code or choose a framework, to explain or compare testing techniques in the abstract, to partition a non-numeric field (a status enum, an email, a color name — those have no numeric edge; return an empty set), or to reason about a continuous / floating-point quantity where "just outside" needs an epsilon rather than ±1.
For a valid integer range [min, max], the boundary test set is the six values, three per limit:
min-1, min, min+1max-1, max, max+1min and max are the last valid values; min-1 and max+1 are the first invalid values on each side; min+1 and max-1 are one step inside. Then deduplicate and sort ascending — because when the range is narrow the two boundaries' triples overlap:
max - min >= 3 → all six are distinct: six values.max - min == 2 → min+1 equals max-1; they collapse to five.max - min == 1 (adjacent limits) → the triples overlap by two values; four remain (min-1, min, max, max+1).max - min == 0 (a single allowed value, min == max) → both triples are the same; three remain (v-1, v, v+1).The set never depends on the sign or magnitude of the limits: if min is 0, the just-outside value is -1; if min is negative, min-1 is further negative. Emit every value the rule produces, including negatives and zero.
(Standard boundary-value analysis, three-value variant — paraphrased from the ISTQB Foundation Level syllabus and BS 7925-2, as of 2026-07. https://www.istqb.org — the technique itself is uncontested; the base's gap is omitting the just-outside invalid points.)
Rule — include the just-outside invalid values. Field: a brightness setting accepting 10..90.
[10, 90] — only the two limits. Off-by-one bugs at either edge are invisible.[9, 10, 11, 89, 90, 91] — the limit, one inside, and one outside at each end.Rule — a range starting at zero produces a negative just-outside value. Field: a retry count 0..3.
[0, 1, 2, 3] — it lists the valid values and never tests below the floor.[-1, 0, 1, 2, 3] — min-1 is -1; min+1 (1) and max-1 (2) already sit among the valid values, so the deduplicated set is five.Rule — a single-value range collapses to three. Field: a lock that accepts exactly 50.
[50] — one value, no edges probed.[49, 50, 51] — min == max, so both triples coincide.Rule — negative limits shift, they do not disappear. Field: a thermostat -2..4.
[-2, 4].[-3, -2, -1, 0, 3, 4, 5] — min-1 is -3, max+1 is 5; nothing about the negative sign changes the recipe.max = min+1). The two triples share min+1 (= max) and max-1 (= min), so four distinct values remain — do not list six with duplicates.min-1 crosses zero. For 1..n the lower just-outside value is 0; for 0..n it is -1. Always compute min-1 literally.3..30 → 2,3,4,29,30,31); the field being text does not make it non-numeric.±1 is the wrong step size; this skill covers integer ranges only. Do not emit min-1/max+1 as if the field were integral.min-1 and max+1 every time — they are the whole point.min and max; two valid endpoints cannot catch a wrong comparison operator.0's lower neighbor is -1, a negative min's neighbor is more negative.±1 recipe to a non-integer or unordered field — return empty instead.[min, max] — the single most common and most damaging omission.min, min+1, max-1, max (four) but dropping min-1 and max+1 — the invalid partitions never get tested.[0,1] when only four distinct integers exist.min-1 to 0 for a 0..n range instead of testing -1.min-1, min, min+1.max-1, max, max+1.min-1 go to 0 or negative.min-1 and max+1) survived — they are the values the base drops.Return the values as a JSON object: {"boundary_values": [ ... ]} — one array, deduplicated, sorted from lowest to highest, integers only. When the input has no ordered integer range (a category, free text, a name, a boolean), the array is empty.
scripts/grading_spec.json holds the correct integer set for each benchmark field, and scripts/grade.py compares a submitted boundary_values array against it as a set — order-independent, with duplicates collapsed on both sides. See the eval suite.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted. The headline lift of +30 percentage points is the difference between those two pass rates over the 23 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
| Model | Method | Date | Lift |
|---|---|---|---|
| gemini-3.5-flash | replay | 7/21/2026 | +12% |
| gemini-3.5-flash | replay | 7/21/2026 | +8% |
Other measured skills in the registry, with their headline benchmark lift.