# Action Receipt

> Pattern 11 · Trust & transparency · part of Agent Consent Patterns.
> Human page: https://agentconsent.dev/patterns/action-receipt/

Consent doesn't end when the user clicks approve, and for a standing grant, there was no click at all. After the agent acts, the user needs a durable record: what it did, on exactly what, under what authority, and when, with a way to take it back where the action allows.

## Problem

Every consent pattern so far happens *before* the agent acts. But approval is a moment, and the action has a life after it. Where did the money go? Which messages got sent? And for anything an agent did under a standing grant, a Consent Memory "always" or an Automatic authority level, there was no approval moment at all; the action simply happened.

If that action leaves no trace the user can review, consent quietly degrades into trust-and-hope. The user can't notice a mistake, can't question a borderline call, and can't reverse something that shouldn't have happened, because there's no surface that says *this is what I did, and here's why I was allowed to*. Auditability here is the other half of consent: a grant the user can't see being exercised is a grant they can't really govern.

## Solution

Give every consequential action a receipt: a durable, reviewable record.

- **State what happened, exactly.** The action in the past tense, an outcome badge, and the concrete details (recipient, amount, file). These are the same facts the user would have approved, now preserved.
- **Name the authority.** Tie the action back to the grant, approval, or standing rule that permitted it. This is the receipt's distinct job: answering *why were you allowed to do this?*, which matters most for actions taken with no prompt.
- **Offer undo where the action allows.** A reversible action gets a real undo: consent extended past approval into the power to take it back. An irreversible one says so honestly, rather than dangling a button it can't honour.

> **Live demo** — an interactive Action Receipt demo runs on the page: https://agentconsent.dev/patterns/action-receipt/

The demo is the `ActionReceipt` component from `@agentconsent/react`. Undo recalls the send and flips the receipt to its Undone state. After that, it offers no second undo.

## Anatomy

> **Anatomy** — a labeled breakdown of the Action Receipt component's parts is shown on the interactive page: https://agentconsent.dev/patterns/action-receipt/

## When to use it

- **After any consequential action**, whether it was approved in the moment or taken under standing authority. The less a user was involved up front, the more a receipt matters.
- **As the landing surface after an [Action Preview](/patterns/action-preview/).** The preview approves; the receipt records the same facts, before and after.
- **Anywhere autonomy runs unattended.** An [Authority Boundary](/patterns/authority-boundary/) set to Automatic, or a [Spend & Rate Limits](/patterns/spend-rate-limits/) budget being drawn down, needs receipts so the user can review what happened while they weren't looking.

## When not to use it

- **Trivial, inconsequential actions.** A receipt for every read or every keystroke is noise that buries the actions that matter. Reserve it for acts with a real effect.
- **As a substitute for asking first.** A receipt is not permission to skip a needed [Action Preview](/patterns/action-preview/) or [Irreversibility Gate](/patterns/irreversibility-gate/). "We'll log it" is not consent for a high-stakes act that should have been confirmed.
- **When you can't actually honour the undo.** Don't show an undo affordance for something already gone; mark it plainly as irreversible instead.

## Real-world examples

- **Gmail's undo send.** The archetype: the action goes through, and the receipt arrives as a toast with a live reversal window. No pre-confirmation friction, full post-hoc control. The trade this pattern formalizes.
- **ChatGPT agent's activity view.** A step-by-step log of everything the agent did during a run, so when something goes wrong the user can trace exactly where. The agent-native version of the receipt, at run granularity.
- **Banking and card apps.** The transaction detail screen (what, when, how much, with dispute and reversal paths attached) is the receipt anatomy users already trust with their money; Stripe's dashboard event log is the same surface for developers.

*Annotated screenshots of these flows are being collected. Products are credited, annotations follow the site-wide callout conventions, and any screenshot is removed on request. See [About](/about/).*

## Accessibility

- The receipt is an `article` labelled by what the agent did, so assistive tech announces it as one named record, and its **title is a non-heading element** with an id, so a receipt drops into an activity log at any depth without breaking heading order.
- **The outcome is text, not colour.** Completed / Undone / Failed is spelled out; the tint is redundant.
- **Undo is a real button when it's real, and not there when it isn't.** An irreversible or already-undone action renders an inert note instead of a disabled-looking control, so a screen reader is never offered an action that can't be taken.
- Details, authority, and timing are marked up as description lists, so their label/value pairing survives without visual layout.

## Anti-patterns

- **The silent success.** Doing something consequential and showing nothing. The user finds out only when something breaks. If it was worth approving, it's worth a receipt.
- **A receipt with no authority.** Recording *what* happened but not *under what grant* leaves the user unable to tell an authorised action from an overreach. Name the authority, especially for anything done without a prompt.
- **A dangling undo.** An undo button that does nothing, errors, or "reverses" something already irreversible is worse than no button. It promises control that isn't there.
- **The unauditable standing grant.** Letting Automatic authority or an always-allow fire with no trace means the user granted power they can now never actually watch being used. Standing authority *most* needs receipts.
- **Vague summaries.** "Updated your calendar" instead of the exact event, time, and attendees. A receipt that can't be checked against reality isn't a record.

## Code

```tsx
import { ActionReceipt } from "@agentconsent/react";
import "@agentconsent/react/theme.css";

<ActionReceipt.Root
  outcome="completed"            // "completed" | "undone" | "failed"
  reversibility="reversible"     // "reversible" | "irreversible" → governs Undo
>
  <ActionReceipt.Header>
    <ActionReceipt.Icon>✉</ActionReceipt.Icon>
    <ActionReceipt.Title>Sent email to Dana Ito</ActionReceipt.Title>
    <ActionReceipt.Outcome />
  </ActionReceipt.Header>

  <ActionReceipt.Details>
    <ActionReceipt.Detail label="To">dana@northwindcap.com</ActionReceipt.Detail>
    <ActionReceipt.Detail label="Subject">Q3 board deck</ActionReceipt.Detail>
  </ActionReceipt.Details>

  <ActionReceipt.Authority
    grant="Standing grant · Send email"     // what permitted it
    via="always-allow · set Jul 2"
  />

  <ActionReceipt.Meta>
    <ActionReceipt.MetaItem label="When">Jul 9, 2:14 PM</ActionReceipt.MetaItem>
  </ActionReceipt.Meta>

  <ActionReceipt.Actions>
    <ActionReceipt.Undo onClick={recall}>Undo send</ActionReceipt.Undo>
  </ActionReceipt.Actions>
</ActionReceipt.Root>
```

`Undo` renders a button only when the receipt is `reversible` and not already
`undone`; otherwise it's an honest note ("Can't be undone", "Undone"). This is a
display surface, like Connection Card it takes no decision callbacks; wire
`Undo` to your own handler. All parts are unstyled primitives with `data-acp`
attributes; skip `theme.css` and style them yourself, or override the `--acp-*`
tokens to retheme.
