{"abstract":"Either citizen or foreigner numbers get check letters from the other table.","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":"Selecting the citizen table only for S sends T-series numbers to the foreigner table.","family":"w2-check_digit_algorithms-sg-nric-table-selection","id":"FA-72786","implementations":{"attempt":{"sha256":"b4635ee55b49b57cbd154c073efcf2d729c3509648745da08ef32ca9743d914f","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] == 'S' 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 [\"F4595639V\"]', ['F4595639V'], ['M', False]], ['regression [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['partial-repair [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['partial-repair [\"T7996809P\"]', ['T7996809P'], ['E', False]], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['control [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S3757569X\"]', ['S3757569X'], ['J', False]]], [['regression [\"F3876611S\"]', ['F3876611S'], ['L', False]], ['regression [\"T7996809P\"]', ['T7996809P'], ['E', False]], ['partial-repair [\"T2474569W\"]', ['T2474569W'], ['J', False]], ['partial-repair [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['control [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"G4191951W\"]', ['G4191951W'], ['K', False]]], [['regression [\"F4160346W\"]', ['F4160346W'], ['K', False]], ['regression [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"T7398755K\"]', ['T7398755K'], ['A', False]], ['partial-repair [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['control [\"S0978420O\"]', ['S0978420O'], ['I', False]], ['control [\"S1234567D\"]', ['S1234567D'], ['D', True]], ['control [\"G1234567X\"]', ['G1234567X'], ['X', True]], ['control [\"S123456D\"]', ['S123456D'], 'malformed']], [['regression [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['regression [\"T1007654T\"]', ['T1007654T'], ['J', False]], ['partial-repair [\"T1234567J\"]', ['T1234567J'], ['J', True]], ['partial-repair [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['control [\"SA234567D\"]', ['SA234567D'], 'malformed'], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['control [\"G0138893V\"]', ['G0138893V'], ['U', False]]], [['regression [\"F5183813A\"]', ['F5183813A'], ['X', False]], ['regression [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['partial-repair [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"T2474569W\"]', ['T2474569W'], ['J', False]], ['control [\"G1812101N\"]', ['G1812101N'], ['N', True]], ['control [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]]]]\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":"fe45df2d1a1d9f776618159d6a80e3c534e06b79c9b7c7df2e30c3154d57b7ce","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 'SF' 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 [\"F4595639V\"]', ['F4595639V'], ['M', False]], ['regression [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['partial-repair [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['partial-repair [\"T7996809P\"]', ['T7996809P'], ['E', False]], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['control [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S3757569X\"]', ['S3757569X'], ['J', False]]], [['regression [\"F3876611S\"]', ['F3876611S'], ['L', False]], ['regression [\"T7996809P\"]', ['T7996809P'], ['E', False]], ['partial-repair [\"T2474569W\"]', ['T2474569W'], ['J', False]], ['partial-repair [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['control [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"G4191951W\"]', ['G4191951W'], ['K', False]]], [['regression [\"F4160346W\"]', ['F4160346W'], ['K', False]], ['regression [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"T7398755K\"]', ['T7398755K'], ['A', False]], ['partial-repair [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['control [\"S0978420O\"]', ['S0978420O'], ['I', False]], ['control [\"S1234567D\"]', ['S1234567D'], ['D', True]], ['control [\"G1234567X\"]', ['G1234567X'], ['X', True]], ['control [\"S123456D\"]', ['S123456D'], 'malformed']], [['regression [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['regression [\"T1007654T\"]', ['T1007654T'], ['J', False]], ['partial-repair [\"T1234567J\"]', ['T1234567J'], ['J', True]], ['partial-repair [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['control [\"SA234567D\"]', ['SA234567D'], 'malformed'], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['control [\"G0138893V\"]', ['G0138893V'], ['U', False]]], [['regression [\"F5183813A\"]', ['F5183813A'], ['X', False]], ['regression [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['partial-repair [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"T2474569W\"]', ['T2474569W'], ['J', False]], ['control [\"G1812101N\"]', ['G1812101N'], ['N', True]], ['control [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]]]]\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":"9bf0a054476aa5baf9e5a5a444b7d815bd10291bea09723e8f282f172289c1c9","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 [\"F4595639V\"]', ['F4595639V'], ['M', False]], ['regression [\"F4116515A\"]', ['F4116515A'], ['N', False]], ['partial-repair [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['partial-repair [\"T7996809P\"]', ['T7996809P'], ['E', False]], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['control [\"G0138893V\"]', ['G0138893V'], ['U', False]], ['control [\"S3757569X\"]', ['S3757569X'], ['J', False]]], [['regression [\"F3876611S\"]', ['F3876611S'], ['L', False]], ['regression [\"T7996809P\"]', ['T7996809P'], ['E', False]], ['partial-repair [\"T2474569W\"]', ['T2474569W'], ['J', False]], ['partial-repair [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['control [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]], ['control [\"G4191951W\"]', ['G4191951W'], ['K', False]]], [['regression [\"F4160346W\"]', ['F4160346W'], ['K', False]], ['regression [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"T7398755K\"]', ['T7398755K'], ['A', False]], ['partial-repair [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['control [\"S0978420O\"]', ['S0978420O'], ['I', False]], ['control [\"S1234567D\"]', ['S1234567D'], ['D', True]], ['control [\"G1234567X\"]', ['G1234567X'], ['X', True]], ['control [\"S123456D\"]', ['S123456D'], 'malformed']], [['regression [\"T0395099X\"]', ['T0395099X'], ['E', False]], ['regression [\"T1007654T\"]', ['T1007654T'], ['J', False]], ['partial-repair [\"T1234567J\"]', ['T1234567J'], ['J', True]], ['partial-repair [\"T4006687X\"]', ['T4006687X'], ['F', False]], ['control [\"SA234567D\"]', ['SA234567D'], 'malformed'], ['control [\"S6621805O\"]', ['S6621805O'], ['H', False]], ['control [\"G1651468G\"]', ['G1651468G'], ['W', False]], ['control [\"G0138893V\"]', ['G0138893V'], ['U', False]]], [['regression [\"F5183813A\"]', ['F5183813A'], ['X', False]], ['regression [\"T6283906Q\"]', ['T6283906Q'], ['B', False]], ['partial-repair [\"T5805633Y\"]', ['T5805633Y'], ['I', False]], ['partial-repair [\"T2474569W\"]', ['T2474569W'], ['J', False]], ['control [\"G1812101N\"]', ['G1812101N'], ['N', True]], ['control [\"G9259714Y\"]', ['G9259714Y'], ['N', False]], ['control [\"S5101399J\"]', ['S5101399J'], ['I', False]], ['control [\"S0965290F\"]', ['S0965290F'], ['F', True]]]]\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-table-selection","generated_at":"2026-09-29T14:48:41.587073+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":"Use the JZIHGFEDCBA table for S/T and XWUTRQPNMLK for F/G.","root_cause":"The citizen table is chosen for S and F instead of S and T.","sha256":"c81e0c58780f879f9931735be83a730d12cc6e44f6bb261566b6140fe901b59d","title":"NRIC pairs the wrong series with each letter table · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":39.341,"exit_code":1,"observations":[{"actual":["M",false],"check":"regression [\"F4595639V\"]","expected":["M",false],"passed":true},{"actual":["N",false],"check":"regression [\"F4116515A\"]","expected":["N",false],"passed":true},{"actual":["Q",false],"check":"partial-repair [\"T4006687X\"]","expected":["F",false],"passed":false},{"actual":["P",true],"check":"partial-repair [\"T7996809P\"]","expected":["E",false],"passed":false},{"actual":["H",false],"check":"control [\"S6621805O\"]","expected":["H",false],"passed":true},{"actual":["W",false],"check":"control [\"G1651468G\"]","expected":["W",false],"passed":true},{"actual":["U",false],"check":"control [\"G0138893V\"]","expected":["U",false],"passed":true},{"actual":["J",false],"check":"control [\"S3757569X\"]","expected":["J",false],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"F4595639V\\\"]\", \"actual\": [\"M\", false], \"expected\": [\"M\", false], \"passed\": true}, {\"check\": \"regression [\\\"F4116515A\\\"]\", \"actual\": [\"N\", false], \"expected\": [\"N\", false], \"passed\": true}, {\"check\": \"partial-repair [\\\"T4006687X\\\"]\", \"actual\": [\"Q\", false], \"expected\": [\"F\", false], \"passed\": false}, {\"check\": \"partial-repair [\\\"T7996809P\\\"]\", \"actual\": [\"P\", true], \"expected\": [\"E\", false], \"passed\": false}, {\"check\": \"control [\\\"S6621805O\\\"]\", \"actual\": [\"H\", false], \"expected\": [\"H\", false], \"passed\": true}, {\"check\": \"control [\\\"G1651468G\\\"]\", \"actual\": [\"W\", false], \"expected\": [\"W\", false], \"passed\": true}, {\"check\": \"control [\\\"G0138893V\\\"]\", \"actual\": [\"U\", false], \"expected\": [\"U\", false], \"passed\": true}, {\"check\": \"control [\\\"S3757569X\\\"]\", \"actual\": [\"J\", false], \"expected\": [\"J\", false], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":40.96,"exit_code":1,"observations":[{"actual":["C",false],"check":"regression [\"F4595639V\"]","expected":["M",false],"passed":false},{"actual":["D",false],"check":"regression [\"F4116515A\"]","expected":["N",false],"passed":false},{"actual":["Q",false],"check":"partial-repair [\"T4006687X\"]","expected":["F",false],"passed":false},{"actual":["P",true],"check":"partial-repair [\"T7996809P\"]","expected":["E",false],"passed":false},{"actual":["H",false],"check":"control [\"S6621805O\"]","expected":["H",false],"passed":true},{"actual":["W",false],"check":"control [\"G1651468G\"]","expected":["W",false],"passed":true},{"actual":["U",false],"check":"control [\"G0138893V\"]","expected":["U",false],"passed":true},{"actual":["J",false],"check":"control [\"S3757569X\"]","expected":["J",false],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"F4595639V\\\"]\", \"actual\": [\"C\", false], \"expected\": [\"M\", false], \"passed\": false}, {\"check\": \"regression [\\\"F4116515A\\\"]\", \"actual\": [\"D\", false], \"expected\": [\"N\", false], \"passed\": false}, {\"check\": \"partial-repair [\\\"T4006687X\\\"]\", \"actual\": [\"Q\", false], \"expected\": [\"F\", false], \"passed\": false}, {\"check\": \"partial-repair [\\\"T7996809P\\\"]\", \"actual\": [\"P\", true], \"expected\": [\"E\", false], \"passed\": false}, {\"check\": \"control [\\\"S6621805O\\\"]\", \"actual\": [\"H\", false], \"expected\": [\"H\", false], \"passed\": true}, {\"check\": \"control [\\\"G1651468G\\\"]\", \"actual\": [\"W\", false], \"expected\": [\"W\", false], \"passed\": true}, {\"check\": \"control [\\\"G0138893V\\\"]\", \"actual\": [\"U\", false], \"expected\": [\"U\", false], \"passed\": true}, {\"check\": \"control [\\\"S3757569X\\\"]\", \"actual\": [\"J\", false], \"expected\": [\"J\", false], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":40.914,"exit_code":0,"observations":[{"actual":["M",false],"check":"regression [\"F4595639V\"]","expected":["M",false],"passed":true},{"actual":["N",false],"check":"regression [\"F4116515A\"]","expected":["N",false],"passed":true},{"actual":["F",false],"check":"partial-repair [\"T4006687X\"]","expected":["F",false],"passed":true},{"actual":["E",false],"check":"partial-repair [\"T7996809P\"]","expected":["E",false],"passed":true},{"actual":["H",false],"check":"control [\"S6621805O\"]","expected":["H",false],"passed":true},{"actual":["W",false],"check":"control [\"G1651468G\"]","expected":["W",false],"passed":true},{"actual":["U",false],"check":"control [\"G0138893V\"]","expected":["U",false],"passed":true},{"actual":["J",false],"check":"control [\"S3757569X\"]","expected":["J",false],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression [\\\"F4595639V\\\"]\", \"actual\": [\"M\", false], \"expected\": [\"M\", false], \"passed\": true}, {\"check\": \"regression [\\\"F4116515A\\\"]\", \"actual\": [\"N\", false], \"expected\": [\"N\", false], \"passed\": true}, {\"check\": \"partial-repair [\\\"T4006687X\\\"]\", \"actual\": [\"F\", false], \"expected\": [\"F\", false], \"passed\": true}, {\"check\": \"partial-repair [\\\"T7996809P\\\"]\", \"actual\": [\"E\", false], \"expected\": [\"E\", false], \"passed\": true}, {\"check\": \"control [\\\"S6621805O\\\"]\", \"actual\": [\"H\", false], \"expected\": [\"H\", false], \"passed\": true}, {\"check\": \"control [\\\"G1651468G\\\"]\", \"actual\": [\"W\", false], \"expected\": [\"W\", false], \"passed\": true}, {\"check\": \"control [\\\"G0138893V\\\"]\", \"actual\": [\"U\", false], \"expected\": [\"U\", false], \"passed\": true}, {\"check\": \"control [\\\"S3757569X\\\"]\", \"actual\": [\"J\", false], \"expected\": [\"J\", false], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}