ci: allow protected mobile candidate
This commit is contained in:
parent
4872d6f6c5
commit
1f71cf6fae
3 changed files with 797 additions and 9 deletions
733
docs/v3/MOBILE_RELEASE_HANDOFF_2026-08-29.md
Normal file
733
docs/v3/MOBILE_RELEASE_HANDOFF_2026-08-29.md
Normal file
|
|
@ -0,0 +1,733 @@
|
|||
# D3RO Voice 모바일 출시 핸드오프 — 2026-08-29
|
||||
|
||||
## 0. 결론
|
||||
|
||||
**모바일 앱은 아직 출시 가능 상태가 아니다.** Google Play 등록정보의 텍스트,
|
||||
아이콘, feature graphic 초안은 준비됐지만 production AAB, Firebase Android 설정,
|
||||
upload signing, Play-signed 설치본, 실제 핵심 기능 E2E, 스토어용 앱 스크린샷이 없다.
|
||||
|
||||
2026-08-29 실제 `1.1.0` debug 앱을 새 Pixel 7 에뮬레이터에서 열어 보니 다음을
|
||||
확인했다.
|
||||
|
||||
- Metro가 없으면 `Unable to load script` 오류 화면이 표시된다.
|
||||
- Metro 연결 후 첫 부팅 중 빈 흰 화면이 잠시 표시됐다.
|
||||
- 이후 실제 onboarding과 로그인 화면은 열렸다.
|
||||
- 인증 세션이 없어 녹음·전사·AI·팀 화면에는 진입하지 못했다.
|
||||
- production/Play-signed 설치본이 아니므로 이번 캡처는 Google Play 제출물이 아니다.
|
||||
|
||||
사용자 요청에 따라 작업은 여기서 중단했다. `/goal`은 완료로 처리하지 않는다.
|
||||
|
||||
## 1. 중단 상태
|
||||
|
||||
종료 확인일: 2026-08-29 KST
|
||||
|
||||
| 항목 | 종료 상태 |
|
||||
| ------------------- | --------------------------------------------------------------------------- |
|
||||
| 전용 캡처 AVD | `D3RO_PlayCapture_20260829` 생성됨, `emulator-5556` 종료됨 |
|
||||
| 기존 AVD | `emulator-5554`만 연결 상태로 보존. 기존 `0.0.0-e2e` 데이터는 건드리지 않음 |
|
||||
| Metro | `localhost:8081` listener 없음 |
|
||||
| 로컬 Supabase | `supabase stop --workdir server` 완료, local data는 Docker volume에 백업됨 |
|
||||
| Android 앱 프로세스 | 전용 `emulator-5556` 종료로 함께 중단 |
|
||||
| Play Console | 더 이상 변경하지 않음. 기본 등록정보 페이지는 초안 상태 |
|
||||
| Firebase | 프로젝트 생성 버튼을 누르지 않음. 신규 Firebase 프로젝트 없음 |
|
||||
| Git | 이 핸드오프 문서 외 추가 stage/commit/push 없음 |
|
||||
| Forgejo 배포 | run #46 실패 상태. 반복 push/retry하지 않음 |
|
||||
|
||||
## 2. 이번 세션에서 이룬 것
|
||||
|
||||
### 2.1 버전과 릴리즈 메타데이터
|
||||
|
||||
- 제품 버전: `1.1.0`
|
||||
- Android versionCode: `1010001`
|
||||
- iOS build number: `1010001`
|
||||
- release date: `2026-08-29`
|
||||
- SSOT: `release/product-version.json`
|
||||
- root, desktop, mobile package version과 Android/iOS 버전 동기화 검증 GREEN
|
||||
- `CHANGELOG.md`의 `1.1.0` 항목 갱신
|
||||
- Android `ko-KR`/`en-US` release notes 준비:
|
||||
- `apps/mobile-rn/metadata/android/ko-KR/changelogs/1010001.txt`
|
||||
- `apps/mobile-rn/metadata/android/en-US/changelogs/1010001.txt`
|
||||
- `npm run release:metadata` GREEN
|
||||
- `npm run release:metadata:test` GREEN, fail-closed negative 6건
|
||||
|
||||
### 2.2 Play 등록정보 초안
|
||||
|
||||
Play 앱:
|
||||
|
||||
- 개발자 계정: 개인 Play Console 계정
|
||||
- Play app ID: `4976102237698469110`
|
||||
- package: `com.d3ro.voice`
|
||||
- 기본 언어: `ko-KR`
|
||||
- 상태: draft
|
||||
|
||||
저장한 초안:
|
||||
|
||||
- 앱 이름: `D3RO Voice`
|
||||
- 짧은 설명: 42자
|
||||
- 자세한 설명: 1,213자
|
||||
- 유명 음성 기록·전사 앱의 정보 구조를 비교하되 문구를 복제하지 않고,
|
||||
첫 효용 → 결과 중심 기능 → 요금·광고 → 개인정보 → 책임 고지 순서로 작성
|
||||
- 파일: `docs/v3/play/01-store-listing.md`
|
||||
|
||||
중요 경계:
|
||||
|
||||
- 초안만 저장했다.
|
||||
- 리뷰, App content, Data safety, internal/closed/production 제출은 하지 않았다.
|
||||
- 휴대전화 스크린샷 영역에는 아무 이미지도 업로드하지 않았다.
|
||||
|
||||
### 2.3 아이콘과 feature graphic
|
||||
|
||||
Play icon:
|
||||
|
||||
- 파일: `docs/v3/play/assets/d3ro-voice-play-icon-512.png`
|
||||
- 규격: 512×512 PNG
|
||||
- SHA-256: `0FAE53FB40CCE4B9FB0213CBEDB4E087CA00A8F8C438D6731C5C47C4AFD096B1`
|
||||
- Play Console 업로드와 preview 확인 완료
|
||||
|
||||
Feature graphic canonical E:
|
||||
|
||||
- 제출본: `docs/v3/play/assets/feature-graphic/candidate-e-generated-signal-stage.png`
|
||||
- 규격: 1024×500, PNG24, sRGB, alpha 없음
|
||||
- SHA-256: `A5D82B65B95027ACE184FA06A3BBDA3433995C70F064932B5733C3D3A99644D9`
|
||||
- 생성 원본, prompt, 제출본, hash를 별도로 보존
|
||||
- Play Console preview에서 crop·thumbnail contrast·규격 경고 없음을 확인
|
||||
- 이것은 **feature graphic**이며 앱 스크린샷이 아니다.
|
||||
|
||||
검증:
|
||||
|
||||
- `npm run release:play:assets` GREEN
|
||||
- `npm run release:play:assets:test` GREEN
|
||||
- canonical E 변조 포함 fail-closed negative 7건 GREEN
|
||||
|
||||
### 2.4 Git과 CI
|
||||
|
||||
현재 권위 있는 SHA:
|
||||
|
||||
```text
|
||||
4872d6f6c50a15104792fb31a97176527c3cd9a2
|
||||
```
|
||||
|
||||
다음 ref가 모두 위 SHA와 일치한다.
|
||||
|
||||
- local `main`
|
||||
- `origin/main`
|
||||
- `chanpaca/main`
|
||||
|
||||
주요 릴리즈 커밋:
|
||||
|
||||
```text
|
||||
4872d6f docs(release): update 1.1.0 launch metadata
|
||||
0a8cf43 feat(play): finalize store graphics and copy
|
||||
563d4cb fix(ci): make mobile Gradle wrapper executable
|
||||
6a9608c ci: bootstrap Linux release toolchains
|
||||
30d5127 build(release): forbid unsigned Windows artifacts
|
||||
ec5aec7 fix(release): retire legacy capture publisher
|
||||
547d4ad security: remove credential automation from releases
|
||||
f342ea8 fix(release): sync legacy mobile version
|
||||
3e9e04f ci(release): require trusted Windows signing
|
||||
5205dcd feat(release): prepare 1.1.0 candidate
|
||||
```
|
||||
|
||||
GitLab CI:
|
||||
|
||||
- 최종 pipeline: `72066`
|
||||
- URL: `https://gitlab.twentyoz.kr:8443/d3r0/voice/-/pipelines/72066`
|
||||
- commit: `4872d6f6`
|
||||
- 결과: SUCCESS, 7/7
|
||||
- GREEN jobs: lint/typecheck, unit, API, Edge, mobile-quality,
|
||||
build-workspaces, mobile-android
|
||||
- 이전 graphics/copy pipeline `72065`도 SUCCESS, 7/7
|
||||
|
||||
주의: CI GREEN은 production AAB, Play 설치, 실제 provider, 스크린샷 검증을
|
||||
대체하지 않는다.
|
||||
|
||||
### 2.5 실제 앱 실행 시도
|
||||
|
||||
새 전용 AVD:
|
||||
|
||||
- 이름: `D3RO_PlayCapture_20260829`
|
||||
- device profile: Pixel 7
|
||||
- system image: Android 34 Google APIs Play Store x86_64
|
||||
- serial: 실행 시 `emulator-5556`
|
||||
- 원래 해상도: 1080×2400
|
||||
- 캡처 시 임시 override: 1080×1920
|
||||
- 현재 상태: 종료됨
|
||||
|
||||
설치한 실제 debug APK:
|
||||
|
||||
- 파일: `apps/mobile-rn/android/app/build/outputs/apk/debug/app-debug.apk`
|
||||
- package: `com.d3ro.voice`
|
||||
- label: `D3RO Voice`
|
||||
- versionName: `1.1.0`
|
||||
- versionCode: `1010001`
|
||||
- targetSdk: 36
|
||||
- SHA-256: `7AD0FD0716D8F900053B31D72C53ADC035889D8B507D95602FEC49F5A5C78B87`
|
||||
- signer: Android Debug
|
||||
- debug signer SHA-256:
|
||||
`FAC61745DC0903786FB9EDE62A962B399F7348F0BB6F899B8332667591033B9C`
|
||||
|
||||
정상 확인:
|
||||
|
||||
- 새 AVD 설치 성공
|
||||
- cold start가 `com.d3ro.voice/.MainActivity`로 실행됨
|
||||
- Metro 연결 후 React Native `D3ROVoice` root 실행 확인
|
||||
- 실제 onboarding과 login UI 확인
|
||||
- Keychain이 빈 새 설치에서 인증 세션 없음 확인
|
||||
|
||||
## 3. 하지 못한 것
|
||||
|
||||
### 3.1 실제 핵심 기능 검증
|
||||
|
||||
다음 화면은 실제 앱에서 열지 못했다.
|
||||
|
||||
- 녹음 ready/recording/paused 상태
|
||||
- 실제 WAV 생성과 foreground notification
|
||||
- 오디오/MP4 가져오기
|
||||
- 실제 전사 결과와 history detail
|
||||
- Talk AI 응답과 신고 sheet
|
||||
- 생성 문서/회의록
|
||||
- 팀/초대/역할 화면
|
||||
- 개인정보, export/restore, account deletion의 authenticated 경로
|
||||
- 광고 동의·배너·rewarded SSV
|
||||
- Play Billing purchase/restore
|
||||
|
||||
원인:
|
||||
|
||||
- 새 debug 설치에는 로그인 세션이 없다.
|
||||
- debug 앱은 production Supabase를 사용한다.
|
||||
- 안전한 인증 우회나 기능 화면 deep link가 없다.
|
||||
- auth session은 Android Keychain에 암호화되므로 AsyncStorage/adb seed로 우회할 수 없다.
|
||||
- 사용자의 실제 계정을 캡처에 사용하지 않았다.
|
||||
- 외부 disposable 계정도 새로 만들지 않았다.
|
||||
|
||||
### 3.2 production Android release
|
||||
|
||||
아직 없는 것:
|
||||
|
||||
- Firebase project와 Android app
|
||||
- `google-services.json`
|
||||
- production upload keystore path/alias/password CI 설정
|
||||
- release evidence private key CI 설정
|
||||
- Firebase project ID/number/mobile SDK app ID CI 설정
|
||||
- `D3RO_MOBILE_PRODUCTION_RELEASE_ENABLED=true`
|
||||
- Android emulator runner production gate
|
||||
- production signed AAB
|
||||
- `v1.1.0` tag
|
||||
- Play internal track upload
|
||||
- Play-signed install
|
||||
- App Bundle Explorer/signing evidence
|
||||
|
||||
production AAB는 생성되지 않았다. self-signed, debug, E2E 또는 출처 불명
|
||||
keystore를 사용하지 않았다.
|
||||
|
||||
### 3.3 Google Play 스크린샷
|
||||
|
||||
현재 store-ready 휴대전화 스크린샷 수: **0장**
|
||||
|
||||
- Play Console screenshot slot은 비어 있다.
|
||||
- 최소 2장, 권장 4장 이상이 필요하다.
|
||||
- 실제 핵심 기능 화면을 아직 열지 못했으므로 업로드하지 않았다.
|
||||
|
||||
### 3.4 Firebase
|
||||
|
||||
생성 예정으로 준비했던 값:
|
||||
|
||||
- project name: `D3RO Voice Production`
|
||||
- project ID: `d3ro-voice-production`
|
||||
- Android package: `com.d3ro.voice`
|
||||
- Developer Program: off
|
||||
- Gemini: off
|
||||
- Analytics: off
|
||||
|
||||
하지만 최종 `프로젝트 만들기` 버튼은 누르지 않았다. Firebase project/API
|
||||
identity는 생성되지 않았다. 내일 action-time 승인 후 다시 시작해야 한다.
|
||||
|
||||
### 3.5 공개 사이트 배포
|
||||
|
||||
Forgejo push 자체는 완료됐다.
|
||||
|
||||
- `chanpaca/main`: `4872d6f6c50a15104792fb31a97176527c3cd9a2`
|
||||
- sparse pack 문제를 비활성화해 136MiB 전송을 3.66MiB로 줄인 뒤 push 성공
|
||||
|
||||
하지만 배포는 실패했다.
|
||||
|
||||
- Forgejo deploy-site run: `#46`
|
||||
- 결과: FAILURE
|
||||
- 실패 위치: `Set up job`
|
||||
- 경과: 10분 53초
|
||||
- checkout/build/Cloudflare/verify: 모두 0초, 시작되지 않음
|
||||
- 원인: `linux-builder` runner가 job을 claim/initialize하지 못해 timeout
|
||||
|
||||
현재 public 상태는 최신 배포가 아니다.
|
||||
|
||||
- `/release-identity.json`: 404
|
||||
- root `/`: 404
|
||||
- live `assetlinks.json`: 과거 인증서 SHA 유지
|
||||
- live download page: 과거 `v1.0.0 STABLE` / `Signed & Verified` 문구 유지
|
||||
- privacy/terms/delete-account: 기존 공개 페이지는 접근 가능
|
||||
|
||||
새 commit이나 반복 push로 해결할 문제가 아니다. runner 복구 후 run #46만
|
||||
재실행하고 public exact verification을 해야 한다.
|
||||
|
||||
### 3.6 Windows 공개 릴리즈
|
||||
|
||||
- 로컬 installer는 Authenticode `NotSigned`
|
||||
- public-trust code-signing certificate/PFX가 없음
|
||||
- 기존 self-signed `CN=Everything2EverythingDev`는 public release에 사용 금지
|
||||
- stable `v1.1.0` tag/release와 updater publish는 계속 차단
|
||||
|
||||
## 4. 새로 발견된 것
|
||||
|
||||
### 4.1 설치돼 있던 앱은 production 앱이 아니었다
|
||||
|
||||
기존 `emulator-5554`의 `com.d3ro.voice`:
|
||||
|
||||
- versionName: `0.0.0-e2e.20260829.1`
|
||||
- versionCode: `202608291`
|
||||
- installer: `null`
|
||||
- microphone/notification permission: 미허용
|
||||
|
||||
기존 상태를 캡처해 Play 증거로 쓰면 안 된다. 기존 에뮬레이터는 보존했다.
|
||||
|
||||
### 4.2 debug APK는 Metro 없이 standalone 실행되지 않는다
|
||||
|
||||
`app-debug.apk` 첫 cold start에서 Metro가 없으면 다음 오류가 실제로 표시됐다.
|
||||
|
||||
```text
|
||||
Unable to load script.
|
||||
Make sure you're running Metro or that your bundle 'index.android.bundle'
|
||||
is packaged correctly for release.
|
||||
```
|
||||
|
||||
이는 debug variant의 예상 개발 경계이지만, source/build GREEN만으로 앱을
|
||||
열었다고 판단하면 안 된다는 실증이다. 최종 Play 캡처는 embedded bundle을 가진
|
||||
production/Play-signed 설치본이어야 한다.
|
||||
|
||||
### 4.3 Metro 연결 직후 빈 흰 화면이 관찰됐다
|
||||
|
||||
Metro bundle 로딩 뒤 첫 캡처는 status/navigation bar 외 전부 흰 화면이었다.
|
||||
수 초 뒤 onboarding이 표시됐다. production build에서 다음을 별도로 검증해야 한다.
|
||||
|
||||
- cold start splash/boot feedback
|
||||
- blank frame 지속 시간
|
||||
- provider/auth 초기화 실패 시 fail-closed UI
|
||||
- offline/slow network 시작 경로
|
||||
- process death 후 recovery
|
||||
|
||||
### 4.4 실제 onboarding은 열렸지만 핵심 기능은 인증 뒤에 있다
|
||||
|
||||
실제 onboarding과 signup/login 화면은 정상 렌더됐다. 그러나 debug 앱에는
|
||||
안전한 local/demo 기능 route가 없고 인증 우회도 없다. local disposable
|
||||
Supabase + E2E APK를 사용하면 기능 UI를 열 수 있지만 그 결과는 TEST-DEMO이며
|
||||
Play-signed production 증거가 아니다.
|
||||
|
||||
### 4.5 캡처용 해상도를 별도로 고정해야 한다
|
||||
|
||||
Pixel 7 AVD 기본 캡처는 1080×2400이었다. Play draft 요구와 일관된 세로 캡처를
|
||||
위해 dedicated AVD에 `wm size 1080x1920`을 적용했다. 내일 재개 시 실제 값을
|
||||
다시 확인하고, Play-signed 설치본에서도 동일 viewport가 제품 UI를 자르거나
|
||||
왜곡하지 않는지 검증해야 한다.
|
||||
|
||||
### 4.6 작업 트리가 매우 dirty하다
|
||||
|
||||
중단 시 `git status --short` 집계:
|
||||
|
||||
- total: 197
|
||||
- modified: 55
|
||||
- deleted: 17
|
||||
- untracked: 125
|
||||
|
||||
대부분 기존 build/test/generated/user 작업이다. 전체 stage, 전체 commit,
|
||||
reset, restore, clean을 금지한다. 이번에 새로 생긴 캡처 디렉터리만 별도로
|
||||
식별됐다.
|
||||
|
||||
## 5. 캡처 증거 원장
|
||||
|
||||
디렉터리:
|
||||
|
||||
`docs/v3/play/assets/screenshots/1.1.0-debug-capture-20260829/`
|
||||
|
||||
| 파일 | 규격 | SHA-256 | 내용 | 판정 |
|
||||
| ------------------------ | --------- | ------------------------------------------------------------------ | ----------------------------------------- | ------------------------------------------------- |
|
||||
| `00-launch.png` | 1080×2400 | `4818E5266471D07A63B0162D60B673354E17DF8BD0F557FE0ADDF9E04EE94711` | Metro 미연결 `Unable to load script` 오류 | **폐기**, 오류 증거만 보존 |
|
||||
| `01-runtime.png` | 1080×1920 | `89947F52FE4CA38A2729D1C706CAB5C0AD87A45405843F4769D0ABDFD4F440CC` | Metro 연결 직후 빈 흰 화면 | **폐기**, boot 문제 증거만 보존 |
|
||||
| `02-after-bootstrap.png` | 1080×1920 | `95AC6B0B2792086DE2D38AE719FBED222A3595158A2C9F37403E31F756FD6FC8` | 실제 `1.1.0` onboarding 1/5 | 실제 앱 화면이지만 **debug이며 store-ready 아님** |
|
||||
|
||||
세 파일 모두 Play Console에 업로드하지 않는다. `02-after-bootstrap.png`도
|
||||
production/Play-signed 재촬영 전에는 참고 증거일 뿐이다.
|
||||
|
||||
## 6. 내일 진행해야 할 것
|
||||
|
||||
### P0 — 앱을 먼저 검증한다
|
||||
|
||||
1. 아래 `재개 전 사실 확인` 명령을 실행한다.
|
||||
2. Firebase project/app 생성에 대한 action-time 승인을 다시 받는다.
|
||||
3. Firebase Android app `com.d3ro.voice`를 등록한다.
|
||||
4. Play app-signing SHA-1/SHA-256과 upload key SHA를 Firebase에 정확히 등록한다.
|
||||
5. `google-services.json`을 내려받아 package/project identity를 검증한다.
|
||||
6. public-trust와 별개인 Android upload key를 기대 SHA와 대조한다.
|
||||
7. GitLab protected/masked/hidden CI variables를 구성한다.
|
||||
8. `mobile-production-release` job으로 production AAB를 만든다.
|
||||
9. AAB version/package/SDK/merged manifest/dependency/signature/provenance를 검증한다.
|
||||
10. 사용자 확인 후 Play internal track에 AAB를 업로드한다.
|
||||
11. Play가 서명한 설치본을 clean install한다.
|
||||
12. 로그인, 녹음, 전사, AI, 팀, 신고, 광고, Billing, 삭제를 실제로 검증한다.
|
||||
|
||||
### P0 — 실제 스토어 스크린샷을 만든다
|
||||
|
||||
최종 캡처는 Play-signed 설치본과 dedicated reviewer/capture 계정을 사용한다.
|
||||
사용자의 실제 이메일, 회의, 음성, 팀, 토큰을 사용하지 않는다.
|
||||
|
||||
권장 6장 흐름:
|
||||
|
||||
1. **녹음** — 녹음 준비 또는 실제 recording 상태, 명확한 controls와 상태 표시
|
||||
2. **전사 결과** — 실제 WAV에서 생성된 transcript/history detail
|
||||
3. **AI 문서화** — 실제 transcript 기반 요약/문서와 책임 있는 사용 경계
|
||||
4. **Talk + 신고** — 실제 AI 응답과 사용자가 접근 가능한 report affordance
|
||||
5. **작업/팀** — Works hub 또는 팀 협업의 실제 접근 가능한 구조
|
||||
6. **데이터 관리** — privacy, export/restore, device/account deletion 경로
|
||||
|
||||
각 이미지 acceptance criteria:
|
||||
|
||||
- 1080×1920 PNG 또는 Console이 수락하는 검증된 실제 device ratio
|
||||
- package `com.d3ro.voice`
|
||||
- versionName `1.1.0`, versionCode `1010001`
|
||||
- installer `com.android.vending`
|
||||
- Play app-signing certificate SHA-256이 기대값과 일치
|
||||
- DEBUGGABLE 아님
|
||||
- test AdMob label/fixture/debug menu/error/red screen/blank screen 없음
|
||||
- 생성형 mock UI 없음
|
||||
- 실사용자 PII, reviewer credential, token, 실제 회의 내용 없음
|
||||
- 화면의 모든 기능이 같은 Play 설치본에서 실제 접근 가능
|
||||
- crop/자막을 쓰더라도 실제 UI를 가리거나 기능을 과장하지 않음
|
||||
|
||||
### P1 — Forgejo 공개 배포 복구
|
||||
|
||||
1. `linux-builder` runner service/registration/labels/capacity를 복구한다.
|
||||
2. 새 commit이나 push를 만들지 않는다.
|
||||
3. run #46만 재실행한다.
|
||||
4. public `release-identity.json`의 commit이
|
||||
`4872d6f6c50a15104792fb31a97176527c3cd9a2`인지 확인한다.
|
||||
5. version이 `1.1.0`인지 확인한다.
|
||||
6. root/privacy/terms/delete-account가 HTTPS 200인지 확인한다.
|
||||
7. download page에서 stale `v1.0.0 STABLE`과 unsigned `Signed & Verified`
|
||||
문구가 사라졌는지 확인한다.
|
||||
8. `assetlinks.json`이 Play app-signing SHA만 포함하고 upload SHA를 포함하지
|
||||
않는지 확인한다.
|
||||
|
||||
### P1 — Windows 공개 릴리즈
|
||||
|
||||
1. public-trust Windows code-signing certificate를 준비한다.
|
||||
2. expected signer subject를 CI secret와 gate에 설정한다.
|
||||
3. installer와 unpacked exe 모두 Authenticode `Valid`를 검증한다.
|
||||
4. 설치된 앱, registry, updater feed, visible version까지 E2E한다.
|
||||
5. 그 이후에만 `v1.1.0` tag/release/updater publish를 진행한다.
|
||||
|
||||
## 7. 재개 전 사실 확인
|
||||
|
||||
저장소 루트 PowerShell:
|
||||
|
||||
```powershell
|
||||
git status --short
|
||||
git rev-parse HEAD
|
||||
git rev-parse origin/main
|
||||
git rev-parse chanpaca/main
|
||||
git ls-remote origin refs/heads/main
|
||||
git ls-remote chanpaca refs/heads/main
|
||||
adb devices -l
|
||||
Get-NetTCPConnection -LocalPort 8081 -State Listen -ErrorAction SilentlyContinue
|
||||
docker ps --format '{{.Names}}' | Select-String 'supabase_.*d3ro-voice'
|
||||
npm run release:metadata
|
||||
npm run release:play:assets
|
||||
npm run release:mobile:boundary
|
||||
```
|
||||
|
||||
기대 기준:
|
||||
|
||||
- 세 Git SHA가 모두 `4872d6f6c50a15104792fb31a97176527c3cd9a2`
|
||||
- 기존 `emulator-5554` 외 새 캡처 emulator는 자동으로 실행돼 있지 않음
|
||||
- Metro 8081 listener 없음
|
||||
- local Supabase containers 없음
|
||||
- release metadata/assets/boundary GREEN
|
||||
|
||||
## 8. 캡처 AVD 재개 명령
|
||||
|
||||
이 명령은 **debug 진단용**이다. 최종 스토어 캡처는 Play-signed 설치본으로 한다.
|
||||
|
||||
```powershell
|
||||
$emulatorExe = "$env:ANDROID_SDK_ROOT\emulator\emulator.exe"
|
||||
Start-Process -FilePath $emulatorExe -ArgumentList @(
|
||||
'-avd', 'D3RO_PlayCapture_20260829',
|
||||
'-port', '5556',
|
||||
'-no-snapshot-save',
|
||||
'-no-boot-anim',
|
||||
'-gpu', 'auto'
|
||||
)
|
||||
|
||||
adb -s emulator-5556 wait-for-device
|
||||
adb -s emulator-5556 shell getprop sys.boot_completed
|
||||
adb -s emulator-5556 shell wm size 1080x1920
|
||||
```
|
||||
|
||||
Debug + Metro가 필요할 때만:
|
||||
|
||||
```powershell
|
||||
Set-Location apps/mobile-rn
|
||||
npm run start -- --port 8081
|
||||
adb -s emulator-5556 reverse tcp:8081 tcp:8081
|
||||
adb -s emulator-5556 install -r android/app/build/outputs/apk/debug/app-debug.apk
|
||||
adb -s emulator-5556 shell am start -W -n com.d3ro.voice/.MainActivity
|
||||
```
|
||||
|
||||
실제 화면 캡처 기본형:
|
||||
|
||||
```powershell
|
||||
adb -s emulator-5556 shell screencap -p /sdcard/d3ro-capture.png
|
||||
adb -s emulator-5556 pull /sdcard/d3ro-capture.png <VERIFIED_OUTPUT_PATH>
|
||||
```
|
||||
|
||||
중단:
|
||||
|
||||
```powershell
|
||||
adb -s emulator-5556 emu kill
|
||||
supabase stop --workdir D:\workspace\D3ROVoice\server
|
||||
```
|
||||
|
||||
## 9. 인증서와 identity 기준
|
||||
|
||||
Play app-signing SHA-256:
|
||||
|
||||
```text
|
||||
01:00:19:21:DB:4F:33:40:85:CE:21:E4:B8:DE:CC:BD:
|
||||
71:DA:87:67:C5:6E:3B:59:83:2A:A1:C8:29:EA:0D:AB
|
||||
```
|
||||
|
||||
Upload key SHA-256:
|
||||
|
||||
```text
|
||||
4F:AC:69:24:82:1C:50:DA:AB:ED:76:49:32:A5:3C:48:
|
||||
6F:8C:6C:5F:34:B9:F1:8D:B9:20:AA:40:99:15:2B:54
|
||||
```
|
||||
|
||||
두 값은 서로 달라야 한다. Firebase에는 Google/FCM/auth 요구에 맞춰 필요한
|
||||
Play app-signing 및 upload certificate fingerprint를 명확히 구분해 등록한다.
|
||||
`assetlinks.json`에는 Play가 최종 사용자 APK에 적용하는 app-signing SHA만 둔다.
|
||||
|
||||
## 10. 외부 변경과 확인 경계
|
||||
|
||||
다음은 action-time 사용자 확인 후에만 한다.
|
||||
|
||||
- Firebase project 최종 생성
|
||||
- Firebase Android app 등록과 persistent API identity 생성
|
||||
- GitLab secret/protected variable 생성·변경
|
||||
- Play internal/closed/production track AAB 업로드와 저장
|
||||
- App content, Data safety, 등급, 금융 기능, FGS, AI/UGC 선언 저장
|
||||
- reviewer credential 입력
|
||||
- merchant/payment/tax profile 변경
|
||||
- production review 제출·staged rollout
|
||||
- public tag/release/updater publish
|
||||
- cloud account/project/API key 삭제
|
||||
|
||||
## 11. 금지 사항
|
||||
|
||||
- `00-launch.png`, `01-runtime.png`, `02-after-bootstrap.png`를 Play 최종
|
||||
스크린샷으로 업로드하지 않는다.
|
||||
- feature graphic을 앱 스크린샷이라고 부르지 않는다.
|
||||
- 생성 이미지, mock UI, 로그인/초대 failure evidence를 제품 스크린샷으로 쓰지 않는다.
|
||||
- debug/E2E APK, sideload installer, self-signed certificate를 production 증거로 쓰지 않는다.
|
||||
- 실제 사용자의 이메일, 토큰, 음성, 전사, 회의, 팀을 캡처에 노출하지 않는다.
|
||||
- unknown/nontracked keystore를 비밀번호 추측으로 사용하지 않는다.
|
||||
- public-trust Windows certificate 없이 stable tag/release를 만들지 않는다.
|
||||
- Forgejo runner failure에 새 commit/push를 반복하지 않는다.
|
||||
- dirty worktree 전체를 stage/commit/reset/restore/clean하지 않는다.
|
||||
- legal/Data safety/production 제출을 자동 진행하지 않는다.
|
||||
|
||||
## 12. 소스 오브 트루스
|
||||
|
||||
- 모바일 완료 상태: `docs/v3/MOBILE_APP_COMPLETION_SSOT.md`
|
||||
- 이전 제품화 핸드오프: `docs/v3/MOBILE_PRODUCTIZATION_HANDOFF_2026-08-21.md`
|
||||
- Play 패키지 안내: `docs/v3/play/README.md`
|
||||
- Play 등록정보: `docs/v3/play/01-store-listing.md`
|
||||
- Data safety 초안: `docs/v3/play/02-data-safety-draft.md`
|
||||
- App content 초안: `docs/v3/play/03-app-content-draft.md`
|
||||
- 출시 체크리스트: `docs/v3/play/04-release-checklist.md`
|
||||
- 신고 운영: `docs/v3/play/05-content-reporting-operations.md`
|
||||
- version SSOT: `release/product-version.json`
|
||||
- Android release identity: `release/android-release-identity.json`
|
||||
- CI production job: `.gitlab-ci.yml`의 `mobile-production-release`
|
||||
- Play asset verifier: `scripts/ci/verify-play-store-assets.mjs`
|
||||
- release metadata verifier: `scripts/ci/verify-release-metadata.mjs`
|
||||
- mobile boundary verifier: `scripts/ci/verify-mobile-release-boundary.mjs`
|
||||
|
||||
## 13. 내일 첫 체크포인트
|
||||
|
||||
내일은 Play Console부터 만지지 않는다. 다음 순서로 시작한다.
|
||||
|
||||
1. Git/프로세스/AVD/local stack 상태 재확인
|
||||
2. 이 문서의 `새로 발견된 것`을 재현 가능한 issue로 분리
|
||||
3. production-like cold start에서 red screen/blank screen이 없는지 먼저 검증
|
||||
4. Firebase/signing/AAB gate를 닫음
|
||||
5. Play-signed install에서 핵심 기능 E2E
|
||||
6. 그 뒤 실제 스토어 스크린샷 촬영과 Play draft 업로드
|
||||
|
||||
이 순서를 바꾸지 않는다.
|
||||
|
||||
## 14. 2026-08-30 재개 감사
|
||||
|
||||
이 절은 2026-08-29의 중단 스냅샷을 지우지 않고, 다음 날 다시 확인한 현재
|
||||
상태와 새 작업을 추가한다. 이 절의 사실이 앞 절의 역사적 상태와 충돌하면 이
|
||||
절을 우선한다.
|
||||
|
||||
### 14.1 현재 상태 재검증
|
||||
|
||||
- local `main`, `HEAD`, local `origin/main`, local `chanpaca/main`, 실제
|
||||
`origin/main`은 계속
|
||||
`4872d6f6c50a15104792fb31a97176527c3cd9a2`다.
|
||||
- 실제 `chanpaca/main` 조회와 Forgejo public/LAN API, run #46 API는 timeout이라
|
||||
현재 원격 상태를 확정하지 못했다. remote-tracking ref만으로 최신 원격 상태를
|
||||
주장하지 않는다.
|
||||
- 작업 트리는 198개 변경이며 staged는 0개다. 2026-08-29의 197개에 이 핸드오프
|
||||
문서 자체가 untracked로 추가된 수치다. 전체 stage/reset/restore/clean 금지는
|
||||
그대로다.
|
||||
- Android emulator와 emulator/qemu 프로세스는 0개다. 전용
|
||||
`D3RO_PlayCapture_20260829` AVD와 userdata는 디스크에 남아 있다.
|
||||
`emulator-5554`는 현재 연결돼 있지 않으므로 앞 절의 "연결 상태로 보존"은
|
||||
2026-08-29 종료 시점의 역사적 사실로만 본다.
|
||||
- Fold6 무선 ADB endpoint가 두 줄로 보이지만 같은 물리기기다. 이를 두 대의
|
||||
기기 증거로 세지 않는다.
|
||||
- Metro 8081 listener와 D3ROVoice Supabase container는 없다. DB/storage/
|
||||
edge-runtime Docker volume은 남아 있지만 이번 감사에서 내용 무결성까지 다시
|
||||
검증한 것은 아니다.
|
||||
- Firebase CLI와 GCP에서 exact `d3ro-voice-production` project는 없거나 현재
|
||||
계정에서 접근 불가임을 확인했다. Firebase project 생성은 여전히 action-time
|
||||
승인 대상이다.
|
||||
- 현재 인앱 Play Console 세션은 `TWENTYOZ` 조직 계정이며 6개 앱 목록에
|
||||
`com.d3ro.voice`와 Play app ID `4976102237698469110`이 없다. 이 계정에서는
|
||||
변경하지 않았다. Chrome 세션도 올바른 개인 개발자 계정으로 연결돼 있지 않다.
|
||||
다음 단계 전에 해당 앱을 보유한 개인 Play 계정 로그인이 필요하다.
|
||||
- GitLab browser 세션은 로그인돼 있지 않고 저장된 Git credential로 variables API
|
||||
조회도 401이었다. 따라서 production CI variable 존재 여부를 추측하지 않는다.
|
||||
|
||||
### 14.2 production-like cold start 진단
|
||||
|
||||
기존 `app-e2e.apk`를 전용 `emulator-5556`에 clean install해 Metro와 local
|
||||
Supabase 없이 cold start했다.
|
||||
|
||||
- artifact: `apps/mobile-rn/android/app/build/outputs/apk/e2e/app-e2e.apk`
|
||||
- version: `0.0.0-e2e.20260829.1` / `202608291`
|
||||
- SHA-256: `0D20ABB8C87B088C308E2379A91448F051C13B3778C1D79962C5D004B0F5BABE`
|
||||
- `DEBUGGABLE=false`, `assets/index.android.bundle` 포함
|
||||
- signer: Android Debug
|
||||
- 판정: embedded-bundle 시작 진단용 TEST-DEMO이며 production/Play 증거가 아님
|
||||
|
||||
진단 원본은 `scratch/mobile-release-coldstart-20260830/`에 둔다.
|
||||
|
||||
| 프레임 | SHA-256 | 관찰 |
|
||||
| ------------------- | ------------------------------------------------------------------ | ------------------------------------------ |
|
||||
| `frame-00330ms.png` | `0D718DB0947DD7CDD598C13DA36EF06440A12ED418B9ACABE28806832678C2AC` | Android launch splash와 실제 launcher icon |
|
||||
| `frame-01828ms.png` | `163BC50C7AA0EB8227E7803719454256B5255359A5CB2FD6E2326878B26D23CA` | 앱 bootstrap spinner |
|
||||
| `frame-02526ms.png` | `3A9C6F58B2CD0FBA33D39074D659FEB6A4B2807FF8E6CD9BD8EE7DD0CBE2B624` | onboarding 1/5 표시 |
|
||||
| `frame-08003ms.png` | `DE53F4EF82F6D1714E9D13CA2B02104FE3F4C71015C3F689ED4DE3CDFF924BAA` | 같은 onboarding이 안정적으로 유지됨 |
|
||||
|
||||
Android log의 `Displayed com.d3ro.voice/.MainActivity`는 `+1s606ms`였다. fatal
|
||||
exception, red screen, `Unable to load script`, 흰 화면 고착은 재현되지 않았다.
|
||||
Firebase 미구성 경고와 새 설치의 Keychain entry 없음 로그는 남았으며 production
|
||||
Firebase 설치본에서 다시 확인해야 한다. 진단 뒤 `emulator-5556`을 다시 종료했고
|
||||
Metro/Supabase는 시작하지 않았다.
|
||||
|
||||
따라서 2026-08-29의 빈 흰 화면은 현재까지 debug+Metro bootstrap에서 본
|
||||
증거다. embedded bundle 경로의 영구 결함으로 일반화하지 않는다. production
|
||||
Play-signed 설치본의 cold start 검증은 여전히 RED다.
|
||||
|
||||
### 14.3 새로 확인한 release artifact 경계
|
||||
|
||||
- 저장소 어디에도 production AAB가 없다.
|
||||
- 저장소/CI 작업 디렉터리에 materialize된 `google-services.json`,
|
||||
`android/app/release.keystore`, release evidence private key, release
|
||||
snapshot/publication은 없다.
|
||||
- 저장소 밖 upload PKCS12와 Ed25519 evidence private key는 실제로 남아 있다.
|
||||
`verify-windows-android-upload-key.ps1`은 alias
|
||||
`d3ro-upload-20260821`, certificate SHA-256
|
||||
`4F:AC:69:24:82:1C:50:DA:AB:ED:76:49:32:A5:3C:48:6F:8C:6C:5F:34:B9:F1:8D:B9:20:AA:40:99:15:2B:54`,
|
||||
private-key readback과 Credential Manager target을 다시 GREEN으로 확인했다.
|
||||
evidence keypair도 keyId
|
||||
`2797d3e63affd2348941bc2871b57e520c958f7f5da1a4bbe8aa46904a890b7f`와
|
||||
sign/verify roundtrip이 GREEN이다. 없는 것은 CI secret materialization,
|
||||
offline 복구 백업, 실제 AAB signer/evidence다.
|
||||
- `npm run release:mobile:config`는 실제 production config가 없으므로
|
||||
`google_services_file_unreadable`로 fail-closed한다.
|
||||
- 기존 `android/app/build/outputs/apk/release/app-release.apk`는 2026-08-20의
|
||||
오래된 `1.0/1`이다. SHA-256은
|
||||
`8530D5ABEE72DB00E332B1362D5B3568CFBD080405D15DC27125F66E18A354B3`, signer
|
||||
SHA-256은 `06EEC757...2E481`이며 현재 verifier가 차단한다. 필수 Whisper
|
||||
model도 없어 `missing_entry_assets/models/ggml-tiny.bin`으로 실패한다.
|
||||
절대 재사용하지 않는다.
|
||||
- local Node는 `.nvmrc`의 `24.19.0`이 아니라 `23.4.0`이다. production artifact는
|
||||
이 dirty local checkout에서 만들지 않고 고정된 CI image/toolchain에서 만든다.
|
||||
|
||||
### 14.4 AAB/tag 교착의 소스 수정
|
||||
|
||||
기존 GitLab job은 exact stable tag가 있어야만 production AAB를 만들 수 있었지만,
|
||||
이 문서는 Windows public-trust signing 전 stable tag를 금지했다. 이 순서는 실행
|
||||
불가능했다.
|
||||
|
||||
다음 두 파일을 좁게 수정했다.
|
||||
|
||||
- `.gitlab-ci.yml`
|
||||
- `scripts/ci/verify-mobile-release-boundary.mjs`
|
||||
|
||||
새 계약:
|
||||
|
||||
- protected exact `main`에서는 `mobile-production-release`를 수동 실행해
|
||||
Maintainer 전용 candidate AAB/evidence만 만든다.
|
||||
- branch candidate evidence ref는 `refs/heads/main`이다.
|
||||
- exact stable semver tag 경로는 계속 지원하며 tag evidence ref를 쓴다.
|
||||
- `publish-release`는 계속 tag-only다. main candidate가 public release를
|
||||
트리거하지 않는다.
|
||||
|
||||
mobile boundary self-test, release metadata self-test, YAML parser 2종, job shell
|
||||
syntax, `git diff --check`는 GREEN이다. 두 코드 파일은 staged/committed/pushed되지
|
||||
않았고 이 핸드오프 문서도 untracked다. 사용자 확인 후 이 세 파일만 좁게
|
||||
commit/push해야 실제 GitLab candidate job을 사용할 수 있다.
|
||||
|
||||
### 14.5 Play-signed 캡처 기기 교착
|
||||
|
||||
현재 production release 계약은 `arm64-v8a`만 허용하지만 전용 Pixel 7 AVD는
|
||||
`x86_64`다. 따라서 현 AAB의 Play-signed APK를 이 AVD에 설치할 수 있다고
|
||||
가정하면 안 된다.
|
||||
|
||||
Google Play의 현재 공식 요구는 휴대전화 screenshot의 최소 변 320px, 최대 변
|
||||
3840px, 긴 변이 짧은 변의 2배 이하이며, 추천 노출은 1080×1920 이상의 9:16
|
||||
세로 이미지 4장 이상이다. 실제 앱 경험을 보여야 한다.
|
||||
|
||||
- 규격 근거:
|
||||
`https://support.google.com/googleplay/android-developer/answer/9866151`
|
||||
- Play-signed universal/device APK 근거:
|
||||
`https://support.google.com/googleplay/android-developer/answer/9844279`
|
||||
|
||||
최종 선택지는 다음 중 하나를 production AAB 전에 확정한다.
|
||||
|
||||
1. arm64 Fold6에 Play internal 설치 후 실제 UI를 왜곡하지 않는 9:16 store
|
||||
canvas로 구성하고 Console 수락을 검증한다.
|
||||
2. release AAB에 검증된 `x86_64` 지원을 추가하고 verifier/CI/실기기 matrix를
|
||||
함께 확장한 뒤 전용 AVD에서 Play 설치를 검증한다.
|
||||
|
||||
단순 crop/stretch, debug/E2E 재촬영, installer/certificate 검증 없는 sideload는
|
||||
대안이 아니다.
|
||||
|
||||
### 14.6 현재 재개 순서와 승인 요청
|
||||
|
||||
1. 위 두 CI 파일과 이 핸드오프 문서의 좁은 commit/push를 승인받는다.
|
||||
2. Firebase project `d3ro-voice-production` 최종 생성과 Android app
|
||||
`com.d3ro.voice` 등록을 action-time 승인받는다.
|
||||
3. 올바른 개인 Play Console 계정과 GitLab Maintainer 세션에 로그인한다.
|
||||
4. Firebase fingerprints/config를 검증하고 GitLab protected/masked/hidden
|
||||
variables를 구성한다.
|
||||
5. protected exact `main` candidate job과 emulator prerequisite를 실행한다.
|
||||
6. AAB/evidence를 독립 검증한 뒤 별도 승인으로 Play internal track에 올린다.
|
||||
7. Play-signed arm64 설치본으로 핵심 E2E를 통과한다.
|
||||
8. 실제 UI 기반 6장만 제작·검증·업로드한다.
|
||||
9. `linux-builder`와 Forgejo 접근 경로를 복구한 뒤 run #46만 재실행한다.
|
||||
|
||||
Firebase 생성, GitLab variable 변경, Play 업로드, legal declaration, tag/public
|
||||
release는 이번 감사에서 실행하지 않았다.
|
||||
Loading…
Add table
Add a link
Reference in a new issue