feat(play): finalize store graphics and copy

This commit is contained in:
Yun Chan 2026-08-29 20:11:54 +09:00
parent 563d4cb1de
commit 0a8cf4396f
9 changed files with 316 additions and 92 deletions

View file

@ -31,28 +31,66 @@ D3RO Voice
### 전체 설명
```text
한 내용을 놓치지 않고, 다시 활용할 수 있는 기록으로 바꿔보세요.
하는 동안에는 대화에 집중하세요.
D3RO Voice는 음성 녹음과 미디어 가져오기, 전사, AI 보조 문서화, 메모와 팀 협업을 한곳에서 이어주는 생산성 앱입니다.
D3RO Voice가 음성 녹음부터 전사, AI 보조 문서화, 메모와 팀 공유까지 하나의 흐름으로 이어줍니다. 음성을 남기는 데서 끝내지 않고, 다시 찾고 정리해 다음 작업에 활용할 수 있는 기록으로 바꿔보세요.
주요 기능
• 마이크 녹음: 지속 알림에서 녹음 상태를 확인하고 일시정지, 재개, 중지 또는 폐기할 수 있습니다.
• 음성·미디어 가져오기: 앱이 검증할 수 있는 오디오 형식과 MP4 파일을 선택해 처리할 수 있습니다.
• 전사 경로: 인증된 클라우드 전사를 사용하고, 지원되는 Android 환경에서는 제공자 장애 시 기기 내 전사를 대체 경로로 사용합니다.
• 회의와 기록: 전사문, 회의록, 메모, 템플릿과 생성 문서를 계정에 정리합니다.
• AI 보조: 대화형 AI와 문서 생성 기능으로 전사 내용을 요약하고 다음 작업을 구체화할 수 있습니다.
• 팀 협업: 초대한 팀원과 팀 회의 및 관련 기록을 공유하고 역할을 관리할 수 있습니다.
• 데이터 관리: 계정 데이터 내보내기·복원, 기기 관리와 계정 삭제 경로를 제공합니다.
D3RO VOICE로 할 수 있는 일
요금제와 광고
Free 요금제에는 Google AdMob 배너 광고가 표시될 수 있습니다. 사용자가 선택해 보상형 광고를 완료하면 서버 검증 후 앱 내부 AI 사용량 크레딧을 받을 수 있습니다. 선택형 Google Play 구독은 추가 사용량과 광고 없는 이용 환경을 제공할 수 있습니다. 실제 가격과 갱신 조건은 구매 화면과 Google Play 결제 창에 표시됩니다.
• 바로 녹음하기
마이크 녹음을 시작하면 지속 알림에서 상태를 확인하고 일시정지, 재개, 중지 또는 폐기할 수 있습니다.
개인정보와 책임 있는 사용
마이크 권한은 녹음을 시작할 때 요청합니다. 음성·텍스트는 사용자가 클라우드 기능을 실행한 경우 필요한 범위에서 처리되며, 광고 요청은 동의 및 개인정보 옵션을 확인한 뒤 시작합니다. 개인정보처리방침과 계정 삭제 경로는 앱 설정에서 언제든 확인할 수 있습니다.
• 오디오와 MP4 가져오기
앱이 직접 검증할 수 있는 지원 오디오 형식과 MP4 파일을 선택해 처리할 수 있습니다.
자동 전사와 AI 생성 결과에는 오류가 있을 수 있습니다. 중요한 사실과 결정을 직접 검토하고, 의료·법률·재무 또는 안전에 중대한 전문 조언으로 사용하지 마세요. 타인의 음성을 녹음하거나 콘텐츠를 공유할 때는 관련 법률과 필요한 동의를 지켜야 합니다.
• 상황에 맞게 전사하기
인증된 클라우드 전사를 사용합니다. 지원되는 Android 환경에서는 클라우드 제공자를 사용할 수 없을 때 기기 내 전사를 대체 경로로 사용할 수 있습니다.
• 기록을 한곳에 정리하기
전사문, 회의록, 메모, 템플릿과 생성 문서를 계정에 모아 관리합니다.
• AI로 핵심과 다음 작업 찾기
대화형 AI와 문서 생성 기능으로 전사 내용을 요약하고 후속 작업을 구체화할 수 있습니다.
• 팀과 필요한 기록 공유하기
초대한 팀원과 팀 회의 및 관련 기록을 공유하고 역할을 관리할 수 있습니다.
• 내 데이터 관리하기
계정 데이터 내보내기와 복원, 등록 기기 관리, 계정 삭제 경로를 제공합니다.
FREE 요금제, 광고 및 구독
Free 요금제에는 Google AdMob 배너 광고가 표시될 수 있습니다. 사용자가 직접 선택해 보상형 광고를 완료하면 서버 검증 후 앱 내부 AI 사용량 크레딧을 받을 수 있습니다.
선택형 Google Play 구독은 추가 사용량과 광고 없는 이용 환경을 제공할 수 있습니다. 실제 가격, 갱신 및 취소 조건은 구매 화면과 Google Play 결제 창에서 확인할 수 있습니다.
개인정보와 데이터 관리
마이크 권한은 녹음을 시작할 때 요청합니다. 음성과 텍스트는 사용자가 클라우드 기능을 실행한 경우 필요한 범위에서 처리됩니다. 광고 요청은 적용되는 동의 및 개인정보 옵션을 확인한 뒤 시작합니다.
개인정보처리방침과 계정 삭제 경로는 앱 설정에서 언제든 확인할 수 있습니다.
책임 있는 사용
자동 전사와 AI 생성 결과에는 오류가 있을 수 있습니다. 중요한 사실과 결정은 직접 검토하세요. 의료·법률·재무 또는 안전에 중대한 전문 조언으로 사용해서는 안 됩니다.
타인의 음성을 녹음하거나 콘텐츠를 공유할 때는 관련 법률을 확인하고 필요한 동의를 받아야 합니다.
```
### `ko-KR` 카피 벤치마크
2026-08-29에 Google Play의 [Google Recorder](https://play.google.com/store/apps/details?id=com.google.android.apps.recorder&hl=ko),
[Voicenotes](https://play.google.com/store/apps/details?id=com.app.voicenotes&hl=ko),
[Fireflies](https://play.google.com/store/apps/details?id=ai.fireflies.mobile&hl=ko),
[Otter](https://play.google.com/store/apps/details?id=com.aisense.otter&hl=ko),
[Notta](https://play.google.com/store/apps/details?id=com.langogo.transcribe&hl=ko),
[Dolby On](https://play.google.com/store/apps/details?id=com.dolby.dolby234&hl=ko),
[PLAUD](https://play.google.com/store/apps/details?id=ai.plaud.android.plaud&hl=ko),
[Transkriptor](https://play.google.com/store/apps/details?id=com.transkriptor.app&hl=ko)
등록정보를 대조했다. 문구를 복제하지 않고, 첫 문단에서 제품 흐름을 설명한 뒤
결과 중심 기능, 요금·광고, 개인정보, 책임 고지를 분리하는 정보 구조만 적용했다.
검증되지 않은 정확도, 처리 시간, 사용자 수, 인증 또는 최상급 표현은 사용하지 않는다.
## `en-US`
### App name
@ -70,26 +108,50 @@ Record, transcribe, and turn conversations into practical AI-assisted notes.
### Full description
```text
Turn spoken ideas into records you can review, organize, and use again.
Stay focused on the conversation while you speak.
D3RO Voice brings microphone recording, supported media import, transcription, AI-assisted documents, notes, and team collaboration into one productivity app.
D3RO Voice connects voice recording, transcription, AI-assisted documentation, notes, and team sharing in one continuous flow. Go beyond saving audio and turn it into records you can find, organize, and use for the next step.
Key features
• Microphone recording: See an ongoing notification and pause, resume, stop, or discard a recording.
• Supported media import: Select audio formats and MP4 files that the app can independently validate and process.
• Transcription paths: Use authenticated cloud transcription, with on-device transcription as a fallback on supported Android environments when the cloud provider is unavailable.
• Meetings and records: Organize transcripts, meeting notes, memos, templates, and generated documents in your account.
• AI assistance: Use conversational AI and document generation to summarize transcripts and shape follow-up work.
• Team collaboration: Share team meetings and related records with invited members and manage member roles.
• Data controls: Export or restore account data, manage registered devices, and request account deletion.
WHAT YOU CAN DO WITH D3RO VOICE
Plans and ads
The Free plan may show Google AdMob banner ads. When a user chooses to complete a rewarded ad, in-app AI usage credits are granted only after server verification. Optional Google Play subscriptions may provide additional usage and an ad-free experience. Current price, renewal, and cancellation terms are shown in the purchase screen and Google Play billing flow.
• Start recording right away
When microphone recording starts, use the ongoing notification to check its status, pause, resume, stop, or discard it.
Privacy and responsible use
Microphone permission is requested when recording starts. Audio and text are processed only as needed when the user invokes a cloud feature, and ad requests begin only after the applicable consent and privacy-options flow. The privacy policy and account-deletion path remain available from Settings.
• Import audio and MP4 files
Select supported audio formats and MP4 files that the app can independently validate and process.
Automated transcripts and AI-generated output can be incorrect. Review important facts and decisions yourself, and do not treat the output as professional medical, legal, financial, or safety advice. Follow applicable law and obtain any required consent before recording another person or sharing content.
• Transcribe through an available path
Use authenticated cloud transcription. On supported Android environments, on-device transcription can serve as a fallback when the cloud provider is unavailable.
• Keep records organized
Manage transcripts, meeting notes, memos, templates, and generated documents in your account.
• Find key points and next steps with AI
Use conversational AI and document generation to summarize transcripts and shape follow-up work.
• Share the records your team needs
Share team meetings and related records with invited members and manage member roles.
• Manage your data
Export or restore account data, manage registered devices, and access the account-deletion path.
FREE PLAN, ADS, AND SUBSCRIPTIONS
The Free plan may show Google AdMob banner ads. If a user chooses to complete a rewarded ad, in-app AI usage credits are granted only after server verification.
Optional Google Play subscriptions may provide additional usage and an ad-free experience. Current pricing, renewal, and cancellation terms are shown on the purchase screen and in the Google Play billing flow.
PRIVACY AND DATA CONTROLS
Microphone permission is requested when recording starts. Audio and text are processed only as needed when the user invokes a cloud feature. Ad requests begin only after the applicable consent and privacy-options flow.
The privacy policy and account-deletion path remain available from Settings.
RESPONSIBLE USE
Automated transcripts and AI-generated output can be incorrect. Review important facts and decisions yourself. Do not treat the output as professional medical, legal, financial, or safety advice.
Follow applicable law and obtain any required consent before recording another person or sharing content.
```
## 지원 정보
@ -109,7 +171,7 @@ Automated transcripts and AI-generated output can be incorrect. Review important
- `Free` reviewer 계정에서 배너와 보상형 광고 경로를, 별도 유료 reviewer 계정에서 광고 미요청과 구독 기능을 확인한다.
- AI 신고 source와 local tests는 구현·GREEN이지만 아직 production migration/function 배포, purge scheduler·운영 담당 연결과 Play 설치본 E2E가 없다. 이 운영 경로가 GREEN이 되기 전에는 AI 보조 문구가 포함된 등록정보를 제출하지 않는다.
- Play icon 512×512와 canonical SVG source는 `docs/v3/play/assets/`에 생성됐고 Android legacy/adaptive/monochrome launcher resource에도 반영됐다. Pixel Launcher emulator의 adaptive circle mask는 `assets/proof/d3ro-icon-pixel-launcher-20260824.png`로 확인됐다. 다만 Play-signed release 설치본과 실제 Pixel/Samsung 등 OEM mask·scale 검증은 아직 필요하다.
- feature graphic 1024×500 후보 4개와 재현·해시 기록은 `assets/feature-graphic/`에 준비됐다. 현재 권장안은 A지만 사용자 선택과 Console preview 검증 전에는 최종 자산으로 확정하지 않는다.
- feature graphic A-D 역사 후보와 imagegen canonical E의 원본·prompt·1024×500 제출본·해시는 `assets/feature-graphic/`에 준비됐다. E는 2026-08-29 Console preview에서 safe crop·thumbnail contrast·규격 경고 없음을 확인했다.
- 실제 앱 화면 스크린샷 최소 2장(권장 4장 이상)은 아직 준비해야 한다. 로그인/초대 E2E 증거 이미지는 스토어 자산으로 사용하지 않는다.
- 자막이나 합성 UI가 실제 기능을 과장하지 않는지 확인한다. [Google의 등록정보 정확성 기준](https://support.google.com/googleplay/android-developer/answer/15191715?hl=en)을 따른다.

View file

@ -4,17 +4,17 @@
### 2026-08-29 Play Console live 스냅샷
| 항목 | 확인된 현재 사실 | 판정 |
|---|---|---|
| 앱 | `D3RO Voice`, package `com.d3ro.voice`, app ID `4976102237698469110` | 생성 완료 |
| Console 상태 | `임시`; 첫 AAB 업로드 0건, 설정 0/11 | 제출 불가 |
| release identity | versionName `1.1.0`, Android versionCode `1010001` | 소스 SSOT에서 확정; AAB 증거는 아직 없음 |
| Play app-signing SHA-256 | `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` | Console 실확인 |
| upload key | 외부 PKCS12·user-only ACL·Credential Manager·private-key readback GREEN; cert 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` | local key 준비. Console 표시·AAB signer 대조는 첫 AAB 후 |
| release evidence | Ed25519 keypair roundtrip GREEN; public key·keyId `2797d3e63affd2348941bc2871b57e520c958f7f5da1a4bbe8aa46904a890b7f` SSOT | CI private-key secret·복구 백업 미완료 |
| Firebase | Google Console `u/0`, `u/1` 모두 D3RO project 없음 | 프로젝트·Android 앱 생성은 사용자 승인 필요 |
| closed test | 0명 / 요건 12명, 연속 14일 | 미시작 |
| production access | disabled | closed test와 access 신청·승인 전까지 출시 불가 |
| 항목 | 확인된 현재 사실 | 판정 |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| 앱 | `D3RO Voice`, package `com.d3ro.voice`, app ID `4976102237698469110` | 생성 완료 |
| Console 상태 | `임시`; 첫 AAB 업로드 0건, 설정 0/11 | 제출 불가 |
| release identity | versionName `1.1.0`, Android versionCode `1010001` | 소스 SSOT에서 확정; AAB 증거는 아직 없음 |
| Play app-signing SHA-256 | `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` | Console 실확인 |
| upload key | 외부 PKCS12·user-only ACL·Credential Manager·private-key readback GREEN; cert 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` | local key 준비. Console 표시·AAB signer 대조는 첫 AAB 후 |
| release evidence | Ed25519 keypair roundtrip GREEN; public key·keyId `2797d3e63affd2348941bc2871b57e520c958f7f5da1a4bbe8aa46904a890b7f` SSOT | CI private-key secret·복구 백업 미완료 |
| Firebase | Google Console `u/0`, `u/1` 모두 D3RO project 없음 | 프로젝트·Android 앱 생성은 사용자 승인 필요 |
| closed test | 0명 / 요건 12명, 연속 14일 | 미시작 |
| production access | disabled | closed test와 access 신청·승인 전까지 출시 불가 |
외부 법적·정책 선언은 일반적인 배포 지시로 대신하지 않는다. Console의 실제 문구를 사용자가 검토하고 action-time 승인하기 전에는 저장·제출하지 않는다.
@ -26,8 +26,9 @@
- [x] 기본 Android Studio launcher icon을 D3RO legacy/adaptive/monochrome icon source로 교체하고 512×512 Play icon을 만들었다.
- [x] JDK 17 양 ABI debug build와 기존 데이터 보존 update install 후 Pixel Launcher emulator의 adaptive circle mask를 확인했다.
- [ ] Play-signed release 설치본과 실제 Pixel/Samsung 등 OEM mask·monochrome scale을 확인했다.
- [x] 1024×500 feature graphic 후보 4개와 SVG 원본·PNG 해시·재현 절차를 준비했다.
- [ ] 사용자 선택 및 Console preview 검증으로 feature graphic 최종본을 확정했다.
- [x] 1024×500 feature graphic A-D 역사 후보와 SVG 원본·PNG 해시·재현 절차를 보존했다.
- [x] canonical icon을 reference로 한 imagegen E 원본·prompt·1024×500 제출본·해시를 준비하고 선택했다.
- [x] Console preview에서 feature graphic E의 safe crop·thumbnail contrast·규격 경고 없음을 확인했다.
- [ ] 실제 release 앱 스크린샷을 준비했다.
- [x] Console에서 Play app-signing certificate SHA-256을 확인했다.
- [ ] 첫 AAB 업로드 후 Console이 표시하는 upload certificate가 준비한 key의 SHA-256과 일치하고 Play app-signing certificate와 다름을 증명했다.
@ -163,14 +164,15 @@ D3RO Voice는 React Native/Whisper 등 native library를 포함하고 NDK r27.1
- [ ] 지원 이메일의 수신·응답을 확인했다.
- [ ] privacy/terms/delete URL이 익명 모바일 브라우저에서 HTTPS 200, 올바른 title/본문, no-login이다.
- [ ] root website가 유효한 지원 사이트가 아니면 website 필드를 비워 뒀다.
- [x] Play Console ko-KR 초안에 42자 짧은 설명, 1,213자 전체 설명, 512 아이콘, canonical E를 저장했다. 리뷰·트랙 제출은 진행하지 않았다.
- [x] 기본 Android robot launcher icon을 제거했다.
- [x] adaptive icon foreground/background/monochrome와 legacy density icon을 같은 canonical D3RO artwork로 만들었다.
- [x] Pixel Launcher emulator의 adaptive circle mask를 캡처했다: `docs/v3/play/assets/proof/d3ro-icon-pixel-launcher-20260824.png`, SHA-256 `7A2DA876FBFD54089B783A7FD45C2472476ED47DCEABA08AB305B7B01A18D430`.
- [ ] Play-signed release를 실제 Pixel/Samsung 등 OEM 기기에 설치해 icon scale·safe zone·monochrome를 캡처했다.
- [x] Play icon 512×512 PNG를 생성했다: `docs/v3/play/assets/d3ro-voice-play-icon-512.png`.
- [ ] Console upload 후 alpha/모서리/안전 영역 경고가 없는지 확인했다.
- [x] feature graphic 1024×500 후보 4개와 재현·해시 기록을 준비했다: `docs/v3/play/assets/feature-graphic/`.
- [ ] 후보 중 최종본을 사용자 선택 후 Console preview에서 검증했다.
- [x] Play icon Console upload 후 alpha/모서리/안전 영역 경고가 없는지 확인했다.
- [x] feature graphic A-D 역사 후보와 imagegen canonical E의 원본·prompt·1024×500 제출본·해시 기록을 준비했다: `docs/v3/play/assets/feature-graphic/`.
- [x] 선택한 E를 Console preview에서 검증했다.
- [ ] phone screenshot 최소 2장, 권장 4장 이상을 실제 Play release 설치본에서 1080×1920급으로 캡처했다.
- [ ] 녹음, 전사 결과, Talk+신고, 회의/팀, 개인정보/삭제처럼 실제 핵심 기능을 보여준다.
- [ ] reviewer credential, 실사용자 이메일, 토큰, 실제 전사·회의 내용을 screenshot에 넣지 않았다.
@ -326,18 +328,18 @@ AdMob 콘솔 준비를 실제 광고 게재 승인·수입·Play release 완료
## 외부 placeholder 레지스트리
| Placeholder | 실제 값 소유 위치 | 완료 조건 |
| ----------------------------------------------------------- | ---------------------------- | ---------------------------------------- |
| `<PLACEHOLDER_RELEASE_COMMIT_SHA>` | Git remote/CI | 권위 있는 release source SHA |
| versionName `1.1.0` / versionCode `1010001` | release SSOT | 확정. 실제 AAB·Console metadata 대조는 대기 |
| `<PLACEHOLDER_RELEASE_AAB_SHA256>` | restricted artifact/evidence | 실제 production AAB hash |
| upload SHA-256 `4F:AC:69:24:...:15:2B:54` | external key/Play Console | local 값 확정. AAB signer·Console 표시와 일치 대기 |
| evidence keyId `2797d3e6...4a890b7f` | release identity/CI secret | public·roundtrip 확인. private CI secret·복구 백업 대기 |
| Play app-signing SHA-1 | Play Console App integrity | SHA-256은 확인. SHA-1·Firebase 대조는 대기 |
| `<PLACEHOLDER_FIREBASE_PROJECT_ID>` | Firebase Console | 올바른 계정·package 등록 |
| `<PLACEHOLDER_PLAY_SERVICE_ACCOUNT>` | Google Cloud/Play Console | 최소 권한, RTDN/API GREEN |
| `<PLACEHOLDER_MERCHANT_PROFILE_ID>` | Google payments/Play Console | 상품 판매 가능, 법적·세금 정보 완료 |
| `<PLACEHOLDER_ADMOB_PAYMENT_PROFILE_STATUS>` | AdMob/Google payments | 지급 profile와 검토 완료 |
| reviewer credentials | Play Console App access만 | 24시간 재사용 가능, no OTP |
| `<PLACEHOLDER_FGS_DEMO_URL>` | unlisted video storage | 익명 접근 가능, 실제 release 실기기 영상 |
| `<PLACEHOLDER_REPORT_TEST_EVIDENCE>` | redacted production evidence | 신고→운영 원장 E2E GREEN |
| Placeholder | 실제 값 소유 위치 | 완료 조건 |
| -------------------------------------------- | ---------------------------- | ------------------------------------------------------- |
| `<PLACEHOLDER_RELEASE_COMMIT_SHA>` | Git remote/CI | 권위 있는 release source SHA |
| versionName `1.1.0` / versionCode `1010001` | release SSOT | 확정. 실제 AAB·Console metadata 대조는 대기 |
| `<PLACEHOLDER_RELEASE_AAB_SHA256>` | restricted artifact/evidence | 실제 production AAB hash |
| upload SHA-256 `4F:AC:69:24:...:15:2B:54` | external key/Play Console | local 값 확정. AAB signer·Console 표시와 일치 대기 |
| evidence keyId `2797d3e6...4a890b7f` | release identity/CI secret | public·roundtrip 확인. private CI secret·복구 백업 대기 |
| Play app-signing SHA-1 | Play Console App integrity | SHA-256은 확인. SHA-1·Firebase 대조는 대기 |
| `<PLACEHOLDER_FIREBASE_PROJECT_ID>` | Firebase Console | 올바른 계정·package 등록 |
| `<PLACEHOLDER_PLAY_SERVICE_ACCOUNT>` | Google Cloud/Play Console | 최소 권한, RTDN/API GREEN |
| `<PLACEHOLDER_MERCHANT_PROFILE_ID>` | Google payments/Play Console | 상품 판매 가능, 법적·세금 정보 완료 |
| `<PLACEHOLDER_ADMOB_PAYMENT_PROFILE_STATUS>` | AdMob/Google payments | 지급 profile와 검토 완료 |
| reviewer credentials | Play Console App access만 | 24시간 재사용 가능, no OTP |
| `<PLACEHOLDER_FGS_DEMO_URL>` | unlisted video storage | 익명 접근 가능, 실제 release 실기기 영상 |
| `<PLACEHOLDER_REPORT_TEST_EVIDENCE>` | redacted production evidence | 신고→운영 원장 E2E GREEN |

View file

@ -14,7 +14,7 @@
3. [`03-app-content-draft.md`](03-app-content-draft.md): 광고, 앱 액세스, 등급, 금융 기능, 계정 삭제, AI·UGC, FGS 답변
4. [`04-release-checklist.md`](04-release-checklist.md): 앱 생성부터 internal/closed/production까지의 출시 게이트
5. [`05-content-reporting-operations.md`](05-content-reporting-operations.md): AI 신고 검토·종결·보관·purge 운영 절차
6. [`assets/feature-graphic/README.md`](assets/feature-graphic/README.md): 1024×500 후보, 원본, 재현 절차와 해시
6. [`assets/feature-graphic/README.md`](assets/feature-graphic/README.md): 1024×500 A-D 역사 후보와 imagegen canonical E의 원본·prompt·재현 절차·해시
7. [`../e2e/RED_E2E_500_CONTENT_REPORT.md`](../e2e/RED_E2E_500_CONTENT_REPORT.md): local Gateway→Edge→DB 650개 AI 신고 Red-path E2E
## 상태 표기

View file

@ -1,12 +1,26 @@
# Google Play feature graphic 후보
# Google Play feature graphic
기준일: 2026-08-24
기준일: 2026-08-29
Google Play의 1024×500 feature graphic 규격에 맞춘 선택 후보다. 네 후보 모두
저장소의 canonical D3RO microphone motif와 `D3RO VOICE` 표기만 사용하며, 기능이나
성과를 주장하는 문구와 합성 앱 화면은 포함하지 않는다.
Google Play의 1024×500 feature graphic 규격에 맞춘 자산과 provenance 기록이다.
A-D는 2026-08-24에 만든 역사적 vector 후보이고, E는 canonical 앱 아이콘을
reference로 사용해 2026-08-29에 생성한 선택 자산이다. 어느 자산도 검증되지 않은
기능·성과 문구나 합성 앱 화면을 포함하지 않는다.
## 후보와 권장안
## 선택 자산 E
| 역할 | 파일 | SHA-256 |
| ----------- | ----------------------------------------------- | ------------------------------------------------------------------ |
| 생성 원본 | `candidate-e-generated-signal-stage-source.png` | `BFACF64CE206D794F307662797489E27286E7F7CE7DEF5F8748C4C5332C3323D` |
| 생성 prompt | `candidate-e-generated-signal-stage.prompt.md` | `AC6C1BEB6409E84764791ACCD919FE162FFAFD4759F3E49B9DA6F877C283BA1C` |
| Play 제출본 | `candidate-e-generated-signal-stage.png` | `A5D82B65B95027ACE184FA06A3BBDA3433995C70F064932B5733C3D3A99644D9` |
E는 음성 파형이 canonical mark를 거쳐 전사·구조화 기록·협업 신호로 전환되는
흐름을 텍스트 없이 표현한다. 사용자 요청에 따라 E를 선택했고 2026-08-29 Play
Console preview에서 safe crop, thumbnail contrast, 규격 경고 없음을 확인했다.
manifest 상태는 `selected_console_preview_verified`다.
## 역사 후보 A-D
| 후보 | 방향 | PNG SHA-256 |
| ------------------------------ | --------------------------------------- | ------------------------------------------------------------------ |
@ -15,22 +29,32 @@ Google Play의 1024×500 feature graphic 규격에 맞춘 선택 후보다. 네
| C `candidate-c-blueprint-band` | light/dark blueprint split | `C484AC514966347BF4E7AA526B040B88DDA89F9150AC3677B8C74297A1373C1E` |
| D `candidate-d-monolith` | bold dark monolith | `28FC7B608454E073A29AFE2149414F4186629AE8889B3FE2FA683D786F8C3EA9` |
현재 권장안은 **A**다. 작은 스토어 카드에서도 microphone, 제품명, 파형이 가장
명확하게 분리된다. 다만 최종 자산 확정과 Play Console 업로드는 사용자 선택 및
Console preview 검증 뒤에만 진행한다.
## 원본과 재현
- brand source: `site/public/favicon.svg`
- Play icon source: `docs/v3/play/assets/d3ro-voice-play-icon-source.svg`
- 편집 원본: 각 후보의 `.svg`
- 제출 후보: 같은 basename의 `.png`
- E generation reference: `docs/v3/play/assets/d3ro-voice-play-icon-512.png`
- E byte-for-byte source: `candidate-e-generated-signal-stage-source.png`
- E prompt provenance: `candidate-e-generated-signal-stage.prompt.md`
- E Play output: `candidate-e-generated-signal-stage.png`
- A-D 역사 원본: 각 후보의 `.svg`
- A-D 역사 출력: 같은 basename의 `.png`
- export runtime: ImageMagick `7.1.2-25 Q16-HDRI`
- 출력 조건: 1024×500, PNG, sRGB, 8-bit, TrueColor, 완전 불투명
- machine-readable manifest: `manifest.json`
- verifier: `scripts/ci/verify-play-store-assets.mjs`
저장소 루트의 PowerShell에서 다음 명령으로 다시 내보낸다.
E 생성 원본은 수정하지 않는다. 저장소 루트의 PowerShell에서 종횡비를 왜곡하지
않고 중앙 crop으로 Play 제출본을 다시 만든다.
```powershell
magick docs/v3/play/assets/feature-graphic/candidate-e-generated-signal-stage-source.png `
-auto-orient -resize '1024x500^' -gravity center -extent 1024x500 `
-alpha off -strip -colorspace sRGB `
'PNG24:docs/v3/play/assets/feature-graphic/candidate-e-generated-signal-stage.png'
```
A-D 역사 후보의 vector export는 다음 명령으로 재현한다.
```powershell
Get-ChildItem docs/v3/play/assets/feature-graphic/candidate-*.svg |
@ -40,8 +64,9 @@ Get-ChildItem docs/v3/play/assets/feature-graphic/candidate-*.svg |
}
```
환경이나 SVG renderer 버전이 바뀌면 raster hash가 달라질 수 있다. 제출할 PNG는
위 해시, 크기, 불투명 여부를 다시 확인하고 그 파일을 release evidence에 기록한다.
환경이나 renderer 버전이 바뀌면 raster hash가 달라질 수 있다. 제출할 canonical
PNG는 위 해시, 크기, 색상 유형, 불투명 여부를 다시 확인하고 release evidence에
기록한다.
```powershell
npm run release:play:assets

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 KiB

View file

@ -0,0 +1,68 @@
# Candidate E image-generation provenance
- Generated on: 2026-08-29
- Generator: OpenAI built-in `image_gen`
- Brand reference: `../d3ro-voice-play-icon-512.png`
- Generated source: `candidate-e-generated-signal-stage-source.png`
- Play output: `candidate-e-generated-signal-stage.png`
- Source SHA-256: `BFACF64CE206D794F307662797489E27286E7F7CE7DEF5F8748C4C5332C3323D`
- Output SHA-256: `A5D82B65B95027ACE184FA06A3BBDA3433995C70F064932B5733C3D3A99644D9`
## Prompt
Create a premium Google Play feature graphic for the D3RO Voice productivity app,
using the attached canonical app icon as the exact brand reference.
OUTPUT AND COMPOSITION:
- Wide cinematic landscape, designed to be safely center-cropped to exactly
1024 x 500 pixels (2.048:1).
- Keep all essential visual elements within the central 80% horizontally and
central 75% vertically.
- No border, no rounded outer frame, no device mockup.
BRAND INVARIANTS:
- Preserve the attached D3RO Voice symbol's recognizable geometry and cobalt-blue
color. Do not redraw it into a different logo.
- Deep graphite / near-black background.
- Palette: canonical vivid cobalt blue, restrained mint-teal highlights, cool
white only for tiny signal points.
- Place one clear brand symbol slightly left of center, with generous negative
space and strong silhouette.
VISUAL STORY:
- Depict voice becoming organized knowledge: a clean audio waveform and sparse
signal particles enter from the left, pass through the D3RO mark, then resolve
into elegant horizontal transcript lines, small structured note blocks, and a
subtle collaboration node constellation toward the right.
- Editorial, precise, high-end dark technology art direction; calm confidence
rather than flashy sci-fi.
- Fine grid and restrained luminous accents, crisp vector-like geometry, subtle
depth, no busy clutter.
- The right-side structures must remain abstract and non-readable, not fake app UI.
STRICT EXCLUSIONS:
- No text, no letters, no words, no captions, no slogans, no watermarks.
- No people, faces, hands, phones, laptops, microphones other than the supplied
abstract brand symbol.
- No fake screenshots, no legible interface, no generic AI brain, no robot, no
neon rainbow, no stock-photo look.
- No changes to the logo proportions.
- No copyright/trademark marks from any other brand.
Finish as a polished store-ready visual with excellent contrast at thumbnail size.
## Deterministic Play export
The source is preserved byte-for-byte. The Play image is produced without aspect
ratio distortion by filling the target frame, then cropping from the center:
```powershell
magick candidate-e-generated-signal-stage-source.png -auto-orient `
-resize '1024x500^' -gravity center -extent 1024x500 `
-alpha off -strip -colorspace sRGB `
'PNG24:candidate-e-generated-signal-stage.png'
```

View file

@ -1,9 +1,9 @@
{
"schemaVersion": 1,
"generatedOn": "2026-08-24",
"schemaVersion": 2,
"generatedOn": "2026-08-29",
"selection": {
"recommended": "A",
"status": "pending_user_selection_and_console_preview"
"recommended": "E",
"status": "selected_console_preview_verified"
},
"brandSource": "site/public/favicon.svg",
"export": {
@ -16,6 +16,18 @@
"pngColorType": 2,
"opaque": true
},
"canonical": {
"id": "E",
"source": "candidate-e-generated-signal-stage-source.png",
"sourceBytes": 1224200,
"sourceSha256": "BFACF64CE206D794F307662797489E27286E7F7CE7DEF5F8748C4C5332C3323D",
"prompt": "candidate-e-generated-signal-stage.prompt.md",
"promptBytes": 2852,
"promptSha256": "AC6C1BEB6409E84764791ACCD919FE162FFAFD4759F3E49B9DA6F877C283BA1C",
"output": "candidate-e-generated-signal-stage.png",
"outputBytes": 441480,
"outputSha256": "A5D82B65B95027ACE184FA06A3BBDA3433995C70F064932B5733C3D3A99644D9"
},
"candidates": [
{
"id": "A",

View file

@ -235,12 +235,9 @@ function verifyFeatureGraphics(root) {
'feature_asset_directory'
)
const manifest = readJson(assetDirectory, 'manifest.json', 'feature_manifest')
assert(manifest.schemaVersion === 1, 'manifest_schema')
assert(manifest.schemaVersion === 2, 'manifest_schema')
assert(Array.isArray(manifest.candidates) && manifest.candidates.length === 4, 'candidate_count')
assert(
manifest.selection?.status === 'pending_user_selection_and_console_preview',
'selection_status'
)
assert(manifest.selection?.status === 'selected_console_preview_verified', 'selection_status')
const candidateIds = new Set()
for (const candidate of manifest.candidates) {
@ -272,8 +269,45 @@ function verifyFeatureGraphics(root) {
assert(png.colorType === manifest.export.pngColorType, `png_color_type_${candidate.id}`)
}
assert(candidateIds.has(manifest.selection.recommended), 'recommended_candidate_missing')
return manifest.candidates.length
const canonical = manifest.canonical
assert(canonical?.id === manifest.selection.recommended, 'canonical_selection')
assert(!candidateIds.has(canonical.id), 'canonical_id_conflict')
const canonicalSource = readRequired(assetDirectory, canonical.source, 'feature_canonical_source')
const canonicalPrompt = readRequired(assetDirectory, canonical.prompt, 'feature_canonical_prompt')
const canonicalOutput = readRequired(assetDirectory, canonical.output, 'feature_canonical_output')
assert(
statSync(canonicalSource.absolutePath).size === canonical.sourceBytes,
'feature_canonical_source_size'
)
assert(
statSync(canonicalPrompt.absolutePath).size === canonical.promptBytes,
'feature_canonical_prompt_size'
)
assert(
statSync(canonicalOutput.absolutePath).size === canonical.outputBytes,
'feature_canonical_output_size'
)
assert(sha256(canonicalSource.file) === canonical.sourceSha256, 'feature_canonical_source_hash')
assert(sha256(canonicalPrompt.file) === canonical.promptSha256, 'feature_canonical_prompt_hash')
verifyPng(
assetDirectory,
canonical.output,
{
sha256: canonical.outputSha256,
width: manifest.export.width,
height: manifest.export.height,
bitDepth: manifest.export.bitDepth,
colorType: manifest.export.pngColorType,
alpha: 'no_alpha_channel'
},
'feature_canonical'
)
return {
candidateCount: manifest.candidates.length,
canonicalId: canonical.id
}
}
function verifyAndroidIcons(root, android) {
@ -537,11 +571,11 @@ function verifyMobileIcons(root) {
}
function verifyAll(root, printSummary = true) {
const featureCandidateCount = verifyFeatureGraphics(root)
const feature = verifyFeatureGraphics(root)
const mobile = verifyMobileIcons(root)
if (printSummary) {
console.log(
`Play store assets verified: ${featureCandidateCount} feature candidates, canonical 512 icon, ${mobile.androidLegacyIconCount} Android legacy icons + adaptive/monochrome, ${mobile.iosIconCount} iOS/iPad icons, hashes and alpha contracts GREEN`
`Play store assets verified: ${feature.candidateCount} historical feature candidates + canonical ${feature.canonicalId}, canonical 512 icon, ${mobile.androidLegacyIconCount} Android legacy icons + adaptive/monochrome, ${mobile.iosIconCount} iOS/iPad icons, hashes and alpha contracts GREEN`
)
}
}
@ -695,7 +729,28 @@ function runSelfTests() {
'ios_icon_iphone_20x20_2x_color_type'
)
console.log('Play/mobile icon negative self-tests GREEN: 6 fail-closed cases')
expectSelfTestFailure(
'feature_canonical_hash',
(root) => {
const manifestPath = resolveInside(
root,
`${featureAssetDirectoryRelative}/manifest.json`,
'self_test_feature_manifest'
)
const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
const path = resolveInside(
root,
`${featureAssetDirectoryRelative}/${manifest.canonical.output}`,
'self_test_feature_canonical'
)
const bytes = readFileSync(path)
bytes[bytes.length - 1] ^= 0xff
writeFileSync(path, bytes)
},
'feature_canonical_hash'
)
console.log('Play/mobile icon negative self-tests GREEN: 7 fail-closed cases')
}
const argumentsSet = new Set(process.argv.slice(2))