# Terms consent

The AI disclosure and terms, asked once per terms version. Says plainly what's AI and what a person still decides (the points come from the service), links the documents, and asks for an explicit agreement. If the terms change, the new version asks again and says what changed.

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

## Install

```bash
npx candor-ui add terms-consent
```

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

## Example

```tsx
"use client"

import { TermsConsent } from "@/components/terms-consent"

export default function Example() {
  return (
    <TermsConsent
      version="2026-11"
      points={[
        "Keel’s agents use AI models to read your code and propose changes; their answers can be wrong.",
        "Nothing reaches Production until someone with the right role approves it.",
        "Model providers don’t keep or train on your data.",
      ]}
      documents={[
        { label: "Terms of service", href: "#terms" },
        { label: "Privacy", href: "#privacy" },
        { label: "AI use", href: "#ai-use" },
      ]}
      onAgree={() => {}}
    />
  )
}
```

## <TermsConsent>

Props:

- `version: string`: e.g. "2026-11".
- `points: string[]`: What's AI and what people decide, one sentence each.
- `documents: { label: string; href: string }[]`: The terms documents, linked and opened in a new tab.
- `changed?: string | undefined`: Set when this replaces a version the person agreed to.
- `onAgree: (version: string) => void`: Called with the terms version when the person agrees.
- `busy?: boolean | undefined` (default `false`): Disables Agree while the agreement is being recorded.
- `className?: string | undefined`

## Strings (`termsConsent`)

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

- `beforeYouStart`: Before you start
- `changed`: Our terms changed
- `version`: Terms version {version}
- `newTab`: (opens in a new tab)
- `agreeLabel`: I’ve read these and agree to them.
- `tickFirst`: Tick the box to agree first.
- `agree`: Agree and continue

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