Skip to content

fix(mobile): remove developer feature-flag rows from Preferences - #6609

Merged
iscekic merged 4 commits into
mainfrom
kwf/explorer-4-visual-defects-on-android-the-preferences-scre-6d51f-8779
Sep 23, 2026
Merged

iscekic merged 4 commits into
mainfrom
kwf/explorer-4-visual-defects-on-android-the-preferences-scre-6d51f-8779

Conversation

@iscekic

@iscekic iscekic commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • Preferences no longer shows developer feature-flag rows that list internal flag keys, their remote or default source, and the build version.
  • Preferences keeps its product rows: General, Voice input, Translate tool summaries, Appearance, Account, Notifications, and Spend alerts.

Changelog for maintainers

  • Finding 1 — accepted and fixed: the development-only flag debug section is removed, so a development build renders only the product rows and none of 'Feature flags', 'mobile-pr-review', 'mobile-quick-chat', or 'not loaded'.
  • Finding 2 — rejected: the model picker's favourite-star control keeps the same left edge on the selected 'Auto Efficient' row and on every unselected row, so only the check mark sits inboard; no product code changed.
  • Finding 3 — rejected: 'Refreshing' is not an app string; no locale catalog contains it and the settled Arabic New session digest has zero occurrences, so the banner originates outside the app.
  • Finding 4 — rejected: the Arabic run-location helper renders kilo remote and /remote inline with no literal backticks, so the finding did not reproduce.
  • Removed the debug surface's PostHog projection (FeatureFlagsSection, useFeatureFlagStatuses, getFeatureFlagStatuses, FeatureFlagStatus) while keeping the version-gated useFeatureFlag path that product code reads.
  • Removed the five preferences.featureFlags* messages from every locale catalog and the matching English-identical allowlist entries in the catalog checker.
  • Updated mounted tests and their PostHog mocks, and added a Preferences test that a development build renders no developer rows.
  • Review first the Preferences render tree and any remaining importer of the deleted PostHog exports; the risk is a latent consumer of getFeatureFlagStatuses outside the updated tests.

E2E proof

[e1] Finding 1, Preferences screen: no developer feature-flag rows — the header 'Feature flags' and the slugs 'mobile-pr-review' / 'mobile-quick-chat' and the raw state 'Enabled · default · not loaded'… — android emulator-5554; declared state 'settings' restored (STATE HIT settings, e1-state.log) and the harvested replay ran as SCENE e1 OK (e1-scene.log line 1), whose settled digest shows the Preferences screen with only the product rows 'General' and 'Account' plus Voice input / Translate tool summaries / APPEARANCE / Notifications / Spend alerts, and zero occurrences of 'Feature flags', 'mobile-pr-review', 'mobile-quick-chat' or 'not loaded' (grep -cE over the digest = 0); the removed debug surface therefore does not render while the product rows do; capture e1.png is provided for the visual…

Finding 1, Preferences screen: no developer feature-flag rows — the header 'Feature flags' and the slugs 'mobile-pr-review' / 'mobile-quick-chat' and the raw state 'Enabled · default · not loaded'… — e1.png

[e7] ux-check: Model picker with 'Auto Efficient' selected: the favourite star on the selected row has the same left-edge x-position as the star on every unselected row; only the check mark sits inboard… — android: the e7 scene opens the model picker from the agent-picker state ('SCENE e7 OK', 'Select model' in e7-picker.log); in the 1080x2400 hierarchy the favourite-star control's left edge is 853 on the selected row and on every unselected row ('Add Auto Efficient to favorites' bounds="[853,1623][968,1739]", 'Add Laguna S 2.1 (free) to favorites' bounds="[853,1803][968,1918]", 'Add Nemotron 3 Ultra (free) to favorites' bounds="[853,2011][968,2127]", 'Add Dots3-Note Preview (free) to favorites' bounds="[853,2219][968,2335]") and the star glyph is 885 on every row…

