Omniscio documentation
Browse all documentation
  1. Getting Started13
  2. Sessions & Agents115
  3. Inbox & Notifications59
  4. Projects & Tasks95
  5. Automation & Scheduling75
  6. Knowledge & Memory26
  7. AI Features60
  8. Integrations100
  9. Plugins & Marketplace33
  10. Cloud & Teams56
  11. Settings & Customization58
  12. Account & Billing28
  13. Troubleshooting84
  14. CLI & API Reference22
  15. Legal & Policies4
  16. Uncategorised22

Email Cleanup

The Gmail Clean Up tool: it works out who matters to you, then walks you through archiving, unsubscribing and deleting in bulk — with the safety guarantees that keep a bulk action from being irreversible.

What it is

RETIRED SURFACE (2026-08-27): the standalone Email Cleanup sidebar panel (__email_cleanup__) is retired in favor of the Inbox Concierge mission (Missions hub — missions-hub.md). Its sidebar row is hidden for everyone (the Dashboard visibility filter) and any stale pointer redirects to the Inbox. Everything below — the cleanup ENGINE, its safety guarantees, the /gmail/cleanup/* routes, and the ✨ Clean Up button inside the Gmail inbox — is UNCHANGED and still works. Only the standalone sidebar entry was removed.

Email Cleanup is the Gmail "Clean Up" tool, reimagined as an AI-guided walkthrough and originally given its own first-class sidebar home (that standalone panel is now RETIRED — see the note above; the engine described here is unchanged). It first works out who matters to you — your bank and other high-consequence senders, colleagues on your own company domain, people you write back to, and anyone you've explicitly chosen to keep — and never recommends removing them (the trust fix: no more "unsubscribe from your bank"). For everything else it judges each sender from your real behavior — Gmail's own category, how much of their mail you read, and how you dispose of it (archiving vs deleting) — to recommend an action with a reason that cites the numbers ("You've opened 2 of their 40 emails"). The primary way to clean up is now a chat box — ask in your own words ("unsubscribe from all promos, keep anything from my bank") and it proposes the changes for you to confirm — with the group-by-group walkthrough (one-tap batch cleanup, always confirmed) kept a tap away in a collapsed Browse by category section. A Protected Senders panel lets you manage who's kept, and self-sent + automated system mail gets its own lane. The classic flat sender-list is preserved one toggle away. It is the SAME execution engine (and the same safety guarantees) as the ✨ Clean Up button inside the Gmail inbox — the who-matters intelligence and the front door are what's new.

Where to find it

UI surface

  • Sidebar row "Email Cleanup" — RETIRED (2026-08-27). The standalone __email_cleanup__ sidebar panel no longer renders (hidden for all users via the Dashboard visibility filter); its virtual-project sentinel + panel component (EmailCleanupView.tsx) stay in-tree but dormant. Reach the cleanup via the in-Gmail ✨ Clean Up button (below) or the Inbox Concierge mission — see missions-hub.md.
  • The ✨ Clean Up button inside the Gmail inbox toolbar is unchanged and still works — the tool is reachable from both places. Both entry points render the same view.
  • The walkthrough is chat-first. It shows a smart summary ("N emails from M senders"), then a chat box as the primary surface — a welcoming "Tell me what to clean up" prompt with tappable example requests when it's empty, and a message box pinned front-and-center at the bottom. The click-through category stages (Promotions, Newsletters, Receipts, Social, Updates, People, Automated & self-sent, Likely-spam) — each with the AI's recommendation + reason, a one-tap Clean up batch, and per-sender drill-in — are shrunk into a collapsed "Browse by category" disclosure you can open to do it yourself. A protected sender shows a shield + a plain "kept because" reason (e.g. "Important account mail") so you can see why it is kept, and a collapsible Protected Senders panel lets you view / add / remove who is protected by email address or whole domain.
  • Because the tool reads and archives your Gmail, the panel needs Gmail connected. If it isn't, the panel shows the shared Connect Gmail / Reconnect Google gate (the same one the Gmail inbox uses).
  • Renders on desktop and mobile (it mounts through the standard sidebar panel host; no new push channels, so it stays within the mobile contract).
  • Rollback: Settings → Gmail → Classic Email Cleanup Layout (emailCleanupClassicLayout, default off) restores the original flat sender list instantly.

How it behaves

How it works

Selecting Email Cleanup mounts a thin panel (EmailCleanupView.tsx) that self-checks the Gmail connection (a brief "Checking your Gmail connection…" spinner so you never see a false "not connected" flash), gates on it (shared GmailConnectGate when not connected), and on entry auto-starts the inbox scan. It then renders GmailCleanupView.tsx, which branches:

  • Default → the AI walkthrough (GmailCleanupWalkthroughView.tsx):
    1. Scan enriches with a free behavior signal. The scan sweeps your whole inbox (bounded by a high safety ceiling, not just the most recent page) and groups by sender; from the message labelIds it ALREADY fetches, it tags each sender with Gmail's own category (Promotions / Social / Updates / …) and how many of their scanned messages are unread — zero extra API calls.
    2. Who-matters protection FIRST, then behavior. A Main-process call runs a shared decision engine over EVERY sender. It first resolves who is protected — your explicit keep-list, high-consequence senders (bank / payments / tax-gov / account-security) that pass an "is this real?" legitimacy gate (a bulk-marketing sender wearing a financial-sounding name — Gmail Promotions — is never mistaken for your bank), your own organization domain (derived from the connected account and its verified "send mail as" identities, so it works even when you've connected a personal Gmail), people you correspond with, and contacts the profile-miner already knows you know (consumed read-only) — and a protected sender is never a removal candidate (a confident keep with a generic, no-PII reason). Your explicit keep/remove choices persist in a soft-deleted store and take precedence over every auto-rule on the next scan. For the rest it judges the lifetime engagement signal — read-rate, reply-rate, and how you dispose of the mail (archive-rate + delete-rate) — via cheap count-only Gmail queries (resultSizeEstimate, no message bodies). Deleting a sender's mail is active rejection, so a consistent delete-rate drives a confident removal even at a high read-rate; a passive open-rate alone never does. Self-sent + transactional-automation senders route to their own Automated & self-sent lane — and a non-marketing service notification (CI, forums, account alerts) is filed there rather than mislabeled unsubscribe, even when it carries an unsubscribe header; only genuine marketing is ever unsubscribed. The engine makes the confident calls itself with a reason that cites the numbers; only genuinely ambiguous senders (low confidence) escalate to a stronger (Sonnet-tier) model. Groups render instantly and enhance when the classify lands — never blank, never hard-depends on the model (offline / no key / daily cap / breaker → the deterministic verdicts still stand, source:'ai').
    3. Chat is the primary surface. The chat box — front-and-center, with a "Tell me what to clean up" welcome + tappable example-request chips before you type — turns free-form requests ("unsubscribe from all promos, keep anything from my bank") into proposed action batches you approve. The chat never executes anything itself, and clicking an example chip only fills the box (it never sends), so you always review before anything happens.
    4. Guided batches (always-ask), in the "Browse by category" fallback. Open the collapsed Browse by category disclosure to work through it by hand: each category stage's header reflects its real dominant recommendation — Clean up N when there's a confident actionable subset, Review N when the recommendations are present but low-confidence (act per-row), and Recommended: keep only when the group genuinely should be kept. A low-confidence group never collapses into a false whole-group "keep" (the label is decoupled from the confidence-gated batch). The one-tap Clean up N runs every confident sender's recommended action in a single batch — one bulk archive, one undo, one toast. Nothing fires without a confirm dialog; keep senders are never touched, and a low-confidence recommendation is excluded from the batch (below BATCH_MIN_CONFIDENCE) — you can still act on it per-row, so a one-tap never acts on a guess.
  • Rollback → the classic flat list (GmailCleanupClassicView, same file) when emailCleanupClassicLayout is on: scan-by-sender with per-sender Archive / Unsubscribe + Archive / Never again, exactly as before.

Execution is unchanged either way. Every archive / unsubscribe / auto-archive filter still flows through the existing main-process engine and IPC — the AI only reasons, it never bypasses a safety guarantee (SSRF-guarded one-click unsubscribe, replied-to/starred protection, undo). The model runs ONLY on the ambiguous residual (Sonnet-tier) behind a $0.50/day cap (a local-midnight day, charged against the email-cleanup cost label — there is no setting for it), with injection-safe prompts (sender subjects are treated as untrusted data) and every model-returned address validated against the scanned set; the count-queries are read-only and need no new Gmail permission. See the cleanup contract (.claude/memory/contracts/gmail-inbox-cleanup-contract.md) for the full invariant list (1–10 engine, 11–20 AI + signal layer, 21–23 whole-inbox scan · real-recommendation group label · read-only CLI route, 24–33 the who-matters trust layer — protection-first, memory precedence, mined-by-source-message, generic no-PII reasons, soft-delete store, own-domain (account + verified send-as identities, freemail-excluded), archive/delete discard signal, self-sent/automation lane, the shield protection flag, and the legitimacy gate — a marketer is never granted operational protection, and a service notification is never mislabeled unsubscribe).

For agents

Code references

  • Branch wrapper + classic view: GmailCleanupView.tsx
  • AI walkthrough UI: GmailCleanupWalkthroughView.tsx; shared per-sender row + confirm copy: gmail-cleanup-shared.tsx
  • AI module (Main, deterministic-first + LLM residual): gmail-cleanup-ai.ts; the shared decision engine + grouping + dominantGmailCategory + discard signals + self-sent/automation lane: gmail-cleanup-heuristic.ts; count-query helper estimateCount: gmail-read.ts
  • Who-matters protection resolver (memory / operational / own-domain / mined, read-only): cleanup-who-matters.ts; shared real-person-vs-bulk primitive: gmail-sender-kind.ts
  • Protected-senders MEMORY store (soft-deleted, reactivating) + management UI: verdicts.ts, cleanup-memory-types.ts, migration 20260817233911-add-cleanup-sender-verdicts-table.ts, panel GmailCleanupProtectedSenders.tsx
  • Store (classification + chat + batched actions): gmail-cleanup-store.ts
  • IPC: gmail:cleanup-classify + gmail:cleanup-chat (read-only), plus the verdict-memory writes gmail:cleanup-set-verdict / -delete-verdict / -list-verdicts, in gmail-handlers.ts
  • Read-only CLI analysis route + shared senderToCleanupInput projection: gmail-mail-routes.ts, gmail-cleanup-heuristic.ts
  • Standalone panel + connect gate: EmailCleanupView.tsx, GmailConnectGate.tsx
  • Execution engine (unchanged): gmail-cleanup-service.ts, gmail-list-unsubscribe.ts, ssrf-guard.ts
  • Rollback setting: emailCleanupClassicLayout in channels-settings.ts, surfaced in GmailSettings.tsx

CLI

One read-only analysis route: GET /gmail/cleanup/analysis (bearer-auth, read-scoped, read-budgeted). It runs the same scan + reason-only classify so an agent or script can drive and verify the recommendations without touching the desktop UI — it returns the grouped recommendations (per-group category, label, sender/email counts) plus the per-sender classifications and the classify source. ?limit= (default a fast 500-message sample, up to the whole-inbox ceiling) trades speed for coverage. It never executes an action: the route module intentionally does not import the archive / unsubscribe / auto-archive-filter functions, so a CLI caller can analyze but can never fire a destructive Gmail action — a build guard (gmail-cleanup-cli-route-readonly.test.ts) asserts that import boundary. Every real cleanup action stays confirm-gated in the desktop UI; the two AI calls remain renderer-driven IPC (the manifest still declares no cliSkillIds). The who-matters memory is CLI-manageable too — POST /gmail/cleanup/memory/set (protect/unprotect a sender or whole domain), POST /gmail/cleanup/memory/delete, and GET /gmail/cleanup/memory/list — so an agent can curate your protected-senders list; these write only the local keep/remove verdict store, never a Gmail action.

Related

See also

  • gmail-integration.md — the Gmail inbox, the in-inbox Clean Up button, and every cleanup action in detail
  • INDEX.md

Last verified 2026-09-28