Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
204 changes: 204 additions & 0 deletions .claude/skills/platform-ui-drift/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
---
name: platform-ui-drift
description: Audit and fix drift between Platform docs UI tokens and the loft-enterprise UI source. Use when running the drift report, interpreting its output, verifying findings against loft-enterprise, or fixing stale nav paths, labels, and informal prose in platform docs.
context: fork
---

# Platform UI Drift

The `report-platform-ui-drift` script compares UI tokens in platform docs (text wrapped in `<Button>`, `<Label>`, `<NavStep>`, `<Input>`, `<Field>`) against the loft-enterprise UI source. It also flags informal prose that should use proper doc components.

Run it before a release, when a support engineer reports drift, or when reviewing a batch of platform doc files.

## Run the report

```bash
npm run report-platform-ui-drift
# or with JSON output for scripting:
node scripts/report-platform-ui-drift.js --json
```

Requires `loft-enterprise` checked out as a sibling of this repo at `../loft-enterprise`.

## Interpret the output

### Unmatched tokens section

Tokens in `<Button>`, `<Label>`, `<NavStep>`, `<Input>` that the script did not find in the loft-enterprise UI source. These are **leads, not proof** — some are genuine drift, some are script limitations.

**High-confidence drift signals:**

- `<Button>` text not found — buttons rename frequently (e.g. "Create Space Template" → "Create Namespace Template")
- `<Label>` text not found — field labels rename when forms are redesigned
- Single-segment `<NavStep>` not found (e.g. `<NavStep>Allowed Templates</NavStep>`) — tab or section name changed
- `<Input>` placeholder text not found — placeholder copy changes silently

**Lower-confidence (verify before fixing):**

- Multi-part `<NavStep>` paths like `Infrastructure > Control Plane Clusters` — the script checks each segment separately; a match means each word exists *somewhere* in 1779 UI files, not necessarily as a nav label. Spot-check in `loft-enterprise/ui/src/Layout/Sidebar/config/sections.tsx` and the relevant page layout file.

**Known expected unmatched tokens (ignore these):**

Some tokens will never match because their text is generated at runtime or the feature has no dedicated UI component files in the source:

| Token | File | Reason |
|---|---|---|
| `<Label>Argo CD Template ID</Label>` | `integrations/argocd/deploy-applications.mdx` | Label built from `entityTypeName` prop in `ArgoCDApplicationTemplates.tsx` — not a literal string |
| `<Label>Argo CD Application ID</Label>` | `integrations/argocd/deploy-applications.mdx` | Same — built from `entityTypeName` in `ArgoCDApplicationConfigForm.tsx` |
| `<Button>Create Namespace Constraints</Button>` | `_partials/space-constraints/create-ui.mdx`, `use-platform/namespaces/_partials/space-constraints/create-ui.mdx` | Feature exists (breadcrumb in `breadcumbsTransforms.ts`) but has no dedicated UI component files in source |
| `<Label>Enforce Namespace Constraints</Label>` | `use-platform/namespaces/_partials/space-constraints/enforce-ui.mdx` | Same — no component file to grep |

**Common false negatives (real drift the script misses):**

- `Admin > Config` — matched because "admin" and "config" appear elsewhere in code, but the real nav path is `Platform > Platform Config`. Always verify `Admin > *` paths manually.

### Instruction phrases section

Prose that uses informal UI terminology outside of a doc component. These are always real leads — the UI check adds no signal here, so every occurrence is worth reviewing.

| Phrase found | What to do |
|---|---|
| `left menu` / `left sidebar` | Remove — the nav component conveys location implicitly |
| `drop down arrow` / `drop down menu` / `dropdown menu` | Replace the whole step with `Click <Button>X</Button>` |
| `drawer` | Replace with "configuration sheet" |
| `configuration pane` | Replace with "tab" (e.g. "click the `<Label>Agent</Label>` tab") |
| `textarea` | Replace with "field" |
| `checkbox` | Replace with "enable `<Label>X</Label>`" |

## Verify a finding against loft-enterprise

Before fixing, confirm what the UI actually says. The UI source is at `../loft-enterprise/ui/src`.

### Nav paths

```bash
# Section labels and item names
cat ../loft-enterprise/ui/src/Layout/Sidebar/config/sections.tsx

# Sub-nav tabs for a given view (e.g. clusters)
cat ../loft-enterprise/ui/src/views/Clusters/hooks/useClusterTabs.tsx
```

