Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions app/scaling/components/CeilingCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import Link from 'next/link';

import { Card } from '../../components/ui/Card';
import { Text } from '../../components/ui/Text';
import { deriveBinding, type Ceiling, type CeilingInput } from '../snapshot.mjs';
import { Info } from './Info';
import { Tag } from './Tag';

const AREAS: [Ceiling['area'], string][] = [['da', 'DA'], ['execution', 'Execution'], ['state', 'State'], ['networking', 'Networking']];

function input({ name, value, unit, status, asOf }: CeilingInput): string {
const shown = value === null ? status : `${value} ${unit}`.trim();
return [name, shown, value === null ? null : status, asOf && new Date(asOf).toISOString().slice(0, 10)].filter(Boolean).join(' · ');
}

export function CeilingCards({ ceilings }: { ceilings: Ceiling[] }) {
const binding = deriveBinding(ceilings);
return (
<section className="flex flex-col gap-3">
<Text as="h2" variant="headline">Ceilings by bottleneck <span className="text-bds-gray-60">· Mgas/s</span></Text>
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4">
{AREAS.map(([area, name]) => {
const c = ceilings.find((x) => x.area === area)!;
return (
<Card key={area} className="flex flex-col gap-2 bg-background p-4 text-[13px] dark:bg-white/5">
<span className="flex items-center gap-1">
<Link className="underline" href={`/scaling/${area}`}><Text as="span" variant="label">{name}</Text></Link>
<Info label={`About the ${name} ceiling`}>{c.help}</Info>
</span>
<span className="flex flex-wrap items-center gap-2">
<span className="font-mono text-[20px]">{c.value === null ? '—' : c.value.toLocaleString('en-US', { maximumFractionDigits: 2 })}</span>
<Tag tag={c.tag} />
{c === binding ? <span className="rounded-md bg-base-blue px-2 py-0.5 text-[12px] text-white">Binding</span> : null}
</span>
<code className="break-words font-mono text-[12px] text-bds-gray-60">{c.formula}</code>
{c.reason ? <p className="text-bds-gray-60">{c.reason}</p> : null}
<ul className="flex flex-col gap-0.5 text-[12px] text-bds-gray-60 empty:hidden">
{c.inputs.map((i) => <li key={i.name}>{input(i)}</li>)}
</ul>
</Card>
);
})}
</div>
</section>
);
}
57 changes: 57 additions & 0 deletions app/scaling/components/Guardrails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { cn } from '../../components/ui/cn';
import { Card } from '../../components/ui/Card';
import { Text } from '../../components/ui/Text';
import type { Guardrail } from '../snapshot.mjs';
import { Info } from './Info';
import { Tag } from './Tag';

const TH = 'px-4 py-2 text-left text-[12px] font-[500] text-bds-gray-60';
const TD = 'px-4 py-3 align-top';
const DOT: Record<Guardrail['status'], string> = { ok: 'bg-bds-green-50', breached: 'bg-bds-red-50', unknown: 'bg-bds-gray-30' };
const STATUS: Record<Guardrail['status'], string> = { ok: 'OK', breached: 'Breached', unknown: 'Unknown' };

const fmt = (n: number, unit: string) => `${n.toLocaleString('en-US', { maximumFractionDigits: 2 })} ${unit}`.trim();

export function Guardrails({ guardrails }: { guardrails: Guardrail[] }) {
return (
<section className="flex flex-col gap-3">
<Text as="h2" variant="headline">Guardrails</Text>
<Card className="overflow-x-auto bg-background dark:bg-white/5">
<table className="w-full border-collapse text-[13px]">
<thead>
<tr className="border-b border-bds-gray-10 dark:border-white/10">
<th className={TH}>Guardrail</th>
<th className={TH}>Value</th>
<th className={TH}>Threshold</th>
<th className={TH}>Status</th>
</tr>
</thead>
<tbody>
{guardrails.map((g) => (
<tr key={g.id} className="border-b border-bds-gray-10 last:border-0 dark:border-white/10">
<td className={TD}>
<span className="flex items-center gap-1">{g.label} <Info label={`About ${g.label}`}>{g.help}</Info></span>
</td>
<td className={cn(TD, 'whitespace-nowrap font-mono')}>{g.value === null ? '—' : fmt(g.value, g.unit)}</td>
<td className={TD}>
<span className="flex flex-wrap items-center gap-2">
<span className="whitespace-nowrap font-mono">{g.threshold === null ? '—' : `${g.comparator === '<=' ? '≤' : '≥'} ${fmt(g.threshold, g.unit)}`}</span>
{g.thresholdTag === 'set' ? null : <Tag tag={g.thresholdTag} />}
{g.owner ? <span className="text-bds-gray-60">{g.owner}</span> : null}
</span>
</td>
<td className={cn(TD, 'whitespace-nowrap')}>
<span className="flex items-center gap-2">
<span aria-hidden="true" className={cn('h-2 w-2 rounded-full', DOT[g.status])} />
{STATUS[g.status]}
</span>
</td>
</tr>
))}
</tbody>
</table>
</Card>
<Text variant="footnote" tone="muted">Breached SLOs are not attributed to saturation until triaged.</Text>
</section>
);
}
4 changes: 2 additions & 2 deletions app/scaling/components/Ladder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import { cn } from '../../components/ui/cn';
import { Text } from '../../components/ui/Text';
import { deriveBinding, type Rung, type Snapshot } from '../snapshot.mjs';
import { Info } from './Info';
import { Tag } from './Tag';
import { layoutRungs, type Anchor } from './ladderLayout';

