* feat(stack): per-stack activity timeline with actor attribution
Adds an Activity tab to the Stack Anatomy panel showing a timestamped
event log for each stack: deploys, restarts, starts, stops, and image
updates, attributed to the user who triggered them or 'system' for
automated actions.
Backend:
- Extends notification_history with actor_username column (idempotent
migration) and a partial composite index on (node_id, stack_name,
timestamp DESC) for efficient per-stack lookups.
- NotificationService.dispatchAlert() accepts an optional actor that
is written to the new column.
- Success-side dispatchAlert calls added after deploy, bulkContainerOp
(start/stop/restart), and update handlers in routes/stacks.ts so
user-initiated operations are recorded, not just failures.
- New GET /api/stacks/:stackName/activity?limit&before endpoint with
stack:read permission gate and cursor-based pagination.
Frontend:
- StackAnatomyPanel grows an Anatomy / Activity tab pair using the
existing Tabs primitive.
- StackActivityTimeline fetches the initial 50 events, paginates on
demand, and prepends live events arriving over the existing WS
notifications stream without duplicates.
- NotificationPanel bell dropdown suppresses user-initiated success
events (start/stop/restart/deploy/update triggered by a real user),
keeping the tray focused on alerts and system events.
* docs(stack): add stack activity timeline feature page and internal arch docs
* fix(test): add actor_username to notification-routing history assertions
dispatchAlert now passes actor_username to addNotificationHistory after
the activity timeline PR added the column. Update the two exact-match
assertions that were failing because the expected object shape was missing
this field.