Gallery › Vibe Tracks › Vibe Tracks KPIs

Vibe Tracks KPIs

Vibe Tracks' KPI section rebuilt from one .base file: the headline SPPM card with its run history, the smaller cards beside it (computation time, grasp success, p95, bench score), filled marks for measured readings and hollow ones for estimates. The history is a chart view (Vega-Lite), so the page has one chart engine.

Vibe Trackskpicharttable4 views of one kpis.json

The .base file and its data

Every tab above is one entry of this file; the views read these rows. ⋯ in the toolbar copies the current view as YAML.

# Vibe Tracks' KPI section as data-ui views: one row per KPI reading (Vibe Tracks' synthetic grasp bench, its
# committed fixture), the headline card with its run history, the smaller cards beside it, and the history as charts.
# Check it: node bin/data-ui.mjs check <this file>
data: kpis.json
facets:
  - label
  - model
  - lane
  - { property: t, as: range }
properties:
  label: { displayName: KPI }
  t: { displayName: When }
  value: { displayName: Value }
  better: { displayName: Better }
  model: { displayName: Model }
  lane: { displayName: Lane }
  bench: { displayName: Bench }
  commit: { displayName: Commit }
  runs: { displayName: Runs }
  run_ids: { displayName: Run ids }
views:
  - type: kpi
    name: KPIs
    groupBy: { property: label }
    groupOrder: [Successful picks per minute (SPPM), Computation time, Grasp success, Computation time p95, Bench score]
    sort:
      - { property: t, direction: ASC }
    kpi:
      value: { property: value }
      compare: { against: previous, better: better, neutral: 0.01 }
      spark: { x: t, y: value }
  - type: chart
    name: SPPM history
    filters: 'kpi == "sppm"'
    chart:
      mark: { type: line, point: true }
      encoding:
        x: { field: t, title: Build }
        y: { field: value, title: Successful picks per minute }
        color: { field: model }
    guides:
      - { rule: { y: 30 }, label: "one robot at a 2 s cycle: 30 picks/min" }
    hover: { title: label, fields: [value, model, t, runs, lane] }
  - type: chart
    name: Every KPI
    filters: 'kpi != "bench_score"'
    chart:
      mark: { type: line, point: true }
      encoding:
        x: { field: t, title: null }
        y: { field: value, title: null }
        facet: { field: label, columns: 2 }
      resolve: { scale: { y: independent } }
    hover: { title: label, fields: [value, model, t, runs] }
  - type: table
    name: Readings
    order: [label, t, value, model, lane, runs, bench, commit]
    groupBy: { property: label }
    sort:
      - { property: t, direction: DESC }
    fold: closed
// kpis.json: 161 rows, 78 KB; the first 3
{
 "id": "vibetracks-kpis",
 "title": "Vibe Tracks KPIs (synthetic grasp bench)",
 "titleProperty": "label",
 "source": "vibetracks storybook/fixtures/synthetic/kpi-doc.syn.json (vt-kpi-doc/1, synthetic: made-up models)",
 "properties": {
  "label": {
   "type": "text",
   "width": 240
  },
  "kpi": {
   "type": "text",
   "hidden": true
  },
  "t": {
   "type": "date",
   "width": 190
  },
  "value": {
   "type": "number",
   "width": 150
  },
  "better": {
   "type": "text",
   "width": 70
  },
  "model": {
   "type": "text",
   "width": 120,
   "display": "badge"
  },
  "lane": {
   "type": "text",
   "width": 90
  },
  "bench": {
   "type": "text",
   "width": 70
  },
  "commit": {
   "type": "text",
   "width": 90
  },
  "runs": {
   "type": "number",
   "width": 60
  },
  "run_ids": {
   "type": "list",
   "width": 380
  }
 },
 "rows": [
  {
   "id": "sppm-01",
   "kpi": "sppm",
   "label": "Successful picks per minute (SPPM)",
   "t": "2026-09-23T09:00:00-07:00",
   "value": {
    "value": 9.9186,
    "unit": "picks/min",
    "basis": "measured",
    "n": 3,
    "source": "Synthetic grasp bench (fixture): r01-graspnet1b-seen, r01-graspnet1b-novel, r01-clutter6d-hard",
    "asOf": "2026-09-23T09:00:00-07:00",
    "low": 6.5041,
    "high": 13.4037
   },
   "better": "higher",
   "model": "M1.base",
   "lane": "models",
   "bench": "v1",
   "commit": "dc9f6529",
   "runs": 3,
   "run_ids": [
    "r01-graspnet1b-seen",
    "r01-graspnet1b-novel",
    "r01-clutter6d-hard"
   ]
  },
  {
   "id": "success_rate-01",
   "kpi": "success_rate",
   "label": "Grasp success",
   "t": "2026-09-23T09:00:00-07:00",
   "value": {
    "value": 43.7229,
    "unit": "%",
    "basis": "measured",
    "n": 3,
    "source": "Synthetic grasp bench (fixture): r01-graspnet1b-seen, r01-graspnet1b-novel, r01-clutter6d-hard",
    "asOf": "2026-09-23T09:00:00-07:00",
    "low": 28.6715,
    "high": 59.0861
   },
   "better": "higher",
   "model": "M1.base",
   "lane": "models",
   "bench": "v1",
   "commit": "dc9f6529",
   "runs": 3,
   "run_ids": [
    "r01-graspnet1b-seen",
    "r01-graspnet1b-novel",
    "r01-clutter6d-hard"
   ]
  },
  {
   "id": "compute_mean_s-01",
   "kpi": "compute_mean_s",
   "label": "Computation time",
   "t": "2026-09-23T09:00:00-07:00",
   "value": {
    "value": 2.6449,
    "unit": "s",
    "basis": "measured",
    "n": 3,
    "source": "Synthetic grasp bench (fixture): r01-graspnet1b-seen, r01-graspnet1b-novel, r01-clutter6d-hard",
    "asOf": "2026-09-23T09:00:00-07:00"
   },
   "better": "lower",
   "model": "M1.base",
   "lane": "models",
   "bench": "v1",
   "commit": "dc9f6529",
   "runs": 3,
   "run_ids": [
    "r01-graspnet1b-seen",
    "r01-graspnet1b-novel",
    "r01-clutter6d-hard"
   ]
  }
 ]
}
skin.css, README.md
/* Vibe Tracks' skin: its own tokens (vibetracks~/tokens.css, Claude Desktop's, read 2026-10-25), then the
   one block that maps them onto data-ui's --data-* (docs/SPEC.md §10). good / bad are its success and danger inks,
   so a KPI delta reads green or red outside its neutral band, as Vibe Tracks' tiles do. */
