FAILURE MAP
← Case archive

FA-96561 / Phone number formatting / Open access

As-you-type ten-digit formatter: parentheses appear after three digits · case 01

Typing three digits shows "(555)" before the user continues.

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

ROOT CAUSE

The bare range is len(d) < 3.

VERIFIED REPAIR

Keep up to three digits bare; open the parentheses from the fourth digit.

Unsuccessful approach: Keeping four digits bare delays the area formatting by one keystroke.

Case contract

Input the digits typed so far. A leading 1 becomes the prefix "1 ". With more than ten remaining digits the raw input is returned. Up to 3 digits are shown bare; 4..6 as "(AAA) E.."; 7..10 as "(AAA) EEE-S...". The result is stripped of surrounding spaces.

Why this case matters

Input masks re-render on every keystroke; premature punctuation or a lost prefix makes the caret jump and corrupts what users type.

1 / The failure

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

N = 1
observations = []
def solve(x):
    d = x
    prefix = ''
    if d.startswith('1'):
        prefix, d = '1 ', d[1:]
    if len(d) > 10:
        return x
    if len(d) < 3:
        body = d
    elif len(d) <= 6:
        body = '(' + d[:3] + ') ' + d[3:]
    else:
        body = '(' + d[:3] + ') ' + d[3:6] + '-' + d[6:]
    return (prefix + body).strip()
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['first digit', '5', '5'], ['three digits stay bare', '555', '555'], ['fourth digit opens the area', '5550', '(555) 0'], ['six digits without hyphen', '555011', '(555) 011'], ['seventh digit adds the hyphen', '5550113', '(555) 011-3'], ['complete number', '5550113456', '(555) 011-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1555', '1 555'], ['national prefix with full number', '15550113456', '1 (555) 011-3456'], ['too many digits after the prefix', '155501134561', '155501134561'], ['too many digits without prefix', '55501134561', '55501134561']], [['first digit', '6', '6'], ['three digits stay bare', '655', '655'], ['fourth digit opens the area', '6550', '(655) 0'], ['six digits without hyphen', '655012', '(655) 012'], ['seventh digit adds the hyphen', '6550123', '(655) 012-3'], ['complete number', '6550123456', '(655) 012-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1655', '1 655'], ['national prefix with full number', '16550123456', '1 (655) 012-3456'], ['too many digits after the prefix', '165501234562', '165501234562'], ['too many digits without prefix', '65501234562', '65501234562']], [['first digit', '7', '7'], ['three digits stay bare', '755', '755'], ['fourth digit opens the area', '7550', '(755) 0'], ['six digits without hyphen', '755013', '(755) 013'], ['seventh digit adds the hyphen', '7550133', '(755) 013-3'], ['complete number', '7550133456', '(755) 013-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1755', '1 755'], ['national prefix with full number', '17550133456', '1 (755) 013-3456'], ['too many digits after the prefix', '175501334563', '175501334563'], ['too many digits without prefix', '75501334563', '75501334563']], [['first digit', '8', '8'], ['three digits stay bare', '855', '855'], ['fourth digit opens the area', '8550', '(855) 0'], ['six digits without hyphen', '855014', '(855) 014'], ['seventh digit adds the hyphen', '8550143', '(855) 014-3'], ['complete number', '8550143456', '(855) 014-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1855', '1 855'], ['national prefix with full number', '18550143456', '1 (855) 014-3456'], ['too many digits after the prefix', '185501434564', '185501434564'], ['too many digits without prefix', '85501434564', '85501434564']], [['first digit', '9', '9'], ['three digits stay bare', '955', '955'], ['fourth digit opens the area', '9550', '(955) 0'], ['six digits without hyphen', '955015', '(955) 015'], ['seventh digit adds the hyphen', '9550153', '(955) 015-3'], ['complete number', '9550153456', '(955) 015-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1955', '1 955'], ['national prefix with full number', '19550153456', '1 (955) 015-3456'], ['too many digits after the prefix', '195501534565', '195501534565'], ['too many digits without prefix', '95501534565', '95501534565']]]
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
first digit55Passed
three digits stay bare(555)555Failed
fourth digit opens the area(555) 0(555) 0Passed
six digits without hyphen(555) 011(555) 011Passed
seventh digit adds the hyphen(555) 011-3(555) 011-3Passed
complete number(555) 011-3456(555) 011-3456Passed
lone national prefix11Passed
national prefix with three digits1 (555)1 555Failed
national prefix with full number1 (555) 011-34561 (555) 011-3456Passed
too many digits after the prefix155501134561155501134561Passed
too many digits without prefix5550113456155501134561Passed

