{"abstract":"The top buttonhole lands in the neckband.","category":"Knitting and sewing pattern grading","checks":8,"contract":"Buttonholes run from bottom_offset to band_len - top_offset (cm), evenly spaced; a single buttonhole goes at the top position. Convert each position to a 1-based row: half-up of position*rows_per_10cm/10, plus 1. n < 1 -> \"error: count\"; top position below bottom -> \"error: offsets\".","contract_signature":"band_len, n, top_offset, bottom_offset, rows_per_10cm","evaluation_group":"w2-knitting_and_sewing_pattern_grading-buttonhole-rows","failed_approach":"Subtracting both offsets double-counts the bottom offset.","family":"w2-knitting_and_sewing_pattern_grading-buttonhole-rows-top-offset","id":"FA-97626","implementations":{"attempt":{"sha256":"cbd3cc39bd472acf4c473e1e125395899b1cdd7e486e8bc3b4eddb5c784cced9","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nfrom fractions import Fraction\nN = 1\nobservations = []\ndef solve(band_len, n, top_offset, bottom_offset, rows_per_10cm):\n    if n < 1:\n        return 'error: count'\n    lo = Fraction(str(bottom_offset))\n    hi = Fraction(str(band_len)) - Fraction(str(top_offset)) - Fraction(str(bottom_offset))\n    if hi < lo:\n        return 'error: offsets'\n    g = Fraction(str(rows_per_10cm)) / 10\n    if n == 1:\n        pos = [hi]\n    else:\n        gap = (hi - lo) / (n - 1)\n        pos = [lo + i * gap for i in range(n)]\n    return [math.floor(p * g + Fraction(1, 2)) + 1 for p in pos]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['single button', [40, 1, 2, 2, '28'], [107]], ['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['regression: top offset', [40, 4, 2, 1, '36.5'], [5, 50, 95, 140]],\n  ['repair check: top offset', [60, 7, 1.5, 1, '30'], [4, 33, 62, 90, 119, 148, 177]],\n  ['generated control 1', [55.5, 7, 1, 4, '32'], [14, 41, 68, 95, 122, 148, 175]],\n  ['generated control 2', [50, 4, 2, 4, '36.5'], [16, 69, 123, 176]],\n  ['generated control 3', [40, 6, 1, 1, '32'], [4, 29, 53, 77, 101, 126]]],\n [['single button', [40, 1, 2, 2, '28'], [107]], ['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['regression: top offset', [40, 4, 3, 1, '30'], [4, 40, 76, 112]],\n  ['repair check: top offset', [50, 5, 2, 2.5, '32'], [9, 45, 82, 118, 155]],\n  ['generated control 1', [55.5, 2, 1.5, 2.5, '32'], [9, 174]],\n  ['generated control 2', [40, 6, 3, 1, '28'], [4, 24, 44, 64, 84, 105]],\n  ['generated control 3', [60, 0, 2, 2.5, '32'], 'error: count']],\n [['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['single button', [40, 1, 2, 2, '28'], [107]],\n  ['regression: top offset', [55.5, 7, 1.5, 4, '28'], [12, 36, 59, 82, 106, 129, 152]],\n  ['repair check: top offset', [40, 6, 2, 1, '36.5'], [5, 32, 59, 86, 113, 140]],\n  ['generated control 1', [50, 1, 3, 4, '32'], [151]],\n  ['generated control 2', [55.5, 7, 2, 2, '36.5'], [8, 40, 71, 102, 134, 165, 196]],\n  ['generated control 3', [55.5, 6, 1, 2.5, '30'], [9, 40, 71, 102, 133, 165]]],\n [['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['single button', [40, 1, 2, 2, '28'], [107]], ['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['regression: top offset', [55.5, 5, 2, 4, '36.5'], [16, 61, 106, 151, 196]],\n  ['repair check: top offset', [50, 7, 3, 2.5, '36.5'], [10, 37, 64, 91, 118, 145, 173]],\n  ['generated control 1', [60, 1, 1, 2.5, '36.5'], [216]],\n  ['generated control 2', [40, 6, 2, 4, '32'], [14, 36, 57, 79, 101, 123]],\n  ['generated control 3', [50, 2, 3, 4, '28'], [12, 133]]],\n [['single button', [40, 1, 2, 2, '28'], [107]], ['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['regression: top offset', [50, 6, 3, 2.5, '28'], [8, 33, 58, 83, 108, 133]],\n  ['repair check: top offset', [62, 5, 2, 1, '36.5'], [5, 58, 112, 166, 220]],\n  ['generated control 1', [50, 6, 1.5, 4, '28'], [12, 37, 62, 87, 112, 137]],\n  ['generated control 2', [40, 5, 3, 1, '32'], [4, 33, 62, 91, 119]],\n  ['generated control 3', [62, 2, 1.5, 1, '32'], [4, 195]]]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"842a401ecb838a497e35f1e2afc61346df600744b2798d041709e561fa69a877","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport math\nfrom fractions import Fraction\nN = 1\nobservations = []\ndef solve(band_len, n, top_offset, bottom_offset, rows_per_10cm):\n    if n < 1:\n        return 'error: count'\n    lo = Fraction(str(bottom_offset))\n    hi = Fraction(str(band_len))\n    if hi < lo:\n        return 'error: offsets'\n    g = Fraction(str(rows_per_10cm)) / 10\n    if n == 1:\n        pos = [hi]\n    else:\n        gap = (hi - lo) / (n - 1)\n        pos = [lo + i * gap for i in range(n)]\n    return [math.floor(p * g + Fraction(1, 2)) + 1 for p in pos]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['single button', [40, 1, 2, 2, '28'], [107]], ['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['regression: top offset', [40, 4, 2, 1, '36.5'], [5, 50, 95, 140]],\n  ['repair check: top offset', [60, 7, 1.5, 1, '30'], [4, 33, 62, 90, 119, 148, 177]],\n  ['generated control 1', [55.5, 7, 1, 4, '32'], [14, 41, 68, 95, 122, 148, 175]],\n  ['generated control 2', [50, 4, 2, 4, '36.5'], [16, 69, 123, 176]],\n  ['generated control 3', [40, 6, 1, 1, '32'], [4, 29, 53, 77, 101, 126]]],\n [['single button', [40, 1, 2, 2, '28'], [107]], ['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['regression: top offset', [40, 4, 3, 1, '30'], [4, 40, 76, 112]],\n  ['repair check: top offset', [50, 5, 2, 2.5, '32'], [9, 45, 82, 118, 155]],\n  ['generated control 1', [55.5, 2, 1.5, 2.5, '32'], [9, 174]],\n  ['generated control 2', [40, 6, 3, 1, '28'], [4, 24, 44, 64, 84, 105]],\n  ['generated control 3', [60, 0, 2, 2.5, '32'], 'error: count']],\n [['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['single button', [40, 1, 2, 2, '28'], [107]],\n  ['regression: top offset', [55.5, 7, 1.5, 4, '28'], [12, 36, 59, 82, 106, 129, 152]],\n  ['repair check: top offset', [40, 6, 2, 1, '36.5'], [5, 32, 59, 86, 113, 140]],\n  ['generated control 1', [50, 1, 3, 4, '32'], [151]],\n  ['generated control 2', [55.5, 7, 2, 2, '36.5'], [8, 40, 71, 102, 134, 165, 196]],\n  ['generated control 3', [55.5, 6, 1, 2.5, '30'], [9, 40, 71, 102, 133, 165]]],\n [['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['single button', [40, 1, 2, 2, '28'], [107]], ['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['regression: top offset', [55.5, 5, 2, 4, '36.5'], [16, 61, 106, 151, 196]],\n  ['repair check: top offset', [50, 7, 3, 2.5, '36.5'], [10, 37, 64, 91, 118, 145, 173]],\n  ['generated control 1', [60, 1, 1, 2.5, '36.5'], [216]],\n  ['generated control 2', [40, 6, 2, 4, '32'], [14, 36, 57, 79, 101, 123]],\n  ['generated control 3', [50, 2, 3, 4, '28'], [12, 133]]],\n [['single button', [40, 1, 2, 2, '28'], [107]], ['no buttons', [40, 0, 2, 2, '28'], 'error: count'],\n  ['five buttons', [50, 5, 1.5, 2, '30'], [7, 42, 77, 112, 147]],\n  ['regression: top offset', [50, 6, 3, 2.5, '28'], [8, 33, 58, 83, 108, 133]],\n  ['repair check: top offset', [62, 5, 2, 1, '36.5'], [5, 58, 112, 166, 220]],\n  ['generated control 1', [50, 6, 1.5, 4, '28'], [12, 37, 62, 87, 112, 137]],\n  ['generated control 2', [40, 5, 3, 1, '32'], [4, 33, 62, 91, 119]],\n  ['generated control 3', [62, 2, 1.5, 1, '32'], [4, 195]]]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-knitting_and_sewing_pattern_grading-buttonhole-rows-top-offset","generated_at":"2026-09-29T14:52:34.003807+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Cardigan button bands place buttonholes evenly between neck and hem offsets.","root_cause":"The top offset is not subtracted from the band length.","sha256":"914ca0d2487b9ac7df05795ed00c58851fbf152e9f603c570a8b94e6cc56f50c","title":"Buttonhole row planner: top offset · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verified":true,"visibility":"public","verification":{"attempt":{"elapsed_ms":43.952,"exit_code":1,"observations":[{"actual":[7,40,74,107,141],"check":"five buttons","expected":[7,42,77,112,147],"passed":false},{"actual":[102],"check":"single button","expected":[107],"passed":false},{"actual":"error: count","check":"no buttons","expected":"error: count","passed":true},{"actual":[5,48,92,136],"check":"regression: top offset","expected":[5,50,95,140],"passed":false},{"actual":[4,32,61,89,117,145,174],"check":"repair check: top offset","expected":[4,33,62,90,119,148,177],"passed":false},{"actual":[14,39,63,88,113,138,163],"check":"generated control 1","expected":[14,41,68,95,122,148,175],"passed":false},{"actual":[16,64,113,162],"check":"generated control 2","expected":[16,69,123,176],"passed":false},{"actual":[4,28,52,75,99,123],"check":"generated control 3","expected":[4,29,53,77,101,126],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"five buttons\", \"actual\": [7, 40, 74, 107, 141], \"expected\": [7, 42, 77, 112, 147], \"passed\": false}, {\"check\": \"single button\", \"actual\": [102], \"expected\": [107], \"passed\": false}, {\"check\": \"no buttons\", \"actual\": \"error: count\", \"expected\": \"error: count\", \"passed\": true}, {\"check\": \"regression: top offset\", \"actual\": [5, 48, 92, 136], \"expected\": [5, 50, 95, 140], \"passed\": false}, {\"check\": \"repair check: top offset\", \"actual\": [4, 32, 61, 89, 117, 145, 174], \"expected\": [4, 33, 62, 90, 119, 148, 177], \"passed\": false}, {\"check\": \"generated control 1\", \"actual\": [14, 39, 63, 88, 113, 138, 163], \"expected\": [14, 41, 68, 95, 122, 148, 175], \"passed\": false}, {\"check\": \"generated control 2\", \"actual\": [16, 64, 113, 162], \"expected\": [16, 69, 123, 176], \"passed\": false}, {\"check\": \"generated control 3\", \"actual\": [4, 28, 52, 75, 99, 123], \"expected\": [4, 29, 53, 77, 101, 126], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.016,"exit_code":1,"observations":[{"actual":[7,43,79,115,151],"check":"five buttons","expected":[7,42,77,112,147],"passed":false},{"actual":[113],"check":"single button","expected":[107],"passed":false},{"actual":"error: count","check":"no buttons","expected":"error: count","passed":true},{"actual":[5,52,100,147],"check":"regression: top offset","expected":[5,50,95,140],"passed":false},{"actual":[4,34,63,93,122,152,181],"check":"repair check: top offset","expected":[4,33,62,90,119,148,177],"passed":false},{"actual":[14,41,69,96,124,151,179],"check":"generated control 1","expected":[14,41,68,95,122,148,175],"passed":false},{"actual":[16,72,128,184],"check":"generated control 2","expected":[16,69,123,176],"passed":false},{"actual":[4,29,54,79,104,129],"check":"generated control 3","expected":[4,29,53,77,101,126],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"five buttons\", \"actual\": [7, 43, 79, 115, 151], \"expected\": [7, 42, 77, 112, 147], \"passed\": false}, {\"check\": \"single button\", \"actual\": [113], \"expected\": [107], \"passed\": false}, {\"check\": \"no buttons\", \"actual\": \"error: count\", \"expected\": \"error: count\", \"passed\": true}, {\"check\": \"regression: top offset\", \"actual\": [5, 52, 100, 147], \"expected\": [5, 50, 95, 140], \"passed\": false}, {\"check\": \"repair check: top offset\", \"actual\": [4, 34, 63, 93, 122, 152, 181], \"expected\": [4, 33, 62, 90, 119, 148, 177], \"passed\": false}, {\"check\": \"generated control 1\", \"actual\": [14, 41, 69, 96, 124, 151, 179], \"expected\": [14, 41, 68, 95, 122, 148, 175], \"passed\": false}, {\"check\": \"generated control 2\", \"actual\": [16, 72, 128, 184], \"expected\": [16, 69, 123, 176], \"passed\": false}, {\"check\": \"generated control 3\", \"actual\": [4, 29, 54, 79, 104, 129], \"expected\": [4, 29, 53, 77, 101, 126], \"passed\": false}], \"passed\": false}\n"}},"member_only":{"stages":["fixed"],"fields":["implementations.fixed","verification.fixed","harness","repair"],"note":"The verified repair, its recorded checks, the repair description, and the scoring harness are available to members."}}