FAILURE MAP
← Case archive

FA-82541 / Chess move legality / Open access

FEN placement read bottom-up · case 01

White pieces listed on the last FEN row appear on rank 8.

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

ROOT CAUSE

Rows are numbered from rank 1 although FEN lists rank 8 first.

VERIFIED REPAIR

Row i of the placement field is rank 8 - i.

Unsuccessful approach: Using 7 - i shifts every piece down one rank and puts the first row on rank 7.

Case contract

Input: a FEN string. Return {"pieces": {square: piece}, "turn", "castling", "ep", "halfmove", "fullmove"} or "invalid". Placement lists rank 8 first; digits skip empty squares; each rank must total 8; exactly one king per side. Turn is w or b; castling is "-" or letters from KQkq (returned as "" when "-"); ep is "-" (null) or a square on rank 6 when white is to move, rank 3 when black is; halfmove is a non-negative integer and fullmove at least 1.

Why this case matters

Every position-based legality check starts from a parsed FEN; a misparse silently changes which moves are legal.

1 / The failure

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

N = 1
observations = []
def solve(x):
    parts=x.split()
    if len(parts)!=6: return 'invalid'
    rows=parts[0].split('/')
    if len(rows)!=8: return 'invalid'
    board={}
    for i,row in enumerate(rows):
        rank=i+1; f=0
        for ch in row:
            if ch.isdigit(): f+=int(ch)
            elif ch in 'pnbrqkPNBRQK':
                if f>7: return 'invalid'
                board[chr(97+f)+str(rank)]=ch; f+=1
            else: return 'invalid'
        if f!=8: return 'invalid'
    vals=list(board.values())
    if vals.count('K')!=1 or vals.count('k')!=1: return 'invalid'
    turn=parts[1]
    if turn not in ('w','b'): return 'invalid'
    cast='' if parts[2]=='-' else parts[2]
    if any(c not in 'KQkq' for c in cast): return 'invalid'
    ep=None if parts[3]=='-' else parts[3]
    if ep is not None and ep[1:]!=('6' if turn=='w' else '3'): return 'invalid'
    if not (parts[4].isdigit() and parts[5].isdigit()) or int(parts[5])<1: return 'invalid'
    return {'pieces':board,'turn':turn,'castling':cast,'ep':ep,'halfmove':int(parts[4]),'fullmove':int(parts[5])}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid')],
 [('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid'),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid'),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'}),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')],
 [('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'})]]
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
kings and rook{'castling': 'Q', 'ep': None, 'fullmove': 1, 'halfmove': 0, 'pieces': {'a8': 'R', 'e1': 'k', 'e8': 'K'}, 'turn': 'w'}{'castling': 'Q', 'ep': None, 'fullmove': 1, 'halfmove': 0, 'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'}, 'turn': 'w'}Failed
black to move ep{'castling': '', 'ep': 'd3', 'fullmove': 12, 'halfmove': 0, 'pieces': {'d5': 'P', 'e1': 'k', 'e5': 'p', 'e8': 'K'}, 'turn': 'b'}{'castling': '', 'ep': 'd3', 'fullmove': 12, 'halfmove': 0, 'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'}, 'turn': 'b'}Failed
ep wrong sideinvalidinvalidPassed
two white kingsinvalidinvalidPassed
two white kings no blackinvalidinvalidPassed
missing black kinginvalidinvalidPassed
short rankinvalidinvalidPassed
fullmove zeroinvalidinvalidPassed

