Skip to content

Remove native Kilo Pass sales from mobile - #7272

Closed
iscekic wants to merge 5 commits into
mainfrom
igor/mobile-subscription-sales-free
Closed

iscekic wants to merge 5 commits into
mainfrom
igor/mobile-subscription-sales-free

Conversation

@iscekic

@iscekic iscekic commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator

Scope

PR 1 of the native subscription retirement plan.

  • Remove native Kilo Pass purchase requests, tier selection, upgrades, promotions, and sales disclosures.
  • Show subscription state, paid expiry, streak, and available bonus credits without web checkout links.
  • Keep native credit packs and matching-platform management for existing store subscriptions.
  • Keep owned native management available when the primary subscription is on web or backend recovery is incomplete.
  • Keep charged receipt recovery, historical product recognition, account fencing, and completion idempotency.
  • Remove organization subscription checkout and web management actions.
  • Set the app version to 1.0.15 and update all 87 locale catalogs.

Verification

  • Focused mobile tests: 24 files, 331 tests passed.
  • Organization tests: 2 files, 15 tests passed.
  • Mobile typecheck, lint, unused-code check, locale check, and source formatting passed.
  • GCE Android debug build 1.0.15 installed and ran against the isolated backend and Metro.
  • iOS debug build 1.0.15 compiled with the local Xcode toolchain, installed, and ran against the VM.
  • Both apps showed an owned local fixture with $57 in credits, three streak months, and paid expiry.
  • iOS showed matching-store management; Android did not show an App Store management action.
  • iOS showed four localized credit prices and reached native Apple authentication for the $10-credit pack.
  • Canceling that request kept the displayed credit balance at $57.
  • The organization hub showed read-only Kilo Pass state without a setup link.
  • The latest storage, casing invariant, and subscription management suites passed: 3 files, 87 tests.
  • CI passed all 30 checks; Kilobot recommends merge with no unresolved threads.

Remaining store verification

Live sandbox payment fulfillment is not yet verified for this branch.
The simulator authentication sheet did not prove sandbox mode, so no Apple credential or payment was submitted.
Google Play verification requires an approved second factor; that sign-in stopped without a purchase.
The new iOS binary opens native management, but the unsigned-in store displays Cannot Connect.
Verify sandbox fulfillment and both signed release builds before submitting or forcing an upgrade.

Release boundary

This PR does not submit a store release, raise minimum versions, retire renewals, send migration emails, or change production settings.
The backend migration PR remains independent.
The release tool generates CHANGELOG.md after an actual submission supplies the build identity.

@iscekic iscekic self-assigned this Oct 8, 2026
@iscekic

iscekic commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Local runtime evidence. Android ran the 1.0.15 debug binary on GCE. iOS ran the changed JavaScript on a compatible 1.0.13 development binary. The paid subscription is a synthetic local database fixture, not a live store purchase.

iOS read-only paid subscription, expiry and streak

Android paid subscription without a cross-store management action

iOS localized one-off credit catalog

Organization Kilo Pass state without a setup link

@kilo-code-bot

kilo-code-bot Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of commit 408bea37 finds the type-only change in apps/mobile/src/lib/persist/encrypted-kv.ts correct: ExpoSQLiteDatabase is exported from drizzle-orm/expo-sqlite/driver in the pinned drizzle-orm 0.45.2, and the new KVDatabase alias is structurally equivalent to the previous ReturnType<typeof drizzle>, so there is no behavior or type regression.

Files Reviewed (1 file)
  • apps/mobile/src/lib/persist/encrypted-kv.ts
Previous Review Summaries (4 snapshots, latest commit 017525d)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 017525d)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of commit 017525d7 finds the restored apps/mobile/src/lib/case-guard.test.ts guard consistent with the current apps/mobile/src tree: every non-test bare toUpperCase()/toLowerCase() call site in components, lib, and app is covered by the reasoned allowlist (verified mechanically), the referenced guard files exist, and the previously flagged comment in session-list-helpers.ts that cited this guard is accurate again now that the guard is restored. No high-confidence defects found in the changed code.

Files Reviewed (1 file)
  • apps/mobile/src/lib/case-guard.test.ts

Previous review (commit bbd99d1)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/mobile/src/components/agents/session-list-helpers.ts 125 Comment still cites the deleted src/lib/case-guard.test.ts guard as the enforcement for the bare-toLowerCase() ban
Files Reviewed (1 file)
  • apps/mobile/src/lib/case-guard.test.ts (deleted) - test-only removal; no production impact

Fix these issues in Kilo Cloud

Previous review (commit 79e6b64)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of the follow-up commit 79e6b647 finds the owned-native-receipt management path internally consistent: the new store-evidence hook fences by auth epoch and account token, the screen only uses native evidence to expose the platform's own management sheet (benefits still come from the backend), and the changed tests cover ownership, expiry, pending, and suspended states. No high-confidence defects found.

Files Reviewed (4 files)
  • apps/mobile/README.md
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.test.ts
  • apps/mobile/src/lib/kilo-pass/use-owned-native-kilo-pass.ts (new)

Previous review (commit 4c25ce4)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The native Kilo Pass sales removal in apps/mobile is internally consistent: deleted modules have no remaining references, all locale keys used by the new read-only surfaces exist across the 87 catalogs, and the changed test/source behavior aligns with the current client logic. No high-confidence defects found.

Files Reviewed (50 files + 87 locale catalogs)

