# BIBIVIDI — TODOS.md
> Tracked decisions from CEO plan reviews (2026-03-13, 2026-03-15). Build-now items are NOT here — see commit log.

---

## P1 — Required before beta launch

### ~~TODO-01~~ — ✅ SHIPPED — Sandbox: migrate to process isolation (seccomp/nsjail)
**What:** Replace the Python import-blocking sandbox with OS-level process isolation. On Linux: `seccomp` BPF filter via `python-seccomp` or `nsjail`. On macOS: `sandbox-exec` profile. Skills run in a subprocess with no filesystem access, no network, no process spawning — enforced by the kernel, not Python.

**Why:** The current `builtins.__import__` replacement is bypassable by any CPython built-in C extension (`ctypes`, `gc`, `_thread`). A malicious BSS skill from the marketplace could exfiltrate API keys or spawn processes. One public exploit kills the product's trust model permanently.

**Pros:** True security guarantee. Required for safe marketplace distribution. Aligns with Phase 3 WASM plan (seccomp is the bridge).

**Cons:** Platform-specific implementation (Linux vs. macOS vs. Windows). Windows has no seccomp — needs a Docker fallback or a `--no-sandbox` flag for Windows users.

**Context:** `bvd/engine/runner.py:77` — `asyncio.create_subprocess_exec(sys.executable, "-c", wrapped, ...)`. Add seccomp filtering here. The SANDBOX_WRAPPER can be simplified once OS-level isolation is in place.

**Effort:** M | **Priority:** P1 | **Depends on:** Nothing

---

### ~~TODO-02~~ — ✅ SHIPPED — Generator: add pending approval state before execution
**What:** Generated skills start in `status = "pending"`. They are saved, embedded, and matched normally, but `run_script()` checks the status and skips execution (falls through to pass-through) until the user approves via `bibividi review` / `bibividi approve <skill-id>`. The `/bibividi/ui` dashboard shows pending skills with a "Review & Approve" button.

**Why:** The generator calls an LLM and executes whatever Python it returns on the next matching request. A hallucinated `skill_py` that calls `exec()` or a prompt-injected skill could run dangerous code. One auto-executed bad generation and the product's trust is gone.

**Pros:** Trust-first design. Users see what BIBIVIDI wants to run before it runs. Creates a natural "BIBIVIDI learned something, go review it" engagement loop.

**Cons:** Adds friction — generated skills don't activate immediately. Mitigate with a clear `bibividi review` CLI command and a notification ("1 new skill pending review").

**Context:** `bvd/engine/library.py:48` — add `status: str = "active"` to `Script` dataclass. `bvd/engine/library.py:21` — add `status TEXT NOT NULL DEFAULT 'active'` to DDL. `bvd/engine/runner.py` — add status check before execution. `bvd/cli.py` — add `bibividi review` and `bibividi approve <id>` commands.

**Effort:** S | **Priority:** P1 | **Depends on:** TODO-03 (schema migration)

---

## P2 — Required before public launch

### ~~TODO-03~~ — ✅ SHIPPED — SQLite schema migration system
**What:** Add a `schema_version` table to `library.db`. On startup, compare current version against expected. Apply incremental SQL migration scripts (e.g. `migrations/002_add_status_column.sql`). Can be as simple as a hand-rolled version check — Alembic is overkill here.

**Why:** Once `~/.bibividi/library.db` is on beta users' machines, every schema change (new column, new table, changed type) requires migration. Without it, upgrading BIBIVIDI corrupts or silently ignores new features (e.g. the `status` column from TODO-02 won't exist on existing installs).

**Pros:** Safe upgrades. Users don't lose their skill library. Required for any schema change in Phase 2+.

**Cons:** Small ongoing maintenance burden for each schema change.

**Context:** `bvd/engine/library.py:77` — `library.init()` is the right place to run migrations before DDL.

**Effort:** M | **Priority:** P2 | **Depends on:** Nothing

---

### ~~TODO-04~~ — ✅ SHIPPED — Web dashboard at /bibividi/ui (React + Vite, served from FastAPI)
**What:** A React (Vite) single-page app served as static files from a new `/bibividi/ui` FastAPI route. Features for Phase 2: live request feed (skills matched, scores, before/after sizes), savings graph, pending skill review queue. This replaces Tauri for Phase 2. Tauri wraps this same bundle in Phase 3.

**Why:** 20 beta users need a way to see what BIBIVIDI is doing without reading logs. A web UI at `http://localhost:8080/bibividi/ui` requires zero install, works on every OS, and is the foundation for the Tauri app.

**Pros:** Fast to ship (no Rust, no code signing, no app store). Same UI reused in Tauri. Live request feed is the product's best demo moment.

**Cons:** Adds a JS build step to the Python project. Bundle must be committed or built at install time.

**Context:** New `bvd/ui/` directory. `bvd/core/proxy.py` — add `app.mount("/bibividi/ui", StaticFiles(...))`. FastAPI `StaticFiles` serves the built bundle.

**Effort:** M | **Priority:** P2 | **Depends on:** Nothing (can start in parallel with P1 items)

---

### ~~TODO-05~~ — ✅ SHIPPED — bibividi calibrate command
**What:** A CLI command that takes a set of sample prompts (or reads from `~/.bibividi/test_prompts.json`) and runs them against the installed skills, reporting: best match score for each, whether it exceeds the current threshold, and a suggested threshold value.

**Why:** The match threshold is a critical tuning parameter. Too low (0.50) → false positives that corrupt responses. Too high (0.90) → nothing ever matches. `calibrate` turns this from a magic number into a data-driven decision.

**Pros:** Removes guesswork from threshold tuning. Valuable for enterprise customers with specialized vocabularies.

**Cons:** Requires sample prompts — first-time users have none. Could bootstrap from recent request history.

**Context:** `bvd/cli.py` — add `@cli.command()`. Uses `matcher.match()` internally with a range of thresholds.

**Effort:** S | **Priority:** P2 | **Depends on:** Nothing

---

### ~~TODO-06~~ — ✅ SHIPPED — Ed25519 signature verification for BSS packs
**What:** Implement the `skill.sig` + `pubkey` fields defined in the BSS v1 spec (MVP.md). When importing a skill pack, verify the Ed25519 signature of `skill.py` against the `pubkey` in `skill.json`. Use the `cryptography` library (already likely in the dependency graph via `certs.py`).

