만든 도구진행 중

죽은 채널

정교한 쪽이 조용히 죽어 있었고, 그걸 진단한 제 문서도 두 군데가 틀렸습니다.

20.6MB

같은 목적의 장치가 이미 하나 있었습니다. 더 정교했습니다. 그리고 «조용히 죽어» 있었습니다 — 몇 달 동안 아무도 몰랐습니다.

있던 장치

이 루프를 만들기 전에도 같은 목적의 것이 하나 있었습니다. 그리고 설계가 더 정교했습니다.

  1. 작업하는 동안 자동으로 관찰해서 쌓음
  2. 쌓인 것에서 패턴을 뽑아 「본능」으로 만듦
  3. 그 본능이 다음 작업에 쓰임

전부 자동이었습니다. 사람이 아무것도 안 해도 됩니다.

열어 보니

무엇 상태
1번(관찰) 127개 파일 · 20.6MB 쌓여 있음
2번(패턴 뽑기) 한 번도 안 돎
3번(본능) 0개

앞은 열심히 돌았고 뒤는 한 번도 안 돌았습니다.

그리고 몇 달 동안 아무도 몰랐습니다.

왜 몰랐나 — 「오류가 안 났기 때문」입니다

이게 이 글의 핵심입니다.

만약 오류가 났으면 빨간 글씨가 떴을 것이고, 봤을 것입니다.

그런데 아무 오류도 안 났습니다. 그냥 안 돌았습니다. 그리고 안 도는 것과 잘 도는 것은 화면이 똑같습니다 — 둘 다 조용합니다.

「자동이라서 죽는다」 — 반직관적인데 기제는 단순합니다

「자동이면 사람이 안 해도 되니까 더 오래 살겠지」 싶은데 반대입니다.

손으로 하는 것 자동인 것
안 돌면 내가 안 한 걸 앎 아무 일도 안 일어남
결과물이 없으면 내가 알아챔 원래 그런 줄 앎

손으로 하는 건 안 하면 내가 압니다. 자동인 건 안 돌아도 내가 모릅니다. 원래 자동이니까 신경을 안 쓰고 있었으니까요.

자동화는 「내가 신경 안 써도 되게」 만드는 것인데, 그 말은 「죽어도 내가 모르게」 만드는 것이기도 합니다.

그리고 제 진단도 두 군데가 틀렸습니다

이 문제를 정리한 설계 문서를 적대적으로 검토에 넣었더니, 제가 문제라고 적어 둔 것 두 개가 사실이 아니었습니다.

죽은 걸 발견하고 나면 「왜 죽었나」를 서둘러 적게 됩니다. 그리고 그 설명은 확인 없이 그럴듯한 것으로 채워집니다.

고장을 찾은 흥분이 원인 분석의 정확도를 떨어뜨립니다.

그리고 20.6MB가 클라우드로 올라가고 있었습니다

제일 아찔했던 부분입니다.

관찰 장치는 읽은 것, 가져온 것, 도구가 돌려준 것을 «원문 그대로» 저장했습니다.

빠져 있던 것
출처 구분 없음
비밀값 가리기 없음

그리고 그 20.6MB가 조용히 클라우드 백업으로 동기화되고 있었습니다.

세 가지가 겹쳐서 나쁩니다.

  1. 원문 그대로 저장 — 무엇이 들었는지 아무도 모름
  2. 쓰이지 않음 — 2번이 안 도니까 쌓이기만 함
  3. 밖으로 나감 — 백업으로

즉 아무도 안 쓰는 데이터가, 걸러지지 않은 채로, 밖으로 나가고 있었습니다.

「쓰려고 모았는데 안 쓰였다」가 그냥 낭비가 아니라 위험이 된 경우입니다.

→ 배운 것: 모으는 장치를 만들 때는 「무엇을 모으나」보다 「안 쓰이면 어떻게 되나」를 먼저 봐야 합니다.

죽은 쪽 — 완전 자동 · 정교 관찰 훅 사람 손 0 관찰 127파일 20.6MB 누적 증류기 한 번도 안 돌았다 본능 0 조용히 죽음 산 쪽 — 단순 · 손으로 씀 메모리 파일 직접 쓴다 매 세션 주입 실제로 읽힌다 살아 있다 지금도 돈다 부품이 많은 쪽이 먼저 죽었다
왼쪽은 전부 자동이라 아무도 안 봤고, 오른쪽은 손이 가야 해서 계속 봤다.

