<!-- GENERATED by scripts/build-llms.mjs from llms/agent-tools.md — do not edit this file. -->

# `lr-policy-summary`

- **Import** `import '@aceshooting/lyra-ui/components/lr-policy-summary.js';` (stable tag alias; registers the tag)
- **Class** `LyraPolicySummary`, also available unregistered from `@aceshooting/lyra-ui/components/agent-tools/policy-summary/policy-summary.class.js`
- **Family** `components/agent-tools/` — see `llms/index.md` for its siblings
- **Status** `stable` since `4.1.0` — see the maturity and deprecation policy in `llms/shared.md`
- **Release history** [CHANGELOG.md](../../CHANGELOG.md); family-wide breaking-change summaries: [llms-full.txt](../../llms-full.txt)
- **Deprecations** none
- **Optional peers** none
- **Themeable via** 12 parts, 3 custom properties — see this component's own `@csspart`/`@cssprop` list below
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-policy-summary`

Read-only list of guardrail, permission, privacy, and tool-policy decisions with accessible
allow, deny, or needs-review explanations.

**Properties:** `decisions: PolicyDecision[] = []` (attribute: false) — `PolicyDecision { id: string;
category: PolicyDecisionCategory; label: string; state: PolicyDecisionState; explanation: string;
detail?: string }`, with `PolicyDecisionCategory = 'guardrail' | 'permission' | 'privacy' | 'tool'`
and `PolicyDecisionState = 'allow' | 'deny' | 'needs-review'` (all three exported here). `label` is
host-supplied data rendered as-is, never localized (a rule name, or a tool name for `category:
'tool'`). `explanation` is an **always-visible** plain-text reason — `state` is never conveyed by
color alone; it tones the badge as `allow` → success, `deny` → danger, `needs-review` → warning,
while the always-visible explanation remains plain text. `detail` is optional richer evidence
(matched rule text, policy id) revealed through
progressive disclosure. Controlled and never mutated — pass a new array to update it.
`id` is the stable decision identity; empty/blank ids and later duplicates are omitted before counts, disclosure state,
and rows are derived.

**Events:** none. Read-only and display-only: this component never mutates a decision and offers no
resolve/acknowledge action — see `lr-tool-approval-dialog`/`lr-confirm-bar` for a real approve/deny
gate.

**CSS parts:** `base`, `empty`, `summary`, `count`, `state-badge`,
`list`, `decision`, `decision-header`, `category`, `label`, `detail`, `explanation`.

**Themeable custom properties:** `--lr-policy-summary-count-allow-color` (default
`var(--lr-color-success)`), `--lr-policy-summary-count-deny-color` (default
`var(--lr-color-danger)`) and `--lr-policy-summary-count-needs-review-color` (default
`var(--lr-color-warning)`) — the text color of each state's count in the summary strip. All three
follow the state-scoped-property convention described under `lr-span-waterfall`: inline `var()`
fallbacks rather than `:host` declarations, so each can be set on the element or on any ancestor.
They exist because `::part(count)[data-state='deny']` is invalid CSS — Shadow Parts forbids an
attribute selector after `::part()` — so retoning one state's count otherwise meant overriding the
library-wide status tokens and repainting every other surface reading them.