**Why:** SHA-256 hash (currently implemented) verifies integrity but not authenticity. Without signatures, anyone can create a skill with a matching hash. Ed25519 signatures bind the skill to its author's keypair — required for a trusted marketplace.

**Pros:** Completes the BSS v1 security model as specced. Enables author reputation on the marketplace.

**Cons:** Requires key management (authors need a keypair). Can be optional for local skills (signature field absent = hash-only verification).

**Context:** `bvd/engine/library.py:186` — `import_bss()` currently only verifies hash. Add signature check here. `bvd/engine/certs.py` already uses `cryptography` — reuse it.

**Effort:** M | **Priority:** P2 | **Depends on:** Nothing

---

## P2 — Delight features

### ~~TODO-07~~ — ✅ SHIPPED — BIBIVIDI_DRY_RUN=true mode
**What:** When `BIBIVIDI_DRY_RUN=true`, the proxy runs the full match pipeline (embeds the prompt, finds the best skill, runs the script) but does NOT inject the condensed result. Instead it logs: `[DRY RUN] Would have condensed: X tokens → Y tokens (Z% saving)`. The original request is forwarded unchanged.

**Why:** New users need to trust BIBIVIDI before they let it modify their requests. Dry run is the onboarding bridge — "see the savings without taking the risk." Every developer who sees the log will be converted.

**Pros:** Zero-risk onboarding. Great for demos. Builds trust before users enable live mode.

**Cons:** None — XS effort.

**Context:** `bvd/config.py` — add `dry_run: bool = False`. `bvd/core/proxy.py:143` — add dry-run branch after match.

**Effort:** XS | **Priority:** P2 | **Depends on:** Nothing

---

### ~~TODO-08~~ — ✅ SHIPPED — Weekly savings digest (desktop notification + optional Slack webhook)
**What:** Every Monday morning, BIBIVIDI computes the week's savings from the `executions` table and sends: tokens saved, estimated $ saved, CO₂ equivalent (tokens × 0.003 gCO₂eq), top skill used. Delivered via OS desktop notification (`plyer` or `notify-py`) and optionally a Slack webhook URL configured via `BIBIVIDI_SLACK_WEBHOOK`.

**Why:** The savings are already tracked in SQLite. The CO₂ + $ framing is BIBIVIDI's best marketing message. A message that says "BIBIVIDI saved you $340 this week and 12 kg CO₂" gets forwarded to CFOs and posted on LinkedIn. This is the viral loop.

**Pros:** Zero extra data collection (uses existing stats). Drives engagement, retention, and word-of-mouth. Foundation for the CSRD/ESG reporting feature.

**Cons:** Requires a background scheduler (APScheduler or a cron job). Adds a dependency.

**Context:** `bvd/engine/stats.py` — add `weekly_summary()` method. New `bvd/notifier.py`. `bvd/cli.py` — add `bibividi digest --now` to trigger manually.

**Effort:** S | **Priority:** P2 | **Depends on:** Nothing

---

### ~~TODO-09~~ — ✅ SHIPPED — bibividi simulate <requests.json>
**What:** A CLI command that takes a JSON file of request logs (same format as the real API — array of `{messages: [...]}` objects) and runs them through the matching engine without calling the AI API or modifying anything. Reports: which requests matched, which skill, the condensed output, and total tokens/$ saved.

**Why:** This is the enterprise sales tool. A prospect can export their last week of AI logs, run `bibividi simulate logs.json`, and see their exact ROI before signing up. Nothing closes a deal faster than "you would have saved $12,000 last month."

**Pros:** Zero AI API cost to demonstrate value. Powerful presales tool. Also useful for debugging skill coverage.

**Cons:** Requires users to have request logs. Need to document the expected format.

**Context:** `bvd/cli.py` — add `@cli.command()`. Reuses `matcher.match()` and `run_script()` directly.

**Effort:** S | **Priority:** P1 | **Depends on:** Nothing

> **Priority elevated P2 → P1 (2026-03-14 CEO review):** `bibividi simulate` is the enterprise sales closer. A prospect who sees "you would have saved $12,000 last month" converts. It must work before enterprise outreach begins, not after.

---

### ~~TODO-10~~ — ✅ SHIPPED — bibividi feedback bad <request_id> (trust feedback loop)
**What:** Users can flag a request where BIBIVIDI produced a wrong output. The flagged skill gets its per-skill match threshold raised (or it enters a "needs review" state). Flags are stored in the `executions` table (`feedback` column). The `/bibividi/ui` shows flagged skills prominently.

**Why:** Without a feedback mechanism, bad skills accumulate silently. The trust feedback loop is what makes BIBIVIDI's quality self-improving. For the marketplace, aggregated feedback (anonymized) is how skill authors know to improve their packs.

**Pros:** Makes quality self-improving. Creates natural engagement ("go review flagged skills"). Foundation for marketplace ratings.

**Cons:** Requires request IDs to be tracked (add `X-BIBIVIDI-Request-ID` header to all proxied requests).

**Context:** `bvd/engine/stats.py` — add `feedback` column to executions. `bvd/cli.py` — add `bibividi feedback bad <request_id>`. `bvd/core/proxy.py` — generate and log a request ID per request.

**Effort:** S | **Priority:** P2 | **Depends on:** Request ID tracking (small prerequisite)

---

## P3 — Phase 3 items

### TODO-27 — Windows code signing certificate (SmartScreen blocker)
**What:** Acquire and configure a Windows Code Signing Certificate to sign the `.msi` and `.exe` Tauri installers. Add the signing step to `release.yml` via the `TAURI_SIGNING_PRIVATE_KEY` secret already wired in CI. Two options: OV certificate (~€150/yr, SmartScreen reputation builds progressively) or EV certificate (~€400/yr, SmartScreen suppressed immediately on first install).

**Why:** Without a signature, Windows SmartScreen blocks the installer with "Unknown publisher" — the user must click "More info → Run anyway" which most non-technical users won't do. The current `.msi` (v0.1.0) is already built and available but unusable on Windows in practice.

**Pros:** Removes the SmartScreen blocker entirely. Required for any serious Windows distribution (enterprise IT policies often hard-block unsigned installers). EV cert also enables kernel-mode drivers if ever needed.

**Cons:** EV certificates require a physical hardware token (USB) shipped to a registered company address — implies legal entity registration. OV certificates are simpler but don't suppress SmartScreen immediately (reputation takes weeks of downloads to build).

