diff --git a/tests/test_publication_claims.py b/tests/test_publication_claims.py index 43e1340..ee82ad2 100644 --- a/tests/test_publication_claims.py +++ b/tests/test_publication_claims.py @@ -49,13 +49,15 @@ def test_public_claim_surfaces_use_the_frozen_lane_and_current_gate() -> None: def test_employer_facing_site_links_current_evidence_and_metadata() -> None: - hero = Path("web/src/components/Hero.tsx").read_text() + results = Path("web/src/components/ResultsExplorer.tsx").read_text() footer = Path("web/src/components/Footer.tsx").read_text() index = Path("web/index.html").read_text() - assert "0 beat the scripted bar" in hero - assert "sota-v2-phase-one-2026-07-19" in hero - assert "Built by Ned Cutler" in footer + assert "Above scripted bar" in results + assert "modelsAboveBar" in results + assert "Holm-adjusted family test" in results + assert "sota-v2-phase-one-2026-07-19" in footer + assert "Ned Cutler" in footer assert "REPRODUCING_SOTA_V2_RELEASE.md" in footer assert 'href="%BASE_URL%favicon.svg"' in index assert 'rel="canonical" href="https://nedcut.github.io/gm-bench/"' in index diff --git a/web/bun.lock b/web/bun.lock index eac3a05..42a519d 100644 --- a/web/bun.lock +++ b/web/bun.lock @@ -5,10 +5,14 @@ "": { "name": "web", "dependencies": { + "d3-array": "^3.2.4", + "d3-scale": "^4.0.2", "react": "^19.2.7", "react-dom": "^19.2.7", }, "devDependencies": { + "@types/d3-array": "^3.2.2", + "@types/d3-scale": "^4.0.9", "@types/node": "^26.1.1", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", @@ -102,6 +106,12 @@ "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], + "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="], + + "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="], + + "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="], + "@types/node": ["@types/node@26.1.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="], "@types/react": ["@types/react@19.2.17", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw=="], @@ -152,12 +162,28 @@ "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="], + + "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="], + + "d3-format": ["d3-format@3.1.2", "", {}, "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg=="], + + "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="], + + "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="], + + "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="], + + "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="], + "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], + "lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="], "lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="], diff --git a/web/index.html b/web/index.html index 5eae457..11e609e 100644 --- a/web/index.html +++ b/web/index.html @@ -4,31 +4,31 @@ - + - + - + - GM-Bench — Can a language model run a front office? + GM-Bench — phase one standings diff --git a/web/package.json b/web/package.json index a8fe951..2343f75 100644 --- a/web/package.json +++ b/web/package.json @@ -5,15 +5,20 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc -b && vite build", + "validate:data": "bun scripts/validate_results_data.ts", + "build": "bun run validate:data && tsc -b && vite build", "lint": "oxlint", "preview": "vite preview" }, "dependencies": { + "d3-array": "^3.2.4", + "d3-scale": "^4.0.2", "react": "^19.2.7", "react-dom": "^19.2.7" }, "devDependencies": { + "@types/d3-array": "^3.2.2", + "@types/d3-scale": "^4.0.9", "@types/node": "^26.1.1", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", diff --git a/web/public/favicon.svg b/web/public/favicon.svg index fc4dfe2..18cdfe4 100644 --- a/web/public/favicon.svg +++ b/web/public/favicon.svg @@ -1,5 +1,5 @@ - + - + diff --git a/web/scripts/validate_results_data.ts b/web/scripts/validate_results_data.ts new file mode 100644 index 0000000..1b7db4d --- /dev/null +++ b/web/scripts/validate_results_data.ts @@ -0,0 +1,18 @@ +import leaderboardData from "../src/data/leaderboard.json"; +import { buildBenchmarkView } from "../src/benchmarkData"; +import type { Leaderboard } from "../src/types"; + +const leaderboard = leaderboardData as Leaderboard; +const benchmark = buildBenchmarkView(leaderboard); + +if (benchmark.modelCount !== leaderboard.publication.eligible_headline_models) { + throw new Error( + `Results UI has ${benchmark.modelCount} rows, but publication metadata declares ` + + `${leaderboard.publication.eligible_headline_models} eligible headline models`, + ); +} + +console.log( + `Validated ${benchmark.modelCount} result rows from one leaderboard source ` + + `(${benchmark.repeats} repeats; ${benchmark.modelsAboveBar} above scripted bar).`, +); diff --git a/web/src/App.tsx b/web/src/App.tsx index 5845b2e..3597fb2 100644 --- a/web/src/App.tsx +++ b/web/src/App.tsx @@ -1,30 +1,40 @@ +import { useState } from "react"; import snapshotData from "./data/snapshot.json"; import leaderboardData from "./data/leaderboard.json"; import type { Leaderboard as LeaderboardData, Snapshot } from "./types"; +import { buildBenchmarkView } from "./benchmarkData"; import Nav from "./components/Nav"; -import Hero from "./components/Hero"; -import Leaderboard from "./components/Leaderboard"; -import Integrity from "./components/Integrity"; -import Results from "./components/Results"; +import ResultsExplorer from "./components/ResultsExplorer"; +import Analysis from "./components/Analysis"; import HowItWorks from "./components/HowItWorks"; -import Adapters from "./components/Adapters"; import Quickstart from "./components/Quickstart"; import Footer from "./components/Footer"; const snapshot = snapshotData as Snapshot; const leaderboard = leaderboardData as LeaderboardData; +const benchmark = buildBenchmarkView(leaderboard); export default function App() { + const [selectedModelId, setSelectedModelId] = useState( + benchmark.models[0]?.id ?? "", + ); + return ( <>