언더스코어 하나가 사람을 18개월 감옥에 보냈다
하나 밝히고 시작하겠습니다. 이 주제로 최근 30일간의 커뮤니티 반응을 찾아봤는데, 건질 만한 실시간 논의가 없었습니다. 그래서 이번 글은 커뮤니티 반응 정리가 아닙니다. 개발자와 시스템 설계자의 눈으로 이런 사고가 왜 자꾸 반복되는지를 짚어보는 쪽으로 방향을 잡았습니다. 특정 사건의 세부 사실관계는 확정적으로 쓰지 않겠습니다. 대신 이 문제의 구조를 이야기하겠습니다.
문제의 뿌리는 단순합니다. 문자 하나가 빠지면 시스템은 그걸 “다른 사람"으로 보지 않습니다. “비슷한 사람"으로 봅니다. 그 순간부터 무고한 사람의 인생이 흔들리기 시작합니다.
언더스코어는 왜 그렇게 위험한가
개발자라면 다들 아실 겁니다. 식별자에서 언더스코어, 하이픈, 공백은 셋 다 “구분 문자"처럼 생겼지만 시스템은 이걸 전혀 다르게 취급합니다.
SMITH_JOHN과 SMITHJOHN은 문자열 비교에서 완전히 다른 값입니다. 그런데 사람 눈에는 거의 같아 보입니다. 데이터 입력 담당자가 언더스코어를 하나 빠뜨리면 그건 오타가 아니라 새로운 사람의 탄생입니다. 없던 사람이 데이터베이스 안에 하나 생겨나는 겁니다.
반대 방향은 더 고약합니다. 두 사람의 식별자가 정규화를 거치면서 하나로 합쳐집니다. 레거시 시스템은 검색 편의를 위해 특수문자를 떼고 비교하는 경우가 많습니다. 그러면 KIM_MS와 KIMMS가 같은 값이 됩니다. 서로 다른 두 사람의 기록이 한 폴더에 담기는 순간입니다.
경찰 데이터베이스에서 이 일이 벌어지면 데이터 오류로 끝나지 않습니다. 누군가의 전과가 엉뚱한 사람에게 붙습니다.
형사사법 시스템에는 “되돌리기” 버튼이 없다
보통의 소프트웨어 버그는 발견되면 고칩니다. 롤백하고 패치 배포하고 사과 공지 올리면 끝입니다.
형사사법 시스템은 다릅니다. 잘못된 데이터가 체포를 부르고, 체포가 구속을 부르고, 구속이 재판으로 갑니다. 각 단계가 앞 단계를 사실로 전제합니다. 검사는 경찰 기록을 믿고 판사는 검사의 자료를 믿습니다. 원본 데이터가 맞는지 다시 확인하는 사람은 없습니다.
18개월이 무서운 건 그래서입니다. 버그가 18개월 동안 발견되지 않았다는 뜻이 아닙니다. 18개월 동안 아무도 의심하지 않았다는 뜻입니다. 시스템이 뱉은 값이라는 이유 하나로요.
“자동화 편향"이라고 부르는 심리가 이 대목에서 작동합니다. 컴퓨터가 말하면 사람 말보다 더 믿는 겁니다. 당사자가 아무리 “나 아니다"라고 해도 화면에 뜬 매칭 결과 하나를 이기지 못합니다.
진짜 문제는 오타가 아니라 설계다
이런 사건이 터지면 보통 “입력 실수"로 정리됩니다. 담당자 한 명이 징계를 받고 끝나죠. 하지만 개발자 눈으로 보면 이건 명백한 설계 실패입니다.
사람 손으로 입력하는 필드에 오타가 나는 건 버그가 아니라 상수입니다. 반드시 일어납니다. 잘 설계된 시스템은 그 전제 위에서 출발합니다.
제대로 만들었다면 이런 장치가 있었어야 합니다.
체크섬이 포함된 식별자를 씁니다. 주민등록번호 마지막 자리나 신용카드 번호의 룬 알고리즘처럼, 한 글자만 틀려도 유효하지 않은 값이 되도록 만드는 겁니다. 오타가 조용히 통과하지 못하게 막는 가장 기본적인 방법입니다.
퍼지 매칭 결과와 정확 매칭 결과를 구분해서 표시합니다. “이 사람입니다"와 “이 사람일 수도 있습니다"는 화면에서 완전히 다르게 보여야 합니다. 지금 많은 시스템이 둘을 같은 목록에 섞어서 보여줍니다.
신원 확인에는 독립적인 근거를 두 개 이상 요구합니다. 이름 문자열 하나로 사람을 특정하지 않는다는 원칙입니다.
이의 제기 경로도 실제로 작동해야 합니다. 당사자가 “이건 내가 아니다"라고 말하면 그 말이 데이터베이스 재검증으로 이어지는 절차가 있어야 합니다.
AI가 끼어들면 상황은 더 나빠진다
지금 각국 수사기관이 AI 기반 매칭 시스템을 빠르게 도입합니다. 얼굴 인식, 이름 유사도 분석, 여러 데이터베이스 교차 검증까지요.
역설은 여기서 시작됩니다. AI는 언더스코어 하나 빠진 것 정도는 알아서 보정해줍니다. 오타에 강합니다. 문제는 과하게 보정한다는 겁니다.
문자열 매칭은 최소한 “왜 매칭됐는지"를 설명할 수 있습니다. 이 문자와 저 문자가 같아서요. 반면 임베딩 유사도 기반 매칭은 “0.87점이 나왔습니다"라고만 말합니다. 어디가 왜 비슷한지는 아무도 모릅니다.
기존 시스템은 오류가 선명했습니다. 문자가 다르면 안 걸리고 같으면 걸립니다. 새 시스템은 오류가 흐릿합니다. 그래서 반박하기가 훨씬 어렵습니다. 무고함을 증명해야 하는 쪽이 상대할 게 문자열에서 확률 분포로 바뀐 겁니다.
우리가 만드는 시스템에도 같은 구멍이 있다
솔직히 말하면 이건 남의 나라 경찰 이야기가 아닙니다.
사용자 병합 로직에서 이메일 소문자 변환만으로 동일인 판정을 하고 계신가요. 결제 시스템에서 이름과 생년월일 조합으로 고객을 식별하고 계신가요. 로그 분석에서 문자열 정규화한 뒤 같은 세션으로 묶고 계신가요.
전부 같은 구조입니다. 차이는 실패했을 때의 비용뿐입니다.
경찰 데이터베이스는 그 비용이 18개월의 자유였습니다. 우리 서비스는 대개 그보다 가볍지만, “가볍다"가 “없다"는 아닙니다. 계정 하나가 잘못 병합되면 누군가의 개인정보가 남의 화면에 뜹니다.
사람은 계속 틀린다
이 사건의 교훈은 “데이터를 꼼꼼히 입력하자"가 아닙니다. 사람은 계속 틀립니다. 그건 없앨 대상이 아니라 깔고 가야 할 전제입니다.
필요한 건 틀린 데이터가 조용히 통과하지 못하게 만드는 설계입니다. 그 데이터가 사람의 삶을 결정하는 자리라면 더 그렇습니다.
지금 만들고 계신 시스템에서 문자 하나가 빠지면 무슨 일이 벌어지나요. 답이 바로 나오지 않는다면 오늘 한번 확인해보세요.
댓글
댓글을 불러오는 중...