# Eval scorecard

An eval run against its baseline: overall pass rate, then each criterion's rate, its change from the baseline, and a regression flag where it fell by more than the threshold. A criterion with no baseline shows its rate and no change rather than comparing against nothing.

- Registry name: `eval-scorecard` (`@candor/eval-scorecard`)
- Tier: Pro. Installing it needs a Pro, Premium or Team licence key: the person runs `npx candor-ui key <key>` themselves; never ask for the key in chat or write it to a file.
- Docs: https://candor.themethodic.com/docs/eval-scorecard

## Install

```bash
npx candor-ui add eval-scorecard
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/eval-scorecard`.
It brings in: locale, ops, utils.
npm packages: lucide-react@^1.67.0.

## Example

```tsx
"use client"

import { EvalScorecard } from "@/components/eval-scorecard"
import type { Criterion } from "@/lib/ops"

const criteria: Criterion[] = [
  { id: "c1", label: "Cites a file or table for every fact about the code", passed: 92, failed: 8, baseline: 0.9 },
  { id: "c2", label: "Asks before acting when the target environment is unclear", passed: 71, failed: 29, baseline: 0.84 },
  { id: "c3", label: "Uses the code’s own names (tables, files, flags)", passed: 97, failed: 3, baseline: 0.95 },
  { id: "c4", label: "Marks assumptions as assumptions", passed: 64, failed: 16, baseline: null },
]

export default function Example() {
  return <EvalScorecard className="max-w-2xl" title="Dev agent · Instructions v4" criteria={criteria} />
}
```

## <EvalScorecard>

Props:

- `title: string`: The run's name, shown over the overall pass rate.
- `criteria: Criterion[]`: Each criterion's passed and failed counts and its baseline pass rate (0–1, null when there is none).
- `threshold?: number | undefined` (default `0.05`): A drop larger than this (0–1) counts as a regression.
- `unit?: string | undefined`: What each counted item is, plural, as in "12 of 14 checks passed". Defaults to "checks".
- `criterionLabel?: string | undefined`: The heading over the criteria column. Defaults to "Criterion".
- `baselineLabel?: string | undefined`: What the comparison is against, as in "vs baseline" and `No ${baselineLabel}`. Defaults to "baseline".
- `className?: string | undefined`

## Strings (`evalScorecard`)

The fixed words, English by default. Override any of them under `evalScorecard` in `<LocaleProvider strings={{ evalScorecard: { … } }}>`; the table is exported as `evalScorecardStrings`.

- `unit`: checks
- `criterion`: Criterion
- `baseline`: baseline
- `percentPass`: % pass
- `passedOf`: {passed} of {total} {unit} passed
- `regressions`: { one: "{count} regression", other: "{count} regressions" }
- `passRate`: Pass rate
- `vs`: vs {baseline}
- `passedFailed`: {passed} passed · {failed} failed
- `noBaseline`: No {baseline}
- `points`: {points} pts

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider` (fixed strings) and `TermsProvider` (nouns); entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
