Approvals Inbox
The dedicated agent-to-owner communications surface. Every structured card any agent emits lives here — approvals, decisions, reports, milestones, errors, manual tasks — grouped by urgency and filtered by type.
How it works
Every agent in the system — the CEO, the 18 specialists, the
Evaluator — communicates with the owner through one mechanism:
the emit_owner_card MCP tool defined in
apps/engine/src/ceo/tools.ts. It\'s the canonical
and only sanctioned path. When an agent calls it, the engine
writes an AgentEvent to stdout as a
bb_event line; the API server streams that line
to the browser via SSE; the Inbox view (at
apps/web/src/views/Inbox.tsx) renders it as a
card.
There are exactly seven event types, declared in
apps/engine/src/events/types.ts:
approval_needed, manual_task,
report_ready, decision_required,
error_alert, milestone_reached, and
info. Four priorities — low, medium, high,
urgent — and four status values — pending, handled, dismissed,
expired.
Cards carry a shape: title,
description, optional reportContent
(Markdown body for reports), optional actions
(buttons), inputs (form fields), options
(pick-one), attachments (clickable files), and
metadata (free-form, including the
deliverableId that ties a card to an evaluator
verdict).
Trace events — ceo_thinking,
plan_proposed, plan_execution_started,
plan_execution_finished — share the same transport
but never reach the Inbox. The useAgentEvents
hook filters them out, and they drive dedicated Boardroom
components (ThinkingTrace, PlanIndicator) instead.
What you see in the UI
Four filter tabs across the top: Pending, Handled, Dismissed, All. A type filter for the 7 card types. Full-text search across titles and descriptions. Cards sort by priority-rank then by timestamp, so the urgent stuff surfaces first.
Each card header shows the agent\'s name and role, a type-coded icon (green check for milestones, red triangle for errors, amber flag for approvals), and a priority pill. Primary actions render as filled buttons; secondary as ghost; danger as red. Swipe-style interactions on mobile let you approve, dismiss, or hand back without opening the card.
A concrete example
Your Sales Specialist finishes the overnight cold-outreach
batch. It drafts 12 personalized first messages, each as an
approval_needed card with two actions:
Approve & send and Needs changes. You open
the Inbox at 7am, filter to Pending, swipe through the 12,
approve 9, reject 2, and ask for changes on 1. The Sales
Specialist picks up the verdicts and queues the approved
messages in SmartLead.
Technical details
// apps/engine/src/events/types.ts
export type AgentEventType =
| 'approval_needed'
| 'manual_task'
| 'report_ready'
| 'decision_required'
| 'error_alert'
| 'milestone_reached'
| 'info'
// Soft trace events — never reach the Inbox.
| 'ceo_thinking'
| 'plan_proposed'
| 'plan_execution_started'
| 'plan_execution_finished';
Blocking card types (approval_needed,
decision_required, manual_task)
pause the CEO\'s loop: emit_owner_card awaits
an owner response before returning. Non-blocking types
(info, milestone_reached,
report_ready, error_alert) fire
and forget. That\'s why a finished landing page arrives as
a single non-blocking card — the CEO is free to move on.
Related features
- Evaluator gate — why report_ready cards can\'t ship without PASS.
- Action Feed — the overnight-summary surface that links into the Inbox.
- The CEO agent — the primary emitter of cards.
Related concepts
FAQ
What are the seven event types?
approval_needed, manual_task, report_ready, decision_required, error_alert, milestone_reached, info. The type governs the icon, the color, and the default action set. The list is defined in apps/engine/src/events/types.ts and mirrored in the web-app types.
What's the difference between "approval" and "decision"?
An approval is yes/no on something the team has already drafted ("Send this email? [yes/no]"). A decision is a pick-one from options the team can't choose for you ("Which domain should I register: .com or .ai?"). Decisions use the EventOption array; approvals use EventAction.
Are soft events like "thinking" mixed into the Inbox?
No. ceo_thinking, plan_proposed, plan_execution_started, and plan_execution_finished are trace events that drive the Boardroom's ThinkingTrace and PlanIndicator components. useAgentEvents explicitly filters them out of the Inbox.
Can I attach files to cards?
Specialists can attach files to cards they emit — e.g. the business-ops specialist attaches a draft invoice PDF to a milestone_reached card. The attachments field on AgentEvent surfaces as clickable buttons beneath the card body.
Try Black Box
Swipe-fast approvals on the work the team can\'t finish without you. Everything else moves without interruption.