Repository navigation
feat(dashboard): show scorer pass rates, what drives them, and whether a team change helped (#1182) - #1466
Conversation
The PR description documents sufficient testing, including a built real-CLI run at Review was read-only; no PR code was run, built, or installed. |
|
Fixed in f72f689.
Checked in a real |
|
No new findings in the scoped PR diff.
Review was read-only. No PR code was run, built, or installed. |
SaulMoro
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
@hz89Dev Thanks, this is a substantial piece of work. We ran teamai dashboard from the built CLI at f72f689 against a fixture team with session and workflow labels, and worked out every count by hand first:
- Criteria 1–13 of #1182 hold.
mainanswers 404 for/api/scorers, and the new tests fail there.- Bad parameters get 400, and the server listens on 127.0.0.1 only.
- None of the answers carries reasoning, transcript text or the native session id.
- f72f689 fixes the CI review's one finding, the typed commit erased on re-render.
One change before this can be approved:
- [P1 blocking] The friction-reminder table is always empty in a user-scope install.
handleScorerspassesscopedEvents(workspace.id)(src/dashboard.ts:320).workspaceEvents(src/dashboard/workspaces.ts:107-117) puts each session in a project workspace or underunassigned, never underuser. So withteamai init … --scope user,GET /api/scorers?workspace=user&…returns 0 sessions in every reminder row. The same events and reminder state under a workspace-scope install give yes 2, no 3, not recorded 2. The "Unassigned sessions" workspace, which does hold those sessions, answersconfigured: false. Your record used--scope workspace, which is why it doesn't show. The reminder state is machine-wide, so the user workspace could take its sessions from the events no project workspace owns. Otherwise, omitremindersthere and say so indocs/guide/dashboard.md, whose sentence about the table is wrong for user scope today.
Non-blocking:
- [P2 non-blocking] Cost on a large team. Every change on the page re-reads the whole reports branch and returns every failing label. With 90k labels and 18k run records, each click took 2.0–4.6 s, answers reached 4 MB, and the server used about 980 MiB. The Workflow Runs page takes 1.5 s on the same data. Caching the read per branch commit and paging the failing labels would bound both.
- [P3 nit] The 30-day sweep record in
src/contribute-check.tsis also written for the other per-session files in~/.teamai/sessions/, so a stale TodoWrite-hint file is recorded as "reminder fired". The table doesn't read those today, but #1388 is meant to reuse this record.
Overlap: #1379 conflicts only on the last paragraph of both scorers.md pages. #1414's conflict in src/dashboard.ts exists against main too.
CI review: we agree with its finding, which f72f689 fixes.
Verified at f72f689: tsc and lint pass. 516 unit tests and the e2e files pass, also under a symlinked TMPDIR. CI has no failed job. Not run here: a browser (we checked the API and the client code), and the real contribute-check hook reaching the sweep (we called the same function).
@jeff-r2026 This adds a new dashboard page and API, so it's yours to decide.
f72f689 to
65a20e1
Compare
|
No new findings in the scoped PR diff.
Review was read-only. No PR code was run, built, or installed. |
65a20e1 to
4839370
Compare
|
No new findings in the scoped PR diff.
Review was read-only. No PR code was run, built, or installed. |
… failing labels and reminder table
…and cap the failing list
…ered windows and groupings with the page
- Apply only the newest response, so a selection made while a page load is pending is not lost, and drop a refused commit from the query. - Show `teamai session resume <name> --platform <platform>`, which the command requires. - Leave out a benchmark run's labels even when its run file is on this machine. - Count a judge model under one measurement whatever alias named it, and show the newest alias. - Build group keys from their parts, so a value named `none` stays apart from labels that recorded none. - Cut the reminder table to the 30 days reminder decisions are kept. - Run the commit split's git checks in batches of 8, write swept records atomically, and show a run that cannot be found without a link. - Drop `headline` and `trend` from the selected cohort; they repeated the cohort's own counts.
…scope reminder table (Tencent#1182, Tencent#1472)
…les, not other hooks' per-session files (Tencent#1182)
…orts or team clone moves
…s on the selected cohort, and name ownSessionEvents for what it returns
…ep team reads only for branch worktree reports
4839370 to
eb8fd44
Compare
|
All three are fixed at
The PR also now closes #1472 (labels by value, under |
|
No new findings in the scoped PR diff.
Review was read-only. No PR code was run, built, or installed. |
SaulMoro
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
Re-review at eb8fd44. All three findings from our last review are fixed, and nothing new blocks. Whether the new dashboard page and its read API go in is the maintainer's call.
Earlier findings
| Finding | Status |
|---|---|
| [P1] Empty friction-reminder table in a user-scope install | Fixed. Built CLI, user scope: yes 2/2/1, no 3/2/2, not recorded 2/2/0 (all 0 at f72f689). Workspace scope is unchanged. The "not recorded" labelled count differs between scopes because the local label lives only in the user scope's data home; that is correct. |
| [P2] Cost on a large team | Fixed for clicks and answer size. Same 90k-label fixture, old and new builds run in turn: repeat clicks 0.7-3.5 s against 6.8-19.5 s, answers 11-25 KB against up to 4 MB. First load and memory (about 900 MiB) are unchanged, as the body says. |
| [P3] Sweep record written for other hooks' files | Fixed. Through the real contribute-check hook, only the contribute state file gets a record. |
New, non-blocking
- [P3 nit] The new cache of the team's labels lives as long as the server, so its memory is not released. The body says so.
The read API now takes group and failing, and its answer changes shape (failing is {labels,total}, new cohort.values). Both the API and the page are new in this PR, so nothing existing breaks. The PR also closes #1472 (labels by value), and the counts add up to the label count in the real-CLI answers.
Verification at eb8fd44
npm ci,npm run build,npx tsc --noEmit,npm run lintexit 0.- The PR's unit files (51 tests, also with a symlinked TMPDIR) and their callers (389 tests) pass. The e2e files that reach the changed code pass; the full e2e suite was not rerun.
- Every CI job passed at this head. The body's real-CLI record is at eb8fd44 and includes a user-scope run.
Not run here: the page in a browser, the gitlab and github providers, agents other than Claude.
SaulMoro
left a comment
There was a problem hiding this comment.
This was generated by AI during triage.
Approving at eb8fd44. The review is in our comment above: the three earlier findings are fixed and checked with the built CLI, CI is green, and the body has a real-CLI record at this head. The one nit left (the team-label cache is never released while the server runs) is already noted in the body.
Summary
Score labels from sessions and workflow runs are published to
teamai-reports, but nothing reads them. A team cannot see how its tools do on real work, or whether a change to its skills helped. The dashboard now has a Scorers page. It shows pass rates one measurement at a time, and only sums labels that measure the same thing.teamai contributenow keeps{ hinted }for 30 days when it sweeps a session's state file. Without that record, the reminder table would lose every session older than a day.Since the review
ownSessionEvents). A project workspace still counts only its own sessions.hintedare read back.Also new: Labels by value (#1472), on
selected.cohort.values, and the phone layout for its table and the reminder table.Cost per click on a fixture with 90,000 labels and 18,000 run records (server CPU time per request; wall time was not usable on a loaded machine):
48393701)eb8fd443)New screenshots:
Screenshots from the first round (fixture team, real
teamai dashboard):No horizontal page overflow at 390px or 820px. The four-column tables fit the phone width; wider tables scroll inside their panel.
Type of Change
Test Plan
npx tsc --noEmitpassesnpm run lintpassesnpx vitest run: the scorer, dashboard and contribute tests pass (51 in the five files this branch adds to). A full local run on a heavily loaded machine (load average 120-228) had 13-20 failures in timing-dependent workflow and usage tests this branch does not touch, and the set changed between runs. CI ateb8fd443passes the full suite on Node 20, 22 and 24 on Ubuntu and macOS, plus Windows and the three E2E shards.New tests:
Real CLI record at head
eb8fd443(teamai dashboardbuilt from this branch, same fixture team plus a routing scorer; the user scope run uses a--scope userinstall of the same team):In the browser, on the 90,000 label fixture: Show more went 25, 50, ... 1,000 of 3,873, then the button gave way to "Pick a group or a shorter window to list the rest." with no error.
First real CLI record (
teamai0.22.0 built from this branch, head41256ff3). The fixture team has two scorers. It holds 222 session labels across 3 members, 52 workflow labels joined to 26 run records (one of them a benchmark), and one session pushed to the archive:An independent check against the same server recomputed every count from the fixture files. It confirmed that none of the 222 session ids in the fixture appears in any of 33 responses. It also confirmed that no response carries
isolation,access, reasoning or prompt text.In the browser:
Not covered locally: providers
gitlabandgithub, and agents other than Claude. They are left to CI. The page readsteamai-reportsthe same way the Workflow Runs page does.Related Issues
Closes #1182
Closes #1472
Notes for Reviewers
rubric.sourceHash, source, run mode and judge (kind, tool, model; reported and requested-only apart). The judge's team alias is shown but does not split a measurement. The label parser refuses a label withoutrubric.sourceHashorjudge, so the page has norubric not recordedorjudge not recordedcohort.git merge-base --is-ancestorin this machine's team clone, at most 8 at a time. A revision the clone does not have counts as not recorded, never as before.benchmarkare left out, also when the run file is on this machine. Nothing writesbenchmarkbefore [feat] Run benchmark suites as workflows #1180, so today this only guards future records.--platform, whichteamai session resumerequires. They never show the native session id.teamai score --team-sessiondoes not exist yet, so the row offers resume only.teamai contributekeeps decisions for. A session counts as fired if its live state or its swept record says so.httpteams, whose sync rewrites reports without a commit. A session archive index written without a commit shows its name after the next commit or pull.