{"abstract":"A four-card run also scores its two three-card sub-runs.","category":"Card game rule engines","checks":8,"contract":"Input [four_card_hand, starter, is_crib]. Fifteens (any 2-5 cards, A=1, T/J/Q/K=10) score 2; each pair 2; runs score their length for every distinct combination of the longest run length; a four-card hand flush scores 4 (+1 with the starter) but the crib scores only a five-card flush; a hand jack matching the starter suit scores 1. Return the total.","evaluation_group":"w2-card-game-rule-engines-cribbage-hand","failed_approach":"Scoring the length once ignores double and triple runs.","family":"w2-card-game-rule-engines-cribbage-hand-run-length-precedence","id":"FA-83541","implementations":{"attempt":{"sha256":"b1f94fa4940068afba72f4ebcf0e91aaa1595e4453d31bfd7460d59fc8662f74","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport itertools\nN = 1\nobservations = []\ndef solve(x):\n    hand, starter, crib = x\n    order = 'A23456789TJQK'\n    cards = hand + [starter]\n    def val(c):\n        return min(order.index(c[0]) + 1, 10)\n    score = 0\n    for k in range(2, 6):\n        for combo in itertools.combinations(cards, k):\n            if sum(val(c) for c in combo) == 15:\n                score += 2\n    for a, b in itertools.combinations(cards, 2):\n        if a[0] == b[0]:\n            score += 2\n    ranks = sorted(order.index(c[0]) for c in cards)\n    for size in (5, 4, 3):\n        runs = 0\n        for combo in itertools.combinations(ranks, size):\n            if all(combo[i + 1] == combo[i] + 1 for i in range(size - 1)):\n                runs += 1\n        if runs:\n            score += size\n            break\n    suits = [c[1] for c in hand]\n    if len(set(suits)) == 1:\n        if starter[1] == suits[0]:\n            score += 5\n        elif not crib:\n            score += 4\n    for c in hand:\n        if c[0] == 'J' and c[1] == starter[1]:\n            score += 1\n    return score\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[['AC', '9C', '4C', 'TC'], '5S', True], 6], [[['KD', 'AH', '4S', '8D'], 'QH', False], 4], [[['3C', '3S', '4S', '5H'], '2D', False], 12], [[['5H', '9S', '6S', '2S'], 'AH', False], 4], [[['3S', '3H', '5H', 'JH'], 'QS', False], 6], [[['4C', 'QC', 'AC', '6C'], '5D', True], 9], [[['AD', 'AH', '2S', '3H'], 'KC', False], 12], [[['6H', '6D', '7S', '8H'], 'JD', False], 10]], [[[['6S', '8D', 'JD', '9C'], '6D', False], 7], [[['4S', '5D', '9D', 'TC'], 'QH', True], 4], [[['5H', 'KC', '2H', '3S'], '6H', True], 4], [[['9H', '7H', 'QH', 'TH'], 'JH', False], 9], [[['2C', '2S', '3S', '4H'], 'KD', False], 12], [[['4S', '3S', '9S', 'TD'], '7C', False], 0], [[['4C', '4S', '5S', '6H'], '3D', True], 14], [[['KH', '9S', 'JS', 'JD'], 'QC', False], 8]], [[[['3H', 'QS', '3C', '6S'], '8D', False], 2], [[['JH', '9H', '9S', 'TD'], '3H', False], 9], [[['6C', '2C', '7C', 'AC'], '4H', True], 2], [[['4D', 'AS', '7H', 'QD'], '9S', False], 2], [[['6S', '5S', 'QS', '8C'], 'AC', False], 4], [[['8S', 'QS', 'TH', '9C'], 'QC', False], 5], [[['QS', 'KC', 'JC', '6H'], 'TH', False], 4], [[['AC', 'AH', '2S', '3H'], 'AD', False], 15]], [[[['AD', 'AH', '2S', '3H'], 'KC', False], 12], [[['AS', '9S', 'TS', '2S'], '4C', False], 8], [[['TD', 'KS', 'TH', 'TS'], 'JC', False], 6], [[['KS', '5D', '3H', '8D'], 'KD', True], 6], [[['2S', '8S', 'TC', 'JS'], 'QH', False], 3], [[['9H', '7S', 'QH', '5H'], '3D', False], 4], [[['KH', '3C', '5H', '5C'], '8S', False], 6], [[['3H', '4D', '6D', 'AS'], '5S', False], 8]], [[[['8D', '8C', '9S', 'TH'], 'AH', True], 8], [[['2H', '5H', 'AC', '3S'], '8C', False], 5], [[['AD', '4S', '9D', '4H'], 'TH', False], 6], [[['9S', '9C', 'JH', 'KS'], '3H', False], 3], [[['KD', 'TC', 'QS', '4D'], 'TH', True], 2], [[['QD', '8S', 'JC', '5H'], '6C', False], 5], [[['6H', '6D', '7S', '8H'], 'JD', False], 10], [[['5S', 'TD', 'JC', 'QH'], 'KS', False], 12]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"hand score case %d\" % i, 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":"dbba51ea489467afe08aff7f8eac5d049c6c38a4e53b2065cde7ec36c245a8d1","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport itertools\nN = 1\nobservations = []\ndef solve(x):\n    hand, starter, crib = x\n    order = 'A23456789TJQK'\n    cards = hand + [starter]\n    def val(c):\n        return min(order.index(c[0]) + 1, 10)\n    score = 0\n    for k in range(2, 6):\n        for combo in itertools.combinations(cards, k):\n            if sum(val(c) for c in combo) == 15:\n                score += 2\n    for a, b in itertools.combinations(cards, 2):\n        if a[0] == b[0]:\n            score += 2\n    ranks = sorted(order.index(c[0]) for c in cards)\n    for size in (5, 4, 3):\n        runs = 0\n        for combo in itertools.combinations(ranks, size):\n            if all(combo[i + 1] == combo[i] + 1 for i in range(size - 1)):\n                runs += 1\n        if runs:\n            score += runs * size\n    suits = [c[1] for c in hand]\n    if len(set(suits)) == 1:\n        if starter[1] == suits[0]:\n            score += 5\n        elif not crib:\n            score += 4\n    for c in hand:\n        if c[0] == 'J' and c[1] == starter[1]:\n            score += 1\n    return score\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[['AC', '9C', '4C', 'TC'], '5S', True], 6], [[['KD', 'AH', '4S', '8D'], 'QH', False], 4], [[['3C', '3S', '4S', '5H'], '2D', False], 12], [[['5H', '9S', '6S', '2S'], 'AH', False], 4], [[['3S', '3H', '5H', 'JH'], 'QS', False], 6], [[['4C', 'QC', 'AC', '6C'], '5D', True], 9], [[['AD', 'AH', '2S', '3H'], 'KC', False], 12], [[['6H', '6D', '7S', '8H'], 'JD', False], 10]], [[[['6S', '8D', 'JD', '9C'], '6D', False], 7], [[['4S', '5D', '9D', 'TC'], 'QH', True], 4], [[['5H', 'KC', '2H', '3S'], '6H', True], 4], [[['9H', '7H', 'QH', 'TH'], 'JH', False], 9], [[['2C', '2S', '3S', '4H'], 'KD', False], 12], [[['4S', '3S', '9S', 'TD'], '7C', False], 0], [[['4C', '4S', '5S', '6H'], '3D', True], 14], [[['KH', '9S', 'JS', 'JD'], 'QC', False], 8]], [[[['3H', 'QS', '3C', '6S'], '8D', False], 2], [[['JH', '9H', '9S', 'TD'], '3H', False], 9], [[['6C', '2C', '7C', 'AC'], '4H', True], 2], [[['4D', 'AS', '7H', 'QD'], '9S', False], 2], [[['6S', '5S', 'QS', '8C'], 'AC', False], 4], [[['8S', 'QS', 'TH', '9C'], 'QC', False], 5], [[['QS', 'KC', 'JC', '6H'], 'TH', False], 4], [[['AC', 'AH', '2S', '3H'], 'AD', False], 15]], [[[['AD', 'AH', '2S', '3H'], 'KC', False], 12], [[['AS', '9S', 'TS', '2S'], '4C', False], 8], [[['TD', 'KS', 'TH', 'TS'], 'JC', False], 6], [[['KS', '5D', '3H', '8D'], 'KD', True], 6], [[['2S', '8S', 'TC', 'JS'], 'QH', False], 3], [[['9H', '7S', 'QH', '5H'], '3D', False], 4], [[['KH', '3C', '5H', '5C'], '8S', False], 6], [[['3H', '4D', '6D', 'AS'], '5S', False], 8]], [[[['8D', '8C', '9S', 'TH'], 'AH', True], 8], [[['2H', '5H', 'AC', '3S'], '8C', False], 5], [[['AD', '4S', '9D', '4H'], 'TH', False], 6], [[['9S', '9C', 'JH', 'KS'], '3H', False], 3], [[['KD', 'TC', 'QS', '4D'], 'TH', True], 2], [[['QD', '8S', 'JC', '5H'], '6C', False], 5], [[['6H', '6D', '7S', '8H'], 'JD', False], 10], [[['5S', 'TD', 'JC', 'QH'], 'KS', False], 12]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"hand score case %d\" % i, 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"},"fixed":{"sha256":"1c6977447567fff117e9fadeb944b6c6903194b80f6858d88216000e1f79b069","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\nimport itertools\nN = 1\nobservations = []\ndef solve(x):\n    hand, starter, crib = x\n    order = 'A23456789TJQK'\n    cards = hand + [starter]\n    def val(c):\n        return min(order.index(c[0]) + 1, 10)\n    score = 0\n    for k in range(2, 6):\n        for combo in itertools.combinations(cards, k):\n            if sum(val(c) for c in combo) == 15:\n                score += 2\n    for a, b in itertools.combinations(cards, 2):\n        if a[0] == b[0]:\n            score += 2\n    ranks = sorted(order.index(c[0]) for c in cards)\n    for size in (5, 4, 3):\n        runs = 0\n        for combo in itertools.combinations(ranks, size):\n            if all(combo[i + 1] == combo[i] + 1 for i in range(size - 1)):\n                runs += 1\n        if runs:\n            score += runs * size\n            break\n    suits = [c[1] for c in hand]\n    if len(set(suits)) == 1:\n        if starter[1] == suits[0]:\n            score += 5\n        elif not crib:\n            score += 4\n    for c in hand:\n        if c[0] == 'J' and c[1] == starter[1]:\n            score += 1\n    return score\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[['AC', '9C', '4C', 'TC'], '5S', True], 6], [[['KD', 'AH', '4S', '8D'], 'QH', False], 4], [[['3C', '3S', '4S', '5H'], '2D', False], 12], [[['5H', '9S', '6S', '2S'], 'AH', False], 4], [[['3S', '3H', '5H', 'JH'], 'QS', False], 6], [[['4C', 'QC', 'AC', '6C'], '5D', True], 9], [[['AD', 'AH', '2S', '3H'], 'KC', False], 12], [[['6H', '6D', '7S', '8H'], 'JD', False], 10]], [[[['6S', '8D', 'JD', '9C'], '6D', False], 7], [[['4S', '5D', '9D', 'TC'], 'QH', True], 4], [[['5H', 'KC', '2H', '3S'], '6H', True], 4], [[['9H', '7H', 'QH', 'TH'], 'JH', False], 9], [[['2C', '2S', '3S', '4H'], 'KD', False], 12], [[['4S', '3S', '9S', 'TD'], '7C', False], 0], [[['4C', '4S', '5S', '6H'], '3D', True], 14], [[['KH', '9S', 'JS', 'JD'], 'QC', False], 8]], [[[['3H', 'QS', '3C', '6S'], '8D', False], 2], [[['JH', '9H', '9S', 'TD'], '3H', False], 9], [[['6C', '2C', '7C', 'AC'], '4H', True], 2], [[['4D', 'AS', '7H', 'QD'], '9S', False], 2], [[['6S', '5S', 'QS', '8C'], 'AC', False], 4], [[['8S', 'QS', 'TH', '9C'], 'QC', False], 5], [[['QS', 'KC', 'JC', '6H'], 'TH', False], 4], [[['AC', 'AH', '2S', '3H'], 'AD', False], 15]], [[[['AD', 'AH', '2S', '3H'], 'KC', False], 12], [[['AS', '9S', 'TS', '2S'], '4C', False], 8], [[['TD', 'KS', 'TH', 'TS'], 'JC', False], 6], [[['KS', '5D', '3H', '8D'], 'KD', True], 6], [[['2S', '8S', 'TC', 'JS'], 'QH', False], 3], [[['9H', '7S', 'QH', '5H'], '3D', False], 4], [[['KH', '3C', '5H', '5C'], '8S', False], 6], [[['3H', '4D', '6D', 'AS'], '5S', False], 8]], [[[['8D', '8C', '9S', 'TH'], 'AH', True], 8], [[['2H', '5H', 'AC', '3S'], '8C', False], 5], [[['AD', '4S', '9D', '4H'], 'TH', False], 6], [[['9S', '9C', 'JH', 'KS'], '3H', False], 3], [[['KD', 'TC', 'QS', '4D'], 'TH', True], 2], [[['QD', '8S', 'JC', '5H'], '6C', False], 5], [[['6H', '6D', '7S', '8H'], 'JD', False], 10], [[['5S', 'TD', 'JC', 'QH'], 'KS', False], 12]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"hand score case %d\" % i, 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 bounded toy rule contract stated explicitly in the contract field; cards are two-character codes (rank, suit). Not a complete implementation of any published rulebook or casino table rules. 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-card-game-rule-engines-cribbage-hand-run-length-precedence","generated_at":"2026-09-29T14:50:22.593537+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Card-game engines, scoring apps and online tables apply this rule automatically on every hand.","repair":"Score only the longest run length found.","root_cause":"The run loop does not stop after the longest run length.","sha256":"df3976e49cd628056d6d68e08c161606ef85727602c922d6e4e9a180129d241d","title":"Sub-runs inside a longer run are also scored · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":40.161,"exit_code":1,"observations":[{"actual":6,"check":"hand score case 0","expected":6,"passed":true},{"actual":4,"check":"hand score case 1","expected":4,"passed":true},{"actual":8,"check":"hand score case 2","expected":12,"passed":false},{"actual":4,"check":"hand score case 3","expected":4,"passed":true},{"actual":6,"check":"hand score case 4","expected":6,"passed":true},{"actual":9,"check":"hand score case 5","expected":9,"passed":true},{"actual":9,"check":"hand score case 6","expected":12,"passed":false},{"actual":7,"check":"hand score case 7","expected":10,"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"hand score case 0\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"hand score case 1\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"hand score case 2\", \"actual\": 8, \"expected\": 12, \"passed\": false}, {\"check\": \"hand score case 3\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"hand score case 4\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"hand score case 5\", \"actual\": 9, \"expected\": 9, \"passed\": true}, {\"check\": \"hand score case 6\", \"actual\": 9, \"expected\": 12, \"passed\": false}, {\"check\": \"hand score case 7\", \"actual\": 7, \"expected\": 10, \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":42.553,"exit_code":1,"observations":[{"actual":6,"check":"hand score case 0","expected":6,"passed":true},{"actual":4,"check":"hand score case 1","expected":4,"passed":true},{"actual":24,"check":"hand score case 2","expected":12,"passed":false},{"actual":4,"check":"hand score case 3","expected":4,"passed":true},{"actual":6,"check":"hand score case 4","expected":6,"passed":true},{"actual":9,"check":"hand score case 5","expected":9,"passed":true},{"actual":12,"check":"hand score case 6","expected":12,"passed":true},{"actual":10,"check":"hand score case 7","expected":10,"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"hand score case 0\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"hand score case 1\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"hand score case 2\", \"actual\": 24, \"expected\": 12, \"passed\": false}, {\"check\": \"hand score case 3\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"hand score case 4\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"hand score case 5\", \"actual\": 9, \"expected\": 9, \"passed\": true}, {\"check\": \"hand score case 6\", \"actual\": 12, \"expected\": 12, \"passed\": true}, {\"check\": \"hand score case 7\", \"actual\": 10, \"expected\": 10, \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":39.775,"exit_code":0,"observations":[{"actual":6,"check":"hand score case 0","expected":6,"passed":true},{"actual":4,"check":"hand score case 1","expected":4,"passed":true},{"actual":12,"check":"hand score case 2","expected":12,"passed":true},{"actual":4,"check":"hand score case 3","expected":4,"passed":true},{"actual":6,"check":"hand score case 4","expected":6,"passed":true},{"actual":9,"check":"hand score case 5","expected":9,"passed":true},{"actual":12,"check":"hand score case 6","expected":12,"passed":true},{"actual":10,"check":"hand score case 7","expected":10,"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"hand score case 0\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"hand score case 1\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"hand score case 2\", \"actual\": 12, \"expected\": 12, \"passed\": true}, {\"check\": \"hand score case 3\", \"actual\": 4, \"expected\": 4, \"passed\": true}, {\"check\": \"hand score case 4\", \"actual\": 6, \"expected\": 6, \"passed\": true}, {\"check\": \"hand score case 5\", \"actual\": 9, \"expected\": 9, \"passed\": true}, {\"check\": \"hand score case 6\", \"actual\": 12, \"expected\": 12, \"passed\": true}, {\"check\": \"hand score case 7\", \"actual\": 10, \"expected\": 10, \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}