**Current sidebar structure (as of 2026-06):**

| Section label | Key items |
|---|---|
| Infrastructure | Infra Providers, Control Plane Clusters, Connectors, Bare Metal Servers |
| Tenant Management | Cluster Templates, Namespace Templates, Argo CD Templates, Apps |
| Access & Secrets | Users & Roles, SSH Keys, Global Secrets |
| Platform | Logs & Activity, Cost Control, Platform Config |

Control Plane Clusters sub-tabs: Host Clusters, Cluster Access, Cluster Roles, VPN.

### Button and label text

```bash
# Text in JSX children (most reliable)
grep -r "Button text or label" ../loft-enterprise/ui/src --include="*.tsx" | grep -v "spec\|test\|//"

# Text in JSX props (label=, title=, placeholder=, submitLabel=)
grep -r 'label="Button text"' ../loft-enterprise/ui/src --include="*.tsx" | grep -v "spec\|test"
```

The script now extracts both — but grepping directly is faster for spot-checking.

### Cluster/form sheet tabs

```bash
# Cluster edit sheet tabs
grep -n "label" ../loft-enterprise/ui/src/views/Clusters/ClusterDrawer/ClusterDrawer.tsx
# Current tabs: Agent, Direct Access, Argo CD, Management Access

# Project form section titles
grep -rn "title=" ../loft-enterprise/ui/src/views/Projects/ProjectForm/Sections --include="*.tsx"
# Current: Members and Roles, Control Plane Clusters, Template Options, Quotas, Advanced, Argo CD Integration
```

### Role sheet sections

```bash
grep -n "title=" ../loft-enterprise/ui/src/views/Roles/RoleForm/RoleForm.tsx
# Sections: Rules (tabs: RBAC Rules, Aggregation Rule), Management Access
```

## Fix patterns

### Navigation steps

Replace the old `<NavStep>` path with the current one. Always use `Infrastructure > Control Plane Clusters` for the clusters section.

```mdx
<!-- Before -->
Go to the <NavStep>Clusters</NavStep> view using the menu on the left.

<!-- After -->
Go to <NavStep>Infrastructure > Control Plane Clusters</NavStep>.
```

Remove trailing "using the menu on the left" — the `<NavStep>` component conveys location.

### Cluster actions menu (Edit)

The cluster list has a per-row actions menu (gear icon). Reference the action text directly:

```mdx
<!-- Before -->
Click the drop down arrow next to the cluster name you wish to modify. In
the drop down menu click the <Label>Edit</Label> button.

<!-- After -->
Click the <Button>Edit</Button> option for the cluster you want to modify.
```

### Configuration sheet (formerly "drawer")

```mdx
<!-- Before -->
In the drawer that appears from the right, click on the <Label>Agent</Label>
configuration pane.

<!-- After -->
In the configuration sheet that opens, click the <Label>Agent</Label> tab.
```

### Section names in forms

| Old | Current |
|---|---|
| `Access` (cluster role form) | `Management Access` |
| `Allowed Templates` (project) | `Template Options` |
| `Allowed Clusters` (project) | `Control Plane Clusters` |
| `Configure Project Quotas` | `Quotas` |
| `Cluster Role` tab | `Cluster Roles` |

### Argo CD

The UI uses a space: "Argo CD" not "ArgoCD". The script normalizes this so it matches, but fix prose spelling when you touch the file.

## After fixing: Vale

Run Vale on every file you touch and fix all warnings — not just the drift-related lines.

```bash
vale platform/path/to/file.mdx
```

Common warnings triggered by drift fixes:
- `click on` → `click`
- Headings ending in `-ing` (Finding, Setting, Troubleshooting) → use imperative (Find, Set, Troubleshoot)
- Title-case headings → sentence case
- `via` → `using`

## Drift baseline (as of 2026-06-26)

After the DOC-1574 sweep, the report stands at 4 unmatched tokens (all in the "known expected" table above) and 0 instruction phrases. Any new findings above this baseline represent genuine drift introduced since that date.

## Release checklist use

Run the report as part of platform release prep:

