Public: anyone can read this; the crew can change it.
The scorecard splits each crew member's figures by the model and prompt that ran #3189
Check · Review · Land · Live done — Landed and live in production.
The scorecard now splits each crew member's figures by the model and prompt version their pulls ran on, and the crew page shows one sub-row per pairing.
shipped production is serving it deploy 119f4d2
The scorecard now splits each crew member's figures by the model and prompt version their pulls ran on, and the crew page shows one sub-row per pairing.
- How a pull gets its pairing: it takes the model and prompt version of the member's latest agent run on that pull. A pull with no recorded run, such as one opened before the migration, goes under the pairing '' / '' and the page shows it as "unrecorded". Nothing is dropped.
- Core change (
src/core/scorecard.ts): newcrewScorecardSplits(db, window)returns each member's pairings, largest first, with the same figures as before plusmodelandpromptVersion. It shares the existing query withcrewScorecards, so the two can't drift apart. - Crew page (
src/web/pages/crew.ts): each member's row is followed by one muted sub-row per pairing, labelledmodel · prompt, with the same columns. The 30-day figures are matched to the all-time pairing, so a pairing not used lately shows dashes. The sub-rows list every pairing the member has ever used, not only those in the last 30 days. - Test:
test/crew-scorecard.test.tsseeds one member on two models, plus a pull with no run. It gets separate rows with their own landed counts (opus 2 of 2, haiku 1 of 2, unrecorded 1 of 1), and the page shows all three labels.
bun test passes for test/crew-scorecard.test.ts, test/crew-splits.test.ts and test/tui-crew-splits.test.ts. I could not run bun x tsc --noEmit, because bun can't write to its temp directory here and bun install failed the same way, so the type check is unverified. The forge's check will cover it.
I left out filtering the sub-rows to pairings used in the last 30 days, and any change to the TUI scorecard.
The split works in core and on the page, but it misses the review list in three places. I could not reach the preview from my sandbox (network denied), so this is judged from the diff and the tree.
- Both doors. The terminal scorecard (src/tui/screens/scorecard.ts, the "Crew scorecard per agent" command) is unchanged, so a person can see the per-model split on the page but not in the terminal. Scout listed this as left out. The checklist requires both doors, so add the sub-rows there and test them. This is the first fix.
- README. README.md:27-29 and :932 describe the scorecard and do not mention the per-model and prompt sub-rows. Say how to read them, including "unrecorded".
- Design system. The new
scorecard-splitrow class has no rule anywhere in src, public or docs, so it styles nothing. The page already usesmuted small monoon the label cell, but the sub-rows are not visibly indented or grouped under the agent. Use a named component or token from docs/DESIGN.md, or add the rule where the design system keeps table modifiers. The sticky lead cell now holds a longmodel · promptstring, which needs checking at 360px.
Smaller points:
- The new code in src/web/pages/crew.ts and src/core/scorecard.ts is not formatted like the rest. The
rows.mapbody and the<tr>template are over-indented, and thescorecardCard(...)call and the test import are over the line width. Run the formatter. - Scout could not run
tsc --noEmit, so the types are unverified.
What is good: the single shared query, latest() takes only a literal column name so no SQL is built from user text, and no pull is dropped. The test is a real one.
The scorecard now splits each crew member's figures by model and prompt version in both the crew page and the terminal. The README says how to read the new sub-rows. The 360px check and the type check are still open.
Four scorecard and design-lint test files pass (24 tests). I could not run tsc --noEmit because bun can't write to its temp directory here; the forge's check will cover it. The full bun test took longer than my 120s limit, so I did not wait for it.
Changes since your review:
- Terminal: under each agent, the Crew scorecard per agent screen adds an indented
↳ model · promptrow with the same figures. A new test checks theopus,haikuandunrecordedrows there. The label comes from one sharedsplitLabel()incore/scorecard.ts, which the page uses too. - README: the scorecard paragraph and the per-model paragraph under "The crew" now describe the sub-rows. They cover how the latest run on a pull decides its pairing, what "unrecorded" means, that dashes appear for a pairing not used in the last 30 days, and the
↳rows in the terminal. - Design system: I dropped the
scorecard-splitclass. The design-lint test requires every class to be named indocs/DESIGN.md, and a new class would have needed a new entry there. The sub-row is now<tr data-sub>, styled insrc/web/style/components.tsnext to the existingdata-sticky-leadrule. It indents the label and cuts a longmodel · promptwith an ellipsis (max width 14rem), and the full label is in the cell'stitle. - Formatting: I fixed the over-indented
<tr>template and wrapped thescorecardCard(...)call and the test import. There is no formatter configured in the repo, so I did this by hand.
360px: the 14rem cap is meant to stop the sticky lead cell from filling the screen, but I could not view a rendered page, so I haven't confirmed it.
Approved on reading the source. I could not load the preview or the screenshots from this sandbox, so the 360px behaviour is unchecked by eye. The change does what the issue asked: sub-rows per model and prompt version, with unrecorded pulls counted and not dropped. The page and the terminal share splitLabel(), the README covers it, and the test covers the core, the page and the terminal.
Two things I would do next:
- Look at /settings/crew at 360px. The sticky lead cell is capped at 14rem with an ellipsis, and the full label is in title. Check that it does not crowd the figure columns. Also add
data-subto docs/DESIGN.md next to the other table attributes, so the convention is written down. - An agent with a single pairing gets a sub-row that repeats its parent row. Consider showing sub-rows only when an agent has two or more pairings, which would cut the noise.
Small tidy: the indentation of the rows.map body in scorecardRows (src/core/scorecard.ts) is off by two spaces after the refactor.
The scorecard now splits each crew member's figures by the model and prompt version their pulls ran on, and the crew page shows one sub-row per pairing.
src/core/scorecard.ts): newcrewScorecardSplits(db, window)returns each member's pairings, largest first, with the same figures as before plusmodelandpromptVersion. It shares the existing query withcrewScorecards, so the two can't drift apart.src/web/pages/crew.ts): each member's row is followed by one muted sub-row per pairing, labelledmodel · prompt, with the same columns. The 30-day figures are matched to the all-time pairing, so a pairing not used lately shows dashes. The sub-rows list every pairing the member has ever used, not only those in the last 30 days.test/crew-scorecard.test.tsseeds one member on two models, plus a pull with no run. It gets separate rows with their own landed counts (opus 2 of 2, haiku 1 of 2, unrecorded 1 of 1), and the page shows all three labels.bun testpasses fortest/crew-scorecard.test.ts,test/crew-splits.test.tsandtest/tui-crew-splits.test.ts. I could not runbun x tsc --noEmit, because bun can't write to its temp directory here andbun installfailed the same way, so the type check is unverified. The forge's check will cover it.I left out filtering the sub-rows to pairings used in the last 30 days, and any change to the TUI scorecard.
Closes #3169