Skip to content

fix(mobile): show feature-flag row state in the app language - #6608

Merged
iscekic merged 1 commit into
mainfrom
kwf/explorer-2-visual-defects-on-android-the-feature-flag-row-489aa-54f3
Sep 23, 2026
Merged

iscekic merged 1 commit into
mainfrom
kwf/explorer-2-visual-defects-on-android-the-feature-flag-row-489aa-54f3

Conversation

@iscekic

@iscekic iscekic commented Sep 23, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • Preferences feature-flag rows now name the value's source and state in the app language, so an Arabic screen reads مفعّل · افتراضي · لم يتم التحميل instead of mixing in default · not loaded.
  • The flag key, the ≥ / < version operators and the v{{version}} build line stay as notation.

Changelog for maintainers

  • All 86 non-English catalogs now carry their own preferences.featureFlagApplied, preferences.featureFlagSkipped and preferences.featureFlagNotLoaded; the English copy in en.json is unchanged.
  • tools/i18n/check-catalogs.mjs no longer allows those three keys to stay English, so check:i18n now fails a catalog that ships the English words; only preferences.featureFlagsBuild stays allowlisted on that screen.
  • New unit test apps/mobile/src/i18n/feature-flag-copy.test.ts fails when a catalog is missing a key, is empty, or equals the English copy; a key missing at runtime resolves to English, so it is caught too.
  • The row still renders <value> · <source> · <state>; the section header, {{min}}, ≥ / < and {{version}} are unchanged.
  • Finding: the .com orphan on the sign-in code heading is already resolved at the base, where the recipient address starts its own line; this PR adds no code for it and the device run confirms it.
  • Review first: the three catalog keys and the allowlist removal; the rest of the diff repeats the same three-key edit across the other catalogs.

E2E proof

[e1] settings (Android, app language Arabic) — android emulator-5554, dev build: e1-scene.log line 1 SCENE e1 OK proves every step passed, including the three absent steps and the switch back to English (final digest Preferences + Enabled · default · not loaded). The live Arabic Preferences digest is e1-arabic.txt, whose resolved-state lines read text="مفعّل · افتراضي · لم يتم التحميل" and text="معطّل · افتراضي · لم يتم التحميل" beside text="mobile-pr-review" under text="أعلام الميزات", with text="v1.0.12" unchanged; the only English-looking tokens left are the flag keys mobile-pr-review/mobile-quick-chat. Start state…

[e1] settings (Android, app language Arabic) — e2e-mobile-app/e1.png

[e1] settings (Android, app language Arabic)

[e1] settings (Android, app language Arabic) — e2e-mobile-app/e1-arabic.png

[e2] sign-in-wrong-code (Android): after the reported address is submitted the code-screen heading reads with the address starting its own line — e2e-mobile-cloud-android@example.com alone on line 2, no… — android emulator-5554: e2-scene.log line 1 SCENE e2 OK (address assert passed before and after the failed verify), line 6 Enter the code sent to &#10;e2e-mobile-cloud-android@example.com is one heading node with the full address starting its own line, line 16 That code is incorrect. Please try again. proves the wrong-code re-render; capture e2.png for the visual wrap judgement.

[e2] sign-in-wrong-code (Android): after the reported address is submitted the code-screen heading reads with the address starting its own line — e2e-mobile-cloud-android@example.com alone on line 2, no… — scripted-shard1/e2.png

[e5] ux-check: Sign-in wrong-code screen: the heading shows the instruction and the full recipient address beginning on its own line; no line consists only of punctuation; '.com' is not isolated on its… — android emulator-5554: e5-scene.log line 6 Enter the code sent to &#10;e2e-mobile-cloud-android@example.com shows the instruction plus the full recipient address on its own line with .com inside it, line 16 That code is incorrect. Please try again. with Resend code and Back as recovery actions; every text node in the digest (lines 5-16) is a complete phrase, no punctuation-only line; no UX-DEFECT (capture e5.png, wrap judged by the visual reviewer).

[e5] ux-check: Sign-in wrong-code screen: the heading shows the instruction and the full recipient address beginning on its own line; no line consists only of punctuation; '.com' is not isolated on its… — prior/e5.png