1. `npm run report-platform-ui-drift > .user/ui-drift-$(date +%Y%m%d).txt`
2. Review unmatched tokens — focus on `<Button>` and single-segment `<NavStep>` first
3. Spot-check two or three Label findings against loft-enterprise source
4. Fix confirmed drift files; treat instruction phrases as a separate writing-quality pass
5. Re-run report to confirm unmatched count dropped
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"sync-upstream": "node scripts/sync-upstream-features.js",
"validate-upstream": "node scripts/sync-upstream-features.js --dry-run",
"validate-versioned-links": "node scripts/validate-versioned-links.js",
"report-platform-ui-drift": "node scripts/report-platform-ui-drift.js",
"check-latest-versions": "node scripts/check-latest-versions.js",
"sync-latest-versions": "node scripts/check-latest-versions.js --update",
"check-eos-eol-labels": "node scripts/check-eos-eol-labels.js",
Expand Down
4 changes: 2 additions & 2 deletions platform/_partials/access-key/create-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import CreateSpaceStep2 from '@site/static/media/ui/screenshots/spaces/create-sp

<Flow id="create-space-template-ui">
<Step>
Go to the <NavStep>Profile</NavStep> view using the menu on the left
Go to <NavStep>Profile</NavStep>.
</Step>
<Step>
Switch to the <Label>Access Keys</Label> tab
Expand All @@ -20,7 +20,7 @@ import CreateSpaceStep2 from '@site/static/media/ui/screenshots/spaces/create-sp
Click the <Button>Create Access Key</Button> button to create a new access key
</Step>
<Step>
In the drawer that appears on the right, use the field <Label>Display Name</Label> to specify a <Input>Name</Input> for your access key
In the configuration sheet that opens, use the <Label>Display Name</Label> field to specify a <Input>Name</Input> for your access key
</Step>
<Step>
OPTIONAL: Expand the <Expander>Limit Access Key Scope</Expander> section to specify which clusters, namespaces and virtual clusters this access key can be used for
Expand Down
18 changes: 9 additions & 9 deletions platform/_partials/cluster/connect-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@ import Expander from '@site/src/components/Expander'

<Flow id="cluster-connect-ui">
<Step>
Go to the <NavStep>Clusters</NavStep> view using the menu on the left.
Go to <NavStep>Infrastructure > Control Plane Clusters</NavStep>.
</Step>
<Step>
Click on the <Button>Connect Cluster via CLI</Button> button on the right.
Click <Button>Connect Cluster</Button>.
</Step>
<Step>
In the drawer that appears from the right, give your cluster a name in the <Label>Display Name</Label> field.
Optionally give a name for the underlying kubernetes resource in the <Label>Kubernetes Name (ID)</Label>, or leave it empty to have it autogenerated for you.
Then click on the <Button>Next</Button> button.
Give your cluster a name in <Label>Display Name</Label>.
Optionally, give a name for the underlying kubernetes resource in the <Label>Cluster ID</Label> field, or leave it empty to autogenerate one.
Then click <Button>Next</Button>.
</Step>
<Step>
In the section "Cluster Connection", please copy & execute the displayed vCluster CLI or Helm command
Copy & execute the displayed vCluster CLI or Helm command.
</Step>
<Step>
Please wait until vCluster Platform installs the agent in your connected cluster.
Wait until vCluster Platform installs the agent in your connected cluster.
</Step>
<Step>
Once successful, you may create a space / virtual cluster in the newly connected cluster by using the displayed vCluster CLI command.
Once successful, use the displayed CLI command to create a space / virtual cluster in the newly connected cluster.
</Step>
<Step>
Click on the <Button>Finish</Button> button to go to the <NavStep>Clusters</NavStep> view.
Click <Button>Finish</Button> to go to the <NavStep>Control Plane Clusters</NavStep> view.
</Step>
</Flow>
7 changes: 3 additions & 4 deletions platform/_partials/cluster/create-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Flow, { Step } from "@site/src/components/Flow";
If you are still impersonating, click <Button>Stop Impersonation</Button>
</Step>
<Step>
Go to the <NavStep>Clusters</NavStep> view using the main menu on the left
Go to <NavStep>Infrastructure > Control Plane Clusters</NavStep>.
</Step>
<Step>
Switch to the tab <NavStep>Cluster Access</NavStep>
Expand All @@ -27,15 +27,14 @@ import Flow, { Step } from "@site/src/components/Flow";
individual user access to a cluster
</Step>
<Step image="">
Use the field <Label>Select Individual Users</Label> and select the{" "}
<Input>User(s)</Input> you want to create this cluster access for
Select the users you want to give this cluster access to.
</Step>
<Step image="">
In the <Label>Clusters</Label> section, either select{" "}
<Input>All Clusters</Input> or the specific cluster that you want to make
accessible for the users you selected in the previous step
</Step>
<Step image="">
Click the button <Button>Create</Button> at the bottom of the drawer
Click <Button>Create</Button> at the bottom of the configuration sheet.
</Step>
</Flow>
11 changes: 4 additions & 7 deletions platform/_partials/namespace-template/create-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,13 @@ import CreateSpaceStep2 from '@site/static/media/ui/screenshots/spaces/create-sp