여기부터는 자세한 기록입니다

이 루프를 설계하기 전에도 같은 목적의 장치가 하나 있었다. 세션을 자동으로 관찰해 쌓고, 거기서 패턴을 증류해 “본능”으로 만드는 파이프라인이다. 훅으로 전부 자동이었고, 설계가 정교했다.

열어 보니 관찰이 127파일 20.6MB 쌓여 있었고, 증류기는 한 번도 돌지 않았다. 본능은 0개였다. 몇 달 동안 아무도 몰랐다 — 에러가 안 났기 때문이다.

바로 옆에서 잘 돌던 건 훨씬 단순한 쪽이었다. 손으로 쓰는 메모리 파일. 매 세션 주입되고, 실제로 읽히고, 틀리면 내가 고친다.

여기서 교훈이 뒤집혔다. 완전 자동이라서 죽었고, 손이 가서 살았다. 그런데 내 원안은 정확히 반대 교훈으로 쓰여 있었다 — 죽은 쪽을 되살리고 그 위에 자동화를 더 얹는 계획이었다.

왜 자동이 죽는가

“자동이라 죽는다”가 반직관적으로 들리는데, 기제는 단순하다.

자동화된 것은 관측 대상에서 빠진다. 손이 가는 것은 손을 댈 때마다 눈에 들어온다. 메모리 파일은 내가 직접 쓰니까 안 쓰이면 바로 안다. 관찰 훅은 알아서 도니까 안 돌아도 알 방법이 없다.

그리고 산출물이 없어도 아무 일도 안 일어나는 구조였다. 증류기가 안 돌면 본능 파일이 안 생길 뿐이고, 본능 파일이 없어도 세션은 멀쩡히 돈다. 실패에 대가가 없으면 실패가 지속된다.

내 초기 진단은 두 군데가 틀렸다

설계 문서를 적대적 리뷰에 넣었더니, 내가 문제라고 적어 둔 것 두 개가 사실이 아니었다.

  • “관찰이 안 쌓인다” → 틀렸다. 20.6MB가 실재했다. 진짜 원인은 훅 실패가 아니라 증류기 미가동이었다. 고칠 곳을 완전히 잘못 짚고 있었다.
  • “상시 주입되는 색인은 3~4KB” → 틀렸다. 재보니 16.8KB, 예산의 4.2배였다. 본문 98파일은 370KB — 상시 주입이 물리적으로 불가능한 크기고, 필요할 때 불러오는 배선은 애초에 없었다.

원인을 잘못 짚은 계획은 아무리 정교해도 엉뚱한 데를 고친다. 이 두 정정이 계획의 절반을 지웠다.

배운 건 이거다. 자기 시스템을 진단할 때 제일 위험한 건 모르는 것이 아니라 안다고 생각하는 것이다. 나는 “관찰이 안 쌓인다”를 재보지도 않고 전제로 깔고 있었다.

그리고 그 20.6MB는 백업으로 올라가고 있었다

관찰 훅은 읽은 것, 가져온 것, 도구가 돌려준 것을 원문 그대로 캡처했다. 출처 구분도 없고 비밀값 마스킹도 없었다. 그리고 그 20.6MB는 조용히 클라우드 백업에 동기화되고 있었다.

“사람 승인 후에만, 외부에서 온 내용은 제외”는 설계 문서에 분명히 적혀 있었다. 강제하는 코드는 0줄이었다.

문서에만 적힌 규칙은 규칙이 아니다. 그리고 이 경우는 특히 나쁜데, 아무도 그걸 안 읽고 있었기 때문에 위반 사실조차 없었다 — 위반하려면 규칙을 알아야 하는데, 코드는 규칙을 모른다.

정리는 단순했다. 죽은 훅 두 개를 끄고, 20.6MB와 빈 껍데기 127개를 지우고, 시크릿 스캔을 돌렸다. 스캔 결과는 0건이었지만, 그건 운이지 설계가 아니었다.