{"abstract":"A defender matching the knocker deadwood loses instead of undercutting.","category":"Card game rule engines","checks":8,"contract":"Input [knocker_deadwood_cards, defender_deadwood_after_layoffs, gin, big_gin]. Deadwood: A=1, T/J/Q/K=10, others pip. Knocking above 10 is [\"illegal\", 0]. Big gin scores 31 + defender deadwood, gin 25 + defender deadwood (gin cannot be undercut). Otherwise if defender deadwood <= knocker deadwood the defender undercuts for 25 + difference; else knocker scores the difference.","evaluation_group":"w2-card-game-rule-engines-gin-knock","failed_approach":"Awarding a flat 25 drops the deadwood difference from the undercut.","family":"w2-card-game-rule-engines-gin-knock-undercut-tie","id":"FA-83476","implementations":{"attempt":{"sha256":"300e903f9537784e596a66c28f2adfaa91c01e01bc2111860824a1ca64cc2051","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    kc, dc, gin, big = x\n    def dw(cards):\n        t = 0\n        for c in cards:\n            r = c[0]\n            t += 1 if r == 'A' else 10 if r in 'TJQK' else int(r)\n        return t\n    k = dw(kc)\n    d = dw(dc)\n    if k > 10:\n        return ['illegal', 0]\n    if big:\n        return ['knocker', 31 + d]\n    if gin:\n        return ['knocker', 25 + d]\n    if d <= k:\n        return ['defender', 25]\n    return ['knocker', d - k]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[[], [], False, False], ['defender', 25]], [[[], ['KS', '5S', '4H'], False, False], ['knocker', 19]], [[['KD', 'JH', '9S'], ['JS', '7D'], False, False], ['illegal', 0]], [[['4S', '4D', 'AS'], ['3D', 'JS', 'KD', '7D'], False, False], ['knocker', 21]], [[['TS', 'JC', '5S'], ['4H', '7C'], False, False], ['illegal', 0]], [[[], ['KS', 'TD', '5D', '7D'], False, False], ['knocker', 32]], [[[], ['7H', '5D'], False, False], ['knocker', 12]], [[['KS'], [], False, False], ['defender', 35]]], [[[['6S', '8S', '6C'], ['4C', 'KH', '9S'], False, False], ['illegal', 0]], [[[], [], True, False], ['knocker', 25]], [[['6C'], [], False, False], ['defender', 31]], [[[], ['4D', 'JS'], True, False], ['knocker', 39]], [[['4S'], ['JH', '9H', '8C'], False, False], ['knocker', 23]], [[[], ['KH', '3D'], False, False], ['knocker', 13]], [[[], [], False, False], ['defender', 25]], [[['2H'], [], False, False], ['defender', 27]]], [[[['KH', '4H', 'JD'], [], False, False], ['illegal', 0]], [[[], ['8S', 'QD'], True, False], ['knocker', 43]], [[['7D', '7S'], ['2S', 'QC'], False, False], ['illegal', 0]], [[['2C'], ['2D', 'AH', 'JD', '5S'], False, False], ['knocker', 16]], [[[], ['3C', '3H', '5S'], True, False], ['knocker', 36]], [[['AC', '9D', 'AD'], ['8S'], False, False], ['illegal', 0]], [[['JC'], ['AC', 'AH'], False, False], ['defender', 33]], [[[], [], False, False], ['defender', 25]]], [[[[], ['JS', '8H', '7C'], False, False], ['knocker', 25]], [[[], ['2C'], False, False], ['knocker', 2]], [[[], ['KD'], False, False], ['knocker', 10]], [[[], [], True, False], ['knocker', 25]], [[['TH', '3H', 'KC'], ['TD', 'AS', 'JD', '5H'], False, False], ['illegal', 0]], [[['TH', '8S'], ['QC', '5S', '2S', '6D'], False, False], ['illegal', 0]], [[['QD'], [], False, False], ['defender', 35]], [[['3S'], ['2C', 'AD'], False, False], ['defender', 25]]], [[[[], [], False, False], ['defender', 25]], [[['TH', '6C'], ['6D', 'QC'], False, False], ['illegal', 0]], [[['9C'], ['8S', 'JD'], False, False], ['knocker', 9]], [[['5H', '6D'], ['QH', '8D', 'KH'], False, False], ['illegal', 0]], [[['QC', 'JD'], ['7C', 'KH', '8C', '5S'], False, False], ['illegal', 0]], [[[], ['4D', '3S'], False, False], ['knocker', 7]], [[['8D', 'AH'], [], False, False], ['defender', 34]], [[['6D', '6H'], ['6C', 'QD', '9S', '5C'], False, False], ['illegal', 0]]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"knock 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":"36a36130ece0a84b7863722dede6702af521e8e482f9b2d220925a567d1dda84","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    kc, dc, gin, big = x\n    def dw(cards):\n        t = 0\n        for c in cards:\n            r = c[0]\n            t += 1 if r == 'A' else 10 if r in 'TJQK' else int(r)\n        return t\n    k = dw(kc)\n    d = dw(dc)\n    if k > 10:\n        return ['illegal', 0]\n    if big:\n        return ['knocker', 31 + d]\n    if gin:\n        return ['knocker', 25 + d]\n    if d < k:\n        return ['defender', 25 + k - d]\n    return ['knocker', d - k]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[[], [], False, False], ['defender', 25]], [[[], ['KS', '5S', '4H'], False, False], ['knocker', 19]], [[['KD', 'JH', '9S'], ['JS', '7D'], False, False], ['illegal', 0]], [[['4S', '4D', 'AS'], ['3D', 'JS', 'KD', '7D'], False, False], ['knocker', 21]], [[['TS', 'JC', '5S'], ['4H', '7C'], False, False], ['illegal', 0]], [[[], ['KS', 'TD', '5D', '7D'], False, False], ['knocker', 32]], [[[], ['7H', '5D'], False, False], ['knocker', 12]], [[['KS'], [], False, False], ['defender', 35]]], [[[['6S', '8S', '6C'], ['4C', 'KH', '9S'], False, False], ['illegal', 0]], [[[], [], True, False], ['knocker', 25]], [[['6C'], [], False, False], ['defender', 31]], [[[], ['4D', 'JS'], True, False], ['knocker', 39]], [[['4S'], ['JH', '9H', '8C'], False, False], ['knocker', 23]], [[[], ['KH', '3D'], False, False], ['knocker', 13]], [[[], [], False, False], ['defender', 25]], [[['2H'], [], False, False], ['defender', 27]]], [[[['KH', '4H', 'JD'], [], False, False], ['illegal', 0]], [[[], ['8S', 'QD'], True, False], ['knocker', 43]], [[['7D', '7S'], ['2S', 'QC'], False, False], ['illegal', 0]], [[['2C'], ['2D', 'AH', 'JD', '5S'], False, False], ['knocker', 16]], [[[], ['3C', '3H', '5S'], True, False], ['knocker', 36]], [[['AC', '9D', 'AD'], ['8S'], False, False], ['illegal', 0]], [[['JC'], ['AC', 'AH'], False, False], ['defender', 33]], [[[], [], False, False], ['defender', 25]]], [[[[], ['JS', '8H', '7C'], False, False], ['knocker', 25]], [[[], ['2C'], False, False], ['knocker', 2]], [[[], ['KD'], False, False], ['knocker', 10]], [[[], [], True, False], ['knocker', 25]], [[['TH', '3H', 'KC'], ['TD', 'AS', 'JD', '5H'], False, False], ['illegal', 0]], [[['TH', '8S'], ['QC', '5S', '2S', '6D'], False, False], ['illegal', 0]], [[['QD'], [], False, False], ['defender', 35]], [[['3S'], ['2C', 'AD'], False, False], ['defender', 25]]], [[[[], [], False, False], ['defender', 25]], [[['TH', '6C'], ['6D', 'QC'], False, False], ['illegal', 0]], [[['9C'], ['8S', 'JD'], False, False], ['knocker', 9]], [[['5H', '6D'], ['QH', '8D', 'KH'], False, False], ['illegal', 0]], [[['QC', 'JD'], ['7C', 'KH', '8C', '5S'], False, False], ['illegal', 0]], [[[], ['4D', '3S'], False, False], ['knocker', 7]], [[['8D', 'AH'], [], False, False], ['defender', 34]], [[['6D', '6H'], ['6C', 'QD', '9S', '5C'], False, False], ['illegal', 0]]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"knock 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":"75d452b84ba53e4b34aef33df260deeeb334e1e96d17b23faea5bfb1ab5445f0","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    kc, dc, gin, big = x\n    def dw(cards):\n        t = 0\n        for c in cards:\n            r = c[0]\n            t += 1 if r == 'A' else 10 if r in 'TJQK' else int(r)\n        return t\n    k = dw(kc)\n    d = dw(dc)\n    if k > 10:\n        return ['illegal', 0]\n    if big:\n        return ['knocker', 31 + d]\n    if gin:\n        return ['knocker', 25 + d]\n    if d <= k:\n        return ['defender', 25 + k - d]\n    return ['knocker', d - k]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[[], [], False, False], ['defender', 25]], [[[], ['KS', '5S', '4H'], False, False], ['knocker', 19]], [[['KD', 'JH', '9S'], ['JS', '7D'], False, False], ['illegal', 0]], [[['4S', '4D', 'AS'], ['3D', 'JS', 'KD', '7D'], False, False], ['knocker', 21]], [[['TS', 'JC', '5S'], ['4H', '7C'], False, False], ['illegal', 0]], [[[], ['KS', 'TD', '5D', '7D'], False, False], ['knocker', 32]], [[[], ['7H', '5D'], False, False], ['knocker', 12]], [[['KS'], [], False, False], ['defender', 35]]], [[[['6S', '8S', '6C'], ['4C', 'KH', '9S'], False, False], ['illegal', 0]], [[[], [], True, False], ['knocker', 25]], [[['6C'], [], False, False], ['defender', 31]], [[[], ['4D', 'JS'], True, False], ['knocker', 39]], [[['4S'], ['JH', '9H', '8C'], False, False], ['knocker', 23]], [[[], ['KH', '3D'], False, False], ['knocker', 13]], [[[], [], False, False], ['defender', 25]], [[['2H'], [], False, False], ['defender', 27]]], [[[['KH', '4H', 'JD'], [], False, False], ['illegal', 0]], [[[], ['8S', 'QD'], True, False], ['knocker', 43]], [[['7D', '7S'], ['2S', 'QC'], False, False], ['illegal', 0]], [[['2C'], ['2D', 'AH', 'JD', '5S'], False, False], ['knocker', 16]], [[[], ['3C', '3H', '5S'], True, False], ['knocker', 36]], [[['AC', '9D', 'AD'], ['8S'], False, False], ['illegal', 0]], [[['JC'], ['AC', 'AH'], False, False], ['defender', 33]], [[[], [], False, False], ['defender', 25]]], [[[[], ['JS', '8H', '7C'], False, False], ['knocker', 25]], [[[], ['2C'], False, False], ['knocker', 2]], [[[], ['KD'], False, False], ['knocker', 10]], [[[], [], True, False], ['knocker', 25]], [[['TH', '3H', 'KC'], ['TD', 'AS', 'JD', '5H'], False, False], ['illegal', 0]], [[['TH', '8S'], ['QC', '5S', '2S', '6D'], False, False], ['illegal', 0]], [[['QD'], [], False, False], ['defender', 35]], [[['3S'], ['2C', 'AD'], False, False], ['defender', 25]]], [[[[], [], False, False], ['defender', 25]], [[['TH', '6C'], ['6D', 'QC'], False, False], ['illegal', 0]], [[['9C'], ['8S', 'JD'], False, False], ['knocker', 9]], [[['5H', '6D'], ['QH', '8D', 'KH'], False, False], ['illegal', 0]], [[['QC', 'JD'], ['7C', 'KH', '8C', '5S'], False, False], ['illegal', 0]], [[[], ['4D', '3S'], False, False], ['knocker', 7]], [[['8D', 'AH'], [], False, False], ['defender', 34]], [[['6D', '6H'], ['6C', 'QD', '9S', '5C'], False, False], ['illegal', 0]]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"knock 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-gin-knock-undercut-tie","generated_at":"2026-09-29T14:50:21.952294+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":"Defender deadwood <= knocker deadwood is an undercut.","root_cause":"The undercut test uses strict less-than.","sha256":"d27e96a9a98058bc55dee10ac9a3bfb616c8967758bca63429b1c86f59875daf","title":"Equal deadwood is not an undercut · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.325,"exit_code":1,"observations":[{"actual":["defender",25],"check":"knock score case 0","expected":["defender",25],"passed":true},{"actual":["knocker",19],"check":"knock score case 1","expected":["knocker",19],"passed":true},{"actual":["illegal",0],"check":"knock score case 2","expected":["illegal",0],"passed":true},{"actual":["knocker",21],"check":"knock score case 3","expected":["knocker",21],"passed":true},{"actual":["illegal",0],"check":"knock score case 4","expected":["illegal",0],"passed":true},{"actual":["knocker",32],"check":"knock score case 5","expected":["knocker",32],"passed":true},{"actual":["knocker",12],"check":"knock score case 6","expected":["knocker",12],"passed":true},{"actual":["defender",25],"check":"knock score case 7","expected":["defender",35],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"knock score case 0\", \"actual\": [\"defender\", 25], \"expected\": [\"defender\", 25], \"passed\": true}, {\"check\": \"knock score case 1\", \"actual\": [\"knocker\", 19], \"expected\": [\"knocker\", 19], \"passed\": true}, {\"check\": \"knock score case 2\", \"actual\": [\"illegal\", 0], \"expected\": [\"illegal\", 0], \"passed\": true}, {\"check\": \"knock score case 3\", \"actual\": [\"knocker\", 21], \"expected\": [\"knocker\", 21], \"passed\": true}, {\"check\": \"knock score case 4\", \"actual\": [\"illegal\", 0], \"expected\": [\"illegal\", 0], \"passed\": true}, {\"check\": \"knock score case 5\", \"actual\": [\"knocker\", 32], \"expected\": [\"knocker\", 32], \"passed\": true}, {\"check\": \"knock score case 6\", \"actual\": [\"knocker\", 12], \"expected\": [\"knocker\", 12], \"passed\": true}, {\"check\": \"knock score case 7\", \"actual\": [\"defender\", 25], \"expected\": [\"defender\", 35], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.475,"exit_code":1,"observations":[{"actual":["knocker",0],"check":"knock score case 0","expected":["defender",25],"passed":false},{"actual":["knocker",19],"check":"knock score case 1","expected":["knocker",19],"passed":true},{"actual":["illegal",0],"check":"knock score case 2","expected":["illegal",0],"passed":true},{"actual":["knocker",21],"check":"knock score case 3","expected":["knocker",21],"passed":true},{"actual":["illegal",0],"check":"knock score case 4","expected":["illegal",0],"passed":true},{"actual":["knocker",32],"check":"knock score case 5","expected":["knocker",32],"passed":true},{"actual":["knocker",12],"check":"knock score case 6","expected":["knocker",12],"passed":true},{"actual":["defender",35],"check":"knock score case 7","expected":["defender",35],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"knock score case 0\", \"actual\": [\"knocker\", 0], \"expected\": [\"defender\", 25], \"passed\": false}, {\"check\": \"knock score case 1\", \"actual\": [\"knocker\", 19], \"expected\": [\"knocker\", 19], \"passed\": true}, {\"check\": \"knock score case 2\", \"actual\": [\"illegal\", 0], \"expected\": [\"illegal\", 0], \"passed\": true}, {\"check\": \"knock score case 3\", \"actual\": [\"knocker\", 21], \"expected\": [\"knocker\", 21], \"passed\": true}, {\"check\": \"knock score case 4\", \"actual\": [\"illegal\", 0], \"expected\": [\"illegal\", 0], \"passed\": true}, {\"check\": \"knock score case 5\", \"actual\": [\"knocker\", 32], \"expected\": [\"knocker\", 32], \"passed\": true}, {\"check\": \"knock score case 6\", \"actual\": [\"knocker\", 12], \"expected\": [\"knocker\", 12], \"passed\": true}, {\"check\": \"knock score case 7\", \"actual\": [\"defender\", 35], \"expected\": [\"defender\", 35], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.676,"exit_code":0,"observations":[{"actual":["defender",25],"check":"knock score case 0","expected":["defender",25],"passed":true},{"actual":["knocker",19],"check":"knock score case 1","expected":["knocker",19],"passed":true},{"actual":["illegal",0],"check":"knock score case 2","expected":["illegal",0],"passed":true},{"actual":["knocker",21],"check":"knock score case 3","expected":["knocker",21],"passed":true},{"actual":["illegal",0],"check":"knock score case 4","expected":["illegal",0],"passed":true},{"actual":["knocker",32],"check":"knock score case 5","expected":["knocker",32],"passed":true},{"actual":["knocker",12],"check":"knock score case 6","expected":["knocker",12],"passed":true},{"actual":["defender",35],"check":"knock score case 7","expected":["defender",35],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"knock score case 0\", \"actual\": [\"defender\", 25], \"expected\": [\"defender\", 25], \"passed\": true}, {\"check\": \"knock score case 1\", \"actual\": [\"knocker\", 19], \"expected\": [\"knocker\", 19], \"passed\": true}, {\"check\": \"knock score case 2\", \"actual\": [\"illegal\", 0], \"expected\": [\"illegal\", 0], \"passed\": true}, {\"check\": \"knock score case 3\", \"actual\": [\"knocker\", 21], \"expected\": [\"knocker\", 21], \"passed\": true}, {\"check\": \"knock score case 4\", \"actual\": [\"illegal\", 0], \"expected\": [\"illegal\", 0], \"passed\": true}, {\"check\": \"knock score case 5\", \"actual\": [\"knocker\", 32], \"expected\": [\"knocker\", 32], \"passed\": true}, {\"check\": \"knock score case 6\", \"actual\": [\"knocker\", 12], \"expected\": [\"knocker\", 12], \"passed\": true}, {\"check\": \"knock score case 7\", \"actual\": [\"defender\", 35], \"expected\": [\"defender\", 35], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}