FA-026 / Text processing / Open access
Equivalent names create separate identities · case 01
Case and Unicode composition produce multiple identities for equivalent names.
ROOT CAUSE
Identity comparison uses raw codepoints without a normalization contract.
VERIFIED REPAIR
Normalize to NFC and case-fold each name before comparing identities.
Unsuccessful approach: Normalization alone leaves case differences intact.
Case contract
Normalize to NFC and case-fold each name before comparing identities.
Why this case matters
A compact reasoning and repair task with executable evidence.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import unicodedata
N = 1
observations = []
def solve(names):
return len(set(names))
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composed variants', solve(['CAFÉ', 'Cafe\u0301', 'café'] * N), 1)
check('different names', solve(['north', 'south']), 2)
check('empty list', solve([]), 0)
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| composed variants | 3 | 1 | Failed |
| different names | 2 | 2 | Passed |
| empty list | 0 | 0 | Passed |
SHA-256 / c87705150b84b05830cdef8dd75077a0aac297472c8606561593d4b5aae4fb91
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
import unicodedata
N = 1
observations = []
def solve(names):
return len({unicodedata.normalize('NFC', name) for name in names})
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composed variants', solve(['CAFÉ', 'Cafe\u0301', 'café'] * N), 1)
check('different names', solve(['north', 'south']), 2)
check('empty list', solve([]), 0)
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| composed variants | 3 | 1 | Failed |
| different names | 2 | 2 | Passed |
| empty list | 0 | 0 | Passed |
SHA-256 / f01f5b6542143e79f65eb5a2b2494eea0dad346cfeb4dab1f2d61b7351d52069
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
import unicodedata
N = 1
observations = []
def solve(names):
return len({unicodedata.normalize('NFC', name).casefold() for name in names})
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('composed variants', solve(['CAFÉ', 'Cafe\u0301', 'café'] * N), 1)
check('different names', solve(['north', 'south']), 2)
check('empty list', solve([]), 0)
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| composed variants | 1 | 1 | Passed |
| different names | 2 | 2 | Passed |
| empty list | 0 | 0 | Passed |
SHA-256 / 5dc18376990d0086c7af28f372b2ca1f2ef279341d6481b530197b73525a4ed8
Verification & scope
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:36:49.872091+00:00.
Case digest / 1d485484ea1a1f0634d95a8d3cb8854a9d6ca356af9e3e002cb09b1dc1c29cc1