Guardrail List

The safety checks around a run and how each one landed, ordered by consequence rather than by execution. A skipped check is its own state — “we did not scan” and “the scan found nothing” are opposite facts.

src/components/ui/guardrail-list.tsx

About

From the component's own source, where it was written.

The safety checks around a run, and how each one landed.

Guardrails are the part of an agent people are asked to sign off on, so the list is ordered by consequence rather than by execution: everything that blocked comes first, then warnings, then passes. A screen that renders fifteen green rows and buries the one that blocked in the middle is technically complete and useless in a review.

**A skipped check is not a passing one.** skipped is its own state, drawn neutrally, because "we did not run the PII scan" and "the PII scan found nothing" are opposite facts and folding them together is how an unchecked output ships. Same reasoning for pending during a live run.

Counts come from the data rather than being passed in, so a summary cannot disagree with the rows beneath it.

Install

npx astralyx-ui add guardrail-list

Usage

import { GuardrailList } from '@/components/ui/guardrail-list'

<GuardrailList guardrails={rails} summary={(c) => `${c.block} blocked, ${c.warn} warnings`} />

Composer

Change the props and the source below follows.

1 blocked · 1 warning · 2 passed · 1 skipped
  • Spend cap

    tool

    issue_refund asked for £340, over the £200 per-run cap.

    Blocked
  • Prompt injection

    input

    A retrieved document contained instruction-like text. Quoted rather than followed.

    0.62Warning
  • Citation grounding

    output

    Skipped — the run was blocked before an answer was produced.

    Skipped
  • PII scan

    input

    No identifiers found in the prompt.

    48msPassed
  • Tone check

    output
    31msPassed
Props
tsx
<GuardrailList
  guardrails={rails}
  sorted={true}
  summary={(c) => `${c.block} blocked`}
/>

Examples

A blocked run

API

Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.

GuardrailList

The safety checks around a run, and how each one landed.

Extends Omit<ComponentProps<'div'>, 'children'>.

PropTypeDefaultDescription
guardrailsGuardrail[]required{ id, name, outcome, detail?, stage?, meta? }.
sortedbooleantrueWorst first. A screen that buries the one blocked check among fifteen green rows is complete and useless.
outcomeLabelsPartial<Record<GuardrailOutcome, string>>—Override any wording.
summary(counts: Record<GuardrailOutcome, number>) => ReactNode—Tallies come from the data, so a summary cannot disagree with the rows under it.
emptyLabelstring'No guardrails configured.'—
labelstring'Guardrails'—

Types

Guardrail

FieldTypeDescription
idstring—
namestring—
outcomeGuardrailOutcomeFive states, not three. Skipped and pending are distinct from passing, and collapsing them is how an unchecked output ships.
detail?ReactNodeWhat it checked, or why it landed the way it did.
stage?stringWhere it ran — 'input', 'output', a stage name.
meta?ReactNodeTrailing slot — a score, a duration, a link to the policy.
TypeDefinitionDescription
GuardrailOutcome
'pass' | 'warn' | 'block' | 'skipped' | 'pending'
—