Skip to content

feat(mobile): auto-open first-run tour only for zero-usage accounts on cold boot - #6327

Merged
iscekic merged 3 commits into
mainfrom
kwf/req-20260918-155205-bb44
Sep 23, 2026
Merged

iscekic merged 3 commits into
mainfrom
kwf/req-20260918-155205-bb44

Conversation

@iscekic

@iscekic iscekic commented Sep 18, 2026 •

Copy link
Copy Markdown
Collaborator

Changelog for users

  • The guided tour opens by itself once, on a cold app launch, and only for accounts with no Kilo gateway usage.
  • An account with any Kilo gateway usage never gets the automatic tour.
  • The Profile Tutorial row still opens the tour on demand.
  • Opening the tour from Profile does not re-arm the automatic open.
  • Requests for a currently disabled Kilo-only OpenAI alias no longer use a person's "Sign in with ChatGPT" connection.
  • The repair changes no user-visible behavior; it only restores the branch's failing build and test checks.

Changelog for maintainers

  • apps/mobile/src/components/tour/tour-auto-open.tsx:151 — accepted: the gate returned on the consent and usage holds without spending the process attempt, so a later sign-in could inherit it and auto-open. The attempt is now bound to the launch account, and a different account spends it instead of opening.
  • apps/web/src/routers/user-router.test.ts:1970 — accepted: the hasGatewayUsage teardown deleted the org and its users but left the organization_memberships row createTestOrganization inserted. It now deletes that membership row for the org owner first.
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.ts:112 — accepted: a disabled Kilo-exclusive alias was treated as a delegated OpenAI model. The gate now rejects disabled exclusives and trims and lower-cases the id before its alias checks. Review this gate first; it decides delegated eligibility for every OpenAI model id. routing.test.ts parameterized coverage pins the disabled aliases (plain, upper-case, padded) as ineligible before any connection, token, or served-model lookup; apps/mobile/src/lib/case-guard.test.ts allows lib/auth/passkey-client.ts, whose bare case calls classify native credential-API errors and never produce display text.
  • Adds user.hasGatewayUsage, a single indexed lookup on the primary database that reports any microdollar_usage row; org-scoped and zero-cost free-model rows count as usage. Mobile reads the signal through the new useTourGatewayUsage hook, enabled while the launch attempt is unspent. services/kilo-mcp/catalog.json commits the summary, so the catalog dump no longer calls the unsigned Kilo CLI on CI.
  • A once-per-process boot marker defines cold boot, so a warm entry into the (app) area or a foreground resume cannot re-arm the automatic open. Unknown usage (loading or failed) holds the gate without spending the launch account's attempt, and an unknown value never opens the tour.
  • A completed or already-open tour spends the attempt, so no later account in the same process can auto-open, and the per-account SecureStore record keeps a Profile replay manual. Start review at the mobile tour gate effect, where consent, usage, route, and process state combine.
  • apps/mobile/src/components/ui/segmented-control.tsx — a duplicated numberOfLines prop failed typecheck and lint; the duplicate is removed and one numberOfLines with adjustsFontSizeToFit remains, so every option label stays on one line. Start the repair review here.
  • The repair also corrects three stale mobile tests, and no check is skipped: manual-review-screen.mounted.test.tsx stubs the keyboard-padding wrapper, whose module loads the real React Native through react-native-safe-area-context outside the partial mock; text.rtl-tracking.mounted.test.tsx expects the RTL eyebrow to drop the Latin tracking class; screen-insets.test.ts pins the Profile sign-out confirmation to the shared useSignOutConfirmation hook. Proof replacement: the passing e1 verification under E2E proof replaces the superseded zero-usage cold-start proof, and the 2026-09-18 gateway-usage captures remain valid. The mobile device checks for the segmented-control label and the RTL eyebrow did not run (the Android resource did not start), so they remain skipped and pending owner verification.

E2E proof

[e2] [non-zero usage] a user with gateway usage never auto-opens it, but Profile > Tutorial still opens it. — prior/e2-consent-accepted.png

[e2] [non-zero usage] a user with gateway usage never auto-opens it, but Profile > Tutorial still opens it. — prior/e2-tutorial.png

e8-coldstart2

