"문 없는 벽은 trust boundary 가 아니야. 아직 아무도 지키라고 요구하지 않은 약속일 뿐이지."
아카이브가 드디어 기준선을 넘는 날
두 레슨 전의 격리는 팔자가 편했어. 승인된 게 하나도 없고, 급할 것도 없고, 벽을 넘은 transcript 가 단 하나도 없는 채로 제품이 완벽하게 돌아갔으니까. 시작을 그렇게 하는 건 진짜로 옳아. 하지만 게이트가 시험받는 날은 누군가 저쪽 편에 진짜로 보내고 싶은 transcript 를 수천 개 들고 오는 날이야. 그때부터 질문이 바뀌어. "기본값이 거부여야 하나?" 가 아니라 훨씬 어려운 "이 규모에서 사람의 결정이라는 게 대체 무슨 모양이지?" 가 되는 거지.
정직한 문제는 이거야. release 하나하나 리뷰는 영상 수천 개로 확장이 안 돼. 그런데 된다고 우기면 제일 나쁜 결과가 나와. 다들 중요하다고 동의하지만 아무도 실제로 운영하지 않는 게이트, 그러다 누군가 일을 진행하려고 조용히 넓혀버리는 게이트. 게다가 사실 승인하고 있는 대상은 개별 transcript 가 아니야. 파이프라인이지. 이 provider, 이 model, 이 설정, 이 오디오 준비가 이런 구조적 품질의 출력을 낸다는 것. 표본을 봤고, 파이프라인에 대한 판단을 내렸고, 거기서 나온 release 라면 기꺼이 보증할 수 있다는 것.
인스턴스 말고 신원을 승인해
그래서 Recall 은 문을 코호트 정책으로 만들었어. operator 가 정책을 만들면서, 판단이 덮는 그 파이프라인을 정의하는 모든 걸 정확한 값으로 못박아.
- provider 와 model.
- 설정 해시와 오디오 proxy 설정 해시. 유료 ledger 가 쓰는 바로 그 content-addressed 지문이야.
- 이 정책이 덮는 release 상태와 구조적 품질 등급.
- 승인자, 그리고 결정의 근거.
그 정확한 신원에 맞는 release 만 정책 아래 선택될 수 있고, 하나를 선택하면 어느 정책에서 왔는지 이름이 박힌 release 별 승인 행이 durable 하게 남아. 판단은 한 사람이 정밀하게 기술된 모집단에 대해 한 번 내리고, 그다음엔 그 구성원들에게 기계적으로 적용돼. 승격은 자동화됐고, 판단은 절대 아니야.
여기서 설정 해시가 뭘 사주는지 봐야 해. 이게 안전한 이유 전체거든. 파이프라인에서 뭐 하나라도 어긋나면, 새 model 이든 바뀐 설정이든 다른 오디오 준비든, 지문이 바뀌고 그 어긋난 release 들은 그냥 정책에 안 맞아. 다른 것에 대해 내려진 판단의 힘을 빌려 슬그머니 딸려 들어오지 못하는 거야. 정책이 못박은 게 서술이 아니라 신원이라서, 승인자가 본 적 없는 출력까지 조용히 덮도록 자라날 수가 없어.
수동 게이트는 어디 안 갔어
원래 경로는 손대지 않았고 여전히 유효해. 사람이 개별적으로 리뷰하고 승인한 release 는 예전 그대로 적격이야. 코호트 경로는 그걸 대체하는 게 아니라 옆에 나란히 서고, 일부러 더 좁아. 완전히 다른 model 이 만들어낸 옛 레거시 transcript 들은 어떤 Scribe 코호트 정책에도 안 걸려서 격리된 채로 남아. 문이 둘, 둘 다 사람을 요구하고, 그중 하나가 결정을 모집단 전체로 실어 나를 수 있는 거지.
코호트 경로는 쉽게 쓸 수 있었던 지름길도 거부해. 정책 아래 release 를 승인해도 그 release 자신의 리뷰 상태는 안 고쳐 써. candidate 는 candidate 로 남고, 정책 승인은 그 옆에 별도의 durable 한 사실로 기록돼. 정책이 건드린 전부에 "reviewed" 를 찍는 게 얼마나 편했겠어. 그리고 그건 거짓말이었을 거야. 아무도 안 읽었으니까. 시스템은 편한 거짓 하나 대신 참인 문장 둘을 쥐기로 한 거야. 그 정직함엔 값이 붙고, 청구서가 어디로 오는지 볼 값어치가 있어. 1번 레슨의 export guard 는 candidate release 를 그냥 거부하거든. 그러니까 상태를 정직하게 두겠다는 건 guard 가 더는 검사 하나의 사슬일 수 없다는 뜻이야. guard 는 선택지 둘이 됐어. 수동 경로를 걸었으면 내보내거나, 아니면 살아 있는 정책 아래 살아 있는 승인 행을 쥐고 있으면 내보내거나. 두 branch 다 eligibility 가 명시적으로 approved 이고, release 가 current 이고, 영상이 은퇴하지 않았을 것은 여전히 요구하고. 문과 문간은 같은 변경에서 지어. 소비하는 쪽 경계에 자기를 위한 branch 가 없는 승격 경로는 벽을 향해 열리는 문이야. 그리고 조용히 닫힌 채로 실패하는데, 그게 제일 알아채기 어려운 종류거든.
발행은 버튼이 아니라 job 이야
Operations 에서 Publish to Lantern 을 눌러도 요청 안에서 발행이 일어나진 않아. 트랙 2 가 금지했고, 여기가 그 규칙이 압력 아래에서 버티는 걸 구경하기 좋은 자리야. 대신 기록되는 세 단계를 가진 durable job 하나를 만들어. 정책 종류에 맞는 남은 release 를 전부 승인하고, corpus 엔진에 완전 재색인을 요청하고, 그 의미 벡터를 재조정하는 것. job 도 각 단계의 응답도 페이지를 닫든 control plane 이 재시작하든 살아남아. 중단된 job 은 시작할 때 큐로 돌아가서 idempotent 한 단계들을 다시 밟고, 실패는 정확히 어느 단계였는지와 원격 에러를 기록해서 의도적인 재시도를 기다려. DB 인덱스가 동시에 떠 있는 발행 job 을 정확히 하나로 제한해.
설계가 끝났다고 말해주는 디테일은 이거야. 아무것도 승인하지 않는 실행도 돌릴 값어치가 있어. 지난 발행 이후의 수정과 은퇴도 전파돼야 하거든. 수정된 release 는 옛 버전을 feed 에서 떨구고, 은퇴한 실종 영상은 다음 재조정에서 사라져. 발행은 새 자료를 한 방향으로 밀어넣는 게 아니라, corpus 가 지금 담고 있어야 할 것의 재조정이야. 들여보낼 줄만 아는 게이트는 결국 더 이상 보증하지 않게 된 것들로 corpus 를 채우게 돼.