From abf645f73746dbf8a73c12a903f73916296645ad Mon Sep 17 00:00:00 2001 From: aurph Date: Tue, 1 Sep 2026 12:27:50 -0400 Subject: [PATCH 1/2] Compute Frontier: buildout reality strip (energized vs announced GW) The strongest pattern from the outside-sources comparison (SemiAnalysis lifecycle stages, Cleanview's operating-vs-planned framing, Epoch's verified estimates): answer 'is this buildout real?' in one honest read. New strip between the cards and charts: of the full announced build-out, how much is energized today (9.0% at commit time - 11.2 of 124.6 GW), segmented energized / growth at live sites / under construction / announced-only in a proportion bar whose segments partition totalPlannedMW exactly (locked by test - a drifting sum would make the chart quietly lie). Capex context at Epoch AI's ~$38B per GW, attributed and labeled order-of-magnitude (our MW mix facility and IT bases). Colors: status ramp + a lighter operational step for growth-at-live-sites; labels carry identity. Pure math in client/src/lib/buildout-reality.ts (3 tests incl. degenerate inputs). 494 tests, tsc, build green; partition verified against the live /api/clusters/metrics. --- .../lib/__tests__/buildout-reality.test.ts | 43 ++++++++++++++ client/src/lib/buildout-reality.ts | 58 +++++++++++++++++++ client/src/pages/compute-frontier.tsx | 53 +++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 client/src/lib/__tests__/buildout-reality.test.ts create mode 100644 client/src/lib/buildout-reality.ts diff --git a/client/src/lib/__tests__/buildout-reality.test.ts b/client/src/lib/__tests__/buildout-reality.test.ts new file mode 100644 index 0000000..5bdafc0 --- /dev/null +++ b/client/src/lib/__tests__/buildout-reality.test.ts @@ -0,0 +1,43 @@ +// The proportion bar must partition the announced build-out exactly; a +// segment sum that drifts from the total would make the chart quietly lie. +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { computeBuildoutReality, EPOCH_CAPEX_B_PER_GW } from "../buildout-reality"; + +const METRICS = { + totalPlannedMW: 124_646, + operationalMW: 11_189, + byStatus: [ + { status: "operational", ratedMW: 11_189, plannedMW: 19_309 }, + { status: "construction", ratedMW: 852, plannedMW: 70_000 }, + { status: "announced", ratedMW: 0, plannedMW: 35_337 }, + ], +}; + +test("segments partition totalPlannedMW exactly", () => { + const r = computeBuildoutReality(METRICS); + assert.equal(r.energizedMW + r.growingOnSiteMW + r.constructionMW + r.announcedMW, r.totalPlannedMW); + assert.equal(r.energizedMW, 11_189); + assert.equal(r.growingOnSiteMW, 19_309 - 11_189); + assert.equal(r.announcedMW, 35_337); +}); + +test("energized share and capex context", () => { + const r = computeBuildoutReality(METRICS); + assert.ok(Math.abs(r.energizedShare - 11_189 / 124_646) < 1e-9); + assert.equal(r.unbuiltMW, 124_646 - 11_189); + assert.equal(r.unbuiltCapexB, Math.round(((124_646 - 11_189) / 1000) * EPOCH_CAPEX_B_PER_GW)); +}); + +test("degenerate inputs stay safe", () => { + const r = computeBuildoutReality({ totalPlannedMW: 0, operationalMW: 0, byStatus: [] }); + assert.equal(r.energizedShare, 0); + assert.equal(r.unbuiltCapexB, 0); + // rated above planned on operational clusters must not go negative + const odd = computeBuildoutReality({ + totalPlannedMW: 100, + operationalMW: 90, + byStatus: [{ status: "operational", ratedMW: 90, plannedMW: 80 }], + }); + assert.equal(odd.growingOnSiteMW, 0); +}); diff --git a/client/src/lib/buildout-reality.ts b/client/src/lib/buildout-reality.ts new file mode 100644 index 0000000..ff9cee9 --- /dev/null +++ b/client/src/lib/buildout-reality.ts @@ -0,0 +1,58 @@ +/** + * Buildout reality: how much of the announced AI build-out is actually + * energized today. The segments partition totalPlannedMW exactly, so the + * proportion bar is mathematically true, never suggestive: + * + * energized rated MW of operational clusters (running today) + * growingOnSite operational clusters' planned MW beyond what runs + * construction planned MW of clusters under construction + * announced planned MW of announced-only clusters + * + * Capex context uses Epoch AI's published ~$38B per GW of IT capacity + * ($26B compute + $12B construction). Our MW mix facility and IT bases, + * so the dollar figure is order-of-magnitude context, labeled as such. + */ + +export interface StatusBucketLite { + status: string; + ratedMW: number; + plannedMW: number; +} + +export interface BuildoutReality { + totalPlannedMW: number; + energizedMW: number; + growingOnSiteMW: number; + constructionMW: number; + announcedMW: number; + energizedShare: number; // 0..1 of the full announced build-out + unbuiltMW: number; + unbuiltCapexB: number; // rough $B at Epoch's ~$38B/GW +} + +export const EPOCH_CAPEX_B_PER_GW = 38; + +export function computeBuildoutReality(m: { + totalPlannedMW: number; + operationalMW: number; + byStatus: StatusBucketLite[]; +}): BuildoutReality { + const bucket = (s: string) => m.byStatus.find((b) => b.status === s); + const opPlanned = bucket("operational")?.plannedMW ?? 0; + const energizedMW = m.operationalMW; + const growingOnSiteMW = Math.max(0, opPlanned - energizedMW); + const constructionMW = bucket("construction")?.plannedMW ?? 0; + const announcedMW = bucket("announced")?.plannedMW ?? 0; + const totalPlannedMW = m.totalPlannedMW; + const unbuiltMW = Math.max(0, totalPlannedMW - energizedMW); + return { + totalPlannedMW, + energizedMW, + growingOnSiteMW, + constructionMW, + announcedMW, + energizedShare: totalPlannedMW > 0 ? energizedMW / totalPlannedMW : 0, + unbuiltMW, + unbuiltCapexB: Math.round((unbuiltMW / 1000) * EPOCH_CAPEX_B_PER_GW), + }; +} diff --git a/client/src/pages/compute-frontier.tsx b/client/src/pages/compute-frontier.tsx index 2f5d5f1..2b67efc 100644 --- a/client/src/pages/compute-frontier.tsx +++ b/client/src/pages/compute-frontier.tsx @@ -26,6 +26,7 @@ import { ArrowUpDown, Atom } from "lucide-react"; import { PageHeader, HeaderStat } from "@/components/PageHeader"; import { BRAND, INK, SURFACE, CATEGORY_COLORS, STATUS_COLORS } from "@/lib/tokens"; import { axisProps, gridProps, seriesMotion, tooltipContentStyle, tooltipItemStyle, tooltipLabelStyle } from "@/lib/chart-theme"; +import { computeBuildoutReality } from "@/lib/buildout-reality"; // ─── Types (mirror /api/clusters and /api/clusters/metrics) ──────────────── @@ -263,6 +264,58 @@ export default function ComputeFrontier() { + {/* Buildout reality: how much of the promise is energized today */} + {metrics && (() => { + const r = computeBuildoutReality(metrics); + const seg = [ + // "growth at live sites" is a lighter step of the operational hue: + // same sites, capacity not yet running. Construction and announced + // keep their own status-ramp colors. + { key: "energized", label: "energized today", mw: r.energizedMW, color: STATUS_COLOR.operational }, + { key: "growing", label: "growth at live sites", mw: r.growingOnSiteMW, color: `${STATUS_COLOR.operational}66` }, + { key: "construction", label: "under construction", mw: r.constructionMW, color: STATUS_COLOR.construction }, + { key: "announced", label: "announced only", mw: r.announcedMW, color: STATUS_COLOR.announced ?? INK.faint }, + ].filter((s) => s.mw > 0); + return ( + +

