{"abstract":"After a quiet white knight move, a black rook standing on its own king's file is reported as a discovered check.","category":"Chess move legality","checks":8,"contract":"Input: {\"board\", \"move\": [from, to] or [from, to, promotion letter]}. Apply the move (promotion letter becomes a piece of the mover's colour) and classify the check it gives to the enemy king: \"direct\" (the moved piece attacks it), \"discovered\" (another of the mover's pieces now attacks it), \"double\" (both) or \"none\". Pawns attack diagonally forward, sliders need a clear path.","contract_signature":"x","evaluation_group":"w2-chess_move_legality-move-check-classifier","failed_approach":"Filtering for white pieces works only when white moves.","family":"w2-chess_move_legality-move-check-classifier-discovering-piece-colour","id":"FA-82811","implementations":{"attempt":{"sha256":"a34b26110396eb7ffc8d4eaeb7f07b45ac12207c8eef435634422e8e4e8b386a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    b=dict(x['board']); fr,to=x['move'][:2]; p=b.pop(fr)\n    if len(x['move'])>2: p=x['move'][2].upper() if p.isupper() else x['move'][2].lower()\n    b[to]=p\n    white=p.isupper()\n    ks=[s for s,v in b.items() if v==('k' if white else 'K')][0]\n    def hits(src, tgt):\n        v=b[src]; t=v.upper()\n        f,r=ord(src[0])-97,int(src[1])-1\n        tf,tr=ord(tgt[0])-97,int(tgt[1])-1\n        df,dr=tf-f,tr-r\n        if t=='P': return abs(df)==1 and dr==(1 if v.isupper() else -1)\n        if t=='N': return (abs(df),abs(dr)) in ((1,2),(2,1))\n        if t=='K': return max(abs(df),abs(dr))==1\n        orth=(df==0)!=(dr==0); diag=abs(df)==abs(dr) and df!=0\n        if not ((t in ('R','Q') and orth) or (t in ('B','Q') and diag)): return False\n        sf=(df>0)-(df<0); sr=(dr>0)-(dr<0)\n        cf,cr=f+sf,r+sr\n        while (cf,cr)!=(tf,tr):\n            if chr(97+cf)+str(cr+1) in b: return False\n            cf+=sf; cr+=sr\n        return True\n    direct=hits(to,ks)\n    disc=any(hits(s,ks) for s,v in b.items() if s!=to and v.isupper() and v.upper()!='K')\n    if direct and disc: return 'double'\n    if direct: return 'direct'\n    if disc: return 'discovered'\n    return 'none'\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},\n   'direct'),\n  ('knight promotion check',\n   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),\n  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),\n  ('discovered by bishop',\n   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),\n  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},\n   'double'),\n  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},\n   'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],\n [('discovered by bishop',\n   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),\n  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},\n   'double'),\n  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},\n   'direct'),\n  ('rook lands on king diagonal',\n   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),\n  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),\n  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},\n   'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],\n [('rook lands on king diagonal',\n   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),\n  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),\n  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},\n   'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),\n  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),\n  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),\n  ('white piece near own line',\n   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},\n   'discovered')],\n [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},\n   'direct'),\n  ('knight promotion check',\n   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),\n  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),\n  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),\n  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),\n  ('white piece near own line',\n   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},\n   'discovered')],\n [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},\n   'direct'),\n  ('knight promotion check',\n   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),\n  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),\n  ('discovered by bishop',\n   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),\n  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},\n   'double'),\n  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},\n   'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')]]\nfor label, args, expected in fixtures[N-1]:\n    try:\n        actual = solve(args)\n    except Exception as exc:\n        actual = 'error:' + type(exc).__name__\n    check(label, actual, 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":"73e77117e57f64a3c1118178592038d47ee43f5692ecabcb8bb7836d559adee9","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    b=dict(x['board']); fr,to=x['move'][:2]; p=b.pop(fr)\n    if len(x['move'])>2: p=x['move'][2].upper() if p.isupper() else x['move'][2].lower()\n    b[to]=p\n    white=p.isupper()\n    ks=[s for s,v in b.items() if v==('k' if white else 'K')][0]\n    def hits(src, tgt):\n        v=b[src]; t=v.upper()\n        f,r=ord(src[0])-97,int(src[1])-1\n        tf,tr=ord(tgt[0])-97,int(tgt[1])-1\n        df,dr=tf-f,tr-r\n        if t=='P': return abs(df)==1 and dr==(1 if v.isupper() else -1)\n        if t=='N': return (abs(df),abs(dr)) in ((1,2),(2,1))\n        if t=='K': return max(abs(df),abs(dr))==1\n        orth=(df==0)!=(dr==0); diag=abs(df)==abs(dr) and df!=0\n        if not ((t in ('R','Q') and orth) or (t in ('B','Q') and diag)): return False\n        sf=(df>0)-(df<0); sr=(dr>0)-(dr<0)\n        cf,cr=f+sf,r+sr\n        while (cf,cr)!=(tf,tr):\n            if chr(97+cf)+str(cr+1) in b: return False\n            cf+=sf; cr+=sr\n        return True\n    direct=hits(to,ks)\n    disc=any(hits(s,ks) for s,v in b.items() if s!=to and v.upper()!='K')\n    if direct and disc: return 'double'\n    if direct: return 'direct'\n    if disc: return 'discovered'\n    return 'none'\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},\n   'direct'),\n  ('knight promotion check',\n   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),\n  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),\n  ('discovered by bishop',\n   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),\n  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},\n   'double'),\n  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},\n   'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],\n [('discovered by bishop',\n   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),\n  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},\n   'double'),\n  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},\n   'direct'),\n  ('rook lands on king diagonal',\n   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),\n  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),\n  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},\n   'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],\n [('rook lands on king diagonal',\n   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),\n  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),\n  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},\n   'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),\n  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),\n  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),\n  ('white piece near own line',\n   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},\n   'discovered')],\n [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},\n   'direct'),\n  ('knight promotion check',\n   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),\n  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),\n  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),\n  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),\n  ('white piece near own line',\n   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},\n   'discovered')],\n [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},\n   'direct'),\n  ('knight promotion check',\n   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),\n  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),\n  ('discovered by bishop',\n   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),\n  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},\n   'double'),\n  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},\n   'direct'),\n  ('defender rook on own king line',\n   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),\n  ('black discovered',\n   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')]]\nfor label, args, expected in fixtures[N-1]:\n    try:\n        actual = solve(args)\n    except Exception as exc:\n        actual = 'error:' + type(exc).__name__\n    check(label, actual, 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 model with an explicitly stated contract; boards are {square: piece} with white upper-case and black lower-case pieces; no claim of full FIDE Laws conformance. 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-chess_move_legality-move-check-classifier-discovering-piece-colour","generated_at":"2026-09-29T14:50:15.509354+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"SAN \"+\" suffixes and double-check rules both depend on this classification.","root_cause":"The discovered scan does not filter attackers by the mover's colour.","sha256":"58f3e044ad557fc86a591328857fbe3da117a63a905a90efd1a5247a265508fd","title":"Enemy piece on its own king's line counted as discovered check · 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":40.409,"exit_code":1,"observations":[{"actual":"direct","check":"promotion gives check","expected":"direct","passed":true},{"actual":"direct","check":"knight promotion check","expected":"direct","passed":true},{"actual":"direct","check":"simple direct","expected":"direct","passed":true},{"actual":"discovered","check":"discovered by bishop","expected":"discovered","passed":true},{"actual":"double","check":"double check","expected":"double","passed":true},{"actual":"direct","check":"queen diagonal direct","expected":"direct","passed":true},{"actual":"none","check":"defender rook on own king line","expected":"none","passed":true},{"actual":"none","check":"black discovered","expected":"discovered","passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"promotion gives check\", \"actual\": \"direct\", \"expected\": \"direct\", \"passed\": true}, {\"check\": \"knight promotion check\", \"actual\": \"direct\", \"expected\": \"direct\", \"passed\": true}, {\"check\": \"simple direct\", \"actual\": \"direct\", \"expected\": \"direct\", \"passed\": true}, {\"check\": \"discovered by bishop\", \"actual\": \"discovered\", \"expected\": \"discovered\", \"passed\": true}, {\"check\": \"double check\", \"actual\": \"double\", \"expected\": \"double\", \"passed\": true}, {\"check\": \"queen diagonal direct\", \"actual\": \"direct\", \"expected\": \"direct\", \"passed\": true}, {\"check\": \"defender rook on own king line\", \"actual\": \"none\", \"expected\": \"none\", \"passed\": true}, {\"check\": \"black discovered\", \"actual\": \"none\", \"expected\": \"discovered\", \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.932,"exit_code":1,"observations":[{"actual":"direct","check":"promotion gives check","expected":"direct","passed":true},{"actual":"direct","check":"knight promotion check","expected":"direct","passed":true},{"actual":"direct","check":"simple direct","expected":"direct","passed":true},{"actual":"discovered","check":"discovered by bishop","expected":"discovered","passed":true},{"actual":"double","check":"double check","expected":"double","passed":true},{"actual":"direct","check":"queen diagonal direct","expected":"direct","passed":true},{"actual":"discovered","check":"defender rook on own king line","expected":"none","passed":false},{"actual":"discovered","check":"black discovered","expected":"discovered","passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"promotion gives check\", \"actual\": \"direct\", \"expected\": \"direct\", \"passed\": true}, {\"check\": \"knight promotion check\", \"actual\": \"direct\", \"expected\": \"direct\", \"passed\": true}, {\"check\": \"simple direct\", \"actual\": \"direct\", \"expected\": \"direct\", \"passed\": true}, {\"check\": \"discovered by bishop\", \"actual\": \"discovered\", \"expected\": \"discovered\", \"passed\": true}, {\"check\": \"double check\", \"actual\": \"double\", \"expected\": \"double\", \"passed\": true}, {\"check\": \"queen diagonal direct\", \"actual\": \"direct\", \"expected\": \"direct\", \"passed\": true}, {\"check\": \"defender rook on own king line\", \"actual\": \"discovered\", \"expected\": \"none\", \"passed\": false}, {\"check\": \"black discovered\", \"actual\": \"discovered\", \"expected\": \"discovered\", \"passed\": true}], \"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."}}