Chrome AI Privacy Extension

MSN-002 · 2025 · chrome, gemini-nano, on-device-ml

Chrome extension using the Prompt API and Gemini Nano for on-device text classification. Runs entirely in the browser with no server-side inference.

Smart ScreenTime is a Manifest V3 Chrome extension that uses the browser's built-in Gemini Nano model to classify web content into one of twelve categories, then enforces a per-category policy based on a user-defined focus schedule. No text leaves the device at any point in the loop.

Why on-device classification

The standard approach — extracting page content and sending it to a remote inference endpoint — creates a persistent record of browsing context on a third-party server. Chrome ships with Gemini Nano already installed and exposes it through the experimental Prompt API. Using that instead costs nothing in privacy and adds no latency from a network round-trip. The trade-off is that the model is smaller, so I built a heuristic fallback for cases where the Prompt API is unavailable or returns a confidence score below the configured threshold.

Architecture: Manifest V3 Pipeline & Precedence Chain

┌────────────────────────────────────────────────────────────────────────────────────────┐
│ DOM / TAB CONTENT CONTEXT (Content Script • `document_idle`)                           │
│                                                                                        │
│   ┌───────────────────────────┐   ┌──────────────────────┐   ┌─────────────────────┐   │
│   │ TreeWalker Node Filter    │──►│ Metadata Extractor   │──►│ chrome.runtime      │   │
│   │ Strips nav/footer/sidebars│   │ OG tags, H1, videos  │   │ .sendMessage()      │   │
│   └───────────────────────────┘   └──────────────────────┘   └──────────┬──────────┘   │
└─────────────────────────────────────────────────────────────────────────┼──────────────┘
                                                                          │ IPC Message
                                                                          ▼
┌────────────────────────────────────────────────────────────────────────────────────────┐
│ BACKGROUND SERVICE WORKER (Event-Driven Precedence Chain)                              │
│                                                                                        │
│   [Tier 1: 15-Min Temp Overrides] ──(Hit: Allow)───────────────────────────────────┐   │
│                 │ Miss                                                             │   │
│   [Tier 2: Hostname Allowlist]   ──(Hit: Allow)───────────────────────────────────┤   │
│                 │ Miss                                                             │   │
│   [Tier 3: Hostname Blocklist]   ──(Hit: Block)───────────────────────────────────┤   │
│                 │ Miss                                                             │   │
│   [Tier 4: Dynamic Cache Check]  ──(Hit: Return Cached Decision)──────────────────┤   │
│                 │ Miss                                                             │   │
│                 ▼                                                                  │   │
│   ┌────────────────────────────────────────────────────────────────────────────┐   │   │
│   │ Is Chrome Prompt API Available?                                            │   │   │
│   │    ├── YES ──► Gemini Nano (`temperature: 0.1`) ──► Structured Category JSON   │   │
│   │    └── NO  ──► Heuristic Classifier (Keyword/Domain Matching Engine)       │   │   │
│   └─────────────────────────────────────┬──────────────────────────────────────┘   │   │
│                                         │ Category + Confidence Score              │   │
│                                         ▼                                          │   │
│   ┌────────────────────────────────────────────────────────────────────────────┐   │   │
│   │ Focus / Leisure Policy Matrix (Schedule-Driven Decision Engine)            │   │   │
│   └─────────────────────────────────────┬──────────────────────────────────────┘   │   │
│                                         │ Allow / Block Action                     │   │
│                                         ▼                                          │   │
└─────────────────────────────────────────┼──────────────────────────────────────────┘   │
                                          │                                              │
                                          ▼                                              │
┌────────────────────────────────────────────────────────────────────────────────────────┴┐
│ DOM MODAL INJECTION (When Blocked: Keyboard Trap Modal • CSS Isolation via Manifest V3) │
└─────────────────────────────────────────────────────────────────────────────────────────┘

Classification pipeline

The content script runs at `document_idle` with a 500ms debounce to handle SPA navigation. It extracts a cleaned text snippet (capped at ~1,200 characters) from semantic content elements — `

`, `
`, `[role="main"]` — while stripping nav, sidebar, and footer nodes using a `TreeWalker` with a custom `NodeFilter`. It also collects Open Graph metadata, the first `

`, and signals like `