**Next step:** Purchase from Sectigo, DigiCert, or GlobalSign. Add `WINDOWS_CERTIFICATE` + `WINDOWS_CERTIFICATE_PASSWORD` secrets to the repo, then configure `tauri.conf.json` `bundle.windows.certificateThumbprint`.

**Decision 2026-03-16:** Dépriorisé. Le MVP cible la web app (`/bibividi/ui` — TODO-04) avant toute distribution native. Le cert Windows n'a de sens qu'une fois le Tauri installer nécessaire (TODO-11, P3). Pas d'investissement cert avant validation beta web.

**Effort:** S (integration) + procurement | **Priority:** P3 | **Depends on:** TODO-11 (Tauri installer), legal entity (for EV) or company domain (for OV)

---

### TODO-11 — Native installer (Tauri .exe / .dmg / .AppImage)
**What:** Wrap the Python proxy + web UI in a Tauri desktop app. The app bundles a Python runtime (or calls the system Python), starts the proxy on launch, and opens the web UI in a native window. Distributed as a signed .exe (Windows), .dmg (macOS), and .AppImage (Linux).

**Why:** `pip install` requires Python. Non-developer users (CFOs, team leads, enterprise IT) want to double-click and install. A native installer is required for the Pro/Enterprise market and for app store distribution.

**Pros:** Zero-friction install for non-developers. Enables code signing and OS-level auto-update. Same web UI reused (no Tauri-specific UI code).

**Cons:** Rust build pipeline required. Code signing certificates (Apple $99/yr, Windows EV cert). CI matrix for 3 platforms.

**Context:** Follows the web UI (TODO-04). The Tauri `webview` just wraps `http://localhost:8080/bibividi/ui`.

**Effort:** L | **Priority:** P3 | **Depends on:** TODO-04 (web UI)

---

### ~~TODO-12~~ — ✅ SHIPPED — FAISS / approximate nearest-neighbor matching
**What:** Replace the O(n) cosine scan in `matcher.py` with FAISS (Facebook AI Similarity Search) or `hnswlib`. At 500+ skills, the linear scan becomes measurable latency.

**Why:** At current scale (5–50 skills) the O(n) scan is ~50µs — negligible. At marketplace scale (500–5000 skills) it becomes 0.5–5ms per request at 100 req/s. FAISS gives sub-millisecond search at any scale.

**Context:** `bvd/engine/matcher.py:57` — replace the for-loop with a FAISS index. The embedding dimension is 384 (all-MiniLM-L6-v2). FAISS IVF index with 16 centroids handles 10,000 vectors comfortably.

**Effort:** S | **Priority:** P3 | **Depends on:** Nothing (straightforward swap)

---

## P1 — Business model prerequisites (from CEO review 2026-03-14)

### ~~TODO-28~~ — ✅ SHIPPED — User identity: license key system (prerequisite for billing)
**What:** Before billing can attribute savings to a user, BIBIVIDI needs a user identity. Decision (2026-03-17): **license key**, not OAuth/email account. On first `bibividi start`, if no key is found in `~/.bibividi/config.toml`, the user runs `bibividi activate <license-key>`. The key is stored locally and sent as a header (`X-BIBIVIDI-License`) on all outbound calls to the billing backend. The billing backend maps key → Stripe customer.

**Key issuance flow:**
1. User completes Stripe Checkout on `bibividi.ai`
2. Stripe webhook (`checkout.session.completed`) → billing backend generates a UUID license key (`bvd-xxxxxxxx`) tied to the Stripe `customer_id`
3. Transactional email (Resend or Postmark) sent to the Stripe billing email with the key: "Your license key: `bvd-xxxxxxxx`. Run `bibividi activate bvd-xxxxxxxx`."
4. User activates locally — no browser, no account portal

**Key flows:**
- `bibividi activate <key>` — validates key against billing API, stores in `~/.bibividi/config.toml` under `[auth] license_key = "..."`, prints confirmation
- `bibividi start` without a key — proxy starts normally but billing/stats upload is disabled; prints one-time notice: "No license key. Run `bibividi activate <key>` to enable savings tracking."
- Free-tier (no key) — proxy works fully locally, savings stored in local SQLite only, no cloud sync, no billing
- All executions rows include `license_key_hash` (SHA-256 of key — not the key itself) for audit trail

**Why:** OAuth adds a web signup flow, a session system, and a callback server — overkill for a local CLI tool. A license key is the standard model for developer tools (JetBrains, Tailscale, Raycast). It requires no browser, no account portal, and no new infrastructure beyond a key validation endpoint. Key issuance is handled by Stripe (license key = Stripe customer ID alias or a short UUID generated at checkout).

**Pros:** Zero friction — one CLI command to activate. No browser required. No session management. Aligns with developer tool conventions. License key = natural upsell gate (free tier works without key, Pro requires one).

**Cons:** Key sharing is possible (mitigated by usage anomaly detection, not a hard blocker for Phase 2). Key rotation requires a new `bibividi activate` call — document in upgrade notes.

**Repo split — decision 2026-03-17:**
- `bibividi/bibividi` (this repo) — proxy, CLI, `bvd/license.py`, `bibividi activate`
- `bibividi/website` (separate repo) — `bibividi.ai` homepage, pricing page, ROI calculator (TODO-17), Stripe Checkout, **webhook handler** (`POST /webhooks/stripe`)
- The webhook handler MUST live in `bibividi/website` (or a future `bibividi/api` repo), NOT in this repo. The local proxy runs on `localhost:8080` — Stripe cannot reach it. The webhook endpoint must be a publicly deployed HTTPS service.
- `/bibividi/ui` dashboard (TODO-04) stays in this repo (`bvd/ui/`) — it is served by FastAPI, delivered with `pip install`, and runs locally. No auth needed (localhost = trusted).

**Context (this repo):**
- `bvd/license.py` — `load_license_key()`, `hash_license_key()`, `validate_key_with_api()`, `BIBIVIDI_DATA_DIR`
- `bvd/config.py` — add `license_key: str | None = None` read from `~/.bibividi/config.toml` (separate from `.env` — config.toml is user state, .env is deployment config)
- `bvd/cli.py` — add `bibividi activate <key>` command; validates against `BIBIVIDI_BILLING_API_URL/v1/keys/validate`
- `bvd/billing.py` (TODO-13) — reads `config.license_key`, sends as `X-BIBIVIDI-License` header on billing calls
- `bvd/engine/stats.py` — add `license_key_hash TEXT` column to `executions` (migration v4, after TODO-19 v3)

