Files
crank/__REVIEW_UX.md
T
2026-04-12 01:12:24 +03:00

737 lines
16 KiB
Markdown

# 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.