feat: ship agent-first mission control v0.2.57
@@ -0,0 +1,101 @@
|
||||
# Authenticated dashboard design migration audit
|
||||
|
||||
## Outcome
|
||||
|
||||
The dashboard V2 language now covers all 16 other authenticated routes through
|
||||
a shared token source, presentation layer, and aligned legacy shell. Dashboard
|
||||
and Login remain visually unchanged. No product behavior, backend contract,
|
||||
route registration, store/service/composable logic, or permission rule was
|
||||
modified.
|
||||
|
||||
## Implemented layers
|
||||
|
||||
1. Expanded `nexus-tokens.css` into the V2 source for surfaces, text, accents,
|
||||
status colors, focus, typography, page geometry, and legacy aliases.
|
||||
2. Added `nexus-components.css` for route frames, headers, glass panels,
|
||||
controls, badges, modals, and state surfaces.
|
||||
3. Aligned `App.vue`, `AppSidebar`, and `AppHeader` with the dashboard's galaxy,
|
||||
248px sidebar, 62px topbar, glass, and responsive navigation.
|
||||
4. Applied standard, workspace, or reading-width contracts to every migrated
|
||||
route family.
|
||||
5. Replaced presentation emoji/glyph icons with existing Lucide icons and added
|
||||
accessible names, semantic interactive elements, keyboard equivalence, and
|
||||
visible focus.
|
||||
6. Unified both authenticated navigation shells around the four dashboard
|
||||
categories and added a persistent Settings destination to the dashboard
|
||||
footer. Shared-shell and dashboard destinations now use RouterLinks, while
|
||||
detail routes retain the active state of their parent section.
|
||||
|
||||
## Evidence matrix
|
||||
|
||||
| Evidence | Coverage | Result |
|
||||
| --- | --- | --- |
|
||||
| Fresh dashboard reference | `/dashboard`, `1440 × 900` | Passed |
|
||||
| Full desktop route matrix | all 18 registered routes, `1440 × 900` | Passed |
|
||||
| Full migrated mobile matrix | 16 migrated routes, `375 × 812` | Passed |
|
||||
| Representative responsive matrix | 5 route families at `768`, `1024`, `1920px` | Passed |
|
||||
| Automated geometry | document width and route-root geometry | Passed |
|
||||
| Same-viewport visual comparison | dashboard reference beside migrated Agents | Passed |
|
||||
| Core interactions | filters, forms, modal, detail changes, board, chat, notifications | Passed |
|
||||
| Keyboard/accessibility | names, semantics, focus, equivalent activation | Passed |
|
||||
| Frontend gates | typecheck, tests, build | Passed |
|
||||
|
||||
Evidence is under `screenshots/`. The final reference is
|
||||
`screenshots/00-dashboard-reference-1440.png`; route captures are under
|
||||
`screenshots/design-migration-routes/`; and the combined visual comparison is
|
||||
`screenshots/design-qa-comparison-dashboard-vs-agents-1280.png`.
|
||||
|
||||
## Measured contracts
|
||||
|
||||
- Sidebar: `248px` desktop.
|
||||
- Topbar: `62px`.
|
||||
- Page title: Space Grotesk `24px / 30px`, weight `700`.
|
||||
- Desktop/mobile inset: `20px / 14px`.
|
||||
- Maximum route widths: standard `1180px`, workspace `1440px`, reading/form
|
||||
`880px`.
|
||||
- No document-level horizontal overflow at the required breakpoints.
|
||||
- Task Board columns retain their intentional internal horizontal scroller.
|
||||
|
||||
## Findings resolved during QA
|
||||
|
||||
- The inherited 768px shell breakpoint initially hid the sidebar without
|
||||
exposing the mobile navigation button. The shell now switches coherently at
|
||||
`900px`.
|
||||
- Scoped Settings width rules initially overrode the shared reading-width
|
||||
modifier. Higher-specificity shared contracts now enforce `880px` for every
|
||||
reading/form root.
|
||||
- Undefined or ambiguous legacy color aliases and hard-coded route colors were
|
||||
replaced by V2 semantic tokens.
|
||||
- Presentation emoji/glyph icons and unnamed icon controls were replaced with
|
||||
Lucide icons and explicit accessible names.
|
||||
- The shared sidebar initially exposed one flat list and the dashboard omitted
|
||||
Settings. Both shells now expose the same category framework and persistent
|
||||
Settings access without changing routes, handlers, stores, or permissions.
|
||||
- A RouterLink migration initially shadowed each dashboard item's target with
|
||||
the current route. The prop/current-route names are now distinct, and browser
|
||||
checks confirmed the real registered destinations.
|
||||
|
||||
## Residuals
|
||||
|
||||
There are no P0-P2 design defects. A deliberate Task Board route leave aborts
|
||||
the fixture-backed live stream and logs the existing polling-fallback warning.
|
||||
This is outside the presentation scope and does not affect the rendered result
|
||||
or interaction path.
|
||||
|
||||
## Verification
|
||||
|
||||
```text
|
||||
pnpm typecheck -> passed
|
||||
pnpm test -> passed (1 file, 2 tests)
|
||||
pnpm build -> passed (1,882 modules)
|
||||
git diff --check -> passed; line-ending notices only
|
||||
```
|
||||
|
||||
Navigation follow-up evidence:
|
||||
|
||||
```text
|
||||
navigation-groups-after-dashboard.png
|
||||
navigation-groups-after-settings.png
|
||||
navigation-groups-after-settings-375.png
|
||||
navigation-groups-comparison-dashboard-vs-settings-1440.png
|
||||
```
|
||||
@@ -0,0 +1,148 @@
|
||||
# Nexus – Seitenaudit
|
||||
|
||||
**Datum:** 2026-07-26
|
||||
**Commit:** `3bc7622977f4a6c2f2e98ab4aa856a2e45c3cf49`
|
||||
**Auditumfang:** Alle 18 in `frontend/src/router.ts` registrierten Seiten plus
|
||||
ungültige Navigationsziele und sechs Viewport-Größen.
|
||||
|
||||
## Methodik und Evidenzgrenze
|
||||
|
||||
Die Anwendung wurde lokal gebaut und im Browser mit repräsentativen,
|
||||
deterministischen API-Fixtures betrieben. Dadurch konnten Authentifizierung,
|
||||
Routen, Inhalte, Lade-/Leerzustände, Interaktionen und Responsive-Verhalten
|
||||
reproduzierbar geprüft werden.
|
||||
|
||||
Die Fixtures ersetzen keinen Live-Systemtest:
|
||||
|
||||
- keine reale PostgreSQL- oder OpenClaw-Verbindung,
|
||||
- kein produktiver Nginx-/Traefik-Pfad,
|
||||
- SSE absichtlich nicht als Live-Vertrag bewertet,
|
||||
- fixturebedingte Datums- oder Reconnect-Anzeigen gelten nicht als
|
||||
Produktdefekte.
|
||||
|
||||
Jeder Screenshot stammt aus diesem Auditlauf und liegt unter
|
||||
[`screenshots/`](screenshots/).
|
||||
|
||||
## Leitbefunde
|
||||
|
||||
1. **Dashboard ist zwischen 375 und 1024 px nicht nutzbar.** Agent-Cards,
|
||||
Header und Iris-Panel überlappen oder werden abgeschnitten.
|
||||
2. **Bei 768 px greift der mobile Sidebar-Breakpoint noch nicht.** Die feste
|
||||
248-px-Sidebar lässt dem Board nur einen schmalen Restbereich.
|
||||
3. **Zwei UI-Shells erzeugen einen Produktbruch.** Dashboard und restliche
|
||||
Seiten unterscheiden sich in Navigation, Sprache, Dichte, Tokens und
|
||||
Verhalten.
|
||||
4. **Vier Dashboard-Navigationsziele sind nicht registriert.** Der
|
||||
Wildcard-Redirect kaschiert das Problem und zeigt wieder `/dashboard`.
|
||||
5. **Daten nach Login werden nicht zuverlässig initialisiert.** Projects,
|
||||
Models und Activity bleiben bis zum manuellen Refresh leer.
|
||||
6. **Task Board verliert auf kleinen Displays den Gesamtüberblick.** Es zeigt
|
||||
praktisch nur die erste Spalte und erzeugt große leere Höhen.
|
||||
7. **Kontrast und Schriftgrößen sind zu schwach.** Das betrifft besonders
|
||||
Labels, Metadaten, Buttons und sekundäre Texte.
|
||||
|
||||
## Visuelle Kernevidenz
|
||||
|
||||
### Dashboard, Desktop 1440 px
|
||||
|
||||

|
||||
|
||||
### Dashboard, Mobile 375 px
|
||||
|
||||

|
||||
|
||||
### Dashboard, Tablet 768 px
|
||||
|
||||

|
||||
|
||||
### Task Board, Mobile 375 px
|
||||
|
||||

|
||||
|
||||
## Audit pro registrierter Seite
|
||||
|
||||
| Route | Status | Wesentliche Befunde | Evidenz |
|
||||
|---|---|---|---|
|
||||
| `/login` | P1 | Visuell fokussiert, aber sehr dunkel. Bei 320×568 werden oberer Brand-Bereich und untere Inhalte nicht gemeinsam sichtbar; der Flow benötigt Scrollen. | [Desktop](screenshots/01-login-desktop.png), [320 px](screenshots/22-login-mobile-320.png) |
|
||||
| `/dashboard` | P0 | Eigenständige V2-Shell; dichte, überlappende Agent-Topologie; Suche und „Ask Iris“ ohne vollständige Aktion; feste Dashboard-Aktivmarkierung. Zwischen 375 und 1024 px schwer bis vollständig unbrauchbar. | [1440](screenshots/02-dashboard-desktop.png), [375](screenshots/19-dashboard-mobile-375.png), [768](screenshots/23-dashboard-tablet-768.png), [1024](screenshots/24-dashboard-1024.png), [1920](screenshots/25-dashboard-wide-1920.png) |
|
||||
| `/memory` | P2 | Kohärente List-/Detailansicht, aber sehr kleine und kontrastarme Metadaten. Der große leere Detailbereich gibt beim Einstieg wenig Orientierung. | [Desktop](screenshots/03-memory-desktop.png) |
|
||||
| `/docs` | P2 | Such- und Kategorienstruktur sind verständlich. Initial bleibt viel leerer Raum; kein automatisch ausgewähltes Dokument und zu schwache Sekundärtexte. | [Desktop](screenshots/04-docs-desktop.png) |
|
||||
| `/agents/:id` | P1 | Informationsarchitektur ist brauchbar. „Zurück zum Team“ navigiert jedoch zu nicht registriertem `/team` und landet über Wildcard auf dem Dashboard. | [Detail](screenshots/05-agent-detail-desktop.png), [Fehlredirect](screenshots/05b-agent-back-redirect-desktop.png) |
|
||||
| `/security` | P0 | Übersicht ist visuell nachvollziehbar, vermittelt aber mehr Sicherheit als die tatsächliche Controller-Autorisierung bietet. Deaktivierte 2FA und kritische Zugriffslücken sind nicht als Release-Blocker erkennbar. | [Desktop](screenshots/06-security-desktop.png) |
|
||||
| `/incidents` | P2 | Solide List-/Detailstruktur. Kleine Typografie, schwache Statusdifferenzierung und ein großer initial leerer Detailbereich bremsen den Scan. | [Desktop](screenshots/07-incidents-desktop.png) |
|
||||
| `/calendar` | P2 | Termine und Zeitbezug sind gut strukturiert. Refresh und Metadaten sind visuell zu zurückhaltend. | [Desktop](screenshots/08-calendar-desktop.png) |
|
||||
| `/projects` | P1 | Nach normalem Login zunächst leer. Erst manueller Refresh lädt Daten. Geladener ModuleView wirkt weitgehend ungestaltet und nicht wie Teil derselben Anwendung. | [Vor Refresh](screenshots/09-projects-desktop.png), [nach Refresh](screenshots/09b-projects-after-refresh-desktop.png) |
|
||||
| `/projects/:id` | P2 | Klare Stammdaten und Task-Zuordnung. Sehr große Leerflächen; destruktive Archivaktion erhält relativ viel visuelles Gewicht. | [Desktop](screenshots/10-project-detail-desktop.png) |
|
||||
| `/tasks` | P1 | Funktionsreicher Board-Flow, aber fünf Spalten überlaufen bereits auf Desktop. Auf 375 px ist nur eine Spalte plus Restkante sichtbar; keine gute mobile Statusnavigation. | [Desktop](screenshots/11-tasks-desktop.png), [375 px](screenshots/20-task-board-mobile-375.png) |
|
||||
| `/tasks/:id` | P1 | Detail- und Subtask-Struktur sind brauchbar. Existierende Priorität `Critical` erscheint leer, weil die Select-Option fehlt. | [Desktop](screenshots/12-task-detail-desktop.png) |
|
||||
| `/agents` | P2 | Stärkste Legacy-Übersichtsseite: konsistentes Grid und verständliche Rollen. Ganze `article`-Cards sind jedoch clickbar statt semantische Links/Buttons zu verwenden. | [Desktop](screenshots/13-agents-desktop.png) |
|
||||
| `/models` | P1 | Initial leer wegen fehlender Store-Hydration. Nach Refresh inhaltlich vorhanden, aber visuell als roher ModuleView ohne klare Hierarchie. | [Vor Refresh](screenshots/14-models-desktop.png), [nach Refresh](screenshots/14b-models-after-refresh-desktop.png) |
|
||||
| `/activity` | P1 | Dasselbe Hydration-Problem. Geladene Activity ist funktional lesbar, wirkt aber wie eine unvollständige Zwischenansicht. | [Vor Refresh](screenshots/15-activity-desktop.png), [nach Refresh](screenshots/15b-activity-after-refresh-desktop.png) |
|
||||
| `/chat` | P1 | Kernfunktion ist erkennbar, Oberfläche wirkt jedoch unfertig: schwache Hierarchie, rohe Form-Controls und keine belastbare mobile Conversation-Struktur. | [Desktop](screenshots/16-chat-desktop.png) |
|
||||
| `/notifications` | P2 | Filter und Gruppierung sind vorhanden. Kontrast ist schwach; Emoji-Icons brechen die sonstige Icon-Sprache und besitzen uneinheitliche Semantik. | [Desktop](screenshots/17-notifications-desktop.png) |
|
||||
| `/settings` | P2 | Am besten gelöste responsive Legacy-Seite. Formfelder bleiben bei 375 px nutzbar. Globale Topbar-Icons und kleine Labels bleiben Accessibility-Risiken. | [Desktop](screenshots/18-settings-desktop.png), [375 px](screenshots/21-settings-mobile-375.png) |
|
||||
|
||||
## Nicht registrierte oder defekte Ziele
|
||||
|
||||
| Quelle | Ziel | Tatsächliches Verhalten |
|
||||
|---|---|---|
|
||||
| Dashboard-Sidebar | `/orchestration` | Wildcard -> `/dashboard` |
|
||||
| Dashboard-Sidebar | `/research` | Wildcard -> `/dashboard` |
|
||||
| Dashboard-Sidebar | `/hosts` | Wildcard -> `/dashboard` |
|
||||
| Dashboard-Sidebar | `/costs` | Wildcard -> `/dashboard` |
|
||||
| Agent Detail | `/team` | Wildcard -> `/dashboard` |
|
||||
|
||||
`TeamView.vue` existiert, ist aber nicht im Router registriert. Der
|
||||
Wildcard-Redirect macht diese Integrationsfehler für Nutzer schwer
|
||||
diagnostizierbar.
|
||||
|
||||
## Responsive-Matrix
|
||||
|
||||
| Viewport | Ergebnis |
|
||||
|---|---|
|
||||
| 320 px | Login scrollbar und vertikal gequetscht; kein kompakter First-Viewport-Flow |
|
||||
| 375 px | Dashboard P0-defekt; Task Board nur eingeschränkt navigierbar; Settings brauchbar |
|
||||
| 768 px | Schlechtester Dashboard-Zwischenzustand durch Off-by-one-Breakpoint und feste Sidebar |
|
||||
| 1024 px | Dashboard weiterhin überlappend und abgeschnitten |
|
||||
| 1440 px | Grundsätzlich bedienbar, aber Dashboard-Header/Cards kollidieren und Task Board läuft horizontal über |
|
||||
| 1920 px | Dashboard erstmals stabiler, erzeugt jedoch übermäßig viel ungenutzten Raum |
|
||||
|
||||
## Accessibility-Spot-Check
|
||||
|
||||
Keine vollständige WCAG-Prüfung. Sichtbar und im DOM nachvollziehbar:
|
||||
|
||||
- zahlreiche Icon-Buttons ohne Accessible Name,
|
||||
- clickbare `article`-Elemente statt Links oder Buttons,
|
||||
- sehr kleine Textgrößen bis in den einstelligen Pixelbereich,
|
||||
- schwache Kontraste für Text, Controls und Statusinformationen,
|
||||
- horizontale Informationsarchitektur ohne gleichwertige mobile Alternative,
|
||||
- Platzhalter-Controls, deren sichtbare Affordance keine Aktion auslöst.
|
||||
|
||||
## Priorisierte Korrekturen
|
||||
|
||||
### P0
|
||||
|
||||
1. Dashboard zwischen 375 und 1024 px neu layouten; 768-px-Grenze explizit
|
||||
testen.
|
||||
2. Navigation nur aus registrierten Routen erzeugen oder fehlende Seiten
|
||||
bewusst implementieren.
|
||||
3. Security-Seite und Release-Status an die tatsächlichen
|
||||
Zugriffskontrollbefunde koppeln.
|
||||
|
||||
### P1
|
||||
|
||||
1. Eine gemeinsame Shell, Tokenbasis und Navigation für alle Seiten festlegen.
|
||||
2. Operations Store direkt nach erfolgreichem Login hydratisieren.
|
||||
3. Task Board mit mobiler Statusauswahl oder segmentierter Liste statt
|
||||
abgeschnittener Fünf-Spalten-Fläche ausstatten.
|
||||
4. `Critical` im gesamten Priority-Vertrag unterstützen.
|
||||
5. Suche, Ask-Iris, Logout und Back-Navigation entweder funktionsfähig machen
|
||||
oder ihre Affordance entfernen.
|
||||
|
||||
### P2
|
||||
|
||||
1. Standardgrößen und Kontrast anheben.
|
||||
2. Empty-/Loading-/Error-Zustände mit klarer nächster Aktion gestalten.
|
||||
3. Interaktive Cards und Icon-Buttons semantisch und keyboard-tauglich machen.
|
||||
4. Projects, Models, Activity und Chat aus dem generischen ModuleView in
|
||||
kohärente Produktseiten überführen.
|
||||
@@ -0,0 +1,117 @@
|
||||
# Structural proof preflight
|
||||
|
||||
- Product, route, or flow: Nexus authenticated legacy shell and the first migrated grid route, `/agents`
|
||||
- Selected direction or inspected source: `/dashboard`, captured in `screenshots/02-dashboard-desktop.png`
|
||||
- First bounded slice: shared V2 tokens, legacy sidebar/topbar/content frame, and the Agents overview
|
||||
- Explicit exclusions: dashboard and login visuals; route targets; stores, services, API contracts, backend behavior, and domain state transitions
|
||||
- Owner: Codex
|
||||
- Status: passed
|
||||
|
||||
## Entry contract
|
||||
|
||||
- Entry mode: task-first
|
||||
- Minimum context required before the first real action: current route title, gateway state, agent count, and any loading/error warning
|
||||
- Why each preceding block is necessary: the shell orients the user; the route header identifies the operational scope; gateway feedback determines whether agent data is trustworthy
|
||||
- First real action or task-entry control: open an agent profile
|
||||
- Success destination: the existing `/agents/:id` route
|
||||
- Blocked-destination reason and recovery: when no agents are returned, the existing empty state names gateway reachability and configuration as the recovery path
|
||||
|
||||
| Viewport or container | Initial `scrollY` | Identifying context rectangle | Action rectangle | Required reserve | Destination and sticky offset | Settled result |
|
||||
| --- | ---: | --- | --- | ---: | --- | --- |
|
||||
| Narrowest supported / `375px` | 0 | `x=14`, `y=76`, `w=332`; identity and gateway status wrap inside the page frame | first agent card `x=14`, `y=186`, `w=332`; keyboard activation verified | 14px page inset | `/agents/iris`; 62px topbar remains visible | passed; no page or content x-overflow |
|
||||
| Representative wide / `1280px` rendered browser ceiling | 0 | `x=268`, `y=82`, `w=977`; title uses Space Grotesk 24/30, 700 | first agent card `x=268`, `y=161`, `w=316` | 20px page inset | `/agents/iris`; 62px topbar remains visible | passed; 248px sidebar and 62px topbar measured |
|
||||
|
||||
## Section grammar
|
||||
|
||||
| Order | Section | Primary role | User question | Evidence or input | Layout grammar | Density and disclosure | Narrow transformation | State responsibility |
|
||||
| ---: | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| 1 | Legacy shell | orient | Where am I and what can I open? | registered navigation and existing counts | fixed sidebar plus topbar | compact operational chrome | sidebar becomes an overlay | active route, connection status, mobile navigation |
|
||||
| 2 | Route header | orient | Which agent surface and gateway state am I seeing? | agent count and gateway response | title cluster plus status badge | concise | stack and wrap | loading, gateway warning, error |
|
||||
| 3 | Agent grid | act | Which agent should I inspect? | existing agent data | responsive card grid | operational summary per agent | 3 to 2 to 1 columns | runtime state and profile navigation |
|
||||
| 4 | Empty/error message | recover | Why is no agent available and what can I check? | existing error and empty copy | single glass state panel | readable | full-width | diagnostic and next valid check |
|
||||
|
||||
- Accidental preamble removed or justified: no decorative preamble is added before the route identity.
|
||||
- Repeated wrappers or layout grammars that need a product reason: cards are reserved for comparable agents and operational panels.
|
||||
- Evidence kept with its claim: gateway state remains in the route header; runtime state remains inside its agent card.
|
||||
- Actions kept with their object and consequence: profile navigation remains on the corresponding agent card.
|
||||
- Recovery kept in destination context: loading, warning, error, and empty feedback stays inside the Agents page.
|
||||
|
||||
## Signature-gesture distribution
|
||||
|
||||
- Gesture: blue-to-violet gradient with controlled glow
|
||||
- One dominant use: active navigation and primary action
|
||||
- Supporting echo 1: brand mark
|
||||
- Supporting echo 2: a meaningful active or blocked status
|
||||
- Prohibited sections or states: ordinary data cards, neutral inputs, metadata, empty states, long-form copy, and destructive confirmation surfaces
|
||||
- Plain operational, error, and recovery grammar: glass surface, semantic border/status color, no decorative glow
|
||||
|
||||
## Content and type pressure
|
||||
|
||||
| Pressure input | Exact fixture or source | Narrow result | Wide result | Fix or accepted rationale | Status |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Longest heading | existing route titles such as `Notifications` and `Project Detail` | retained at 24/30 and allowed to wrap | retained at 24/30 | wrap rather than shrink below the title contract | passed for the slice |
|
||||
| Longest control label | `Iris, Chief of Staff: View Profile` accessible name | keyboard reachable without changing visual copy | card action remains local to its object | preserve copy; allow action rows to wrap | passed |
|
||||
| Largest value or identifier | `claude-sonnet-4-5` | contained in the card metadata track | contained in the three-column grid | mono text keeps the existing ellipsis policy | passed |
|
||||
| Longest error, limitation, and recovery copy | authored error plus the existing gateway/configuration recovery copy | both wrap inside 332px | state surface remains inside the page frame | full-width glass state panels with natural wrapping | passed |
|
||||
| Required localization | current German and English UI strings | German copy wraps naturally; English labels remain intact | no content rewrite | do not rewrite product copy in this visual migration | passed |
|
||||
| `200%` zoom | represented structurally by the single-column narrow transformation and adjacent breakpoint matrix | no x-overflow | n/a | page remains vertically scrollable; controls wrap | accepted; final responsive matrix passed |
|
||||
| Narrow parent container | 375px required viewport | `scrollWidth=clientWidth=375`; content overflow delta `0` | n/a | `min-width: 0`, safe wrapping, and no page-level x overflow | passed |
|
||||
|
||||
- Important instructions, limitations, provenance, status, safety, consequences, and recovery are at least `14px`: required for final proof.
|
||||
- Any `12px` use is truly secondary and nonessential, with contrast and line-height evidence: reserved for compact interface labels; metadata uses JetBrains Mono at 11px minimum.
|
||||
- Min-content and unbreakable-content policy: content columns use `minmax(0, 1fr)` and `min-width: 0`; identifiers wrap or use an existing internal scroller only on horizontal workspaces.
|
||||
- Risky breakpoints and adjacent widths: 375, 767/768, 1023/1024, 1440, and 1920px.
|
||||
|
||||
## State-and-copy truth table
|
||||
|
||||
| State | Entry cause | Visible facts | Allowed actions | Forbidden stale copy or values | Recovery or next action | Focus target | URL, history, and storage effect |
|
||||
| --- | --- | --- | --- | --- | --- | --- | --- |
|
||||
| Initial/loading | route mounts and requests data | route title and loading message | navigation remains available | stale success state must not be presented as current | wait or navigate elsewhere | route heading | unchanged |
|
||||
| Success | API returns agents and gateway data | count, gateway state, cards, runtime metadata | open an agent, navigate, refresh | loading/error copy | select an agent profile | first actionable card | existing router history only |
|
||||
| Failure | API or gateway request fails | existing diagnostic message | navigate or refresh | stale cards presented as newly loaded | retry through the existing refresh/re-entry path | error message then next control | unchanged |
|
||||
| Recovery/empty | response contains no agents | existing empty-state reason and checks | navigate or re-enter after configuration changes | invented agents or changed recovery copy | check gateway reachability/configuration | empty-state heading | unchanged |
|
||||
|
||||
- Additional orthogonal states required: connected, thinking, blocked, ready, stale, error, unsupported, mobile navigation open/closed, and keyboard focus.
|
||||
- Atomic stale-content removal rule: visual CSS must not change existing state guards or data replacement behavior.
|
||||
- Exact reset or recovery snapshot: current store and component behavior remains the source of truth.
|
||||
|
||||
## Action vocabulary ledger
|
||||
|
||||
| User intent | Idle control | Pending or progress | Success or result | Failure and next action | Recovery, undo, or reversal |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Refresh operational data | Refresh | existing loading/spinner treatment | updated current state | existing error message | invoke Refresh again |
|
||||
| Inspect an agent | View Profile / agent card | route transition | agent detail route | existing route/error behavior | return through existing navigation |
|
||||
|
||||
- Same user-recognized verb and domain noun retained through the journey: yes; no product copy or action is renamed by the visual migration.
|
||||
- Labels, statuses, toasts, confirmations, errors, recovery, and assistive announcements agree: existing strings remain authoritative.
|
||||
- Empty and failure states name the next valid action: existing page copy is preserved and presented accessibly.
|
||||
|
||||
## Proof architecture
|
||||
|
||||
- Stable semantic selectors, state attributes, and dedicated value nodes: route root classes, shell landmarks, existing data/state classes, and `data-route` on the legacy content frame
|
||||
- Assertions intentionally independent of translated copy, neighboring text, wrappers, and visual position: geometry and overflow checks target landmarks and route roots
|
||||
- Explicit settle conditions for scroll, fonts, media, transitions, async state, and geometry: document fonts loaded, fixture/API requests settled, no pending transitions, and two animation frames after route mount
|
||||
- Independent oracle or source of truth: router registration plus the independently authored audit fixture; production stores and API contracts are not modified
|
||||
- Required positive and negative assertions: every registered route renders; no page-level horizontal overflow; dashboard/login source files remain visually untouched; navigation/events/handlers remain registered
|
||||
- Source, build, harness, fixture, oracle, and capture bindings: repository HEAD and working tree, frontend build, local fixture, route matrix, and dated screenshots under this audit folder
|
||||
- Capture claim ledger location: `design-qa.md` and `docs/audits/2026-07-26/DESIGN_MIGRATION_AUDIT.md`
|
||||
- Failure classification: product / harness / evidence / environment
|
||||
|
||||
## Structural slice gate
|
||||
|
||||
| Gate | Narrow evidence | Wide evidence | Independent rendered review | Status |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Entry mode and minimum context remain true | title, count, gateway state, and first agent/action are visible | same hierarchy inside the standard page frame | accepted from rendered captures | passed |
|
||||
| First action is reachable and completely framed | first card is fully framed and opens by Enter | first row is visible above the fold | `/agents/iris` navigation verified | passed |
|
||||
| Section roles and layout grammars remain distinct | shell, identity, grid/state surface remain separate | same roles with three-column grid | accepted | passed |
|
||||
| Signature-gesture budget is respected | gradient is limited to active navigation, brand/primary action, and card identity accents | ordinary panels remain plain glass | accepted | passed |
|
||||
| Long content, localization, and min-content pressure pass | long descriptions, model IDs, tags, and recovery copy wrap without x-overflow | three-column content remains contained | accepted for bounded slice | passed |
|
||||
| Core path passes success, failure, and recovery | success grid, empty recovery, and API error were rendered | success grid rendered | fixture states captured independently | passed |
|
||||
| Focus, state copy, controls, and recovery agree | focused agent card measured with 2px blue outline and 2px offset | keyboard Enter opened the existing destination | accepted | passed |
|
||||
| Proof selectors, settle conditions, negatives, oracle, and capture binding pass | `data-route`, route root, landmark geometry, authored fixture, and dated captures recorded | same | typecheck passed; dashboard/login source files untouched | passed |
|
||||
|
||||
- Automated result: candidate
|
||||
- Independent rendered-review result: accepted
|
||||
- Defects and classification: the initial comparison host was capped at 1280px; exact 1440px route checks and 1920px family checks were completed separately and passed.
|
||||
- Contract corrections: moved the gateway chip below the identity cluster on narrow screens; kept all recovery copy in glass state panels; added keyboard-equivalent link semantics to agent cards.
|
||||
- Expansion decision: proceed
|
||||
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 63 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 1.1 MiB |