# Build the "Capability disclosure" pattern: `CapabilityStatement`

## Stack (edit this block to match your project)
- React 18+ with TypeScript: one function component, typed props, no `any`.
- Tailwind CSS, using your design system's tokens if you have them.
- Presentational only: data comes in through props, decisions go out through callbacks. No fetching or global state inside.
- If your codebase already has conventions (naming, shared components, tokens), follow them over this spec.

## What the pattern is for
A plain statement of what the agent can do, what it cannot, and what it will never do without asking.

Use it when: First run of any agent with side effects, and any surface where users must calibrate trust fast.

## What to build
A panel that tells a person, in their own terms, what the agent does on its own, what it asks about first, and what it never does. It is built from the agent's registered tools, so it always matches what is switched on, and it can show exactly what the agent would do for a sample request. It renders on an agent's setup screen, settings page or first-run sheet.

### Props
- `capabilities`: Array<{ id: string; tier: "auto" | "ask" | "never"; text: string; toolId?: string; limit?: string }>, one row per behaviour, derived from the registered tool set by the parent, e.g. { tier: "ask", text: "Refund a customer", toolId: "billing.refund", limit: "Up to $2,000 per ticket" }.
- `tierLabels`: Record<"auto" | "ask" | "never", { title: string; note: string }>, e.g. "Does on its own" / "Logged on the record".
- `source`: { toolCount: number; generatedAt: Date; changedBy?: string }, shown as a provenance line so readers know the list came from the live tool set.
- `samples?`: Array<{ id: string; request: string; steps: Array<{ text: string; tier: "auto" | "ask" | "never" }> }>, example requests and the ordered steps the agent would take for each.
- `showToolIds?`: boolean, reveals the tool identifier beside each row for technical readers (default false).
- `status`: "loading" | "ready" | "error" | "stale", controlled by the parent.
- `onEnable?()` and `onEditPermissions?(capabilityId: string)`: callbacks for the primary action and per-row changes. The component never changes permissions itself.

### States it must render
- Loading: three tier groups with skeleton rows, so the layout does not jump when the list arrives.
- Ready: three groups in fixed order (auto, ask, never), each row a plain sentence about behaviour with its limit, and a provenance line such as "Built from the 9 tools enabled here".
- Sample selected: the chosen request expands into a numbered list of steps, each tagged with its tier, so a person sees where the agent would stop and wait.
- Empty tier: a group with no rows still renders with a line such as "Nothing in this group", so its absence is visible rather than ambiguous.
- Stale: the tool set changed since the list was generated; a notice says so and offers refresh instead of showing an out-of-date list as current.
- Error: the list could not be built; say so and do not render a generic placeholder list.

### Interactions
- Selecting a sample request shows its steps; selecting it again collapses them. Only one sample is open at a time.
- Each row in the ask and auto groups has an optional "Change" control that calls `onEditPermissions(id)`.
- The primary action calls `onEnable`; it is disabled while loading, in error or stale.

### Edge cases
- A capability with no backing tool (the agent cannot do it at all) belongs in the never group and its note should say why, e.g. "No tool connected".
- Rows must describe behaviour, never risk transfer: reject or flag text supplied as a disclaimer ("You are responsible for…") by keeping the row format to a verb-led action and limit.
- A sample step whose tier is never: render it as a stop, with the steps after it shown as not taken.
- Long lists: keep all never rows visible; collapse auto rows beyond 6 behind "Show all".

## Must avoid
Legal-flavoured disclaimers that dump risk on the user instead of describing behaviour in their terms.

## Engineering constraint
Generate the list from the actual registered tool set so it cannot drift from what shipped.

## Accessibility
- Each tier group is a list with a heading; the tier is stated in text in every sample step, not only by colour or icon.
- Sample requests are buttons with `aria-expanded`, and the step list they control is linked with `aria-controls`.

## House rules
- Real `<button>`/`<input>` elements, full keyboard use, visible focus; announce status changes with `aria-live="polite"`; respect `prefers-reduced-motion`.
- All user-facing text comes from props (or a `labels` prop) so it can be translated.
- One consistent accent marks anything the AI made or is doing; amber means "needs a person", red means risky, green means done. Never rely on colour alone.
- Fits a 360 px wide container without horizontal scrolling.

## Acceptance checks
- [ ] Every state above can be rendered by passing props, with no internal fake data.
- [ ] Every interaction and edge case above behaves as described.
- [ ] Nothing in "Must avoid" can happen with this component.

## Deliver
1. The component file with its exported prop types.
2. A short usage example that renders each state.
