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.
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| 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