FAILURE MAP
← Case archive

FA-82796 / Chess move legality / Open access

Promotion check evaluated as a pawn · case 01

b7-b8=Q with the king on e8 is classified "none".

Verified by executionVariant 1 · 8 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The promotion letter is ignored, so the new queen still attacks like a pawn.

VERIFIED REPAIR

Replace the pawn with the promoted piece in the mover's colour before classifying.

Unsuccessful approach: Using the raw lower-case letter turns a white promotion into a black piece and targets the wrong king.

Case 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.

Why this case matters

SAN "+" suffixes and double-check rules both depend on this classification.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    b=dict(x['board']); fr,to=x['move'][:2]; p=b.pop(fr)
    pass
    b[to]=p
    white=p.isupper()
    ks=[s for s,v in b.items() if v==('k' if white else 'K')][0]
    def hits(src, tgt):
        v=b[src]; t=v.upper()
        f,r=ord(src[0])-97,int(src[1])-1
        tf,tr=ord(tgt[0])-97,int(tgt[1])-1
        df,dr=tf-f,tr-r
        if t=='P': return abs(df)==1 and dr==(1 if v.isupper() else -1)
        if t=='N': return (abs(df),abs(dr)) in ((1,2),(2,1))
        if t=='K': return max(abs(df),abs(dr))==1
        orth=(df==0)!=(dr==0); diag=abs(df)==abs(dr) and df!=0
        if not ((t in ('R','Q') and orth) or (t in ('B','Q') and diag)): return False
        sf=(df>0)-(df<0); sr=(dr>0)-(dr<0)
        cf,cr=f+sf,r+sr
        while (cf,cr)!=(tf,tr):
            if chr(97+cf)+str(cr+1) in b: return False
            cf+=sf; cr+=sr
        return True
    direct=hits(to,ks)
    disc=any(hits(s,ks) for s,v in b.items() if s!=to and v.isupper()==white and v.upper()!='K')
    if direct and disc: return 'double'
    if direct: return 'direct'
    if disc: return 'discovered'
    return 'none'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),
  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
   'direct'),
  ('defender rook on own king line',
   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
  ('black discovered',
   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
   'direct'),
  ('defender rook on own king line',
   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
  ('black discovered',
   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),
  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
  ('white piece near own line',
   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
   'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
  ('white piece near own line',
   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
   'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'error:' + type(exc).__name__
    check(label, actual, 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 fixtureActualExpectedOutcome
promotion gives checknonedirectFailed
knight promotion checknonedirectFailed
simple directdirectdirectPassed
discovered by bishopdiscovereddiscoveredPassed
double checkdoubledoublePassed
queen diagonal directdirectdirectPassed
rook lands on king diagonalnonenonePassed
rook quietnonenonePassed

SHA-256 / 30cb71c97610bd5c71f1954224947216675c873a382d90c1b2e8a8d7cf86fe82

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    b=dict(x['board']); fr,to=x['move'][:2]; p=b.pop(fr)
    if len(x['move'])>2: p=x['move'][2]
    b[to]=p
    white=p.isupper()
    ks=[s for s,v in b.items() if v==('k' if white else 'K')][0]
    def hits(src, tgt):
        v=b[src]; t=v.upper()
        f,r=ord(src[0])-97,int(src[1])-1
        tf,tr=ord(tgt[0])-97,int(tgt[1])-1
        df,dr=tf-f,tr-r
        if t=='P': return abs(df)==1 and dr==(1 if v.isupper() else -1)
        if t=='N': return (abs(df),abs(dr)) in ((1,2),(2,1))
        if t=='K': return max(abs(df),abs(dr))==1
        orth=(df==0)!=(dr==0); diag=abs(df)==abs(dr) and df!=0
        if not ((t in ('R','Q') and orth) or (t in ('B','Q') and diag)): return False
        sf=(df>0)-(df<0); sr=(dr>0)-(dr<0)
        cf,cr=f+sf,r+sr
        while (cf,cr)!=(tf,tr):
            if chr(97+cf)+str(cr+1) in b: return False
            cf+=sf; cr+=sr
        return True
    direct=hits(to,ks)
    disc=any(hits(s,ks) for s,v in b.items() if s!=to and v.isupper()==white and v.upper()!='K')
    if direct and disc: return 'double'
    if direct: return 'direct'
    if disc: return 'discovered'
    return 'none'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),
  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
   'direct'),
  ('defender rook on own king line',
   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
  ('black discovered',
   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
   'direct'),
  ('defender rook on own king line',
   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
  ('black discovered',
   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),
  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
  ('white piece near own line',
   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
   'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
  ('white piece near own line',
   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
   'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'error:' + type(exc).__name__
    check(label, actual, 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 fixtureActualExpectedOutcome
promotion gives checknonedirectFailed
knight promotion checknonedirectFailed
simple directdirectdirectPassed
discovered by bishopdiscovereddiscoveredPassed
double checkdoubledoublePassed
queen diagonal directdirectdirectPassed
rook lands on king diagonalnonenonePassed
rook quietnonenonePassed

SHA-256 / 52af2124975c6cd783294ef5bbd30c9200c6621df1edcf34db8881439daa83f2

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(x):
    b=dict(x['board']); fr,to=x['move'][:2]; p=b.pop(fr)
    if len(x['move'])>2: p=x['move'][2].upper() if p.isupper() else x['move'][2].lower()
    b[to]=p
    white=p.isupper()
    ks=[s for s,v in b.items() if v==('k' if white else 'K')][0]
    def hits(src, tgt):
        v=b[src]; t=v.upper()
        f,r=ord(src[0])-97,int(src[1])-1
        tf,tr=ord(tgt[0])-97,int(tgt[1])-1
        df,dr=tf-f,tr-r
        if t=='P': return abs(df)==1 and dr==(1 if v.isupper() else -1)
        if t=='N': return (abs(df),abs(dr)) in ((1,2),(2,1))
        if t=='K': return max(abs(df),abs(dr))==1
        orth=(df==0)!=(dr==0); diag=abs(df)==abs(dr) and df!=0
        if not ((t in ('R','Q') and orth) or (t in ('B','Q') and diag)): return False
        sf=(df>0)-(df<0); sr=(dr>0)-(dr<0)
        cf,cr=f+sf,r+sr
        while (cf,cr)!=(tf,tr):
            if chr(97+cf)+str(cr+1) in b: return False
            cf+=sf; cr+=sr
        return True
    direct=hits(to,ks)
    disc=any(hits(s,ks) for s,v in b.items() if s!=to and v.isupper()==white and v.upper()!='K')
    if direct and disc: return 'double'
    if direct: return 'direct'
    if disc: return 'discovered'
    return 'none'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none'),
  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
   'direct'),
  ('defender rook on own king line',
   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
  ('black discovered',
   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('black rook direct', {'board': {'a8': 'r', 'e1': 'K', 'h8': 'k'}, 'move': ['a8', 'a1']},
   'direct'),
  ('defender rook on own king line',
   {'board': {'a1': 'K', 'b1': 'N', 'e5': 'r', 'e8': 'k'}, 'move': ['b1', 'c3']}, 'none'),
  ('black discovered',
   {'board': {'a8': 'k', 'e1': 'K', 'e7': 'n', 'e8': 'r'}, 'move': ['e7', 'c6']}, 'discovered'),
  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
  ('white piece near own line',
   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
   'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('bishop direct', {'board': {'a1': 'K', 'e8': 'k', 'f1': 'B'}, 'move': ['f1', 'b5']}, 'direct'),
  ('pawn push check', {'board': {'a1': 'K', 'd5': 'P', 'e7': 'k'}, 'move': ['d5', 'd6']}, 'direct'),
  ('white piece near own line',
   {'board': {'a1': 'K', 'a2': 'r', 'c1': 'B', 'e3': 'P', 'h6': 'k'}, 'move': ['e3', 'e4']},
   'discovered')],
 [('promotion gives check', {'board': {'a1': 'K', 'b7': 'P', 'e8': 'k'}, 'move': ['b7', 'b8', 'q']},
   'direct'),
  ('knight promotion check',
   {'board': {'a1': 'K', 'e7': 'P', 'g7': 'k'}, 'move': ['e7', 'e8', 'n']}, 'direct'),
  ('simple direct', {'board': {'b1': 'N', 'd4': 'k', 'h1': 'K'}, 'move': ['b1', 'c2']}, 'direct'),
  ('discovered by bishop',
   {'board': {'a1': 'K', 'c3': 'B', 'd4': 'N', 'h8': 'k'}, 'move': ['d4', 'b5']}, 'discovered'),
  ('double check', {'board': {'a1': 'K', 'e1': 'R', 'e4': 'N', 'e8': 'k'}, 'move': ['e4', 'f6']},
   'double'),
  ('queen diagonal direct', {'board': {'a2': 'K', 'd1': 'Q', 'h8': 'k'}, 'move': ['d1', 'd4']},
   'direct'),
  ('rook lands on king diagonal',
   {'board': {'b1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['b1', 'b2']}, 'none'),
  ('rook quiet', {'board': {'a1': 'R', 'e1': 'K', 'h8': 'k'}, 'move': ['a1', 'b1']}, 'none')]]
for label, args, expected in fixtures[N-1]:
    try:
        actual = solve(args)
    except Exception as exc:
        actual = 'error:' + type(exc).__name__
    check(label, actual, 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 fixtureActualExpectedOutcome
promotion gives checkdirectdirectPassed
knight promotion checkdirectdirectPassed
simple directdirectdirectPassed
discovered by bishopdiscovereddiscoveredPassed
double checkdoubledoublePassed
queen diagonal directdirectdirectPassed
rook lands on king diagonalnonenonePassed
rook quietnonenonePassed

SHA-256 / 4921dc0ad8db5a68d4dde89bbbd1a6171ebcf5c278c05579679c83f6d8484b1e

Verification & scope

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.

Observations recorded using Python 3.12.14 at 2026-09-29T14:50:15.376757+00:00.

Case digest / 503d47d155b5783342234dc02cf919d62331a6065242b0543946770627ab4826