FAILURE MAP
← Case archive

FA-83321 / Go territory scoring / Open access

Surplus handicap stones are accepted · case 01

Black places more free handicap stones than agreed.

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

ROOT CAUSE

The count test only rejects too few stones.

VERIFIED REPAIR

Require exactly count stones.

Unsuccessful approach: Rejecting only surplus stones accepts incomplete placements.

Case contract

Input [size, count, stones]. Check in order: every stone on the board ("range"), no duplicate ("duplicate"), exactly count stones and 2 <= count <= 9 ("count"). Otherwise "ok".

Why this case matters

Go servers and scoring tools compute this value automatically; a wrong answer changes a game result.

1 / The failure

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

N = 1
observations = []
def solve(x):
    size, count, stones = x
    seen = set()
    for r, c in stones:
        if not (0 <= r < size and 0 <= c < size):
            return 'range'
    for r, c in stones:
        if (r, c) in seen:
            return 'duplicate'
        seen.add((r, c))
    if len(stones) < count:
        return 'count'
    if count < 2 or count > 9:
        return 'count'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[19, 9, [[3, 17], [1, 1], [7, 14], [1, 11], [0, 9], [7, 13], [15, 1], [12, 18], [13, 0], [2, 13]]], 'count'], [[19, 6, [[11, 2], [8, 5], [4, 4], [13, 0], [13, 0], [18, 7], [16, 11]]], 'duplicate'], [[13, 10, [[2, 5], [11, 3], [10, 11], [11, 4], [8, 9], [8, 12], [12, 10], [10, 2], [5, 4], [9, 5], [2, 5]]], 'duplicate'], [[9, 7, [[6, 0], [6, 0], [8, 5], [0, 0], [6, 3], [0, 5], [1, 3]]], 'duplicate'], [[9, 5, [[-1, 7], [0, 2], [8, 4], [4, 1]]], 'range'], [[13, 6, [[3, 6], [11, 11], [4, 13], [9, 0], [1, 1], [12, 9], [3, 6]]], 'range'], [[9, 3, [[8, 1], [5, 2], [6, 2], [7, 2], [8, 1]]], 'duplicate'], [[19, 8, [[9, 4], [12, 2], [8, 12], [9, 15], [3, 17], [4, 10], [14, 17]]], 'count']], [[[19, 4, [[7, 1], [8, 9], [14, 2], [11, 12], [7, 1]]], 'duplicate'], [[19, 1, [[16, 11]]], 'count'], [[9, 4, [[6, 3], [1, 8], [0, 0], [6, 3]]], 'duplicate'], [[13, 6, [[0, 10], [10, 12], [0, 10], [12, 10], [9, 2], [6, 8]]], 'duplicate'], [[19, 8, [[12, 5], [16, 15], [17, 16], [10, 3], [0, 13], [14, 9], [7, 1], [9, 11]]], 'ok'], [[9, 6, [[3, 5], [1, 3], [5, 6], [2, 2], [0, 4], [8, 1], [1, 7]]], 'count'], [[13, 6, [[11, 11], [5, 6], [8, 12], [8, 0], [10, 6], [1, 9], [2, 8]]], 'count'], [[13, 5, [[11, 11], [12, 8], [3, 3], [7, 0]]], 'count']], [[[13, 6, [[11, 11], [5, 6], [8, 12], [8, 0], [10, 6], [1, 9], [2, 8]]], 'count'], [[13, 4, [[6, 3], [6, 5], [6, 11]]], 'count'], [[9, 10, [[5, 7], [1, 6], [6, 6], [4, 3], [4, 6], [5, 8], [7, 5], [5, 0], [5, 3], [5, 7]]], 'duplicate'], [[9, 5, [[3, 6], [8, 4], [0, 2], [7, 8], [1, 7]]], 'ok'], [[9, 1, [[1, 5], [7, 2]]], 'count'], [[13, 3, [[10, 0], [0, 11]]], 'count'], [[9, 2, [[3, 0], [2, 4], [6, 5]]], 'count'], [[9, 3, [[1, 1], [2, 2]]], 'count']], [[[13, 3, [[5, 9], [5, 9], [2, 6]]], 'duplicate'], [[13, 2, [[1, 3], [12, 8]]], 'ok'], [[19, 4, [[4, 4], [6, 18], [15, 18], [12, 5]]], 'ok'], [[13, 0, []], 'count'], [[19, 5, [[7, 1], [7, 3], [13, 10], [3, 11], [3, 8]]], 'ok'], [[19, 7, [[8, 18], [18, 18], [12, 4], [10, 13], [16, 1], [8, 1], [14, 7], [8, 18]]], 'duplicate'], [[9, 4, [[7, 3], [8, 3], [3, 0]]], 'count'], [[19, 7, [[7, 15], [15, 17], [17, 14], [13, 0], [5, 8], [7, 1], [14, 6], [11, 12]]], 'count']], [[[13, 10, [[11, 9], [11, 11], [7, 2], [0, 2], [10, 3], [11, 5], [7, 6], [1, 10], [3, 2], [3, 12]]], 'count'], [[13, 4, [[6, 0], [7, 9], [12, 11], [11, 9], [12, 5]]], 'count'], [[19, 1, [[10, 17], [11, 15]]], 'count'], [[13, 8, [[12, 0], [8, 0], [9, 8], [8, 5], [2, 3], [5, 12], [7, 5], [5, 0]]], 'ok'], [[13, 4, [[3, 7], [1, 12], [0, 11], [4, 6]]], 'ok'], [[13, 2, [[0, 10], [1, 4], [0, 10]]], 'duplicate'], [[19, 6, [[0, 8], [2, 10], [17, 12], [2, 15], [5, 4]]], 'count'], [[19, 5, [[7, 12], [7, 1], [13, 10], [1, 9], [14, 1], [0, 4]]], 'count']]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("free placement case %d" % i, solve(args), 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
free placement case 0okcountFailed
free placement case 1duplicateduplicatePassed
free placement case 2duplicateduplicatePassed
free placement case 3duplicateduplicatePassed
free placement case 4rangerangePassed
free placement case 5rangerangePassed
free placement case 6duplicateduplicatePassed
free placement case 7countcountPassed

SHA-256 / 1720fb9200f02e7f46084dcb5f491960ee351e78f3bf7b17e428cbb916a1be80

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    size, count, stones = x
    seen = set()
    for r, c in stones:
        if not (0 <= r < size and 0 <= c < size):
            return 'range'
    for r, c in stones:
        if (r, c) in seen:
            return 'duplicate'
        seen.add((r, c))
    if len(stones) > count:
        return 'count'
    if count < 2 or count > 9:
        return 'count'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[19, 9, [[3, 17], [1, 1], [7, 14], [1, 11], [0, 9], [7, 13], [15, 1], [12, 18], [13, 0], [2, 13]]], 'count'], [[19, 6, [[11, 2], [8, 5], [4, 4], [13, 0], [13, 0], [18, 7], [16, 11]]], 'duplicate'], [[13, 10, [[2, 5], [11, 3], [10, 11], [11, 4], [8, 9], [8, 12], [12, 10], [10, 2], [5, 4], [9, 5], [2, 5]]], 'duplicate'], [[9, 7, [[6, 0], [6, 0], [8, 5], [0, 0], [6, 3], [0, 5], [1, 3]]], 'duplicate'], [[9, 5, [[-1, 7], [0, 2], [8, 4], [4, 1]]], 'range'], [[13, 6, [[3, 6], [11, 11], [4, 13], [9, 0], [1, 1], [12, 9], [3, 6]]], 'range'], [[9, 3, [[8, 1], [5, 2], [6, 2], [7, 2], [8, 1]]], 'duplicate'], [[19, 8, [[9, 4], [12, 2], [8, 12], [9, 15], [3, 17], [4, 10], [14, 17]]], 'count']], [[[19, 4, [[7, 1], [8, 9], [14, 2], [11, 12], [7, 1]]], 'duplicate'], [[19, 1, [[16, 11]]], 'count'], [[9, 4, [[6, 3], [1, 8], [0, 0], [6, 3]]], 'duplicate'], [[13, 6, [[0, 10], [10, 12], [0, 10], [12, 10], [9, 2], [6, 8]]], 'duplicate'], [[19, 8, [[12, 5], [16, 15], [17, 16], [10, 3], [0, 13], [14, 9], [7, 1], [9, 11]]], 'ok'], [[9, 6, [[3, 5], [1, 3], [5, 6], [2, 2], [0, 4], [8, 1], [1, 7]]], 'count'], [[13, 6, [[11, 11], [5, 6], [8, 12], [8, 0], [10, 6], [1, 9], [2, 8]]], 'count'], [[13, 5, [[11, 11], [12, 8], [3, 3], [7, 0]]], 'count']], [[[13, 6, [[11, 11], [5, 6], [8, 12], [8, 0], [10, 6], [1, 9], [2, 8]]], 'count'], [[13, 4, [[6, 3], [6, 5], [6, 11]]], 'count'], [[9, 10, [[5, 7], [1, 6], [6, 6], [4, 3], [4, 6], [5, 8], [7, 5], [5, 0], [5, 3], [5, 7]]], 'duplicate'], [[9, 5, [[3, 6], [8, 4], [0, 2], [7, 8], [1, 7]]], 'ok'], [[9, 1, [[1, 5], [7, 2]]], 'count'], [[13, 3, [[10, 0], [0, 11]]], 'count'], [[9, 2, [[3, 0], [2, 4], [6, 5]]], 'count'], [[9, 3, [[1, 1], [2, 2]]], 'count']], [[[13, 3, [[5, 9], [5, 9], [2, 6]]], 'duplicate'], [[13, 2, [[1, 3], [12, 8]]], 'ok'], [[19, 4, [[4, 4], [6, 18], [15, 18], [12, 5]]], 'ok'], [[13, 0, []], 'count'], [[19, 5, [[7, 1], [7, 3], [13, 10], [3, 11], [3, 8]]], 'ok'], [[19, 7, [[8, 18], [18, 18], [12, 4], [10, 13], [16, 1], [8, 1], [14, 7], [8, 18]]], 'duplicate'], [[9, 4, [[7, 3], [8, 3], [3, 0]]], 'count'], [[19, 7, [[7, 15], [15, 17], [17, 14], [13, 0], [5, 8], [7, 1], [14, 6], [11, 12]]], 'count']], [[[13, 10, [[11, 9], [11, 11], [7, 2], [0, 2], [10, 3], [11, 5], [7, 6], [1, 10], [3, 2], [3, 12]]], 'count'], [[13, 4, [[6, 0], [7, 9], [12, 11], [11, 9], [12, 5]]], 'count'], [[19, 1, [[10, 17], [11, 15]]], 'count'], [[13, 8, [[12, 0], [8, 0], [9, 8], [8, 5], [2, 3], [5, 12], [7, 5], [5, 0]]], 'ok'], [[13, 4, [[3, 7], [1, 12], [0, 11], [4, 6]]], 'ok'], [[13, 2, [[0, 10], [1, 4], [0, 10]]], 'duplicate'], [[19, 6, [[0, 8], [2, 10], [17, 12], [2, 15], [5, 4]]], 'count'], [[19, 5, [[7, 12], [7, 1], [13, 10], [1, 9], [14, 1], [0, 4]]], 'count']]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("free placement case %d" % i, solve(args), 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
free placement case 0countcountPassed
free placement case 1duplicateduplicatePassed
free placement case 2duplicateduplicatePassed
free placement case 3duplicateduplicatePassed
free placement case 4rangerangePassed
free placement case 5rangerangePassed
free placement case 6duplicateduplicatePassed
free placement case 7okcountFailed

SHA-256 / 0f9f539a036416e554a9a33c7d0b7f1aedbd36bf99db191d101155e93976488f

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    size, count, stones = x
    seen = set()
    for r, c in stones:
        if not (0 <= r < size and 0 <= c < size):
            return 'range'
    for r, c in stones:
        if (r, c) in seen:
            return 'duplicate'
        seen.add((r, c))
    if len(stones) != count:
        return 'count'
    if count < 2 or count > 9:
        return 'count'
    return 'ok'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[[[19, 9, [[3, 17], [1, 1], [7, 14], [1, 11], [0, 9], [7, 13], [15, 1], [12, 18], [13, 0], [2, 13]]], 'count'], [[19, 6, [[11, 2], [8, 5], [4, 4], [13, 0], [13, 0], [18, 7], [16, 11]]], 'duplicate'], [[13, 10, [[2, 5], [11, 3], [10, 11], [11, 4], [8, 9], [8, 12], [12, 10], [10, 2], [5, 4], [9, 5], [2, 5]]], 'duplicate'], [[9, 7, [[6, 0], [6, 0], [8, 5], [0, 0], [6, 3], [0, 5], [1, 3]]], 'duplicate'], [[9, 5, [[-1, 7], [0, 2], [8, 4], [4, 1]]], 'range'], [[13, 6, [[3, 6], [11, 11], [4, 13], [9, 0], [1, 1], [12, 9], [3, 6]]], 'range'], [[9, 3, [[8, 1], [5, 2], [6, 2], [7, 2], [8, 1]]], 'duplicate'], [[19, 8, [[9, 4], [12, 2], [8, 12], [9, 15], [3, 17], [4, 10], [14, 17]]], 'count']], [[[19, 4, [[7, 1], [8, 9], [14, 2], [11, 12], [7, 1]]], 'duplicate'], [[19, 1, [[16, 11]]], 'count'], [[9, 4, [[6, 3], [1, 8], [0, 0], [6, 3]]], 'duplicate'], [[13, 6, [[0, 10], [10, 12], [0, 10], [12, 10], [9, 2], [6, 8]]], 'duplicate'], [[19, 8, [[12, 5], [16, 15], [17, 16], [10, 3], [0, 13], [14, 9], [7, 1], [9, 11]]], 'ok'], [[9, 6, [[3, 5], [1, 3], [5, 6], [2, 2], [0, 4], [8, 1], [1, 7]]], 'count'], [[13, 6, [[11, 11], [5, 6], [8, 12], [8, 0], [10, 6], [1, 9], [2, 8]]], 'count'], [[13, 5, [[11, 11], [12, 8], [3, 3], [7, 0]]], 'count']], [[[13, 6, [[11, 11], [5, 6], [8, 12], [8, 0], [10, 6], [1, 9], [2, 8]]], 'count'], [[13, 4, [[6, 3], [6, 5], [6, 11]]], 'count'], [[9, 10, [[5, 7], [1, 6], [6, 6], [4, 3], [4, 6], [5, 8], [7, 5], [5, 0], [5, 3], [5, 7]]], 'duplicate'], [[9, 5, [[3, 6], [8, 4], [0, 2], [7, 8], [1, 7]]], 'ok'], [[9, 1, [[1, 5], [7, 2]]], 'count'], [[13, 3, [[10, 0], [0, 11]]], 'count'], [[9, 2, [[3, 0], [2, 4], [6, 5]]], 'count'], [[9, 3, [[1, 1], [2, 2]]], 'count']], [[[13, 3, [[5, 9], [5, 9], [2, 6]]], 'duplicate'], [[13, 2, [[1, 3], [12, 8]]], 'ok'], [[19, 4, [[4, 4], [6, 18], [15, 18], [12, 5]]], 'ok'], [[13, 0, []], 'count'], [[19, 5, [[7, 1], [7, 3], [13, 10], [3, 11], [3, 8]]], 'ok'], [[19, 7, [[8, 18], [18, 18], [12, 4], [10, 13], [16, 1], [8, 1], [14, 7], [8, 18]]], 'duplicate'], [[9, 4, [[7, 3], [8, 3], [3, 0]]], 'count'], [[19, 7, [[7, 15], [15, 17], [17, 14], [13, 0], [5, 8], [7, 1], [14, 6], [11, 12]]], 'count']], [[[13, 10, [[11, 9], [11, 11], [7, 2], [0, 2], [10, 3], [11, 5], [7, 6], [1, 10], [3, 2], [3, 12]]], 'count'], [[13, 4, [[6, 0], [7, 9], [12, 11], [11, 9], [12, 5]]], 'count'], [[19, 1, [[10, 17], [11, 15]]], 'count'], [[13, 8, [[12, 0], [8, 0], [9, 8], [8, 5], [2, 3], [5, 12], [7, 5], [5, 0]]], 'ok'], [[13, 4, [[3, 7], [1, 12], [0, 11], [4, 6]]], 'ok'], [[13, 2, [[0, 10], [1, 4], [0, 10]]], 'duplicate'], [[19, 6, [[0, 8], [2, 10], [17, 12], [2, 15], [5, 4]]], 'count'], [[19, 5, [[7, 12], [7, 1], [13, 10], [1, 9], [14, 1], [0, 4]]], 'count']]]
for i, (args, expected) in enumerate(fixtures[N-1]):
    check("free placement case %d" % i, solve(args), 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
free placement case 0countcountPassed
free placement case 1duplicateduplicatePassed
free placement case 2duplicateduplicatePassed
free placement case 3duplicateduplicatePassed
free placement case 4rangerangePassed
free placement case 5rangerangePassed
free placement case 6duplicateduplicatePassed
free placement case 7countcountPassed

SHA-256 / 18d0d5033cd2f636e028177461b9a8a929f7c891fabbbc6dbecde043d3bf8414

Verification & scope

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.

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

Case digest / 8c67fd6ffaa8db709fffad0fd636352f0a40338774d71df3f35123e185e13c35