SHA-256 / 9299a4323c0cc621f8e7c5df2225ccdb5bcee8b27cd9c4c0b22436ca1be9fd32

2 / The unsuccessful fix

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

N = 1
observations = []
def solve(x):
    d = x
    prefix = ''
    if d.startswith('1'):
        prefix, d = '1 ', d[1:]
    if len(d) > 10:
        return x
    if len(d) <= 4:
        body = d
    elif len(d) <= 6:
        body = '(' + d[:3] + ') ' + d[3:]
    else:
        body = '(' + d[:3] + ') ' + d[3:6] + '-' + d[6:]
    return (prefix + body).strip()
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['first digit', '5', '5'], ['three digits stay bare', '555', '555'], ['fourth digit opens the area', '5550', '(555) 0'], ['six digits without hyphen', '555011', '(555) 011'], ['seventh digit adds the hyphen', '5550113', '(555) 011-3'], ['complete number', '5550113456', '(555) 011-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1555', '1 555'], ['national prefix with full number', '15550113456', '1 (555) 011-3456'], ['too many digits after the prefix', '155501134561', '155501134561'], ['too many digits without prefix', '55501134561', '55501134561']], [['first digit', '6', '6'], ['three digits stay bare', '655', '655'], ['fourth digit opens the area', '6550', '(655) 0'], ['six digits without hyphen', '655012', '(655) 012'], ['seventh digit adds the hyphen', '6550123', '(655) 012-3'], ['complete number', '6550123456', '(655) 012-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1655', '1 655'], ['national prefix with full number', '16550123456', '1 (655) 012-3456'], ['too many digits after the prefix', '165501234562', '165501234562'], ['too many digits without prefix', '65501234562', '65501234562']], [['first digit', '7', '7'], ['three digits stay bare', '755', '755'], ['fourth digit opens the area', '7550', '(755) 0'], ['six digits without hyphen', '755013', '(755) 013'], ['seventh digit adds the hyphen', '7550133', '(755) 013-3'], ['complete number', '7550133456', '(755) 013-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1755', '1 755'], ['national prefix with full number', '17550133456', '1 (755) 013-3456'], ['too many digits after the prefix', '175501334563', '175501334563'], ['too many digits without prefix', '75501334563', '75501334563']], [['first digit', '8', '8'], ['three digits stay bare', '855', '855'], ['fourth digit opens the area', '8550', '(855) 0'], ['six digits without hyphen', '855014', '(855) 014'], ['seventh digit adds the hyphen', '8550143', '(855) 014-3'], ['complete number', '8550143456', '(855) 014-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1855', '1 855'], ['national prefix with full number', '18550143456', '1 (855) 014-3456'], ['too many digits after the prefix', '185501434564', '185501434564'], ['too many digits without prefix', '85501434564', '85501434564']], [['first digit', '9', '9'], ['three digits stay bare', '955', '955'], ['fourth digit opens the area', '9550', '(955) 0'], ['six digits without hyphen', '955015', '(955) 015'], ['seventh digit adds the hyphen', '9550153', '(955) 015-3'], ['complete number', '9550153456', '(955) 015-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1955', '1 955'], ['national prefix with full number', '19550153456', '1 (955) 015-3456'], ['too many digits after the prefix', '195501534565', '195501534565'], ['too many digits without prefix', '95501534565', '95501534565']]]
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
first digit55Passed
three digits stay bare555555Passed
fourth digit opens the area5550(555) 0Failed
six digits without hyphen(555) 011(555) 011Passed
seventh digit adds the hyphen(555) 011-3(555) 011-3Passed
complete number(555) 011-3456(555) 011-3456Passed
lone national prefix11Passed
national prefix with three digits1 5551 555Passed
national prefix with full number1 (555) 011-34561 (555) 011-3456Passed
too many digits after the prefix155501134561155501134561Passed
too many digits without prefix5550113456155501134561Passed

