Commit da3b501
Merge task overview and trial QA into unified panel (#1065)
* Open a task overview instead of the first trial from experiments
Clicking a task in an experiment used to jump straight into its first
trial; the task pane's default view was the static checks alone. Both now
land on a task overview that gathers the task's QA in one place:
- New TaskOverviewPanel: QA verdict (in panes without their own verdict
card), the static checks, and the trial-level QA aggregated across the
shown version's trials — classification counts, deduped findings (by
the server's content-hash action-item ids), and per-trial
classifications, each linking to the trial that surfaced it.
- Trial links open in the caller's own drawer when the trial is
addressable there, falling back to the task page deep link
(?version=&trial=) otherwise.
- The experiment grid's task click opens task mode (the overview) rather
than promoting to the first trial; "View trials" and the overview's
links drill in.
- SeverityGroups accepts an optional renderItemFooter so aggregated
findings can append their "seen in" trial links.
The overview replaces the "Static checks" entry at the top of the task
pane sidebar; probes stay excluded and the public share view (which hides
analysis) is unchanged.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRu1mqJXR7HzspFFCsP2fs
* Merge the static checks into the overview's unified findings
The overview no longer carries a standalone "Static checks" section.
Source-audit findings and trial-QA action items now land in one Findings
list, deduped by the server's content-hash ids, with each item tagged by
its sources: a "Source audit" chip and/or links to the trials that
surfaced it. The audit's lifecycle survives in the section header —
status summary, cost, and the Run/Re-run audit button, with the same
loading/unknown-state guard that kept a misread "unaudited" from wiping
real findings.
StaticChecksPanel had no other consumers, so the component is deleted;
its staticCheckState state machine moves into the overview panel.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRu1mqJXR7HzspFFCsP2fs
* Join audit and trial findings through links_to, not ids
Bugbot caught that the overview's finding dedupe could never merge
across sources: the server's content-hash ids include the analyzer
source, so an audit (pre_trial) row and a trial (post_trial) row for the
same defect always hash differently. The real cross-source join is
links_to, which the panel now reads from both places: a trial's
exploitation assessments put exploiting trials on the audit row's "seen
in" list, and a post-trial action item that links to an audit finding
folds into that row instead of duplicating it. Trials are deduped per
row so a trial contributing through both paths appears once.
Also stop the clean-state copy from vouching for trial QA that hasn't
run: without any analyzed trials it now only speaks for the source
audit.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRu1mqJXR7HzspFFCsP2fs
* Keep the overview's trial aggregation on the pinned version
Bugbot caught that the overview received version={checksVersion?.version
?? null}: while /detail was loading (or after it failed) the prop
collapsed to null — the "aggregate every version" value — even when the
host pane already had a pinned taskVersion. The pinned version now wins
outright, and without a pin the prop stays undefined until /detail
resolves, which the panel renders as a waiting state instead of a
briefly version-spanning aggregation; a dead /detail says the version
could not be resolved. Only a loaded task with no versions is genuinely
unscoped.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRu1mqJXR7HzspFFCsP2fs
* Open overview trial links in the drawer, never the task page
The overview's trial links only opened in place when the trial was
already in the host's loaded trial list, and routed to the task page
otherwise. On the experiment page that list streams in progressively, so
the lookup usually missed and a click navigated away from an experiment
whose drawer can render the trial on the same page.
The overview hands the full trial row to the callback, so both hosts now
always open it in their own drawer — a grid/version-list match is still
preferred so the per-group trial nav lines up, and an unmatched trial
opens with no group index. The task-page deep link remains only as the
no-callback fallback.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRu1mqJXR7HzspFFCsP2fs
* Make the overview's trial data cheap: scope, seed, and calm the polling
Opening any task fetched every trial the task ever had — all versions,
all experiments, each with its full analysis payload — and re-fetched it
on a 5s loop whenever an analysis sat pending, which is most tasks with
QA enabled. That made the whole page feel slow.
- GET /tasks/{task_id}/trials gains a `version` filter (inner join to
task_versions), so the overview's fetch carries one version's rows
instead of the task's entire history; the Next proxy forwards it and
the panel waits for the resolved version before fetching at all.
Deploy skew is safe: an older backend ignores the param and the
panel's client-side version filter still applies.
- The panel seeds from the trials the host already has in memory (grid
rows / task page), so the aggregation paints immediately; the scoped
fetch then replaces the seed to add action items and exploitation.
Seeded rows also cover a failed fetch instead of an error flash.
- Polling drops to 15s and stops revalidating on focus.
Also addresses this round's Bugbot findings: a /detail load failure now
shows the error above whatever trial-side findings exist instead of
hiding them, and the rows handed to SeverityGroups carry trial ids
rather than full trial objects so the per-item copy button no longer
serializes nested trial payloads.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRu1mqJXR7HzspFFCsP2fs
* Treat an empty trial seed as no seed
Bugbot caught that an empty seed array slipped past the loading gate:
displayTrials became [] while the scoped fetch was still in flight, so
the pane flashed "No trials" for a task whose rows simply weren't in the
host's memory yet. Only a non-empty seed may paint; an empty one falls
back to the loading state until the fetch answers.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRu1mqJXR7HzspFFCsP2fs
* Scope the overview's trial QA to the host's own trials
In an experiment drawer the aggregation pulled from the task-wide trials
fetch, so trials from other experiments showed up in a context that
should only speak for its own rows. The host's trial set is now the
authoritative scope: the experiment drawer and task page pass their own
rows, and the fetch only enriches those by id with the fields the
compact payload omits (action items, exploitation) — it can never widen
the set. An empty scope renders as loading while the host is still
streaming trials and as an honest "no trials" once it isn't. Panes with
no host scope (none remain today) fall back to the fetched
version-scoped set.
Also drops the backend `version` filter from this branch — that, its
test, and the core helper change move to their own PR so this one stays
a pure side-panel change. The frontend still sends the param; a backend
without it ignores it, and the scope semantics above no longer depend
on it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FRu1mqJXR7HzspFFCsP2fs
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 9b13139 commit da3b501
8 files changed
Lines changed: 917 additions & 226 deletions
File tree
- frontend/src
- app
- (app)/tasks/[task_id]
- api/tasks/[task_id]/trials
- components
- qa-report
- lib
Lines changed: 19 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
878 | 878 | | |
879 | 879 | | |
880 | 880 | | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
881 | 895 | | |
882 | 896 | | |
883 | 897 | | |
| |||
1406 | 1420 | | |
1407 | 1421 | | |
1408 | 1422 | | |
| 1423 | + | |
| 1424 | + | |
| 1425 | + | |
1409 | 1426 | | |
| 1427 | + | |
1410 | 1428 | | |
1411 | 1429 | | |
1412 | 1430 | | |
| |||
1424 | 1442 | | |
1425 | 1443 | | |
1426 | 1444 | | |
| 1445 | + | |
1427 | 1446 | | |
1428 | 1447 | | |
1429 | 1448 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
19 | | - | |
20 | | - | |
21 | | - | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
22 | 30 | | |
23 | 31 | | |
24 | 32 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1571 | 1571 | | |
1572 | 1572 | | |
1573 | 1573 | | |
| 1574 | + | |
| 1575 | + | |
| 1576 | + | |
| 1577 | + | |
| 1578 | + | |
| 1579 | + | |
| 1580 | + | |
| 1581 | + | |
| 1582 | + | |
| 1583 | + | |
| 1584 | + | |
| 1585 | + | |
| 1586 | + | |
| 1587 | + | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
1574 | 1598 | | |
1575 | 1599 | | |
1576 | 1600 | | |
| |||
1690 | 1714 | | |
1691 | 1715 | | |
1692 | 1716 | | |
1693 | | - | |
1694 | | - | |
1695 | | - | |
1696 | | - | |
1697 | | - | |
| 1717 | + | |
| 1718 | + | |
| 1719 | + | |
| 1720 | + | |
1698 | 1721 | | |
1699 | 1722 | | |
1700 | | - | |
| 1723 | + | |
1701 | 1724 | | |
1702 | 1725 | | |
1703 | 1726 | | |
1704 | | - | |
1705 | | - | |
| 1727 | + | |
| 1728 | + | |
1706 | 1729 | | |
1707 | 1730 | | |
1708 | 1731 | | |
| |||
1727 | 1750 | | |
1728 | 1751 | | |
1729 | 1752 | | |
| 1753 | + | |
| 1754 | + | |
| 1755 | + | |
| 1756 | + | |
1730 | 1757 | | |
| 1758 | + | |
| 1759 | + | |
1731 | 1760 | | |
1732 | 1761 | | |
1733 | 1762 | | |
| |||
1769 | 1798 | | |
1770 | 1799 | | |
1771 | 1800 | | |
| 1801 | + | |
| 1802 | + | |
1772 | 1803 | | |
1773 | 1804 | | |
1774 | 1805 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
1 | 3 | | |
2 | 4 | | |
3 | 5 | | |
| |||
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| 22 | + | |
20 | 23 | | |
21 | 24 | | |
22 | 25 | | |
23 | 26 | | |
| 27 | + | |
24 | 28 | | |
25 | 29 | | |
26 | 30 | | |
| |||
75 | 79 | | |
76 | 80 | | |
77 | 81 | | |
| 82 | + | |
| 83 | + | |
78 | 84 | | |
79 | 85 | | |
80 | 86 | | |
| |||
101 | 107 | | |
102 | 108 | | |
103 | 109 | | |
| 110 | + | |
104 | 111 | | |
105 | 112 | | |
106 | 113 | | |
107 | 114 | | |
108 | 115 | | |
109 | 116 | | |
| 117 | + | |
| 118 | + | |
110 | 119 | | |
111 | 120 | | |
112 | 121 | | |
| |||
155 | 164 | | |
156 | 165 | | |
157 | 166 | | |
| 167 | + | |
158 | 168 | | |
159 | 169 | | |
160 | 170 | | |
| |||
This file was deleted.
0 commit comments