# UX and Copy Remediation Plan

## Purpose

This document defines the UX, copywriting, and localization cleanup track for the current UI. It is separate from `__REVIEW_FRONT.md`:

- `__REVIEW_FRONT.md` focuses on frontend architecture, safety, module structure, and delivery mechanics;
- `__REVIEW_UX.md` focuses on user-facing clarity, consistency, language quality, and product honesty.

The goal is to remove developer-facing language, broken localization patterns, misleading placeholders, and half-functional UI signals from the product surface.

## Core Principle

The UI must speak to operators, not to developers.

That means:

- no implementation jargon such as "slice", "wired", "resolved at runtime" unless the user truly needs it;
- no debug-style booleans in user-visible success messages;
- no fake functionality presented as nearly available unless the user can act on it;
- no mixed EN/RU phrasing where the product can speak normally in one language.

## Scope

This plan covers:

1. English copy cleanup;
2. Russian copy cleanup;
3. pluralization support;
4. login UX cleanup;
5. settings honesty cleanup;
6. command palette decision and follow-through;
7. wizard message polish;
8. terminology consistency rules.

## Track A: English Copy Quality

### Problem Types

#### A1. Literal formatting markers leaking into UI

Examples:

- `apikeys.callout.body`
- `wizard.step2.auth_profile_hint`

Current issue:

- backticks are rendered literally as characters;
- they do not become semantic formatting in HTML;
- the user sees developer-style markdown notation.

### Decision

Do not use markdown-style backticks in translation strings rendered through normal text nodes.

Allowed alternatives:

- plain text without emphasis;
- explicit `<code>` only when rendered through a trusted HTML path that is intended for markup;
- a dedicated visual class if code-like styling is actually needed.

### Required fixes

- `apikeys.callout.body`
  - replace `` `Last used` `` with plain text or a proper code-like span in a trusted template
- `wizard.step2.auth_profile_hint`
  - remove `` `execution_config.auth_profile_ref` `` from user-facing copy

### Preferred rewrites

Instead of:

- `Last used updates after successful MCP authentication.`

Use:

- `Last used updates after a successful MCP call.`

Instead of:

- `Selected profile will be resolved at runtime and attached through execution_config.auth_profile_ref.`

Use:

- `The selected auth profile is applied automatically when this tool runs.`

#### A2. Internal planning jargon visible to users

Examples:

- `secrets.profiles.empty_body`

Current issue:

- `next slice` is a delivery-planning term, not a product term.

### Decision

All planning jargon must be removed from UI strings.

Forbidden user-facing phrases:

- `next slice`
- `this build does not pretend`
- `wired yet`
- `not wired`
- `backed by`
- `resolved at runtime` unless the user truly configures runtime behavior

### Preferred rewrite

Instead of:

- `Create auth profiles in the next slice to bind secrets to upstream authentication.`

Use:

- `Create auth profiles in the Wizard when configuring an operation.`

#### A3. Unsafe or awkward symbols in plain text

Examples:

- `agents.drawer.recommendation`

Current issue:

- `<15` appears directly in text and should not rely on plain text rendering safety.

### Decision

Prefer natural language over symbolic shorthand in user guidance.

Preferred rewrite:

- `LLMs usually work best when an agent has fewer than 15 tools.`

#### A4. Debug-style status messages

Examples:

- `wizard.test.window_completed_body`
- `wizard.test.session_started_body`

Current issue:

- booleans like `true/false` are shown directly to users;
- milliseconds are exposed when approximate guidance is enough.

### Decision

User-visible status text must describe outcome, not internal flags.

### Required rewrites

`wizard.test.window_completed_body`

Current:

- `Window complete: {window_complete}. Truncated: {truncated}. Has more: {has_more}.`

Target behavior:

- message should describe:
  - how many items were collected;
  - whether data was truncated;
  - whether more data is available.

Preferred shape:

- `Collected {count} items.`
- `Collected {count} items. Results were truncated.`
- `Collected {count} items. More data is available if you extend the window or continue polling.`

`wizard.test.session_started_body`

Current:

- `Poll after {poll_after_ms} ms from the stream sessions view.`

Preferred:

- `Session started. Check Stream sessions in a few seconds.`

#### A5. Awkward English phrasing

Examples:

- `logs.range.1h: Last 1 hour`

Preferred:

- `Last hour`

### Acceptance Criteria

- no markdown backticks in plain-text translations;
- no delivery jargon in user-facing EN strings;
- no debug booleans in wizard result messaging;
- obvious awkward phrases are normalized to natural English.

## Track B: Russian Copy Quality

### Problem Types

#### B1. Missing keys

Known example:

- `wizard.step2.auth_basic` exists in EN and must exist in RU with product-quality copy.
- `secrets.profiles.subtitle_count` in the RU section is effectively still English and must be treated as a translation-parity defect, not just as weak wording.

### Decision

Translation parity is mandatory for both locales.

Every newly added EN key must either:

- be translated in RU in the same change;
- or fail verification.

### Required future safeguard

Add a translation parity checker to detect:

- missing RU keys;
- missing EN keys;
- exact duplicate placeholder keys if unintended.

#### B2. Russian pluralization is currently structurally incomplete

Known examples:

- `workspace_setup.member_count`
- `workspace_setup.members.days_ago`
- `secrets.used_by_count`

Current problem:

- templates like `{count} участников` fail for `1`;
- templates like `{count} дня назад` fail for `5`.

### Decision

Introduce plural helpers based on `Intl.PluralRules`.

### Target API

In `i18n.js`, add a helper such as:

```js
function tPlural(count, forms) {
  // locale-aware choice
}
```

Where:

- English uses `one / other`
- Russian uses `one / few / many`

### Target translation style

Instead of one flat string:

- `workspace_setup.member_count: '{count} участников'`

Use grouped forms, for example:

- `workspace_setup.member_count.one`
- `workspace_setup.member_count.few`
- `workspace_setup.member_count.many`

Or an equivalent plural storage format, as long as the API is stable.

### First keys to migrate

- `workspace_setup.member_count`
- `workspace_setup.members.days_ago`
- `secrets.used_by_count`
- `secrets.profiles.subtitle_count`
- `wizard.step3.grpc.streaming_hidden`
- `wizard.grpc.services_found`

#### B3. Developer calques and transliterated jargon

Examples:

- `резолвиться`
- `в следующем срезе`
- `notification settings`
- `lifecycle`
- `usage references`
- `advanced future integrations`

### Decision

Russian copy should be plain product Russian, while keeping real technical terms intact.

Keep in English only true technical terms such as:

- `gRPC`
- `WSDL`
- `JSON`
- `Bearer`
- `Query`
- `Mutation`
- `WebSocket`

Rewrite non-terms into Russian.

### Required rewrites

`wizard.step2.auth_profile_hint`

Instead of:

- `Выбранный профиль будет резолвиться в runtime...`

Use:

- `Выбранный профиль применяется автоматически при каждом вызове инструмента.`

`secrets.callout.body`

Remove mixed language and rewrite as:

- `После создания или ротации API возвращает только метаданные, поэтому на этой странице доступны управление секретами и просмотр их использования.`

`secrets.hint.generic`

Avoid:

- `advanced future integrations`

Use:

- `Подходит для произвольного JSON, если секрет нужно использовать в нестандартной интеграции.`

`workspace_setup.create.footer`

Replace:

- `Owner`

With:

- `Владелец`

`secrets.profiles.subtitle_count`

Current RU text is still English-like and must be translated fully.

### Acceptance Criteria

- no missing translation keys between EN/RU;
- Russian plural forms are grammatically correct;
- no developer calques remain in user-facing RU strings;
- role names are translated consistently.

## Track C: Login Experience Cleanup

### Problem

The login screen currently highlights unavailable functionality:

- Forgot password
- Google SSO
- Request access

all with `Planned` badges.

This creates the impression of unfinished product state on the very first screen.

There is also a developer-style note explaining what is not wired.

### Decision

The login page must present only working entry points.

### Recommended product behavior

#### Production/default mode

Show:

- email
- password
- sign-in button

Optionally show a single unobtrusive note:

- `Password reset and SSO will be added later.`

But only if product really needs that promise visible.

Preferred option:

- hide non-working actions completely.

#### Development-only mode

If the team wants visibility for future auth work, gate it behind a development flag.

Example:

- `window.CrankFeatures.showPlannedAuth`

### Required changes

#### Remove or gate:

- disabled `Forgot password?`
- disabled `Google SSO`
- disabled `Request access`
- `login.password_only` developer note from production HTML

### Acceptance Criteria

- login page does not lead with unavailable features;
- no developer-facing implementation note is shown in normal product mode.

## Track D: Settings Honesty Pass

### Problem

The settings page still contains a full `Notifications` section and other planned capability language that reads like UI cargo cult:

- detailed controls that do nothing;
- developer-style subtitle text;
- explanation written from the implementation perspective.

### Decision

If a settings area is not functional, it should not be represented as a near-complete interactive configuration panel.

### Product rule

There are only two acceptable states:

1. fully functional configuration;
2. compact informational placeholder.

Avoid:

- large fake forms;
- multiple toggles with `Planned` badges;
- controls that imply persistence when none exists.

### Required changes

#### `settings.page.subtitle`

Current EN subtitle speaks about capabilities being visible but not wired.

Replace with a user-centered subtitle such as:

- `Manage your profile, password, and workspace settings.`

#### Notifications section

Replace the current detailed pseudo-settings with one compact informational card:

- title
- short explanation
- possibly one sentence: `Notification routing and per-user preferences will be added later.`

No fake toggles.

#### Planned security capabilities

Keep only if:

- they are clearly informational;
- they do not look like interactive controls.

If they look interactive, collapse them into one planned card as well.

### Acceptance Criteria

- settings page describes what users can do now;
- non-functional areas are compact and clearly informational;
- no fake detailed settings remain.

## Track E: Command Palette Decision

### Problem