SHA-256 / 3cdfca62871cce868edc8514b20be32aa9bfd944e367803c56bbe630eea53555

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    parts=x.split()
    if len(parts)!=6: return 'invalid'
    rows=parts[0].split('/')
    if len(rows)!=8: return 'invalid'
    board={}
    for i,row in enumerate(rows):
        rank=7-i; f=0
        for ch in row:
            if ch.isdigit(): f+=int(ch)
            elif ch in 'pnbrqkPNBRQK':
                if f>7: return 'invalid'
                board[chr(97+f)+str(rank)]=ch; f+=1
            else: return 'invalid'
        if f!=8: return 'invalid'
    vals=list(board.values())
    if vals.count('K')!=1 or vals.count('k')!=1: return 'invalid'
    turn=parts[1]
    if turn not in ('w','b'): return 'invalid'
    cast='' if parts[2]=='-' else parts[2]
    if any(c not in 'KQkq' for c in cast): return 'invalid'
    ep=None if parts[3]=='-' else parts[3]
    if ep is not None and ep[1:]!=('6' if turn=='w' else '3'): return 'invalid'
    if not (parts[4].isdigit() and parts[5].isdigit()) or int(parts[5])<1: return 'invalid'
    return {'pieces':board,'turn':turn,'castling':cast,'ep':ep,'halfmove':int(parts[4]),'fullmove':int(parts[5])}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid')],
 [('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid'),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid'),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'}),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')],
 [('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'})]]
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
kings and rook{'castling': 'Q', 'ep': None, 'fullmove': 1, 'halfmove': 0, 'pieces': {'a0': 'R', 'e0': 'K', 'e7': 'k'}, 'turn': 'w'}{'castling': 'Q', 'ep': None, 'fullmove': 1, 'halfmove': 0, 'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'}, 'turn': 'w'}Failed
black to move ep{'castling': '', 'ep': 'd3', 'fullmove': 12, 'halfmove': 0, 'pieces': {'d3': 'P', 'e0': 'K', 'e3': 'p', 'e7': 'k'}, 'turn': 'b'}{'castling': '', 'ep': 'd3', 'fullmove': 12, 'halfmove': 0, 'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'}, 'turn': 'b'}Failed
ep wrong sideinvalidinvalidPassed
two white kingsinvalidinvalidPassed
two white kings no blackinvalidinvalidPassed
missing black kinginvalidinvalidPassed
short rankinvalidinvalidPassed
fullmove zeroinvalidinvalidPassed

