feat(site): open the leaderboard on the latest releases - #617
lazizbekravshanov wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved rendering, scope metadata, routing, seed parity, and test reliability issues remain.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Updates /leaderboard/ to default to the latest-releases ranking while preserving existing adoption and reported-score views.
Changes:
- Adds ranking windows, disclosures, signal details, routing, and localization.
- Adds static seeds, responsive styling, metadata, and full-data loading.
- Adds fixtures and renderer, routing, seed, and integration tests.
File summaries
| File | Reviewed changes |
|---|---|
tests/test_site.py |
Route-model coverage |
tests/test_latest_releases_view.py |
View, seed, and SEO tests |
tests/latest_releases_render_harness.mjs |
Renderer and seed parity tests |
tests/latest_releases_harness.mjs |
Routing and helper behavior tests |
tests/fixtures/latest_releases.json |
Synthetic ranking fixture |
src/benchmark_radar/app_seeds.py |
Static leaderboard seed generation |
site/llms.txt |
Updated leaderboard metadata |
site/index.html |
Leaderboard modes and ranking markup |
site/assets/styles.css |
Ranking layout and responsive styles |
site/assets/app.js |
Rendering, routing, loading, and translations |
Review details
Suppressed comments (7)
site/assets/app.js:7912
- The summary only contains the benchmark name and release date; the purpose is rendered inside
latest-release-body, which is behind the collapsed<details>. Issue #530's first-screen contract requires each Top 10 row to show a one-line purpose with its name and release date, so keep the disclosure but include the purpose in the summary as well (and mirror that change in the Python seed).
element("span", { className: "leaderboard-top-name" }, [
element("span", { text: entry.name }),
entry.release_date
? element("small", {
className: "latest-release-date",
site/assets/app.js:7837
- A non-null component with
status: "unknown"is rendered as a bare number here, making an unverified fallback counter indistinguishable from a fresh observation. The ranking engine intentionally emits this combination for connector fallback metrics (release_leaderboard.pypreserves the value but refuses freshness), so the UI must label unknown as non-fresh (and mirror that behavior in the seed) rather than implying current attention.
const status = component?.status || "unknown";
const value = component?.value;
if (status === "unavailable") return t("unavailable");
if (value === null || value === undefined) return t("not observed");
const number = Number(value).toLocaleString();
site/assets/app.js:8050
- This branch treats only an empty
entriesarray as an empty state. The ranking engine deliberately keeps limited-signal candidates inentrieseven whenranked_countis zero, so a 30-day window with only unranked releases never offers the wider window even when 90 days has ranked results. Use the ranked count when deciding whether to add a broader-window action, while retaining the limited rows.
const entries = windowData.entries || [];
if (!entries.length) {
const suggestion = latestReleasesEmptyState(windowKey, payload);
site/assets/app.js:8141
- This renders the latest-release view even when adoption mode is active. After a reader has selected a non-default window, the bootstrap normally lacks that window, so this hidden render calls
ensureFullData()and fetches/data/radar.jsoneven thoughstateNeedsFullData()intentionally excludes adoption mode. Only render the latest section whenstate.lmode !== "adoption".
syncLeaderboardMode();
renderLatestReleases();
site/index.html:509
- The always-visible scope only says
· 30 days; the generated/data-through time and the window bounds are available only inside the collapsed method note, whilewindowData.signal_coverageis never rendered at all. Issue #530 requires the active scope, data-as-of, window boundaries, ranked population, and signal coverage on the first screen, so add those values to the visible heading/metadata instead of relying on the(i)disclosure.
<h2 id="latest-releases-heading"><span data-i18n="Latest releases">Latest releases</span> <span class="latest-releases-window" id="latest-releases-window">· 30 days</span></h2>
<span id="latest-releases-info"></span>
</div>
<p class="section-note latest-releases-deck" data-i18n="latest.deck">Recently released benchmarks, ranked by the attention they are receiving now: GitHub stars, Hugging Face paper upvotes and Hugging Face dataset downloads over the last 30 days.</p>
src/benchmark_radar/app_seeds.py:315
- For a non-empty window this seed replaces the list but never replaces
#latest-releases-note, even thoughrenderLatestReleases()fills that node with the ranked-population summary. A no-JavaScript/crawler response therefore omits content the hydrated reader sees and violates the seed parity contract; seed this note alongside the rows.
rows = "".join(_latest_release_row(entry, top) for entry in entries)
seeds[
'<ol class="leaderboard-top-list latest-releases-list" id="latest-releases-list"></ol>'
] = (
'<ol class="leaderboard-top-list latest-releases-list" id="latest-releases-list" '
f"data-seed>{rows}</ol>"
tests/test_latest_releases_view.py:42
- This helper launches Node while the temporary JSON file is still open and buffered.
json.dumphas not been flushed or closed beforereadFileSyncruns, so the child can see an empty/truncated fixture and make this test fail nondeterministically. Flush the handle before starting the subprocess.
with open(FIXTURE.with_name("latest_releases_under_test.json"), "w", encoding="utf-8") as fh:
json.dump(payload, fh)
- Files reviewed: 10/10 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| component.weight !== undefined && component.weight !== null | ||
| ? element("small", { | ||
| className: "latest-release-weight", | ||
| text: `${t("weight")} ${Math.round(Number(component.weight) * 100)}%`, | ||
| }) |
| if (note) { | ||
| note.textContent = t( | ||
| "{ranked} of {total} releases in this window are ranked; the rest are listed with limited signals.", | ||
| { | ||
| ranked: Number(windowData.ranked_count || 0).toLocaleString(), |
| state.view === "leaderboard" | ||
| && state.lmode !== "adoption" | ||
| && latest | ||
| && state.lwindow | ||
| && !latest.windows?.[state.lwindow] |
a507fb9 to
12084e8
Compare
12084e8 to
fcdf4c8
Compare
Issue ktwu01#530 asks the leaderboard to answer "which newly released benchmarks are gaining attention now" first, and to keep the cumulative model-card adoption view and the reported-score workbench as separate modes. The ranking engine and its `latest_releases_leaderboard` payload landed for that issue; nothing on the page read them, so `/leaderboard/` still opened on model-card adoption. The page now has three modes on one address. Latest releases opens by default and prints the payload for a 7-, 30- or 90-day window, the 30-day one first: rank, name, release date, a bar scaled against the top score, the score and its confidence, and behind each row every input the rank was computed from, with its status, its weight and a link to the resource it was read from. A release the engine could not rank keeps its place, marked as limited signals, rather than vanishing. Every reading says how much it can be trusted. A signal is fresh, stale since the day it was last read, unavailable, or not observed; and a reading the engine declined to promote to fresh prints as unverified rather than bare. Connector counters reach the payload that way, as a real number carrying `unknown` status that `release_leaderboard._extract_fallback_metric` keeps visible for audit and deliberately does not promote, so printing it bare made an unverified count read exactly like a fresh observation. That is the imputation this issue rules out. The (i) beside the heading states the method version, the weights read from the published components, the normalization, the rolling nature of the download count and the window bounds. Model-card adoption keeps its markup, ids, seeds and handlers as a block that is hidden in the latest mode and shown in its own. Reported scores links to the existing `/saturation/` workbench, and switches to it client-side when the payload has loaded. A mode is a different ranking, so choosing one pushes a history entry Back undoes; a window refines the entry in place. Rows a reader has opened stay open across a redraw. Adoption mode never fetches a release window, matching the `stateNeedsFullData` guard rather than pulling the whole corpus in to fill a section it has hidden. Addresses stay honest in both directions. A permalink written before the page had modes carries the adoption view's own filters, so any of them selects that mode on read and the mode writes them back in the same shape; the latest mode writes only a non-default `lwindow`. The cutoff is shared with Saturation, whose every address carries it, so on a Saturation address it alone chooses no mode. Empty windows are a real state: the page says no release in the window has a measurable signal yet and offers the wider windows, and past the widest one the adoption view. The bootstrap payload carries the default window only; an address naming another is a full-data route. A window the corpus fails to load, or does not carry, says so rather than staying on a loading line. `/leaderboard/` is seeded at build time with what the renderer draws for the default window: the rows with their disclosure bodies, the method note, the ranked-count note, or the empty state with its way out, so a crawler or a reader without scripts sees the page a reader sees. A test runs the real renderer on a shared fixture and compares its markup with the seed byte for byte. Every visible string has a Chinese translation, and the route-model test now loads the mode and window helpers readUrl and writeUrl call. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UaUf4LgR9HogJ1DhXwjESy
fcdf4c8 to
37aa1b0
Compare
ktwu01
left a comment
There was a problem hiding this comment.
Thanks for the careful implementation and seed-parity work. The combined tree passes all local CI checks (1,395 tests), but several reader-facing #530 contracts are still missing:\n\n- Render each component’s published normalized value, including an explicit unknown state, and mirror it in the static seed.\n- Put each benchmark’s one-line purpose in the visible row summary; it is currently only inside the collapsed disclosure.\n- Include data-through and signal coverage in the compact scope note for the active window.\n- On a direct non-default-window URL, render or clear that requested window when the full-data fetch fails; otherwise the 30-day static seed can remain under a 90-day URL.\n- Add search for the current latest-release cohort rather than leaving search only inside the hidden adoption view.\n\nCould you address these and extend the renderer and seed tests before merge?
Part of #530: the page half. Together with the collector PR for #589 it completes the issue's acceptance list; the two are independent and merge in either order.
One commit on top of upstream
mainat 5d9e378.What changes for a reader
/leaderboard/opens on "Latest releases · 30 days". Recently released benchmarks ranked by the attention they are receiving now, from thelatest_releases_leaderboardpayload the pipeline already publishes. 7- and 90-day windows are one click away./saturation/workbench.Acceptance criteria this covers
/leaderboard/defaults to Latest releases · 30dstate.lmode,latestReleasesDefaultWindowlatestReleaseRow,latestReleasesMethodNotelatestSignalText/saturation/unchangedlatestReleasesEmptyStateThe cohort, dedupe, keyword and parent-framework rules are the engine's (
release_leaderboard.py) and the collector's (the collector PR); this PR prints what they publish and computes nothing.Addresses
A permalink written before the page had modes carries the adoption view's own filters (
lscore,lq,ldomain,lorg,lera,lheight). Any of them selects the adoption mode on read, and the mode writes them back in exactly the shape it always did, sotest_clean_route_model_migrates_legacy_urls_and_preserves_utility_backgroundsholds unchanged. The latest mode writes only a non-defaultlwindow, so its address can never flip modes on reload.?lmode=latest|adoptionis accepted as an explicit override.The cutoff is shared with Saturation, whose every address carries it, so on a Saturation address
lscorealone is not a mode choice: a reader who goes Latest releases → Saturation → Back → Forward → Leaderboard lands on Latest releases, not on a mode they never picked. The mode is resolved after the legacy benchmark permalink redirect for the same reason.Wiring
site/index.html: the mode strip, the latest-releases section, and the adoption block wrapper (#leaderboard-adoption, hidden by default; its seeded rows stay in the document for crawlers).site/assets/app.js:state.lmode/state.lwindow;readUrlandwriteUrl;leaderboardModeFromParams,latestReleasesWindowKey,latestSignalText,latestReleasesEmptyState,latestReleasesMethodNote,latestReleaseRow,renderLatestReleases,syncLeaderboardMode; one delegated click handler for the mode and window controls (the empty state renders its own buttons); zh strings.site/assets/styles.css: the mode and window pills, the row disclosure and its signal grid, phone layout.src/benchmark_radar/app_seeds.py:_latest_releases_seed, so the static/leaderboard/page carries what the renderer draws for the default window: the rows with their disclosure bodies (signals, statuses, weights, source links, coverage and confidence), the method note, and, for an empty window, the empty state with its way out. A test runs the real renderer on a shared fixture and compares the markup byte for byte with the seed.site/llms.txtandVIEW_SEO.leaderboard: the page's title, description and llms.txt entry describe the new default.tests/test_site.py: the route-model test loads the mode and window helpersreadUrlandwriteUrlnow call.snapshots.py); a leaderboard address naming another one is a full-data route instateNeedsFullData, so boot, Back and the refresh control fetch the corpus for it the way they do for a historical Today URL, and the renderer fetches it on a window click.Tests
tests/test_latest_releases_view.py(eleven tests),tests/latest_releases_harness.mjsandtests/latest_releases_render_harness.mjs, each named for the failure it protects against: the page opens on the latest ranking with the adoption block hidden and intact; mode resolution for bare, legacy, explicit and bogus addresses, and for a Saturation address with and without the adoption filters; window fallback; signal text for fresh, stale (dated and undated), unavailable, zero and null; the empty-state suggestion for a loaded-empty, unloaded and widest window; weights read from components; the method note; the URL round trip through the realreadUrlandwriteUrl; adoption filters written only in adoption mode, a mode switch pushed and a window switch replaced; every visible string translated and no key entered twice; the static seed (order, escaping, limited entries kept, disclosure bodies, method note, empty state, default window named, nothing seeded for nothing); the seed equal to what the real renderer draws on a shared fixture (a ranked row with fresh, stale and unavailable signals, a limited row, an unsafe source URL, an empty window); the renderer keeping open rows across a redraw, treating a missing window as a full-data route, fetching it, reporting a failed fetch and a window the corpus does not carry, and drawing the Chinese interface; the page metadata describing the new default; the written page carrying both rankings; bar widths scaled against the top score.Twenty-two behaviours were checked by reverting each one and watching its test go red, among them: the default mode, adoption filters leaking into the latest address, Saturation's cutoff choosing a mode, the mode resolved before the legacy redirect, a missing window not counted as a full-data route, a failed fetch left on the loading line, a loaded corpus without the window left on it, open rows collapsing, a mode switch replacing history, the seed dropping the confidence pill, the disclosure body, a weight, or offering a window known to be empty, a release date formatted outside UTC, a duplicated translation key, and the method note printed for a window with no bounds.
Verification
Clean-worktree run of the CI sequence (
git worktree add --detach, submodule initialized):ruff check .,ruff format --check .,normalize-catalog,classifyandbuild-data-releasepass;pytest -qreports 1344 passed, 1 failed.The one failure is
tests/test_briefing.py::test_zh_output_budget_covers_worst_case, which downloads tiktoken'so200k_basetable fromopenaipublic.blob.core.windows.net, a host the build sandbox's egress policy blocks. It fails identically on an untouchedmaincheckout in the same sandbox and passes on GitHub's runner.Driven in Chromium against a built payload with four synthetic entries (three ranked, one limited): the page opens on the 30-day ranking with the adoption block hidden and the unranked row announced as "unranked" to assistive technology; a row opens to its signals, with the stale upvote dated and the gone dataset marked unavailable; the 7-day window fetches the full corpus and lands on the empty state whose "Try 30 days" button restores the ranking; the 90-day window shows its five rows, and booting directly on
?lwindow=90dloads them through the boot path; choosing the adoption mode pushes one history entry (pressing it again pushes none) and Back returns to Latest releases; an opened row stays open across the refresh control;/saturation/?lscore=60then the Leaderboard tab opens Latest releases, while/saturation/?lscore=60&lq=agentopens adoption with the search filled; "Reported scores" switches to Saturation without a page load; withradar.jsonblocked, the 90-day window reports that it could not be loaded and the refresh control brings its rows back, and booting on the 90-day address shows the error banner rather than a loading line; the Chinese interface translates the heading, modes, columns, note and signal text; at 400px the body has no horizontal scroll. No page errors.Not in this PR
The collector that fills the payload with real counters (the collector PR). Until it merges the live page shows the empty state, which is the honest reading of an empty payload.
🤖 Generated with Claude Code
https://claude.ai/code/session_01UaUf4LgR9HogJ1DhXwjESy