FA-96381 / Phone number formatting / Open access
E.164 parser with trunk prefixes: national numbers without the trunk are silently shortened · case 01
A ten-digit AA number without its trunk loses its first digit and is accepted.
ROOT CAUSE
The first digit is dropped as if it were the trunk without checking it.
THE FAILURE
The first digit is dropped as if it were the trunk without checking it.
Unsuccessful approach: Making the trunk optional accepts a nine-digit number typed without it.
Case contract
Input [number, default region]. Toy table (cc, trunk, national lengths): DD 8/-/9, AA 42/0/9, BB 83/8/10, CC 891/-/7-8. Remove "(0)" and keep digits. A leading "+" or "00" means international: drop "00", pick the country with the longest matching code. Otherwise the region is used and a national number of a trunk country must start with its trunk, which is removed once. The national part must have an allowed length. Return "+" cc national or None.
Why this case matters
Canonical E.164 storage is the join key for calls, messaging and deduplication; one wrong prefix rule routes numbers to another country.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
num, region = x
TABLE = {'DD': ('8', '', (9,)), 'AA': ('42', '0', (9,)), 'BB': ('83', '8', (10,)), 'CC': ('891', '', (7, 8))}
s = num.strip().replace('(0)', '')
raw = ''.join(c for c in s if c.isdigit())
if s.startswith('+') or raw.startswith('00'):
if not s.startswith('+'):
raw = raw[2:]
best = None
for code, (cc, trunk, lens) in TABLE.items():
if raw.startswith(cc) and (best is None or len(cc) > len(TABLE[best][0])):
best = code
if best is None:
return None
cc, trunk, lens = TABLE[best]
nat = raw[len(cc):]
else:
if region not in TABLE:
return None
cc, trunk, lens = TABLE[region]
if trunk:
raw = raw[len(trunk):]
nat = raw
if len(nat) not in lens:
return None
return '+' + cc + nat
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['national with trunk zero', ['0555011234', 'AA'], '+42555011234'], ['national missing its trunk', ['555011234', 'AA'], None], ['ten digits without trunk', ['5555011234', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550111', 'BB'], '+838125550111'], ['international two-digit code', ['+83 8125550111', 'AA'], '+838125550111'], ['double-zero international prefix', ['0083 8125550111', 'CC'], '+838125550111'], ['parenthesized trunk in international form', ['+42 (0)555011234', 'BB'], '+42555011234'], ['one-digit country code', ['+8 555011223', 'AA'], '+8555011223'], ['three-digit country code', ['+891 5550113', 'BB'], '+8915550113'], ['international with wrong length', ['+83 555011234', 'AA'], None], ['national without trunk country', ['5550113', 'CC'], '+8915550113']], [['national with trunk zero', ['0555012345', 'AA'], '+42555012345'], ['national missing its trunk', ['555012345', 'AA'], None], ['ten digits without trunk', ['5555012345', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550122', 'BB'], '+838125550122'], ['international two-digit code', ['+83 8125550122', 'AA'], '+838125550122'], ['double-zero international prefix', ['0083 8125550122', 'CC'], '+838125550122'], ['parenthesized trunk in international form', ['+42 (0)555012345', 'BB'], '+42555012345'], ['one-digit country code', ['+8 555022334', 'AA'], '+8555022334'], ['three-digit country code', ['+891 5550124', 'BB'], '+8915550124'], ['international with wrong length', ['+83 555012345', 'AA'], None], ['national without trunk country', ['5550124', 'CC'], '+8915550124']], [['national with trunk zero', ['0555013456', 'AA'], '+42555013456'], ['national missing its trunk', ['555013456', 'AA'], None], ['ten digits without trunk', ['5555013456', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550133', 'BB'], '+838125550133'], ['international two-digit code', ['+83 8125550133', 'AA'], '+838125550133'], ['double-zero international prefix', ['0083 8125550133', 'CC'], '+838125550133'], ['parenthesized trunk in international form', ['+42 (0)555013456', 'BB'], '+42555013456'], ['one-digit country code', ['+8 555033445', 'AA'], '+8555033445'], ['three-digit country code', ['+891 5550135', 'BB'], '+8915550135'], ['international with wrong length', ['+83 555013456', 'AA'], None], ['national without trunk country', ['5550135', 'CC'], '+8915550135']], [['national with trunk zero', ['0555014567', 'AA'], '+42555014567'], ['national missing its trunk', ['555014567', 'AA'], None], ['ten digits without trunk', ['5555014567', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550144', 'BB'], '+838125550144'], ['international two-digit code', ['+83 8125550144', 'AA'], '+838125550144'], ['double-zero international prefix', ['0083 8125550144', 'CC'], '+838125550144'], ['parenthesized trunk in international form', ['+42 (0)555014567', 'BB'], '+42555014567'], ['one-digit country code', ['+8 555044556', 'AA'], '+8555044556'], ['three-digit country code', ['+891 5550146', 'BB'], '+8915550146'], ['international with wrong length', ['+83 555014567', 'AA'], None], ['national without trunk country', ['5550146', 'CC'], '+8915550146']], [['national with trunk zero', ['0555015678', 'AA'], '+42555015678'], ['national missing its trunk', ['555015678', 'AA'], None], ['ten digits without trunk', ['5555015678', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550155', 'BB'], '+838125550155'], ['international two-digit code', ['+83 8125550155', 'AA'], '+838125550155'], ['double-zero international prefix', ['0083 8125550155', 'CC'], '+838125550155'], ['parenthesized trunk in international form', ['+42 (0)555015678', 'BB'], '+42555015678'], ['one-digit country code', ['+8 555055667', 'AA'], '+8555055667'], ['three-digit country code', ['+891 5550157', 'BB'], '+8915550157'], ['international with wrong length', ['+83 555015678', 'AA'], None], ['national without trunk country', ['5550157', 'CC'], '+8915550157']]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| national with trunk zero | +42555011234 | +42555011234 | Passed |
| national missing its trunk | None | None | Passed |
| ten digits without trunk | +42555011234 | None | Failed |
| national whose number repeats the trunk digit | +838125550111 | +838125550111 | Passed |
| international two-digit code | +838125550111 | +838125550111 | Passed |
| double-zero international prefix | +838125550111 | +838125550111 | Passed |
| parenthesized trunk in international form | +42555011234 | +42555011234 | Passed |
| one-digit country code | +8555011223 | +8555011223 | Passed |
| three-digit country code | +8915550113 | +8915550113 | Passed |
| international with wrong length | None | None | Passed |
| national without trunk country | +8915550113 | +8915550113 | Passed |
SHA-256 / 37b34962c38a24de864192ebb9fde2cb56c4977254c6e8b225c2598b948c475d
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
N = 1
observations = []
def solve(x):
num, region = x
TABLE = {'DD': ('8', '', (9,)), 'AA': ('42', '0', (9,)), 'BB': ('83', '8', (10,)), 'CC': ('891', '', (7, 8))}
s = num.strip().replace('(0)', '')
raw = ''.join(c for c in s if c.isdigit())
if s.startswith('+') or raw.startswith('00'):
if not s.startswith('+'):
raw = raw[2:]
best = None
for code, (cc, trunk, lens) in TABLE.items():
if raw.startswith(cc) and (best is None or len(cc) > len(TABLE[best][0])):
best = code
if best is None:
return None
cc, trunk, lens = TABLE[best]
nat = raw[len(cc):]
else:
if region not in TABLE:
return None
cc, trunk, lens = TABLE[region]
if trunk:
if raw.startswith(trunk):
raw = raw[len(trunk):]
nat = raw
if len(nat) not in lens:
return None
return '+' + cc + nat
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[['national with trunk zero', ['0555011234', 'AA'], '+42555011234'], ['national missing its trunk', ['555011234', 'AA'], None], ['ten digits without trunk', ['5555011234', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550111', 'BB'], '+838125550111'], ['international two-digit code', ['+83 8125550111', 'AA'], '+838125550111'], ['double-zero international prefix', ['0083 8125550111', 'CC'], '+838125550111'], ['parenthesized trunk in international form', ['+42 (0)555011234', 'BB'], '+42555011234'], ['one-digit country code', ['+8 555011223', 'AA'], '+8555011223'], ['three-digit country code', ['+891 5550113', 'BB'], '+8915550113'], ['international with wrong length', ['+83 555011234', 'AA'], None], ['national without trunk country', ['5550113', 'CC'], '+8915550113']], [['national with trunk zero', ['0555012345', 'AA'], '+42555012345'], ['national missing its trunk', ['555012345', 'AA'], None], ['ten digits without trunk', ['5555012345', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550122', 'BB'], '+838125550122'], ['international two-digit code', ['+83 8125550122', 'AA'], '+838125550122'], ['double-zero international prefix', ['0083 8125550122', 'CC'], '+838125550122'], ['parenthesized trunk in international form', ['+42 (0)555012345', 'BB'], '+42555012345'], ['one-digit country code', ['+8 555022334', 'AA'], '+8555022334'], ['three-digit country code', ['+891 5550124', 'BB'], '+8915550124'], ['international with wrong length', ['+83 555012345', 'AA'], None], ['national without trunk country', ['5550124', 'CC'], '+8915550124']], [['national with trunk zero', ['0555013456', 'AA'], '+42555013456'], ['national missing its trunk', ['555013456', 'AA'], None], ['ten digits without trunk', ['5555013456', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550133', 'BB'], '+838125550133'], ['international two-digit code', ['+83 8125550133', 'AA'], '+838125550133'], ['double-zero international prefix', ['0083 8125550133', 'CC'], '+838125550133'], ['parenthesized trunk in international form', ['+42 (0)555013456', 'BB'], '+42555013456'], ['one-digit country code', ['+8 555033445', 'AA'], '+8555033445'], ['three-digit country code', ['+891 5550135', 'BB'], '+8915550135'], ['international with wrong length', ['+83 555013456', 'AA'], None], ['national without trunk country', ['5550135', 'CC'], '+8915550135']], [['national with trunk zero', ['0555014567', 'AA'], '+42555014567'], ['national missing its trunk', ['555014567', 'AA'], None], ['ten digits without trunk', ['5555014567', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550144', 'BB'], '+838125550144'], ['international two-digit code', ['+83 8125550144', 'AA'], '+838125550144'], ['double-zero international prefix', ['0083 8125550144', 'CC'], '+838125550144'], ['parenthesized trunk in international form', ['+42 (0)555014567', 'BB'], '+42555014567'], ['one-digit country code', ['+8 555044556', 'AA'], '+8555044556'], ['three-digit country code', ['+891 5550146', 'BB'], '+8915550146'], ['international with wrong length', ['+83 555014567', 'AA'], None], ['national without trunk country', ['5550146', 'CC'], '+8915550146']], [['national with trunk zero', ['0555015678', 'AA'], '+42555015678'], ['national missing its trunk', ['555015678', 'AA'], None], ['ten digits without trunk', ['5555015678', 'AA'], None], ['national whose number repeats the trunk digit', ['8 8125550155', 'BB'], '+838125550155'], ['international two-digit code', ['+83 8125550155', 'AA'], '+838125550155'], ['double-zero international prefix', ['0083 8125550155', 'CC'], '+838125550155'], ['parenthesized trunk in international form', ['+42 (0)555015678', 'BB'], '+42555015678'], ['one-digit country code', ['+8 555055667', 'AA'], '+8555055667'], ['three-digit country code', ['+891 5550157', 'BB'], '+8915550157'], ['international with wrong length', ['+83 555015678', 'AA'], None], ['national without trunk country', ['5550157', 'CC'], '+8915550157']]]
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| national with trunk zero | +42555011234 | +42555011234 | Passed |
| national missing its trunk | +42555011234 | None | Failed |
| ten digits without trunk | None | None | Passed |
| national whose number repeats the trunk digit | +838125550111 | +838125550111 | Passed |
| international two-digit code | +838125550111 | +838125550111 | Passed |
| double-zero international prefix | +838125550111 | +838125550111 | Passed |
| parenthesized trunk in international form | +42555011234 | +42555011234 | Passed |
| one-digit country code | +8555011223 | +8555011223 | Passed |
| three-digit country code | +8915550113 | +8915550113 | Passed |
| international with wrong length | None | None | Passed |
| national without trunk country | +8915550113 | +8915550113 | Passed |
SHA-256 / caea7c123449936a691191bdb3e30ba21e5fd790296c42d16410bb696a9cb1b0
HELD IN THE MEMBER ARCHIVE
The verified repair and its recorded checks are member-only.
This mechanism has 11 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.
Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.
Member access is invitation-based. Sign in with your invited account to inspect the repair.
Sign in to the archive ↗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:22.406985+00:00.
Case digest / 7b7a518b294231888f390edaba0fe83017f0cfa8acd04b2467aa8daaea0fa674