{"abstract":"A white pawn arriving on the seventh rank is expanded into promotion moves, while the eighth rank is not.","category":"Chess move legality","checks":8,"contract":"Input: {\"board\", \"from\": square of a pawn, \"ep\": en passant target square or null}. Return sorted pseudo-legal destinations: one step forward if empty; two steps from the starting rank if both squares are empty; diagonal captures of enemy pieces or onto the ep square. A destination on the last rank is expanded into four entries suffixed q, r, b, n.","evaluation_group":"w2-chess_move_legality-pawn-move-generation","failed_approach":"Hard-coding rank index 7 never promotes black pawns.","family":"w2-chess_move_legality-pawn-move-generation-promotion-rank-test","id":"FA-82401","implementations":{"attempt":{"sha256":"dd7f9a4637fa6023f949c9198fc43f029dc96faa5c765625131721918a2cc32d","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    b=x['board']; sq=x['from']; p=b[sq]; white=p=='P'\n    f,r=ord(sq[0])-97,int(sq[1])-1\n    d=1 if white else -1\n    start=1 if white else 6\n    last=7 if white else 0\n    def at(ff,rr): return chr(97+ff)+str(rr+1)\n    out=[]\n    if 0<=r+d<8 and at(f,r+d) not in b:\n        out.append(at(f,r+d))\n        if r==start and at(f,r+2*d) not in b: out.append(at(f,r+2*d))\n    for df in (-1,1):\n        ff=f+df\n        if not 0<=ff<8 or not 0<=r+d<8: continue\n        t=at(ff,r+d); occ=b.get(t)\n        if (occ and occ.isupper()!=white) or t==x.get('ep'): out.append(t)\n    res=[]\n    for t in out:\n        if int(t[1])-1==7: res+=[t+c for c in 'qrbn']\n        else: res.append(t)\n    return sorted(res)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r'])],\n [('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('en passant target', {'board': {'d5': 'p', 'e5': 'P'}, 'ep': 'd6', 'from': 'e5'}, ['d6', 'e6']),\n  ('black on sixth rank', {'board': {'a6': 'p'}, 'ep': None, 'from': 'a6'}, ['a5']),\n  ('white third rank', {'board': {'g3': 'P'}, 'ep': None, 'from': 'g3'}, ['g4'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('en passant target', {'board': {'d5': 'p', 'e5': 'P'}, 'ep': 'd6', 'from': 'e5'}, ['d6', 'e6']),\n  ('black on sixth rank', {'board': {'a6': 'p'}, 'ep': None, 'from': 'a6'}, ['a5']),\n  ('white third rank', {'board': {'g3': 'P'}, 'ep': None, 'from': 'g3'}, ['g4']),\n  ('black blocked by own', {'board': {'a6': 'P', 'b6': 'p', 'b7': 'p'}, 'ep': None, 'from': 'b7'},\n   ['a6'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('black blocked by own', {'board': {'a6': 'P', 'b6': 'p', 'b7': 'p'}, 'ep': None, 'from': 'b7'},\n   ['a6'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r'])]]\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":"34bc0fd42977c2773f91c403e9e3632c1b05c73982358caaf74b008a6b42c4ae","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    b=x['board']; sq=x['from']; p=b[sq]; white=p=='P'\n    f,r=ord(sq[0])-97,int(sq[1])-1\n    d=1 if white else -1\n    start=1 if white else 6\n    last=7 if white else 0\n    def at(ff,rr): return chr(97+ff)+str(rr+1)\n    out=[]\n    if 0<=r+d<8 and at(f,r+d) not in b:\n        out.append(at(f,r+d))\n        if r==start and at(f,r+2*d) not in b: out.append(at(f,r+2*d))\n    for df in (-1,1):\n        ff=f+df\n        if not 0<=ff<8 or not 0<=r+d<8: continue\n        t=at(ff,r+d); occ=b.get(t)\n        if (occ and occ.isupper()!=white) or t==x.get('ep'): out.append(t)\n    res=[]\n    for t in out:\n        if int(t[1])==last: res+=[t+c for c in 'qrbn']\n        else: res.append(t)\n    return sorted(res)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r'])],\n [('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('en passant target', {'board': {'d5': 'p', 'e5': 'P'}, 'ep': 'd6', 'from': 'e5'}, ['d6', 'e6']),\n  ('black on sixth rank', {'board': {'a6': 'p'}, 'ep': None, 'from': 'a6'}, ['a5']),\n  ('white third rank', {'board': {'g3': 'P'}, 'ep': None, 'from': 'g3'}, ['g4'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('en passant target', {'board': {'d5': 'p', 'e5': 'P'}, 'ep': 'd6', 'from': 'e5'}, ['d6', 'e6']),\n  ('black on sixth rank', {'board': {'a6': 'p'}, 'ep': None, 'from': 'a6'}, ['a5']),\n  ('white third rank', {'board': {'g3': 'P'}, 'ep': None, 'from': 'g3'}, ['g4']),\n  ('black blocked by own', {'board': {'a6': 'P', 'b6': 'p', 'b7': 'p'}, 'ep': None, 'from': 'b7'},\n   ['a6'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('black blocked by own', {'board': {'a6': 'P', 'b6': 'p', 'b7': 'p'}, 'ep': None, 'from': 'b7'},\n   ['a6'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r'])]]\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"},"fixed":{"sha256":"265e58d6130dae31d9aec2fd7dd4dbb05360642039d6936ed062c49531d74366","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    b=x['board']; sq=x['from']; p=b[sq]; white=p=='P'\n    f,r=ord(sq[0])-97,int(sq[1])-1\n    d=1 if white else -1\n    start=1 if white else 6\n    last=7 if white else 0\n    def at(ff,rr): return chr(97+ff)+str(rr+1)\n    out=[]\n    if 0<=r+d<8 and at(f,r+d) not in b:\n        out.append(at(f,r+d))\n        if r==start and at(f,r+2*d) not in b: out.append(at(f,r+2*d))\n    for df in (-1,1):\n        ff=f+df\n        if not 0<=ff<8 or not 0<=r+d<8: continue\n        t=at(ff,r+d); occ=b.get(t)\n        if (occ and occ.isupper()!=white) or t==x.get('ep'): out.append(t)\n    res=[]\n    for t in out:\n        if int(t[1])-1==last: res+=[t+c for c in 'qrbn']\n        else: res.append(t)\n    return sorted(res)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r'])],\n [('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('en passant target', {'board': {'d5': 'p', 'e5': 'P'}, 'ep': 'd6', 'from': 'e5'}, ['d6', 'e6']),\n  ('black on sixth rank', {'board': {'a6': 'p'}, 'ep': None, 'from': 'a6'}, ['a5']),\n  ('white third rank', {'board': {'g3': 'P'}, 'ep': None, 'from': 'g3'}, ['g4'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('en passant target', {'board': {'d5': 'p', 'e5': 'P'}, 'ep': 'd6', 'from': 'e5'}, ['d6', 'e6']),\n  ('black on sixth rank', {'board': {'a6': 'p'}, 'ep': None, 'from': 'a6'}, ['a5']),\n  ('white third rank', {'board': {'g3': 'P'}, 'ep': None, 'from': 'g3'}, ['g4']),\n  ('black blocked by own', {'board': {'a6': 'P', 'b6': 'p', 'b7': 'p'}, 'ep': None, 'from': 'b7'},\n   ['a6'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r']),\n  ('black blocked by own', {'board': {'a6': 'P', 'b6': 'p', 'b7': 'p'}, 'ep': None, 'from': 'b7'},\n   ['a6'])],\n [('white double push', {'board': {'e2': 'P'}, 'ep': None, 'from': 'e2'}, ['e3', 'e4']),\n  ('black double push', {'board': {'d7': 'p'}, 'ep': None, 'from': 'd7'}, ['d5', 'd6']),\n  ('blocked jump', {'board': {'e2': 'P', 'e3': 'n'}, 'ep': None, 'from': 'e2'}, []),\n  ('far square blocked', {'board': {'c5': 'P', 'c7': 'p'}, 'ep': None, 'from': 'c7'}, ['c6']),\n  ('captures both colours', {'board': {'c5': 'p', 'd4': 'P', 'e5': 'B'}, 'ep': None, 'from': 'd4'},\n   ['c5', 'd5']),\n  ('black captures',\n   {'board': {'e5': 'P', 'f5': 'P', 'f6': 'p', 'g5': 'n'}, 'ep': None, 'from': 'f6'}, ['e5']),\n  ('white promotion', {'board': {'a8': 'r', 'b7': 'P'}, 'ep': None, 'from': 'b7'},\n   ['a8b', 'a8n', 'a8q', 'a8r', 'b8b', 'b8n', 'b8q', 'b8r']),\n  ('black promotion', {'board': {'h2': 'p'}, 'ep': None, 'from': 'h2'},\n   ['h1b', 'h1n', 'h1q', 'h1r'])]]\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-pawn-move-generation-promotion-rank-test","generated_at":"2026-09-29T14:50:11.849853+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Move validators gate every move in engines, servers and arbiters; accepting an illegal move or rejecting a legal one corrupts the game record.","repair":"Convert the destination rank to zero-based before comparing.","root_cause":"The rank digit is compared to a zero-based last-rank index.","sha256":"5bd1e43efb3aaf17d08c0aa40d966bb40135a2f27999a9704fa2617267080364","title":"Promotion triggered one rank early · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":41.198,"exit_code":1,"observations":[{"actual":["e3","e4"],"check":"white double push","expected":["e3","e4"],"passed":true},{"actual":["d5","d6"],"check":"black double push","expected":["d5","d6"],"passed":true},{"actual":[],"check":"blocked jump","expected":[],"passed":true},{"actual":["c6"],"check":"far square blocked","expected":["c6"],"passed":true},{"actual":["c5","d5"],"check":"captures both colours","expected":["c5","d5"],"passed":true},{"actual":["e5"],"check":"black captures","expected":["e5"],"passed":true},{"actual":["a8b","a8n","a8q","a8r","b8b","b8n","b8q","b8r"],"check":"white promotion","expected":["a8b","a8n","a8q","a8r","b8b","b8n","b8q","b8r"],"passed":true},{"actual":["h1"],"check":"black promotion","expected":["h1b","h1n","h1q","h1r"],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"white double push\", \"actual\": [\"e3\", \"e4\"], \"expected\": [\"e3\", \"e4\"], \"passed\": true}, {\"check\": \"black double push\", \"actual\": [\"d5\", \"d6\"], \"expected\": [\"d5\", \"d6\"], \"passed\": true}, {\"check\": \"blocked jump\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"far square blocked\", \"actual\": [\"c6\"], \"expected\": [\"c6\"], \"passed\": true}, {\"check\": \"captures both colours\", \"actual\": [\"c5\", \"d5\"], \"expected\": [\"c5\", \"d5\"], \"passed\": true}, {\"check\": \"black captures\", \"actual\": [\"e5\"], \"expected\": [\"e5\"], \"passed\": true}, {\"check\": \"white promotion\", \"actual\": [\"a8b\", \"a8n\", \"a8q\", \"a8r\", \"b8b\", \"b8n\", \"b8q\", \"b8r\"], \"expected\": [\"a8b\", \"a8n\", \"a8q\", \"a8r\", \"b8b\", \"b8n\", \"b8q\", \"b8r\"], \"passed\": true}, {\"check\": \"black promotion\", \"actual\": [\"h1\"], \"expected\": [\"h1b\", \"h1n\", \"h1q\", \"h1r\"], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":41.543,"exit_code":1,"observations":[{"actual":["e3","e4"],"check":"white double push","expected":["e3","e4"],"passed":true},{"actual":["d5","d6"],"check":"black double push","expected":["d5","d6"],"passed":true},{"actual":[],"check":"blocked jump","expected":[],"passed":true},{"actual":["c6"],"check":"far square blocked","expected":["c6"],"passed":true},{"actual":["c5","d5"],"check":"captures both colours","expected":["c5","d5"],"passed":true},{"actual":["e5"],"check":"black captures","expected":["e5"],"passed":true},{"actual":["a8","b8"],"check":"white promotion","expected":["a8b","a8n","a8q","a8r","b8b","b8n","b8q","b8r"],"passed":false},{"actual":["h1"],"check":"black promotion","expected":["h1b","h1n","h1q","h1r"],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"white double push\", \"actual\": [\"e3\", \"e4\"], \"expected\": [\"e3\", \"e4\"], \"passed\": true}, {\"check\": \"black double push\", \"actual\": [\"d5\", \"d6\"], \"expected\": [\"d5\", \"d6\"], \"passed\": true}, {\"check\": \"blocked jump\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"far square blocked\", \"actual\": [\"c6\"], \"expected\": [\"c6\"], \"passed\": true}, {\"check\": \"captures both colours\", \"actual\": [\"c5\", \"d5\"], \"expected\": [\"c5\", \"d5\"], \"passed\": true}, {\"check\": \"black captures\", \"actual\": [\"e5\"], \"expected\": [\"e5\"], \"passed\": true}, {\"check\": \"white promotion\", \"actual\": [\"a8\", \"b8\"], \"expected\": [\"a8b\", \"a8n\", \"a8q\", \"a8r\", \"b8b\", \"b8n\", \"b8q\", \"b8r\"], \"passed\": false}, {\"check\": \"black promotion\", \"actual\": [\"h1\"], \"expected\": [\"h1b\", \"h1n\", \"h1q\", \"h1r\"], \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.454,"exit_code":0,"observations":[{"actual":["e3","e4"],"check":"white double push","expected":["e3","e4"],"passed":true},{"actual":["d5","d6"],"check":"black double push","expected":["d5","d6"],"passed":true},{"actual":[],"check":"blocked jump","expected":[],"passed":true},{"actual":["c6"],"check":"far square blocked","expected":["c6"],"passed":true},{"actual":["c5","d5"],"check":"captures both colours","expected":["c5","d5"],"passed":true},{"actual":["e5"],"check":"black captures","expected":["e5"],"passed":true},{"actual":["a8b","a8n","a8q","a8r","b8b","b8n","b8q","b8r"],"check":"white promotion","expected":["a8b","a8n","a8q","a8r","b8b","b8n","b8q","b8r"],"passed":true},{"actual":["h1b","h1n","h1q","h1r"],"check":"black promotion","expected":["h1b","h1n","h1q","h1r"],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"white double push\", \"actual\": [\"e3\", \"e4\"], \"expected\": [\"e3\", \"e4\"], \"passed\": true}, {\"check\": \"black double push\", \"actual\": [\"d5\", \"d6\"], \"expected\": [\"d5\", \"d6\"], \"passed\": true}, {\"check\": \"blocked jump\", \"actual\": [], \"expected\": [], \"passed\": true}, {\"check\": \"far square blocked\", \"actual\": [\"c6\"], \"expected\": [\"c6\"], \"passed\": true}, {\"check\": \"captures both colours\", \"actual\": [\"c5\", \"d5\"], \"expected\": [\"c5\", \"d5\"], \"passed\": true}, {\"check\": \"black captures\", \"actual\": [\"e5\"], \"expected\": [\"e5\"], \"passed\": true}, {\"check\": \"white promotion\", \"actual\": [\"a8b\", \"a8n\", \"a8q\", \"a8r\", \"b8b\", \"b8n\", \"b8q\", \"b8r\"], \"expected\": [\"a8b\", \"a8n\", \"a8q\", \"a8r\", \"b8b\", \"b8n\", \"b8q\", \"b8r\"], \"passed\": true}, {\"check\": \"black promotion\", \"actual\": [\"h1b\", \"h1n\", \"h1q\", \"h1r\"], \"expected\": [\"h1b\", \"h1n\", \"h1q\", \"h1r\"], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}