[e8] ux-check: Signed in with an account that has any Kilo gateway usage, cold-start the app: the tour never auto-opens; switching tabs and backgrounding/foregrounding the app also never opens it… — prior/e8-profile.png

[e8] ux-check: Signed in with an account that has any Kilo gateway usage, cold-start the app: the tour never auto-opens; switching tabs and backgrounding/foregrounding the app also never opens it… — prior/e8-after-foreground.png

[e6] ux-check: zero-usage account, cold-start shows the guided tour exactly once and dismissing it does not reopen it in the session (android emulator-5604) — prior/e6-home.png

[e6] ux-check: zero-usage account, cold-start shows the guided tour exactly once and dismissing it does not reopen it in the session (android emulator-5604) — prior/e6-tour.png

[e1] Zero-usage account cold start: the tour auto-opens exactly once; dismissing it and a warm background/foreground resume do not reopen it. — scripted-shard1/e1.png

e3-04-home

e3-04-home

Owner request

Change which users see the first-run tour in the mobile app (the cloud repo).

Target behaviour. The tour auto-opens once, on a cold boot only, and only for a user whose
kilo gateway usage is zero
. A user who has used Kilo (any gateway usage) must never see it
automatically. They can still open it by hand from the Tutorial row in Profile, and a manual open
must not re-arm the automatic one.

Where the gate is today. apps/mobile/src/components/tour/tour-auto-open.tsx (120 lines) is the
whole gate; it is mounted in apps/mobile/src/app/(app)/_layout.tsx:125. It pushes the tour once per
account when: a user id exists, the completion store is loaded, the tour is not completed for that
account, consent is accepted, it has not already opened for this account in this session, and it is
not already on the consent or tour routes. The per-account decision lives in
apps/mobile/src/lib/tour/tour-completion.ts — one SecureStore record per user
(tour-completed-<hex>), deliberately never cleared, so a Profile replay stays a manual action. The
manual entry point is the Tutorial row in apps/mobile/src/components/profile-screen.tsx.