`⌘K` is visible in the navigation, but there is no working command palette attached to it.

This is worse than not showing it at all.

### Decision Matrix

#### Option 1: Remove it

Choose this if:

- there is no actual command palette implementation;
- there is no near-term product need for it;
- keeping the hint only creates false expectation.

#### Option 2: Implement it

Choose this only if the product has a real command list worth exposing.

Minimum useful scope:

- go to Operations
- go to Agents
- go to API Keys
- go to Secrets
- go to Logs
- go to Usage
- go to Settings
- switch workspace
- create new operation
- create new agent

### Current recommendation

Based on current code surface, remove it first.

Reason:

- there is visible affordance;
- there is no working interaction;
- product already has enough active work without adding a new shell feature mid-stream.

If later implemented, it should land as its own feature:

- `feat/frontend-command-palette`

### Acceptance Criteria

- either `⌘K` is removed everywhere;
- or a real command palette exists and is keyboard-accessible.

No middle state.

## Track F: Wizard Messaging and Step Clarity

### Problem

Wizard copy still includes:

- technical internal language;
- poor plural handling;
- insufficiently clear streaming result messages;
- protocol-step context that changes without enough explicit signaling.

### Required changes

#### F1. Auth selector copy

Remove implementation references such as:

- `execution_config.auth_profile_ref`

Replace with operator language:

- `The selected auth profile is applied automatically when the tool runs.`

#### F2. Streaming result messages

Replace technical booleans and milliseconds with outcome-focused language.

For:

- `window`
- `session`
- `async_job`

#### F3. gRPC plural and summary strings

Fix:

- `streaming method(s)`
- `1 services`

Use locale-aware pluralization helpers.

#### F4. Step-3 protocol clarity

The sidebar label changing per protocol is useful, but not always obvious enough after protocol switching.

Recommended UI change:

- add a small protocol badge near the step title on step 3:
  - `REST config`
  - `GraphQL operation`
  - `gRPC method`
  - `WebSocket stream`
  - `SOAP binding`

This should exist both:

- in the main pane heading;
- optionally in the sidebar if compact enough.

### Acceptance Criteria

- wizard status/result text reads like product UX, not runtime telemetry;
- plural forms are correct;
- step 3 protocol-specific context is explicit.

## Track G: Terminology Rules

### Problem

The UI currently mixes three categories without a clear rule:

1. real technical terms;
2. product concepts;
3. implementation jargon.

### Terminology Policy

#### Keep as technical terms

- `Query`
- `Mutation`
- `gRPC`
- `REST`
- `WebSocket`
- `SOAP`
- `WSDL`
- `JSON`
- `Bearer token`

#### Translate to product language

- `workflow`
- `settings`
- `usage`
- `notifications`
- `workspace`
- `owner`

#### Never expose as user-facing jargon

- `slice`
- `wired`
- `resolved at runtime`
- `metadata only` if better phrasing exists
- `future integrations`
- `usage references`
- `backed by`

### Acceptance Criteria

- technical terms remain technical;
- implementation jargon disappears from UI.

## Track H: Verification and Guardrails

### Problem

Without guardrails, translation and UX regressions will return.

### Required safeguards

#### H1. Translation parity check

Add a script/test that verifies:

- EN and RU contain the same key set;
- missing keys fail CI.

#### H2. Dangerous copy lint

Add a lightweight scan for forbidden phrases in user-facing translations:

- `next slice`
- `wired`
- `resolved at runtime`
- backticks in plain text translations
- `(s)` plural suffix

This can be a simple repo script at first.

#### H3. UX regression checklist

Extend manual regression docs with:

- login first impression check;
- no dead nav affordances;
- no fake settings sections;
- pluralization smoke in RU.

### Acceptance Criteria

- parity regressions are caught automatically;
- obvious UX copy anti-patterns are detectable before release.

## Delivery Order

Recommended order:

1. `feat/frontend-ux-review-plan`
2. `feat/frontend-i18n-remediation`
3. `feat/frontend-login-simplification`
4. `feat/frontend-settings-honesty-pass`
5. `feat/frontend-command-palette-decision`
6. `feat/frontend-wizard-copy-polish`
7. `feat/frontend-plural-rules`
8. `feat/frontend-ux-guardrails`

## Per-Slice Verification

Each slice should include:

- targeted `node --check` for touched JS
- targeted Playwright smoke if the affected page already has coverage
- manual locale switch smoke for EN and RU

Additional rules:

- login cleanup must be visually checked on first load;
- plural-rule slice must include sample assertions for RU forms;
- command-palette decision slice must verify no dead `⌘K` affordance remains.

## Success Definition

This UX cleanup track is complete when:

- the product no longer exposes developer planning language;
- EN and RU feel intentional rather than partially translated;
- plural forms are correct in both locales;
- login shows only meaningful actions;
- settings no longer presents fake detailed controls;
- the command palette affordance is either real or removed;
- wizard status and streaming messages are understandable without internal knowledge.

At that point, the UI stops feeling like a well-built internal tool and starts reading like a finished product surface.
