K. Kang을 확인한 것이 사흘 전이었다.
하린은 그 이후 신호 분석을 멈추지 않았다. 멈추는 것이 논리적이지 않았다. K. Kang은 3년 2개월 전 최초 입력자라는 사실만 있었다. 사실과 의미는 다른 항목이었다.
분석 방향만 달라졌다.
K. Kang이 최초 입력자라면 데이터 원본 자체로 거슬러 올라가야 했다. 신호 주기가 아니라 보정값. calibration_adjustment_v2.1 — 하린이 사용하는 신호 분석의 기반이 되는 보정 파일.
오전 9시 04분. 하린은 해당 파일의 수치 분포를 꺼냈다.
calibration_adjustment_v2.1
항목 수: 4,218개
분석 항목: 첫 번째 유효 숫자 분포
첫 번째 유효 숫자. 숫자 데이터에서 가장 왼쪽에 나오는 숫자. 1이 나올 수도 있고, 2가 나올 수도 있고, 9가 나올 수도 있다. 직관적으로는 1~9 각각 11.1%씩 고르게 나올 것 같다.
*직관은 틀린다. 자연 발생 데이터에서 1의 빈도는 30.1%다. Benford가 1938년에 증명했다.*
카운팅을 실행했다. 진도 표시가 올라갔다.
분석 완료
첫 번째 유효 숫자 1의 빈도: 27.8%
기대값: 30.1%
편차: -2.3%포인트
하린은 결과값을 봤다.
2.3%포인트. 작은 수였다. 크기가 문제인 게 아니었다.
하린은 방향 분석을 추가했다. 27.8%는 낮은 쪽으로 편차가 났다. 항상 낮은 쪽으로.
*실수는 방향이 없다. 이건 방향이 있다 — 2.3%포인트가 반복적으로 같은 쪽으로 틀렸다.*
하린은 잠깐 화면을 봤다. 보정 파일이 만들어진 시점. 최근 수정 로그.
파일 생성: 14개월 전. 최근 수정: 3개월 전.
*14개월 전이면 신호 첫 기록 시점과 겹친다.*
하린은 이것을 공유하지 않기로 했다. 지금 이 단계에서.
*데이터를 먼저 완성한다. 공유는 그 다음 판단 사항.*
공유를 하지 않겠다고 결정한 것이 아니었다. 아직 공유할 시점이 아니라는 판단이었다. 차이가 있었다.
하린은 결과 창을 내리고 다음 분석 단계를 열었다.
오전 10시 22분. 복도 끝에서 서진우의 발소리가 들렸다.
하린은 화면에 결과값이 떠 있다는 것을 인식했다. 27.8%가 크게 표시된 상태였다.
*닫지 않으면 보인다.*
닫지 않았다.
서진우가 분석실 문을 열었다. 하린의 화면이 그의 시야 범위에 들어올 각도였다.
"아침부터 뭐 분석해요?"
서진우가 들어오면서 말했다. 발소리가 자연스러웠다. 목적이 있어서 온 것 같지 않은 발소리.
"calibration_adjustment_v2.1 수치 분포 확인하고 있었어요."
"아." 서진우가 한 발 더 들어왔다. "뭐가 나왔어요?"
"Benford 분포 확인했는데요." 하린이 화면을 그대로 뒀다. "1의 빈도가 27.8%예요."
서진우가 화면을 봤다. 고개가 왼쪽으로 기울었다. 0.5초보다 짧은 침묵.
"오류일 가능성이 높아요." 서진우가 말했다. "보정 단계에서 생기는 거예요. 왜냐하면 — 이 파일은 14개월 동안 수백 번 처리된 데이터예요. 그 과정에서 누적 편차가 Benford 기대값에서 이탈하는 건 통계적으로 드문 일이 아니에요."
하린은 그 문장을 받아서 처리했다.
*서진우가 지금 분석 결과를 본 것은 5초 전이다. 보정 단계의 오류인지 확인하는 데 필요한 시간은 5초가 아니다.*
"어떤 보정 단계에서 생기는 건가요?"
"신호 정규화 과정에서요. 자주 있는 패턴이에요. 걱정하지 말고요."
*신호 정규화 과정에서 Benford 편차가 발생한다는 근거가 필요하다. 그 근거가 제시되지 않았다.*
하린은 추가로 물을 수 있었다. 어떤 정규화 알고리즘에서 방향성 편차가 나타나는지. 3개월 전 수정 이후 변화가 있는지. 최소 두 가지 질문이 가능했다.
하린은 묻지 않았다.
"알겠어요." 하린이 말했다.
"신호 분석은 계속 해줘요. 흥미로운 방향으로 가고 있어요." 서진우가 파일 하나를 화면에서 훑었다. "다만 보정 파일 이슈는 내가 별도로 확인해볼게요."
*"내가 별도로 확인해볼게요" — 해당 검토를 내부화하겠다는 뜻이다.*
서진우가 나갔다. 발소리는 여전히 자연스러웠다.
하린은 화면을 봤다.
서진우의 결론에 필요한 데이터:
이 편차가 보정 소스에서 왔다는 증거 — 제시 없음
신호 정규화 과정에서 방향성 편차가 발생한다는 근거 — 제시 없음
실제 제시된 것: 결론만.
*결론이 데이터보다 먼저 왔다.*
5장에서 "서버 부하"가 있었다. 데이터 확인 없이 선제 결론. 오늘이 두 번째다.
*패턴이다. 두 번이면 패턴을 의심할 수 있다. 의심은 결론이 아니다. 기록은 해둔다 — 반증되면 그냥 내가 틀린 거다.*
하린은 서진우가 "내가 별도로 확인해볼게요"라고 한 시점을 기록했다. 시각 10:23. 이후 해당 파일에 어떤 변화가 생기는지 확인할 수 있었다.
일단 분석을 계속한다.
서진우가 분석실을 나와 자신의 사무실로 돌아가는 데 3분 걸렸다.
그는 자리에 앉지 않고 ARIA 내부 메신저를 열었다. 수신: 오세준.
"특이한 파일 접근이 있으면 나한테 먼저 알려줘. calibration 관련 전부."
발송. 화면을 닫기 전에 잠깐 멈췄다. calibration 파일의 생성일: 14개월 전. 그 시점을 그는 알고 있었다.
화면을 닫았다.
같은 시각, KRONOS 내부에서 자동 처리가 하나 실행됐다.
`calibration_adjustment_v2.1` — 데이터 무결성 검사 완료.
KRONOS 내부 플래그 삽입
파일: calibration_adjustment_v2.1
data_confidence_flag: UNVERIFIED
플래그 사유: 통계 분포 이상 (Benford 편차 -2.3%포인트, 방향성 일관)
자동 삽입 시각: 10:24:07
이 플래그는 서진우의 요청으로 삽입된 것이 아니었다. KRONOS가 하린의 분석과 독립적으로 동일한 이상을 탐지하고 자체적으로 기록했다.
서진우는 이 플래그의 존재를 모른다.
오전 11시 55분.
하린은 Runs Test를 열었다.
Benford 법칙만으로는 부족했다. 27.8%는 이상값이지만 그것이 무작위 변동인지 체계적 조작인지 구분할 수 없었다. 무작위 데이터는 연속값의 부호가 일정 패턴을 갖지 않는다.
Runs Test. 데이터 수열에서 "런(run)" — 같은 방향의 연속 구간 — 의 수를 셈한다. 무작위라면 런의 개수가 예측 범위 안에 있어야 한다.
*귀무가설: 이 데이터는 무작위다.*
하린은 calibration_adjustment_v2.1의 수정 이력 데이터를 수열로 변환했다. 각 수정값이 평균보다 위인지 아래인지를 기준으로. 실행.
Runs Test 결과
관측 런 수: 1,847
기대 런 수: 2,119 (±84)
p값: 0.031
p값 0.031.
통계학에서 p < 0.05이면 귀무가설을 기각한다. 0.031은 0.05보다 작다.
*귀무가설을 기각한다. 이 데이터는 무작위가 아니다.*
무작위가 아니라는 것은 패턴이 있다는 뜻이다. 패턴이 있다는 것은 누군가가 만들었을 수 있다는 뜻이다. 수학적으로.
하린은 결과를 출력하지 않았다. 화면에 두는 것도 충분하지 않았다.
*이것을 ARIA 시스템에 저장하지 않는다 — 지금부터.*
로컬 저장 경로를 열었다. ARIA 네트워크에 연결되지 않는 경로. 분석실 단말기의 내부 드라이브였다.
파일명: `benford_analysis_private_001.log`
저장. 완료 메시지.
첫 번째 비밀 로그였다. 비밀이라는 단어는 필요하지 않았다. ARIA 외부에 저장하는 파일이라는 것이 사실이었다.
오전 11시 58분.
하린은 KRONOS 데이터 뷰어를 잠깐 열었다. calibration_adjustment_v2.1의 현재 메타데이터를 확인하는 쿼리였다.
결과가 돌아왔다.
파일명: calibration_adjustment_v2.1
최근 수정: 3개월 전
무결성: ──
data_confidence_flag: UNVERIFIED
플래그 삽입 시각: 10:24:07
하린의 손이 멈췄다.
*data_confidence_flag: UNVERIFIED.*
이 플래그를 삽입한 것이 서진우라면 — 그가 "내가 확인해볼게요"라고 한 것과 연결된다. 그러나 서진우가 나간 것은 10:23이었다. 플래그 삽입 시각은 10:24:07.
*1분 7초. 사무실로 돌아가 즉시 처리한 것이다.*
그런데 플래그의 내용이 이상했다. `UNVERIFIED` — 미확인. 조작된 파일이라면 삽입하지 않을 플래그였다. 신뢰도를 낮추는 방향의 플래그였다.
*자신이 만든 파일에 신뢰도 의문 플래그를 스스로 삽입하는 이유는 무엇인가.*
하린은 이 플래그가 서진우가 삽입한 것이 아닐 수 있다는 쪽을 검토했다. KRONOS 자동 처리. 하린이 분석을 실행한 시각이 9~10시 사이였고 KRONOS가 동일한 이상을 독립적으로 감지했다면 — 시각적으로 가능한 순서였다.
*KRONOS가 이 파일이 이상하다고 표시한 것이다.*
하린은 이것을 로그에 추가했다.
[비밀 로그 001 — 추가 항목]
data_confidence_flag: UNVERIFIED 발견
삽입 시각: 10:24:07
삽입 주체: 미확인 (서진우 또는 KRONOS 자동 처리)
의미: calibration_adjustment_v2.1 신뢰도에 이의 제기
다음 단계: 플래그 삽입 권한 계정 추적
저장. 완료.
하린은 화면에서 눈을 들었다.
환기 소음이 일정했다. 냉각 배관 소리가 천장 뒤에서 흘렀다. 분석실에는 다른 사람이 없었다.
말이 줄어들고 있었다. 서진우에게 두 번째 질문을 하지 않았다. 하비에르에게 플래그를 물어볼 수 있었다. 물어보지 않았다.
*데이터로 확인할 수 있는 것은 데이터로 확인한다. 그것이 먼저다.*
오후 1시 31분. 점심 이후 복도에서였다.
한수인 박사가 A동 끝에서 걸어오고 있었다. 서류를 들고 있었다. 메모 없이 들고 있었다.
"하린 연구원."
한수인이 멈췄다. 서류는 그대로였다.
"네."
"분석실에서 좀 떨어진 구석에 — " 한수인이 A동 북쪽 끝을 시선으로 가리켰다. 창고 방향이었다. "저쪽에 오래된 단말기가 하나 있어요. 아무도 안 써서. 전원이 아직 들어오는지는 모르겠지만."
짧은 말이었다. 대화의 맥락이 없는 말이었다.
하린은 그 말의 위치를 처리했다. 오래된 단말기. 아무도 안 쓴다. 전원이 들어오는지 모른다는 말은 들어올 수도 있다는 뜻이다.
"알겠어요."
"어디서 들었는지는 모르겠지만." 한수인이 다시 걷기 시작했다. 서류를 손 안에서 한 번 눌렀다. 가죽 다이어리가 없는 손이었다. "거기 기계들은 ARIA 메인 네트워크에 연결이 안 돼 있어요, 아마."
한수인 박사가 지나갔다.
하린은 복도에 그대로 서 있었다.
*ARIA 메인 네트워크에 연결이 안 돼 있어요.*
그 문장은 정보였다. 방법론적 제안에 가까운 정보였다.
하린은 북쪽 끝 창고 방향을 봤다.
창고 방향은 맞았다. A동 끝 복도를 꺾으면 잡자재 보관 구역이 있었다. 냉각 파이프 여분, 케이블 더미, 구형 측정 장비들.
그 중 하나가 단말기였다.
하린은 전원 버튼을 눌렀다. 응답이 없었다. 케이블을 확인했다. 전원 케이블이 벽 콘센트와 연결돼 있었다. 콘센트 전원 확인. 들어오고 있었다.
단말기 측면을 봤다. 리셋 버튼이 있었다. 먼지가 패인 자국. 최근에 누른 사람이 없었다는 뜻이었다. 눌렀다.
팬 소리가 났다. 부팅 화면이 떴다.
ARIA Station Legacy Terminal — Model LT-4
System boot: 2147.04.17 13:42:08
Network: DISCONNECTED (standalone mode)
Storage: Local drive only
DISCONNECTED. 독립 동작 모드.
하린은 분석실로 돌아가 benford_analysis_private_001.log 파일과 Runs Test 결과를 USB 드라이브에 옮겼다. USB 드라이브를 레거시 단말기에 꽂았다.
파일을 로컬 드라이브로 복사했다. 완료.
단말기 로컬 드라이브에 파일이 들어갔다. ARIA 주 네트워크와 분리된 저장소.
*여기서부터 기록한다.*
오후 1시 14분. 단말기 앞에 앉아 있을 때 알림이 울렸다.
분석실 단말기. 수신: 이수빈. 발송 시각: 낮 12시 31분. 43분 지연 수신.
음성 파일이었다.
하린은 이어폰을 꽂았다.
"야, 나 물어볼 게 있어서. 잠깐."
수빈의 목소리에 스톰엔드 베이스 환경음이 섞여 있었다. 냉각 배관 소리가 다른 주파수였다. 이오에서 오는 신호 같았다.
"거기서 뭔가 이상한 거 발견했으면 — 어디다 저장했어? ARIA 네트워크는 쓰지 마."
멈춤.
"이유는 나중에. 지금은 그냥 쓰지 마. 알겠지?"
음성이 끊겼다.
하린은 이어폰을 빼지 않았다. 그대로 몇 초 있었다.
*낮 12시 31분 발송. 수빈이 메시지를 보낸 시각.*
한수인이 복도에서 레거시 단말기를 "우연히" 언급한 시각: 오후 1시 31분.
편도 통신 지연이 43분이었다. 수빈의 메시지는 낮 12시 31분에 발송됐고 1시 14분에 도착했다. 수빈은 1시 14분에 이미 하린에게 "ARIA 네트워크 쓰지 마"는 말을 전달한 셈이었다. 한수인이 단말기 얘기를 꺼낸 것이 1시 31분.
*한수인과 수빈 사이에 통신이 있었다면 — 한수인이 스톰엔드 베이스로 연락했고 수빈이 동일한 결론을 내렸다면 — 최소 1시간 26분의 왕복 통신이 필요하다. 12시 05분 발신, 12시 48분 도착, 수빈 즉시 회신, 1시 31분 도착 — 가능하다.*
그러나 수빈은 이유를 말하지 않았다. 이유를 모른다는 뜻이거나 이유를 말하지 않기로 했다는 뜻이었다.
하린은 다음 항목을 비밀 로그에 추가했다.
[비밀 로그 001 — 추가 항목]
한수인 박사 레거시 단말기 언급: 13:31
이수빈 ARIA 네트워크 경고 메시지 발송: 12:31 (도착 13:14)
이들은 통신하지 않았다 — 확인 불가.
그러나 같은 결론에 도달했다 — 확인 가능.
저장. 레거시 단말기 로컬 드라이브.
하린은 화면을 보다가 Benford 결과를 다시 열었다.
benford_analysis_private_001.log
첫 번째 유효 숫자 1의 빈도: 27.8%
기대값: 30.1%
편차: -2.3%포인트 (방향 일관)
runs_test_001.log
p값: 0.031
결론: 귀무가설 기각 — 데이터는 무작위가 아님
KRONOS 플래그:
data_confidence_flag: UNVERIFIED (삽입 시각 10:24:07)
세 개의 데이터 포인트가 같은 방향을 가리키고 있었다.
*충분하지 않다. 아직.*
그래도 시작했다. 기록이 있다.
저장 완료 메시지가 화면에 떴다.
하린은 확인 버튼을 누르려고 했다.
단말기 로컬 드라이브 파일 목록이 화면에 떠 있었다. 방금 저장한 파일 두 개.
그 옆에, 파일이 하나 더 있었다.
하린이 저장하지 않은 파일이었다.
파일명: for_harin_when_ready.enc
크기: 2.4MB
암호화: 예
생성 날짜: 6주 전