{"abstract":"Fewer than four digits are revealed when the number contains separators.","category":"Phone number formatting","checks":7,"contract":"Strip. A leading \"+\" and the digits right after it (the country code) are shown. Among the remaining digits only the last four are shown and the others become \"*\"; separators are kept. If four or fewer digits remain they are all masked.","evaluation_group":"w2-phone-number-formatting-display-mask","failed_approach":"Excluding spaces from the length still counts hyphens.","family":"w2-phone-number-formatting-display-mask-digit-count","id":"FA-96496","implementations":{"attempt":{"sha256":"b79a7e1f2796ebc3ed12560241ba6c392fc86352325a8a49360a09f16ce2a56e","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    cc_end = 0\n    if s.startswith('+'):\n        cc_end = 1\n        while cc_end < len(s) and s[cc_end].isdigit():\n            cc_end += 1\n    head, body = s[:cc_end], s[cc_end:]\n    total = len(body.replace(' ', ''))\n    if total <= 4:\n        return head + ''.join('*' if c.isdigit() else c for c in body)\n    seen, out = 0, []\n    for c in body:\n        if c.isdigit():\n            seen += 1\n            out.append(c if seen > total - 4 else '*')\n        else:\n            out.append(c)\n    return head + ''.join(out)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['international with country code kept', '+42 555 010 1123', '+42 *** *** 1123'], ['three-digit code with hyphen', '+891 555-0114', '+891 ***-0114'], ['four subscriber digits are fully masked', '+8 1122', '+8 ****'], ['five subscriber digits', '+83 11123', '+83 *1123'], ['national number without code', '555 0115', '*** 0115'], ['parenthesized area', '+42 (555) 0112', '+42 (***) 0112'], ['hyphenated national number', '555-010-1122', '***-***-1122']], [['international with country code kept', '+42 555 010 1234', '+42 *** *** 1234'], ['three-digit code with hyphen', '+891 555-0125', '+891 ***-0125'], ['four subscriber digits are fully masked', '+8 2233', '+8 ****'], ['five subscriber digits', '+83 22234', '+83 *2234'], ['national number without code', '555 0126', '*** 0126'], ['parenthesized area', '+42 (555) 0123', '+42 (***) 0123'], ['hyphenated national number', '555-010-2233', '***-***-2233']], [['international with country code kept', '+42 555 010 1345', '+42 *** *** 1345'], ['three-digit code with hyphen', '+891 555-0136', '+891 ***-0136'], ['four subscriber digits are fully masked', '+8 3344', '+8 ****'], ['five subscriber digits', '+83 33345', '+83 *3345'], ['national number without code', '555 0137', '*** 0137'], ['parenthesized area', '+42 (555) 0134', '+42 (***) 0134'], ['hyphenated national number', '555-010-3344', '***-***-3344']], [['international with country code kept', '+42 555 010 1456', '+42 *** *** 1456'], ['three-digit code with hyphen', '+891 555-0147', '+891 ***-0147'], ['four subscriber digits are fully masked', '+8 4455', '+8 ****'], ['five subscriber digits', '+83 44456', '+83 *4456'], ['national number without code', '555 0148', '*** 0148'], ['parenthesized area', '+42 (555) 0145', '+42 (***) 0145'], ['hyphenated national number', '555-010-4455', '***-***-4455']], [['international with country code kept', '+42 555 010 1567', '+42 *** *** 1567'], ['three-digit code with hyphen', '+891 555-0158', '+891 ***-0158'], ['four subscriber digits are fully masked', '+8 5566', '+8 ****'], ['five subscriber digits', '+83 55567', '+83 *5567'], ['national number without code', '555 0159', '*** 0159'], ['parenthesized area', '+42 (555) 0156', '+42 (***) 0156'], ['hyphenated national number', '555-010-5566', '***-***-5566']]]\nfor label, arg, expected in fixtures[N - 1]:\n    check(label, solve(arg), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"a0c0a89e695feae5a3f9e33537ad68429b6fce6e57fc06567bda1d09b788eaef","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    cc_end = 0\n    if s.startswith('+'):\n        cc_end = 1\n        while cc_end < len(s) and s[cc_end].isdigit():\n            cc_end += 1\n    head, body = s[:cc_end], s[cc_end:]\n    total = len(body)\n    if total <= 4:\n        return head + ''.join('*' if c.isdigit() else c for c in body)\n    seen, out = 0, []\n    for c in body:\n        if c.isdigit():\n            seen += 1\n            out.append(c if seen > total - 4 else '*')\n        else:\n            out.append(c)\n    return head + ''.join(out)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['international with country code kept', '+42 555 010 1123', '+42 *** *** 1123'], ['three-digit code with hyphen', '+891 555-0114', '+891 ***-0114'], ['four subscriber digits are fully masked', '+8 1122', '+8 ****'], ['five subscriber digits', '+83 11123', '+83 *1123'], ['national number without code', '555 0115', '*** 0115'], ['parenthesized area', '+42 (555) 0112', '+42 (***) 0112'], ['hyphenated national number', '555-010-1122', '***-***-1122']], [['international with country code kept', '+42 555 010 1234', '+42 *** *** 1234'], ['three-digit code with hyphen', '+891 555-0125', '+891 ***-0125'], ['four subscriber digits are fully masked', '+8 2233', '+8 ****'], ['five subscriber digits', '+83 22234', '+83 *2234'], ['national number without code', '555 0126', '*** 0126'], ['parenthesized area', '+42 (555) 0123', '+42 (***) 0123'], ['hyphenated national number', '555-010-2233', '***-***-2233']], [['international with country code kept', '+42 555 010 1345', '+42 *** *** 1345'], ['three-digit code with hyphen', '+891 555-0136', '+891 ***-0136'], ['four subscriber digits are fully masked', '+8 3344', '+8 ****'], ['five subscriber digits', '+83 33345', '+83 *3345'], ['national number without code', '555 0137', '*** 0137'], ['parenthesized area', '+42 (555) 0134', '+42 (***) 0134'], ['hyphenated national number', '555-010-3344', '***-***-3344']], [['international with country code kept', '+42 555 010 1456', '+42 *** *** 1456'], ['three-digit code with hyphen', '+891 555-0147', '+891 ***-0147'], ['four subscriber digits are fully masked', '+8 4455', '+8 ****'], ['five subscriber digits', '+83 44456', '+83 *4456'], ['national number without code', '555 0148', '*** 0148'], ['parenthesized area', '+42 (555) 0145', '+42 (***) 0145'], ['hyphenated national number', '555-010-4455', '***-***-4455']], [['international with country code kept', '+42 555 010 1567', '+42 *** *** 1567'], ['three-digit code with hyphen', '+891 555-0158', '+891 ***-0158'], ['four subscriber digits are fully masked', '+8 5566', '+8 ****'], ['five subscriber digits', '+83 55567', '+83 *5567'], ['national number without code', '555 0159', '*** 0159'], ['parenthesized area', '+42 (555) 0156', '+42 (***) 0156'], ['hyphenated national number', '555-010-5566', '***-***-5566']]]\nfor label, arg, expected in fixtures[N - 1]:\n    check(label, solve(arg), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"f8332f5b881a35f77f502d796816059ee631605638760dc1e3a779d9558f24c4","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(x):\n    s = x.strip()\n    cc_end = 0\n    if s.startswith('+'):\n        cc_end = 1\n        while cc_end < len(s) and s[cc_end].isdigit():\n            cc_end += 1\n    head, body = s[:cc_end], s[cc_end:]\n    total = sum(c.isdigit() for c in body)\n    if total <= 4:\n        return head + ''.join('*' if c.isdigit() else c for c in body)\n    seen, out = 0, []\n    for c in body:\n        if c.isdigit():\n            seen += 1\n            out.append(c if seen > total - 4 else '*')\n        else:\n            out.append(c)\n    return head + ''.join(out)\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['international with country code kept', '+42 555 010 1123', '+42 *** *** 1123'], ['three-digit code with hyphen', '+891 555-0114', '+891 ***-0114'], ['four subscriber digits are fully masked', '+8 1122', '+8 ****'], ['five subscriber digits', '+83 11123', '+83 *1123'], ['national number without code', '555 0115', '*** 0115'], ['parenthesized area', '+42 (555) 0112', '+42 (***) 0112'], ['hyphenated national number', '555-010-1122', '***-***-1122']], [['international with country code kept', '+42 555 010 1234', '+42 *** *** 1234'], ['three-digit code with hyphen', '+891 555-0125', '+891 ***-0125'], ['four subscriber digits are fully masked', '+8 2233', '+8 ****'], ['five subscriber digits', '+83 22234', '+83 *2234'], ['national number without code', '555 0126', '*** 0126'], ['parenthesized area', '+42 (555) 0123', '+42 (***) 0123'], ['hyphenated national number', '555-010-2233', '***-***-2233']], [['international with country code kept', '+42 555 010 1345', '+42 *** *** 1345'], ['three-digit code with hyphen', '+891 555-0136', '+891 ***-0136'], ['four subscriber digits are fully masked', '+8 3344', '+8 ****'], ['five subscriber digits', '+83 33345', '+83 *3345'], ['national number without code', '555 0137', '*** 0137'], ['parenthesized area', '+42 (555) 0134', '+42 (***) 0134'], ['hyphenated national number', '555-010-3344', '***-***-3344']], [['international with country code kept', '+42 555 010 1456', '+42 *** *** 1456'], ['three-digit code with hyphen', '+891 555-0147', '+891 ***-0147'], ['four subscriber digits are fully masked', '+8 4455', '+8 ****'], ['five subscriber digits', '+83 44456', '+83 *4456'], ['national number without code', '555 0148', '*** 0148'], ['parenthesized area', '+42 (555) 0145', '+42 (***) 0145'], ['hyphenated national number', '555-010-4455', '***-***-4455']], [['international with country code kept', '+42 555 010 1567', '+42 *** *** 1567'], ['three-digit code with hyphen', '+891 555-0158', '+891 ***-0158'], ['four subscriber digits are fully masked', '+8 5566', '+8 ****'], ['five subscriber digits', '+83 55567', '+83 *5567'], ['national number without code', '555 0159', '*** 0159'], ['parenthesized area', '+42 (555) 0156', '+42 (***) 0156'], ['hyphenated national number', '555-010-5566', '***-***-5566']]]\nfor label, arg, expected in fixtures[N - 1]:\n    check(label, solve(arg), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"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.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-phone-number-formatting-display-mask-digit-count","generated_at":"2026-09-29T14:52:23.240204+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Masked numbers appear in receipts, logs and support tools; revealing too much leaks personal data and revealing too little makes verification impossible.","repair":"Count only digits.","root_cause":"The total is the body length rather than its digit count.","sha256":"a6446c579f6bf6da44ccbff03ec3b28ca977c8f2ba2bb32a06682768edb2e9f8","title":"Display masking of subscriber digits: separators are counted as digits · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.401,"exit_code":1,"observations":[{"actual":"+42 *** *** 1123","check":"international with country code kept","expected":"+42 *** *** 1123","passed":true},{"actual":"+891 ***-*114","check":"three-digit code with hyphen","expected":"+891 ***-0114","passed":false},{"actual":"+8 ****","check":"four subscriber digits are fully masked","expected":"+8 ****","passed":true},{"actual":"+83 *1123","check":"five subscriber digits","expected":"+83 *1123","passed":true},{"actual":"*** 0115","check":"national number without code","expected":"*** 0115","passed":true},{"actual":"+42 (***) **12","check":"parenthesized area","expected":"+42 (***) 0112","passed":false},{"actual":"***-***-**22","check":"hyphenated national number","expected":"***-***-1122","passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"international with country code kept\", \"actual\": \"+42 *** *** 1123\", \"expected\": \"+42 *** *** 1123\", \"passed\": true}, {\"check\": \"three-digit code with hyphen\", \"actual\": \"+891 ***-*114\", \"expected\": \"+891 ***-0114\", \"passed\": false}, {\"check\": \"four subscriber digits are fully masked\", \"actual\": \"+8 ****\", \"expected\": \"+8 ****\", \"passed\": true}, {\"check\": \"five subscriber digits\", \"actual\": \"+83 *1123\", \"expected\": \"+83 *1123\", \"passed\": true}, {\"check\": \"national number without code\", \"actual\": \"*** 0115\", \"expected\": \"*** 0115\", \"passed\": true}, {\"check\": \"parenthesized area\", \"actual\": \"+42 (***) **12\", \"expected\": \"+42 (***) 0112\", \"passed\": false}, {\"check\": \"hyphenated national number\", \"actual\": \"***-***-**22\", \"expected\": \"***-***-1122\", \"passed\": false}], \"passed\": false}\n"},"broken":{"elapsed_ms":38.695,"exit_code":1,"observations":[{"actual":"+42 *** *** ***3","check":"international with country code kept","expected":"+42 *** *** 1123","passed":false},{"actual":"+891 ***-**14","check":"three-digit code with hyphen","expected":"+891 ***-0114","passed":false},{"actual":"+8 *122","check":"four subscriber digits are fully masked","expected":"+8 ****","passed":false},{"actual":"+83 **123","check":"five subscriber digits","expected":"+83 *1123","passed":false},{"actual":"*** *115","check":"national number without code","expected":"*** 0115","passed":false},{"actual":"+42 (***) ****","check":"parenthesized area","expected":"+42 (***) 0112","passed":false},{"actual":"***-***-**22","check":"hyphenated national number","expected":"***-***-1122","passed":false}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"international with country code kept\", \"actual\": \"+42 *** *** ***3\", \"expected\": \"+42 *** *** 1123\", \"passed\": false}, {\"check\": \"three-digit code with hyphen\", \"actual\": \"+891 ***-**14\", \"expected\": \"+891 ***-0114\", \"passed\": false}, {\"check\": \"four subscriber digits are fully masked\", \"actual\": \"+8 *122\", \"expected\": \"+8 ****\", \"passed\": false}, {\"check\": \"five subscriber digits\", \"actual\": \"+83 **123\", \"expected\": \"+83 *1123\", \"passed\": false}, {\"check\": \"national number without code\", \"actual\": \"*** *115\", \"expected\": \"*** 0115\", \"passed\": false}, {\"check\": \"parenthesized area\", \"actual\": \"+42 (***) ****\", \"expected\": \"+42 (***) 0112\", \"passed\": false}, {\"check\": \"hyphenated national number\", \"actual\": \"***-***-**22\", \"expected\": \"***-***-1122\", \"passed\": false}], \"passed\": false}\n"},"fixed":{"elapsed_ms":39.892,"exit_code":0,"observations":[{"actual":"+42 *** *** 1123","check":"international with country code kept","expected":"+42 *** *** 1123","passed":true},{"actual":"+891 ***-0114","check":"three-digit code with hyphen","expected":"+891 ***-0114","passed":true},{"actual":"+8 ****","check":"four subscriber digits are fully masked","expected":"+8 ****","passed":true},{"actual":"+83 *1123","check":"five subscriber digits","expected":"+83 *1123","passed":true},{"actual":"*** 0115","check":"national number without code","expected":"*** 0115","passed":true},{"actual":"+42 (***) 0112","check":"parenthesized area","expected":"+42 (***) 0112","passed":true},{"actual":"***-***-1122","check":"hyphenated national number","expected":"***-***-1122","passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"international with country code kept\", \"actual\": \"+42 *** *** 1123\", \"expected\": \"+42 *** *** 1123\", \"passed\": true}, {\"check\": \"three-digit code with hyphen\", \"actual\": \"+891 ***-0114\", \"expected\": \"+891 ***-0114\", \"passed\": true}, {\"check\": \"four subscriber digits are fully masked\", \"actual\": \"+8 ****\", \"expected\": \"+8 ****\", \"passed\": true}, {\"check\": \"five subscriber digits\", \"actual\": \"+83 *1123\", \"expected\": \"+83 *1123\", \"passed\": true}, {\"check\": \"national number without code\", \"actual\": \"*** 0115\", \"expected\": \"*** 0115\", \"passed\": true}, {\"check\": \"parenthesized area\", \"actual\": \"+42 (***) 0112\", \"expected\": \"+42 (***) 0112\", \"passed\": true}, {\"check\": \"hyphenated national number\", \"actual\": \"***-***-1122\", \"expected\": \"***-***-1122\", \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}