Skip to content

Commit f25e198

Browse files
KSemenenkoclaude
andcommitted
Unify the console and site on one light KeyLoad identity
ADR-053: a canonical brand.css and logo.svg in the console assets, mirrored byte-for-byte to the site and guarded by a SiteTests parity test. The light console groups monitoring, data and infrastructure views with real-session charts, a bounded server failure log, catalog categories, an RF3 voter figure from configured membership and disk usage. The site adopts the same tokens, logo, typography and palette while keeping every tested hook and budget. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent f627d4b commit f25e198

35 files changed

Lines changed: 753 additions & 319 deletions
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# ADR-053: one light KeyLoad visual identity for the console and the site
2+
3+
Status: Accepted. Date: 2026-10-02. Owner: KeyLoad lead. Related: REQ-AD-008..010 / AC-AD-008..010 ([AdminDashboard](../Features/AdminDashboard.md)), REQ-BC-029 / AC-BC-029 ([BenchmarkComparisons](../Features/BenchmarkComparisons.md)), ADR-040 site design, ADR-051 admin console.
4+
5+
## Context
6+
7+
The owner rejected the visuals of both surfaces:
8+
- The runtime console (`/admin`) used a dark mint theme, a text monogram and a single polyline chart.
9+
- The public site used a warm-paper/forest editorial style with serif display type.
10+
11+
The two surfaces shared no logo, palette, typography or components, so KeyLoad read as two unrelated products. The owner asked for:
12+
- one style across both surfaces, starting with a simple, clear, light and attractive console;
13+
- clear charts;
14+
- convenient menus and categories;
15+
- error logs, data volume, performance and nodes.
16+
17+
## Decision
18+
19+
- **One brand source.** `src/KeyLoad.Server/Features/AdminDashboard/Assets/brand.css` holds the tokens (surfaces, ink, brand blue/indigo gradient, reserved status colours, the dataviz-validated categorical chart order, radii, shadows, focus ring and system font stacks) and the shared primitives (`kl-brand`, `kl-btn`, `kl-card`, `kl-badge`, `kl-chip`, reduced motion).
20+
- The logo `logo.svg` is a rounded indigo→blue tile with a "K" whose stem is three stacked replica blocks (RF3) and whose arms form a forward chevron.
21+
- `site/Features/BenchmarkComparisons/brand.css` and `site/favicon.svg` are byte-identical mirrors.
22+
- The SiteTests drift test `AC_VI_001` fails on any difference. Both surfaces keep their own CSP-compatible, same-origin delivery: the console whitelists embedded assets, and the site build copies listed assets.
23+
- **Light only.** System fonts only. No external fonts or CDNs. The console CSP is unchanged: styles and scripts are same-origin and SVG is drawn through DOM APIs. Dynamic geometry uses CSSOM properties only.
24+
- **Console information architecture.**
25+
- **Monitoring:**
26+
- Overview: KPI tiles with sparklines, a stacked request-activity chart, a storage donut, a node card, admission and recent errors.
27+
- Performance: throughput, latency and error-rate charts, lifetime totals and admission meters.
28+
- Errors & logs: the server failure log with status filters, plus session events.
29+
- **Data:** Catalog with kind chips, Collections, Queues and Blob storage.
30+
- **Infrastructure:** Nodes (RF3 voter figure and details) and Disk usage (category bar and largest files).
31+
- Every original `data-view` and pinned browser hook is preserved.
32+
- **Real data only.** Charts plot at most 120 comparable session samples and reset on process change, failure or reconnect. The error log is a new bounded server observation: `AdminHttpSnapshot.RecentFailures`, at most 50 newest-first entries holding the route template, normalised method, status, aborted flag and duration. It never holds a raw path, query, payload or credential.
33+
- The voter figure uses configured membership (`AdminNodeSnapshot.LocalVoter`, `Voters`) and the reported leader. Peers are labelled as not observed from the executing node.
34+
- **Site.** The site gets the same tokens, logo, sans display type, cards, buttons, tabs, bars and tables. Engine colours and the Three.js scene colours move to the brand palette. All site hooks, budgets and lifecycle contracts are unchanged.
35+
36+
```mermaid
37+
flowchart LR
38+
Brand[brand.css and logo.svg canonical in console Assets] --> Console[admin console embedded whitelist]
39+
Brand -->|byte identical mirror| Site[site brand.css and favicon.svg]
40+
Drift[SiteTests AC_VI_001 parity] --> Site
41+
Drift --> Brand
42+
Server[AdminHttpMetrics ring of 50 failures] --> Snapshot[AdminNodeSnapshot]
43+
Config[Replica voter membership] --> Snapshot
44+
Snapshot --> Console
45+
```
46+
47+
## Alternatives
48+
49+
- Restyle each surface separately. Rejected because drift returns.
50+
- A shared npm or MSBuild design package. Rejected: it adds tooling and dependencies, the Docker context holds only `src/`, and the site build is a separate pipeline.
51+
- Inline the logo into each page. Rejected because the favicon and logo bytes must stay one fact.
52+
53+
## Implementation contract
54+
55+
1. **VI-L (lead):** brand tokens and logo, mirrored to the site. Done before the UI packets.
56+
2. **VI-B (worker, sonnet):** ring buffer and middleware in `src/KeyLoad.Server/Features/AdminDashboard/AdminHttp*.cs`, with unit tests `AdminHttpMetricsTests` and `AdminHttpMetricsMiddlewareTests` written first. The DTO is frozen by the lead in Abstractions.
57+
3. **VI-D (lead):** console `Assets/*` and the `AdminStaticAssets` whitelist. The lead also adds the voter membership fields and observer, and owns the `AdminDashboardRf3Tests` assertions.
58+
4. **VI-S (lead):** site HTML/CSS/poster, colour constants in `measurements.mjs` and `scene-geometry.mjs`, `BUILD.assets` and SiteTests parity.
59+
5. **VI-J (lead):** feature docs, this ADR, the Architecture map and exact-SHA CI evidence.
60+
61+
Dependencies:
62+
- Contract additions are additive init properties with defaults. The SDK and the official MCP output pick them up from the DTO type.
63+
- No schema, storage, routing or package change.
64+
65+
Migration, rollback and verification:
66+
- **Rollout:** a single release. The console and the site deploy independently.
67+
- **Rollback:** revert the assets and remove the three init properties. Stored data is untouched.
68+
- **Verification:**
69+
- ci.yml unit tests: metrics ring and middleware.
70+
- RF3: failure-log route template and voter membership through the real SDK and official MCP.
71+
- Real Chrome console flow: existing hooks plus new views.
72+
- pages.yml SiteTests: unchanged hooks, budgets and the parity test.
73+
- Subjective beauty is judged from desktop/mobile screenshots of a real RF3 cluster (manual exception). It never replaces a functional gate.
74+
75+
Join points: shared enum/DTO edits are lead-only, and backend and UI write scopes are disjoint. This ADR stays Accepted until exact-SHA unit, RF3 browser and site qualification pass.

‎docs/ADR/README.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,10 @@ Full coverage/verification: [catalog](../implementation/documentation-coverage.j
8383
library and existing typed executable boundary required by BenchmarkDotNet's real
8484
generated external consumer. REQ-BC-022/AC-EM-001..004 include complete source/lifetime
8585
and GitHub TUnit/Dry qualification; implementation and exact-SHA proof are pending.
86+
87+
[ADR-053](ADR-053-unified-visual-identity.md) accepts one light KeyLoad identity shared by the `/admin` console and the public site:
88+
- a canonical `brand.css` and `logo.svg` with byte-identical site mirrors and a SiteTests drift gate;
89+
- a bounded server failed-request log;
90+
- configured voter membership for the console's node view.
91+
92+
REQ/AC-AD-008..010 and REQ/AC-BC-029 apply. Exact-SHA qualification is pending.

‎docs/Architecture.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# KeyLoad architecture and ownership map
22

3-
The additive [AdminDashboard](Features/AdminDashboard.md) slice under [ADR-051](ADR/ADR-051-admin-dashboard.md) hosts the runtime read-only console in `src/KeyLoad.Server/Features/AdminDashboard/Assets/`, with shared Abstractions DTOs, Core catalog/queue readers, matching Client SDK and UnitTests/IntegrationTests slices. It borrows the existing unique Orleans request/read actors and node-local administration; physical observations are explicitly per node. The public benchmark `site/` remains its own surface. Exact-SHA dashboard unit/RF3/native browser cases pass and retained desktop/mobile images are visually reviewed; complete recovery/comparison and numeric coverage qualification remains open.
3+
The additive [AdminDashboard](Features/AdminDashboard.md) slice under [ADR-051](ADR/ADR-051-admin-dashboard.md) hosts the runtime read-only console in `src/KeyLoad.Server/Features/AdminDashboard/Assets/`, with shared Abstractions DTOs, Core catalog/queue readers, matching Client SDK and UnitTests/IntegrationTests slices. It borrows the existing unique Orleans request/read actors and node-local administration; physical observations are explicitly per node. The public benchmark `site/` remains its own surface. Both surfaces share one light visual identity under [ADR-053](ADR/ADR-053-unified-visual-identity.md): the console owns the canonical `brand.css`/`logo.svg`, and the site keeps byte-identical mirrors checked by SiteTests. Exact-SHA dashboard unit/RF3/native browser cases pass and retained desktop/mobile images are visually reviewed; complete recovery/comparison and numeric coverage qualification remains open.
44

55
```mermaid
66
flowchart LR

‎docs/Features/AdminDashboard.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ This is the durable requirements and acceptance contract. Architecture and the o
1313
| REQ-AD-005 non-consuming queue counters/metadata | AC-AD-005 | AdminQueueTests, AdminDashboardRf3Tests |
1414
| REQ-AD-006 accessible responsive usable administration console | AC-AD-006 | AdminDashboardBrowserTests and explicit subjective screenshot review |
1515
| REQ-AD-007 integrated .NET/official MCP callers and honest qualification | AC-AD-007 | MCP inventory and RF3 tests; canonical GitHub gates |
16+
| REQ-AD-008 bounded failed-request log for operators | AC-AD-008 | AdminHttpMetricsTests, AdminHttpMetricsMiddlewareTests, AdminDashboardRf3Tests |
17+
| REQ-AD-009 configured voter membership for the node view | AC-AD-009 | AdminDashboardRf3Tests (SDK and official MCP) |
18+
| REQ-AD-010 light console in the shared KeyLoad identity (ADR-053) | AC-AD-010 | AdminDashboardBrowserTests, SiteBrandParityTests; desktop/mobile review |
1619

1720
```mermaid
1821
flowchart LR
@@ -61,6 +64,19 @@ Actors: an operator with a current persisted administrator principal, an unautho
6164
- **AC-AD-006 / REQ-AD-006**: console provides coherent sidebar navigation (overview, collections, queues, files, cluster), readable metric cards and measured throughput plot, scope controls, manual refresh and bounded automatic refresh, paginated tables, document JSON details, empty/loading/unauthorized/disconnected/error states. Desktop and 390 px mobile layouts fit without page overflow; keyboard navigation, visible focus, labels, status announcements and reduced-motion behavior work. Disconnect clears credential and all sensitive DOM/history; one in-flight refresh per session and abort/epoch handling prevent stale post-disconnect renders. Background tabs suspend polling; overlapping polls cannot accumulate.
6265
- **AC-AD-007 / REQ-AD-007**: all three new reads are available through typed .NET SDK and explicit official MCP catalog/agent gateway with read-only/nondestructive hints and unchanged prior operation semantics. TUnit/Microsoft.Testing.Platform regressions use actual file-backed stores and actual Docker/Aspire RF3 + real .NET/official MCP clients; browser tests use the real server/browser, no mocked API or doubles. Exact-SHA GitHub build/format/analyzer/governance/unit/recovery/RF3/browser receipts and artifacts must exist before qualification is claimed. Required coverage thresholds stay mandatory; absent collector/result is an open gate, not success.
6366

67+
- **AC-AD-008 / REQ-AD-008**: `AdminHttpSnapshot.RecentFailures` keeps the newest 50 failed `/v1` and `/mcp` requests (status ≥ 400, aborted or faulted), newest first. Each entry holds the completion time, normalised method (unknown methods become `OTHER`), matched route template (or `unmatched`), status, aborted flag and duration.
68+
- It never holds a raw path, query, payload, header or credential.
69+
- Successful and excluded (dashboard polling, admission, status, static, health) requests are never logged.
70+
- The log resets with the process. The Errors view filters 4xx/5xx/aborted and clears on disconnect.
71+
- **AC-AD-009 / REQ-AD-009**: the snapshot carries the executing voter identity (`LocalVoter`) and configured membership (`Voters`), comparable with `Node.Leader`.
72+
- The Nodes view draws the executing node, the leader and the remaining peers, and labels peers as not observed from this node. Membership never implies peer health.
73+
- **AC-AD-010 / REQ-AD-010**: the console uses the shared brand (ADR-053) in a light theme with grouped navigation:
74+
- Monitoring: overview, performance, errors.
75+
- Data: catalog, collections, queues, blob storage.
76+
- Infrastructure: nodes, disk usage.
77+
- It also has KPI sparklines, stacked request activity with a crosshair tooltip, a storage donut, admission meters, catalog kind chips (page counts, never totals) and a disk category bar with largest files.
78+
- All AC-AD-006 hooks and behaviours stay intact. No horizontal overflow at 1440 and 390 px. A mobile menu toggle exposes `aria-expanded`.
79+
6480
## Criterion-to-test matrix
6581

6682
| Criteria | Planned test/level | Assertions and verification |
@@ -72,6 +88,9 @@ Actors: an operator with a current persisted administrator principal, an unautho
7288
| 005 | AdminQueueTests / real store; AdminDashboardRf3Tests | empty and populated lanes, metadata pagination, state/counter/read-position unchanged; CI unit + RF3 |
7389
| 006 | AdminDashboardBrowserTests / real RF3 + actual headless browser | navigation, credential disconnect, empty/error/loading, document viewing, viewport overflow, keyboard; CI RF3 browser; manual visual inspection adds design evidence only |
7490
| 007 | MCP catalog unit assertions + AdminDashboardRf3Tests | tool inventory/shapes/hints, real SDK/MCP agreement and auth failure; all canonical CI gates |
91+
| 008 | AdminHttpMetricsTests, AdminHttpMetricsMiddlewareTests / unit; AdminDashboardRf3Tests / RF3 | bound, order, exact fields, template-not-path, exclusions, real SDK failure appears; CI unit + RF3 |
92+
| 009 | AdminDashboardRf3Tests / RF3 SDK and official MCP | three distinct voters, local voter and leader are members, SDK and MCP agree; CI RF3 |
93+
| 010 | AdminDashboardBrowserTests / real Chrome; SiteBrandParityTests / pages | navigation across all nine views, overflow, reduced motion, brand parity; screenshots reviewed |
7594

7695
Manual exception: subjective visual polish is inspected via desktop/mobile screenshots; it does not replace functional browser or numeric coverage qualification. Migration is additive, with no persisted schema changes or dependencies. Rollback removes this slice's routes/assets/client methods/read enum additions in a coordinated release; existing wire enum numbers remain stable. ADR-051 defines the implementation contract. Unknown SMID mapping and separate Orleans Streams qualification remain visible independent workstreams.
7796

‎docs/Features/BenchmarkComparisons.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,3 +236,20 @@ real Chrome evidence is required, with every existing oracle and numeric gate.
236236
The live responsive product page includes the bounded independent Three.js scene, accessible charts/tables, workload/metric/repetition controls and exact JSON/CSV/Markdown downloads. Current published measurements are the authentic successful comparison36926803549 at9c570f8c33a7a9667507a8e1c0ca68860de3be45; failed current producer37013008931 supplies no new results. Website/control/measured revisions and run/job/artifact hashes remain distinct. Every performance number is derived from these raw reports; unsupported values stay unavailable.
237237

238238
Pages at https://www.keyload.cloud/ uses enforced HTTPS; live apex redirects301 to www. Both automatic triggers, current-main/evidence freshness, immutable Pages35-file output and all9 raw-report bytes were verified. Manual mobile/desktop/WebGPU review complements real Chrome qualification; physical GPU-loss qualification remains explicitly unexercised. The feature's global status, BC001–010/019–023/026, schema3/advanced profiles and database/endurance/readiness qualification remain unchanged.
239+
240+
241+
## REQ-BC-029: shared KeyLoad visual identity
242+
243+
- **AC-BC-029:** the public site uses the shared light identity from [ADR-053](../ADR/ADR-053-unified-visual-identity.md):
244+
- the same logo, tokens and sans display type, plus cards, buttons, tabs, bars and tables;
245+
- brand-palette engine colours and scene colours.
246+
- `site/Features/BenchmarkComparisons/brand.css` and `site/favicon.svg` are byte-identical mirrors of the console's canonical `brand.css` and `logo.svg`. The test is `SiteBrandParityTests.AC_VI_001_SiteAndConsoleShareByteIdenticalBrandSources` in pages.yml.
247+
- Every existing site hook, the size budgets, no-overflow widths, poster/scene lifecycle, zero console errors and the JS inventory remain unchanged. Copy keeps the early-development and no-winner wording.
248+
- Subjective visual quality is a desktop/mobile screenshot review. It is not a numeric gate.
249+
250+
```mermaid
251+
flowchart LR
252+
Canonical[Console brand.css and logo.svg] -->|mirror| SiteBrand[site brand.css and favicon.svg]
253+
SiteBrand --> Pages[Pages build BUILD.assets]
254+
Parity[SiteBrandParityTests] --> SiteBrand
255+
```

0 commit comments

Comments
 (0)