const LABEL_PX = 150;
const ROW = 44;
const AXIS = 12;
const AREA_NAME = { da: 'DA', execution: 'execution', state: 'state', networking: 'networking' };
const TAG_LABEL: Record<string, string> = { 'not-measured': 'Not measured', 'not-modeled': 'Not modeled', 'not-established': 'Not established' };
const ALIGN: Record<Anchor, string> = { start: 'items-start text-left', middle: 'items-center text-center', end: 'items-end text-right' };
const SHIFT: Record<Anchor, string> = { start: 'none', middle: 'translateX(-50%)', end: 'translateX(-100%)' };

Expand Down Expand Up @@ -95,7 +95,7 @@ export function Ladder(props: Props) {
{all.filter((item) => !placed.has(item.id)).map((item) => (
<li key={item.id} className="flex items-center gap-1.5">
<span className="text-bds-gray-60">{item.label}</span>
<span className="rounded-md border border-dashed border-bds-gray-40 px-2 py-0.5 text-[12px] text-bds-gray-60">{TAG_LABEL[item.tag] ?? item.tag}</span>
<Tag tag={item.tag} />
<Info label={`About ${item.label}`}>{item.help}</Info>
</li>
))}
Expand Down
11 changes: 11 additions & 0 deletions app/scaling/components/Tag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const LABEL: Record<string, string> = {
measured: 'Measured', modeled: 'Modeled', estimated: 'Estimated',
'not-measured': 'Not measured', 'not-modeled': 'Not modeled', 'not-established': 'Not established',
provisional: 'Provisional', unset: 'Unset',
};

export function Tag({ tag }: { tag: string }) {
return (
<span className="rounded-md border border-dashed border-bds-gray-40 px-2 py-0.5 text-[12px] text-bds-gray-60">{LABEL[tag] ?? tag}</span>
);
}
50 changes: 50 additions & 0 deletions app/scaling/components/firstScreen.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { readFileSync } from 'node:fs';

import { renderToStaticMarkup } from 'react-dom/server';
import { describe, expect, it } from 'vitest';

import type { Snapshot } from '../snapshot.mjs';
import { CeilingCards } from './CeilingCards';
import { Guardrails } from './Guardrails';

// Synthetic data only: real snapshots are internal and never committed.
function fixture(): Snapshot {
return JSON.parse(readFileSync(new URL('../fixtures/synthetic.v2.json', import.meta.url), 'utf8'));
}

const cards = (html: string) => html.split('<a ').slice(1);

describe('CeilingCards', () => {
it('renders every area in a fixed order with its tag, and badges the binding card', () => {
const html = cards(renderToStaticMarkup(<CeilingCards ceilings={fixture().ceilings.reverse()} />));
expect(html.map((c) => c.match(/href="\/scaling\/(\w+)"/)![1])).toEqual(['da', 'execution', 'state', 'networking']);
expect(html.map((c) => c.match(/border-dashed[^>]*>([^<]+)</)![1])).toEqual(['Modeled', 'Estimated', 'Not modeled', 'Not modeled']);
expect(html.map((c) => c.includes('>Binding<'))).toEqual([true, false, false, false]);
});

it('moves the binding badge to a lower measured ceiling, and shows a dash, reason and pending inputs when there is no value', () => {
const { ceilings } = fixture();
ceilings[1] = { ...ceilings[1], value: 90, tag: 'measured' };
const html = cards(renderToStaticMarkup(<CeilingCards ceilings={ceilings} />));
expect(html.map((c) => c.includes('>Binding<'))).toEqual([false, true, false, false]);
expect(html[2]).toContain('>—<');
expect(html[2]).toContain('live-state growth not measured');
expect(html[2]).toContain('state_bytes_per_gas · pending</li>');
expect(html[2]).toContain('runway_years · 4 years · provisional · 2026-01-01</li>');
});
});

describe('Guardrails', () => {
it('shows comparator and unit with the threshold, tags provisional and unset thresholds, and colors only known statuses', () => {
const rows = renderToStaticMarkup(<Guardrails guardrails={fixture().guardrails} />).split('<tr').slice(2);
expect(rows[0]).toContain('≤ 80 %');
expect(rows[0]).toContain('bg-bds-green-50');
expect(rows[1]).toContain('≥ 99.9 %');
expect(rows[1]).toContain('bg-bds-red-50');
expect(rows[2]).toContain('>Provisional<');
expect(rows[2]).toContain('Synthetic owner');
expect(rows[3]).toContain('>Unset<');
expect(rows[3]).toContain('bg-bds-gray-30');
expect(rows[3]).not.toMatch(/bg-bds-(green|red)/);
});
});
4 changes: 4 additions & 0 deletions app/scaling/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { Card } from '../components/ui/Card';
import { EmptyState } from '../components/ui/EmptyState';
import { Text } from '../components/ui/Text';

import { CeilingCards } from './components/CeilingCards';
import { Guardrails } from './components/Guardrails';
import { Ladder } from './components/Ladder';
import { isStale, parseSnapshot, type Metric, type Snapshot, type WorkItem } from './snapshot.mjs';

Expand Down Expand Up @@ -68,6 +70,8 @@ export default async function ScalingPage() {
</header>

<Ladder ladder={snapshot.ladder} ceilings={snapshot.ceilings} translations={snapshot.translations} windows={snapshot.windows} />
<CeilingCards ceilings={snapshot.ceilings} />
<Guardrails guardrails={snapshot.guardrails} />

{snapshot.sections.map((section) => (
<section key={section.id} className="flex flex-col gap-3">
Expand Down
Loading