---
title: Inbox Attention Analytics — how your inbox triage behaves
---

# Inbox Attention Analytics — how your inbox triage behaves

## What it is

> **Library page** — describes what users see and how it works, self-contained so an
> outside AI with no repo access can answer "what is Inbox Attention Analytics and how
> does it work?"

Inbox Attention Analytics is a built-in, **100% local** report on how you work your
Omniscio inbox — not what's in it, but how it *behaves*: how long items wait before you
clear them, how many pile up on average, how often you open an item and move on without
acting, and how long you spend looking at each one. It answers "where does my triage time
go?" and surfaces the answer in a new **Inbox** tab inside the Stats virtual project.

It is the inbox counterpart to [UI Usage tracking](ui-usage-tracking.md): both quietly
record lightweight signals on your own device and show you a picture of your own habits.
Nothing here ever leaves the machine.

## Where to find it

1. Open Omniscio.
2. In the project sidebar, open the **Omniscio** group and click **Stats** (chart icon).
3. In the Stats sub-sidebar, pick the **Inbox** tab (second, right under Overview).

The **Time Range** selector (Today / Yesterday / 7d / 30d / 90d / All) filters every
number on the tab, exactly like the rest of Stats.

## How it behaves

### What it shows

- **Four headline tiles** — **Avg time to clear** (how long an item waited before it left
  the inbox), **Avg items waiting** (the time-weighted average inbox depth over the
  window), **Looked without acting** (how many times you opened an item and moved on with
  no action, plus that as a % of views), and **Avg view time** (how long you spend on a
  single item per view).
- **Items waiting over time** — a per-day bar strip of the inbox depth at the end of each
  day in the window, so you can see the backlog rise and fall.
- **By type** — the same stats broken down by item *type* (session, SMS, daily digest,
  cron approval, alert, …).
- **By project** — broken down by the owning project (resolved to the project's name).
- **Top sessions** — the sessions you triaged most, with their clear/view stats.
- **Actions taken** — how items left the inbox: dismiss / approve / reject / snooze counts.

An empty state ("No inbox activity tracked yet — triage some inbox items and check back")
shows until there's data; a "Tracking since <date>" note shows how far back it goes.

### How the metrics are defined

- **Age / time to clear** — the interval from when an item first appeared in the inbox to
  when it left (you replied, approved, dismissed, snoozed, or it resolved on its own).
- **Average items waiting (depth)** — event-sourced: every arrival is +1 and every clear
  is −1, ordered over time, and the report computes the time-weighted average of that
  running depth over the window (there is no polling/sampling loop). Depth is clamped at 0.
- **Looked but didn't act** — a completed *view* counts as this when you opened the item
  and, by the time the view settled, the item was **still in the inbox** and no tracked
  action fired during it. If the item left the inbox (you resolved it), the view counts as
  *acted* instead. Sub-second views (auto-select flashes) are ignored.
- **View time** — how long a single item was the open item, per view.

### The setting, and privacy

- **On by default.** A **"Track inbox attention analytics"** toggle in **Settings →
  Diagnostics** turns it off; when off, no new events are recorded at all.
- **On-device only.** The report is built entirely from a local database and is **never**
  sent anywhere — it is deliberately kept out of the anonymous fleet-telemetry digest, and
  its table is classified so it is **never merged into a portable backup that moves to
  another machine**.
- **No content, ever.** Only bounded dimensions leave the renderer — the item **type**, the
  **project id**, and (for session items) the **session id** — plus the computed durations.
  No message content, titles, phone numbers, or raw item ids are stored; the correlation key
  the tracker uses to pair an arrival with its clear stays in memory and is never persisted.
- **Retention.** Events are pruned after **90 days** (and above a row cap) by the same local
  background sweep that prunes the other local logs.

### Limits

- View time and looked-but-didn't-act only count while the app is open on the item.
- Depth history builds **forward** from when tracking started — there's no backfill of inbox
  activity from before install.

## For agents

### How it works

The inbox is a live aggregation with no persistent per-item record, so capture is
**renderer-driven**. `InboxAttentionTracker.tsx` (a null-rendering leaf mounted once in
`App.tsx`, isolated so its subscriptions never re-render the app shell) watches
`useVisibleInboxItems()` + `useActiveInboxItem()` and drives `lib/inbox-attention-tracker.ts`:

- It **diffs** the visible list to detect arrivals and clears, holding a departure briefly
  to debounce a re-fetch **flicker**, and **suppresses the launch snapshot** (items already
  present when a run starts emit no arrival, so depth can't double-count across a restart).
- It tracks which item is **open** to time views, deciding looked-but-didn't-act by whether
  the item survived in the inbox.
- `markInboxItemActed(...)` is called beside the existing triage sinks (dismiss in
  `active-inbox-item-actions.ts`, approve/reject in `inbox-actions.ts`, snooze at the
  renderer snooze chokepoint) — fire-and-forget, never throwing into the click path.

Finished events are buffered and fire-and-forget flushed over the `inbox-analytics:record`
IPC channel (an auto-discovered handler) into a dumb-storage `inbox_item_events` SQLite
table. The windowed report is a Stats channel (`stats:inbox-analytics-report`) read by the
Stats store like every other tab. Full invariants + the tests that lock them:
`.claude/memory/contracts/inbox-analytics-contract.md`.

### Data source & CLI access

Reads only the local `inbox_item_events` table — no network calls, no data leaves the
machine. Like the rest of Stats, the report has **no CLI control-server route**; it's a
read-only renderer surface. An agent that needs these numbers reads the local DB directly.

## Related

- [Stats](stats.md) — the parent virtual project (cost, tokens, time, spend, feature usage).
- [UI Usage tracking](ui-usage-tracking.md) — the sibling local "how you use the app" report.
- [Inbox overview](inbox-overview.md) — the unified inbox these metrics measure.
- [Inbox Pilot](inbox-pilot.md) — the AI that triages the inbox for you (a different system).