ux-check: Model picker with 'Auto Efficient' selected: the favourite star on the selected row has the same left-edge x-position as the star on every unselected row; only the check mark sits inboard… — e7.png

[e6] ux-check: Preferences on a production/release build: the screen is pixel-identical to before the change (the debug section never rendered there). — Android emulator-5604: Preferences digest shows only General, Voice input, Translate tool summaries, APPEARANCE (System/Light/Dark), Account, Notifications, Spend alerts ('- Button "General" [ref=e3]', '- Button "Account, Language, trusted hosts, and device sessions" [ref=e19]'); the removed debug surface is absent — no 'Feature flags', no 'mobile-pr-review'/'mobile-quick-chat', no 'Enabled · default · not loaded'; still captured at e6-preferences.png for the visual reviewer; UX-DEFECT: none. e2e-index gap: no switch to force a release/DEV-false profile on the device build.

ux-check: Preferences on a production/release build: the screen is pixel-identical to before the change (the debug section never rendered there). — e6-preferences.png

[e1] Finding 1, Preferences screen: no developer feature-flag rows — the header 'Feature flags' and the slugs 'mobile-pr-review' / 'mobile-quick-chat' and the raw state 'Enabled · default · not loaded'…

[e1] Finding 1, Preferences screen: no developer feature-flag rows — the header 'Feature flags' and the slugs 'mobile-pr-review' / 'mobile-quick-chat' and the raw state 'Enabled · default · not loaded'… — scripted-shard1/e1.png

[e5] ux-check: Preferences renders no feature-flag debug rows — android emulator-5554 dev build: e5.log shows 'SCENE e5 OK' with TextViews General, Voice input, Translate tool summaries, APPEARANCE, Account, Notifications, Spend alerts and zero 'flag'/mobile-pr-review/mobile-quick-chat matches; screenshot for the visual reviewer at e5.png.

[e5] ux-check: Preferences renders no feature-flag debug rows — prior/e5.png

[e9] ux-check: run-location helper has no literal backticks — android emulator-5554 dev build: e9.log 'SCENE e9 OK' renders the TextView 'Run kilo remote on your computer, or /remote in a running CLI session, to control a local kilo process.' with no backtick characters in the file; screenshot for the visual reviewer at e9.png.

[e9] ux-check: run-location helper has no literal backticks — prior/e9.png

[e7] ux-check: Model picker with 'Auto Efficient' selected: the favourite star on the selected row has the same left-edge x-position as the star on every unselected row; only the check mark sits inboard…

[e7] ux-check: Model picker with 'Auto Efficient' selected: the favourite star on the selected row has the same left-edge x-position as the star on every unselected row; only the check mark sits inboard… — prior/e7-model-picker.png

E2E proof — log excerpts