.data-ui-skin {
  --surface: #ffffff; --ink: #0b0b0b; --ink-2: #52514e; --alpha-1: rgba(11, 11, 11, .05); --line: rgba(11, 11, 11, .10);
  --hover: rgba(11, 11, 11, .05); --accent: #2a78d6; --warn-ink: #734500; --success-ink: #2f7a4a; --danger-ink: #8e2626;
  --font: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace; --radius: 6px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .data-ui-skin {
    --surface: #1a1a1a; --ink: #f0efec; --ink-2: #c3c2b7; --alpha-1: rgba(255, 255, 255, .05); --line: #252525;
    --hover: rgba(255, 255, 255, .06); --accent: #2a78d6; --warn-ink: #db9300; --success-ink: #6fbf8b; --danger-ink: #ec7e7e;
  }
}
:root[data-theme="dark"] .data-ui-skin {
  --surface: #1a1a1a; --ink: #f0efec; --ink-2: #c3c2b7; --alpha-1: rgba(255, 255, 255, .05); --line: #252525;
  --hover: rgba(255, 255, 255, .06); --accent: #2a78d6; --warn-ink: #db9300; --success-ink: #6fbf8b; --danger-ink: #ec7e7e;
}
/* the mapping (SPEC §10's Vibe Tracks block, plus the KPI inks) */
.data-ui-skin {
  --data-bg: var(--surface); --data-fg: var(--ink); --data-muted: var(--ink-2); --data-subtle: var(--alpha-1);
  --data-border: var(--line); --data-rule: var(--alpha-1); --data-hover: var(--hover); --data-accent: var(--accent);
  --data-warn: var(--warn-ink); --data-font: var(--font); --data-mono: var(--mono); --data-radius: var(--radius);
  --data-good: var(--success-ink); --data-bad: var(--danger-ink);
}
# Vibe Tracks KPIs

Vibe Tracks' KPI section rebuilt from one `.base` file: the headline SPPM card with its run history, the smaller
cards beside it (computation time, grasp success, p95, bench score), filled marks for measured readings and hollow
ones for estimates. The history is a `chart` view (Vega-Lite), so the page has one chart engine.

- **App:** Vibe Tracks
- **Replaces:** Vibe Tracks' hand-rolled KPI section (`vibetracks~/kpi-chart.js`: `<vt-kpi-progress>`,
  the headline and its driver tiles on ECharts, about 2,000 lines) and the tiles of `kpi-panel.js`
  (`VT.ui.kpiTile`, Storybook's `Components/KPI tile`).
- **Shows:** `type: kpi` grouped one card per KPI with `groupOrder` (the first is the headline); the producer's
  number, never recomputed, with its basis badge and "computed from 3 runs"; the delta against the previous reading,
  coloured by which way is better (picks per minute up, computation time down: `compare.better: better` names the
  rows' own `better` column, so each card reads its direction from its newest row); a gap
  where a reading was not taken; "—" with its reason for the bench score; click a card for the readings behind it.
  Two chart presets: SPPM history by model with the 30 picks/min reference line, and every KPI as small multiples.
- **Data:** `kpis.json`, written by `source/build.py` from Vibe Tracks' committed synthetic fixture
  (`storybook/fixtures/synthetic/kpi-doc.syn.json`): made-up models, no real track's figures. The fixture has no
  bench score, so that card says so.
- **Skin:** `skin.css` maps Vibe Tracks' tokens (Claude Desktop's) onto `--data-*`, with its success and danger inks
  as `--data-good` and `--data-bad`.

The original UI it replaces

Vibe Tracks' hand-rolled KPI section (vibetracks~/kpi-chart.js: <vt-kpi-progress>, the headline and its driver tiles on ECharts, about 2,000 lines) and the tiles of kpi-panel.js (VT.ui.kpiTile, Storybook's Components/KPI tile).

What it shows

type: kpi grouped one card per KPI with groupOrder (the first is the headline); the producer's number, never recomputed, with its basis badge and "computed from 3 runs"; the delta against the previous reading, coloured by which way is better (picks per minute up, computation time down: compare.better: better names the rows' own better column, so each card reads its direction from its newest row); a gap where a reading was not taken; "—" with its reason for the bench score; click a card for the readings behind it. Two chart presets: SPPM history by model with the 30 picks/min reference line, and every KPI as small multiples.

Data

kpis.json, written by source/build.py from Vibe Tracks' committed synthetic fixture (storybook/fixtures/synthetic/kpi-doc.syn.json): made-up models, no real track's figures. The fixture has no bench score, so that card says so.

Skin

skin.css maps Vibe Tracks' tokens (Claude Desktop's) onto --data-*, with its success and danger inks as --data-good and --data-bad.