docs: finalize mobile release handoff

This commit is contained in:
Yun Chan 2026-08-30 09:50:07 +09:00
parent 784c9c291e
commit aa5fc5b7d9

View file

@ -1,10 +1,15 @@
# D3RO Voice 모바일 출시 핸드오프 — 2026-08-29 # D3RO Voice 모바일 출시 핸드오프 — 2026-08-29
최종 갱신: 2026-08-30 KST. 0~14절은 시간순 증거이며 현재 판정과 재개 순서는
15절을 우선한다.
## 0. 결론 ## 0. 결론
**모바일 앱은 아직 출시 가능 상태가 아니다.** Google Play 등록정보의 텍스트, **모바일 앱은 아직 출시 가능 상태가 아니다.** Google Play 등록정보의 텍스트,
아이콘, feature graphic 초안은 준비됐지만 production AAB, Firebase Android 설정, 아이콘, feature graphic 초안과 Firebase project/Android app/config는 준비됐다.
upload signing, Play-signed 설치본, 실제 핵심 기능 E2E, 스토어용 앱 스크린샷이 없다. 그러나 Firebase SHA fingerprint와 CI secret materialization, production AAB,
upload-key로 서명된 candidate, Play-signed 설치본, 실제 핵심 기능 E2E, 스토어용
앱 스크린샷은 없다.
2026-08-29 실제 `1.1.0` debug 앱을 새 Pixel 7 에뮬레이터에서 열어 보니 다음을 2026-08-29 실제 `1.1.0` debug 앱을 새 Pixel 7 에뮬레이터에서 열어 보니 다음을
확인했다. 확인했다.
@ -15,7 +20,9 @@ upload signing, Play-signed 설치본, 실제 핵심 기능 E2E, 스토어용
- 인증 세션이 없어 녹음·전사·AI·팀 화면에는 진입하지 못했다. - 인증 세션이 없어 녹음·전사·AI·팀 화면에는 진입하지 못했다.
- production/Play-signed 설치본이 아니므로 이번 캡처는 Google Play 제출물이 아니다. - production/Play-signed 설치본이 아니므로 이번 캡처는 Google Play 제출물이 아니다.
사용자 요청에 따라 작업은 여기서 중단했다. `/goal`은 완료로 처리하지 않는다. 2026-08-29에는 사용자 요청에 따라 출시 실행을 중단했다. 이 핸드오프 문서는
15절의 closeout으로 마무리하되, 제품 출시 자체를 완료 또는 production-ready로
처리하지 않는다.
## 1. 중단 상태 ## 1. 중단 상태
@ -26,7 +33,7 @@ upload signing, Play-signed 설치본, 실제 핵심 기능 E2E, 스토어용
| 전용 캡처 AVD | `D3RO_PlayCapture_20260829` 생성됨, `emulator-5556` 종료됨 | | 전용 캡처 AVD | `D3RO_PlayCapture_20260829` 생성됨, `emulator-5556` 종료됨 |
| 기존 AVD | `emulator-5554`만 연결 상태로 보존. 기존 `0.0.0-e2e` 데이터는 건드리지 않음 | | 기존 AVD | `emulator-5554`만 연결 상태로 보존. 기존 `0.0.0-e2e` 데이터는 건드리지 않음 |
| Metro | `localhost:8081` listener 없음 | | Metro | `localhost:8081` listener 없음 |
| 로컬 Supabase | `supabase stop --workdir server` 완료, local data는 Docker volume에 백업됨 | | 로컬 Supabase | `supabase stop --workdir server` 완료, local Docker volume 보존 |
| Android 앱 프로세스 | 전용 `emulator-5556` 종료로 함께 중단 | | Android 앱 프로세스 | 전용 `emulator-5556` 종료로 함께 중단 |
| Play Console | 더 이상 변경하지 않음. 기본 등록정보 페이지는 초안 상태 | | Play Console | 더 이상 변경하지 않음. 기본 등록정보 페이지는 초안 상태 |
| Firebase | 프로젝트 생성 버튼을 누르지 않음. 신규 Firebase 프로젝트 없음 | | Firebase | 프로젝트 생성 버튼을 누르지 않음. 신규 Firebase 프로젝트 없음 |
@ -360,6 +367,8 @@ production/Play-signed 재촬영 전에는 참고 증거일 뿐이다.
### P0 — 앱을 먼저 검증한다 ### P0 — 앱을 먼저 검증한다
이 절은 2026-08-29의 역사적 계획이다. 현재 실행 순서는 15.5절로 대체됐다.
1. 아래 `재개 전 사실 확인` 명령을 실행한다. 1. 아래 `재개 전 사실 확인` 명령을 실행한다.
2. Firebase project/app 생성에 대한 action-time 승인을 다시 받는다. 2. Firebase project/app 생성에 대한 action-time 승인을 다시 받는다.
3. Firebase Android app `com.d3ro.voice`를 등록한다. 3. Firebase Android app `com.d3ro.voice`를 등록한다.
@ -444,10 +453,13 @@ npm run release:mobile:boundary
기대 기준: 기대 기준:
- 세 Git SHA가 모두 `4872d6f6c50a15104792fb31a97176527c3cd9a2` - local `HEAD`와 실제 `origin/main`이 일치한다. `chanpaca/main`은 Forgejo
runner/public deploy 복구 전까지 이전 public baseline일 수 있으므로 세 SHA가
같다고 가정하지 않는다.
- 기존 `emulator-5554` 외 새 캡처 emulator는 자동으로 실행돼 있지 않음 - 기존 `emulator-5554` 외 새 캡처 emulator는 자동으로 실행돼 있지 않음
- Metro 8081 listener 없음 - Metro 8081 listener 없음
- local Supabase containers 없음 - D3RO Voice local Supabase containers 없음. 다른 프로젝트의 local Supabase
container는 이 판정에 포함하지 않는다.
- release metadata/assets/boundary GREEN - release metadata/assets/boundary GREEN
## 8. 캡처 AVD 재개 명령 ## 8. 캡처 AVD 재개 명령
@ -561,6 +573,8 @@ Play app-signing 및 upload certificate fingerprint를 명확히 구분해 등
## 13. 내일 첫 체크포인트 ## 13. 내일 첫 체크포인트
이 절은 2026-08-29의 역사적 체크포인트다. 현재 실행 순서는 15.5절을 따른다.
내일은 Play Console부터 만지지 않는다. 다음 순서로 시작한다. 내일은 Play Console부터 만지지 않는다. 다음 순서로 시작한다.
1. Git/프로세스/AVD/local stack 상태 재확인 1. Git/프로세스/AVD/local stack 상태 재확인
@ -717,6 +731,8 @@ Google Play의 현재 공식 요구는 휴대전화 screenshot의 최소 변 320
### 14.6 현재 재개 순서와 승인 요청 ### 14.6 현재 재개 순서와 승인 요청
이 승인 전 순서는 15.5절로 대체됐다.
1. 위 두 CI 파일과 이 핸드오프 문서의 좁은 commit/push를 승인받는다. 1. 위 두 CI 파일과 이 핸드오프 문서의 좁은 commit/push를 승인받는다.
2. Firebase project `d3ro-voice-production` 최종 생성과 Android app 2. Firebase project `d3ro-voice-production` 최종 생성과 Android app
`com.d3ro.voice` 등록을 action-time 승인받는다. `com.d3ro.voice` 등록을 action-time 승인받는다.
@ -735,7 +751,7 @@ release는 이번 감사에서 실행하지 않았다.
## 15. 2026-08-30 승인 후 실행과 production 판정 ## 15. 2026-08-30 승인 후 실행과 production 판정
이 절은 14절 작성 뒤 사용자가 명시적으로 승인한 작업과 병렬 production 감사를 이 절은 14절 작성 뒤 사용자가 명시적으로 승인한 작업과 병렬 production 감사를
기록한다. 14절의 승인 전 스냅샷과 충돌하면 이 절을 우선한다. 기록한다. 0~14절의 역사적 또는 승인 전 스냅샷과 충돌하면 이 절을 우선한다.
### 15.1 승인 후 실제로 실행한 것 ### 15.1 승인 후 실제로 실행한 것
@ -746,8 +762,13 @@ release는 이번 감사에서 실행하지 않았다.
- `.gitlab-ci.yml` - `.gitlab-ci.yml`
- `scripts/ci/verify-mobile-release-boundary.mjs` - `scripts/ci/verify-mobile-release-boundary.mjs`
- `docs/v3/MOBILE_RELEASE_HANDOFF_2026-08-29.md` - `docs/v3/MOBILE_RELEASE_HANDOFF_2026-08-29.md`
- 실제 `origin/main``1f71cf6faeb209c85b49a0260312897a25cc41d9` - 후속 audit 결과는 이 핸드오프 문서만 별도 closeout commit으로 반영했다.
확인했다. unrelated dirty worktree는 stage/reset/clean하지 않았다. 최신 commit은 문서 안에 self-reference로 고정하지 않고 `git rev-parse HEAD`
`git ls-remote origin refs/heads/main`의 일치로 확인한다. unrelated dirty
worktree는 stage/reset/clean하지 않았다.
- `origin` push는 성공했지만 최신 commit의 GitLab pipeline ID/job 결과는
로그인 전이라 확인하지 않았다. 과거 pipeline `72066`과 local verifier GREEN을
최신 CI GREEN으로 재사용하지 않는다.
- Firebase production project를 생성했다. - Firebase production project를 생성했다.
- project ID: `d3ro-voice-production` - project ID: `d3ro-voice-production`
- project number: `1013351450402` - project number: `1013351450402`
@ -869,6 +890,8 @@ low-RAM 실기기 profiling이 필요하다.
### 15.5 다음 실행 순서 ### 15.5 다음 실행 순서
이 절이 6절, 13절, 14.6절의 이전 순서를 대체한다.
1. HIGH 인증·계정 삭제·계정 간 local data 경계를 먼저 수정하고 적대적/failure 1. HIGH 인증·계정 삭제·계정 간 local data 경계를 먼저 수정하고 적대적/failure
injection 테스트를 추가한다. injection 테스트를 추가한다.
2. 개인정보처리방침·Data safety와 실제 audio/cache 흐름을 하나의 계약으로 2. 개인정보처리방침·Data safety와 실제 audio/cache 흐름을 하나의 계약으로
@ -888,3 +911,101 @@ low-RAM 실기기 profiling이 필요하다.
위 항목 전에는 공개 출시, production-ready 선언, stable tag/public release, 위 항목 전에는 공개 출시, production-ready 선언, stable tag/public release,
debug/E2E 캡처의 store 제출을 금지한다. debug/E2E 캡처의 store 제출을 금지한다.
### 15.6 핸드오프 최종 종료 상태
- Android emulator/qemu process: `0`
- ADB emulator serial: 없음. Fold6 wireless ADB endpoint 두 줄은 같은 물리기기다.
- Metro `localhost:8081` listener: `0`
- D3RO Voice local Supabase container: `0`
- 보존된 local volume:
- `supabase_db_d3ro-voice`
- `supabase_storage_d3ro-voice`
- `supabase_edge_runtime_d3ro-voice`
- 별도 stop-state archive:
`D:\workspace\_backups\D3ROVoice\local-supabase-stop-20260830\`
- archive manifest:
`D:\workspace\_backups\D3ROVoice\local-supabase-stop-20260830\MANIFEST.md`
- 세 archive는 source volume을 read-only mount해 만들었고 SHA-256을 기록한 뒤
전체 `tar -tzf` listing exit `0`으로 검증했다.
- 캡처 3개의 실파일·화면 내용·SHA-256은 다시 대조해 원장과 일치했다. 다만
`docs/v3/play/assets/screenshots/`는 여전히 untracked이므로 remote clone에
보존된 증거라고 주장하지 않는다. owner가 별도 보존 방식을 결정할 때까지
local evidence로만 취급한다.
- 전용 `emulator-5556`, Metro, local Supabase를 다시 시작하지 않았다.
- Play 제출, CI secret 변경, legal declaration, stable tag/public release,
Forgejo 재배포는 없다.
### 15.7 정확한 재개 명령
먼저 저장소 루트 PowerShell에서 read-only/current-state 검사를 실행한다.
```powershell
git status --short
git rev-parse HEAD
git ls-remote origin refs/heads/main
adb devices -l
Get-NetTCPConnection -LocalPort 8081 -State Listen -ErrorAction SilentlyContinue
docker ps --format '{{.Names}}' | Select-String 'supabase_.*d3ro-voice'
firebase projects:list
firebase apps:list ANDROID --project d3ro-voice-production
firebase apps:android:sha:list 1:1013351450402:android:4d9d0f675b12ee09bf477b `
--project d3ro-voice-production
supabase migration list --linked --workdir server
supabase functions list --workdir server
supabase db push --linked --workdir server --dry-run
```
보안 경계 수정 뒤 최소 local regression gate:
```powershell
npm run security:secrets:test
npm run security:secrets
npm run release:mobile:boundary:test
npm run release:mobile:boundary
npm --prefix apps/mobile-rn run lint
npm --prefix apps/mobile-rn run typecheck
npm --prefix apps/mobile-rn run test:ci
npm --prefix apps/mobile-rn audit --omit=dev
```
다음 production backend 변경 명령은 migration/function diff와 대상 project를
다시 확인하고 **action-time 승인 후에만** 실행한다.
```powershell
supabase db push --linked --workdir server
supabase functions deploy content-report --workdir server
```
GitLab에서는 올바른 Maintainer 계정으로 로그인한 뒤 protected exact `main`
manual `mobile-production-release` job만 실행한다. secret file을 local shell에
복사하지 않는다. job의 전체 명령과 artifact 목록은 `.gitlab-ci.yml`의 같은 job을
소스 오브 트루스로 사용한다.
Maintainer artifact를 별도 검증 디렉터리에 내려받은 뒤:
```powershell
$identity = Get-Content release/android-release-identity.json | ConvertFrom-Json
$product = Get-Content release/product-version.json | ConvertFrom-Json
node scripts/ci/verify-android-artifact.mjs `
--mode release `
--apk <VERIFIED_ARTIFACT_DIR>\app-release.apk `
--aab <VERIFIED_ARTIFACT_DIR>\app-release.aab `
--bundletool <VERIFIED_BUNDLETOOL_JAR> `
--expected-admob-app-id $identity.adMobAppId `
--expected-upload-cert-sha256 $identity.uploadCertificateSha256 `
--expected-version-name $product.version `
--expected-version-code $product.androidVersionCode
Get-FileHash <VERIFIED_ARTIFACT_DIR>\app-release.apk -Algorithm SHA256
Get-FileHash <VERIFIED_ARTIFACT_DIR>\app-release.aab -Algorithm SHA256
```
Play internal upload은 별도 승인 뒤 수행한다. Play가 서명한 Fold6 설치본에서
installer/version/debuggable/signing identity를 먼저 증명한다.
```powershell
adb -s <FOLD6_SERIAL> shell pm list packages -i com.d3ro.voice
adb -s <FOLD6_SERIAL> shell dumpsys package com.d3ro.voice
```
그 뒤에만 15.5절의 provider·failure·접근성 matrix와 6장 캡처를 진행한다.