# Quality trend

Scores over time (judge scores on live threads, by default), with what changed alongside: a model switch, an instructions edit, a new tool. The changes are listed under the chart by date so a move in the line can be read against its likely cause. Days the judge didn't sample are gaps.

- Registry name: `quality-trend` (`@candor/quality-trend`)
- 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/quality-trend

## Install

```bash
npx candor-ui add quality-trend
```

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

## Example

```tsx
"use client"

import { QualityTrend } from "@/components/quality-trend"
import type { QualityPoint } from "@/lib/ops"

const points: QualityPoint[] = [
  { date: "Oct 20", score: 0.86 },
  { date: "Oct 21", score: 0.87 },
  { date: "Oct 22", score: 0.85, change: "Instructions v3: shorter answers" },
  { date: "Oct 23", score: 0.81 },
  { date: "Oct 24", score: null },
  { date: "Oct 25", score: 0.8 },
  { date: "Oct 26", score: 0.83 },
  { date: "Oct 27", score: 0.88, change: "Dev agent moved to Claude Sonnet 5.5" },
  { date: "Oct 28", score: 0.89 },
  { date: "Oct 29", score: 0.9 },
  { date: "Oct 30", score: 0.84, change: "Added the repo.search tool" },
  { date: "Oct 31", score: 0.86 },
]

export default function Example() {
  return <QualityTrend className="max-w-2xl" points={points} />
}
```

## <QualityTrend>

Props:

- `title?: string | undefined`: The chart's title. Defaults to "Answer quality".
- `subtitle?: string | undefined`: The line under the title. Defaults to "Judge score, daily".
- `seriesLabel?: string | undefined`: What the line measures, for the legend and the data table. Defaults to "Judge score".
- `gapNote?: ((days: number) => string) | undefined`: What to say about days with no score, given how many there are. Defaults to "3 days weren’t sampled."
- `points: QualityPoint[]`: One judge score per day (0–1, null when not sampled), with any change made that day.
- `className?: string | undefined`

## Strings (`qualityTrend`)

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

- `title`: Answer quality
- `subtitle`: Judge score, daily
- `seriesLabel`: Judge score
- `gapNote`: { one: "{count} day wasn’t sampled.", other: "{count} days weren’t sampled." }
- `changes`: Changes

## 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`.