[e4] ux-check: Same screen in a second non-English locale (e.g. — android emulator-5604, app language French: the live Preferences screen shows 'INDICATEURS DE FONCTIONNALITÉS' with 'Activé · Par défaut · non chargé' and 'Désactivé · Par défaut · non chargé' (e4-french-notloaded.log, e4-french-notloaded.png) — 2026-09-23; the {{min}} gate branches are not device-forcible (PostHog off in DEV) so they were captured under the pack's temporary-hardcode permission and reverted (worktree clean): 'Activé · Distant · ≥ 1.0.4' and 'Désactivé · Par défaut · < 1.0.6' with no literal '{{min}}'/'undefined' and keys, '≥'/'<', 'v1.0.12' unchanged…

[e4] ux-check: Same screen in a second non-English locale (e.g. — prior/e4-french-notloaded.png

[e4] ux-check: Same screen in a second non-English locale (e.g.

[e4] ux-check: Same screen in a second non-English locale (e.g. — prior/e4-french-applied.png

E2E proof — log excerpts

[e1] settings (Android, app language Arabic) -> pass :: android emulator-5554, dev build: e1-scene.log line 1 `SCENE e1 OK` proves every step passed, including the three absent steps and the switch back to English (final digest `Preferences` + `Enabled · default · not loaded`). The live Arabic Preferences digest is e1-arabic.txt, whose resolved-state lines read `text="مفعّل · افتراضي · لم يتم التحميل"` and `text="معطّل · افتراضي · لم يتم التحميل"` beside `text="mobile-pr-review"` under `text="أعلام الميزات"`, with `text="v1.0.12"` unchanged; the only English-looking tokens left are the flag keys `mobile-pr-review`/`mobile-quick-chat`. Start state `settings` restored by state.sh (e1-state-restore.log `STATE HIT settings`). Captures e1.png (final e
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-2-visual-defects-on-android-the-feature-flag-row-489aa-54f3/e2e-mobile-app/e1-scene.log
android.widget.RadioButton Light tappable [381,971][699,1072]
android.widget.TextView Light tappable [505,998][573,1044]
android.widget.RadioButton Dark tappable [698,971][1015,1072]
android.widget.TextView Dark tappable [825,998][888,1044]
android.widget.TextView FEATURE FLAGS tappable [55,1136][1025,1180]
android.widget.TextView mobile-pr-review tappable [82,1235][998,1281]
android.widget.TextView Enabled · default · not loaded tappable [82,1286][998,1323]
android.widget.TextView mobile-quick-chat tappable [82,1405][998,1451]
android.widget.TextView Off · default · not loaded tappable [82,1456][998,1493]
android.widget.TextView v1.0.12 tappable [55,1548][1025,1585]
android.widget.Button Account, Language, trusted hosts, and device sessions tappable [55,1613][1025,1755]
android.widget.TextView Account tappable [189,1641][933,1687]
android.widget.TextView Language, trusted hosts, and device sessions tappable [189,1691][933,1728]
android.widget.Button Notifications, Push preferences tappable [55,1783][1025,1926]
android.widget.TextView Notifications tappable [189,1811][933,1857]
android.widget.TextView Push preferences tappable [189,1861][933,1898]
android.widget.Button Spend alerts tappable [55,1954][1025,2088]
android.widget.TextView Spend alerts tappable [189,1998][933,2044]
android.widget.Button Home, tab, 1 of 3 tappable [0,2195][360,2337]
android.widget.TextView HOME tappable [13,2281][347,2320]
android.widget.Button Agents, tab, 2 of 3 tappable [360,2195][720,2337]
android.widget.TextView AGENTS tappable [373,2281][707,2320]
android.widget.Button Profile, tab, 3 of 3 tappable [720,2195][1080,2337]
android.widget.TextView PROFILE tappable [733,2281][1067,2320]
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-2-visual-defects-on-android-the-feature-flag-row-489aa-54f3/e2e-mobile-app/e1-arabic.txt
<redacted>
<redacted>
                                        </com.horcrux.svg.GroupView>
                                      </com.horcrux.svg.SvgView>
                                    </android.widget.Button>
                                  </android.view.ViewGroup>
                                </android.view.ViewGroup>
                              </android.view.ViewGroup>
                            </android.widget.ScrollView>
                          </android.view.ViewGroup>
                        </android.view.ViewGroup>
                      </android.view.ViewGroup>
<redacted>
                    </android.view.ViewGroup>
                  </android.view.ViewGroup>
                </android.view.ViewGroup>
              </android.widget.FrameLayout>
            </android.widget.FrameLayout>
          </android.widget.FrameLayout>
        </android.widget.LinearLayout>
      </android.widget.FrameLayout>
    </android.widget.LinearLayout>
  </android.widget.FrameLayout>
</hierarchy>
/home/igor_kilocode_ai/.local/share/kwf/sections/explorer-2-visual-defects-on-android-the-feature-flag-row-489aa-54f3/e2e-mobile-app/e1-state-restore.log
STATE HIT settings
digest: /home/igor_kilocode_ai/.local/share/kwf/sections/explorer-2-visual-defects-on-android-the-feature-flag-row-489aa-54f3/e2e-mobile-app/state-settings.txt
Owner request

Surface: mobile-app

Explorer finding: 2 visual defects on android: The feature-flag rows show raw English d; The recipient address in the heading wra

The user-agent explorer found these 2 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 2 musts, one for each finding below.
The explorer never edits product code.

Evidence (from the device runs):

--- Finding 1 of 2: profile: The feature-flag rows show raw English developer state ("default · not loaded") beside the localized "مفعّل"/"معطّل" inside an otherwise fully Arabic screen.
Flow: profile
Found on revision: f2181ae
Repro:

  1. set this state first: credits 20; reviews 4; uimode day; battery 22 discharging; rotate portrait; relaunch; seed app:user-id e2e-mobile-cloud-android@example.com; the device in light mode
  2. open the app on emulator-5602
  3. reach profile, settings
  4. the capture shows the defect named below
    Observed: The feature-flag rows show raw English developer state ("default · not loaded") beside the localized "مفعّل"/"معطّل" inside an otherwise fully Arabic screen.
    Expected: the screen renders without this defect

--- Finding 2 of 2: sign-in-wrong-code: The recipient address in the heading wraps with '.com' stranded alone on its own centered second line, an orphaned fragment under 'e2e-mobile-cloud-android@example'.
Flow: sign-in-wrong-code
Found on revision: f2181ae
Repro:

  1. set this state first: credits 20; reviews 4; uimode day; battery 22 discharging; rotate portrait; relaunch; seed app:user-id e2e-mobile-cloud-android@example.com; the device in light mode
  2. open the app on emulator-5602
  3. reach sign-in-wrong-code
  4. the capture shows the defect named below
    Observed: The recipient address in the heading wraps with '.com' stranded alone on its own centered second line, an orphaned fragment under 'e2e-mobile-cloud-android@example'.
    Expected: the screen renders without this defect

[e6] ux-check: feature-flag rows fit their card at default font scale in en and ar (no clipped/overlapping third line) — android emulator-5554, default font scale never changed; each row relation is one text node of height 37 px (same single line height as the v1.0.12 line) in en (e6-en.txt) and ar (e3.txt) and does not overlap the next row key (gap 82 px both locales), per e6-rows.log; the wrap/clipping appearance is judged by the visual reviewer from e6-en.png and e3.png. No behavior-level UX defect observed.

[e6] ux-check: feature-flag rows fit their card at default font scale in en and ar (no clipped/overlapping third line) — e6-en.png

[e3] ux-check: Arabic Preferences feature-flag rows render value, source and state in Arabic with no Latin 'remote'/'default'/'not loaded' — android emulator-5554, dev build (FEATURE FLAGS section renders), portrait 1080x2400; app language set to Arabic in-app; digest e3.txt shows 'مفعّل · افتراضي · لم يتم التحميل' and 'معطّل · افتراضي · لم يتم التحميل' and a latin scan of the whole dump for remote|default|not loaded is 0 (e3-arabic.log); capture e3.png. The applied/'remote' branch is not device-forcible (PostHog disabled in DEV) and is pinned for all 86 catalogs by the new feature-flag-copy.test.ts. No behavior-level UX defect observed.

[e3] ux-check: Arabic Preferences feature-flag rows render value, source and state in Arabic with no Latin 'remote'/'default'/'not loaded' — e3.png

Follow-ups (not changed here)

  • not proved live: ux-check: Dev build, app language Arabic, rotate portrait: open Preferences and confirm every feature-flag row renders its value, source and state in Arabic (e.g. 'مفعّل · عن بُعد · ≥ ' and 'مفعّل · افتراضي · لم يتم التحميل'); no row contains the Latin substrings 'remote', 'default', or 'not loaded'. (no capture cited it)
  • not proved live: ux-check: Feature-flag rows still fit within their card at default font scale in en and ar (no row's relation wraps to a clipped or overlapping third line). (no capture cited it)

Open findings (not fixed here)

  • not proved live: profile.png is no longer on the host that took it, so no publish can carry it
  • not proved live: settings.png is no longer on the host that took it, so no publish can carry it
  • not proved live: sign-in-wrong-code.png is no longer on the host that took it, so no publish can carry it

e2

Surface: mobile-app

Explorer finding: 2 visual defects on android: The feature-flag rows show raw English d; The recipient address in the heading wra

The user-agent explorer found these 2 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 2 musts, one for each finding below.
The explorer never edits product code.

Evidence (from the device runs):

--- Finding 1 of 2: profile: The feature-flag rows show raw English developer state ("default · not loaded") beside the localized "مفعّل"/"معطّل" inside an otherwise fully Arabic screen.
Flow: profile
Found on revision: f2181ae
Repro:
1. set this state first: credits 20; reviews 4; uimode day; battery 22 discharging; rotate portrait; relaunch; seed app:user-id e2e-mobile-cloud-android@example.com; the device in light mode
2. open the app on emulator-5602
3. reach profile, settings
4. the capture shows the defect named below
Observed: The feature-flag rows show raw English developer state ("default · not loaded") beside the localized "مفعّل"/"معطّل" inside an otherwise fully Arabic screen.
Expected: the screen renders without this defect
- ~/.local/share/kwf/findings/explorer-2-visual-defects-on-android-the-feature-flag-row-489aab35/profile.png
- ~/.local/share/kwf/findings/explorer-2-visual-defects-on-android-the-feature-flag-row-489aab35/settings.png

--- Finding 2 of 2: sign-
@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

Executive Summary

The Preferences feature-flag row copy (value, source, state) is now translated across all 86 non-English catalogs, guarded by a new per-catalog unit test and a narrowed allowlist in check-catalogs.mjs; the three changed code/config files and the catalog edits check out with no functional issues found.

Files Reviewed (89 files)
  • apps/mobile/src/components/feature-flags-section.tsx - JSDoc only; the rendered shape <value> · <source> · <state> is unchanged
  • apps/mobile/src/i18n/feature-flag-copy.test.ts - new test; catalogValue helper and SUPPORTED_LANGUAGES.filter(tag => tag !== 'en') usage are correct, and src/i18n/**/*.test.ts is included in the mobile-pure vitest project
  • tools/i18n/check-catalogs.mjs - preferences.featureFlagApplied/Skipped/NotLoaded removed from ENGLISH_IDENTICAL_ALLOWLIST; comment updated to match
  • apps/mobile/src/i18n/locales/*.json (86 non-English catalogs) - verified all three keys exist, are non-empty, are not the English copy, keep the {{min}} placeholder where English has it, and use a consistent source (remote/default) and state term per catalog

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: ux-check: Dev build, app language Arabic, rotate portrait: open Preferences and confirm every feature-flag row renders its value, source and state in Arabic (e.g. 'مفعّل · عن بُعد · ≥ ' and 'مفعّل · افتراضي · لم يتم التحميل'); no row contains the Latin substrings 'remote', 'default', or 'not loaded'. (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
@iscekic
iscekic merged commit e5a472e into main Sep 23, 2026
29 checks passed
@iscekic
iscekic deleted the kwf/explorer-2-visual-defects-on-android-the-feature-flag-row-489aa-54f3 branch September 23, 2026 10:34
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