SHA-256 / 00c9fd50682e4cc2876d9e2ec3e079c47db17e019fc78abdacef1f5e1c03350b

3 / The verified repair

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

N = 1
observations = []
def solve(x):
    d = x
    prefix = ''
    if d.startswith('1'):
        prefix, d = '1 ', d[1:]
    if len(d) > 10:
        return x
    if len(d) <= 3:
        body = d
    elif len(d) <= 6:
        body = '(' + d[:3] + ') ' + d[3:]
    else:
        body = '(' + d[:3] + ') ' + d[3:6] + '-' + d[6:]
    return (prefix + body).strip()
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['first digit', '5', '5'], ['three digits stay bare', '555', '555'], ['fourth digit opens the area', '5550', '(555) 0'], ['six digits without hyphen', '555011', '(555) 011'], ['seventh digit adds the hyphen', '5550113', '(555) 011-3'], ['complete number', '5550113456', '(555) 011-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1555', '1 555'], ['national prefix with full number', '15550113456', '1 (555) 011-3456'], ['too many digits after the prefix', '155501134561', '155501134561'], ['too many digits without prefix', '55501134561', '55501134561']], [['first digit', '6', '6'], ['three digits stay bare', '655', '655'], ['fourth digit opens the area', '6550', '(655) 0'], ['six digits without hyphen', '655012', '(655) 012'], ['seventh digit adds the hyphen', '6550123', '(655) 012-3'], ['complete number', '6550123456', '(655) 012-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1655', '1 655'], ['national prefix with full number', '16550123456', '1 (655) 012-3456'], ['too many digits after the prefix', '165501234562', '165501234562'], ['too many digits without prefix', '65501234562', '65501234562']], [['first digit', '7', '7'], ['three digits stay bare', '755', '755'], ['fourth digit opens the area', '7550', '(755) 0'], ['six digits without hyphen', '755013', '(755) 013'], ['seventh digit adds the hyphen', '7550133', '(755) 013-3'], ['complete number', '7550133456', '(755) 013-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1755', '1 755'], ['national prefix with full number', '17550133456', '1 (755) 013-3456'], ['too many digits after the prefix', '175501334563', '175501334563'], ['too many digits without prefix', '75501334563', '75501334563']], [['first digit', '8', '8'], ['three digits stay bare', '855', '855'], ['fourth digit opens the area', '8550', '(855) 0'], ['six digits without hyphen', '855014', '(855) 014'], ['seventh digit adds the hyphen', '8550143', '(855) 014-3'], ['complete number', '8550143456', '(855) 014-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1855', '1 855'], ['national prefix with full number', '18550143456', '1 (855) 014-3456'], ['too many digits after the prefix', '185501434564', '185501434564'], ['too many digits without prefix', '85501434564', '85501434564']], [['first digit', '9', '9'], ['three digits stay bare', '955', '955'], ['fourth digit opens the area', '9550', '(955) 0'], ['six digits without hyphen', '955015', '(955) 015'], ['seventh digit adds the hyphen', '9550153', '(955) 015-3'], ['complete number', '9550153456', '(955) 015-3456'], ['lone national prefix', '1', '1'], ['national prefix with three digits', '1955', '1 955'], ['national prefix with full number', '19550153456', '1 (955) 015-3456'], ['too many digits after the prefix', '195501534565', '195501534565'], ['too many digits without prefix', '95501534565', '95501534565']]]
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
first digit55Passed
three digits stay bare555555Passed
fourth digit opens the area(555) 0(555) 0Passed
six digits without hyphen(555) 011(555) 011Passed
seventh digit adds the hyphen(555) 011-3(555) 011-3Passed
complete number(555) 011-3456(555) 011-3456Passed
lone national prefix11Passed
national prefix with three digits1 5551 555Passed
national prefix with full number1 (555) 011-34561 (555) 011-3456Passed
too many digits after the prefix155501134561155501134561Passed
too many digits without prefix5550113456155501134561Passed

SHA-256 / ac6622f773a2e9947f491bbfc7a69c3c2dc6bb870ce0daad0980f363b70853e0

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:23.835545+00:00.

Case digest / 4b95212cb6110e719731a71e49e78dd25a4def4322384910bc0edc74049b74f0