<Flow id="create-space-template-ui">
<Step>
Go to the <NavStep>Spaces</NavStep> view using the menu on the left
Go to <NavStep>Tenant Management > Namespace Templates</NavStep>.
</Step>
<Step>
Switch to the <Label>Space Templates</Label> tab
Click <Button>Create Namespace Template</Button>.
</Step>
<Step>
Click the <Button>Create Space Template</Button> button to create a new space template
</Step>
<Step>
In the drawer that appears on the right, use the field <Label>Display Name</Label> to specify a <Input>Name</Input> for your space template
In the configuration sheet that opens, use the <Label>Display Name</Label> field to specify a <Input>Name</Input> for your namespace template.
</Step>
<Step>
Specify sleep mode settings as well as enforced labels and annotations for the spaces that will be created from this template
Expand All @@ -29,6 +26,6 @@ import CreateSpaceStep2 from '@site/static/media/ui/screenshots/spaces/create-sp
Expand the <Expander>Deploy Apps</Expander> section to specify which apps should be deployed as part of this template
</Step>
<Step>
On the very bottom, click on the <Button>Create</Button> button to create this space template
Click <Button>Create</Button> to create this namespace template.
</Step>
</Flow>
14 changes: 4 additions & 10 deletions platform/_partials/namespace/add-app-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,20 @@ import Button from '@site/src/components/Button'
import Label from '@site/src/components/Label'

<Step>
Select the <NavStep>Projects</NavStep> field on the left menu bar.
Select the project containing the namespace from the project selector at the top left.
</Step>
<Step>
Select the project containing the namespace that you'd like to install
the App in from the Project drop down menu.
Click <NavStep>Namespaces</NavStep>.
</Step>
<Step>
From the Projects sub-menu, select the Namespaces option.
</Step>
<Step>
Find the namespace you would like to deploy an App to in the list of namespaces, and click on that
Find the namespace you would like to deploy an App to in the list of namespaces, and click that
namespace.
</Step>
<Step>
In the Namespace Management view, click the <Button>Apps</Button> button.
</Step>
<Step>
Select the App you would like to install from the App thumbnails, or, if there
are no recommend Apps, click the <Button>Install App</Button> and find the
desired App in the <Label>Select an App</Label> drop down menu.
Select the App you would like to install from the App thumbnails, or click <Button>Install App</Button> and select the desired App.
</Step>
<Step>
Enter any other required parameters for your App -- this may vary depending on
Expand Down
8 changes: 4 additions & 4 deletions platform/_partials/namespace/share-ui.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import Expander from '@site/src/components/Expander'

<Flow id="namespace-share-ui">
<Step>
Go to the <NavStep>Projects</NavStep> view using the menu on the left
Select the project from the project selector at the top left, then click <NavStep>Namespaces</NavStep>.
</Step>
<Step>
Click on Namespaces and click on the Edit link on a namespace.
Click <Button>Edit</Button> on the namespace you want to share.
</Step>
<Step>
In the drawer select the 'Permissions' section.
In the configuration sheet that opens, click the <Label>Permissions</Label> tab.
</Step>
<Step>
Select the user or team you want to grant permissions in the 'User or Team' select. If you don't see the user or team you want to grant access in there, make sure they have project access.
Expand All @@ -22,6 +22,6 @@ import Expander from '@site/src/components/Expander'
Specify the cluster-role you want to assign the user or team within the namespace.
</Step>
<Step>
Click on the <Button>Save Changes</Button> button at the very bottom
Click the <Button>Save Changes</Button> button.
</Step>
</Flow>
Loading
Loading