FAILURE MAP
← Case archive

FA-97681 / Knitting and sewing pattern grading / Open access

Sleeve cap ease checker: too-little bound · case 01

Exactly 2.5 cm of woven ease is reported as too little.

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The lower bound is exclusive.

VERIFIED REPAIR

Flag only ease strictly below the lower bound.

Unsuccessful approach: Testing against zero misses under-eased woven caps.

Case contract

Ease = cap - (front + back armhole). Allowed ease: woven 2.5-4.5, knit 0-1.5, leather 0-0.5 (inclusive; fabric trimmed, lower-case; other -> "error: fabric"). Verdict "too little", "too much" or "ok". Adjustment per side = (midpoint - ease)/2. Return [ease, verdict, adjust] with floats rounded to 2 decimals.

Why this case matters

Set-in sleeves need a fabric-dependent amount of cap ease to ease into the armhole.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(cap, front, back, fabric):
    R = {'woven': (Fraction(5, 2), Fraction(9, 2)), 'knit': (Fraction(0), Fraction(3, 2)), 'leather': (Fraction(0), Fraction(1, 2))}
    f = fabric.strip().lower()
    if f not in R:
        return 'error: fabric'
    lo, hi = R[f]
    ease = Fraction(cap) - (Fraction(front) + Fraction(back))
    if ease <= lo:
        verdict = 'too little'
    elif ease > hi:
        verdict = 'too much'
    else:
        verdict = 'ok'
    adjust = ((lo + hi) / 2 - ease) / 2
    return [round(float(ease), 2), verdict, round(float(adjust), 2)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['regression: too-little bound', ['48', '23.5', '22', 'woven'], [2.5, 'ok', 0.5]],
  ['repair check: too-little bound', ['49', '24', '23', 'woven'], [2.0, 'too little', 0.75]],
  ['generated control 1', ['46', '23.5', '22', 'Knit '], [0.5, 'ok', 0.12]],
  ['generated control 2', ['50.5', '22', '22', 'woven'], [6.5, 'too much', -1.5]],
  ['generated control 3', ['48', '23.5', '22', 'Knit '], [2.5, 'too much', -0.88]]],
 [['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['regression: too-little bound', ['48', '23.5', '24.5', 'leather'], [0.0, 'ok', 0.12]],
  ['repair check: too-little bound', ['48', '24', '23', 'woven'], [1.0, 'too little', 1.25]],
  ['generated control 1', ['46', '23.5', '24.5', 'leather'], [-2.0, 'too little', 1.12]],
  ['generated control 2', ['52', '24', '23', 'leather'], [5.0, 'too much', -2.38]],
  ['generated control 3', ['46', '23.5', '22', 'knit'], [0.5, 'ok', 0.12]]],
 [['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['regression: too-little bound', ['46', '24', '22', 'Knit '], [0.0, 'ok', 0.38]],
  ['repair check: too-little bound', ['46', '24', '22', 'woven'], [0.0, 'too little', 1.75]],
  ['generated control 1', ['48', '22', '23', 'knit'], [3.0, 'too much', -1.12]],
  ['generated control 2', ['46', '24', '23', 'knit'], [-1.0, 'too little', 0.88]],
  ['generated control 3', ['48', '22', '24.5', 'leather'], [1.5, 'too much', -0.62]]],
 [['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['regression: too-little bound', ['50.5', '23.5', '24.5', 'woven'], [2.5, 'ok', 0.5]],
  ['repair check: too-little bound', ['49', '24', '24.5', 'woven'], [0.5, 'too little', 1.5]],
  ['generated control 1', ['46', '24', '23', 'knit'], [-1.0, 'too little', 0.88]],
  ['generated control 2', ['50.5', '23.5', '22', 'leather'], [5.0, 'too much', -2.38]],
  ['generated control 3', ['52', '22', '23', 'woven'], [7.0, 'too much', -1.75]]],
 [['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['regression: too-little bound', ['46', '24', '22', 'Knit '], [0.0, 'ok', 0.38]],
  ['repair check: too-little bound', ['46', '23.5', '22', 'woven'], [0.5, 'too little', 1.5]],
  ['generated control 1', ['49', '23.5', '23', 'leather'], [2.5, 'too much', -1.12]],
  ['generated control 2', ['50.5', '22', '23', 'leather'], [5.5, 'too much', -2.62]],
  ['generated control 3', ['46', '23.5', '24.5', 'knit'], [-2.0, 'too little', 1.38]]]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
woven ok[3.0, 'ok', 0.25][3.0, 'ok', 0.25]Passed
knit too much[3.5, 'too much', -1.38][3.5, 'too much', -1.38]Passed
leather at lower bound[0.0, 'too little', 0.12][0.0, 'ok', 0.12]Failed
regression: too-little bound[2.5, 'too little', 0.5][2.5, 'ok', 0.5]Failed
repair check: too-little bound[2.0, 'too little', 0.75][2.0, 'too little', 0.75]Passed
generated control 1[0.5, 'ok', 0.12][0.5, 'ok', 0.12]Passed
generated control 2[6.5, 'too much', -1.5][6.5, 'too much', -1.5]Passed
generated control 3[2.5, 'too much', -0.88][2.5, 'too much', -0.88]Passed

SHA-256 / 6801db0936f611e571abf35fb63210b7445f4175721a1fa6a6250e2d2b8cb922

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(cap, front, back, fabric):
    R = {'woven': (Fraction(5, 2), Fraction(9, 2)), 'knit': (Fraction(0), Fraction(3, 2)), 'leather': (Fraction(0), Fraction(1, 2))}
    f = fabric.strip().lower()
    if f not in R:
        return 'error: fabric'
    lo, hi = R[f]
    ease = Fraction(cap) - (Fraction(front) + Fraction(back))
    if ease < 0:
        verdict = 'too little'
    elif ease > hi:
        verdict = 'too much'
    else:
        verdict = 'ok'
    adjust = ((lo + hi) / 2 - ease) / 2
    return [round(float(ease), 2), verdict, round(float(adjust), 2)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['regression: too-little bound', ['48', '23.5', '22', 'woven'], [2.5, 'ok', 0.5]],
  ['repair check: too-little bound', ['49', '24', '23', 'woven'], [2.0, 'too little', 0.75]],
  ['generated control 1', ['46', '23.5', '22', 'Knit '], [0.5, 'ok', 0.12]],
  ['generated control 2', ['50.5', '22', '22', 'woven'], [6.5, 'too much', -1.5]],
  ['generated control 3', ['48', '23.5', '22', 'Knit '], [2.5, 'too much', -0.88]]],
 [['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['regression: too-little bound', ['48', '23.5', '24.5', 'leather'], [0.0, 'ok', 0.12]],
  ['repair check: too-little bound', ['48', '24', '23', 'woven'], [1.0, 'too little', 1.25]],
  ['generated control 1', ['46', '23.5', '24.5', 'leather'], [-2.0, 'too little', 1.12]],
  ['generated control 2', ['52', '24', '23', 'leather'], [5.0, 'too much', -2.38]],
  ['generated control 3', ['46', '23.5', '22', 'knit'], [0.5, 'ok', 0.12]]],
 [['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['regression: too-little bound', ['46', '24', '22', 'Knit '], [0.0, 'ok', 0.38]],
  ['repair check: too-little bound', ['46', '24', '22', 'woven'], [0.0, 'too little', 1.75]],
  ['generated control 1', ['48', '22', '23', 'knit'], [3.0, 'too much', -1.12]],
  ['generated control 2', ['46', '24', '23', 'knit'], [-1.0, 'too little', 0.88]],
  ['generated control 3', ['48', '22', '24.5', 'leather'], [1.5, 'too much', -0.62]]],
 [['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['regression: too-little bound', ['50.5', '23.5', '24.5', 'woven'], [2.5, 'ok', 0.5]],
  ['repair check: too-little bound', ['49', '24', '24.5', 'woven'], [0.5, 'too little', 1.5]],
  ['generated control 1', ['46', '24', '23', 'knit'], [-1.0, 'too little', 0.88]],
  ['generated control 2', ['50.5', '23.5', '22', 'leather'], [5.0, 'too much', -2.38]],
  ['generated control 3', ['52', '22', '23', 'woven'], [7.0, 'too much', -1.75]]],
 [['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['regression: too-little bound', ['46', '24', '22', 'Knit '], [0.0, 'ok', 0.38]],
  ['repair check: too-little bound', ['46', '23.5', '22', 'woven'], [0.5, 'too little', 1.5]],
  ['generated control 1', ['49', '23.5', '23', 'leather'], [2.5, 'too much', -1.12]],
  ['generated control 2', ['50.5', '22', '23', 'leather'], [5.5, 'too much', -2.62]],
  ['generated control 3', ['46', '23.5', '24.5', 'knit'], [-2.0, 'too little', 1.38]]]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
woven ok[3.0, 'ok', 0.25][3.0, 'ok', 0.25]Passed
knit too much[3.5, 'too much', -1.38][3.5, 'too much', -1.38]Passed
leather at lower bound[0.0, 'ok', 0.12][0.0, 'ok', 0.12]Passed
regression: too-little bound[2.5, 'ok', 0.5][2.5, 'ok', 0.5]Passed
repair check: too-little bound[2.0, 'ok', 0.75][2.0, 'too little', 0.75]Failed
generated control 1[0.5, 'ok', 0.12][0.5, 'ok', 0.12]Passed
generated control 2[6.5, 'too much', -1.5][6.5, 'too much', -1.5]Passed
generated control 3[2.5, 'too much', -0.88][2.5, 'too much', -0.88]Passed

SHA-256 / 1cde08fbbec20451897296d42c3015d5624ebf79b7506c23e665d27b9be63926

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
from fractions import Fraction
N = 1
observations = []
def solve(cap, front, back, fabric):
    R = {'woven': (Fraction(5, 2), Fraction(9, 2)), 'knit': (Fraction(0), Fraction(3, 2)), 'leather': (Fraction(0), Fraction(1, 2))}
    f = fabric.strip().lower()
    if f not in R:
        return 'error: fabric'
    lo, hi = R[f]
    ease = Fraction(cap) - (Fraction(front) + Fraction(back))
    if ease < lo:
        verdict = 'too little'
    elif ease > hi:
        verdict = 'too much'
    else:
        verdict = 'ok'
    adjust = ((lo + hi) / 2 - ease) / 2
    return [round(float(ease), 2), verdict, round(float(adjust), 2)]
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['regression: too-little bound', ['48', '23.5', '22', 'woven'], [2.5, 'ok', 0.5]],
  ['repair check: too-little bound', ['49', '24', '23', 'woven'], [2.0, 'too little', 0.75]],
  ['generated control 1', ['46', '23.5', '22', 'Knit '], [0.5, 'ok', 0.12]],
  ['generated control 2', ['50.5', '22', '22', 'woven'], [6.5, 'too much', -1.5]],
  ['generated control 3', ['48', '23.5', '22', 'Knit '], [2.5, 'too much', -0.88]]],
 [['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['regression: too-little bound', ['48', '23.5', '24.5', 'leather'], [0.0, 'ok', 0.12]],
  ['repair check: too-little bound', ['48', '24', '23', 'woven'], [1.0, 'too little', 1.25]],
  ['generated control 1', ['46', '23.5', '24.5', 'leather'], [-2.0, 'too little', 1.12]],
  ['generated control 2', ['52', '24', '23', 'leather'], [5.0, 'too much', -2.38]],
  ['generated control 3', ['46', '23.5', '22', 'knit'], [0.5, 'ok', 0.12]]],
 [['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['regression: too-little bound', ['46', '24', '22', 'Knit '], [0.0, 'ok', 0.38]],
  ['repair check: too-little bound', ['46', '24', '22', 'woven'], [0.0, 'too little', 1.75]],
  ['generated control 1', ['48', '22', '23', 'knit'], [3.0, 'too much', -1.12]],
  ['generated control 2', ['46', '24', '23', 'knit'], [-1.0, 'too little', 0.88]],
  ['generated control 3', ['48', '22', '24.5', 'leather'], [1.5, 'too much', -0.62]]],
 [['woven lower edge', ['50.5', '24', '24', 'woven'], [2.5, 'ok', 0.5]],
  ['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['regression: too-little bound', ['50.5', '23.5', '24.5', 'woven'], [2.5, 'ok', 0.5]],
  ['repair check: too-little bound', ['49', '24', '24.5', 'woven'], [0.5, 'too little', 1.5]],
  ['generated control 1', ['46', '24', '23', 'knit'], [-1.0, 'too little', 0.88]],
  ['generated control 2', ['50.5', '23.5', '22', 'leather'], [5.0, 'too much', -2.38]],
  ['generated control 3', ['52', '22', '23', 'woven'], [7.0, 'too much', -1.75]]],
 [['woven ok', ['50', '23', '24', 'woven'], [3.0, 'ok', 0.25]],
  ['knit too much', ['52', '24', '24.5', 'knit'], [3.5, 'too much', -1.38]],
  ['leather at lower bound', ['46', '23', '23', 'leather'], [0.0, 'ok', 0.12]],
  ['regression: too-little bound', ['46', '24', '22', 'Knit '], [0.0, 'ok', 0.38]],
  ['repair check: too-little bound', ['46', '23.5', '22', 'woven'], [0.5, 'too little', 1.5]],
  ['generated control 1', ['49', '23.5', '23', 'leather'], [2.5, 'too much', -1.12]],
  ['generated control 2', ['50.5', '22', '23', 'leather'], [5.5, 'too much', -2.62]],
  ['generated control 3', ['46', '23.5', '24.5', 'knit'], [-2.0, 'too little', 1.38]]]]
for label, args, expected in fixtures[N - 1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
woven ok[3.0, 'ok', 0.25][3.0, 'ok', 0.25]Passed
knit too much[3.5, 'too much', -1.38][3.5, 'too much', -1.38]Passed
leather at lower bound[0.0, 'ok', 0.12][0.0, 'ok', 0.12]Passed
regression: too-little bound[2.5, 'ok', 0.5][2.5, 'ok', 0.5]Passed
repair check: too-little bound[2.0, 'too little', 0.75][2.0, 'too little', 0.75]Passed
generated control 1[0.5, 'ok', 0.12][0.5, 'ok', 0.12]Passed
generated control 2[6.5, 'too much', -1.5][6.5, 'too much', -1.5]Passed
generated control 3[2.5, 'too much', -0.88][2.5, 'too much', -0.88]Passed

SHA-256 / 4304f41131f5ff48dcf6dd09e6e7b64fb3774709621c42df37b02e269afd6df3

Verification & scope

A deterministic toy contract stated in full here; it is a bounded teaching model, not an authoritative reference or standards implementation. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:52:34.541981+00:00.

Case digest / ff0784068bf4ef9274232cc581767a89ac73355ce5053b7cde34ce2f1bd0f41c