docs: record 1.2.0 and the state of the published 1.1.0
The changelog still described unreleased work under 1.1.0, which was already published with its own notes. Those notes are restored verbatim for history, and the new work has its own 1.2.0 section that the feed publisher will turn into release notes. The release guide, infrastructure map, and mobile SSOT now carry the 1.2.0 identity, state that installer binaries are distributed through the feed and never committed, and record that the published 1.1.0 installer is unsigned and is being superseded rather than rewritten. Backlog entries cover the remaining external signing and token secrets.
This commit is contained in:
parent
035d0a76f5
commit
359b244dc9
10 changed files with 77 additions and 58 deletions
|
|
@ -6,35 +6,36 @@
|
|||
|
||||
| 항목 | 정본 | 현재 판정 |
|
||||
|---|---|---|
|
||||
| 제품 버전 | `release/product-version.json`: `1.1.0` | source SSOT 확정 |
|
||||
| Android | versionCode `1010001` | production AAB 미생성 |
|
||||
| iOS | build `1010001` | production archive 미검증 |
|
||||
| 제품 버전 | `release/product-version.json`: `1.2.0` | source SSOT 확정 |
|
||||
| Android | versionCode `1020001` | production AAB 미생성 |
|
||||
| iOS | build `1020001` | production archive 미검증 |
|
||||
| Android upload key | alias `d3ro-upload-20260821`, cert SHA-256 `4F:AC:69:24:...:15:2B:54` | external PKCS12·user-only ACL·Credential Manager·private-key readback GREEN; CI secret·복구 백업·AAB signer 대조 대기 |
|
||||
| release evidence | Ed25519 public `release/mobile-release-evidence-public.pem`, keyId `2797d3e6...4a890b7f` | external private key ACL·roundtrip GREEN; CI private-key secret·복구 백업 대기 |
|
||||
| desktop offline license | Ed25519 public `apps/desktop/resources/license/production-public.pem`, keyId `5c52b765...81a887f` | 새 전용 keypair·external private ACL·roundtrip·desktop production build GREEN; admin `ADMIN_LICENSE_PRIVATE_KEY` secret 주입 대기 |
|
||||
| Windows Authenticode | external public-trust code-signing certificate | 현재 local `1.1.0` installer·unpacked app은 `NotSigned`; production PFX·CI secret·signed artifact GREEN 전까지 게시 금지 |
|
||||
| Windows Authenticode | external public-trust code-signing certificate | 현재 local installer·unpacked app은 `NotSigned`; production PFX·CI secret·signed artifact GREEN 전까지 게시 금지 |
|
||||
| Firebase | Console `u/0`, `u/1` 모두 D3RO project 없음 | 사용자 승인 후 project·Android app 생성 필요 |
|
||||
| AdMob | app `ca-app-pub-1039714767792854~6427959892`; banner `/9840591290`; rewarded `/2255790918` | SSOT 확정. `검토 필요`·`광고 게재 제한`·store 미연결·결제 프로필 미완료 |
|
||||
| updater feed (canonical) | `https://git.chanpaca.net/api/packages/yunchan/generic/d3ro-voice/latest` | Forgejo Generic Registry. GitLab project 1172은 legacy mirror |
|
||||
| release notes | `CHANGELOG.md` `## [1.1.0]` | 태그 전 확정·검증 필수 |
|
||||
| release notes | `CHANGELOG.md` `## [1.2.0]` | 태그 전 확정·검증 필수 |
|
||||
| 직전 게시본 | Forgejo Release `v1.1.0` (2026-09-15 게시, unsigned installer 포함) | 불변 태그. `1.2.0`은 이를 대체하는 forward-fix |
|
||||
|
||||
source SSOT와 live updater metadata의 버전이 다르므로 아직 `1.1.0` 배포 완료가 아니다.
|
||||
live canonical feed(`git.chanpaca.net/.../d3ro-voice/latest`)의 `latest.yml`은 현재 `1.1.0`을 보고한다. `1.2.0` 태그 파이프라인이 GREEN이 되면 그 값이 올라간다.
|
||||
|
||||
## desktop 릴리스 파이프라인
|
||||
|
||||
```text
|
||||
authoritative release commit
|
||||
→ version/check/test/build GREEN
|
||||
→ annotated tag v1.1.0
|
||||
→ annotated tag v1.2.0
|
||||
→ package-windows (build-win-x64)
|
||||
→ package-macos (build-mac-arm64)
|
||||
→ publish-release (build-linux-x64)
|
||||
├─ publish-forgejo-release.mjs ← canonical
|
||||
│ ├─ Forgejo Generic Registry /d3ro-voice/1.1.0/ (버전별 보존)
|
||||
│ ├─ Forgejo Generic Registry /d3ro-voice/1.2.0/ (버전별 보존)
|
||||
│ ├─ Forgejo Generic Registry /d3ro-voice/latest/ (updater feed + update-policy.json)
|
||||
│ └─ Forgejo Release + CHANGELOG notes + 자산 첨부
|
||||
└─ publish-gitlab-release.mjs ← legacy mirror (pre-Forgejo 설치본)
|
||||
├─ GitLab Generic Registry /d3ro-voice/1.1.0/
|
||||
├─ GitLab Generic Registry /d3ro-voice/1.2.0/
|
||||
├─ GitLab Generic Registry /d3ro-voice/latest/
|
||||
└─ GitLab Release
|
||||
```
|
||||
|
|
@ -49,7 +50,7 @@ authoritative release commit
|
|||
포함되지 않는다. 사이트·웹 다운로드 센터는 로컬 경로가 아니라 feed URL을
|
||||
링크한다. (역사적 `1.0.0` 자산만 추적 상태로 남아 있다.)
|
||||
|
||||
- `scripts/ci/sync-version.mjs --check --tag v1.1.0`는 태그, `release/product-version.json`, package/lockfile, Android/iOS 버전 면의 일치를 fail-closed로 검증한다.
|
||||
- `scripts/ci/sync-version.mjs --check --tag v1.2.0`는 태그, `release/product-version.json`, package/lockfile, Android/iOS 버전 면의 일치를 fail-closed로 검증한다.
|
||||
- `scripts/ci/verify-release-metadata.mjs`는 배포 메타데이터와 CI/publisher 계약을 검증한다.
|
||||
- 같은 gate는 desktop license public key가 Ed25519이고 `release/product-version.json`의 `desktopLicensePublicKeyId`와 일치하는지 검증한다. `electron.vite.config.ts`는 이 파일을 직접 읽으므로 누락·손상된 키로는 build가 시작되지 않는다.
|
||||
- `scripts/ci/publish-forgejo-release.mjs`는 canonical이다. 버전별 패키지를 먼저 올리고, `latest`에서 설치 자산 참조를 검증한 뒤 `latest.yml`과 `update-policy.json`을 마지막에 게시하고 공개 URL에서 재검증한다. `scripts/ci/publish-gitlab-release.mjs`는 legacy mirror로 동일 자산을 GitLab에도 올린다.
|
||||
|
|
@ -83,7 +84,10 @@ https://gitlab.twentyoz.kr:8443/api/v4/projects/1172/packages/generic/d3ro-voice
|
|||
6. installer와 `win-unpacked/D3RO Voice.exe` 모두 external public-trust certificate의 Authenticode `Valid`이고, signer subject가 protected CI identity와 정확히 일치한다.
|
||||
7. 이전 실제 설치본이 feed를 탐지하고, 다운로드·재시작·버전 상승을 끝까지 완료한다.
|
||||
|
||||
2026-08-29 live `latest.yml`의 버전은 `0.2.1-alpha`다(legacy GitLab feed). 이는 updater endpoint가 응답한다는 증거일 뿐 `1.1.0` 게시 증거가 아니다.
|
||||
2026-09-16 live canonical `latest.yml`은 `1.1.0`을 보고한다(2026-09-15 hand-publish).
|
||||
그 installer는 Authenticode 서명이 없으므로 정책상 정상 게시본이 아니다. `1.2.0`은
|
||||
서명 gate를 통과한 CI build로 이 값을 대체하는 forward-fix다. legacy GitLab feed는
|
||||
여전히 `0.2.1-alpha`다.
|
||||
|
||||
## 업데이트 채널과 메이저/증분 정책
|
||||
|
||||
|
|
@ -106,14 +110,14 @@ https://gitlab.twentyoz.kr:8443/api/v4/projects/1172/packages/generic/d3ro-voice
|
|||
- **회수(rollback)**: `stagingPercentage`를 낮추거나 `killSwitch`를 켠다. 이미 배포된 버전은 되돌리지 않고 더 높은 patch로 forward-fix한다.
|
||||
|
||||
|
||||
## `1.1.0` 릴리스 절차
|
||||
## `1.2.0` 릴리스 절차
|
||||
|
||||
1. `release/product-version.json`의 version/build 값과 모든 버전 면을 `npm run version:check`로 대조한다.
|
||||
2. `CHANGELOG.md` `## [1.1.0] - 2026-08-29` 섹션을 사용자 변경점 중심으로 확정한다. publisher는 이 섹션이 없으면 실패해야 한다.
|
||||
2. `CHANGELOG.md` `## [1.2.0] - 2026-09-16` 섹션을 사용자 변경점 중심으로 확정한다. publisher는 이 섹션이 없으면 실패해야 한다.
|
||||
3. dirty/untracked 작업을 임의로 reset·clean하지 말고, release 범위만 검토 가능한 authoritative commit으로 보존한다.
|
||||
4. 같은 commit에서 lint, typecheck, test, build, release metadata·security·artifact gate를 전부 GREEN으로 만든다. Windows는 production Authenticode PFX를 주입한 CI build와 `verify-windows-release-artifact.ps1` GREEN이 필수다.
|
||||
5. desktop offline license를 제공한다면 external private key를 admin의 `ADMIN_LICENSE_PRIVATE_KEY` secret로 주입하고, 저장소 public key와 sign/verify roundtrip 및 발급 감사 로그를 확인한다.
|
||||
6. 이전 버전보다 높은 annotated 태그 `v1.1.0`을 생성해 push한다. `npm run release:tag -- --dry-run`으로 검증한 뒤 `npm run release:tag`(GPG 사용 시 `-- --sign`)와 `git push origin v1.1.0`를 실행한다. 태그는 불변이며 게이트를 시작하는 후속 단계지 검증을 대체하지 않는다.
|
||||
6. 이미 게시된 버전보다 높은 annotated 태그 `v1.2.0`을 생성해 push한다. `npm run release:tag -- --dry-run`으로 검증한 뒤 `npm run release:tag`(GPG 사용 시 `-- --sign`)와 `git push origin v1.2.0`를 실행한다. 태그는 불변이며 게이트를 시작하는 후속 단계지 검증을 대체하지 않는다. 이미 게시된 버전을 재게시하지 않는다: canonical publisher는 버전별 자산이 다른 바이트를 가지면 fail-closed로 중단한다.
|
||||
7. GitLab에서 package-windows, package-macos, publish-release와 의도한 mobile job 상태를 모두 확인한다. publish-release가 Forgejo와 GitLab 양쪽에 게시했는지 로그로 확인한다. pending/stuck/skipped를 GREEN으로 기록하지 않는다.
|
||||
8. Forgejo Release note/asset, `latest.yml`, `update-policy.json`, installer hash를 외부 public URL에서 다시 검증한다.
|
||||
9. 이전 설치본에서 자동 업데이트 E2E를 실행하고 실행 중 버전·프로세스·사용자 데이터 보존을 확인한다.
|
||||
|
|
@ -122,7 +126,7 @@ https://gitlab.twentyoz.kr:8443/api/v4/projects/1172/packages/generic/d3ro-voice
|
|||
|
||||
Desktop release를 게시해도 Android production 출시가 자동으로 완료되지 않는다. Android는 다음을 별도로 증명한다.
|
||||
|
||||
- 준비된 local upload/evidence key와 AdMob identity를 protected CI secret에 주입하고, 사용자 승인 후 생성한 production Firebase config와 함께 version `1.1.0`, versionCode `1010001` AAB 생성
|
||||
- 준비된 local upload/evidence key와 AdMob identity를 protected CI secret에 주입하고, 사용자 승인 후 생성한 production Firebase config와 함께 version `1.2.0`, versionCode `1020001` AAB 생성
|
||||
- package/config/upload signer/ABI/16 KB page size/signed provenance GREEN
|
||||
- public APK 게시 없이 Play internal track에 제한 업로드
|
||||
- Play-signed 실기기 E2E, 12명·연속 14일 closed test, production access 승인
|
||||
|
|
|
|||
|
|
@ -39,15 +39,16 @@
|
|||
| 구성 | 위치 | 상태 |
|
||||
|---|---|---|
|
||||
| 업데이터 서비스 | `apps/desktop/src/main/services/UpdateService.ts` | 단일 feed, 4h 주기, 동의 다이얼로그, skip version |
|
||||
| feed SSOT | `apps/desktop/src/main/update-feed.ts` | GitLab project 1172 `latest` (버전 비고정) |
|
||||
| feed SSOT | `apps/desktop/src/main/update-feed.ts` | canonical Forgejo registry `latest` (버전 비고정) + legacy GitLab mirror 상수 |
|
||||
| 빌더 publish | `apps/desktop/electron-builder.yml` | `provider: generic`, `detectUpdateChannel: false` |
|
||||
| 버전 SSOT | `release/product-version.json` | `1.1.0` / `1010001` |
|
||||
| 버전 SSOT | `release/product-version.json` | `1.2.0` / `1020001` |
|
||||
| 버전 동기화 | `scripts/ci/sync-version.mjs` | 태그·패키지·lockfile·Android/iOS/.NET 일치 fail-closed |
|
||||
| 메타데이터 검증 | `scripts/ci/verify-release-metadata.mjs` | feed·publisher·workflow 계약 self-test |
|
||||
| GitLab publisher | `scripts/ci/publish-gitlab-release.mjs` | 버전별 + `latest`, 설치자산 우선, public 재검증 |
|
||||
| GitLab publisher | `scripts/ci/publish-gitlab-release.mjs` | 버전별 + `latest`, 설치자산 우선, public 재검증 (legacy mirror) |
|
||||
| Forgejo publisher | `scripts/ci/publish-forgejo-release.mjs` | canonical feed·Release·policy 게시, 동일 버전 재게시 fail-closed |
|
||||
| Windows 산출물 gate | `scripts/ci/verify-windows-release-artifact.ps1` | Authenticode·PE version·SHA-512 |
|
||||
| CI | `.gitlab-ci.yml` `package-*` → `publish-release` | 태그 전용 |
|
||||
| Forgejo | `.forgejo/workflows/*` | **사이트 배포만**. 릴리스 배포 금지됨 |
|
||||
| Forgejo | `.forgejo/workflows/release.yml` | tag 전용 release·feed 게시 (동일 publisher 수렴) |
|
||||
| 릴리스 노트 | `CHANGELOG.md` (Keep a Changelog) | publisher가 섹션 누락 시 실패 |
|
||||
|
||||
---
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
> Status: ACTIVE
|
||||
> Last full audit: 2026-09-13
|
||||
> Scope: entire monorepo `D:/workspace/D3ROVoice` at product version `1.1.0`
|
||||
> Scope: entire monorepo `D:/workspace/D3ROVoice` at product version `1.2.0`
|
||||
> Purpose: let any agent (or human) answer two questions in under a minute:
|
||||
> 1. **What infrastructure exists?** (build, CI, services, APIs, data, packages, deploy)
|
||||
> 2. **How far is each feature developed?** (per surface, with file anchors and status)
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ Full detail: [`09-supabase-backend.md`](./09-supabase-backend.md).
|
|||
|
||||
| File | Purpose |
|
||||
|---|---|
|
||||
| `release/product-version.json` | version `1.1.0`, `androidVersionCode`/`iosBuildNumber` `1010001`, releaseDate, desktop license keyId |
|
||||
| `release/product-version.json` | version `1.2.0`, `androidVersionCode`/`iosBuildNumber` `1020001`, releaseDate, desktop license keyId |
|
||||
| `release/android-release-identity.json` | package `com.d3ro.voice`, Play app ID, app-signing SHA-256, upload cert SHA-256, evidence keyId, AdMob unit IDs |
|
||||
| `release/desktop-license-public.pem` | Ed25519 public key for desktop offline licenses |
|
||||
| `release/mobile-release-evidence-public.pem` | Ed25519 public key for mobile release evidence |
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
> Surface: `packages/*` (npm workspaces)
|
||||
> Source of truth for: shared domain logic, design systems, i18n, API client
|
||||
|
||||
All packages are private, version `1.1.0`, source-only (`main`/`types` point at `src`).
|
||||
All packages are private, version `1.2.0`, source-only (`main`/`types` point at `src`).
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ Status quick-reference: `[x]` done+verified · `[~]` partial/unverified · `[ ]`
|
|||
| INFRA-11 | Docker + NAS deploy | [x] | `docker-compose.nas.yml`, `scripts/deploy-nas.*` |
|
||||
| INFRA-12 | Cloudflare edge + tunnel | [x] | `server/cloudflare-worker`, Cloudflare Tunnel `kd-nas` |
|
||||
| INFRA-13 | Site deploy (Cloudflare Pages + GitHub Pages) | [x] | `.forgejo/workflows/deploy-site.yml`, `.github/workflows/deploy-site.yml` |
|
||||
| INFRA-15 | Update & release system | [x] | Canonical Forgejo feed + channels/policy (`release/update-policy.json`, `src/main/update-policy.ts`), canonical publisher `scripts/ci/publish-forgejo-release.mjs`, legacy GitLab mirror; `npm run release:metadata:test`. v1.1.0 published to Forgejo & official download centers active on web (`/download`, `/releases`) and site (`#download`). |
|
||||
| INFRA-15 | Update & release system | [x] | Canonical Forgejo feed + channels/policy (`release/update-policy.json`, `src/main/update-policy.ts`), canonical publisher `scripts/ci/publish-forgejo-release.mjs`, legacy GitLab mirror; `npm run release:metadata:test`. v1.1.0 was published to Forgejo on 2026-09-15; product version moved to `1.2.0` as a forward-fix with CI-only publication, a same-version re-release guard, and download centers that link the feed instead of repository paths. |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ Legend: `[ ]` open · `[~]` in progress · `[!]` blocked externally · `[x]` res
|
|||
| ID | Area | Gap | Evidence | Suggested next step |
|
||||
|---|---|---|---|---|
|
||||
| GAP-QA-01 | Quality | Extreme Red Team: headful end-to-end bug hunting across real desktop Electron, Web Next.js, and CI pipelines. | `red_team_log.md`, `tests/e2e/red_team_cycle*.spec.ts`, `apps/web/e2e/red_team_cycle4_web.spec.ts` | `[x]` 2026-09-15: 18 scenarios executed, 14 defects caught and 100% resolved (infinite chunking loop DEF-008, IPC signature mismatch DEF-004, markdown editor typing rollback DEF-006, Web RSC Link serialization DEF-012, secret scanner lookahead DEF-013, etc.). All 18 scenarios GREEN with zero regressions. |
|
||||
| GAP-REL-01 | Release | Official v1.1.0 release publication to Forgejo and active public download center deployment. | `scripts/ci/publish-forgejo-release.mjs`, `apps/web/src/app/download/page.tsx`, `site/src/sections/Download.tsx`, `apps/web/e2e/red_team_cycle4_web.spec.ts` | `[x]` 2026-09-15: v1.1.0 release assets (`D3RO-Voice-Setup-1.1.0-x64.exe`, `.blockmap`, `latest.yml`, `update-policy.json`) published to canonical Forgejo registry and release hub. Public download centers in `apps/web` (`/download`, `/releases`) and `site` (`#download`) activated with direct 1.1.0 installer download, SHA-256 verification, and mirror links. Playwright E2E tests verified GREEN. |
|
||||
| GAP-REL-01 | Release | Official release publication to Forgejo and active public download center deployment. | `scripts/ci/publish-forgejo-release.mjs`, `apps/web/src/app/download/page.tsx`, `site/src/sections/Download.tsx`, `apps/web/e2e/red_team_cycle4_web.spec.ts` | `[~]` 2026-09-15: v1.1.0 release assets (`D3RO-Voice-Setup-1.1.0-x64.exe`, `.blockmap`, `latest.yml`, `update-policy.json`) published to canonical Forgejo registry and release hub. 2026-09-16: the published 1.1.0 installer carries no Authenticode signature, so it does not satisfy the release policy; product version moved to `1.2.0` and publication must come from CI with the signing gate GREEN. Download centers in `apps/web` (`/download`) and `site` (`#download`) link the canonical Forgejo feed. |
|
||||
| GAP-REL-02 | Release | Windows stable publication needs an external public-trust Authenticode PFX, its password, the exact signer subject, and a Forgejo token, none of which live in the repository. | `.forgejo/workflows/release.yml`, `.gitlab-ci.yml`, `scripts/ci/verify-windows-release-artifact.ps1` | `[!]` 2026-09-16: every publisher fails closed without `WIN_CSC_*` and `FORGEJO_TOKEN`; provide them as protected CI secrets, then re-run the `1.2.0` tag pipeline. |
|
||||
| GAP-ADS-01 | Ads | 9 of 10 desktop ad adapters still extend `UnavailableAdAdapter` (`provider_not_integrated`). | `apps/desktop/src/main/services/ads/*` | `[~]` 2026-09-13: `DirectHouseSponsorAdapter` is now a real configurable REST adapter (bid/impression/click/reward via `endpointUrl`; fail-closed when unconfigured; 22 unit tests GREEN). Remaining 9 need official SDKs/authenticated endpoints. |
|
||||
| GAP-ADS-02 | Ads | Desktop mediation reward accounting is not wired to license quota (`claimReward` still returns no tokens). | `AdMediationEngine.ts`, `AppLayout.tsx` | Wire verified `reportRewardCompletion` to `LicenseService` quota after the direct sponsor endpoint exists. |
|
||||
| GAP-ID-01 | Identity | Supabase, .NET JWT/SQLite, and the desktop offline license each had their own tier/role shape. | `@d3ro/core/entitlement`, `LicenseService`, `entitlement-context` | `[~]` 2026-09-13: canonical `EntitlementSnapshot` + `resolveEntitlement` added with tests; desktop tier normalization + `isPro` fixed. Full adoption tracked as GAP-ID-02. |
|
||||
|
|
|
|||
|
|
@ -2,17 +2,22 @@
|
|||
|
||||
> 상태: ACTIVE
|
||||
> 최초 감사 기준: 2026-08-21 / `main` @ `a9c9a1c`
|
||||
> 마지막 release-readiness 스냅샷: 2026-08-29 (Play Console live 재확인, release identity `1.1.0`/`1010001`, production AAB 대기)
|
||||
> 마지막 release-readiness 스냅샷: 2026-09-16 (release identity `1.2.0`/`1020001`, production AAB 대기)
|
||||
> 직전 스냅샷: 2026-08-29 (Play Console live 재확인, 당시 identity `1.1.0`/`1010001`)
|
||||
> 제품 모바일 런타임: `apps/mobile-rn`
|
||||
> 데이터·권한 정본: `server/supabase/migrations` + Supabase Auth/Storage/Edge Functions
|
||||
> 제품화 재개 핸드오프: [`MOBILE_PRODUCTIZATION_HANDOFF_2026-08-21.md`](./MOBILE_PRODUCTIZATION_HANDOFF_2026-08-21.md)
|
||||
> 이 문서는 이전 `docs/v3/00-mobile-master-plan.md`의 미래 로드맵을 대체하는 구현·검증 정본이다.
|
||||
|
||||
## 0. 2026-08-29 출시 게이트 스냅샷
|
||||
## 0. 2026-09-16 출시 게이트 스냅샷
|
||||
|
||||
데스크톱 `1.1.0`은 2026-09-15에 게시되었고, 그 뒤 커밋된 기능(사전 import/export, push
|
||||
전송, entitlement gate, release pipeline 정비)을 담는 forward-fix로 제품 버전이
|
||||
`1.2.0`/`1020001`로 올라갔다. 아래 표는 그 identity를 기준으로 한다.
|
||||
|
||||
| 게이트 | 현재 증거 | 판정 |
|
||||
|---|---|---|
|
||||
| release identity | `release/product-version.json`: version `1.1.0`, Android versionCode / iOS build `1010001` | source SSOT GREEN; 실제 store artifact 미검증 |
|
||||
| release identity | `release/product-version.json`: version `1.2.0`, Android versionCode / iOS build `1020001` | source SSOT GREEN; 실제 store artifact 미검증 |
|
||||
| Play 앱 | app ID `4976102237698469110`, package `com.d3ro.voice`, 상태 `임시` | 앱 생성 GREEN, 제출 RED |
|
||||
| Play 설정 | 0/11, 첫 AAB 0건 | RED |
|
||||
| App Signing | Play 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` | Play identity 확인; upload certificate 대조는 첫 AAB 후 |
|
||||
|
|
@ -343,7 +348,7 @@
|
|||
- [!] EXT-005 Google service account, Android Publisher API, RTDN Pub/Sub
|
||||
- [~] EXT-006 AdMob app `ca-app-pub-1039714767792854~6427959892`, banner `/9840591290`, rewarded `/2255790918`, SSV 설정 — identity/URL SSOT는 확정. `검토 필요`·`광고 게재 제한`·결제 프로필·store 미연결·test-device 실제 지급 E2E 대기
|
||||
- [x] EXT-007 개인정보 처리방침·이용약관·계정 삭제 공개 URL — NAS host/runtime에 동일 해시로 좁게 배포, `/privacy/`, `/terms/`, `/delete-account/` 외부 HTTPS 200·정확한 title·삭제 요청 링크 확인. 모바일 Settings와 Paywall에서 canonical URL 진입
|
||||
- [!] EXT-008 local upload key·Ed25519 evidence keypair는 ACL/readback/roundtrip GREEN. production Firebase/AdMob/signing/evidence secret의 CI 보관·보호 환경 승인·복구 백업 및 `1.1.0`/`1010001` production AAB workflow는 대기
|
||||
- [!] EXT-008 local upload key·Ed25519 evidence keypair는 ACL/readback/roundtrip GREEN. production Firebase/AdMob/signing/evidence secret의 CI 보관·보호 환경 승인·복구 백업 및 `1.2.0`/`1020001` production AAB workflow는 대기
|
||||
- [!] EXT-011 Firebase Console `u/0`, `u/1` 모두 D3RO project 0개 — 사용자 action-time 승인 후 production project·Android app·Play fingerprint·FCM 생성/연결
|
||||
- [!] EXT-009 Fold6 physical-device install/share/OAuth/purchase 증거 — exact `.11` APK Taildrop 전송 완료, 사용자 설치·실행·공유/OAuth/구매 확인 필요
|
||||
- [!] EXT-010 Play closed test 12명·연속 14일 완료와 production access 승인 — 2026-08-29 현재 0명, access disabled
|
||||
|
|
@ -361,7 +366,7 @@
|
|||
| Latest Android E2E test artifact | JDK 17 `:app:assembleE2e -PreactNativeArchitectures=arm64-v8a,x86_64` + artifact/build-config verifiers | BUILD/verifier GREEN; `com.d3ro.voice`, version `0.0.0-e2e.20260821.11`/`202608221`, non-debuggable, embedded bundle 3,808,068 B·Whisper model 77,691,713 B/SHA 검증, Google test AdMob ID, arm64+x86_64. APK 146,739,935 B, SHA-256 `74035B69DB0A564846DF5ED4B85CA5D0E2289D5BB7D73DEE02C35DFD57380C2B`. API 34 exact-APK fresh install와 cold launch GREEN. production artifact가 아니다 | `apps/mobile-rn/android/app/build/outputs/apk/e2e/app-e2e.apk`, `scripts/ci/verify-android-artifact.mjs`, `scripts/ci/verify-mobile-build-config.mjs` | 2026-08-21 |
|
||||
| Public Forgejo distribution | 최신 E2E TEST-DEMO 고유 asset upload + anonymous redownload hash 대조 | PENDING; `.11` SHA-256 `74035B69…380C2B` 공개 업로드·anonymous redownload 검증은 수행하지 않음 | Forgejo release asset | 2026-08-21 |
|
||||
| Mobile release boundary | `npm run release:mobile:boundary:test` + source-contract/security/syntax/YAML checks | GREEN; release mode·expected version/package/cert/prod AdMob·Ed25519 signed evidence와 artifact hash 일치, immutable snapshot, hardlink/reparse/path-swap/static APK 우회·overwrite·test AdMob/debug signer/nonrelease 거부를 검증. 실제 production APK/AAB에는 아직 실행하지 않음 | `scripts/ci/mobile-release-evidence-lib.mjs`, `scripts/ci/verify-mobile-release-boundary.mjs`, `.github/workflows/release.yml` | 2026-08-21 |
|
||||
| Production Android release gate | release/config/artifact/provenance self-tests + Play/Firebase/AdMob live 재확인 | release identity `1.1.0`/`1010001`, Play app ID `4976102237698469110`, package `com.d3ro.voice`, app-signing SHA-256, local upload/evidence key, AdMob identity를 확인했다. Play는 `임시`, 설정 0/11, AAB 0건, closed tester 0/12명, production access disabled다. Firebase project·CI secret 주입·AAB가 없으므로 현재 판정은 RED다 | `release/product-version.json`, `release/android-release-identity.json`, `scripts/ci/verify-mobile-release-config.mjs`, `scripts/ci/verify-android-artifact.mjs`, live consoles | 2026-08-29 |
|
||||
| Production Android release gate | release/config/artifact/provenance self-tests + Play/Firebase/AdMob live 재확인 | release identity `1.2.0`/`1020001`, Play app ID `4976102237698469110`, package `com.d3ro.voice`, app-signing SHA-256, local upload/evidence key, AdMob identity를 확인했다. Play는 `임시`, 설정 0/11, AAB 0건, closed tester 0/12명, production access disabled다. Firebase project·CI secret 주입·AAB가 없으므로 현재 판정은 RED다 | `release/product-version.json`, `release/android-release-identity.json`, `scripts/ci/verify-mobile-release-config.mjs`, `scripts/ci/verify-android-artifact.mjs`, live consoles | 2026-08-29 |
|
||||
| App Links release identity | source/live exact certificate 대조 | `site/public`, `apps/web/public`, `apps/api-server/wwwroot`의 source 3개는 Play app-signing SHA-256으로 갱신. live는 아직 폐기된 과거 certificate를 반환하므로 deploy·public 재검증 전까지 RED | `*/.well-known/assetlinks.json`, `scripts/ci/verify-android-app-links.mjs`, live `d3ro.chanpaca.net` | 2026-08-29 |
|
||||
| Public legal and deletion resources | scoped NAS host/container deploy + anonymous HTTPS render | 개인정보처리방침, 이용약관, 앱 외부 계정 삭제 요청 경로를 기존 사이트 전체와 분리해 배포했다. host와 running container 4개 파일 SHA 일치; `/privacy/`, `/terms/`, `/delete-account/` 모두 외부 HTTPS 200·정확한 title, privacy→deletion 링크 visible. 실서버 본문 운영자는 `YUN CHAN`, Cloudflare email-protection 복호화 연락처는 `yunchan8804@gmail.com`, `TWENTYOZ` 잔존은 0건이다. Google Play 정책상 필요한 앱 식별·개발자 문의·수집/공유·보관/삭제·외부 삭제 요청 경로를 포함하고 모바일 Settings/Paywall에도 canonical link를 노출 | `site/public/legal.css`, `site/public/privacy/index.html`, `site/public/terms/index.html`, `site/public/delete-account/index.html`, `apps/mobile-rn/src/screens/SettingsScreen.tsx`, live `d3ro.chanpaca.net` | 2026-08-21 |
|
||||
| Android upload signing identity | create-only 3072-bit RSA PKCS12 + Windows credential vault + certificate readback | 2026-08-21에 생성한 local upload-key 후보 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`다. 다만 production CI secret·오프라인 복구 백업·실제 AAB signer 증거는 없다. Play Console upload certificate는 첫 AAB 업로드 후 표시되며, 현재 확인한 Play app-signing SHA-256과 분리해 대조해야 한다 | `release/android-release-identity.json`, `scripts/gen-keystore.js`, Windows Credential Manager | 2026-08-29 |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Google Play 출시 체크리스트
|
||||
|
||||
기준일: 2026-08-29. 체크 표시는 이 문서를 읽은 사람이 실제 증거를 확인한 뒤에만 바꾼다. 소스 검사, debug/E2E APK, HTTP 200 하나만으로 release GREEN을 선언하지 않는다.
|
||||
기준일: 2026-09-16. 체크 표시는 이 문서를 읽은 사람이 실제 증거를 확인한 뒤에만 바꾼다. 소스 검사, debug/E2E APK, HTTP 200 하나만으로 release GREEN을 선언하지 않는다.
|
||||
|
||||
### 2026-08-29 Play Console live 스냅샷
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
|
||||
| 앱 | `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 증거는 아직 없음 |
|
||||
| release identity | versionName `1.2.0`, Android versionCode `1020001` | 소스 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·복구 백업 미완료 |
|
||||
|
|
@ -125,7 +125,7 @@
|
|||
- [x] package는 `com.d3ro.voice`: `apps/mobile-rn/android/app/build.gradle:289-302`.
|
||||
- [x] release cleartext traffic은 false이고 release ABI는 arm64-v8a: `build.gradle:372-386`.
|
||||
- [x] release gate는 keystore, version, Firebase config, production AdMob app/banner/rewarded ID를 요구한다: `build.gradle:45-103,157-219`.
|
||||
- [x] release identity를 `D3RO_VERSION_NAME=1.1.0`, `D3RO_VERSION_CODE=1010001`로 확정했다.
|
||||
- [x] release identity를 `D3RO_VERSION_NAME=1.2.0`, `D3RO_VERSION_CODE=1020001`로 확정했다.
|
||||
- [x] Ed25519 release-evidence keypair을 생성하고 private key를 저장소 밖 user-only ACL 경로에, public key를 `release/mobile-release-evidence-public.pem`에 보존했다. keyId `2797d3e63affd2348941bc2871b57e520c958f7f5da1a4bbe8aa46904a890b7f`, sign/verify roundtrip GREEN이다.
|
||||
- [ ] upload/evidence private key·Firebase·AdMob secrets를 승인된 CI secret store에 주입하고 별도 복구 백업을 검증했다.
|
||||
|
||||
|
|
@ -299,7 +299,7 @@ AdMob 콘솔 준비를 실제 광고 게재 승인·수입·Play release 완료
|
|||
## 13. Production 제출·점진 배포
|
||||
|
||||
- [ ] internal/closed에서 검증한 **동일 AAB SHA** 또는 정당한 수정 후 새로 전부 검증한 AAB를 사용했다.
|
||||
- [x] versionCode `1010001`용 release notes ko/en을 작성했다: `apps/mobile-rn/metadata/android/{ko-KR,en-US}/changelogs/1010001.txt`.
|
||||
- [x] versionCode `1020001`용 release notes ko/en을 작성했다: `apps/mobile-rn/metadata/android/{ko-KR,en-US}/changelogs/1020001.txt`.
|
||||
- [ ] country/region과 가격·세금·정책 적용 범위를 검토했다.
|
||||
- [ ] device catalog 제외가 기능/SDK 사실에 근거하며 불필요하게 넓지 않다.
|
||||
- [ ] 모든 Console warning과 policy declaration을 검토했다.
|
||||
|
|
@ -331,7 +331,7 @@ AdMob 콘솔 준비를 실제 광고 게재 승인·수입·Play release 완료
|
|||
| Placeholder | 실제 값 소유 위치 | 완료 조건 |
|
||||
| -------------------------------------------- | ---------------------------- | ------------------------------------------------------- |
|
||||
| `<PLACEHOLDER_RELEASE_COMMIT_SHA>` | Git remote/CI | 권위 있는 release source SHA |
|
||||
| versionName `1.1.0` / versionCode `1010001` | release SSOT | 확정. 실제 AAB·Console metadata 대조는 대기 |
|
||||
| versionName `1.2.0` / versionCode `1020001` | 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·복구 백업 대기 |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue