Display the current account at the bottom of the sidebar #33

Open
opened 2026-08-22 09:57:08 +00:00 by kayg · 0 comments
Owner

Scope

Add the current account identity as a visible row at the bottom of the sidebar. This is the presentation increment that can ship before the deferred account/profile switching work in #32; it must not expand #32's switching scope.

  • Use a left-aligned pill assembled from system SwiftUI components.
  • Give the bottom of the sidebar the same soft edge as the transcript: one masked material with a gradient mask, rather than stacked bands or glass layered over the NavigationSplitView material.
  • Inject the already-resolved display string at composition. Sidebar presentation must not invent a second gateway-identity lookup.

Identity research / open question

The gateway contract must be checked for the identity it genuinely exposes instead of assuming a human name. Research found that dashboard GET /api/auth/me exposes user_id, email, display_name, org_id, provider, and expiry, but the current Hermes Nous provider maps the JWT subject to user_id and leaves email and display_name empty—there is no human-facing name/profile in the current provider contract. POST /auth/native/token may also return provider and user_id, while GET /api/auth/providers exposes provider metadata (name, display_name, and capability flags). The current credential account key remains the gateway's absolute URL. See #1 for the auth/provider contract and #32 for the deferred account/profile model.

Acceptance criteria

  • Composition injects a non-empty display string sourced from the gateway contract, with this stated fallback chain: non-empty /api/auth/me display_name, then non-empty /api/auth/me email, then /api/auth/me user_id rendered as an Account ID (the current provider's genuine identity), then provider display_name/name, then the gateway host (and finally its absolute URL if needed). No fabricated local username is used, and an opaque user_id is never mislabeled as a human name.
  • If the compact label is visually elided, the complete identity remains recoverable through the row's accessibility label/value and a native macOS help affordance; truncation never changes the stored identity.
  • The bottom soft edge keeps the account text legible while sidebar content scrolls beneath it, using the transcript's single masked-material gradient technique.
  • The pill grows with Dynamic Type and accessibility sizes without clipping the identity or collapsing the row.
  • The account row is one accessible element with one coherent label/value; when it is non-interactive it is not focusable and does not advertise an actionable trait.
## Scope Add the current account identity as a visible row at the bottom of the sidebar. This is the presentation increment that can ship before the deferred account/profile switching work in #32; it must not expand #32's switching scope. - Use a left-aligned pill assembled from system SwiftUI components. - Give the bottom of the sidebar the same soft edge as the transcript: one masked material with a gradient mask, rather than stacked bands or glass layered over the NavigationSplitView material. - Inject the already-resolved display string at composition. Sidebar presentation must not invent a second gateway-identity lookup. ## Identity research / open question The gateway contract must be checked for the identity it genuinely exposes instead of assuming a human name. Research found that dashboard `GET /api/auth/me` exposes `user_id`, `email`, `display_name`, `org_id`, `provider`, and expiry, but the current Hermes Nous provider maps the JWT subject to `user_id` and leaves `email` and `display_name` empty—there is no human-facing name/profile in the current provider contract. `POST /auth/native/token` may also return `provider` and `user_id`, while `GET /api/auth/providers` exposes provider metadata (`name`, `display_name`, and capability flags). The current credential account key remains the gateway's absolute URL. See #1 for the auth/provider contract and #32 for the deferred account/profile model. ## Acceptance criteria - [ ] Composition injects a non-empty display string sourced from the gateway contract, with this stated fallback chain: non-empty `/api/auth/me` `display_name`, then non-empty `/api/auth/me` `email`, then `/api/auth/me` `user_id` rendered as an **Account ID** (the current provider's genuine identity), then provider `display_name`/`name`, then the gateway host (and finally its absolute URL if needed). No fabricated local username is used, and an opaque `user_id` is never mislabeled as a human name. - [ ] If the compact label is visually elided, the complete identity remains recoverable through the row's accessibility label/value and a native macOS help affordance; truncation never changes the stored identity. - [ ] The bottom soft edge keeps the account text legible while sidebar content scrolls beneath it, using the transcript's single masked-material gradient technique. - [ ] The pill grows with Dynamic Type and accessibility sizes without clipping the identity or collapsing the row. - [ ] The account row is one accessible element with one coherent label/value; when it is non-interactive it is not focusable and does not advertise an actionable trait.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/hermternal-apple#33
No description provided.