/inbox is the first surface to consume the universal FilterBar. The
two-tab UI collapses into the bar's approval_viewer_role chip cluster
(per Q4 lock-in 2026-05-08 21:47); status / entity_type / time chips
are new affordances; density toggle gives the activity-feed look the
brief asked for.
Changes:
- system_views.go: InboxSystemView + InboxRequesterSystemView render
spec gains RowAction=approve so shape-list.ts knows which row
layout to stamp (entity title + diff + approve/reject/revoke).
- shape-list.ts: row_action='approve' branch — stamps the inbox-row
markup the surface owned today; surface attaches click handlers
via data-attrs on .views-approval-action / .views-approval-row.
- inbox.tsx: tab row replaced with <div id='inbox-filter-bar'> +
<div id='inbox-results'>. Heading + admin nudge unchanged.
- client/inbox.ts: shrunk to mountFilterBar with axes [time,
approval_viewer_role, approval_status, approval_entity_type,
density, sort]. Action handlers run via fetch + bar.refresh().
Legacy ?tab=mine -> ?a_role=self_requested redirect on mount so
bookmarks / sidebar bell still land on the right sub-view.
Build clean: bun run build + go build/vet/test all pass.