{"abstract":"Taking the last liberty of an enclosing chain is refused although it would capture.","category":"Go territory scoring","checks":8,"contract":"Input [board, colour, row, col]. Occupied point -> [\"illegal\", \"occupied\"]. Otherwise place the stone, remove every adjacent opponent chain left without liberties, then reject the move as [\"illegal\", \"suicide\"] only if the placed chain still has no liberty. Return [new_board, captured_stone_count].","contract_signature":"x","evaluation_group":"w2-go-territory-scoring-move-capture","failed_approach":"Dropping the suicide test entirely accepts genuine suicides and leaves a libertyless chain on the board.","family":"w2-go-territory-scoring-move-capture-suicide-test-before-capture-resolution","id":"FA-82891","implementations":{"attempt":{"sha256":"6d8adcab3d3154adfd3ed1a58d98239351d1483b276fb41531b752dfdd1e40f7","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    board, color, r, c = x\n    g = [list(row) for row in board]\n    n = len(g)\n    m = len(g[0])\n    if g[r][c] != '.':\n        return ['illegal', 'occupied']\n    opp = 'W' if color == 'B' else 'B'\n    g[r][c] = color\n    def group(i, j):\n        col = g[i][j]\n        stones = {(i, j)}\n        libs = set()\n        stack = [(i, j)]\n        while stack:\n            a, b = stack.pop()\n            for p, q in ((a, b + 1), (a + 1, b), (a, b - 1), (a - 1, b)):\n                if 0 <= p < n and 0 <= q < m:\n                    if g[p][q] == '.':\n                        libs.add((p, q))\n                    elif g[p][q] == col and (p, q) not in stones:\n                        stones.add((p, q))\n                        stack.append((p, q))\n        return stones, libs\n    captured = 0\n    for p, q in ((r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)):\n        if 0 <= p < n and 0 <= q < m and g[p][q] == opp:\n            stones, libs = group(p, q)\n            if not libs:\n                for s, t in stones:\n                    g[s][t] = '.'\n                captured += len(stones)\n    return [[''.join(row) for row in g], captured]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[['...', '...', '...'], 'W', 2, 0], [['...', '...', 'W..'], 0]], [[['.B.', 'B.B', '.B.'], 'W', 2, 2], ['illegal', 'suicide']], [[['.B.', 'B.B', '.B.'], 'W', 2, 0], ['illegal', 'suicide']], [[['.B.', 'B.B', '.B.'], 'B', 0, 0], [['BB.', 'B.B', '.B.'], 0]], [[['.B.', 'B.B', '.B.'], 'B', 0, 2], [['.BB', 'B.B', '.B.'], 0]], [[['.B.', 'B.B', '.B.'], 'B', 0, 1], ['illegal', 'occupied']], [[['WWBW', 'WBBW', 'WBB.'], 'W', 2, 3], [['WW.W', 'W..W', 'W..W'], 5]], [[['...', '.BW', '..B', '.BW', 'BB.'], 'W', 4, 2], ['illegal', 'suicide']]], [[[['B..W', 'B..W', 'B..W', 'B..W'], 'B', 1, 1], [['B..W', 'BB.W', 'B..W', 'B..W'], 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], 'W', 0, 2], [['B.WW', 'B..W', 'B..W', 'B..W'], 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], 'B', 0, 1], [['BB.W', 'B..W', 'B..W', 'B..W'], 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], 'B', 2, 0], ['illegal', 'occupied']], [[['.BW.', '.BW.', '.BW.', '.BW.'], 'W', 2, 3], [['.BW.', '.BW.', '.BWW', '.BW.'], 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], 'W', 0, 0], [['WBW.', '.BW.', '.BW.', '.BW.'], 0]], [[['W.WW.', '...BW', '...W.'], 'B', 2, 4], ['illegal', 'suicide']], [[['WBW', 'BBB', 'BB.'], 'W', 2, 2], [['W.W', '...', '..W'], 6]]], [[[['.BW.', '.BW.', '.BW.', '.BW.'], 'B', 2, 0], [['.BW.', '.BW.', 'BBW.', '.BW.'], 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], 'B', 0, 2], ['illegal', 'occupied']], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 'B', 0, 0], [['B.B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 0]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 'B', 1, 1], [['..B..', '.BB..', 'BBBBB', 'WWWWW', '..W..'], 0]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 'B', 4, 0], [['..B..', '..B..', 'BBBBB', 'WWWWW', 'B.W..'], 0]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 'B', 0, 1], [['.BB..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 0]], [[['.B.', 'BWB', '...'], 'W', 0, 0], ['illegal', 'suicide']], [[['B.B', 'WBW', '.W.'], 'B', 2, 2], [['B.B', 'WB.', '.WB'], 1]]], [[[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'W', 2, 1], ['illegal', 'suicide']], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'W', 0, 1], ['illegal', 'suicide']], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'B', 4, 3], [['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..WB.'], 0]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'B', 2, 4], [['B.B.W', '.B.W.', 'B.BWB', 'BBW.W', '..W..'], 0]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'B', 3, 2], ['illegal', 'occupied']], [[['W....', '.....', '.....', '.....', '....B'], 'W', 4, 1], [['W....', '.....', '.....', '.....', '.W..B'], 0]], [[['.W.', 'WBW', 'BWB'], 'B', 0, 2], [['.WB', 'WB.', 'BWB'], 1]], [[['BWB', 'W.W', 'BWB'], 'W', 1, 1], ['illegal', 'suicide']]], [[[['W....', '.....', '.....', '.....', '....B'], 'W', 3, 0], [['W....', '.....', '.....', 'W....', '....B'], 0]], [[['W....', '.....', '.....', '.....', '....B'], 'W', 4, 0], [['W....', '.....', '.....', '.....', 'W...B'], 0]], [[['W....', '.....', '.....', '.....', '....B'], 'B', 4, 4], ['illegal', 'occupied']], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], 'W', 0, 2], [['.WWB.', 'W.WB.', '.WB..', 'WB...', 'B....'], 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], 'W', 0, 0], [['WW.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], 'B', 2, 4], [['.W.B.', 'W.WB.', '.WB.B', 'WB...', 'B....'], 0]], [[['WWW', 'W.W', 'WWW'], 'W', 1, 1], ['illegal', 'suicide']], [[['BWB', 'W.W', 'BWB'], 'B', 1, 1], [['B.B', '.B.', 'B.B'], 4]]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"move result case %d\" % i, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"2dc3464439bcb10837ec8d94e179acedd0d48ca81c6e2d5f732777a2e32b150a","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    board, color, r, c = x\n    g = [list(row) for row in board]\n    n = len(g)\n    m = len(g[0])\n    if g[r][c] != '.':\n        return ['illegal', 'occupied']\n    opp = 'W' if color == 'B' else 'B'\n    g[r][c] = color\n    def group(i, j):\n        col = g[i][j]\n        stones = {(i, j)}\n        libs = set()\n        stack = [(i, j)]\n        while stack:\n            a, b = stack.pop()\n            for p, q in ((a, b + 1), (a + 1, b), (a, b - 1), (a - 1, b)):\n                if 0 <= p < n and 0 <= q < m:\n                    if g[p][q] == '.':\n                        libs.add((p, q))\n                    elif g[p][q] == col and (p, q) not in stones:\n                        stones.add((p, q))\n                        stack.append((p, q))\n        return stones, libs\n    own, own_libs = group(r, c)\n    if not own_libs:\n        return ['illegal', 'suicide']\n    captured = 0\n    for p, q in ((r + 1, c), (r - 1, c), (r, c + 1), (r, c - 1)):\n        if 0 <= p < n and 0 <= q < m and g[p][q] == opp:\n            stones, libs = group(p, q)\n            if not libs:\n                for s, t in stones:\n                    g[s][t] = '.'\n                captured += len(stones)\n    stones, libs = group(r, c)\n    if not libs:\n        return ['illegal', 'suicide']\n    return [[''.join(row) for row in g], captured]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[[[['...', '...', '...'], 'W', 2, 0], [['...', '...', 'W..'], 0]], [[['.B.', 'B.B', '.B.'], 'W', 2, 2], ['illegal', 'suicide']], [[['.B.', 'B.B', '.B.'], 'W', 2, 0], ['illegal', 'suicide']], [[['.B.', 'B.B', '.B.'], 'B', 0, 0], [['BB.', 'B.B', '.B.'], 0]], [[['.B.', 'B.B', '.B.'], 'B', 0, 2], [['.BB', 'B.B', '.B.'], 0]], [[['.B.', 'B.B', '.B.'], 'B', 0, 1], ['illegal', 'occupied']], [[['WWBW', 'WBBW', 'WBB.'], 'W', 2, 3], [['WW.W', 'W..W', 'W..W'], 5]], [[['...', '.BW', '..B', '.BW', 'BB.'], 'W', 4, 2], ['illegal', 'suicide']]], [[[['B..W', 'B..W', 'B..W', 'B..W'], 'B', 1, 1], [['B..W', 'BB.W', 'B..W', 'B..W'], 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], 'W', 0, 2], [['B.WW', 'B..W', 'B..W', 'B..W'], 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], 'B', 0, 1], [['BB.W', 'B..W', 'B..W', 'B..W'], 0]], [[['B..W', 'B..W', 'B..W', 'B..W'], 'B', 2, 0], ['illegal', 'occupied']], [[['.BW.', '.BW.', '.BW.', '.BW.'], 'W', 2, 3], [['.BW.', '.BW.', '.BWW', '.BW.'], 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], 'W', 0, 0], [['WBW.', '.BW.', '.BW.', '.BW.'], 0]], [[['W.WW.', '...BW', '...W.'], 'B', 2, 4], ['illegal', 'suicide']], [[['WBW', 'BBB', 'BB.'], 'W', 2, 2], [['W.W', '...', '..W'], 6]]], [[[['.BW.', '.BW.', '.BW.', '.BW.'], 'B', 2, 0], [['.BW.', '.BW.', 'BBW.', '.BW.'], 0]], [[['.BW.', '.BW.', '.BW.', '.BW.'], 'B', 0, 2], ['illegal', 'occupied']], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 'B', 0, 0], [['B.B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 0]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 'B', 1, 1], [['..B..', '.BB..', 'BBBBB', 'WWWWW', '..W..'], 0]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 'B', 4, 0], [['..B..', '..B..', 'BBBBB', 'WWWWW', 'B.W..'], 0]], [[['..B..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 'B', 0, 1], [['.BB..', '..B..', 'BBBBB', 'WWWWW', '..W..'], 0]], [[['.B.', 'BWB', '...'], 'W', 0, 0], ['illegal', 'suicide']], [[['B.B', 'WBW', '.W.'], 'B', 2, 2], [['B.B', 'WB.', '.WB'], 1]]], [[[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'W', 2, 1], ['illegal', 'suicide']], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'W', 0, 1], ['illegal', 'suicide']], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'B', 4, 3], [['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..WB.'], 0]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'B', 2, 4], [['B.B.W', '.B.W.', 'B.BWB', 'BBW.W', '..W..'], 0]], [[['B.B.W', '.B.W.', 'B.BW.', 'BBW.W', '..W..'], 'B', 3, 2], ['illegal', 'occupied']], [[['W....', '.....', '.....', '.....', '....B'], 'W', 4, 1], [['W....', '.....', '.....', '.....', '.W..B'], 0]], [[['.W.', 'WBW', 'BWB'], 'B', 0, 2], [['.WB', 'WB.', 'BWB'], 1]], [[['BWB', 'W.W', 'BWB'], 'W', 1, 1], ['illegal', 'suicide']]], [[[['W....', '.....', '.....', '.....', '....B'], 'W', 3, 0], [['W....', '.....', '.....', 'W....', '....B'], 0]], [[['W....', '.....', '.....', '.....', '....B'], 'W', 4, 0], [['W....', '.....', '.....', '.....', 'W...B'], 0]], [[['W....', '.....', '.....', '.....', '....B'], 'B', 4, 4], ['illegal', 'occupied']], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], 'W', 0, 2], [['.WWB.', 'W.WB.', '.WB..', 'WB...', 'B....'], 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], 'W', 0, 0], [['WW.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], 0]], [[['.W.B.', 'W.WB.', '.WB..', 'WB...', 'B....'], 'B', 2, 4], [['.W.B.', 'W.WB.', '.WB.B', 'WB...', 'B....'], 0]], [[['WWW', 'W.W', 'WWW'], 'W', 1, 1], ['illegal', 'suicide']], [[['BWB', 'W.W', 'BWB'], 'B', 1, 1], [['B.B', '.B.', 'B.B'], 4]]]]\nfor i, (args, expected) in enumerate(fixtures[N-1]):\n    check(\"move result case %d\" % i, solve(args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"Small rectangular toy boards given as strings of B, W and dot; a bounded teaching model of one scoring or bookkeeping rule, not a complete rules engine or server implementation. 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-go-territory-scoring-move-capture-suicide-test-before-capture-resolution","generated_at":"2026-09-29T14:50:16.411653+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Go servers and scoring tools compute this value automatically; a wrong answer changes a game result.","root_cause":"The own-chain liberty check runs before opponent chains without liberties are removed.","sha256":"7cb675a4b58eb8a87c31267e71e1969f5bf35b78fef9ef07f0af988c8491a1e9","title":"A capturing move into a surrounded point is rejected as suicide · 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":38.843,"exit_code":1,"observations":[{"actual":[["...","...","W.."],0],"check":"move result case 0","expected":[["...","...","W.."],0],"passed":true},{"actual":[[".B.","B.B",".BW"],0],"check":"move result case 1","expected":["illegal","suicide"],"passed":false},{"actual":[[".B.","B.B","WB."],0],"check":"move result case 2","expected":["illegal","suicide"],"passed":false},{"actual":[["BB.","B.B",".B."],0],"check":"move result case 3","expected":[["BB.","B.B",".B."],0],"passed":true},{"actual":[[".BB","B.B",".B."],0],"check":"move result case 4","expected":[[".BB","B.B",".B."],0],"passed":true},{"actual":["illegal","occupied"],"check":"move result case 5","expected":["illegal","occupied"],"passed":true},{"actual":[["WW.W","W..W","W..W"],5],"check":"move result case 6","expected":[["WW.W","W..W","W..W"],5],"passed":true},{"actual":[["...",".BW","..B",".BW","BBW"],0],"check":"move result case 7","expected":["illegal","suicide"],"passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"move result case 0\", \"actual\": [[\"...\", \"...\", \"W..\"], 0], \"expected\": [[\"...\", \"...\", \"W..\"], 0], \"passed\": true}, {\"check\": \"move result case 1\", \"actual\": [[\".B.\", \"B.B\", \".BW\"], 0], \"expected\": [\"illegal\", \"suicide\"], \"passed\": false}, {\"check\": \"move result case 2\", \"actual\": [[\".B.\", \"B.B\", \"WB.\"], 0], \"expected\": [\"illegal\", \"suicide\"], \"passed\": false}, {\"check\": \"move result case 3\", \"actual\": [[\"BB.\", \"B.B\", \".B.\"], 0], \"expected\": [[\"BB.\", \"B.B\", \".B.\"], 0], \"passed\": true}, {\"check\": \"move result case 4\", \"actual\": [[\".BB\", \"B.B\", \".B.\"], 0], \"expected\": [[\".BB\", \"B.B\", \".B.\"], 0], \"passed\": true}, {\"check\": \"move result case 5\", \"actual\": [\"illegal\", \"occupied\"], \"expected\": [\"illegal\", \"occupied\"], \"passed\": true}, {\"check\": \"move result case 6\", \"actual\": [[\"WW.W\", \"W..W\", \"W..W\"], 5], \"expected\": [[\"WW.W\", \"W..W\", \"W..W\"], 5], \"passed\": true}, {\"check\": \"move result case 7\", \"actual\": [[\"...\", \".BW\", \"..B\", \".BW\", \"BBW\"], 0], \"expected\": [\"illegal\", \"suicide\"], \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.946,"exit_code":1,"observations":[{"actual":[["...","...","W.."],0],"check":"move result case 0","expected":[["...","...","W.."],0],"passed":true},{"actual":["illegal","suicide"],"check":"move result case 1","expected":["illegal","suicide"],"passed":true},{"actual":["illegal","suicide"],"check":"move result case 2","expected":["illegal","suicide"],"passed":true},{"actual":[["BB.","B.B",".B."],0],"check":"move result case 3","expected":[["BB.","B.B",".B."],0],"passed":true},{"actual":[[".BB","B.B",".B."],0],"check":"move result case 4","expected":[[".BB","B.B",".B."],0],"passed":true},{"actual":["illegal","occupied"],"check":"move result case 5","expected":["illegal","occupied"],"passed":true},{"actual":["illegal","suicide"],"check":"move result case 6","expected":[["WW.W","W..W","W..W"],5],"passed":false},{"actual":["illegal","suicide"],"check":"move result case 7","expected":["illegal","suicide"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"move result case 0\", \"actual\": [[\"...\", \"...\", \"W..\"], 0], \"expected\": [[\"...\", \"...\", \"W..\"], 0], \"passed\": true}, {\"check\": \"move result case 1\", \"actual\": [\"illegal\", \"suicide\"], \"expected\": [\"illegal\", \"suicide\"], \"passed\": true}, {\"check\": \"move result case 2\", \"actual\": [\"illegal\", \"suicide\"], \"expected\": [\"illegal\", \"suicide\"], \"passed\": true}, {\"check\": \"move result case 3\", \"actual\": [[\"BB.\", \"B.B\", \".B.\"], 0], \"expected\": [[\"BB.\", \"B.B\", \".B.\"], 0], \"passed\": true}, {\"check\": \"move result case 4\", \"actual\": [[\".BB\", \"B.B\", \".B.\"], 0], \"expected\": [[\".BB\", \"B.B\", \".B.\"], 0], \"passed\": true}, {\"check\": \"move result case 5\", \"actual\": [\"illegal\", \"occupied\"], \"expected\": [\"illegal\", \"occupied\"], \"passed\": true}, {\"check\": \"move result case 6\", \"actual\": [\"illegal\", \"suicide\"], \"expected\": [[\"WW.W\", \"W..W\", \"W..W\"], 5], \"passed\": false}, {\"check\": \"move result case 7\", \"actual\": [\"illegal\", \"suicide\"], \"expected\": [\"illegal\", \"suicide\"], \"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."}}