Sources / config:

  • apps/mobile/app.config.ts
  • apps/mobile/src/components/credits/credit-native-iap-owner.tsx
  • apps/mobile/src/components/kilo-pass/kilo-pass-play-manage.ts
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.tsx
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.tsx
  • apps/mobile/src/components/kilo-pass/restore-purchases-button.tsx
  • apps/mobile/src/components/organization/hub-screen.tsx
  • apps/mobile/src/components/organization/org-kilo-pass-row-state.ts
  • apps/mobile/src/lib/analytics/posthog.ts
  • apps/mobile/src/lib/auth/auth-context.tsx
  • apps/mobile/src/lib/iap/store-call-deadline.ts
  • apps/mobile/src/lib/iap/store-purchase-recovery-mount.tsx
  • apps/mobile/src/lib/kilo-pass/historical-store-products.ts (new)
  • apps/mobile/src/lib/kilo-pass/legal-links.ts
  • apps/mobile/src/lib/kilo-pass/subscription-card-state.ts
  • apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.ts
  • apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-recovery.ts (new)
  • apps/mobile/README.md

Tests:

  • apps/mobile/src/components/kilo-pass/kilo-pass-play-manage.test.ts
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.mounted.test.tsx
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-card.narrow.mounted.test.tsx
  • apps/mobile/src/components/kilo-pass/kilo-pass-subscription-screen.test.ts
  • apps/mobile/src/components/organization/org-kilo-pass-row-state.test.ts
  • apps/mobile/src/lib/auth/auth-context.lifecycle.test.tsx
  • apps/mobile/src/lib/auth/auth-context.test.ts
  • apps/mobile/src/lib/auth/credentials.test.ts
  • apps/mobile/src/lib/iap/store-purchase-recovery-mount.mounted.test.tsx
  • apps/mobile/src/lib/iap/store-purchase-recovery-retired-products.mounted.test.tsx (new)
  • apps/mobile/src/lib/kilo-pass/legal-links.test.ts
  • apps/mobile/src/lib/kilo-pass/subscription-card-content-state.test.ts
  • apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-purchase.test.tsx
  • apps/mobile/src/lib/kilo-pass/use-store-kilo-pass-recovery.mounted.test.tsx (new)

Deleted modules (verified unreferenced):

  • kilo-pass-native-iap-owner.tsx (+its test), store-products*.ts, product-query-failure.ts, navigation.ts, use-store-kilo-pass-products.ts(+tests), subscription-card-state.test.ts, subscription-card-ownership-preflight.test.ts

Locale:

  • 87 files under apps/mobile/src/i18n/locales/ (all valid JSON, key parity with en.json, new keys paidThrough, streakMonths, bonusIssued, bonusAvailable, statusPaused present, removed keys unreferenced)

Reviewed by deepseek-v4.1-flash · Input: 42K · Output: 4.7K · Cached: 419.3K

Review guidance: REVIEW.md from base branch main

@iscekic

iscekic commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up 79e6b64 keeps matching native management reachable when Stripe is primary or paid recovery remains unfinished. The regression failed before the fix and passed afterward. All 36 screen cases passed, including ownership, expiry, pending payments, suspended Play state, stopped renewal, and native SKU selection. Mobile typecheck, lint, formatting and unused-code checks passed. The actual iOS app retained read-only status and native management. Opening management reached Apple authentication; no credential or store change was submitted. Live store fulfillment remains a release gate.

@iscekic

iscekic commented Oct 8, 2026 •

Copy link
Copy Markdown
Collaborator Author

Correction: removing the casing guard was wrong. I restored it and added the existing non-display account-token exception for use-owned-native-kilo-pass.ts. The UUID comparison does not change display text. The ownership regression still covers uppercase App Store account tokens. The other 17,172 tests passed in each failed CI job; the new head retains the guard.

@iscekic

iscekic commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

The new CI head reported the unchanged storage query as a void expression. TypeScript 5.9.3 resolves that query to { v: string } | undefined. I replaced the private generic ReturnType alias with the direct ExpoSQLiteDatabase type and its SQLite client handle. The SQL and runtime behavior stay unchanged. Mobile typecheck, lint, formatting, and 87 focused tests passed. The casing invariant remains present with only the owned UUID exception.

@iscekic

iscekic commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

The actual iOS 1.0.15 debug binary now compiles and runs against the isolated VM. Its paid fixture shows 3 streak months, the expiry, and the bonus. The credit screen keeps four localized one-off packs. Neither screen offers a subscription purchase or web checkout link. Native management opens the store sheet; the unsigned-in simulator reports Cannot Connect. No credential or payment followed. All 30 CI checks pass, and Kilobot recommends merge.

Actual 1.0.15 personal profile

Read-only paid Pass and historical management

Remaining native one-off credit packs

Native management reached the unavailable store

@iscekic

iscekic commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

The actual iOS 1.0.15 binary also shows the isolated organization Pass state without subscription setup or web management actions.

Read-only organization Pass without checkout actions

@iscekic

iscekic commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Additional iOS 1.0.15 smoke: switched from the native-paid fake account to a separate fake account. The app showed $0 and no inherited subscription. Its Kilo Pass screen showed Not subscribed and Restore Purchases only. No subscription sale or web checkout link appeared. Optional analytics stayed off. Live native store fulfillment remains an authentication gate.

screenshot

@iscekic

iscekic commented Oct 8, 2026

Copy link
Copy Markdown
Collaborator Author

Actual Android 1.0.15 account-switch smoke passed on the isolated VM.

  • The distinct fake account shows $0 and Not subscribed before local Stripe webhook replay.
  • Kilo Pass shows Restore Purchases only; no sales, web checkout link, or wrong-owner management action appears.
  • The app did not inherit the previous fake account’s $57 or three-month streak.
  • The linked fake email and native v1.0.15 (1) were verified. Optional analytics were verified off.

Live Play checkout and fulfillment remain blocked by unapproved Google second verification. This evidence proves the actual UI and account reset, not live store billing.

subs-android-1 0 15-inactive-switch

@iscekic iscekic closed this Oct 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant