Repository navigation
fix(mobile): localize the Security Agent enable error in every locale - #9443
Conversation
Enabling the agent without the Dependabot permission was refused with an English sentence and no stable code, so a device could only show that sentence. The refusal now carries the same precondition code the manual-sync path uses; the English message stays for the web surface. The config compare-and-set refusal (settings save and the enable toggle) gets its own code for the same reason: another session or device wrote first, and a device needs to say so in the reader's language.
The enable toggle and the settings save toasted the server's sentence as it arrived, so every locale showed English plus the raw permission key. Both now resolve a marked refusal to catalog copy: a missing Dependabot permission reads the same re-authorize sentence the scope screen shows, a stale config reads the new conflict line, and anything else reads the existing localized generic sentence instead of server prose. The conflict copy lands in all 87 catalogs with the English key.
|
bot: Verified on the Android emulator against the local stack, with the app language set to Portuguese (Brazil) and a fixture account whose GitHub connection lacks the Dependabot permission.
Design gate for |
The lint rule for the mobile app requires a switch over a possibly undefined value to name every case; two equality checks read the same and say the same.
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe incremental change marks the empty-scope enable refusal with the existing Assumptions: Files Reviewed (5 incremental files)
Previous Review Summary (commit c548b87)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit c548b87)Status: No Issues Found | Recommendation: Merge Executive SummaryThe change adds stable wire codes ( Assumptions: Files Reviewed (97 files)
Reviewed by deepseek-flash-latest · Input: 56.4K · Output: 9.9K · Cached: 757.4K Review guidance: REVIEW.md from base branch |
eshurakov
left a comment
There was a problem hiding this comment.
Bot - Minor: the sibling enable refusal still loses its actionable text. setEnabled also throws PRECONDITION_FAILED for an empty effective repo scope ("Select at least one repository before enabling Security Agent.", apps/web/src/lib/security-agent/router/shared-handlers.ts:1271) with no stable code, so securityConfigMutationMessage falls through to the generic copy. Before this change the toast carried that sentence; after it, an unmarked PRECONDITION_FAILED classifies as terminal, so the user sees securityAgent.mutations.actionBlocked ("The problem needs fixing before you can retry.") with no hint to pick repositories. Consider giving that refusal its own marker, or reusing the existing noRepositories precondition code mapped to catalog copy.
The empty-scope refusal on enable carried no stable code, so the mobile config-write toast fell back to the generic terminal sentence instead of naming the fix. Mark it with the sync no-repositories code and read the repository picker's own sentence in the config-write toast.
|
bot: Fixed the minor remark in this review: the empty-scope enable refusal no longer falls through to the generic terminal sentence.
The remark's alternative, reusing the code but keeping the sync wording, was not taken because that sentence ends "then sync again", which does not fit an enable refusal. The other observation in the summary stays as designed: a refusal the server does not mark still reads the localized generic sentence, never the server's English prose. |
|
bot: Proof of the empty-scope enable refusal on the Android emulator against this VM's local stack, with the app in Portuguese (Brazil) and a fixture account whose stored repository selection no longer resolves in the GitHub installation. Same screen, same tap of the "Agente de segurança" switch:
Both captures came from a |
…ty-agent-enable-error # Conflicts: # apps/mobile/src/i18n/locales/et.json
|
bot: Verified at this head on the Android emulator against the local stack, with the app language set to Portuguese (Brazil) and a fixture account whose GitHub connection has no Dependabot (vulnerability alerts) permission.
|
|
bot: The red Cause: Evidence on this VM at head |
|
bot: Correction to the previous comment's count: the full-shard evidence at head |










Evidence
Evidence: demonstrated — on the Android emulator against the local stack at this head, with the app in Portuguese (Brazil) and a fixture account whose GitHub connection lacks the Dependabot permission, the enable switch now refuses with app-catalog copy; the merge base bundle on the same device, account and language still showed the server's English sentence with the raw permission key.
Change
Enabling the Security Agent is refused by the server for two reasons, and both carried only an English sentence, which the mobile write path toasted as it arrived: every locale showed untranslated copy, and the first also exposed the raw
vulnerability_alertskey.Server:
shared-handlers.tssetEnabled), so a client can map it. The English message stays for the web surface.SECURITY_CONFIG_CONFLICT_CODE), attached indb/security-config.tsfor both the first-insert race and the stale-revision update.Mobile:
securityConfigMutationMessageinsecurity-agent-ledger.tsresolves a marked refusal to catalog copy: the missing permission reads the same re-authorize sentence the scope screen shows, the empty scope reads the repository picker's "select at least one repository" line, a stale config reads the new conflict line, and anything unmarked reads the existing localized generic sentence instead of server prose.onErrors inuse-security-agent-mutations.ts(the enable toggle and the settings save) use it.Copy: the two refusal cases reuse keys that are already translated in every catalog —
securityAgent.scopeEntry.reauthorizeDescriptionfor the permission andsecurityAgent.repositories.selectAtLeastOnefor the empty scope — so the toast cannot drift from the screens that own the wording. The one new key,securityAgent.mutations.configConflict, is added toen.jsonand translated in all 86 other catalogs in this change, so no translation slice is needed.Verification
npx jest src/lib/security-agent/router/shared-handlers.test.ts src/lib/security-agent/db/security-config.test.ts— 111 tests pass, including checks that the permission refusal carriessecurity_sync_missing_permission, that the empty-scope refusal carriessecurity_sync_no_repositorieson both the personal and organization routers, that a disable still goes through without the permission, and that the stale-revision conflict carriessecurity_config_conflict.npx vitest run --shard=3/8inapps/mobile— 180 files, 3413 tests pass at this head.node tools/i18n/check-catalogs.mjsreports 87 languages matchingen.json,node tools/i18n/check-plurals.mjs --source-onlypasses, and a strict duplicate-key parse of all 87 catalogs is clean (the merge with main resolved one conflicting block inet.json, keeping main's Estonian register for the sibling sentences and this branch's new key).GitHub App does not have vulnerability_alerts permission. After (this head):O agente de segurança precisa de permissão para ler os alertas do Dependabot. Reautorize o app do GitHub para conceder essa permissão.The switch returns to off in both captures.Selecione pelo menos um repositório.PRECONDITION_FAILEDwithdata.upstreamCode = security_sync_missing_permission(andsecurity_sync_no_repositoriesonce the permission is present but the scope is empty) whileerror.messagekeeps the English sentence for web.Production prerequisites
None.
Proxy answers
The owner's proxy gave these answers in the owner's place.
Answer: Reuse the scope screen reauthorize copy (Recommended)
Confidence: 0.80 · Precedent: Speed and least work: 'do the least amount of work possible, with no drop in quality'. The brief asks for wording consistent with the scope screen, and this reuses the exact sentence that is already translated in every catalog.
Answer: Save too: stable conflict code + new key (Recommended)
Confidence: 0.65 · Precedent: Fix the class: 'if anything repeats the same mistake over and over again, fix the class'. i18n is important to the owner. A real conflict should tell the user to review and save again, not show a misleading generic message.