FAILURE MAP
← Case archive

FA-96801 / Phone number formatting / Open access

Numbering prefix pattern classifier: the closing bracket is read as a literal · case 01

Every pattern containing a class fails to match.

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

ROOT CAUSE

After a class the pattern index stops on the closing bracket.

VERIFIED REPAIR

Continue after the closing bracket.

Unsuccessful approach: Advancing by the body length plus one also stops on the bracket.

Case contract

Input [number, rules] with rules [pattern, label] in priority order. Pattern characters: X any digit, [..] a class of single digits and inclusive ranges a-b, other characters literal. A pattern matches when each of its positions matches the corresponding number digit (the number may be longer). Score: literal digit 2, class 1, X 0; the highest score wins and ties keep the earlier rule. No match gives "unknown".

Why this case matters

Numbering-plan tables decide routing, rating and number type from prefixes; specificity and range errors misroute whole blocks of numbers.

1 / The failure

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

N = 1
observations = []
def solve(x):
    num, rules = x
    def match(p, s):
        i = k = 0
        while k < len(p):
            if i >= len(s):
                return False
            if p[k] == 'X':
                ok = s[i].isdigit()
                k += 1
            elif p[k] == '[':
                end = p.index(']', k)
                body, ok, j = p[k + 1:end], False, 0
                while j < len(body):
                    if j + 2 < len(body) and body[j + 1] == '-':
                        ok = ok or body[j] <= s[i] <= body[j + 2]
                        j += 3
                    else:
                        ok = ok or s[i] == body[j]
                        j += 1
                k = end
            else:
                ok = s[i] == p[k]
                k += 1
            if not ok:
                return False
            i += 1
        return True
    def score(p):
        total, depth = 0, 0
        for c in p:
            if c == '[':
                depth += 1
            elif c == ']':
                depth -= 1
                total += 1
            elif c.isdigit() and depth == 0:
                total += 2
        return total
    best = None
    for p, label in rules:
        if match(p, num):
            sc = score(p)
            if best is None or sc > best[0]:
                best = (sc, label)
    return best[1] if best else 'unknown'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['class beats wildcard', ['72555012', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555012', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555012', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555012', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555012', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555012', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555012', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555012', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555023', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555023', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555023', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555023', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555023', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555023', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555023', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555023', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555034', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555034', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555034', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555034', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555034', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555034', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555034', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555034', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555045', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555045', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555045', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555045', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555045', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555045', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555045', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555045', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555056', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555056', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555056', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555056', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555056', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555056', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555056', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555056', [['7X', 'generic']]], 'unknown']]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), 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
class beats wildcardgenericmobileFailed
literal beats classspecialspecialPassed
range upper end inclusivegenericmobileFailed
range lower end inclusivegenericmobileFailed
number shorter than the patternunknownunknownPassed
tie keeps the first listed rulelisted-firstlisted-firstPassed
range then literal in one classunknownclass-rangeFailed
literal then range in one classunknownclass-literalFailed
no rule matchesunknownunknownPassed

SHA-256 / 417c42eb9ee3e292ab1172868f4d207b72aac16f8c6ff0670646da76d0e3ff1a

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    num, rules = x
    def match(p, s):
        i = k = 0
        while k < len(p):
            if i >= len(s):
                return False
            if p[k] == 'X':
                ok = s[i].isdigit()
                k += 1
            elif p[k] == '[':
                end = p.index(']', k)
                body, ok, j = p[k + 1:end], False, 0
                while j < len(body):
                    if j + 2 < len(body) and body[j + 1] == '-':
                        ok = ok or body[j] <= s[i] <= body[j + 2]
                        j += 3
                    else:
                        ok = ok or s[i] == body[j]
                        j += 1
                k += len(body) + 1
            else:
                ok = s[i] == p[k]
                k += 1
            if not ok:
                return False
            i += 1
        return True
    def score(p):
        total, depth = 0, 0
        for c in p:
            if c == '[':
                depth += 1
            elif c == ']':
                depth -= 1
                total += 1
            elif c.isdigit() and depth == 0:
                total += 2
        return total
    best = None
    for p, label in rules:
        if match(p, num):
            sc = score(p)
            if best is None or sc > best[0]:
                best = (sc, label)
    return best[1] if best else 'unknown'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['class beats wildcard', ['72555012', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555012', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555012', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555012', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555012', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555012', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555012', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555012', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555023', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555023', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555023', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555023', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555023', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555023', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555023', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555023', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555034', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555034', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555034', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555034', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555034', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555034', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555034', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555034', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555045', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555045', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555045', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555045', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555045', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555045', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555045', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555045', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555056', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555056', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555056', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555056', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555056', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555056', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555056', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555056', [['7X', 'generic']]], 'unknown']]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), 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
class beats wildcardgenericmobileFailed
literal beats classspecialspecialPassed
range upper end inclusivegenericmobileFailed
range lower end inclusivegenericmobileFailed
number shorter than the patternunknownunknownPassed
tie keeps the first listed rulelisted-firstlisted-firstPassed
range then literal in one classunknownclass-rangeFailed
literal then range in one classunknownclass-literalFailed
no rule matchesunknownunknownPassed

SHA-256 / b2acab37c4d2e44e06b514b43856d7a825cedf7ba18048e3869ca47fc39264cc

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    num, rules = x
    def match(p, s):
        i = k = 0
        while k < len(p):
            if i >= len(s):
                return False
            if p[k] == 'X':
                ok = s[i].isdigit()
                k += 1
            elif p[k] == '[':
                end = p.index(']', k)
                body, ok, j = p[k + 1:end], False, 0
                while j < len(body):
                    if j + 2 < len(body) and body[j + 1] == '-':
                        ok = ok or body[j] <= s[i] <= body[j + 2]
                        j += 3
                    else:
                        ok = ok or s[i] == body[j]
                        j += 1
                k = end + 1
            else:
                ok = s[i] == p[k]
                k += 1
            if not ok:
                return False
            i += 1
        return True
    def score(p):
        total, depth = 0, 0
        for c in p:
            if c == '[':
                depth += 1
            elif c == ']':
                depth -= 1
                total += 1
            elif c.isdigit() and depth == 0:
                total += 2
        return total
    best = None
    for p, label in rules:
        if match(p, num):
            sc = score(p)
            if best is None or sc > best[0]:
                best = (sc, label)
    return best[1] if best else 'unknown'
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['class beats wildcard', ['72555012', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555012', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555012', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555012', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555012', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555012', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555012', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555012', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555023', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555023', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555023', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555023', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555023', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555023', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555023', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555023', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555034', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555034', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555034', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555034', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555034', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555034', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555034', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555034', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555045', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555045', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555045', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555045', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555045', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555045', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555045', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555045', [['7X', 'generic']]], 'unknown']], [['class beats wildcard', ['72555056', [['7X', 'generic'], ['7[0-4]', 'mobile']]], 'mobile'], ['literal beats class', ['72555056', [['7[0-4]', 'mobile'], ['72', 'special']]], 'special'], ['range upper end inclusive', ['74555056', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['range lower end inclusive', ['70555056', [['7[0-4]', 'mobile'], ['7X', 'generic']]], 'mobile'], ['number shorter than the pattern', ['7', [['7X', 'generic']]], 'unknown'], ['tie keeps the first listed rule', ['88555056', [['X8', 'listed-first'], ['8X', 'listed-second']]], 'listed-first'], ['range then literal in one class', ['2555056', [['[0-35]X', 'class-range']]], 'class-range'], ['literal then range in one class', ['5555056', [['[50-3]X', 'class-literal']]], 'class-literal'], ['no rule matches', ['6555056', [['7X', 'generic']]], 'unknown']]]
for label, arg, expected in fixtures[N - 1]:
    check(label, solve(arg), 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
class beats wildcardmobilemobilePassed
literal beats classspecialspecialPassed
range upper end inclusivemobilemobilePassed
range lower end inclusivemobilemobilePassed
number shorter than the patternunknownunknownPassed
tie keeps the first listed rulelisted-firstlisted-firstPassed
range then literal in one classclass-rangeclass-rangePassed
literal then range in one classclass-literalclass-literalPassed
no rule matchesunknownunknownPassed

SHA-256 / 1f76afe85952c4a5a0ee9ba5a5aff4620aa9559d96b258b26daa31e775cc3366

Verification & scope

A deterministic toy contract over synthetic, obviously fictitious telephone numbers and toy country tables. The rules are stipulated for this model only and make no claim of conformance with any numbering plan or telecommunications standard. 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:52:26.024176+00:00.

Case digest / b1638579d904e5437b0e9375b1f047049fcd34e7f00612e5f04171d290bee413