**Context (bibividi/website repo):**
- Stripe Checkout session creation (pricing page → checkout)
- Webhook handler `POST /webhooks/stripe`: verifies Stripe signature, handles `checkout.session.completed` → generates `bvd-xxxxxxxx` key, persists key→customer mapping, sends activation email via Resend/Postmark
- Idempotency: check `session_id` before generating key (duplicate webhook events must not create a second key)
- `GET /v1/keys/validate` — endpoint called by `bibividi activate` to verify a key is valid and active

**Not in scope:** account portal, password reset, OAuth, multi-user per instance. All Phase 3+.

**Effort:** S | **Priority:** P1 | **Depends on:** Nothing | **Blocks:** TODO-13 (billing)

---

### TODO-29 — Deploy bibividi/website to production (Vercel + Neon + Stripe + Resend)
**What:** Deploy the scaffolded `bibividi/website` repo (Next.js 15) to production so that `bibividi.ai` is live, the Stripe webhook is reachable, and `bibividi activate` can validate keys against a real API.

**Checklist (in order):**

1. **Vercel project** — connect `github.com/bibividi/website` to a new Vercel project. Set production domain to `bibividi.ai`. Enable automatic deploys from `main`.

2. **Neon Postgres** — add a Neon database from the Vercel marketplace (Storage tab). Vercel auto-injects `POSTGRES_URL`. Then run the schema migration locally:
   ```bash
   cd website
   cp .env.example .env.local   # fill POSTGRES_URL from Vercel dashboard
   npm run db:generate
   npm run db:migrate
   ```
   Verify the `license_keys` table exists in the Neon console.

3. **Resend** — create an account at resend.com, add and verify the `bibividi.ai` domain (DNS TXT record), create an API key. Set in Vercel env vars:
   - `RESEND_API_KEY=re_...`
   - `RESEND_FROM=BIBIVIDI <noreply@bibividi.ai>`

4. **Stripe** — in the Stripe dashboard:
   - Create products + prices matching the 4 pricing tiers (Free/Pro/Growth/Enterprise)
   - Create a Checkout Session for each paid tier
   - Register the webhook endpoint: `https://bibividi.ai/api/webhooks/stripe`
   - Select event: `checkout.session.completed`
   - Copy the webhook signing secret. Set in Vercel env vars:
     - `STRIPE_SECRET_KEY=sk_live_...`
     - `STRIPE_WEBHOOK_SECRET=whsec_...`
     - `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...`

5. **License secret** — generate a 32-char random string and set:
   - `BIBIVIDI_LICENSE_SECRET=<random>`
   This is used to sign badge HMAC tokens. Must match the value set in the proxy's env.

6. **Smoke test** — after deploy:
   - `curl https://bibividi.ai/api/keys/validate?key=bvd-fake` → should return `{"valid":false}` with HTTP 401
   - Use Stripe's "Send test webhook" → `checkout.session.completed` → check Neon for a new row in `license_keys` and verify the activation email arrives in Resend logs
   - `bibividi activate <key>` on a local install → should print activation confirmation

7. **Update `BIBIVIDI_BILLING_API_URL`** in the proxy's `.env.example`:
   - Add `BIBIVIDI_BILLING_API_URL=https://bibividi.ai` (used by `bibividi activate` and billing calls)

**Why:** The webhook endpoint must be publicly reachable over HTTPS before any beta user can buy a plan. Without this deployed, TODO-28 (license keys) and TODO-13 (billing) cannot be tested end-to-end.

**Effort:** S | **Priority:** P1 | **Depends on:** TODO-28 (license key system) | **Blocks:** TODO-13 (billing end-to-end)

---

### ~~TODO-13~~ — ✅ SHIPPED — Billing infrastructure (Stripe + savings audit trail)
**What:** Stripe integration for savings-share billing. A monthly billing job reads the `executions` table, computes tokens saved per user per month, translates to euros saved using the model price stored at execution time, and charges 20%/15%/10% of savings depending on tier (capped at €200/month for Pro). Every execution row stores `tokens_before`, `tokens_after`, `model_price_per_token_eur` for an immutable audit trail. ToS defines "savings" as `(tokens_before - tokens_after) × model_price_per_token`.

**Why:** Without billing, the savings-share pricing model cannot collect revenue. The audit trail is required to resolve billing disputes — without it, any user can claim the savings calculation is wrong.

**Pros:** Enables the entire revenue architecture. Audit trail eliminates billing disputes. Per-execution pricing data also powers the CSRD module (TODO-14).

**Cons:** Adds Stripe dependency + payment compliance (PCI-DSS scoping, VAT for EU customers). Requires defining a canonical model price list.

**Context:** New `bvd/billing.py`. Monthly billing job can be a CLI command (`bibividi billing run`) or APScheduler task. `bvd/engine/stats.py` — add `tokens_before`, `tokens_after`, `model_price_eur` columns to `executions` table (requires schema migration). `bvd/core/proxy.py` — capture token counts from response before and after script injection.

**Effort:** M | **Priority:** P1 | **Depends on:** TODO-03 (schema migration, shipped ✔), TODO-28 (license key identity), TODO-29 (website deployed), savings-share pricing model (locked 2026-03-14)

---

### TODO-15 — GTM validation sprint (2 weeks, zero cost)
**What:** Five structured validation tests to run before billing infrastructure is built. Each test has a defined success criterion and can be run with existing code.

- **T1 (willingness to pay):** 5 companies on 30-day free trial with `BIBIVIDI_DRY_RUN=true`. Success: 3/5 express willingness to pay after seeing first savings report.
- **T2 (ICP validation):** Direct outreach to 20 AI-native startups (find via GitHub: repos with recent `anthropic` or `openai` API commits). Success: 3 demo calls, 1 converts within 30 days.
- **T3 (marketplace purchase intent):** Post 10 BIBIVIDI-built packs with a "notify me when available" button (no payment required). Success: 10 signups in 30 days.
- **T4 (pricing A/B):** Two landing page variants — flat €45/month vs. savings-share 20%. Success: savings-share has higher click-to-trial CVR.
- **T5 (CSRD interest):** 20 cold emails to ESG/sustainability officers at companies >250 employees. Success: 5 responses, 2 express interest in a paid compliance tool.

**Why:** The business model is pure hypothesis with zero paying customers. These tests cost nothing and validate the most critical assumptions before engineering time is spent on Stripe integration and compliance module.

