# Blast radius

What a plan step can reach in the environment, grouped by kind of thing. Measured, it lists each component with how it changes; metadata types the agent couldn't read are named, because it can't rule them out. When the reach can't be measured, it says so and why — never an empty "nothing affected".

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

## Install

```bash
npx candor-ui add blast-radius
```

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

## Example

```tsx
"use client"

import type { BlastRadiusScope } from "@/lib/work"
import { BlastRadius } from "@/components/blast-radius"

const measured: BlastRadiusScope = {
  kind: "measured",
  unread: ["Mobile app screens"],
  components: [
    { entity: { kind: "component", name: "web/src/customers/CustomerHeader.tsx", label: "CustomerHeader" }, change: "update", diff: { added: 1, removed: 1 } },
    { entity: { kind: "component", name: "web/src/admin/CustomerAdmin.tsx", label: "CustomerAdmin" }, change: "update", diff: { added: 1, removed: 0 } },
    { entity: { kind: "column", name: "customers.region", label: "region" }, change: "read", diff: null },
  ],
}

const unknown: BlastRadiusScope = {
  kind: "unknown",
  reason: "A data backfill touches rows, not code. Which rows change depends on billing country at run time.",
}

export default function Example() {
  return (
    <div className="grid max-w-3xl gap-4 md:grid-cols-2">
      <BlastRadius step="Show region on the customer and admin pages" scope={measured} />
      <BlastRadius step="Backfill region from billing country" scope={unknown} />
    </div>
  )
}
```

## <BlastRadius>

Props:

- `step: string`: The plan step's title, shown as the heading.
- `scope: BlastRadiusScope`: What the step can reach, or why that couldn't be measured.
- `className?: string | undefined`

## Strings (`blastRadius`)

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

- `label`: What “{step}” can reach
- `blastRadius`: Blast radius
- `reach`: {changed} changed · {read} read
- `reachUnknown`: Reach unknown.
- `group`: {noun}s · {count}
- `create`: New
- `update`: Changed
- `delete`: Deleted
- `read`: Read
- `unread`: Couldn’t read {kinds}, so effects there aren’t ruled out.

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