# Privacy — Tabby

**Plain version:** Tabby watches *how many* tabs you have, not *what's in them.*
By default nothing leaves your browser. Two opt-in/necessary exceptions, both
covered below: Pro license validation, and **AI dialogue** (off by default).

## What Tabby stores

Only **numbers and short labels**, in `chrome.storage.local` on this device:

| Stored | Example | Why |
|--------|---------|-----|
| Tab count | `34` | Drives the pet's state |
| Per-tab category | `"news"`, `"shopping"`, `"neutral"` | Picks the right food/reaction |
| Derived counts | `duplicates: 2`, `twitterTabs: 3` | Easter-egg modes |
| Happiness / inventory | `72`, `["🍔","🥦"]` | The toy itself |

## What Tabby NEVER stores

- ❌ URLs
- ❌ Page titles
- ❌ Browsing history
- ❌ Form data, passwords, cookies
- ❌ Anything from **incognito** tabs (counted, never inspected)

## What Tabby NEVER does

- ❌ No analytics. No telemetry. No ads. No tracking.
- ❌ No network requests except Pro license validation and — only if you enable
  it — AI dialogue (see below). Nothing else is ever sent.
- ❌ No account, no sign-in, no cloud sync (V1).
- ❌ No selling/sharing data — there is no data to sell.

## How "toxic site" detection works

`content.js` runs locally on the page, reads the host + title, and decides a
**category string** (e.g. `"negative-news"`). It sends *only that one word* to
the background worker. The URL and title stay on the page and are discarded.

The background worker briefly reads `tab.url` only to count duplicates and spot
3+ Twitter/X tabs, then throws the URL away — it is never written to storage.

## Permissions, justified

| Permission | Used for | Could we drop it? |
|-----------|----------|-------------------|
| `tabs` | Count tabs, detect duplicates, close tabs to "feed" | No — core feature |
| `storage` | Save pet state locally | No |
| `alarms` | 1-min tick for time-based checks | No |
| `<all_urls>` content script | Classify the current page locally | Needed to react to site type |

## Side panel

The side panel shows a **live list of your open tabs** (title + favicon) so you
can drag them onto the pet to close them. This list is read on demand straight
from the browser and **rendered locally** — it is never written to storage and
never sent anywhere. Close the panel and it's gone.

## On-device AI (negative-news detection)

For pages on news domains, `content.js` passes the **page title** to a local
TensorFlow.js model (in an offscreen document) that scores it as
sensational/negative or not. Then:

- The model and its weights are **bundled in the extension** (`model/headline`,
  `vendor/tf.min.js`). There is **no network call** — inference is 100% local.
- The title is used only to compute one number, then **discarded**. It is never
  stored, logged, or transmitted. Only the resulting label (`"negative-news"` or
  `"news"`) is kept — a single word.
- Runs on the CPU backend (no remote code, no `eval`).

## AI dialogue (optional, OFF by default)

Tabby's pet lines are normally **canned** (written into the extension, picked
locally). You can optionally turn on **AI dialogue** (long-press the pet →
"🤖 AI dialogue") to have its click-chatter generated by a model instead.

When — and only when — this is enabled:

- On a click, the extension sends a small **mood snapshot** to Tabby's server
  (`api.feedtabby.app/api/dialogue`): pet state (e.g. `STRESSED`), active
  easter-egg mode, **tab count** (a number), the 0–100 care stats, hour of day,
  and pet type. That's it.
- It **never** sends URLs, page titles, history, or tab contents — the same
  things it never stores. The snapshot is the same coarse data used to drive the
  pet locally.
- The server runs the model (Cloudflare Workers AI) and returns one short line.
  **Nothing is stored** server-side — no snapshot, no output, no logs of content.
- Turn it off any time and Tabby goes back to 100% local canned lines.

## Server-side security (Cloudflare WAF)

Tabby's API sits behind Cloudflare's Web Application Firewall. This is standard
CDN/infrastructure protection — it is **not** a Tabby feature that inspects your
data. Specifically:

- Tabby detects **ANOMALOUS patterns only** (unusual request rates, known attack
  signatures). It **NEVER** reads, stores, or transmits personal data — no URLs,
  no page content, no browsing history, no form inputs, no passwords.
- The data sent to the server is your license key for Pro validation, plus —
  only if you enable AI dialogue — the coarse mood snapshot described above.
  Nothing else leaves your browser.
- Cloudflare, as a standard CDN, sees your **IP address and request metadata**
  (headers, timing). This is inherent to how the internet works and is not
  controlled by Tabby. Cloudflare does not share this data with us.
- The extension's local threat detection (ad blocking, miner detection) looks
  at **structural patterns only** — request frequency, script behavior, known
  malicious signatures. It never inspects page content, form fields, or
  personal information.

If we ever add sync or accounts, it will be **opt-in** and documented here first.
