docs: add ux remediation plan
This commit is contained in:
@@ -19,7 +19,12 @@ DoD:
|
||||
## Backlog
|
||||
|
||||
- `feat/frontend-refactoring-plan`
|
||||
- `feat/frontend-ux-review-plan`
|
||||
- `feat/frontend-xss-hardening`
|
||||
- `feat/frontend-i18n-remediation`
|
||||
- `feat/frontend-login-simplification`
|
||||
- `feat/frontend-settings-honesty-pass`
|
||||
- `feat/frontend-command-palette-decision`
|
||||
- `feat/frontend-shell-unification`
|
||||
- `feat/frontend-wizard-modularization`
|
||||
- `feat/frontend-build-pipeline`
|
||||
|
||||
+735
@@ -0,0 +1,735 @@
|
||||
# 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.
|
||||
|
||||
### 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.
|
||||
Reference in New Issue
Block a user