SHA-256 / db3a70300d01554cde5a854071cb9ddc2077e6f9f1b4ffe38746cf6b6889e0be

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    parts=x.split()
    if len(parts)!=6: return 'invalid'
    rows=parts[0].split('/')
    if len(rows)!=8: return 'invalid'
    board={}
    for i,row in enumerate(rows):
        rank=8-i; f=0
        for ch in row:
            if ch.isdigit(): f+=int(ch)
            elif ch in 'pnbrqkPNBRQK':
                if f>7: return 'invalid'
                board[chr(97+f)+str(rank)]=ch; f+=1
            else: return 'invalid'
        if f!=8: return 'invalid'
    vals=list(board.values())
    if vals.count('K')!=1 or vals.count('k')!=1: return 'invalid'
    turn=parts[1]
    if turn not in ('w','b'): return 'invalid'
    cast='' if parts[2]=='-' else parts[2]
    if any(c not in 'KQkq' for c in cast): return 'invalid'
    ep=None if parts[3]=='-' else parts[3]
    if ep is not None and ep[1:]!=('6' if turn=='w' else '3'): return 'invalid'
    if not (parts[4].isdigit() and parts[5].isdigit()) or int(parts[5])<1: return 'invalid'
    return {'pieces':board,'turn':turn,'castling':cast,'ep':ep,'halfmove':int(parts[4]),'fullmove':int(parts[5])}
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid')],
 [('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('short rank', '4k3/8/8/8/8/8/8/4K2 w - - 0 1', 'invalid'),
  ('fullmove zero', '4k3/8/8/8/8/8/8/4K3 w - - 0 0', 'invalid'),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('halfmove dash', '4k3/8/8/8/8/8/8/4K3 w - - - 1', 'invalid'),
  ('bad castling letter', '4k3/8/8/8/8/8/8/4K3 w X - 0 1', 'invalid'),
  ('bad turn', '4k3/8/8/8/8/8/8/4K3 x - - 0 1', 'invalid'),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')],
 [('kings and rook', '4k3/8/8/8/8/8/8/R3K3 w Q - 0 1',
   {'castling': 'Q',
    'ep': None,
    'fullmove': 1,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'},
    'turn': 'w'}),
  ('black to move ep', '4k3/8/8/8/3Pp3/8/8/4K3 b - d3 0 12',
   {'castling': '',
    'ep': 'd3',
    'fullmove': 12,
    'halfmove': 0,
    'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'},
    'turn': 'b'}),
  ('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'}),
  ('fullmove dash', '4k3/8/8/8/8/8/8/4K3 w - - 0 -', 'invalid')],
 [('white ep target', '4k3/8/8/3pP3/8/8/8/4K3 w - d6 0 9',
   {'castling': '',
    'ep': 'd6',
    'fullmove': 9,
    'halfmove': 0,
    'pieces': {'d5': 'p', 'e1': 'K', 'e5': 'P', 'e8': 'k'},
    'turn': 'w'}),
  ('ep wrong side', '4k3/8/8/3pP3/8/8/8/4K3 w - d3 0 9', 'invalid'),
  ('no castling dash', 'r3k2r/8/8/8/8/8/8/R3K2R b - - 3 20',
   {'castling': '',
    'ep': None,
    'fullmove': 20,
    'halfmove': 3,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'b'}),
  ('black rights only', 'r3k2r/8/8/8/8/8/8/R3K2R w kq - 0 5',
   {'castling': 'kq',
    'ep': None,
    'fullmove': 5,
    'halfmove': 0,
    'pieces': {'a1': 'R', 'a8': 'r', 'e1': 'K', 'e8': 'k', 'h1': 'R', 'h8': 'r'},
    'turn': 'w'}),
  ('two white kings', '4k3/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('two white kings no black', '8/8/8/8/8/8/8/K3K3 w - - 0 1', 'invalid'),
  ('missing black king', '8/8/8/8/8/8/8/4K3 w - - 0 1', 'invalid'),
  ('pawns and knights', 'rn2k3/pp6/8/8/8/8/6PP/4K1NR w K - 7 30',
   {'castling': 'K',
    'ep': None,
    'fullmove': 30,
    'halfmove': 7,
    'pieces': {'a7': 'p',
               'a8': 'r',
               'b7': 'p',
               'b8': 'n',
               'e1': 'K',
               'e8': 'k',
               'g1': 'N',
               'g2': 'P',
               'h1': 'R',
               'h2': 'P'},
    'turn': 'w'})]]
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
kings and rook{'castling': 'Q', 'ep': None, 'fullmove': 1, 'halfmove': 0, 'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'}, 'turn': 'w'}{'castling': 'Q', 'ep': None, 'fullmove': 1, 'halfmove': 0, 'pieces': {'a1': 'R', 'e1': 'K', 'e8': 'k'}, 'turn': 'w'}Passed
black to move ep{'castling': '', 'ep': 'd3', 'fullmove': 12, 'halfmove': 0, 'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'}, 'turn': 'b'}{'castling': '', 'ep': 'd3', 'fullmove': 12, 'halfmove': 0, 'pieces': {'d4': 'P', 'e1': 'K', 'e4': 'p', 'e8': 'k'}, 'turn': 'b'}Passed
ep wrong sideinvalidinvalidPassed
two white kingsinvalidinvalidPassed
two white kings no blackinvalidinvalidPassed
missing black kinginvalidinvalidPassed
short rankinvalidinvalidPassed
fullmove zeroinvalidinvalidPassed

SHA-256 / 78a9b73881ff913ba212bfe49a7ddcb1b37029d73ee5e3e116db00db9d313748

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:13.158097+00:00.

Case digest / d5d6b5383ad8e4ba902a9db723cc73967295819cb4aa19f1aec6cf37d75796c2