**Pros:** Validates willingness to pay, ICP, marketplace demand, and pricing preference in 2 weeks. Each test uses existing shipped code (DRY_RUN mode, web UI).

**Cons:** Requires founder time on outreach rather than engineering.

**Context:** Runs before TODO-13 (billing). Uses `BIBIVIDI_DRY_RUN=true` (shipped ✔) and `/bibividi/ui` dashboard (shipped ✔). T4 requires a landing page — `bibividi.ai`.

**Effort:** S | **Priority:** P1 | **Depends on:** DRY_RUN (shipped ✔), web UI (shipped ✔)

---

### TODO-17 — ROI calculator on landing page
**What:** Interactive calculator on `bibividi.ai` with two sliders: "monthly AI API spend (€)" and "average context size (tokens)". Shows real-time: estimated monthly savings, BIBIVIDI share (20%), net savings to user, CO₂ equivalent avoided. No data collected, no sign-up required. Pre-fills with realistic defaults (€500/month spend, 10,000 tokens avg context).

**Why:** Savings-share pricing only converts if the user can see their own number before installing. A calculator that shows "you would save €380/month and pay BIBIVIDI €76" removes all conversion friction. Static pricing tables don't work for value-based pricing.

**Pros:** Highest-leverage landing page element for savings-share model. Shareable ("look what I calculated"). Also validates TODO-13's pricing assumptions before billing is built.

**Cons:** Requires a landing page (currently README/PyPI only). Needs a model price table embedded in the calculator.

**Context:** Can be a single HTML file with vanilla JS. Model prices hardcoded from current Anthropic/OpenAI pricing. Update quarterly.

**Effort:** S | **Priority:** P1 | **Depends on:** Nothing

---

## P2 — Business delight features (from CEO review 2026-03-14)

### ~~TODO-14~~ — ✅ SHIPPED — CSRD compliance reporting module
**What:** Structured AI Scope 3 emissions report for enterprise customers. Per-month breakdown: total tokens processed, tokens saved, CO₂ equivalent avoided (tokens × 0.003 gCO₂eq, based on published LLM inference studies), exportable as PDF and CSV. Methodology footnoted and citable for CSRD Scope 3 filing. Dashboard panel in `/bibividi/ui` + Enterprise plan add-on at €2,000–€5,000/year.

**Why:** CSRD (Corporate Sustainability Reporting Directive) makes Scope 3 emissions reporting mandatory for 50,000+ European companies from 2024/2025. AI API usage is Scope 3. A tool that measures and reduces AI carbon footprint — and produces an auditable report — is a compliance tool, not a feature. Compliance tools are price-inelastic and commanded by a different buyer (ESG officer, CFO) than the developer.

**Pros:** Opens a compliance buyer segment at 5–10× current Enterprise pricing. First mover in "AI Scope 3 reporting" category. The CO₂ data is already calculable from the `executions` table. Aligns with EcoVadis, Green Software Foundation, INR labels.

**Cons:** Requires CO₂ methodology citation and legal review of claims. "0.003 gCO₂eq/token" is a rough estimate — needs proper sourcing and a disclaimer for legal use.

**Context:** `bvd/engine/stats.py` — add `co2_eq_saved_g` computed column (tokens_saved × 0.003). `bvd/ui/` — add CSRD report panel. New `bvd/reports.py` — PDF/CSV export using `reportlab` or `weasyprint`. `bvd/cli.py` — add `bibividi report --month 2026-03` command.

**Effort:** M | **Priority:** P2 | **Depends on:** TODO-13 (billing, for per-execution token data), TODO-08 (partial overlap with CO₂ digest)

---

### ~~TODO-16~~ — ✅ SHIPPED — Shareable monthly savings badge
**What:** A dynamic SVG badge served at `/bibividi/badge.svg?user=<token>` showing: tokens saved this month, CO₂ equivalent, and the BIBIVIDI logo. Embeddable in GitHub READMEs, product docs, blog posts. Example: `![BIBIVIDI](http://localhost:8080/bibividi/badge.svg)` renders as "BIBIVIDI saved 2.4M tokens · 7.2kg CO₂ this month".

**Why:** Every user who embeds this badge is a marketing channel. The CO₂ framing makes it shareable beyond developer Twitter — it reaches ESG-conscious teams and CTOs. Zero cost to implement.

**Pros:** Viral acquisition loop with zero budget. Each embedded badge is a backlink and a brand impression. The CO₂ angle gives it ESG credibility.

**Cons:** Requires an auth token to avoid leaking usage data publicly. Badge is approximate (monthly aggregate, not real-time).

**Context:** `bvd/core/proxy.py` — add `/bibividi/badge.svg` route. Reads from `stats.monthly_summary()`. SVG template with BIBIVIDI green palette. Token = HMAC of user identifier.

**Effort:** XS | **Priority:** P2 | **Depends on:** stats.py (exists), billing auth token (TODO-13)

---

### ~~TODO-18~~ — ✅ SHIPPED — Quarterly team savings digest email
**What:** For Growth and Enterprise plans, an automated quarterly email to the account owner with: total tokens saved, total € saved (vs. what they paid BIBIVIDI), CO₂ equivalent avoided, top 3 skills by usage, and a "Share with your team" link. Delivered via a simple transactional email provider (Resend or Postmark).

**Why:** A CFO who sees "BIBIVIDI saved your team €12,400 this quarter — you paid us €1,200" does not cancel. They expand. ESG officers attach the CO₂ figure to CSRD quarterly filings. This is the primary enterprise retention and expansion driver — directly targets NRR > 110%.

**Pros:** Drives expansion (upsells to higher tiers). Reduces churn by making savings visceral for the economic buyer. Foundation for CSRD module adoption.

**Cons:** Requires email infrastructure (transactional email provider) and account email storage. RGPD: email is personal data — needs explicit consent at signup.

**Context:** New `bvd/mailer.py`. `bvd/engine/stats.py` — add `quarterly_summary(user_id)` method. `bvd/cli.py` — add `bibividi digest --quarter 2026-Q1` to trigger manually. APScheduler quarterly task.

**Effort:** S | **Priority:** P2 | **Depends on:** TODO-13 (billing, for per-user savings data), email consent at signup

---

## P1 — BSS 1.1 Skill Chaining (from CEO review 2026-03-14)

