Skip to content

feat(site): open the leaderboard on the latest releases - #617

Open
lazizbekravshanov wants to merge 1 commit into
ktwu01:mainfrom
lazizbekravshanov:feat/issue-530-latest-releases-view
Open

lazizbekravshanov wants to merge 1 commit into
ktwu01:mainfrom
lazizbekravshanov:feat/issue-530-latest-releases-view

Conversation

@lazizbekravshanov

Copy link
Copy Markdown

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 main at 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 the latest_releases_leaderboard payload the pipeline already publishes. 7- and 90-day windows are one click away.
  • Model-card adoption and reported scores stay separate modes on the same address. The adoption view keeps every element, id, seed and handler it has today, shown as a block when the reader picks it. Reported scores links to the existing /saturation/ workbench.
  • Every rank shows its inputs. Each row prints rank, name, release date, a bar scaled against the top score, the score and its confidence. Opening a row shows each signal with its value and status (fresh, stale since the day it was last read, unavailable, or not observed), its weight and a link to the resource it was read from, plus coverage and confidence. A release the engine could not rank stays in the list, marked as limited signals, rather than vanishing.
  • The (i) states the method. Method version, the weights read from the published components (not restated in the browser), the log1p normalization, that downloads are a rolling 30-day figure and never cumulative, that stars come from the benchmark's own repository and never a parent framework, and the window bounds in UTC.
  • An empty window is a real state. The page says no release in the window has a measurable signal yet and offers the wider windows; past the widest one it offers the adoption view. A window the corpus fails to load, or does not carry, says so instead of sitting on a loading line, and the refresh control re-requests the corpus for it.
  • Switching modes is one Back away. A mode is a different ranking, so choosing one pushes a history entry; picking a window refines the entry in place. Opening a row's signals survives a redraw (the catalog index landing, a refresh, Back).
  • Chinese interface. Every visible string has a translation.

Acceptance criteria this covers

Criterion Where
/leaderboard/ defaults to Latest releases · 30d mode strip, state.lmode, latestReleasesDefaultWindow
Each rank exposes inputs, components, coverage, confidence, method version, source links latestReleaseRow, latestReleasesMethodNote
Missing and stale metrics stay distinguishable latestSignalText
Downloads never presented as cumulative or delta signal label "last 30 days" and the method note
Existing views preserved with current trust labels adoption block unchanged; /saturation/ unchanged
Empty states suggest broader windows latestReleasesEmptyState

The 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, so test_clean_route_model_migrates_legacy_urls_and_preserves_utility_backgrounds holds unchanged. The latest mode writes only a non-default lwindow, so its address can never flip modes on reload. ?lmode=latest|adoption is accepted as an explicit override.

The cutoff is shared with Saturation, whose every address carries it, so on a Saturation address lscore alone 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; readUrl and writeUrl; 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.txt and VIEW_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 helpers readUrl and writeUrl now call.
  • The bootstrap payload already carries only the default window (snapshots.py); a leaderboard address naming another one is a full-data route in stateNeedsFullData, 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.mjs and tests/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 real readUrl and writeUrl; 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, classify and build-data-release pass; pytest -q reports 1344 passed, 1 failed.

The one failure is tests/test_briefing.py::test_zh_output_budget_covers_worst_case, which downloads tiktoken's o200k_base table from openaipublic.blob.core.windows.net, a host the build sandbox's egress policy blocks. It fails identically on an untouched main checkout 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=90d loads 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=60 then the Leaderboard tab opens Latest releases, while /saturation/?lscore=60&lq=agent opens adoption with the search filled; "Reported scores" switches to Saturation without a page load; with radar.json blocked, 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

Copilot AI lite review requested due to automatic review settings September 12, 2026 15:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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.py preserves 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 entries array as an empty state. The ranking engine deliberately keeps limited-signal candidates in entries even when ranked_count is 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.json even though stateNeedsFullData() intentionally excludes adoption mode. Only render the latest section when state.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, while windowData.signal_coverage is 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 though renderLatestReleases() 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.dump has not been flushed or closed before readFileSync runs, 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.

Comment thread site/assets/app.js
Comment on lines +7950 to +7954
component.weight !== undefined && component.weight !== null
? element("small", {
className: "latest-release-weight",
text: `${t("weight")} ${Math.round(Number(component.weight) * 100)}%`,
})
Comment thread site/assets/app.js
Comment on lines +8087 to +8091
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(),
Comment thread site/assets/app.js
Comment on lines +9581 to +9585
state.view === "leaderboard"
&& state.lmode !== "adoption"
&& latest
&& state.lwindow
&& !latest.windows?.[state.lwindow]
@lazizbekravshanov
lazizbekravshanov force-pushed the feat/issue-530-latest-releases-view branch from a507fb9 to 12084e8 Compare September 12, 2026 17:04
Copilot AI review requested due to automatic review settings September 12, 2026 17:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@lazizbekravshanov
lazizbekravshanov force-pushed the feat/issue-530-latest-releases-view branch from 12084e8 to fcdf4c8 Compare September 12, 2026 18:22
Copilot AI review requested due to automatic review settings September 12, 2026 18:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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
@lazizbekravshanov
lazizbekravshanov force-pushed the feat/issue-530-latest-releases-view branch from fcdf4c8 to 37aa1b0 Compare September 12, 2026 19:23
Copilot AI review requested due to automatic review settings September 12, 2026 19:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@ktwu01 ktwu01 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants