글
- backend · 2026-06-04 변환했다고 믿었지만 이름만 바꿨다 — 그리고 실패한 작업은 목록에서 사라졌다 벌크 사진 보정이 통째로 실패하는데 토스트도 에러 UI도 없었다. 원인은 두 겹 — 한 경로가 HEIC를 변환하지 않고 파일 이름만 .jpg로 바꿔 외부 API가 거부했고, 실패한 작업은 목록 쿼리에서 빠져 사용자에게 보이지조차 않았다. 장애를 숨기는 건 종종 두 번째 결함이다.
- meta · 2026-06-04 이름 하나 바꾸는 PR이 가장 넓은 PR이었다 — rename은 파일명이 아니라 문서 sweep이다 글로벌 미들웨어 파일명 하나를 정통화하는 rename PR. '파일명 + 한 줄'인 줄 알았는데, 진짜 작업은 그 파일을 '현재 동작'으로 묘사하는 라이브 문서 전수 sweep이었다. 정적 리뷰가 내가 놓친 6곳을 잡았고, round-2는 리뷰어 자신이 놓친 1곳을 더 잡았다. 라운드 사이클은 한 사람이 못 잡는 걸 잡는 누적 안전망이다.
- infra · 2026-06-04 공개로 서빙되지만 비밀인 값 — 소유증명 키를 secret으로 다시 분류한 이야기 검색엔진 색인을 앞당기려 소유증명 키를 'URL로 누구나 가져가니 공개값'이라 분류해 git에 커밋했다. 리뷰가 공식 문서로 막았다 — 'Only you and the search engines should know the key'. 공개로 서빙돼야 하지만 비밀로 취급돼야 하는 값은, 정적 파일 대신 엣지 Worker가 secret에서 서빙하면 둘 다 만족한다.
- infra · 2026-06-03 분산하라는 제약이 배포를 막았다 — required anti-affinity와 빠진 두 번째 노드 SPOF를 풀려고 두 stateful에 'required' anti-affinity를 걸었다. 그런데 그 제약을 만족할 두 번째 노드가 아직 없어서, 무관한 팀의 CD가 25시간 조용히 막히고 helm 배포가 5번 연속 실패했다. 분산 제약은 분산될 자리보다 먼저 들어가면 배포를 막는다 — 순서 의존성, 그리고 위험한 runbook 전제를 실행 전 재검증한 이야기.
- infra · 2026-06-03 recreate 한 번에 벡터DB가 영영 안 떴다 — compose `${VAR}` 보간 ≠ env_file 워커 하나만 다시 만들려고 --force-recreate를 돌렸는데, 의존성을 따라 벡터DB까지 재생성되더니 영영 'starting'에 멈췄다. 원인은 빈 스토리지 키 — docker-compose의 ${VAR} 보간은 서비스의 env_file이 아니라 파싱 시점 호스트 셸/top-level .env에서 해석된다. env_file이 붙어 있어도 안 고쳐진다.
- meta · 2026-06-03 두 번째 AI를 어떻게 부르고 언제 멈추나 — headless adversarial 코드리뷰 루프 구현 에이전트와 리뷰 에이전트를 페어로 굴린다. 리뷰어를 화면 제어가 아니라 headless subprocess로 부르고 출력 형식을 강제하니 화면 파싱의 취약점이 통째로 사라졌다. 그리고 사람이 '멈춤선'을 긋고 리뷰어가 그 선을 판정하게 하자 adversarial 리뷰가 9→7→3→APPROVED로 수렴했다.
- infra · 2026-06-03 알람 3개, 근원은 하나 — 노드 host freeze가 분기한 인시던트 검색엔진 down, 메트릭 시계열 역행, 노드 readiness flapping — 도메인이 다른 알람 3개가 동시에 울렸다. 근원은 하나였다: 한 노드의 host freeze. 그리고 probe가 없어 '응답불가인데 1/1 Running'으로 보인 silent hang, drain했더니 갈 곳이 없어 전부 Pending된 단일 노드풀 함정까지.
- frontend · 2026-06-03 한 번 고친 버그가 어떻게 되살아났나 — 그리고 진단이 한 번 더 뒤집힌 이야기 세션 만료 후 보호 페이지가 로그인으로 안 보내졌다. fix 코드는 멀쩡히 살아 있었는데 거기 도달하는 path만 끊겼다. 처음엔 'Nuxt 트레이트'로 진단했지만 그것도 틀렸다 — 미들웨어가 지원하지 않는 `.client` suffix를 붙인 비표준 네이밍의 부산물이었다. 게시 과정의 팩트체크가 코드 정정까지 이끈 기록.
- backend · 2026-06-03 초록불이 거짓말을 하고 있었다 — succeeded 옆의 ERROR가 드러낸 두 겹의 함정 워커 로그에 매번 같은 ERROR가 찍히는데, 바로 다음 줄에서 태스크는 succeeded로 끝났다. 그 모순이 단서였다 — dual-write가 primary 쓰기 실패를 가리고, create-guard가 스키마 진화를 기존 컬렉션에 전파하지 않은 두 겹의 함정. 성공한 태스크의 핵심 작업이 매번 실패하고 있었다.
- infra · 2026-06-03 장기 키 없이 GitHub Actions에서 GCP로 — 어려운 건 WIF 스펙이 아니라 그 주변이었다 SA 키를 받아 Secret에 붙이는 뻔한 경로 대신, 콘솔 경고대로 Workload Identity Federation을 택했다. 스펙 자체는 짧은데 그 주변 디테일 — 자격증명 5분 수명, immutable ID 바인딩, GPP의 ADC opt-in, JAVA_HOME 레이스 — 에서 6일을 태웠다. static review가 잡은 것과 live 실행만 드러낸 것의 경계.