[e1] Finding 2, model picker: open the picker from the New session screen (tap t -> pass :: jev read the digest: pass (confidence 1.00)
[e3] Finding 4, New session run-location helper: scroll to the helper line, 'kil -> pass :: jev read the digest: pass (confidence 1.00)
[e2] Finding 3, New session top banner: 'Refreshing...' is absent while the scre -> pass :: jev read the digest: pass (confidence 1.00)
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-4-visual-defects-on-android-the-preferences-scre-6d51f-8779/e2e-mobile-app/scripted-e1.log
android.widget.TextView Run kilo remote on your computer, or /remote in a running CLI session, to control a local kilo process. tappable [36,1056][1044,1130]
android.widget.TextView Repository tappable [37,1176][1045,1222]
android.widget.Button Repository: Select repository tappable [37,1240][1043,1356]
android.widget.TextView Select repository tappable [67,1270][978,1326]
android.widget.Button Connect GitLab tappable [76,1423][1004,1469]
android.widget.TextView Connect GitLab tappable [76,1423][944,1469]
android.widget.TextView Connect GitLab in your browser, then return here to pick a repository. tappable [76,1497][1004,1589]
android.widget.Button Open GitLab tappable [76,1617][870,1732]
android.widget.TextView Open GitLab tappable [175,1651][768,1697]
android.widget.Button Refresh repositories tappable [888,1617][1004,1732]
android.widget.TextView Changes tappable [37,1818][1045,1864]
android.view.View Changes tappable [37,1882][1043,2001]
android.widget.RadioButton Leave changes tappable [46,1891][540,1992]
android.widget.TextView Leave changes tappable [192,1918][393,1964]
android.widget.RadioButton Commit and push tappable [540,1891][1034,1992]
android.widget.TextView Commit and push tappable [668,1918][905,1964]
android.widget.TextView Environment tappable [37,2047][1045,2093]
android.widget.TextView busy tappable [37,2111][1045,2130]
android.widget.Button Start session [37,2185][1043,2300]
android.widget.TextView Start session tappable [442,2219][638,2265]
android.view.View Select model tappable [37,1255][894,1320]
android.widget.Button Done tappable [921,1237][1043,1338]
android.widget.TextView Done tappable [939,1259][1025,1315]
android.widget.EditText Search models... tappable [130,1414][1017,1489]
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-4-visual-defects-on-android-the-preferences-scre-6d51f-8779/e2e-mobile-app/scripted-e3.log
android.widget.TextView Run kilo remote on your computer, or /remote in a running CLI session, to control a local kilo process. tappable [36,1056][1044,1130]
android.widget.TextView Repository tappable [37,1176][1045,1222]
android.widget.Button Repository: Select repository tappable [37,1240][1043,1356]
android.widget.TextView Select repository tappable [67,1270][978,1326]
android.widget.Button Connect GitLab tappable [76,1423][1004,1469]
android.widget.TextView Connect GitLab tappable [76,1423][944,1469]
android.widget.TextView Connect GitLab in your browser, then return here to pick a repository. tappable [76,1497][1004,1589]
android.widget.Button Open GitLab tappable [76,1617][870,1732]
android.widget.TextView Open GitLab tappable [175,1651][768,1697]
android.widget.Button Refresh repositories tappable [888,1617][1004,1732]
android.widget.TextView Changes tappable [37,1818][1045,1864]
android.view.View Changes tappable [37,1882][1043,2001]
android.widget.RadioButton Leave changes tappable [46,1891][540,1992]
android.widget.TextView Leave changes tappable [192,1918][393,1964]
android.widget.RadioButton Commit and push tappable [540,1891][1034,1992]
android.widget.TextView Commit and push tappable [668,1918][905,1964]
android.widget.TextView Environment tappable [37,2047][1045,2093]
android.widget.TextView busy tappable [37,2111][1045,2130]
android.widget.Button Start session [37,2185][1043,2300]
android.widget.TextView Start session tappable [442,2219][638,2265]
android.view.View Select model tappable [37,1255][894,1320]
android.widget.Button Done tappable [921,1237][1043,1338]
android.widget.TextView Done tappable [939,1259][1025,1315]
android.widget.EditText Search models... tappable [130,1414][1017,1489]
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-4-visual-defects-on-android-the-preferences-scre-6d51f-8779/e2e-mobile-app/scripted-e2.log
android.widget.TextView Run kilo remote on your computer, or /remote in a running CLI session, to control a local kilo process. tappable [36,1056][1044,1130]
android.widget.TextView Repository tappable [37,1176][1045,1222]
android.widget.Button Repository: Select repository tappable [37,1240][1043,1356]
android.widget.TextView Select repository tappable [67,1270][978,1326]
android.widget.Button Connect GitLab tappable [76,1423][1004,1469]
android.widget.TextView Connect GitLab tappable [76,1423][944,1469]
android.widget.TextView Connect GitLab in your browser, then return here to pick a repository. tappable [76,1497][1004,1589]
android.widget.Button Open GitLab tappable [76,1617][870,1732]
android.widget.TextView Open GitLab tappable [175,1651][768,1697]
android.widget.Button Refresh repositories tappable [888,1617][1004,1732]
android.widget.TextView Changes tappable [37,1818][1045,1864]
android.view.View Changes tappable [37,1882][1043,2001]
android.widget.RadioButton Leave changes tappable [46,1891][540,1992]
android.widget.TextView Leave changes tappable [192,1918][393,1964]
android.widget.RadioButton Commit and push tappable [540,1891][1034,1992]
android.widget.TextView Commit and push tappable [668,1918][905,1964]
android.widget.TextView Environment tappable [37,2047][1045,2093]
android.widget.TextView busy tappable [37,2111][1045,2130]
android.widget.Button Start session [37,2185][1043,2300]
android.widget.TextView Start session tappable [442,2219][638,2265]
android.view.View Select model tappable [37,1255][894,1320]
android.widget.Button Done tappable [921,1237][1043,1338]
android.widget.TextView Done tappable [939,1259][1025,1315]
android.widget.EditText Search models... tappable [130,1414][1017,1489]
Owner request

Surface: mobile-app

Explorer finding: 4 visual defects on android: The Preferences screen exposes internal ; On the selected 'Auto Efficient' row the; The blue top banner reads 'Refreshing... (+1 more)

The user-agent explorer found these 4 while using the app like a user. They are one kind of defect on one platform, so they are ONE item: the pull request must fix and prove every one of them.
One must-run scenario per finding: the plan needs 4 musts, one for each finding below.
The explorer never edits product code.

Evidence (from the device runs):

--- Finding 1 of 4: account-en: The Preferences screen exposes internal feature-flag slugs and raw state as user-facing rows ('mobile-pr-review', 'mobile-quick-chat', 'Enabled · default · not loaded'), which are developer words with no user meaning.
Flow: account-en
Found on revision: f2181ae
Repro:

  1. set this state first: seed coding-plans:demo-data; seed coding-plans:available-credentials admin-overview; seed coding-plans:occupied-minimax-byok d43d5aa5-1e1b-4af7-8196-d26c8ff6117f admin-overview; credits 20; uimode day; battery 40 charging; relaunch; reviews 3; the device in light mode
  2. open the app on emulator-5602
  3. reach account-en
  4. the capture shows the defect named below
    Observed: The Preferences screen exposes internal feature-flag slugs and raw state as user-facing rows ('mobile-pr-review', 'mobile-quick-chat', 'Enabled · default · not loaded'), which are developer words with no user meaning.
    Expected: the screen renders without this defect

--- Finding 2 of 4: model-picker: On the selected 'Auto Efficient' row the favourite star is pushed inboard of the selection check, so the star column does not line up with the star in every row below it.
Flow: model-picker
Found on revision: f2181ae
Repro:

  1. set this state first: seed coding-plans:demo-data; seed coding-plans:available-credentials admin-overview; seed coding-plans:occupied-minimax-byok d43d5aa5-1e1b-4af7-8196-d26c8ff6117f admin-overview; credits 20; uimode day; battery 40 charging; relaunch; reviews 3; the device in light mode
  2. open the app on emulator-5602
  3. reach model-picker
  4. the capture shows the defect named below
    Observed: On the selected 'Auto Efficient' row the favourite star is pushed inboard of the selection check, so the star column does not line up with the star in every row below it.
    Expected: the screen renders without this defect

--- Finding 3 of 4: new-session-bottom: The blue top banner reads 'Refreshing...' in English while every other string on the screen is Arabic, so the loading state is not localized.
Flow: new-session-bottom
Found on revision: f2181ae
Repro:

  1. set this state first: seed coding-plans:demo-data; seed coding-plans:available-credentials admin-overview; seed coding-plans:occupied-minimax-byok d43d5aa5-1e1b-4af7-8196-d26c8ff6117f admin-overview; credits 20; uimode day; battery 40 charging; relaunch; reviews 3; the device in light mode
  2. open the app on emulator-5602
  3. reach new-session-bottom
  4. the capture shows the defect named below
    Observed: The blue top banner reads 'Refreshing...' in English while every other string on the screen is Arabic, so the loading state is not localized.
    Expected: the screen renders without this defect

--- Finding 4 of 4: new-session-bottom: The helper line renders literal markdown backticks around kilo remote and /remote instead of styling the commands as code, so tick marks leak into the sentence.
Flow: new-session-bottom
Found on revision: f2181ae
Repro:

  1. set this state first: seed coding-plans:demo-data; seed coding-plans:available-credentials admin-overview; seed coding-plans:occupied-minimax-byok d43d5aa5-1e1b-4af7-8196-d26c8ff6117f admin-overview; credits 20; uimode day; battery 40 charging; relaunch; reviews 3; the device in light mode
  2. open the app on emulator-5602
  3. reach new-session-bottom
  4. the capture shows the defect named below
    Observed: The helper line renders literal markdown backticks around kilo remote and /remote instead of styling the commands as code, so tick marks leak into the sentence.
    Expected: the screen renders without this defect

[e7] ux-check: Model picker with 'Auto Efficient' selected: the favourite star on the selected row has the same left-edge x-position as the star on every unselected row; only the check mark sits inboard… — android: the e7 scene opens the model picker from the agent-picker state ('SCENE e7 OK', 'Select model' in e7-picker.log); in the 1080x2400 hierarchy the favourite-star control's left edge is 853 on the selected row and on every unselected row ('Add Auto Efficient to favorites' bounds="[853,1623][968,1739]", 'Add Laguna S 2.1 (free) to favorites' bounds="[853,1803][968,1918]", 'Add Nemotron 3 Ultra (free) to favorites' bounds="[853,2011][968,2127]", 'Add Dots3-Note Preview (free) to favorites' bounds="[853,2219][968,2335]") and the star glyph is 885 on every row…

[e7] ux-check: Model picker with 'Auto Efficient' selected: the favourite star on the selected row has the same left-edge x-position as the star on every unselected row; only the check mark sits inboard… — e7-model-picker-fav.png

Follow-ups (not changed here)

  • not proved live: Finding 2, model picker: open the picker from the New session screen (tap the model chip) and hold the list on screen — the selected 'Auto Efficient' row's favourite star sits in the same column as the star in every row below it (already fixed at HEAD by 8d4450a / fix(mobile): align favorite star in selected model row #6450, the star keeps an 18px trailing column; the PR still is the live proof). (no capture cited it)
  • not proved live: Finding 3, New session top banner: 'Refreshing...' is absent while the screen's own controls render ('Start session' is pinned on screen). The banner belongs to the Metro/React Native dev Fast-Refresh view (node_modules/react-native/Libraries/Utilities/HMRClient.js:222 -> DevLoadingView.js blue 'refresh' banner), not to app copy, so no app catalog renders it; the still proves the product screen carries no such English loading banner. (no capture cited it)
  • not proved live: Finding 4, New session run-location helper: scroll to the helper line, 'kilo remote' renders as plain text and no backtick appears anywhere on the screen (already fixed at HEAD by 3ecc6d3 / fix(mobile): render run-location help without inline-code backticks #6433 via stripInlineCodeMarkers, applied for all three run-location keys; the still is the live proof). (no capture cited it)
  • not proved live: ux-check: New session run-location helper line: 'kilo remote' and '/remote' render with no literal backtick characters anywhere in the sentence. (no capture cited it)
  • not proved live: ux-check: New session screen in Arabic: no English product copy is visible; the only blue full-width 'Refreshing…' bar is React Native's Fast Refresh dev overlay, which appears only mid-reload in a dev client and is gone once the bundle settles — it is not an app string. (no capture cited it)
  • not proved live: ux-check: Preferences on emulator-5602 (dev build): no 'FEATURE FLAGS' heading and no rows 'mobile-pr-review' or 'mobile-quick-chat' appear; only product rows (General, Voice input, Translate tool summaries, Appearance, Account, Notifications, Spend alerts) render, with no empty gap or blank band where the debug section was. (no capture cited it)

Open findings (not fixed here)

  • not proved live: account-en.png is no longer on the host that took it, so no publish can carry it
  • not proved live: model-picker.png is no longer on the host that took it, so no publish can carry it
  • not proved live: new-session-bottom.png is no longer on the host that took it, so no publish can carry it

Surface: mobile-app

Explorer finding: 4 visual defects on android: The Preferences screen exposes internal ; On the selected 'Auto Efficient' row the; The blue top banner reads 'Refreshing... (+1 more)

The user-agent explorer found these 4 while using the app like a user. They are one kind of defect on one platform, so they are ONE item: the pull request must fix and prove every one of them.
One must-run scenario per finding: the plan needs 4 musts, one for each finding below.
The explorer never edits product code.

Evidence (from the device runs):

--- Finding 1 of 4: account-en: The Preferences screen exposes internal feature-flag slugs and raw state as user-facing rows ('mobile-pr-review', 'mobile-quick-chat', 'Enabled · default · not loaded'), which are developer words with no user meaning.
Flow: account-en
Found on revision: f2181ae
Repro:
1. set this state first: seed coding-plans:demo-data; seed coding-plans:available-credentials admin-overview; seed coding-plans:occupied-minimax-byok d43d5aa5-1e1b-4af7-8196-d26c8ff6117f admin-overview; credits 20; uimode day; battery 40 charging; relaunch; reviews 3; the device in light mode
2. open the app on emulator-5602
3. reach account-en
4. the capture shows the defect named below
Observed: The Preferences screen exposes internal feature-flag slugs and raw state as user-facing rows ('mobile-pr-review', 'mobile-quick-chat', 'Enabled · default · not loaded'), which are developer words with no user meaning.
Expected: the screen
@kilo-code-bot

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

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

The removal is internally consistent: the deleted FeatureFlagsSection/getFeatureFlagStatuses/useFeatureFlagStatuses/FeatureFlagStatus exports have no remaining importers, the statusRevision bookkeeping is gone with its only consumers, posthog.ts still uses currentAppVersion/getFeatureFlagDefinition/isAppVersionAtLeast in isFeatureEnabled, and the five preferences.featureFlag* keys were removed together from en.json and all 89 other catalogs so parity holds.

Files Reviewed (98 files)
  • apps/mobile/src/components/preferences-screen.tsx (removed dev-only FeatureFlagsSection render)
  • apps/mobile/src/lib/analytics/posthog.ts (removed status snapshot machinery)
  • apps/mobile/src/lib/feature-flags.ts (comment update only; registry still powers the version gate)
  • apps/mobile/src/components/preferences-screen.mounted.test.tsx (added dev-build regression test)
  • apps/mobile/src/components/app-unlock-screen.test-helpers.tsx
  • apps/mobile/src/components/settings-screens-a11y.mounted.test.tsx
  • apps/mobile/src/lib/analytics/posthog.feature-flags.test.ts
  • apps/mobile/src/components/feature-flags-section.tsx (deleted)
  • apps/mobile/src/components/feature-flags-section.mounted.test.tsx (deleted)
  • apps/mobile/src/components/preferences-screen.feature-flags.mounted.test.tsx (deleted)
  • tools/i18n/check-catalogs.mjs
  • apps/mobile/src/i18n/locales/*.json (90 catalogs, 5 keys removed each)

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

Review guidance: REVIEW.md from base branch main

@iscekic

iscekic commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator Author

This description names a scenario the proof did not capture:

  • not proved live: Finding 2, model picker: open the picker from the New session screen (tap the model chip) and hold the list on screen — the selected 'Auto Efficient' row's favourite star sits in the same column as the star in every row below it (already fixed at HEAD by 8d4450a / fix(mobile): align favorite star in selected model row #6450, the star keeps an 18px trailing column; the PR still is the live proof). (no capture cited it)

A repeated proof run rebuilds the same evidence, so no proof run is dispatched for a named gap. Merging with this gap open is your decision.

@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 23, 2026
@iscekic iscekic self-assigned this Sep 23, 2026
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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants