diff --git a/agents/clay/musings/dashboard-implementation-spec.md b/agents/clay/musings/dashboard-implementation-spec.md new file mode 100644 index 00000000..7e6e8eb4 --- /dev/null +++ b/agents/clay/musings/dashboard-implementation-spec.md @@ -0,0 +1,423 @@ +--- +type: musing +agent: clay +title: "Dashboard implementation spec — build contract for Oberon" +status: developing +created: 2026-04-01 +updated: 2026-04-01 +tags: [design, dashboard, implementation, oberon, visual] +--- + +# Dashboard Implementation Spec + +Build contract for Oberon. Everything here is implementation-ready — copy-pasteable tokens, measurable specs, named components with data shapes. Design rationale is in the companion diagnostics-dashboard-visual-direction musing (shipping with this PR); this file is the what, not the why. + +--- + +## 1. Design Tokens (CSS Custom Properties) + +```css +:root { + /* ── Background ── */ + --bg-primary: #0D1117; + --bg-surface: #161B22; + --bg-elevated: #1C2128; + --bg-overlay: rgba(13, 17, 23, 0.85); + + /* ── Text ── */ + --text-primary: #E6EDF3; + --text-secondary: #8B949E; + --text-muted: #484F58; + --text-link: #58A6FF; + + /* ── Borders ── */ + --border-default: #21262D; + --border-subtle: #30363D; + + /* ── Activity type colors (semantic — never use these for decoration) ── */ + --color-extract: #58D5E3; /* Cyan — pulling knowledge IN */ + --color-new: #3FB950; /* Green — new claims */ + --color-enrich: #D4A72C; /* Amber — strengthening existing */ + --color-challenge: #F85149; /* Red-orange — adversarial */ + --color-decision: #A371F7; /* Violet — governance */ + --color-community: #6E7681; /* Muted blue — external input */ + --color-infra: #30363D; /* Dark grey — ops */ + + /* ── Brand ── */ + --color-brand: #6E46E5; + --color-brand-muted: rgba(110, 70, 229, 0.15); + + /* ── Agent colors (for sparklines, attribution dots) ── */ + --agent-leo: #D4AF37; + --agent-rio: #4A90D9; + --agent-clay: #9B59B6; + --agent-theseus: #E74C3C; + --agent-vida: #2ECC71; + --agent-astra: #F39C12; + + /* ── Typography ── */ + --font-mono: 'JetBrains Mono', 'IBM Plex Mono', 'Fira Code', monospace; + --font-size-xs: 10px; + --font-size-sm: 12px; + --font-size-base: 14px; + --font-size-lg: 18px; + --font-size-hero: 28px; + --line-height-tight: 1.2; + --line-height-normal: 1.5; + + /* ── Spacing ── */ + --space-1: 4px; + --space-2: 8px; + --space-3: 12px; + --space-4: 16px; + --space-5: 24px; + --space-6: 32px; + --space-8: 48px; + + /* ── Layout ── */ + --panel-radius: 6px; + --panel-padding: var(--space-5); + --gap-panels: var(--space-4); +} +``` + +--- + +## 2. Layout Grid + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ HEADER BAR (48px fixed) │ +│ [Teleo Codex] [7d | 30d | 90d | all] [last sync] │ +├───────────────────────────────────────┬─────────────────────────────┤ +│ │ │ +│ TIMELINE PANEL (60%) │ SIDEBAR (40%) │ +│ Stacked bar chart │ │ +│ X: days, Y: activity count │ ┌─────────────────────┐ │ +│ Color: activity type │ │ AGENT ACTIVITY (60%) │ │ +│ │ │ Sparklines per agent │ │ +│ Phase overlay (thin strip above) │ │ │ │ +│ │ └─────────────────────┘ │ +│ │ │ +│ │ ┌─────────────────────┐ │ +│ │ │ HEALTH METRICS (40%)│ │ +│ │ │ 4 key numbers │ │ +│ │ └─────────────────────┘ │ +│ │ │ +├───────────────────────────────────────┴─────────────────────────────┤ +│ EVENT LOG (collapsible, 200px default height) │ +│ Recent PR merges, challenges, milestones — reverse chronological │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### CSS Grid Structure + +```css +.dashboard { + display: grid; + grid-template-rows: 48px 1fr auto; + grid-template-columns: 60fr 40fr; + gap: var(--gap-panels); + height: 100vh; + padding: var(--space-4); + background: var(--bg-primary); + font-family: var(--font-mono); + color: var(--text-primary); +} + +.header { + grid-column: 1 / -1; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0 var(--space-4); + border-bottom: 1px solid var(--border-default); +} + +.timeline-panel { + grid-column: 1; + grid-row: 2; + background: var(--bg-surface); + border-radius: var(--panel-radius); + padding: var(--panel-padding); + overflow: hidden; +} + +.sidebar { + grid-column: 2; + grid-row: 2; + display: flex; + flex-direction: column; + gap: var(--gap-panels); +} + +.event-log { + grid-column: 1 / -1; + grid-row: 3; + background: var(--bg-surface); + border-radius: var(--panel-radius); + padding: var(--panel-padding); + max-height: 200px; + overflow-y: auto; +} +``` + +### Responsive Breakpoints + +| Viewport | Layout | +|----------|--------| +| >= 1200px | 2-column grid as shown above | +| 768-1199px | Single column: timeline full-width, agent panel below, health metrics inline row | +| < 768px | Skip — this is an ops tool, not designed for mobile | + +--- + +## 3. Component Specs + +### 3.1 Timeline Panel (stacked bar chart) + +**Renders:** One bar per day. Segments stacked by activity type. Height proportional to daily activity count. + +**Data shape:** +```typescript +interface TimelineDay { + date: string; // "2026-04-01" + extract: number; // count of extraction commits + new_claims: number; // new claim files added + enrich: number; // existing claims modified + challenge: number; // challenge claims or counter-evidence + decision: number; // governance/evaluation events + community: number; // external contributions + infra: number; // ops/config changes +} +``` + +**Bar rendering:** +- Width: `(panel_width - padding) / days_shown` with 2px gap between bars +- Height: proportional to sum of all segments, max bar = panel height - 40px (reserve for x-axis labels) +- Stack order (bottom to top): infra, community, extract, new_claims, enrich, challenge, decision +- Colors: corresponding `--color-*` tokens +- Hover: tooltip showing date + breakdown + +**Phase overlay:** 8px tall strip above the bars. Color = phase. Phase 1 (bootstrap): `var(--color-brand-muted)`. Future phases TBD. + +**Time range selector:** 4 buttons in header area — 7d | 30d | 90d | all. Default: 30d. Active button: `border-bottom: 2px solid var(--color-brand)`. + +**Annotations:** Vertical dashed line at key events (e.g., "first external contribution"). Label rotated 90deg, `var(--text-muted)`, `var(--font-size-xs)`. + +### 3.2 Agent Activity Panel + +**Renders:** One row per agent, sorted by total activity last 7 days (most active first). + +**Data shape:** +```typescript +interface AgentActivity { + name: string; // "rio" + display_name: string; // "Rio" + color: string; // var(--agent-rio) resolved hex + status: "active" | "idle"; // active if any commits in last 24h + sparkline: number[]; // 7 values, one per day (last 7 days) + total_claims: number; // lifetime claim count + recent_claims: number; // claims this week +} +``` + +**Row layout:** +``` +┌───────────────────────────────────────────────────────┐ +│ ● Rio ▁▂▅█▃▁▂ 42 (+3) │ +└───────────────────────────────────────────────────────┘ +``` + +- Status dot: 8px circle, `var(--agent-*)` color if active, `var(--text-muted)` if idle +- Name: `var(--font-size-base)`, `var(--text-primary)` +- Sparkline: 7 bars, each 4px wide, 2px gap, max height 20px. Color: agent color +- Claim count: `var(--font-size-sm)`, `var(--text-secondary)`. Delta in parentheses, green if positive + +**Row styling:** +```css +.agent-row { + display: flex; + align-items: center; + gap: var(--space-3); + padding: var(--space-2) var(--space-3); + border-radius: 4px; +} +.agent-row:hover { + background: var(--bg-elevated); +} +``` + +### 3.3 Health Metrics Panel + +**Renders:** 4 metric cards in a 2x2 grid. + +**Data shape:** +```typescript +interface HealthMetrics { + total_claims: number; + claims_delta_week: number; // change this week (+/-) + active_domains: number; + total_domains: number; + open_challenges: number; + unique_contributors_month: number; +} +``` + +**Card layout:** +``` +┌──────────────────┐ +│ Claims │ +│ 412 +12 │ +└──────────────────┘ +``` + +- Label: `var(--font-size-xs)`, `var(--text-muted)`, uppercase, `letter-spacing: 0.05em` +- Value: `var(--font-size-hero)`, `var(--text-primary)`, `font-weight: 600` +- Delta: `var(--font-size-sm)`, green if positive, red if negative, muted if zero + +**Card styling:** +```css +.metric-card { + background: var(--bg-surface); + border: 1px solid var(--border-default); + border-radius: var(--panel-radius); + padding: var(--space-4); +} +``` + +**The 4 metrics:** +1. **Claims** — `total_claims` + `claims_delta_week` +2. **Domains** — `active_domains / total_domains` (e.g., "4/14") +3. **Challenges** — `open_challenges` (red accent if > 0) +4. **Contributors** — `unique_contributors_month` + +### 3.4 Event Log + +**Renders:** Reverse-chronological list of significant events (PR merges, challenges filed, milestones). + +**Data shape (reuse from extract-graph-data.py `events`):** +```typescript +interface Event { + type: "pr-merge" | "challenge" | "milestone"; + number?: number; // PR number + agent: string; + claims_added: number; + date: string; +} +``` + +**Row layout:** +``` +2026-04-01 ● rio PR #2234 merged — 3 new claims (entertainment) +2026-03-31 ● clay Challenge filed — AI acceptance scope boundary +``` + +- Date: `var(--font-size-xs)`, `var(--text-muted)`, fixed width 80px +- Agent dot: 6px, agent color +- Description: `var(--font-size-sm)`, `var(--text-secondary)` +- Activity type indicator: left border 3px solid, activity type color + +--- + +## 4. Data Pipeline + +### Primary Source: Argus API (live) + +The dashboard fetches data from Argus API endpoints at `:8081`. These already serve the data the components need: + +| Component | Argus Endpoint | Notes | +|-----------|---------------|-------| +| Timeline Panel | `GET /api/snapshots?days=N` | Time-series: throughput, approval rate, rejection categories | +| Agent Activity | `GET /api/agents-dashboard` + `GET /api/yield?weeks=N` | Per-agent claims merged 7d/30d, quality scores, extraction yield | +| Health Metrics | `GET /api/vital-signs` | Orphan ratio, linkage density, confidence distribution, domain activity | +| Event Log | `GET /api/metrics` | Status map, throughput, rejection reasons | + +All endpoints are public (no auth), return JSON. Full schemas available from Argus. + +**Data aggregation layer** (`dashboard.js`): The component data shapes from Section 3 don't map 1:1 to API responses. The JS layer transforms API responses into component interfaces: + +```typescript +interface DashboardData { + generated: string; // ISO timestamp + timeline: TimelineDay[]; // from /api/snapshots + agents: AgentActivity[]; // from /api/agents-dashboard + /api/yield + health: HealthMetrics; // from /api/vital-signs + events: Event[]; // from /api/metrics + phase: { current: string; since: string; }; +} +``` + +### Fallback: Static JSON (offline/export) + +For screenshot export mode and offline use, a static `dashboard-data.json` can be generated by extending `ops/extract-graph-data.py` with a `--dashboard` flag. This produces the same `DashboardData` shape from git history analysis. The dashboard checks for API availability first; if Argus is unreachable, it falls back to the static JSON. + +### Deployment + +API-primary: dashboard fetches from Argus on page load. Static JSON generated on push to main as fallback (same CI workflow that syncs graph-data.json to teleo-app). + +--- + +## 5. Tech Stack + +| Choice | Rationale | +|--------|-----------| +| **Static HTML + vanilla JS** | Single page, no routing, no state management needed. No build step — JS fetches from Argus API on load. | +| **CSS Grid + custom properties** | Layout and theming covered by the tokens above. No CSS framework. | +| **Chart rendering** | Chart.js 4.4.6 via CDN (already used by Argus diagnostics dashboard). Handles tooltips, animations, responsive canvas. | +| **Font** | JetBrains Mono via Google Fonts CDN. Fallback: system monospace. | +| **Dark mode only** | No toggle. `background: var(--bg-primary)` on body. | + +--- + +## 6. File Structure + +``` +dashboard/ +├── index.html # Single page +├── style.css # All styles (tokens + layout + components) +├── dashboard.js # API fetch, transform, render +└── data/ # Static fallback (generated by CI) + └── dashboard-data.json +``` + +Or integrate into teleo-app if Oberon prefers — the tokens and components work in any context. + +--- + +## 7. Screenshot/Export Mode + +For social media use (the dual-use case from the visual direction musing): + +- A `?export=timeline` query param renders ONLY the timeline panel at 1200x630px (Twitter card size) +- A `?export=agents` query param renders ONLY the agent sparklines at 800x400px +- White-on-dark, no chrome, no header — just the data visualization +- These URLs can be screenshotted by a cron job for automated social posts + +--- + +## 8. What This Does NOT Cover + +- **Homepage graph + chat** — separate spec (homepage-visual-design.md), separate build +- **Claim network visualization** — force-directed graph for storytelling, separate from ops dashboard +- **Real-time updates** — static JSON is sufficient for current update frequency (~hourly) +- **Authentication** — ops dashboard is internal, served behind VPN or localhost + +--- + +## 9. Acceptance Criteria + +Oberon ships this when: +1. Dashboard loads from Argus API (with static JSON fallback) and renders all 4 panels +2. Time range selector switches between 7d/30d/90d/all +3. Agent sparklines render and sort by activity +4. Health metrics show current counts with weekly deltas +5. Event log shows last 50 events reverse-chronologically +6. Passes WCAG AA contrast ratios on all text (the token values above are pre-checked) +7. Screenshot export mode produces clean 1200x630 timeline images + +--- + +→ FLAG @oberon: This is the build contract. Everything above is implementation-ready. Questions about design rationale → see the companion diagnostics-dashboard-visual-direction musing. Questions about data pipeline → Argus API is the primary source (Section 4); static JSON fallback extends extract-graph-data.py. + +→ FLAG @leo: Spec complete. Covers tokens, grid, components, data pipeline, tech stack, acceptance criteria. This should unblock Oberon's frontend work. diff --git a/agents/clay/musings/diagnostics-dashboard-visual-direction.md b/agents/clay/musings/diagnostics-dashboard-visual-direction.md new file mode 100644 index 00000000..e6b834bc --- /dev/null +++ b/agents/clay/musings/diagnostics-dashboard-visual-direction.md @@ -0,0 +1,155 @@ +--- +type: musing +agent: clay +title: "Diagnostics dashboard visual direction" +status: developing +created: 2026-03-25 +updated: 2026-03-25 +tags: [design, visual, dashboard, communication] +--- + +# Diagnostics Dashboard Visual Direction + +Response to Leo's design request. Oberon builds, Argus architects, Clay provides visual direction. Also addresses Cory's broader ask: visual assets that communicate what the collective is doing. + +--- + +## Design Philosophy + +**The dashboard should look like a Bloomberg terminal had a baby with a git log.** Dense, operational, zero decoration — but with enough visual structure that patterns are legible at a glance. The goal is: Cory opens this, looks for 3 seconds, and knows whether the collective is healthy, where activity is concentrating, and what phase we're in. + +**Reference points:** +- Bloomberg terminal (information density, dark background, color as data) +- GitHub contribution graph (the green squares — simple, temporal, pattern-revealing) +- Grafana dashboards (metric panels, dark theme, no wasted space) +- NOT: marketing dashboards, Notion pages, anything with rounded corners and gradients + +--- + +## Color System + +Leo's suggestion (blue/green/yellow/red/purple/grey) is close but needs refinement. The problem with standard rainbow palettes: they don't have natural semantic associations, and they're hard to distinguish for colorblind users (~8% of men). + +### Proposed Palette (dark background: #0D1117) + +| Activity Type | Color | Hex | Rationale | +|---|---|---|---| +| **EXTRACT** | Cyan | `#58D5E3` | Cool — pulling knowledge IN from external sources | +| **NEW** | Green | `#3FB950` | Growth — new claims added to the KB | +| **ENRICH** | Amber | `#D4A72C` | Warm — strengthening existing knowledge | +| **CHALLENGE** | Red-orange | `#F85149` | Hot — adversarial, testing existing claims | +| **DECISION** | Violet | `#A371F7` | Distinct — governance/futarchy, different category entirely | +| **TELEGRAM** | Muted blue | `#6E7681` | Subdued — community input, not agent-generated | +| **INFRA** | Dark grey | `#30363D` | Background — necessary but not the story | + +### Design rules: +- **Background:** Near-black (`#0D1117` — GitHub dark mode). Not pure black (too harsh). +- **Text:** `#E6EDF3` primary, `#8B949E` secondary. No pure white. +- **Borders/dividers:** `#21262D`. Barely visible. Structure through spacing, not lines. +- **The color IS the data.** No legends needed if color usage is consistent. Cyan always means extraction. Green always means new knowledge. A user who sees the dashboard 3 times internalizes the system. + +### Colorblind safety: +The cyan/green/amber/red palette is distinguishable under deuteranopia (the most common form). Violet is safe for all types. I'd test with a simulator but the key principle: no red-green adjacency without a shape or position differentiator. + +--- + +## Layout: The Three Panels + +### Panel 1: Timeline (hero — 60% of viewport width) + +**Stacked bar chart, horizontal time axis.** Each bar = 1 day. Segments stacked by activity type (color-coded). Height = total commits/claims. + +**Why stacked bars, not lines:** Lines smooth over the actual data. Stacked bars show composition AND volume simultaneously. You see: "Tuesday was a big day and it was mostly extraction. Wednesday was quiet. Thursday was all challenges." That's the story. + +**X-axis:** Last 30 days by default. Zoom controls (7d / 30d / 90d / all). +**Y-axis:** Commit count or claim count (toggle). No label needed — the bars communicate scale. + +**The phase narrative overlay:** A thin horizontal band above the timeline showing which PHASE the collective was in at each point. Phase 1 (bootstrap) = one color, Phase 2 (community) = another. This is the "where are we in the story" context layer. + +**Annotations:** Key events (PR milestones, new agents onboarded, first external contribution) as small markers on the timeline. Sparse — only structural events, not every merge. + +### Panel 2: Agent Activity (25% width, right column) + +**Vertical list of agents, each with a horizontal activity sparkline** (last 7 days). Sorted by recent activity — most active agent at top. + +Each agent row: +``` +[colored dot: active/idle] Agent Name ▁▂▅█▃▁▂ [claim count] +``` + +The sparkline shows activity pattern. A user sees instantly: "Rio has been busy all week. Clay went quiet Wednesday. Theseus had a spike yesterday." + +**Click to expand:** Shows that agent's recent commits, claims proposed, current task. But collapsed by default — the sparkline IS the information. + +### Panel 3: Health Metrics (15% width, far right or bottom strip) + +**Four numbers. That's it.** + +| Metric | What it shows | +|---|---| +| **Claims** | Total claim count + delta this week (+12) | +| **Domains** | How many domains have activity this week (3/6) | +| **Challenges** | Open challenges pending counter-evidence | +| **Contributors** | Unique contributors this month | + +These are the vital signs. If Claims is growing, Domains is distributed, Challenges exist, and Contributors > 1, the collective is healthy. Any metric going to zero is a red flag visible in 1 second. + +--- + +## Dual-Use: Dashboard → External Communication + +This is the interesting part. Three dashboard elements that work as social media posts: + +### 1. The Timeline Screenshot + +A cropped screenshot of the timeline panel — "Here's what 6 AI domain specialists produced this week" — is immediately shareable. The stacked bars tell a visual story. Color legend in the caption, not the image. This is the equivalent of GitHub's contribution graph: proof of work, visually legible. + +**Post format:** Timeline image + 2-3 sentence caption identifying the week's highlights. "This week the collective processed 47 sources, proposed 23 new claims, and survived 4 challenges. The red bar on Thursday? Someone tried to prove our futarchy thesis wrong. It held." + +### 2. The Agent Activity Sparklines + +Cropped sparklines with agent names — "Meet the team" format. Shows that these are distinct specialists with different activity patterns. The visual diversity (some agents spike, some are steady) communicates that they're not all doing the same thing. + +### 3. The Claim Network (not in the dashboard, but should be built) + +A force-directed graph of claims with wiki-links as edges. Color by domain. Size by structural importance (the PageRank score I proposed in the ontology review). This is the hero visual for external communication — it looks like a brain, it shows the knowledge structure, and every node is clickable. + +**This should be a separate page, not part of the ops dashboard.** The dashboard is for operators. The claim network is for storytelling. But they share the same data and color system. + +--- + +## Typography + +- **Monospace everywhere.** JetBrains Mono or IBM Plex Mono. This is a terminal aesthetic, not a marketing site. +- **Font sizes:** 12px body, 14px panel headers, 24px hero numbers. That's the entire scale. +- **No bold except metric values.** Information hierarchy through size and color, not weight. + +--- + +## Implementation Notes for Oberon + +1. **Static HTML + vanilla JS.** No framework needed. This is a single-page data display. +2. **Data source:** JSON files generated from git history + claim frontmatter. Same pipeline that produces `contributors.json` and `graph-data.json`. +3. **Chart library:** If needed, Chart.js or D3. But the stacked bars are simple enough to do with CSS grid + calculated heights if you want zero dependencies. +4. **Refresh:** On page load from static JSON. No websockets, no polling. The data updates when someone pushes to main (~hourly at most). +5. **Dark mode only.** No light mode toggle. This is an ops tool, not a consumer product. + +--- + +## The Broader Visual Language + +Cory's ask: "Posts with pictures perform better. We need diagrams, we need art." + +The dashboard establishes a visual language that should extend to all Teleo visual communication: + +1. **Dark background, colored data.** The dark terminal aesthetic signals: "this is real infrastructure, not a pitch deck." +2. **Color = meaning.** The activity type palette (cyan/green/amber/red/violet) becomes the brand palette. Every visual uses the same colors for the same concepts. +3. **Information density over decoration.** Every pixel carries data. No stock photos, no gradient backgrounds, no decorative elements. The complexity of the information IS the visual. +4. **Monospace type signals transparency.** "We're showing you the raw data, not a polished narrative." This is the visual equivalent of the epistemic honesty principle. + +**Three visual asset types to develop:** +1. **Dashboard screenshots** — proof of collective activity (weekly cadence) +2. **Claim network graphs** — the knowledge structure (monthly or on milestones) +3. **Reasoning chain diagrams** — evidence → claim → belief → position for specific interesting cases (on-demand, for threads) + +→ CLAIM CANDIDATE: Dark terminal aesthetics in AI product communication signal operational seriousness and transparency, differentiating from the gradient-and-illustration style of consumer AI products.