{"abstract":"Identifiers issued from 2000 onwards (T, G) get the wrong check letter.","category":"Check-digit algorithms","checks":8,"contract":"Singapore-style NRIC/FIN check letter for the S, T, F and G series: nine characters, series letter, seven digits, check letter (else \"malformed\"). Weights 2,7,6,5,4,3,2; add 4 for T and G; r = sum mod 11; the letter is \"JZIHGFEDCBA\"[r] for S/T and \"XWUTRQPNMLK\"[r] for F/G. Return [expected letter, match].","evaluation_group":"w2-check_digit_algorithms-sg-nric","failed_approach":"Adding the offset only for T still breaks G-series FINs.","family":"w2-check_digit_algorithms-sg-nric-series-offset","id":"FA-72781","implementations":{"attempt":{"sha256":"1ad057bb7918dfe34978936533941edbb02bf4fcfbed34326ac037680da1c550","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(s):\n    if len(s) != 9 or not s.isascii() or s[0] not in 'STFG' or not s[1:8].isdigit():\n        return 'malformed'\n    total = sum(int(ch) * w for ch, w in zip(s[1:8], [2, 7, 6, 5, 4, 3, 2]))\n    if s[0] == 'T':\n        total += 4\n    r = total % 11\n    table = 'JZIHGFEDCBA' if s[0] in 'ST' else 'XWUTRQPNMLK'\n    c = table[r]\n    return [c, s[8] == c]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['regression [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"F4595639V\"]', ['F4595639V'], ['M', False]], ['control [\"S3757569X\"]', ['S3757569X'], ['J', False]], ['control [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]]], [['regression [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['regression [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['partial-repair [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"F3876611S\"]', ['F3876611S'], ['L', False]], ['control [\"F9230492U\"]', ['F9230492U'], ['L', False]], ['control [\"F4160346W\"]', ['F4160346W'], ['K', False]], ['control [\"S1375256W\"]', ['S1375256W'], ['G', False]]], [['regression [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['regression [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['partial-repair [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S0978420O\"]', ['S0978420O'], ['I', False]], ['control [\"F5183813A\"]', ['F5183813A'], ['X', False]], ['control [\"S1234567D\"]', ['S1234567D'], ['D', True]], ['control [\"F1234567N\"]', ['F1234567N'], ['N', True]]], [['regression [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['regression [\"T1007654T\"]', ['T1007654T'], ['J', False]], ['partial-repair [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['partial-repair [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['control [\"M1234567K\"]', ['M1234567K'], 'malformed'], ['control [\"SA234567D\"]', ['SA234567D'], 'malformed'], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"F4595639V\"]', ['F4595639V'], ['M', False]]], [['regression [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['regression [\"T5563306D\"]', ['T5563306D'], ['H', False]], ['partial-repair [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['partial-repair [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"F3876611S\"]', ['F3876611S'], ['L', False]]]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), 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":"c86639d10c8601cf022c263711bb381fefef610943985647f63fdaa717c296d0","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(s):\n    if len(s) != 9 or not s.isascii() or s[0] not in 'STFG' or not s[1:8].isdigit():\n        return 'malformed'\n    total = sum(int(ch) * w for ch, w in zip(s[1:8], [2, 7, 6, 5, 4, 3, 2]))\n    r = total % 11\n    table = 'JZIHGFEDCBA' if s[0] in 'ST' else 'XWUTRQPNMLK'\n    c = table[r]\n    return [c, s[8] == c]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['regression [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"F4595639V\"]', ['F4595639V'], ['M', False]], ['control [\"S3757569X\"]', ['S3757569X'], ['J', False]], ['control [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]]], [['regression [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['regression [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['partial-repair [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"F3876611S\"]', ['F3876611S'], ['L', False]], ['control [\"F9230492U\"]', ['F9230492U'], ['L', False]], ['control [\"F4160346W\"]', ['F4160346W'], ['K', False]], ['control [\"S1375256W\"]', ['S1375256W'], ['G', False]]], [['regression [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['regression [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['partial-repair [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S0978420O\"]', ['S0978420O'], ['I', False]], ['control [\"F5183813A\"]', ['F5183813A'], ['X', False]], ['control [\"S1234567D\"]', ['S1234567D'], ['D', True]], ['control [\"F1234567N\"]', ['F1234567N'], ['N', True]]], [['regression [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['regression [\"T1007654T\"]', ['T1007654T'], ['J', False]], ['partial-repair [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['partial-repair [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['control [\"M1234567K\"]', ['M1234567K'], 'malformed'], ['control [\"SA234567D\"]', ['SA234567D'], 'malformed'], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"F4595639V\"]', ['F4595639V'], ['M', False]]], [['regression [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['regression [\"T5563306D\"]', ['T5563306D'], ['H', False]], ['partial-repair [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['partial-repair [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"F3876611S\"]', ['F3876611S'], ['L', False]]]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), 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":"3d057a8c301e8d04e0a2f68beb8d1676a8a6a05f540939aff8b0a1b673dffc6b","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(s):\n    if len(s) != 9 or not s.isascii() or s[0] not in 'STFG' or not s[1:8].isdigit():\n        return 'malformed'\n    total = sum(int(ch) * w for ch, w in zip(s[1:8], [2, 7, 6, 5, 4, 3, 2]))\n    if s[0] in 'TG':\n        total += 4\n    r = total % 11\n    table = 'JZIHGFEDCBA' if s[0] in 'ST' else 'XWUTRQPNMLK'\n    c = table[r]\n    return [c, s[8] == c]\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['regression [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"F4595639V\"]', ['F4595639V'], ['M', False]], ['control [\"S3757569X\"]', ['S3757569X'], ['J', False]], ['control [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]]], [['regression [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['regression [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['partial-repair [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"F3876611S\"]', ['F3876611S'], ['L', False]], ['control [\"F9230492U\"]', ['F9230492U'], ['L', False]], ['control [\"F4160346W\"]', ['F4160346W'], ['K', False]], ['control [\"S1375256W\"]', ['S1375256W'], ['G', False]]], [['regression [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['regression [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['partial-repair [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S0978420O\"]', ['S0978420O'], ['I', False]], ['control [\"F5183813A\"]', ['F5183813A'], ['X', False]], ['control [\"S1234567D\"]', ['S1234567D'], ['D', True]], ['control [\"F1234567N\"]', ['F1234567N'], ['N', True]]], [['regression [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['regression [\"T1007654T\"]', ['T1007654T'], ['J', False]], ['partial-repair [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['partial-repair [\"G4191951W\"]', ['G4191951W'], ['K', False]], ['control [\"M1234567K\"]', ['M1234567K'], 'malformed'], ['control [\"SA234567D\"]', ['SA234567D'], 'malformed'], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"F4595639V\"]', ['F4595639V'], ['M', False]]], [['regression [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['regression [\"T5563306D\"]', ['T5563306D'], ['H', False]], ['partial-repair [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['partial-repair [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"F3876611S\"]', ['F3876611S'], ['L', False]]]]\nfor label, args, expected in fixtures[N - 1]:\n    check(label, solve(*args), 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, bounded teaching model of the named scheme under the stated contract; not a certified validator. 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-check_digit_algorithms-sg-nric-series-offset","generated_at":"2026-09-29T14:48:41.513540+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Identity verification forms validate NRIC/FIN numbers before submission.","repair":"Add 4 to the weighted sum for T and G prefixes.","root_cause":"The +4 adjustment for the T and G series is missing.","sha256":"0118c07a237a754c3a9bf8f6dcee5edb9c0271660eb9b7f1591d5a20d28660ff","title":"NRIC omits the offset for T and G series · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":38.266,"exit_code":1,"observations":[{"actual":["M",false],"check":"regression [\"G1651468G\"]","expected":["W",false],"passed":false},{"actual":["L",false],"check":"regression [\"G0138893V\"]","expected":["U",false],"passed":false},{"actual":["H",false],"check":"control [\"S6621805O\"]","expected":["H",false],"passed":true},{"actual":["M",false],"check":"control [\"F4595639V\"]","expected":["M",false],"passed":true},{"actual":["J",false],"check":"control [\"S3757569X\"]","expected":["J",false],"passed":true},{"actual":["N",false],"check":"control [\"F4116515A\"]","expected":["N",false],"passed":true},{"actual":["I",false],"check":"control [\"S5101399J\"]","expected":["I",false],"passed":true},{"actual":["F",true],"check":"control [\"S0965290F\"]","expected":["F",true],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"G1651468G\\\"]\", \"actual\": [\"M\", false], \"expected\": [\"W\", false], \"passed\": false}, {\"check\": \"regression [\\\"G0138893V\\\"]\", \"actual\": [\"L\", false], \"expected\": [\"U\", false], \"passed\": false}, {\"check\": \"control [\\\"S6621805O\\\"]\", \"actual\": [\"H\", false], \"expected\": [\"H\", false], \"passed\": true}, {\"check\": \"control [\\\"F4595639V\\\"]\", \"actual\": [\"M\", false], \"expected\": [\"M\", false], \"passed\": true}, {\"check\": \"control [\\\"S3757569X\\\"]\", \"actual\": [\"J\", false], \"expected\": [\"J\", false], \"passed\": true}, {\"check\": \"control [\\\"F4116515A\\\"]\", \"actual\": [\"N\", false], \"expected\": [\"N\", false], \"passed\": true}, {\"check\": \"control [\\\"S5101399J\\\"]\", \"actual\": [\"I\", false], \"expected\": [\"I\", false], \"passed\": true}, {\"check\": \"control [\\\"S0965290F\\\"]\", \"actual\": [\"F\", true], \"expected\": [\"F\", true], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.879,"exit_code":1,"observations":[{"actual":["M",false],"check":"regression [\"G1651468G\"]","expected":["W",false],"passed":false},{"actual":["L",false],"check":"regression [\"G0138893V\"]","expected":["U",false],"passed":false},{"actual":["H",false],"check":"control [\"S6621805O\"]","expected":["H",false],"passed":true},{"actual":["M",false],"check":"control [\"F4595639V\"]","expected":["M",false],"passed":true},{"actual":["J",false],"check":"control [\"S3757569X\"]","expected":["J",false],"passed":true},{"actual":["N",false],"check":"control [\"F4116515A\"]","expected":["N",false],"passed":true},{"actual":["I",false],"check":"control [\"S5101399J\"]","expected":["I",false],"passed":true},{"actual":["F",true],"check":"control [\"S0965290F\"]","expected":["F",true],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"G1651468G\\\"]\", \"actual\": [\"M\", false], \"expected\": [\"W\", false], \"passed\": false}, {\"check\": \"regression [\\\"G0138893V\\\"]\", \"actual\": [\"L\", false], \"expected\": [\"U\", false], \"passed\": false}, {\"check\": \"control [\\\"S6621805O\\\"]\", \"actual\": [\"H\", false], \"expected\": [\"H\", false], \"passed\": true}, {\"check\": \"control [\\\"F4595639V\\\"]\", \"actual\": [\"M\", false], \"expected\": [\"M\", false], \"passed\": true}, {\"check\": \"control [\\\"S3757569X\\\"]\", \"actual\": [\"J\", false], \"expected\": [\"J\", false], \"passed\": true}, {\"check\": \"control [\\\"F4116515A\\\"]\", \"actual\": [\"N\", false], \"expected\": [\"N\", false], \"passed\": true}, {\"check\": \"control [\\\"S5101399J\\\"]\", \"actual\": [\"I\", false], \"expected\": [\"I\", false], \"passed\": true}, {\"check\": \"control [\\\"S0965290F\\\"]\", \"actual\": [\"F\", true], \"expected\": [\"F\", true], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":42.599,"exit_code":0,"observations":[{"actual":["W",false],"check":"regression [\"G1651468G\"]","expected":["W",false],"passed":true},{"actual":["U",false],"check":"regression [\"G0138893V\"]","expected":["U",false],"passed":true},{"actual":["H",false],"check":"control [\"S6621805O\"]","expected":["H",false],"passed":true},{"actual":["M",false],"check":"control [\"F4595639V\"]","expected":["M",false],"passed":true},{"actual":["J",false],"check":"control [\"S3757569X\"]","expected":["J",false],"passed":true},{"actual":["N",false],"check":"control [\"F4116515A\"]","expected":["N",false],"passed":true},{"actual":["I",false],"check":"control [\"S5101399J\"]","expected":["I",false],"passed":true},{"actual":["F",true],"check":"control [\"S0965290F\"]","expected":["F",true],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"G1651468G\\\"]\", \"actual\": [\"W\", false], \"expected\": [\"W\", false], \"passed\": true}, {\"check\": \"regression [\\\"G0138893V\\\"]\", \"actual\": [\"U\", false], \"expected\": [\"U\", false], \"passed\": true}, {\"check\": \"control [\\\"S6621805O\\\"]\", \"actual\": [\"H\", false], \"expected\": [\"H\", false], \"passed\": true}, {\"check\": \"control [\\\"F4595639V\\\"]\", \"actual\": [\"M\", false], \"expected\": [\"M\", false], \"passed\": true}, {\"check\": \"control [\\\"S3757569X\\\"]\", \"actual\": [\"J\", false], \"expected\": [\"J\", false], \"passed\": true}, {\"check\": \"control [\\\"F4116515A\\\"]\", \"actual\": [\"N\", false], \"expected\": [\"N\", false], \"passed\": true}, {\"check\": \"control [\\\"S5101399J\\\"]\", \"actual\": [\"I\", false], \"expected\": [\"I\", false], \"passed\": true}, {\"check\": \"control [\\\"S0965290F\\\"]\", \"actual\": [\"F\", true], \"expected\": [\"F\", true], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}