4.2 KiB
4.2 KiB
Cordn / MLS / Staircase — UX audit (2026-10-12)
Scope: every surface where a skater meets the crew's encrypted chat — the crew page (Private chat tab + sidebar card), the Messages hub, Settings → Coordinator, and the CrewForm fields — plus the Staircase / Cordn-web hand-offs.
The goal was a coherent story: two chats exist (built-in NIP-17 "Chat" and the real-MLS "Private chat"), and the UI must never make them contradict each other.
Terminology model (the fix that anchors everything)
| Surface | Name | Protocol | Setup |
|---|---|---|---|
| Crew page tab (existing) | Chat | NIP-17 giftwrap | always on |
| Crew page tab (new) | Private chat | MLS via coordinator | created once by an admin |
| Sidebar card | Encrypted chat | covers both | — |
Rule: never call the sidebar card "Private chat" (collides with the MLS tab), and never badge the MLS chat "On" when it hasn't been created.
Findings
| # | Sev | Status | Finding |
|---|---|---|---|
| 1 | High | Fixed | The sidebar card badged "Private chat · On" (meaning the NIP-17 Chat tab) while the MLS tab said "not created yet" — a direct contradiction. The card now shows two explicit rows, Chat (always on) and Private chat (On / Set up / Join / Checking), reflecting the real MLS status. |
| 2 | High | Fixed | Name collision: card "Private Crew Chat" vs tab "Private chat". Card retitled "Encrypted chat"; row names are Chat / Private chat. |
| 3 | Med | Fixed | The card led with external apps ("Cordn (web)", "Copy for Staircase") even though the app now ships its own MLS chat. The in-app Private chat is now the primary CTA (one tap → ?tab=mls); external clients moved under a labelled "Open in another app" row. |
| 4 | Med | Fixed | Joining gave no feedback. The panel now says "Request sent…" after Ask-to-join and "No invite waiting yet…" after Check-for-invite. |
| 5 | Med | Fixed | An admin who created the chat wasn't told how members join. The panel now shows an invite hint while the group has one member. |
| 6 | Med | Fixed | Crews were invisible in the Messages hub. Added a Crews section (status badge + deep link to ?tab=mls). |
| 7 | Low | Fixed | The crew page's tabs weren't deep-linkable; now ?tab=events|chat|mls (explicit param wins over the auto-default). |
| 8 | Low | Open | cordnUi.* / new crewCoordinator.* copy exists only in en/es; other locales fall back to English. Acceptable for a new feature, worth translating once it has users. |
| 9 | Low | Open | Cordn (web) is broken against our coordinator (upstream issue, drafted). Kept as a secondary link only; prefer the in-app chat or Staircase. |
| 10 | Low | Open | CrewForm's "Cordn group" field is Staircase-era jargon; now that the app creates groups natively it mostly serves importing an external group. Consider moving it under an "Advanced" disclosure. |
| 11 | Info | By design | Interactive signer (Amber): no live updates — the panel shows a hint and the DM pages have a manual Refresh. This is the deliberate "never pop Amber in the background" posture. |
| 12 | Info | By design | The coordinator sees ciphertext + metadata only; the card and the Settings privacy note say so plainly. |
Still open / next
- Unread for the Private chat: ⚠️ needs a signed fetch — the MLS messages are behind the coordinator's ContextVM RPC, with no cheap metadata peek (that was the retired sealed-relay path). Options: a silent-signers-only background fetch (no dot for Amber), or leave it. A local-only dot would be misleading.
Shareable "join this crew's chat" link✅ done — the panel's admin Invite action shares…/crew/<pk>/<id>?tab=mlsvia the OS share sheet / clipboard.i18n drift✅ done — all 20 locales back to 100% (see AGENTS.md).- Persisted DM decrypt cache: ✅ done (
src/lib/dmDecryptCache.ts). - Broad polish: still open — candidates: a "Clear cached messages" action, entry-bundle trim, a11y, empty/error-state consistency.
Verified
npm test + check-i18n green; ?tab=mls deep-link wired through the crew page.
Not click-tested in a real browser this session (no logged-in browser fixture).