Today
The Today surface is the daily landing page. It's a feed of agent-generated cards that surface what's changed, what needs your attention, and what's working — refreshed automatically each morning, on-demand any time.
Where most "dashboard" surfaces show static metrics, Today shows observations. A card isn't a number; it's an inference grounded in citations.
What you see
A vertical feed of cards. Each card has:
- Title — one-line summary of the observation.
- Body — 2–4 sentences explaining what happened and why it matters.
- Citation links — every number is hoverable; the citation drawer shows the source rows.
- Actions — context-appropriate (e.g. "Open deal", "Draft reply", "Schedule call").
- Card type tag — single neutral chip, no module color.
The card type tag is deliberately understated. Per DESIGN.md, modules share one neutral typography style — color isn't used to differentiate.
Card types
There are 9 card types as of the current release, across three categories:
Cross-domain (new in 2026)
| Type | What it asks |
|---|---|
pipeline_to_content_attribution | Which content touched the deals that closed this week? |
customer_health_from_engagement | Which customers have engagement patterns that look like churn precursors? |
top_contributing_accounts | Which accounts drove most pipeline movement, weighted by deal stage? |
Module-specific
| Type | What it asks |
|---|---|
pipeline_movers | Deals that changed stage this week, ranked by ARR impact. |
stuck_deals | Deals that haven't moved in N+ days, with suggested next action. |
content_calendar_gap | Days in the next 14 with no scheduled content. |
social_engagement_anomaly | Posts performing far above/below baseline. |
Filler
When the agent doesn't have signal-rich content, it generates educational cards rather than empty space:
| Type | What it shows |
|---|---|
weekly_summary | Plain-language roll-up of the week. |
tip_of_the_day | A platform usage tip relevant to your role. |
The filler types are visually identical to signal-rich cards — same layout, same chip — so the surface always feels populated even on quiet days.
Generation cadence
| Trigger | When |
|---|---|
| Nightly cron | 6 AM local time (per tenant timezone). Generates a full feed for the day. |
| Real-time invalidation | When a watched entity changes (e.g. a deal closes), affected cards regenerate. |
| User-triggered | "+ New card" button — pick a type, runs immediately. |
The nightly cron runs as a series of BullMQ jobs, one per card type per tenant, parallelized by the worker. A typical tenant's full Today feed generates in under a minute end-to-end.
The citation drawer
Click any underlined number, name, or chip in a card. The citation drawer slides in from the right showing:
- Source rows — the exact records that contributed to the claim.
- Aggregate breakdown — if the number is a sum/avg, the individual contributors.
- Query — the
graph_semantic_searchinvocation or dashboard query that produced the result, for transparency.
Hover-only (without click) shows a tooltip with the row count. Click opens the full drawer.
Card lifecycle
| State | Meaning |
|---|---|
generating | Worker is producing the card. Shown as a skeleton. |
live | Published to the feed. |
invalidated | Underlying entity changed; pending regeneration. |
archived | Older than 7 days; moved out of the feed but queryable in Archive. |
You can dismiss any card manually — dismissed cards don't reappear until their underlying observation re-triggers (e.g. the same deal goes stuck again).
Generating on demand
+ New card → pick from the registry of card types → submit. The
worker picks up the job, runs the card-type-specific subagent, and
posts the result back into your feed in ~30–60 seconds. The new
card appears at the top with a "Just now" timestamp.
Useful for:
- One-off "show me X" requests that aren't in the cron schedule.
- Testing how the agent will respond to a new card type before adding it to the cron.
- Quickly demoing the surface to a colleague.
Per-tenant customization
Admins can:
- Disable card types — toggles in Settings → Today.
- Adjust cron schedule — change the local-time anchor.
- Set tenant-wide filler ratio — what % of feed should be filler when signal is thin (default 30%, raise/lower per taste).
Individual users can dismiss cards but can't change the type registry — that's tenant-level.
Performance budget
Per card-type subagent: 3 tool calls average, 1 LLM round, p95 under 8 s. The bottleneck is usually the synthesis LLM call, not the data fetch. We optimize by:
- Caching dashboard query results within the same generation batch.
- Sharing context bundles between card types that read the same entities.
- Batching graph_semantic_search across card types when their queries overlap.