feat(mobile): harden bootstrap, routing, and release gates (w6b) - #5421
Open
iscekic wants to merge 12 commits into
Open
feat(mobile): harden bootstrap, routing, and release gates (w6b)#5421iscekic wants to merge 12 commits into
iscekic wants to merge 12 commits into
Conversation
Add an Explore section with Code Reviewer, Security Agent, and PR Review rows so an empty or erroring Home still offers an outcome-led first action. Scope resolves as organizationId or the personal security scope; PR Review stays feature-flag gated.
The expo config contract assertion hardcoded the ten ENV_KEYS names, so a new key would silently drop out of the preflight check. Import ENV_KEYS from src/lib/env-keys.js and iterate its keys instead.
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryIncremental review of the production-host allowlist and committed-.env host-contract test found no remaining issues. Files Reviewed (2 files)
Previous Review Summaries (3 snapshots, latest commit d7e4503)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit d7e4503)Status: No Issues Found | Recommendation: Merge Files Reviewed (3 files)
Previous review (commit 4276142)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (2 files)
Fix these issues in Kilo Cloud Previous review (commit 04cadd4)Status: 1 Issue Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
Files Reviewed (33 files)
Reviewed by grok-4.6 · Input: 109.6K · Output: 6.9K · Cached: 216.1K Review guidance: REVIEW.md from base branch |
The routing effect reads only decision.tag and the render gating reads only the three error flags and hidden. The seven intermediate derivations were exported but never consumed; keep them as local consts inside the helper.
The runtime production-host check keyed off the Sentry environment, so a preview release build with an unset EXPO_PUBLIC_SENTRY_ENVIRONMENT failed closed and crashed on launch. Bake EAS_BUILD_PROFILE === 'production' into expo extra and gate the check on that flag.
pandemicsyn
approved these changes
Aug 21, 2026
pandemicsyn
left a comment
Contributor
There was a problem hiding this comment.
pre-approving but think robot's inline comment is right and deploys via this new workflow will probably fail.
Add chat.kiloapps.io, events.kiloapps.io, and notifications.kiloapps.io to the production host allowlist, and add a host-contract test that asserts every committed .env URL value against the allowlist.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Home screen now shows an Explore area with three shortcuts: Code Reviewer, Security Agent, and PR Review. The area stays visible when the session list is loading, empty, filled, or failed to load.
The Profile screen now paints first and loads account and organization details only after the screen transition settles, showing placeholders while it waits.
Opening a link with a broken review, session, or organization identifier now shows a not-found screen with a back action instead of a blank or broken screen.
The production host allowlist is now complete. It holds all seven production hosts from the committed environment file, including the three
kiloapps.ioendpoints, and a unit test reads that file and asserts every URL value passes the scheme and host checks, so a missing host fails before any build. A production build still fails on a missing required value, a wrong scheme, an off-allowlist host, or a missing Sentry source-map token.Files
apps/mobile/src/lib/url-contract.js— new; holdsURL_SCHEMES,PRODUCTION_HOSTS,assertUrlScheme, andassertProductionHost; the allowlist now lists all seven production hosts.apps/mobile/app.config.ts— applies the scheme and host checks; makes missing env fatal in production; adds the Sentry token gate; bakesextra.isProductionBuild.apps/mobile/src/lib/config.ts— applies the scheme check at runtime and the production host check whenextra.isProductionBuildis true.The root layout now derives its bootstrap routing and its render gating from one pure resolver instead of two hand-kept copies, so the routing effect and the visibility flags can no longer disagree. The resolver returns a closed union of routing tags plus the error, redirect, and hidden flags, and the routing effect switches over the tag. The old inline if-chain and the old inline gating derivations are deleted; behavior stays the same.
Files
apps/mobile/src/lib/bootstrap-decision.ts— new; exports the input, decision, and tag types and the pure resolver.apps/mobile/src/app/_layout.tsx— calls the resolver in the routing effect and the render gate; replaces the inline if-chain with a switch.The release workflow pins EAS CLI to 21.8.0 and splits the old build-and-submit step into a preflight job, a build job, an artifact download, an inspection step, and separate iOS and Android submissions. The preflight fails closed when the EAS production environment misses a required value or the config contract fails. The build no longer uses
--auto-submit; submission runs from downloaded artifacts after inspection.Files
.github/workflows/kilo-app-release.yml— pins the CLI, adds the preflight job, splits build and submit, adds download and inspection steps.apps/mobile/eas.json— pinscli.versionto 21.8.0.apps/mobile/package.json— pins every eas-cli script to 21.8.0 and adds theassert:configscript.A new preflight script runs the fully evaluated Expo config and fails when the bundle id, package, scheme, associated domain, blocked permissions, Sentry plugin, or any required extra value violates the contract. The preflight invokes it inside the EAS production environment, so config drift fails before any build.
Files
apps/mobile/scripts/assert-expo-config.mjs— new; runsexpo config --jsonand checks the contract values.A new inspection script validates the EAS build result and the signed IPA and AAB before submission, and submission stops when an artifact violates a bundle, permission, endpoint, or debug-symbol contract. The IPA is checked for its bundle id, privacy manifest, usage descriptions, and SKAdNetwork endpoints; the AAB is checked for its package, blocked permissions, cleartext traffic, intent-filter host, and debug symbols.
Files
scripts/inspect-mobile-artifacts.mjs— new; validates build.json, inspects the IPA and AAB, and checks debug symbols.The home screen gains an Explore section with Code Reviewer, Security Agent, and PR Review rows, and the PR Review row stays behind the existing PR Review feature flag. The section renders in the empty, populated, and error states of the session list, so the shortcuts remain available when sessions fail to load.
Files
apps/mobile/src/components/home/product-choices.tsx— new; three rows, PR Review gated by the flag.apps/mobile/src/components/home/home-screen.tsx— renders ProductChoices after the sessions/promo branch.The profile screen defers its two mount-time queries until the navigation transition settles, using a new
useAfterInteractionshook, so the screen paints before the account and organization fetches start. The skeleton, stale, and error states stay, and the linked-accounts section now shows its skeleton while the interactions are pending.Files
apps/mobile/src/lib/hooks/use-after-interactions.ts— new; returns false on mount, then true afterInteractionManager.runAfterInteractions.apps/mobile/src/components/profile-screen.tsx— gates both queries on the hook and keeps the skeleton and error states.Six routes that read a required path parameter now parse it with
parseParamand renderInvalidRouteStatewith a bounded back target when the parameter is missing or malformed. Optional parameters keep their existing first-element unwrapping, and the session route no longer fires its query for a null session id.Files
apps/mobile/src/app/(app)/(tabs)/(3_profile)/code-reviewer/[scope]/index.tsx— parses scope; renders InvalidRouteState.apps/mobile/src/app/(app)/(tabs)/(3_profile)/code-reviewer/[scope]/manual-review.tsx— parses scope; renders InvalidRouteState.apps/mobile/src/app/(app)/(tabs)/(3_profile)/code-reviewer/[scope]/reviews/[id].tsx— parses scope and id; back target depends on scope.apps/mobile/src/app/(app)/(tabs)/(3_profile)/code-reviewer/[scope]/reviews/index.tsx— parses scope; renders InvalidRouteState.apps/mobile/src/app/(app)/(tabs)/(3_profile)/organization/member-limit.tsx— parses memberId; renders InvalidRouteState.apps/mobile/src/app/(app)/agent-chat/[session-id].tsx— parses session-id; disables the query and renders InvalidRouteState when null.Tests: 13 test files added or updated.
Generated: none.
Verification
Two cases ran on iOS across two verification rounds.
No round reproduced a defect on the unfixed build.
Recording:
ev03-coldstart.mp4shows the EV-03 cold launch from force-quit to interactive Home.Visual Changes
Home screen. The user now sees an Explore section on Home with rows for Code Reviewer, Security Agent, and PR Review. In the picture, the EXPLORE header and the three rows sit below the Kilo Agents card and above the tab bar.
Invalid-route screen. The user now gets a bounded not-found state with a back action when a route param is malformed. No picture shows this change. The single candidate shows the session not-found state after a malformed deep link; no deep link yields a malformed param on the device, so the picture fails to show the new InvalidRouteState with Page not found and Go back. The co-located route tests prove that state instead.
Reviewer Notes
Human steps:
apps/mobile/.envhosts before the first real production build; the release preflight fails closed on any mismatch. (after merge)SENTRY_AUTH_TOKENin the EAS production environment with non-secret visibility (plainorsensitive). (after merge)EXPO_PUBLIC_SENTRY_ENVIRONMENT=productionin the EAS production environment; the release preflight asserts it. The EAS preview environment no longer needsEXPO_PUBLIC_SENTRY_ENVIRONMENT=previewto avoid a crash, because the runtime host check now keys off the baked build intent. (after merge)PrivacyInfo.xcprivacyor the AAB may lack debug-symbols metadata; the follow-up fix is named in the plan. (after merge)Info.plistis parsed withpython3 plistlib; the release runner must providepython3. (after merge)Notes: E2E: the follow-up commit 13f4d4b adds three production hosts to the build-time allowlist and a unit test; the host check only runs in production builds, so it has no runtime behavior to verify. The existing iOS verification still holds.