MVP / agentic
approval gate
A bounded action proposal that requires a human decision before execution, with optional rationale.
Specimen
A bounded action proposal that requires a human decision before execution, with optional rationale. Copy Preview, Code, or Install from the tabs. The raw file and standalone fixture remain below.
Preview
approval required
Write release-notes.md?
write-file · release-notes.md · actionId=write-release-notes-01 · exact action shown
Why this is safe
Draft only touches a new markdown file. No secrets or production paths.
Code
<style>
.au-approval-gate {
background: var(--au-surface);
border: 1px solid var(--au-border-emphasis);
border-radius: var(--au-radius-lg);
overflow: hidden;
}
.au-approval-gate__header {
align-items: start;
display: flex;
gap: 16px;
justify-content: space-between;
padding: 18px 20px;
}
.au-approval-gate__eyebrow,
.au-approval-gate__rationale-label {
font: 600 10px/1.3 var(--au-font-mono);
letter-spacing: 0.05em;
text-transform: uppercase;
}
.au-approval-gate__eyebrow {
color: var(--au-warning);
margin: 0 0 7px;
}
.au-approval-gate__title {
font-size: 16px;
letter-spacing: -0.02em;
line-height: 1.3;
margin: 0;
}
.au-approval-gate__aside {
align-items: center;
display: flex;
flex-shrink: 0;
flex-wrap: wrap;
gap: 8px;
justify-content: flex-end;
}
.au-approval-gate__shortcut {
background: var(--au-surface-muted);
border: 1px solid var(--au-border-color);
border-radius: var(--au-radius-sm);
color: var(--au-fg-subtle);
flex-shrink: 0;
font: 10px/1.3 var(--au-font-mono);
padding: 4px 8px;
white-space: nowrap;
}
.au-approval-gate__action {
background: var(--au-surface-muted);
border-top: 1px solid var(--au-border-color);
color: var(--au-fg-muted);
font: 11px/1.5 var(--au-font-mono);
margin: 0;
padding: 12px 20px;
}
.au-approval-gate__rationale {
border-top: 1px solid var(--au-border-color);
padding: 14px 20px;
}
.au-approval-gate__rationale-label {
color: var(--au-fg-subtle);
margin: 0 0 6px;
}
.au-approval-gate__rationale-body {
color: var(--au-fg-muted);
font-size: 14px;
line-height: 1.5;
margin: 0;
}
.au-approval-gate__footer {
border-top: 1px solid var(--au-border-color);
display: flex;
flex-wrap: wrap;
gap: 8px;
justify-content: flex-end;
padding: 12px 20px;
}
.au-approval-gate[data-au-state="success"] {
border-color: var(--au-success);
}
.au-approval-gate[data-au-state="error"] {
border-color: var(--au-danger);
}
</style>
<section class="au-approval-gate" data-au-state="waiting" aria-labelledby="approval-title">
<header class="au-approval-gate__header">
<div>
<p class="au-approval-gate__eyebrow">approval required</p>
<h2 class="au-approval-gate__title" id="approval-title">Write release-notes.md?</h2>
</div>
<div class="au-approval-gate__aside">
<span class="au-approval-gate__shortcut" title="Host-owned shortcut">⌘↵ Approve</span>
</div>
</header>
<p class="au-approval-gate__action">write-file · release-notes.md · 1 file · exact action shown</p>
<div class="au-approval-gate__rationale">
<p class="au-approval-gate__rationale-label">Why this is safe</p>
<p class="au-approval-gate__rationale-body">Draft only touches a new markdown file. No secrets or production paths.</p>
</div>
<footer class="au-approval-gate__footer">
<button class="au-btn au-btn--ghost" type="button">Keep editing</button>
<button class="au-btn au-btn--primary" type="button">Approve write</button>
</footer>
</section>Install
<link rel="stylesheet" href="tokens.css">
<link rel="stylesheet" href="components/approval-gate/approval-gate.css">Component contract
- Dependencies
tokens.css,approval-gate.css,button.css for actions.- States
- `waiting`, `success`, `error`, and `cancelled` are host-supplied decision states.
- CSS variables
- No component-specific variables. Action, warning, danger, and success semantics come from the token layer.
- Events
- Native form, focus, and click events. No custom event or runtime is required.
- No JavaScript
- The exact action, optional rationale, and native decision form remain visible. A normal POST can carry the decision without the runtime.
- Host boundary
- The host validates authorization, records the decision, executes or rejects the action, and owns stale-approval handling.
Accessibility and security
Accessibility: Use a labelled section, explicit action copy, native controls, and text labels. Never rely on border color alone. Security: Bind approval to an immutable action ID plus exact serialized tool name and arguments. Invalidate approval when any of them changes. Countdown or shortcut chrome must not imply silent approval.
Source files
The page is documentation, not a package boundary. Copy the raw files and edit them in your application.