+ Of the{" "} + {gw(r.totalPlannedMW)} GW announced + across every tracked cluster,{" "} + {gw(r.energizedMW)} GW is energized + today — {(r.energizedShare * 100).toFixed(1)}%. +

+
+ {seg.map((s) => ( +
+ ))} +
+
+ {seg.map((s) => ( + + + {s.label} {gw(s.mw)} GW + + ))} +
+

+ The unbuilt {gw(r.unbuiltMW)} GW implies very roughly ${(r.unbuiltCapexB / 1000).toFixed(1)}T of + capital still to be spent, at{" "} + + Epoch AI's ~$38B per GW + {" "} + of IT capacity ($26B compute + $12B construction). Order-of-magnitude context only: tracked MW + mixes facility and IT power bases, and announced figures are targets, not commitments. +

+ + ); + })()} + {/* Charts */}
OP_TOP_N ? ` (top ${OP_TOP_N})` : ""}`}> From f1312e4496849978db9ba1ce79c239a42e1db794 Mon Sep 17 00:00:00 2001 From: aurph Date: Thu, 3 Sep 2026 11:50:03 -0400 Subject: [PATCH 2/2] deps: clear the browserslist + postcss-selector-parser advisories Two advisories published upstream since the last merge (browserslist unbounded memory growth, HIGH; postcss-selector-parser AST recursion, low) trip CI's npm-audit gate on every new push, blocking the whole open PR train. npm audit fix; 0 vulnerabilities after; tests/tsc/build green. Lockfile-only. --- package-lock.json | 104 +++++++++++++++++++++++++++------------------- 1 file changed, 61 insertions(+), 43 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19dc994..af9d835 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3117,6 +3117,19 @@ "node": ">= 0.4" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.20", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.20.tgz", + "integrity": "sha512-H0ulySigv6icDJ1F7SjtdCD6PrhTpdYCmP0CactWy1+ekh0AFd0o1Wn5T8b+hnTmdBx19u9yhL6wvCylXMY7zw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -3205,9 +3218,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", "dev": true, "funding": [ { @@ -3225,10 +3238,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.1" + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" }, "bin": { "browserslist": "cli.js" @@ -3294,9 +3308,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001753", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz", - "integrity": "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw==", + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", "dev": true, "funding": [ { @@ -4100,9 +4114,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.51", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.51.tgz", - "integrity": "sha512-kKeWV57KSS8jH4alKt/jKnvHPmJgBxXzGUSbMd4eQF+iOsVPl7bz2KUmu6eo80eMP8wVioTfTyTzdMgM15WXNg==", + "version": "1.5.420", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.420.tgz", + "integrity": "sha512-2yD6XreGusOfNV+dUcvipJEXc3n/n7fgr7996aszTG+YY5E4mqM4tOq/3uhP129cazL9YHbVWSpc79ePotWtPA==", "dev": true, "license": "ISC" }, @@ -4158,9 +4172,9 @@ } }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -4382,9 +4396,9 @@ } }, "node_modules/fflate": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.4.tgz", - "integrity": "sha512-5u2V/CDW15QM1XbbgS+0DfPxVB+jUKhWEKuuFuHncbk3tEEqzmoXL+2KyOFuKGqOnmdIy0/davWF1CkuwtibCw==", + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.5.tgz", + "integrity": "sha512-QieYf//cis6ywHNi5qW1+PXPQ4bC+XVJAtS4AXIML8P76GroEiOxm/oQtn1f02UkJY1+KsXMJcC+R2v/Eg4G3g==", "license": "MIT" }, "node_modules/filename-reserved-regex": { @@ -5237,11 +5251,14 @@ } }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.54", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz", + "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=18" + } }, "node_modules/normalize-path": { "version": "3.0.0", @@ -5561,9 +5578,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", + "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -5629,12 +5646,13 @@ } }, "node_modules/qs": { - "version": "6.15.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", - "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.16.0.tgz", + "integrity": "sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.1.0" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -6256,14 +6274,14 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -6275,13 +6293,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -6862,9 +6880,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz", + "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==", "dev": true, "funding": [ { @@ -6883,7 +6901,7 @@ "license": "MIT", "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js"