Files
opencode-mobile/distribution/ios-enrollment-runbook.md
Den 2b9b571d6e feat(privacy+dist): telemetry consent gate + app store distribution prep (#4)
* fix(security): fail closed on biometric init error

H-03: setting isAuthenticated: true on initialization failure was a
security bypass — any crash during biometric setup granted full access.
Fail closed instead; user sees auth prompt on next open.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(security): use Crypto.randomUUID for connection IDs

H-04: Math.random() is not cryptographically random. Connection IDs are
used as SecureStore key suffixes; switch to expo-crypto randomUUID for
a secure source.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(deps): pin expo-crypto to ~15.0.9

15.0.10 does not exist on npm; ~15.0.9 is the latest stable in the 15.x series compatible with Expo SDK 54.

* feat: add OpenCode Connect coming-soon waitlist card

Adds a discoverable 'OpenCode Connect — Coming Soon' card to the
add-connection quick-connect screen. Users can enter their email and
tap 'Join Waitlist' to send a pre-filled mailto. No backend required.

* fix(cua): detect actual screen dimensions and fix JSON parsing

- Get real screen size via `wm size` instead of hardcoding 1080x2400;
  emulator is 1080x1920 so y-coordinates were systematically off
- Extract first JSON object via regex when model returns multiple objects
- Use AZURE_OPENAI_MODEL env var for deployment name (defaults gpt-5.4)
- Add AZURE_DEV_AI_* path for Azure AI Foundry endpoints

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(security): SHA-pin upload-google-play and sanitize notification bodies

M-02: Pin r0adkll/upload-google-play to commit SHA e738b9d (v1.1.5)
to prevent supply-chain hijack via tag mutation.

M-03: Sanitize all push notification bodies — strip control chars,
truncate to 200 chars. Prevents server-supplied strings (error messages,
file paths from permission patterns, session titles) from leaking
unbounded text into the OS notification drawer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(privacy): add telemetry consent gate for Sentry crash reporting

Sentry was always-on, violating F-Droid anti-feature policy and user
trust norms. Now gated behind explicit opt-in:

- First-launch consent modal (TelemetryConsentModal) shows once on
  fresh install; user can Allow or Decline.
- Consent state persisted in expo-secure-store (survives restarts).
- Settings > Privacy section: crash reporting toggle + privacy policy link.
- initSentry() called only after consent granted — not on app start.

Closes #3 (partial)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(config): add real icons and complete iOS/Android app.json config

- Add 1024×1024 app icon, 432×432 adaptive icon foreground, 200×200 splash
- iOS: push notification entitlement (aps-environment: production), speech/
  microphone/camera/photo usage descriptions for future features, disable
  ITSAppUsesNonExemptEncryption
- Android: adaptive icon with dark background (#0F172A), versionCode: 1
- expo-notifications plugin wired in app.json

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* feat(dist): add iOS CI workflow, README rewrite, CONTRIBUTING, and LICENSE

- publish-app-store.yml: EAS Build + TestFlight submission; runs on tag/release/
  workflow_dispatch; bumps ios.buildNumber from github.run_number
- README: full rewrite — features, install badges, connection guide, contributing
- CONTRIBUTING.md: contribution guide for OSS contributors
- LICENSE: MIT

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* docs(dist): add store listings, strategy, privacy policy, F-Droid/IzzyOnDroid templates

- distribution/strategy.md: monetization strategy (free client + opencode Cloud)
- distribution/play-listing.md: Google Play store copy (name, description, tags)
- distribution/app-store-listing.md: App Store listing copy
- distribution/privacy-policy.{md,html}: GDPR-compliant privacy policy
- distribution/PLAY_CONSOLE_SETUP.md: Play Console setup runbook
- distribution/ios-enrollment-runbook.md: Apple Developer Program enrollment steps
- distribution/SIGNING-KEY-FINGERPRINTS.md: keystore fingerprint for reproducible builds
- distribution/fdroid-submission/: F-Droid metadata template
- distribution/izzyondroid-submission/: IzzyOnDroid submission template
- distribution/whatsnew/: Play Store release notes (en-US)
- distribution/whatsnew-ios/: TestFlight release notes
- distribution/play-graphics/: Play Store screenshot placeholders
- distribution/app-store-graphics/: App Store screenshot placeholders

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(telemetry): handle SecureStore failure + Android back button

- add .catch() on loadTelemetryConsent() so SecureStore rejection
  shows the consent modal instead of blocking startup forever
- add onRequestClose={onDecline} to Modal so Android back button
  records the decline rather than silently dismissing
- fix catch block in telemetry.ts to not clobber _resolved when
  SecureStore read fails mid-session

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): run gradlew clean to prevent stale modules.json duplicate

Sentry Gradle plugin writes modules.json to src/main/assets; cached
build intermediates contain an old copy → mergeReleaseAssets fails
with 'Duplicate resources'. Running clean before assembleRelease
clears the intermediate state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(ci): remove android build output cache causing duplicate modules.json

Caching android/app/build/intermediates and android/app/.cxx causes
two issues:
1. Stale modules.json in intermediates → Duplicate resources error
2. .cxx CMake artifacts reference absolute paths → ninja clean fails

Keeping only Gradle distribution cache (~/.gradle) which is safe.
Expo prebuild regenerates android sources fresh each run anyway.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 17:42:03 -07:00

174 lines
7.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Apple Developer Program Enrollment Runbook — VIBE TECHNOLOGIES, LLC
Pre-filled guide for enrolling as an organization. Do NOT proceed until you have $99 USD available on the Apple ID credit card, and you have the governor's contact information ready for the verification call.
Reference: https://developer.apple.com/programs/enroll/
---
## Pre-filled Entity Data
| Field | Value | Source |
|---|---|---|
| Legal Entity Name | VIBE TECHNOLOGIES, LLC | WA LLC registration |
| D-U-N-S Number | **142059652** | Already retrieved |
| UBI / EIN | 606 003 933 | WA Secretary of State |
| Legal Address | 519 S Henderson St, Seattle WA 98108-4522, USA | WA LLC registration |
| Legal Entity Type | LLC (Limited Liability Company) | |
| Primary Contact / Authorized Agent | Dzianis Vashchuk | Governor of LLC |
| Primary Contact Phone | (use a number reachable for Apple's verification call) | |
| Primary Contact Email | support@vibebrowser.app | |
| Website | https://www.vibebrowser.app/ | |
---
## Apple ID to Use
**DECIDED 2026-05-24**: Use `support@vibebrowser.app` — mailbox already exists (was verified during Play Console signup, confirmed receiving Google verification codes).
- If no Apple ID exists yet for `support@vibebrowser.app`: create at https://appleid.apple.com/account
- 2FA: enable immediately, trusted phone = Dzianis's mobile
- Bitwarden item naming: store as `APPLE_ID_VIBE_TECHNOLOGIES` (email + password + 2FA recovery codes)
---
## Step-by-Step Enrollment
### Step 1 — Prepare
- [ ] Verify D-U-N-S 142059652 is current at https://developer.apple.com/enroll/duns-lookup/ (takes 14 days to propagate if recently created; ours was already retrieved so should be active)
- [ ] Ensure the Apple ID email mailbox is active and accessible
- [ ] Have a credit card ready ($99 USD charge)
- [ ] Ensure Dzianis Vashchuk is available for a verification phone call during business hours (Apple calls the listed phone number for organization enrollment)
### Step 2 — Start Enrollment
1. Go to https://developer.apple.com/programs/enroll/
2. Click **Start Your Enrollment**
3. Sign in with the Apple ID you chose above (or create one)
4. Select **Company / Organization**
### Step 3 — Enter Organization Details
Fill as follows:
| Prompt | Enter |
|---|---|
| Legal Entity Name | `VIBE TECHNOLOGIES, LLC` |
| D-U-N-S Number | `142059652` |
| Headquarters Address (Line 1) | `519 S Henderson St` |
| City | `Seattle` |
| State | `WA` |
| ZIP | `98108` |
| Country | `United States` |
| Phone | (Dzianis's direct mobile — Apple calls this) |
| Website | `https://www.vibebrowser.app/` |
### Step 4 — Verify Your Authority
Apple asks you to confirm you are authorized to bind the organization to the Apple Developer Program Agreement. As governor/managing member of the LLC, Dzianis Vashchuk has this authority.
Select: "I am authorized to sign legal agreements on behalf of this organization."
### Step 5 — Apple Review & Verification Call
- Apple's team will verify the D-U-N-S number against Dun & Bradstreet records.
- **Expect a phone call** to the number entered above within 2–5 business days.
- The caller will confirm the legal entity name, address, and that you are authorized to enroll.
- Answer in English; have the LLC registration handy (UBI 606 003 933) in case they ask for additional verification.
**Timeline**: 2–7 business days for verification. Apple can take up to 14 days in edge cases.
### Step 6 — Pay
After verification is approved:
- Apple charges **$99 USD/year** to the credit card on the Apple ID.
- Enrollment renews annually. Set a calendar reminder.
- Source: https://developer.apple.com/support/enrollment/ (pricing as of 2025 — verify current pricing at enrollment time)
### Step 7 — Accept Agreements
After payment:
1. Sign in to https://developer.apple.com/account/
2. Accept the Apple Developer Program License Agreement
3. Accept the Paid Applications Agreement (required to distribute free apps too)
### Step 8 — Set Up App Store Connect
1. Go to https://appstoreconnect.apple.com/
2. Sign in with the same Apple ID
3. Fill in banking info even for a free app (required to publish):
- US bank account (ACH/routing number)
- Tax information (W-9 for US entities — EIN 606 003 933)
4. Accept the Paid Applications Schedule even if distributing free (Apple requires this)
---
## What Can Be Done in Parallel (Before Enrollment Approval)
While waiting for Apple's verification call and approval:
- [x] Prepare App Store listing copy → `distribution/app-store-listing.md`
- [x] Write CI workflow (draft) → `.github/workflows/publish-app-store.yml`
- [ ] Create app icon 1024×1024 PNG
- [ ] Capture iPhone screenshots (use iOS Simulator in Xcode on any Mac)
- [ ] Capture iPad screenshots
- [ ] Write/publish privacy policy at https://www.vibebrowser.app/opencode-mobile/privacy
- [ ] Set up EAS account at https://expo.dev/ (free tier, log in with Expo account)
- [ ] Add iOS config patches to `app.json` (done in this PR)
- [ ] Run `npx expo prebuild --platform ios` on a Mac to validate the Xcode project
- [ ] Prepare the Mac build worker (macbook13-pro at 100.68.120.26) as GitHub self-hosted runner
---
## After Enrollment Approval — App Store Connect Setup
1. Create a new App in App Store Connect:
- Platform: iOS
- Name: `OpenCode`
- Primary Language: English (U.S.)
- Bundle ID: `ai.opencode.mobile` — register this explicit App ID first at https://developer.apple.com/account/resources/identifiers/
- SKU: `ai.opencode.mobile` (can match bundle ID)
2. Configure App ID capabilities needed:
- Push Notifications (for `expo-notifications`)
- Associated Domains (if deep linking via `opencode://` is used externally — not strictly needed for current app)
3. Create App Store Connect API Key for CI:
- Go to https://appstoreconnect.apple.com/access/api
- Create key with **App Manager** role
- Download the `.p8` file (can only be downloaded once!)
- Note: Key ID and Issuer ID
- Base64-encode the .p8 and store in GitHub secret `APPLE_APP_STORE_CONNECT_API_KEY`
4. Create an internal TestFlight group and add yourself as tester
---
## Cost Summary
| Item | Cost | Frequency |
|---|---|---|
| Apple Developer Program | $99 USD | Per year (auto-renews) |
| EAS Build (free tier) | $0 | Up to 30 builds/month for iOS |
| EAS Build (production tier) | $19/month | Unlimited builds, priority queue |
| macOS GitHub runner | ~$0.08/min × ~25 min/build ≈ $2/build | Per build |
**Recommendation**: Start with EAS Build free tier for first few releases. Upgrade to production tier ($19/month) if build queue times become a problem. See task 2 analysis in the final report.
---
## Timeline Estimate
| Milestone | Estimated Time from Starting Enrollment |
|---|---|
| Enrollment form submitted | Day 0 |
| Apple verification call | Day 2–5 |
| Enrollment approved + payment | Day 3–7 |
| Banking/tax info set up | Day 7–8 |
| App ID + provisioning profile created | Day 8 |
| First TestFlight build submitted via CI | Day 9–10 |
| TestFlight internal testers can install | Day 9–10 (no review for internal) |
| App Store production submission | Day 10–12 |
| Apple review complete + production live | Day 12–14 (review typically 24–48 hours) |