### ~~TODO-19~~ — ✅ SHIPPED — BSS 1.1 skill chaining (run_chain + schema + dashboard waterfall)
**What:** Implement BSS 1.1 skill chains: a skill can declare `chain: ["skill-a-id", "skill-b-id", "skill-c-id"]` in its `skill.json`. The runner executes the steps sequentially — step N's stdout becomes step N+1's stdin (raw string, no envelope). Every existing skill is immediately chain-compatible with zero changes. An optional `skill.py` finalizer runs after the last step. The proxy dispatches to `run_chain()` instead of `run_script()` when the matched skill has `chain_ids`.

**Data flow:**
```
Prompt → run_chain()
  → run_script(skill_a, prompt)       → stdout₁
  → run_script(skill_b, stdout₁)      → stdout₂
  → run_script(skill_c, stdout₂)      → stdout₃
  → run_script(finalizer, stdout₃)    → final_output  (optional)
  → LLM with final_output
```

**Why:** Single-step skills are monolithic — an invoice processor must reimplement table parsing that `csv-data-summarizer` already has. Chains enable composable, reusable, testable atoms. Three-step pipeline can achieve 99%+ token reduction on complex documents.

**Pros:** Every existing skill is chain-compatible (raw string format). Minimal new abstractions (run_chain wraps run_script). Opens marketplace "Workflows" category. Dashboard waterfall makes savings visceral.

**Cons:** Schema migration required (v3). Cycle detection adds complexity. Total timeout must be tuned carefully to avoid blocking the proxy.