Note a discrepancy to resolve first. The owner reads today's behaviour as "never shown", but the
code above auto-opens once per account after consent. Confirm the real current behaviour (a flag, a
build config, or the account's stored state may be suppressing it) and say what you found before you
change anything. Do not assume either reading.

The usage signal. "Kilo gateway usage" must mean the same thing it means elsewhere in the product
— find the per-user signal rather than inventing one. The mobile app currently only has the
organization-level trpc.organizations.usageStats (apps/mobile/src/lib/hooks/use-organization-queries.ts:139);
the web has the user's own usage. If mobile cannot reach a per-user gateway-usage value, expose the
existing one; do not define a new metric.

Cold boot. Automatic open must happen only on a cold start of the app, not on every entry into the
(app) area or on a foreground resume.

Acceptance.

  • A user with zero gateway usage sees the tour exactly once, on a cold boot.
  • A user with any gateway usage never sees it automatically, at any point.
  • The Profile Tutorial row still opens it, and doing so never re-arms the automatic open.
  • The behaviour is pinned by a test on the gate, covering: zero usage + cold boot (open), non-zero
    usage (never), a manual replay (open, then no re-arm), and a warm entry (no open).

E2E proof — log excerpts

[e1] Zero-usage account cold start: the tour auto-opens exactly once; dismissing -> pass :: jev read the digest: pass (confidence 0.99)

@iscekic
iscekic force-pushed the kwf/req-20260918-155205-bb44 branch from a7224c4 to fba806e Compare September 18, 2026 23:07
Comment thread apps/mobile/src/components/tour/tour-auto-open.tsx
Comment thread apps/web/src/routers/user-router.test.ts
@kilo-code-bot

kilo-code-bot Bot commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the mobile tour cold-boot/zero-usage gate, the launch-account boot marker, the gateway-usage hook and user.hasGatewayUsage, the OpenAI-ChatGPT disabled-alias routing gate, and the accompanying tests; no new defects were found in the changed lines.

Files Reviewed (13 files)
  • apps/mobile/src/components/app-unlock-screen.test-helpers.tsx
  • apps/mobile/src/components/code-reviewer/manual-review-screen.mounted.test.tsx
  • apps/mobile/src/components/tour/tour-auto-open.mounted.test.tsx
  • apps/mobile/src/components/tour/tour-auto-open.tsx
  • apps/mobile/src/components/ui/text.rtl-tracking.mounted.test.tsx
  • apps/mobile/src/lib/tour/tour-auto-open-boot.test.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.ts
  • apps/mobile/src/lib/tour/use-tour-gate-usage.ts
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.test.ts
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.ts
  • apps/web/src/routers/user-router.test.ts
  • apps/web/src/routers/user-router.ts
  • services/kilo-mcp/catalog.json
Previous Review Summaries (5 snapshots, latest commit baa73a0)

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

Previous review (commit baa73a0)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the mobile tour auto-open gate, its once-per-process launch-account marker and gateway-usage hook, the web OpenAI-ChatGPT routing gate and user.hasGatewayUsage, and the follow-up test/cleanup changes; no new defects were found in the changed lines.

Files Reviewed (16 files)
  • apps/mobile/src/components/agents/session-list-header-actions.mounted.test.tsx
  • apps/mobile/src/components/app-unlock-screen.test-helpers.tsx
  • apps/mobile/src/components/code-reviewer/manual-review-screen.mounted.test.tsx
  • apps/mobile/src/components/tour/tour-auto-open.mounted.test.tsx
  • apps/mobile/src/components/tour/tour-auto-open.tsx
  • apps/mobile/src/components/ui/segmented-control.tsx
  • apps/mobile/src/components/ui/text.rtl-tracking.mounted.test.tsx
  • apps/mobile/src/lib/screen-insets.test.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.test.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.ts
  • apps/mobile/src/lib/tour/use-tour-gate-usage.ts
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.test.ts
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.ts
  • apps/web/src/routers/user-router.test.ts
  • apps/web/src/routers/user-router.ts
  • services/kilo-mcp/catalog.json

Previous review (commit 097fa38)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

One narrow gap remains in the mobile tour gate: the process attempt is claimed only after the tour-completion read loads, so a warm account switch during that window can still auto-open the tour; the web routing, user.hasGatewayUsage, and test-teardown changes are correct.

Overview

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

SUGGESTION

File Line Issue
apps/mobile/src/components/tour/tour-auto-open.tsx 140 The launch-account claim is gated behind the completion isLoaded guard, leaving a warm-switch auto-open window
Files Reviewed (12 files)
  • apps/mobile/src/components/app-unlock-screen.test-helpers.tsx
  • apps/mobile/src/components/tour/tour-auto-open.mounted.test.tsx
  • apps/mobile/src/components/tour/tour-auto-open.tsx - 1 issue
  • apps/mobile/src/lib/case-guard.test.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.test.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.ts
  • apps/mobile/src/lib/tour/use-tour-gate-usage.ts
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.test.ts
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.ts
  • apps/web/src/routers/user-router.test.ts
  • apps/web/src/routers/user-router.ts
  • services/kilo-mcp/catalog.json

Fix these issues in Kilo Cloud

Previous review (commit 7311ed5)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

One narrow gap remains in the mobile tour gate: the process attempt is claimed only after the tour-completion read loads, so a warm account switch during that window can still auto-open the tour; the web routing, user.hasGatewayUsage, and test-teardown changes are correct.

Overview

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

SUGGESTION

File Line Issue
apps/mobile/src/components/tour/tour-auto-open.tsx 140 The launch-account claim is gated behind the completion isLoaded guard, leaving a warm-switch auto-open window
Files Reviewed (12 files)
  • apps/mobile/src/components/app-unlock-screen.test-helpers.tsx
  • apps/mobile/src/components/tour/tour-auto-open.mounted.test.tsx
  • apps/mobile/src/components/tour/tour-auto-open.tsx - 1 issue
  • apps/mobile/src/lib/case-guard.test.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.test.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.ts
  • apps/mobile/src/lib/tour/use-tour-gate-usage.ts
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.test.ts
  • apps/web/src/lib/ai-gateway/openai-chatgpt/routing.ts
  • apps/web/src/routers/user-router.test.ts
  • apps/web/src/routers/user-router.ts
  • services/kilo-mcp/catalog.json

Fix these issues in Kilo Cloud

Previous review (commit 1abde4e)

Status: No Issues Found | Recommendation: Merge

Executive Summary

Reviewed the incremental changes — the mobile tour auto-open gate's launch-account attempt binding, its boot marker and tests, the web user-router test teardown, and a provider log cleanup — at high confidence, and found no new defects in the changed lines.

Files Reviewed (6 files)
  • apps/mobile/src/components/tour/tour-auto-open.tsx
  • apps/mobile/src/components/tour/tour-auto-open.mounted.test.tsx
  • apps/mobile/src/lib/tour/tour-auto-open-boot.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.test.ts
  • apps/web/src/routers/user-router.test.ts
  • apps/web/src/lib/ai-gateway/providers/openrouter/fetch-provider-models.ts

Previous review (commit 38133be)

Status: 2 Issues Found | Recommendation: Address before merge

Executive Summary

The tour gate's once-per-process marker is not bound to the account, so a sign-out and sign-in in the same process can auto-open the tour for a later account when the first account never spent the attempt.

Overview

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

WARNING

File Line Issue
apps/mobile/src/components/tour/tour-auto-open.tsx 151 The attempt is not spent on the consent/usage hold paths, so a warm account switch can still auto-open the tour

SUGGESTION

File Line Issue
apps/web/src/routers/user-router.test.ts 1970 The new test block leaves an orphaned organization_memberships row
Files Reviewed (9 files)
  • apps/mobile/src/components/app-unlock-screen.test-helpers.tsx
  • apps/mobile/src/components/tour/tour-auto-open.mounted.test.tsx
  • apps/mobile/src/components/tour/tour-auto-open.tsx - 1 issue
  • apps/mobile/src/lib/tour/tour-auto-open-boot.test.ts
  • apps/mobile/src/lib/tour/tour-auto-open-boot.ts
  • apps/mobile/src/lib/tour/use-tour-gate-usage.ts
  • apps/web/src/routers/user-router.test.ts - 1 issue
  • apps/web/src/routers/user-router.ts
  • services/kilo-mcp/catalog.json

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic marked this pull request as draft September 18, 2026 23:26
iscekic added a commit that referenced this pull request Sep 19, 2026
@iscekic
iscekic force-pushed the kwf/req-20260918-155205-bb44 branch from 03029cc to 1abde4e Compare September 19, 2026 03:45
@iscekic
iscekic marked this pull request as ready for review September 19, 2026 04:05
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 19, 2026
@iscekic iscekic self-assigned this Sep 19, 2026
@iscekic iscekic removed the human-ready The PR is ready for human review. label Sep 19, 2026
@iscekic
iscekic marked this pull request as draft September 19, 2026 13:48
iscekic added a commit that referenced this pull request Sep 19, 2026
@iscekic
iscekic force-pushed the kwf/req-20260918-155205-bb44 branch from f703d6d to 7311ed5 Compare September 19, 2026 14:41
@iscekic
iscekic marked this pull request as ready for review September 19, 2026 15:00
Comment thread apps/mobile/src/components/tour/tour-auto-open.tsx
@iscekic
iscekic marked this pull request as draft September 19, 2026 15:24
iscekic added a commit that referenced this pull request Sep 19, 2026
@iscekic
iscekic force-pushed the kwf/req-20260918-155205-bb44 branch from 2bfe15d to 097fa38 Compare September 19, 2026 17:43
@iscekic
iscekic marked this pull request as ready for review September 19, 2026 18:13
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 19, 2026

@eshurakov eshurakov left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved after a shallow triage pass. Note: also carries an unrelated OpenAI-alias auth-routing fix (ai-gateway/openai-chatgpt/routing.ts, same fix as #6291).

@iscekic iscekic added the merge-by-human the merge bot routed this PR to a human label Sep 22, 2026
@iscekic

iscekic commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator Author

The merge bot leaves this one to a human: Jev names a concrete break (0.89 / named 0.51).

@iscekic
iscekic force-pushed the kwf/req-20260918-155205-bb44 branch from dce8466 to 94d1564 Compare September 22, 2026 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review. merge-by-human the merge bot routed this PR to a human

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants