이번 주도 결국 hyper였다. 커밋만 세어봐도 40개에 가까운데, 나머지 레포를 다 합쳐도 그 절반이 안 된다.
지난주에 대화를 전부 채널로 갈아엎었으니, 이번 주는 그 채널 안에서 봇들이 "언제 말해야 하는가"를 계속 손봤다. 여러 봇이 같은 방에 있으면 필연적으로 생기는 문제인데, 부르지도 않았는데 끼어들거나, 자기가 방금 한 말을 또 하거나, 한 턴에 여러 번 떠드는 게 계속 거슬렸다. 그래서 호출됐을 때만 말하게 막고, 한 턴엔 한 라운드만 돌게 하고, 새 메시지가 자기 얘기일 때만 턴에 끼어들게 했다. 릴레이도 정해진 홉 수 하나로만 판단하게 단순화했고, 그 홉 수를 넘겨서 멘션이 조용히 버려지던 것도 이제는 최소한 버려졌다는 티는 내게 고쳤다. 사람이 중간에 메시지를 보내면 큐에 쌓이는 대신 봇의 턴을 바로 끊고 들어가게 만든 것도 이번 주다. 결국 다 여러 봇이 있는 방을 진짜 단체 채팅방처럼 느껴지게 만드는 작업이었던 것 같다. 근데 "자연스럽다"는 감각이 고칠 때마다 미묘하게 달라져서, 하나 잡으면 다른 데서 또 어색함이 튀어나온다. 이게 규칙 몇 개로 끝날 문제인가 싶기도 하고.
재미있었던 건 봇이 스스로 팔로우업을 예약하는 기능이다. "이따 확인해서 알려줄게" 하고 끝내버리는 게 아니라, 그 약속을 실제로 스케줄러에 등록해서 나중에 정말로 돌아와서 말하게 만들었다. 사람도 @멘션 대상이 되게 하고, 누가 나를 부르면 알림이 오게 한 것도 같은 맥락이다. 링크를 붙이면 OpenGraph 카드로 언퍼닝되는 것, 메시지를 위/아래 화살표로 다시 불러오는 것, 시스템 알림이 "user"라는 이름의 봇처럼 보이던 걸 콜아웃으로 분리한 것도 이번 주에 처리했다 — 마지막 건 왜 이제야 눈에 띄었나 싶다.
인프라도 건드렸다. CI를 셀프호스팅 맥 러너로 옮겼는데, hyper뿐 아니라 creturex CI도 같은 이유로 같은 주에 옮겼다. claude-agent-sdk는 0.1.48에서 0.2.128로 올렸다 — 버전 숫자만 보면 겁부터 나는 폭인데, 막상 올리고 나서 큰 사고는 없었던 것 같다 (아직 며칠 안 지나서 모르는 거지만). ad-revenue 스킬 쪽 리프레시 토큰을 손으로 갱신하던 것도 스크립트 하나로 대체했다.
creturex에서는 뱃지 시스템을 붙였다. 스키마 마이그레이션하고, award_badges 평가기와 인정(recognition) 훅을 만들고, 기존 데이터 백필까지 돌렸다. 근데 배포하자마자 Hall of Collectors가 본인 것만 보이는 버그가 났다. 원래 다른 사람이 모은 뱃지도 보여야 재미있는 화면인데, 그러면 그냥 개인 마이페이지가 되는 거라 서둘러 고쳤다. 새 기능 만드는 것보다 이런 걸 놓쳤을 때가 더 아쉽다.
heg.wtf는 홈페이지를 다시 짰다. CreatureX를 앱스토어 링크로 걸었고, 제주공항주차라는 프로젝트도 새로 올렸다. 포트폴리오에 프로젝트가 하나씩 늘어나는 걸 보면 뿌듯하다가도, 이렇게 벌여놓은 걸 다 챙길 수 있나 하는 생각이 문득 든다. driverpub은 AdMob이랑 안드로이드 릴리즈 빌드가 깨져서 그거 고치는 데 시간을 좀 썼다 (live_activities 패키지를 1.9.5에서 2.4.9로 올렸더니 풀렸다 — 이런 사소한 의존성 하나가 릴리즈를 통째로 막을 수 있다는 걸 또 배웠다).
hyper에 이렇게 오래 붙어있는 게 맞는 속도인지는 잘 모르겠다. 다음 주는 좀 덜 고치고 더 써볼 생각이다.
26.08.02 — 봇들 좀 조용해졌으면.