**Failure modes handled:**
- Circular chain: DFS cycle check at import time + `visited` set at runtime
- Missing dep: `library.get()` returns None → abort, fall back to original prompt
- Step failure (non-zero exit): abort chain, fall back, log which step failed
- Total timeout: `BIBIVIDI_MAX_CHAIN_RUNTIME_S` wraps the entire loop (default: 3× single skill timeout)
- Empty step output: pass previous input to next step (don't abort)
- Chain output larger than original: fall back to original, log warning

**Files to touch:**
- `bvd/engine/runner.py` — `run_chain()`, `ChainRunResult` (with `step_outputs: list`)
- `bvd/engine/library.py` — `Script.chain_ids: list[str]`, `Script.is_chain` property, `Script.bss_version`, `Script.inputs_type`, `Script.outputs_type`, `get_many(ids)`, cycle detection in `import_bss()`
- `bvd/engine/stats.py` — `chain_steps` table (`execution_id, step_num, skill_id, tokens_in, tokens_out, latency_ms`), `record_chain()` method
- `bvd/core/proxy.py` — dispatch: `if script.is_chain: run_chain() else: run_script()`
- `bvd/config.py` — `BIBIVIDI_MAX_CHAIN_DEPTH: int = 10`, `BIBIVIDI_MAX_CHAIN_RUNTIME_S: float`
- `bvd/cli.py` — `bibividi list --chains` (shows dep status, warns on missing), feature flag check
- `bvd/ui/` — token waterfall panel (see below)
- `tests/test_runner.py` — 11 chain test cases (see context)
- `tests/test_library.py` — cycle detection, `import_bss` with chain validation
- `MVP.md` — BSS 1.1 spec section

**Schema migration (v2 → v3):**
```sql
ALTER TABLE scripts ADD COLUMN chain_ids  TEXT NOT NULL DEFAULT '[]';
ALTER TABLE scripts ADD COLUMN chain_mode TEXT NOT NULL DEFAULT 'sequential';
ALTER TABLE scripts ADD COLUMN bss_version TEXT NOT NULL DEFAULT '1.0';
ALTER TABLE scripts ADD COLUMN inputs_type  TEXT;   -- optional typed I/O
ALTER TABLE scripts ADD COLUMN outputs_type TEXT;   -- optional typed I/O

CREATE TABLE IF NOT EXISTS chain_steps (
    id           INTEGER PRIMARY KEY AUTOINCREMENT,
    execution_id INTEGER NOT NULL REFERENCES executions(id),
    step_num     INTEGER NOT NULL,
    skill_id     TEXT NOT NULL,
    tokens_in    INTEGER NOT NULL,
    tokens_out   INTEGER NOT NULL,
    latency_ms   REAL
);
```

**Dashboard token waterfall panel:**
```
invoice-to-summary pipeline (2.1s total)
│
├─ pdf-text-extractor    45,000 → 8,200 tokens  (820ms)
├─ invoice-line-parser    8,200 → 1,100 tokens  (640ms)
└─ financial-summarizer   1,100 →   180 tokens  (640ms)
────────────────────────────────────────────────────────
Total: 44,820 tokens saved (99.6%) · €0.13 saved
```

**Test cases required:**
1. `test_chain_happy_path` — 3 steps succeed, output < original
2. `test_chain_step_failure` — step 2 of 3 exits non-zero → fallback
3. `test_chain_timeout` — total chain timeout hit → fallback + timed_out=True
4. `test_chain_cycle_runtime` — duplicate skill_id in chain_ids → fallback
5. `test_chain_missing_dep` — unknown skill_id → fallback + warning logged
6. `test_chain_empty_step_output` — step prints nothing → next step gets prev input
7. `test_chain_larger_than_original` — output > input token count → fallback
8. `test_chain_single_step` — chain_ids has 1 element → equivalent to run_script()
9. `test_chain_pending_dep` — dep skill is pending → abort
10. `test_chain_with_finalizer` — chain.code runs on last step's output
11. `test_chain_import_cycle_detection` — installing A→B→A → ValueError at import

**Feature flag:** `BIBIVIDI_ENABLE_CHAINS=true` (default: false until shipped)

**Effort:** L | **Priority:** P1 | **Depends on:** TODO-03 (schema migration, shipped ✔)

---

### ~~TODO-23~~ — ✅ SHIPPED — 3 automation recipe chains (BIBIVIDI-built, marketplace launch content)
**What:** Build three BIBIVIDI-authored BSS 1.1 chain packs to seed the "Workflows" marketplace category at BSS 1.1 launch:

1. **Document Intelligence Suite** (`document-intelligence-suite`): `pdf-text-extractor` → `type-classifier` → `content-router`. Routes any document to the right downstream summarizer. Price: €0.005/use.
2. **Financial Pipeline** (`financial-pipeline`): `invoice-parser` → `line-validator` → `totals-summarizer`. Full invoice processing: 50 pages → 200 tokens. Price: €0.008/use.
3. **Code Review Pipeline** (`code-review-pipeline`): `diff-parser` → `complexity-scorer` → `review-formatter`. PR diff → structured review: 8K tokens → 150 tokens. Price: €0.006/use.

**Why:** Without showcase content, BSS 1.1 launches as a spec with no demos. These three chains are the "Show HN" content that makes the feature immediately compelling and seeds the marketplace "Workflows" category.

**Pros:** Demonstrates 99%+ token reduction on real use cases. Generates revenue from day 1. Each chain also sells its dep skills (new installs for free dep packs).

**Cons:** Requires the dep skills (pdf-text-extractor, invoice-parser, diff-parser, etc.) to be built first as standalone skill packs.

**Context:** Build dep skills as free marketplace packs (phase A of marketplace seeding from TODO-15). Then build the paid chains on top. Both serve double duty: free dep skill = adoption, paid chain = revenue.

**Effort:** M | **Priority:** P1 | **Depends on:** TODO-19 (chains engine), dep skill packs

---

## P2 — BSS 1.1 chain ecosystem (from CEO review 2026-03-14)

### ~~TODO-21~~ — ✅ SHIPPED — `bibividi chain build <skill-a> <skill-b> <skill-c>` CLI
**What:** Interactive CLI scaffolding that creates a new BSS 1.1 chain pack from installed skills. Takes ordered skill IDs as arguments, generates a valid `skill.json` with `chain` field and optional `skill.py` stub, runs the pipeline end-to-end on sample input (from stdin), and displays the token waterfall output. Publishes to local library ready to test.

**Why:** Writing a BSS 1.1 `skill.json` by hand is fiddly. Without tooling, chain authorship has too much friction. With it, creating a chain is a 10-second CLI command.

**Pros:** Dramatically lowers the barrier to chain authorship. Every chain author is a potential marketplace publisher. Also serves as a live test of the chain engine.

**Cons:** Requires TODO-19 (chains engine) to exist first.

**Context:** `bvd/cli.py` — add `@cli.group('chain')` with `chain build` subcommand. Validates that all dep skill IDs are installed. Generates minimal `skill.json` to a new directory. Optionally opens the file in `$EDITOR`.

**Effort:** S | **Priority:** P2 | **Depends on:** TODO-19 (chains engine)

---

### ~~TODO-22~~ — ✅ SHIPPED — Chain marketplace revenue split (dep author micro-payments)
**What:** When a paid marketplace chain executes, BIBIVIDI distributes the 80% author share between the chain author and each dep skill author. Default split: chain author gets 40%, each dep author gets `40% / N` (equal weight). Chain authors can optionally declare custom weight per step in `skill.json`. Tracked in a new `marketplace_payouts` table, paid out monthly via Stripe Connect.

**Why:** Building a popular dep skill that others chain to generates passive income for the dep author. This is the npm ecosystem incentive model — package authors earn from downstream usage. It creates a flywheel: more dep skills → more chains possible → more usage → more marketplace revenue for everyone.

**Pros:** Powerful marketplace growth incentive. Differentiates BIBIVIDI's marketplace from any static "buy a script" model. Makes high-quality dep skills commercially valuable.

**Cons:** Requires Stripe Connect (payouts to third parties). Tax/VAT implications for micro-payments to authors in different countries. Minimum payout threshold needed (e.g., €10/month) to avoid micro-transaction fees.

**Context:** New `bvd/marketplace/payouts.py`. `chain_steps` table (from TODO-19) already tracks which dep skill ran each execution — payout calculation reads from it. Requires TODO-13 (billing infrastructure) as prerequisite.

**Effort:** M | **Priority:** P2 | **Depends on:** TODO-13 (billing), TODO-19 (chains engine)

---

## P3 — BSS 2.0 auto-assembly roadmap (from CEO review 2026-03-14)

### ~~TODO-20~~ — ✅ SHIPPED — BSS 2.0 auto-assembly (typed I/O, runtime pipeline discovery)
**What:** The matcher no longer just returns a single skill — it assembles an optimal type-compatible pipeline at runtime. Each skill declares `inputs.type` and `outputs.type` in `skill.json` (already in BSS 1.1 spec as optional fields, tracked in `inputs_type`/`outputs_type` columns from TODO-19 schema). The matcher builds a directed graph of installed skills, finds the shortest type-compatible path from the prompt's detected input type to `plain_text`, and executes it as a chain — without any explicit `chain` declaration.

**Why:** This is the "BIBIVIDI is a compiler" vision fully realized. A developer installs three unrelated skills from the marketplace. BIBIVIDI auto-discovers that they compose into a pipeline for their use case. No configuration. No chain declaration. It just works. This is the Phase 3 cathedral.

**Pros:** Maximum power with zero configuration. Makes every skill combinatorially more valuable. Generates "discovered pipeline" analytics that are valuable for the Voltalis revenue-share story with LLM operators.

**Cons:** Requires 100+ typed skills in the marketplace before the graph has enough nodes to be useful. Type system needs formal definition. Path-finding can have multiple valid solutions — need a ranking function (prefer shorter chains, higher avg_saving skills).

**Context:**
- `bvd/engine/matcher.py` — add `assemble_pipeline(prompt, type_graph)` method
- `bvd/engine/library.py` — build type-compatibility graph from `inputs_type`/`outputs_type`
- `bvd/engine/runner.py` — `run_chain()` already handles dynamically assembled chains
- Requires: BSS 1.1 typed I/O fields (in TODO-19), 100+ marketplace skills with declared types

**Phases:**
- BSS 1.1 (TODO-19): typed I/O fields added to spec, optional, not used by engine
- BSS 1.5 (future): matcher uses type hints for chain validation only
- BSS 2.0 (this TODO): full auto-assembly from type graph

**Effort:** XL | **Priority:** P3 | **Depends on:** TODO-19 (chains + typed I/O), 100+ typed marketplace skills

---

## P1 — Free-tier LLM support (from CEO review 2026-03-15)

### ~~TODO-24~~ — ✅ SHIPPED — Fix Gemini extraction + injection; add Groq/Ollama/Mistral support
**What:** Provider-aware `_extract_prompt()` and `_inject_result()` in `proxy.py`. Gemini uses `contents[].parts[].text` instead of `messages[]`. Both extraction and injection must be provider-aware (if-else per provider, no new abstraction). Add Groq (`api.groq.com`), Together.ai (`api.together.xyz`), Mistral (`api.mistral.ai`) to the default `target_apis` list (all are OpenAI-compatible — no extraction change needed). Add `BIBIVIDI_ALLOW_LOCAL_APIS=false` config flag for Ollama users (`localhost:11434`).

**Why:** Gemini is already in `target_apis` but `_extract_prompt()` returns `None` for all Gemini requests — silently falling through to pass-through with zero optimization and no log warning. Every Gemini user today gets no value. Groq is the most popular free LLM API (Llama 3.3 70B, free tier) and works with one config line. Ollama is the primary local-model option and the largest zero-cost user segment.

**Pros:** Unlocks the entire free-tier user segment. The proxy core is already provider-agnostic — this is a ~40 line fix. Groq support is literally one entry in `target_apis`. Makes BIBIVIDI the universal LLM proxy, not just an Anthropic/OpenAI tool.

**Cons:** Gemini streaming uses a different SSE format from OpenAI — but injection happens on the request, not the response, so streaming is unaffected. Gemini token counting uses `usageMetadata` (not `usage.prompt_tokens`) — stats.py needs a second response-parsing branch for accurate counts.

**Context:**
- `bvd/core/proxy.py:_extract_prompt` — add `if 'googleapis.com' in host:` branch handling `contents[].parts[].text`
- `bvd/core/proxy.py:_inject_result` — add Gemini branch: inject into `contents[-1].parts[-1].text`, not `messages[-1].content`
- `bvd/config.py:target_apis` — add `"api.groq.com"`, `"api.together.xyz"`, `"api.mistral.ai"` to defaults
- `bvd/config.py` — add `allow_local_apis: bool = False` with comment re: SSRF risk
- `bvd/engine/stats.py` — handle Gemini `usageMetadata.promptTokenCount` response format
- Tests to add: `test_extract_prompt_gemini_happy_path`, `test_extract_prompt_gemini_malformed_returns_none`, `test_inject_result_gemini_reconstructs_contents_format`, `test_ssrf_guard_blocks_localhost_by_default`, `test_ssrf_guard_allows_localhost_with_flag`

**Critical gap:** `_inject_result()` currently reconstructs `{"messages": [...]}`. If this runs on a Gemini request, the body forwarded to `generativelanguage.googleapis.com` will be malformed and return a 400 — user will blame BIBIVIDI. Fix injection first before adding Gemini to any user-facing docs.

**Effort:** S | **Priority:** P1 | **Depends on:** Nothing

---

## P2 — Free-tier UX (from CEO review 2026-03-15)

### ~~TODO-25~~ — ✅ SHIPPED — Quota mode: stats + dashboard + bibividi status for zero-cost providers
**What:** When `model_price_eur = 0.0` (Gemini free, Groq free, Ollama), the stats module and UI shift from "€ saved" framing to "quota saved" framing. Specifically: (1) `stats.record_execution()` computes `requests_saved = tokens_saved / avg_tokens_per_request` when price=0; (2) `bibividi status` shows "+850 extra prompts/day" instead of "€0.00 saved"; (3) the `/bibividi/ui` dashboard shows a "Quota Optimizer Mode" indicator and renders a quota bar (daily tokens used vs. cap) instead of a savings chart; (4) the ROI calculator (`/bibividi/roi`) adds a "quota mode" toggle that shows "extra requests/day" instead of "€ saved/month".

**Why:** Today the dashboard shows €0.00 for every free-tier user. The value is real (10x their daily quota) but the UI makes it invisible. A user who installs BIBIVIDI, sees €0.00 everywhere, and gets no positive signal will uninstall. The technical savings are happening; the product just doesn't communicate them.

**Pros:** Converts free-tier installs from zero-signal installs into engaged users who see their value daily. The `requests_saved` metric is already calculable from `tokens_saved` — this is a display change, not a data change. The quota bar makes BIBIVIDI feel like a resource manager for free-tier users (visceral value).

**Cons:** Requires knowing the provider's daily quota limit, which varies by plan and changes without notice. Use `BIBIVIDI_QUOTA_DAILY_TOKENS` env var for user override; hardcode known free tier limits (Gemini 1.5 Flash: 1M/day, Groq: 500k/day) as defaults with a "update quarterly" comment (same pattern as `MODEL_PRICES_EUR` in billing.py).

**Context:**
- `bvd/engine/stats.py` — add `requests_saved` computed column; clamp savings % to 0 when price=0 (fix ZeroDivisionError gap)
- `bvd/config.py` — add `quota_daily_tokens: int | None = None` with known free-tier defaults by provider
- `bvd/cli.py:status` — add quota mode branch
- `bvd/ui/` — quota bar panel, "Quota Optimizer Mode" badge, ROI calculator toggle
- `bvd/billing.py` — no change (free tier already correctly charges €0)

**Effort:** S | **Priority:** P2 | **Depends on:** TODO-24 (Gemini/Groq support)

---

### ~~TODO-26~~ — ✅ SHIPPED — `bibividi simulate` quota output for free-tier users
**What:** `bibividi simulate logs.json` currently outputs "you would have saved €0.13". For free-tier users (Gemini/Groq/Ollama — detected when model_price=0 or when `--quota-mode` flag is passed), also output: "you would have fit 850 more requests/day within your free quota" — using the provider's known daily token limit (from `BIBIVIDI_QUOTA_DAILY_TOKENS` or the hardcoded defaults from TODO-25).

**Why:** `bibividi simulate` is the enterprise sales closer (TODO-09, elevated P1). The same tool should be the free-tier acquisition closer. A student who runs `bibividi simulate my_logs.json` and sees "BIBIVIDI would give you 20x your Groq free quota" converts immediately. Zero incremental engineering after TODO-25 ships.

**Pros:** Reuses quota logic from TODO-25. Turns `bibividi simulate` into a dual-audience tool — one command, two audiences, two conversion motions. The "850 extra requests/day" number is the free-tier equivalent of the enterprise "€12,000 saved last month."

**Cons:** The "extra requests/day" calculation assumes average prompt size from the simulation logs — reasonable but approximate. Add a disclaimer line: "estimate based on average prompt size in provided logs."

**Context:**
- `bvd/cli.py:simulate` — add quota mode output block after existing € output
- Reads `quota_daily_tokens` from config (or provider defaults from TODO-25)
- Formula: `extra_requests = tokens_saved_total / avg_tokens_per_request`; `quota_utilization_before = total_tokens / daily_limit`; `quota_utilization_after = (total_tokens - tokens_saved) / daily_limit`

**Effort:** XS | **Priority:** P2 | **Depends on:** TODO-24 (Groq/Gemini support), TODO-25 (quota mode logic)
