Skip to content

perf(frontend): render bounded task-card trial preview - #1192

Merged
kyle-compute merged 5 commits into
stagingfrom
perf/tasks-card-preview-cap
Aug 12, 2026
Merged

perf(frontend): render bounded task-card trial preview#1192
kyle-compute merged 5 commits into
stagingfrom
perf/tasks-card-preview-cap

Conversation

@kyle-compute

@kyle-compute kyle-compute commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Why this PR exists

Split structure and merge order

  1. perf(tasks): maintain task browse summaries on trial writes #1185 — summary maintenance: model, helpers, write-through refresh hooks.
  2. perf(tasks): repopulate historical task browse summary rows #1190 — historical population: migration task_browse_summary_002.
  3. perf(tasks): summary-first /tasks/browse selection with bounded previews #1191 — backend read cutover: summary-first browse with bounded previews.
  4. perf(frontend): render bounded task-card trial preview #1192 (this PR) — frontend card cap. 48 application-code lines.

Exact screen, request, and frequency

  • Screen: the authenticated main task-card grid at /tasks.
  • Screenshot gate: attach the capped card grid (a truncated card showing the "most recent of N" note) to this body before merge.
  • Controlling browser request: GET /api/tasks/browse, unchanged by this PR.
  • Frequency: every initial visit to /tasks and every browse refetch.
  • S3 involvement: none.

What this PR changes

  • Renders the bounded preview and "showing 24 of N": when latest_trials_truncated is set, the card states "Showing the 24 most recent of N trials" under the preview squares.
  • Reads exact status buckets (pass/partial/fail/harness/skipped/pending) from the browse response instead of reducing over every returned trial, so the pass-rate breakdown stays exact even though the visual preview is capped.
  • Behavior note: the pending segment now shows the summary's not-yet-terminal bucket instead of summing pending+queued+running preview statuses, and scoreless successes count in totals but have no bucket segment. Both match the backend's card semantics.

What this PR does not change

Historical-data decision

  • None. This PR is a pure frontend reader change.

Validation completed

  • Frontend TypeScript check (tsc --noEmit) passed.
  • Focused ESLint on both touched files passed.
  • The combined four splits were click-tested on the seeded local stack (600 tasks, 31,097 trials, hottest version 95 in-scope trials): the hot card renders 24 squares plus the truncation note.

Rollback


Note

Low Risk
Frontend-only reader change for browse cards. Risk is mainly dependency on the new browse response fields from the prior backend cutover.

Overview
Makes task cards work with the bounded browse preview: status breakdowns now come from server-provided counters (pass_count, partial_count, etc.) instead of reducing over every returned trial.

When latest_trials_truncated is set, the card shows a note like "Showing the N most recent of M trials" under the preview squares. Pending now uses the summary's single not-yet-terminal bucket rather than summing pending/queued/running preview statuses.

Reviewed by Cursor Bugbot for commit dfe2f97. Bugbot is set up for automated code reviews on this repo. Configure here.

One summary row per task version (exact card counters, status buckets,
model-grouped cost inputs, last_run_at), refreshed inside the same
transaction as every trial-population mutation: create/import,
start/reset, completion, cancellation, retry/supersede, scoped deletion,
experiment deletion, and default-version selection. Refreshes serialize
per version with sorted transaction-scoped advisory locks because
concurrent trial inserts hold KEY SHARE FK locks on task_versions.

No reader change and no historical scan: the browse endpoint still
aggregates on demand, and rows exist only for versions written to after
deploy. The read cutover and historical population land separately.

Split 1/4 of the #1152 re-land.
Data-only migration: reseed a summary row for every task version, zero
every counter, then replay the scoped aggregate and cost-breakdown
updates from task_browse_summary_001. Needed because the summary table
survived the #1156 revert while write-through maintenance did not, so
existing rows are frozen at the 2026-08-11 backfill, versions created
since have no row at all, and versions whose scoped trials vanished
need resetting.

The default browse reader (next split) has no fallback scan when a
summary row is missing or stale, so it needs this population to return
correct ordering and exact counts for historical tasks.

Split 2/4 of the #1152 re-land.
Default GET /tasks/browse ordering and exact card counters now come from
task_version_browse_summaries: the page query orders current task
versions by the summary's last_run_at and applies the 24-task limit
before any trial aggregation, instead of grouping the organization's
whole trial history first. Selected cards fetch at most 24 recent
current-version trials through an indexed lateral query; total_trials
stays exact and latest_trials_truncated marks a shortened preview.

Advanced aggregate filters, comparisons, and non-default aggregate
sorts keep the on-demand aggregation path. The cost rollup uses the
corrected billed_cost_usd key (the billed_usd KeyError 500'd /tasks and
caused the #1156 revert); billed-trial coverage now pins it.

Split 3/4 of the #1152 re-land; requires the summary maintenance hooks
and historical population from the previous splits.

Local EXPLAIN (600 tasks / 31k trials): page selection 1,552 -> 161
buffers, 21,085 trial rows -> 0 read at selection time.
Task cards read exact status buckets (pass/partial/fail/harness/
skipped/pending) from the browse response instead of reducing over
every returned trial, and show 'Showing the N most recent of M trials'
when latest_trials_truncated is set. With the backend cutover capping
latest_trials at 24, the hot 97-trial card drops from one tooltip
square per historical trial (~8,500 DOM nodes / 3,600 listeners across
the grid) to at most 24 squares plus exact counters.

Split 4/4 of the #1152 re-land; requires the summary-first browse
response fields from the backend cutover split.
@vercel

vercel Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
oddish-app Ready Ready Preview Aug 12, 2026 1:34am

@github-actions

github-actions Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Oddish preview

Commit: dfe2f9796b4e46a26b0b34f13fa208fad03df980

Surface Link Target
Frontend https://pr-1192.oddish.app Vercel preview for dfe2f97
Backend staging staging
Database staging branch staging branch

Vercel deployment URL: https://oddish-ms1t0u18c.oddish.app

Plan:

  • Frontend deploy: true
  • Backend deploy: false
  • Migrations: false

This comment is updated by the PR Preview workflow.

cursor[bot]
cursor Bot previously approved these changes Aug 12, 2026

@cursor cursor Bot 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.

Risk: medium. Approved — Cursor Bugbot passed with no findings requiring human review; Cursor Security Agent was not present on this PR. No reviewers assigned.

Open in Web View Automation 

Sent by Cursor Approval Agent: Pull Request Router and Approver

@kyle-compute
kyle-compute changed the base branch from perf/tasks-browse-cutover to staging August 12, 2026 01:20
@kyle-compute
kyle-compute dismissed cursor[bot]’s stale review August 12, 2026 01:20

The base branch was changed.

@kyle-compute
kyle-compute merged commit 09dafce into staging Aug 12, 2026
16 checks passed
@kyle-compute
kyle-compute deleted the perf/tasks-card-preview-cap branch August 12, 2026 01:34
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.

1 participant